Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/highenergy/src/G4GammaConversionToMuons.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/highenergy/src/G4GammaConversionToMuons.cc (Version 11.3.0) and /processes/electromagnetic/highenergy/src/G4GammaConversionToMuons.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 //                                                 26 //
                                                   >>  27 // $Id: G4GammaConversionToMuons.cc 66996 2013-01-29 14:50:52Z gcosmo $
                                                   >>  28 //
 27 //         ------------ G4GammaConversionToMuo     29 //         ------------ G4GammaConversionToMuons physics process ------
 28 //         by H.Burkhardt, S. Kelner and R. Ko     30 //         by H.Burkhardt, S. Kelner and R. Kokoulin, April 2002
 29 //                                                 31 //
 30 //                                                 32 //
 31 // 07-08-02: missprint in OR condition in DoIt     33 // 07-08-02: missprint in OR condition in DoIt : f1<0 || f1>f1_max ..etc ...
 32 // 25-10-04: migrade to new interfaces of Part     34 // 25-10-04: migrade to new interfaces of ParticleChange (vi)
 33 // -------------------------------------------     35 // ---------------------------------------------------------------------------
 34                                                    36 
 35 #include "G4GammaConversionToMuons.hh"             37 #include "G4GammaConversionToMuons.hh"
 36                                                << 
 37 #include "G4BetheHeitler5DModel.hh"            << 
 38 #include "G4Electron.hh"                       << 
 39 #include "G4EmParameters.hh"                   << 
 40 #include "G4EmProcessSubType.hh"               << 
 41 #include "G4Exp.hh"                            << 
 42 #include "G4Gamma.hh"                          << 
 43 #include "G4Log.hh"                            << 
 44 #include "G4LossTableManager.hh"               << 
 45 #include "G4MuonMinus.hh"                      << 
 46 #include "G4MuonPlus.hh"                       << 
 47 #include "G4NistManager.hh"                    << 
 48 #include "G4PhysicalConstants.hh"                  38 #include "G4PhysicalConstants.hh"
 49 #include "G4Positron.hh"                       << 
 50 #include "G4ProductionCutsTable.hh"            << 
 51 #include "G4SystemOfUnits.hh"                      39 #include "G4SystemOfUnits.hh"
 52 #include "G4UnitsTable.hh"                         40 #include "G4UnitsTable.hh"
                                                   >>  41 #include "G4MuonPlus.hh"
                                                   >>  42 #include "G4MuonMinus.hh"
 53                                                    43 
 54 //....oooOO0OOooo........oooOO0OOooo........oo     44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
 55                                                    45 
 56 static const G4double sqrte = std::sqrt(std::e <<  46 using namespace std;
 57 static const G4double PowSat = -0.88;          << 
 58                                                    47 
 59 G4GammaConversionToMuons::G4GammaConversionToM     48 G4GammaConversionToMuons::G4GammaConversionToMuons(const G4String& processName,
 60                G4ProcessType type)             <<  49     G4ProcessType type):G4VDiscreteProcess (processName, type),
 61   : G4VDiscreteProcess (processName, type),    <<  50     LowestEnergyLimit (4*G4MuonPlus::MuonPlus()->GetPDGMass()), // 4*Mmuon
 62     Mmuon(G4MuonPlus::MuonPlus()->GetPDGMass() <<  51     HighestEnergyLimit(1e21*eV), // ok to 1e21eV=1e12GeV, then LPM suppression
 63     Rc(CLHEP::elm_coupling / Mmuon),           <<  52     CrossSecFactor(1.)
 64     LimitEnergy(5. * Mmuon),                   <<  53 { 
 65     LowestEnergyLimit(2. * Mmuon),             <<  54   SetProcessSubType(15);
 66     HighestEnergyLimit(1e12 * CLHEP::GeV),  // <<  55   MeanFreePath = DBL_MAX;
 67     theGamma(G4Gamma::Gamma()),                << 
 68     theMuonPlus(G4MuonPlus::MuonPlus()),       << 
 69     theMuonMinus(G4MuonMinus::MuonMinus())     << 
 70 {                                              << 
 71   SetProcessSubType(fGammaConversionToMuMu);   << 
 72   fManager = G4LossTableManager::Instance();   << 
 73   fManager->Register(this);                    << 
 74 }                                                  56 }
 75                                                    57 
 76 //....oooOO0OOooo........oooOO0OOooo........oo     58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
 77                                                    59 
 78 G4GammaConversionToMuons::~G4GammaConversionTo <<  60 // destructor
 79 {                                              <<  61 
 80   fManager->DeRegister(this);                  <<  62 G4GammaConversionToMuons::~G4GammaConversionToMuons() // (empty) destructor
 81 }                                              <<  63 { }
 82                                                    64 
 83 //....oooOO0OOooo........oooOO0OOooo........oo     65 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
 84                                                    66 
 85 G4bool G4GammaConversionToMuons::IsApplicable( <<  67 G4bool G4GammaConversionToMuons::IsApplicable(
                                                   >>  68                                         const G4ParticleDefinition& particle)
 86 {                                                  69 {
 87   return (&part == theGamma);                  <<  70    return ( &particle == G4Gamma::Gamma() );
 88 }                                                  71 }
 89                                                    72 
 90 //....oooOO0OOooo........oooOO0OOooo........oo     73 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 91                                                    74 
 92 void G4GammaConversionToMuons::BuildPhysicsTab <<  75 void G4GammaConversionToMuons::BuildPhysicsTable(const G4ParticleDefinition&)
 93 {                                              <<  76 // Build cross section and mean free path tables
 94   Energy5DLimit = G4EmParameters::Instance()-> <<  77 {  //here no tables, just calling PrintInfoDefinition
 95                                                <<  78    PrintInfoDefinition();
 96   auto table = G4Material::GetMaterialTable(); << 
 97   std::size_t nelm = 0;                        << 
 98   for (auto const& mat : *table) {             << 
 99     std::size_t n = mat->GetNumberOfElements() << 
100     nelm = std::max(nelm, n);                  << 
101   }                                            << 
102   temp.resize(nelm, 0);                        << 
103                                                << 
104   if (Energy5DLimit > 0.0 && nullptr != f5Dmod << 
105     f5Dmodel = new G4BetheHeitler5DModel();    << 
106     f5Dmodel->SetLeptonPair(theMuonPlus, theMu << 
107     const std::size_t numElems = G4ProductionC << 
108     const G4DataVector cuts(numElems);         << 
109     f5Dmodel->Initialise(&p, cuts);            << 
110   }                                            << 
111   PrintInfoDefinition();                       << 
112 }                                                  79 }
113                                                    80 
114 //....oooOO0OOooo........oooOO0OOooo........oo     81 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
115                                                    82 
116 G4double G4GammaConversionToMuons::GetMeanFree <<  83 G4double G4GammaConversionToMuons::GetMeanFreePath(const G4Track& aTrack,
117                                                <<  84                                               G4double, G4ForceCondition*)
                                                   >>  85 
118 // returns the photon mean free path in GEANT4     86 // returns the photon mean free path in GEANT4 internal units
                                                   >>  87 // (MeanFreePath is a private member of the class)
                                                   >>  88 
119 {                                                  89 {
120   const G4DynamicParticle* aDynamicGamma = aTr <<  90    const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
121   G4double GammaEnergy = aDynamicGamma->GetKin <<  91    G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
122   const G4Material* aMaterial = aTrack.GetMate <<  92    G4Material* aMaterial = aTrack.GetMaterial();
123   return ComputeMeanFreePath(GammaEnergy, aMat <<  93 
                                                   >>  94    if (GammaEnergy <  LowestEnergyLimit)
                                                   >>  95      MeanFreePath = DBL_MAX;
                                                   >>  96    else
                                                   >>  97      MeanFreePath = ComputeMeanFreePath(GammaEnergy,aMaterial);
                                                   >>  98 
                                                   >>  99    return MeanFreePath;
124 }                                                 100 }
125                                                   101 
126 //....oooOO0OOooo........oooOO0OOooo........oo    102 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
127                                                   103 
128 G4double                                       << 104 G4double G4GammaConversionToMuons::ComputeMeanFreePath(G4double GammaEnergy,
129 G4GammaConversionToMuons::ComputeMeanFreePath( << 105                                                        G4Material* aMaterial)
130                                                << 
131                                                   106 
132 // computes and returns the photon mean free p    107 // computes and returns the photon mean free path in GEANT4 internal units
133 {                                                 108 {
134   if(GammaEnergy <= LowestEnergyLimit) { retur << 
135   const G4ElementVector* theElementVector = aM    109   const G4ElementVector* theElementVector = aMaterial->GetElementVector();
136   const G4double* NbOfAtomsPerVolume = aMateri    110   const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
137                                                   111 
138   G4double SIGMA = 0.0;                        << 112   G4double SIGMA = 0 ;
139   G4double fact  = 1.0;                        << 
140   G4double e = GammaEnergy;                    << 
141   // low energy approximation as in Bethe-Heit << 
142   if(e < LimitEnergy) {                        << 
143     G4double y = (e - LowestEnergyLimit)/(Limi << 
144     fact = y*y;                                << 
145     e = LimitEnergy;                           << 
146   }                                            << 
147                                                   113 
148   for ( std::size_t i=0 ; i < aMaterial->GetNu << 114   for ( size_t i=0 ; i < aMaterial->GetNumberOfElements() ; i++ )
149   {                                               115   {
150     SIGMA += NbOfAtomsPerVolume[i] * fact *    << 116     G4double AtomicZ = (*theElementVector)[i]->GetZ();
151       ComputeCrossSectionPerAtom(e, (*theEleme << 117     G4double AtomicA = (*theElementVector)[i]->GetA()/(g/mole);
                                                   >> 118     SIGMA += NbOfAtomsPerVolume[i] *
                                                   >> 119       ComputeCrossSectionPerAtom(GammaEnergy,AtomicZ,AtomicA);
152   }                                               120   }
153   return (SIGMA > 0.0) ? 1./SIGMA : DBL_MAX;   << 121   return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
154 }                                                 122 }
155                                                   123 
156 //....oooOO0OOooo........oooOO0OOooo........oo    124 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
157                                                   125 
158 G4double G4GammaConversionToMuons::GetCrossSec    126 G4double G4GammaConversionToMuons::GetCrossSectionPerAtom(
159                                    const G4Dyn    127                                    const G4DynamicParticle* aDynamicGamma,
160                                    const G4Ele << 128                                          G4Element*         anElement)
161                                                   129 
162 // gives the total cross section per atom in G    130 // gives the total cross section per atom in GEANT4 internal units
163 {                                                 131 {
164    return ComputeCrossSectionPerAtom(aDynamicG << 132    G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
165                                      anElement << 133    G4double AtomicZ = anElement->GetZ();
                                                   >> 134    G4double AtomicA = anElement->GetA()/(g/mole);
                                                   >> 135    G4double crossSection =
                                                   >> 136         ComputeCrossSectionPerAtom(GammaEnergy,AtomicZ,AtomicA);
                                                   >> 137    return crossSection;
166 }                                                 138 }
167                                                   139 
168 //....oooOO0OOooo........oooOO0OOooo........oo    140 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
169                                                   141 
170 G4double G4GammaConversionToMuons::ComputeCros    142 G4double G4GammaConversionToMuons::ComputeCrossSectionPerAtom(
171                          G4double Egam, G4int  << 143                          G4double Egam, G4double Z, G4double A)
172                                                   144        
173 // Calculates the microscopic cross section in    145 // Calculates the microscopic cross section in GEANT4 internal units.
174 // Total cross section parametrisation from H.    146 // Total cross section parametrisation from H.Burkhardt
175 // It gives a good description at any energy (    147 // It gives a good description at any energy (from 0 to 10**21 eV)
176 {                                              << 148 { static const G4double Mmuon=G4MuonPlus::MuonPlus()->GetPDGMass();
177   if(Egam <= LowestEnergyLimit) { return 0.0;  << 149   static const G4double Mele=electron_mass_c2;
178                                                << 150   static const G4double Rc=elm_coupling/Mmuon; // classical particle radius
179   G4NistManager* nist = G4NistManager::Instanc << 151   static const G4double sqrte=sqrt(exp(1.));
                                                   >> 152   static const G4double PowSat=-0.88;
180                                                   153 
181   G4double PowThres, Ecor, B, Dn, Zthird, Winf << 154   static G4double CrossSection = 0.0 ;
182                                                   155 
183   if (Z == 1) {  // special case of Hydrogen   << 156   if ( A < 1. ) return 0;
184     B = 202.4;                                 << 157   if ( Egam < 4*Mmuon ) return 0 ; // below threshold return 0
185     Dn = 1.49;                                 << 
186   }                                            << 
187   else {                                       << 
188     B = 183.;                                  << 
189     Dn = 1.54 * nist->GetA27(Z);               << 
190   }                                            << 
191   Zthird = 1. / nist->GetZ13(Z);  // Z**(-1/3) << 
192   Winfty = B * Zthird * Mmuon / (Dn * electron << 
193   WMedAppr = 1. / (4. * Dn * sqrte * Mmuon);   << 
194   Wsatur = Winfty / WMedAppr;                  << 
195   sigfac = 4. * fine_structure_const * Z * Z * << 
196   PowThres = 1.479 + 0.00799 * Dn;             << 
197   Ecor = -18. + 4347. / (B * Zthird);          << 
198                                                << 
199   G4double CorFuc = 1. + .04 * G4Log(1. + Ecor << 
200   G4double Eg =                                << 
201     G4Exp(G4Log(1. - 4. * Mmuon / Egam) * PowT << 
202     * G4Exp(G4Log(G4Exp(G4Log(Wsatur) * PowSat << 
203                                                   158 
204   G4double CrossSection = 7. / 9. * sigfac * G << 159   static G4double EgamLast=0,Zlast=0,PowThres,Ecor,B,Dn,Zthird,Winfty,WMedAppr,
205   CrossSection *= CrossSecFactor;  // increase << 160       Wsatur,sigfac;
                                                   >> 161   
                                                   >> 162   if(Zlast==Z && Egam==EgamLast) return CrossSection; // already calculated
                                                   >> 163   EgamLast=Egam;
                                                   >> 164   
                                                   >> 165   if(Zlast!=Z) // new element
                                                   >> 166   { Zlast=Z;
                                                   >> 167     if(Z==1) // special case of Hydrogen
                                                   >> 168     { B=202.4;
                                                   >> 169       Dn=1.49;
                                                   >> 170     }
                                                   >> 171     else
                                                   >> 172     { B=183.;
                                                   >> 173       Dn=1.54*pow(A,0.27);
                                                   >> 174     }
                                                   >> 175     Zthird=pow(Z,-1./3.); // Z**(-1/3)
                                                   >> 176     Winfty=B*Zthird*Mmuon/(Dn*Mele);
                                                   >> 177     WMedAppr=1./(4.*Dn*sqrte*Mmuon);
                                                   >> 178     Wsatur=Winfty/WMedAppr;
                                                   >> 179     sigfac=4.*fine_structure_const*Z*Z*Rc*Rc;
                                                   >> 180     PowThres=1.479+0.00799*Dn;
                                                   >> 181     Ecor=-18.+4347./(B*Zthird);
                                                   >> 182   }
                                                   >> 183   G4double CorFuc=1.+.04*log(1.+Ecor/Egam);
                                                   >> 184   G4double Eg=pow(1.-4.*Mmuon/Egam,PowThres)*pow( pow(Wsatur,PowSat)+
                                                   >> 185               pow(Egam,PowSat),1./PowSat); // threshold and saturation
                                                   >> 186   CrossSection=7./9.*sigfac*log(1.+WMedAppr*CorFuc*Eg);
                                                   >> 187   CrossSection*=CrossSecFactor; // increase the CrossSection by  (by default 1)
206   return CrossSection;                            188   return CrossSection;
207 }                                                 189 }
208                                                   190 
209 //....oooOO0OOooo........oooOO0OOooo........oo    191 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
210                                                   192 
211 void G4GammaConversionToMuons::SetCrossSecFact    193 void G4GammaConversionToMuons::SetCrossSecFactor(G4double fac)
212 // Set the factor to artificially increase the    194 // Set the factor to artificially increase the cross section
213 {                                              << 195 { CrossSecFactor=fac;
214   if (fac < 0.0) return;                       << 196   G4cout << "The cross section for GammaConversionToMuons is artificially "
215   CrossSecFactor = fac;                        << 197          << "increased by the CrossSecFactor=" << CrossSecFactor << G4endl;
216   if (verboseLevel > 1) {                      << 
217     G4cout << "The cross section for GammaConv << 
218            << "increased by the CrossSecFactor << 
219   }                                            << 
220 }                                                 198 }
221                                                   199 
222 //....oooOO0OOooo........oooOO0OOooo........oo    200 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
223                                                   201 
224 G4VParticleChange* G4GammaConversionToMuons::P    202 G4VParticleChange* G4GammaConversionToMuons::PostStepDoIt(
225                                                   203                                                         const G4Track& aTrack,
226                                                   204                                                         const G4Step&  aStep)
227 //                                                205 //
228 // generation of gamma->mu+mu-                    206 // generation of gamma->mu+mu-
229 //                                                207 //
230 {                                                 208 {
231   aParticleChange.Initialize(aTrack);             209   aParticleChange.Initialize(aTrack);
232   const G4Material* aMaterial = aTrack.GetMate << 210   G4Material* aMaterial = aTrack.GetMaterial();
                                                   >> 211 
                                                   >> 212   static const G4double Mmuon=G4MuonPlus::MuonPlus()->GetPDGMass();
                                                   >> 213   static const G4double Mele=electron_mass_c2;
                                                   >> 214   static const G4double sqrte=sqrt(exp(1.));
233                                                   215 
234   // current Gamma energy and direction, retur    216   // current Gamma energy and direction, return if energy too low
235   const G4DynamicParticle* aDynamicGamma = aTr << 217   const G4DynamicParticle *aDynamicGamma = aTrack.GetDynamicParticle();
236   G4double Egam = aDynamicGamma->GetKineticEne    218   G4double Egam = aDynamicGamma->GetKineticEnergy();
237   if (Egam <= LowestEnergyLimit) {             << 219   if (Egam < 4*Mmuon) return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
238     return G4VDiscreteProcess::PostStepDoIt(aT << 
239   }                                            << 
240   //                                           << 
241   // Kill the incident photon                  << 
242   //                                           << 
243   aParticleChange.ProposeMomentumDirection( 0. << 
244   aParticleChange.ProposeEnergy( 0. ) ;        << 
245   aParticleChange.ProposeTrackStatus( fStopAnd << 
246                                                << 
247   if (Egam <= Energy5DLimit) {                 << 
248     std::vector<G4DynamicParticle*> fvect;     << 
249     f5Dmodel->SampleSecondaries(&fvect, aTrack << 
250         aTrack.GetDynamicParticle(), 0.0, DBL_ << 
251     for(auto dp : fvect) { aParticleChange.Add << 
252     return G4VDiscreteProcess::PostStepDoIt(aT << 
253   }                                            << 
254                                                << 
255   G4ParticleMomentum GammaDirection = aDynamic    220   G4ParticleMomentum GammaDirection = aDynamicGamma->GetMomentumDirection();
256                                                   221 
257   // select randomly one element constituting     222   // select randomly one element constituting the material
258   const G4Element* anElement = SelectRandomAto << 223   const G4Element& anElement = *SelectRandomAtom(aDynamicGamma, aMaterial);
259   G4int Z = anElement->GetZasInt();            << 224   G4double Z = anElement.GetZ();
260   G4NistManager* nist = G4NistManager::Instanc << 225   G4double A = anElement.GetA()/(g/mole);
261                                                << 226 
262   G4double B, Dn;                              << 227   static G4double Zlast=0,B,Dn,Zthird,Winfty,A027,C1Num2,C2Term2;
263   G4double A027 = nist->GetA27(Z);             << 228   if(Zlast!=Z) // the element has changed
264                                                << 229   { Zlast=Z;
265   if (Z == 1) {  // special case of Hydrogen   << 230     if(Z==1) // special case of Hydrogen
266     B = 202.4;                                 << 231     { B=202.4;
267     Dn = 1.49;                                 << 232       Dn=1.49;
268   }                                            << 233     }
269   else {                                       << 234     else
270     B = 183.;                                  << 235     { B=183.;
271     Dn = 1.54 * A027;                          << 236       Dn=1.54*pow(A,0.27);
                                                   >> 237     }
                                                   >> 238     Zthird=pow(Z,-1./3.); // Z**(-1/3)
                                                   >> 239     Winfty=B*Zthird*Mmuon/(Dn*Mele);
                                                   >> 240     A027=pow(A,0.27);
                                                   >> 241     G4double C1Num=0.35*A027;
                                                   >> 242     C1Num2=C1Num*C1Num;
                                                   >> 243     C2Term2=Mele/(183.*Zthird*Mmuon);
272   }                                               244   }
273   G4double Zthird = 1. / nist->GetZ13(Z);  //  << 
274   G4double Winfty = B * Zthird * Mmuon / (Dn * << 
275                                                << 
276   G4double C1Num = 0.138 * A027;               << 
277   G4double C1Num2 = C1Num * C1Num;             << 
278   G4double C2Term2 = electron_mass_c2 / (183.  << 
279                                                   245 
280   G4double GammaMuonInv = Mmuon / Egam;        << 246   G4double GammaMuonInv=Mmuon/Egam;
                                                   >> 247   G4double sqrtx=sqrt(.25-GammaMuonInv);
                                                   >> 248   G4double xmax=.5+sqrtx;
                                                   >> 249   G4double xmin=.5-sqrtx;
281                                                   250 
282   // generate xPlus according to the different    251   // generate xPlus according to the differential cross section by rejection
283   G4double xmin = (Egam <= LimitEnergy) ? 0.5  << 252   G4double Ds2=(Dn*sqrte-2.);
284   G4double xmax = 1. - xmin;                   << 253   G4double sBZ=sqrte*B*Zthird/Mele;
285                                                << 254   G4double LogWmaxInv=1./log(Winfty*(1.+2.*Ds2*GammaMuonInv)
286   G4double Ds2 = (Dn * sqrte - 2.);            << 255                              /(1.+2.*sBZ*Mmuon*GammaMuonInv));
287   G4double sBZ = sqrte * B * Zthird / electron << 256   G4double xPlus,xMinus,xPM,result,W;
288   G4double LogWmaxInv =                        << 257   do
289     1. / G4Log(Winfty * (1. + 2. * Ds2 * Gamma << 258   { xPlus=xmin+G4UniformRand()*(xmax-xmin);
290   G4double xPlus = 0.5;                        << 259     xMinus=1.-xPlus;
291   G4double xMinus = 0.5;                       << 260     xPM=xPlus*xMinus;
292   G4double xPM = 0.25;                         << 261     G4double del=Mmuon*Mmuon/(2.*Egam*xPM);
293                                                << 262     W=Winfty*(1.+Ds2*del/Mmuon)/(1.+sBZ*del);
294   G4int nn = 0;                                << 263     if(W<1.) W=1.; // to avoid negative cross section at xmin
295   const G4int nmax = 1000;                     << 264     G4double xxp=1.-4./3.*xPM; // the main xPlus dependence
296                                                << 265     result=xxp*log(W)*LogWmaxInv;
297   // sampling for Egam > LimitEnergy           << 266     if(result>1.) {
298   if (xmin < 0.5) {                            << 267       G4cout << "G4GammaConversionToMuons::PostStepDoIt WARNING:"
299     G4double result, W;                        << 268        << " in dSigxPlusGen, result=" << result << " > 1" << G4endl;
300     do {                                       << 
301       xPlus = xmin + G4UniformRand() * (xmax - << 
302       xMinus = 1. - xPlus;                     << 
303       xPM = xPlus * xMinus;                    << 
304       G4double del = Mmuon * Mmuon / (2. * Ega << 
305       W = Winfty * (1. + Ds2 * del / Mmuon) /  << 
306       G4double xxp = 1. - 4. / 3. * xPM;  // t << 
307       result = (xxp > 0.) ? xxp * G4Log(W) * L << 
308       if (result > 1.) {                       << 
309         G4cout << "G4GammaConversionToMuons::P << 
310                << " in dSigxPlusGen, result="  << 
311       }                                        << 
312       ++nn;                                    << 
313       if(nn >= nmax) { break; }                << 
314     }                                             269     }
315     // Loop checking, 07-Aug-2015, Vladimir Iv << 
316     while (G4UniformRand() > result);          << 
317   }                                               270   }
                                                   >> 271   while (G4UniformRand() > result);
318                                                   272 
319   // now generate the angular variables via th    273   // now generate the angular variables via the auxilary variables t,psi,rho
320   G4double t;                                     274   G4double t;
321   G4double psi;                                   275   G4double psi;
322   G4double rho;                                   276   G4double rho;
323                                                   277 
324   G4double a3 = (GammaMuonInv / (2. * xPM));   << 
325   G4double a33 = a3 * a3;                      << 
326   G4double f1;                                 << 
327   G4double b1  = 1./(4.*C1Num2);               << 
328   G4double b3  = b1*b1*b1;                     << 
329   G4double a21 = a33 + b1;                     << 
330                                                << 
331   G4double f1_max=-(1.-xPM)*(2.*b1+(a21+a33)*G << 
332                                                << 
333   G4double thetaPlus,thetaMinus,phiHalf; // fi    278   G4double thetaPlus,thetaMinus,phiHalf; // final angular variables
334   nn = 0;                                      << 279 
335   // t, psi, rho generation start  (while angl << 280   do      // t, psi, rho generation start  (while angle < pi)
336   do {                                         << 281   {
337     //generate t by the rejection method          282     //generate t by the rejection method
338     do {                                       << 283     G4double C1=C1Num2* GammaMuonInv/xPM;
339       ++nn;                                    << 284     G4double f1_max=(1.-xPM) / (1.+C1);
340       t=G4UniformRand();                       << 285     G4double f1; // the probability density
341       G4double a34=a33/(t*t);                  << 286     do
342       G4double a22 = a34 + b1;                 << 287     { t=G4UniformRand();
343       if(std::abs(b1)<0.0001*a34) {            << 288       f1=(1.-2.*xPM+4.*xPM*t*(1.-t)) / (1.+C1/(t*t));
344         // special case of a34=a22 because of  << 289       if(f1<0 || f1> f1_max) // should never happend
345         f1=(1.-2.*xPM+4.*xPM*t*(1.-t))/(12.*a3 << 290   {
346       }                                        << 291     G4cout << "G4GammaConversionToMuons::PostStepDoIt WARNING:"
347       else {                                   << 292      << "outside allowed range f1=" << f1 << " is set to zero"
348         f1=-(1.-2.*xPM+4.*xPM*t*(1.-t))*(2.*b1 << 293      << G4endl;
349       }                                        << 294           f1 = 0.0;
350       if (f1 < 0.0 || f1 > f1_max) {  // shoul << 295   }
351         G4cout << "G4GammaConversionToMuons::P << 296     }
352         << "outside allowed range f1=" << f1   << 297     while ( G4UniformRand()*f1_max > f1);
353         << " is set to zero, a34 = "<< a34 <<  << 
354         << G4endl;                             << 
355         f1 = 0.0;                              << 
356       }                                        << 
357       if(nn > nmax) { break; }                 << 
358       // Loop checking, 07-Aug-2015, Vladimir  << 
359     } while ( G4UniformRand()*f1_max > f1);    << 
360     // generate psi by the rejection method       298     // generate psi by the rejection method
361     G4double f2_max=1.-2.*xPM*(1.-4.*t*(1.-t))    299     G4double f2_max=1.-2.*xPM*(1.-4.*t*(1.-t));
                                                   >> 300 
362     // long version                               301     // long version
363     G4double f2;                                  302     G4double f2;
364     do {                                       << 303     do
365       ++nn;                                    << 304     { psi=2.*pi*G4UniformRand();
366       psi=twopi*G4UniformRand();               << 305       f2=1.-2.*xPM+4.*xPM*t*(1.-t)*(1.+cos(2.*psi));
367       f2=1.-2.*xPM+4.*xPM*t*(1.-t)*(1.+std::co << 306       if(f2<0 || f2> f2_max) // should never happend
368       if(f2<0 || f2> f2_max) { // should never << 307   {
369         G4cout << "G4GammaConversionToMuons::P << 308     G4cout << "G4GammaConversionToMuons::PostStepDoIt WARNING:"
370                << "outside allowed range f2="  << 309      << "outside allowed range f2=" << f2 << " is set to zero"
371         f2 = 0.0;                              << 310      << G4endl;
372       }                                        << 311           f2 = 0.0;
373       if(nn >= nmax) { break; }                << 312   }
374       // Loop checking, 07-Aug-2015, Vladimir  << 313     }
375     } while ( G4UniformRand()*f2_max > f2);    << 314     while ( G4UniformRand()*f2_max > f2);
376                                                   315 
377     // generate rho by direct transformation      316     // generate rho by direct transformation
378     G4double C2Term1=GammaMuonInv/(2.*xPM*t);     317     G4double C2Term1=GammaMuonInv/(2.*xPM*t);
379     G4double C22 = C2Term1*C2Term1+C2Term2*C2T << 318     G4double C2=4./sqrt(xPM)*pow(C2Term1*C2Term1+C2Term2*C2Term2,2.);
380     G4double C2=4.*C22*C22/std::sqrt(xPM);     << 319     G4double rhomax=1.9/A027*(1./t-1.);
381     G4double rhomax=(1./t-1.)*1.9/A027;        << 320     G4double beta=log( (C2+pow(rhomax,4.))/C2 );
382     G4double beta=G4Log( (C2+rhomax*rhomax*rho << 321     rho=pow(C2 *( exp(beta*G4UniformRand())-1. ) ,0.25);
383     rho=G4Exp(G4Log(C2 *( G4Exp(beta*G4Uniform << 
384                                                   322 
385     //now get from t and psi the kinematical v    323     //now get from t and psi the kinematical variables
386     G4double u=std::sqrt(1./t-1.);             << 324     G4double u=sqrt(1./t-1.);
387     G4double xiHalf=0.5*rho*std::cos(psi);     << 325     G4double xiHalf=0.5*rho*cos(psi);
388     phiHalf=0.5*rho/u*std::sin(psi);           << 326     phiHalf=0.5*rho/u*sin(psi);
389                                                   327 
390     thetaPlus =GammaMuonInv*(u+xiHalf)/xPlus;     328     thetaPlus =GammaMuonInv*(u+xiHalf)/xPlus;
391     thetaMinus=GammaMuonInv*(u-xiHalf)/xMinus;    329     thetaMinus=GammaMuonInv*(u-xiHalf)/xMinus;
392                                                   330 
393     // protection against infinite loop        << 
394     if(nn > nmax) {                            << 
395       if(std::abs(thetaPlus)>pi) { thetaPlus = << 
396       if(std::abs(thetaMinus)>pi) { thetaMinus << 
397     }                                          << 
398                                                << 
399     // Loop checking, 07-Aug-2015, Vladimir Iv << 
400   } while ( std::abs(thetaPlus)>pi || std::abs    331   } while ( std::abs(thetaPlus)>pi || std::abs(thetaMinus) >pi);
401                                                   332 
402   // now construct the vectors                    333   // now construct the vectors
403   // azimuthal symmetry, take phi0 at random b    334   // azimuthal symmetry, take phi0 at random between 0 and 2 pi
404   G4double phi0=twopi*G4UniformRand();         << 335   G4double phi0=2.*pi*G4UniformRand(); 
405   G4double EPlus=xPlus*Egam;                      336   G4double EPlus=xPlus*Egam;
406   G4double EMinus=xMinus*Egam;                    337   G4double EMinus=xMinus*Egam;
407                                                   338 
408   // mu+ mu- directions for gamma in z-directi    339   // mu+ mu- directions for gamma in z-direction
409   G4ThreeVector MuPlusDirection  ( std::sin(th << 340   G4ThreeVector MuPlusDirection  ( sin(thetaPlus) *cos(phi0+phiHalf),
410                    std::sin(thetaPlus)  *std:: << 341                    sin(thetaPlus)  *sin(phi0+phiHalf), cos(thetaPlus) );
411   G4ThreeVector MuMinusDirection (-std::sin(th << 342   G4ThreeVector MuMinusDirection (-sin(thetaMinus)*cos(phi0-phiHalf),
412                   -std::sin(thetaMinus) *std:: << 343                   -sin(thetaMinus) *sin(phi0-phiHalf), cos(thetaMinus) );
413   // rotate to actual gamma direction             344   // rotate to actual gamma direction
414   MuPlusDirection.rotateUz(GammaDirection);       345   MuPlusDirection.rotateUz(GammaDirection);
415   MuMinusDirection.rotateUz(GammaDirection);      346   MuMinusDirection.rotateUz(GammaDirection);
416                                                << 347   aParticleChange.SetNumberOfSecondaries(2);
417   // create G4DynamicParticle object for the p    348   // create G4DynamicParticle object for the particle1
418   auto aParticle1 = new G4DynamicParticle(theM << 349   G4DynamicParticle* aParticle1= new G4DynamicParticle(
                                                   >> 350                            G4MuonPlus::MuonPlus(),MuPlusDirection,EPlus-Mmuon);
419   aParticleChange.AddSecondary(aParticle1);       351   aParticleChange.AddSecondary(aParticle1);
420   // create G4DynamicParticle object for the p    352   // create G4DynamicParticle object for the particle2
421   auto aParticle2 = new G4DynamicParticle(theM << 353   G4DynamicParticle* aParticle2= new G4DynamicParticle(
                                                   >> 354                        G4MuonMinus::MuonMinus(),MuMinusDirection,EMinus-Mmuon);
422   aParticleChange.AddSecondary(aParticle2);       355   aParticleChange.AddSecondary(aParticle2);
                                                   >> 356   //
                                                   >> 357   // Kill the incident photon
                                                   >> 358   //
                                                   >> 359   aParticleChange.ProposeMomentumDirection( 0., 0., 0. ) ;
                                                   >> 360   aParticleChange.ProposeEnergy( 0. ) ;
                                                   >> 361   aParticleChange.ProposeTrackStatus( fStopAndKill ) ;
423   //  Reset NbOfInteractionLengthLeft and retu    362   //  Reset NbOfInteractionLengthLeft and return aParticleChange
424   return G4VDiscreteProcess::PostStepDoIt( aTr    363   return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
425 }                                                 364 }
426                                                   365 
427 //....oooOO0OOooo........oooOO0OOooo........oo    366 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
428                                                   367 
429 const G4Element* G4GammaConversionToMuons::Sel << 368 G4Element* G4GammaConversionToMuons::SelectRandomAtom(
430       const G4DynamicParticle* aDynamicGamma,  << 369                                         const G4DynamicParticle* aDynamicGamma,
431       const G4Material* aMaterial)             << 370                                               G4Material* aMaterial)
432 {                                                 371 {
433   // select randomly 1 element within the mate    372   // select randomly 1 element within the material, invoked by PostStepDoIt
434                                                   373 
435   const std::size_t NumberOfElements      = aM << 374   const G4int NumberOfElements            = aMaterial->GetNumberOfElements();
436   const G4ElementVector* theElementVector = aM    375   const G4ElementVector* theElementVector = aMaterial->GetElementVector();
437   const G4Element* elm = (*theElementVector)[0 << 376   if (NumberOfElements == 1) return (*theElementVector)[0];
438                                                   377 
439   if (NumberOfElements > 1) {                  << 378   const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
440     G4double e = std::max(aDynamicGamma->GetKi << 379 
441     const G4double* natom = aMaterial->GetVecN << 380   G4double PartialSumSigma = 0. ;
442                                                << 381   G4double rval = G4UniformRand()/MeanFreePath;
443     G4double sum = 0.;                         << 382 
444     for (std::size_t i=0; i<NumberOfElements;  << 383 
445       elm = (*theElementVector)[i];            << 384   for ( G4int i=0 ; i < NumberOfElements ; i++ )
446       sum += natom[i]*ComputeCrossSectionPerAt << 385       { PartialSumSigma += NbOfAtomsPerVolume[i] *
447       temp[i] = sum;                           << 386                  GetCrossSectionPerAtom(aDynamicGamma, (*theElementVector)[i]);
448     }                                          << 387         if (rval <= PartialSumSigma) return ((*theElementVector)[i]);
449     sum *= G4UniformRand();                    << 
450     for (std::size_t i=0; i<NumberOfElements;  << 
451       if(sum <= temp[i]) {                     << 
452         elm = (*theElementVector)[i];          << 
453         break;                                 << 
454       }                                           388       }
455     }                                          << 389   G4cout << " WARNING !!! - The Material '"<< aMaterial->GetName()
456   }                                            << 390        << "' has no elements, NULL pointer returned." << G4endl;
457   return elm;                                  << 391   return NULL;
458 }                                                 392 }
459                                                   393 
460 //....oooOO0OOooo........oooOO0OOooo........oo    394 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
461                                                   395 
462 void G4GammaConversionToMuons::PrintInfoDefini    396 void G4GammaConversionToMuons::PrintInfoDefinition()
463 {                                                 397 {
464   G4String comments = "gamma->mu+mu- Bethe Hei << 398   G4String comments ="gamma->mu+mu- Bethe Heitler process, SubType= ";
465   G4cout << G4endl << GetProcessName() << ":   << 399   G4cout << G4endl << GetProcessName() << ":  " << comments
                                                   >> 400    << GetProcessSubType() << G4endl;
466   G4cout << "        good cross section parame    401   G4cout << "        good cross section parametrization from "
467          << G4BestUnit(LowestEnergyLimit, "Ene << 402          << G4BestUnit(LowestEnergyLimit,"Energy")
468          << " GeV for all Z." << G4endl;       << 403          << " to " << HighestEnergyLimit/GeV << " GeV for all Z." << G4endl;
469   G4cout << "        cross section factor: " < << 
470 }                                                 404 }
471                                                   405 
472 //....oooOO0OOooo........oooOO0OOooo........oo    406 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
473                                                   407