Geant4 Cross Reference

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

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

Diff markup

Differences between /processes/electromagnetic/standard/src/G4hIonisation.cc (Version 11.3.0) and /processes/electromagnetic/standard/src/G4hIonisation.cc (Version 3.0)


                                                   >>   1 // This code implementation is the intellectual property of
                                                   >>   2 // the GEANT4 collaboration.
  1 //                                                  3 //
  2 // ******************************************* <<   4 // By copying, distributing or modifying the Program (or any work
  3 // * License and Disclaimer                    <<   5 // based on the Program) you indicate your acceptance of this statement,
  4 // *                                           <<   6 // and all its terms.
  5 // * The  Geant4 software  is  copyright of th << 
  6 // * the Geant4 Collaboration.  It is provided << 
  7 // * conditions of the Geant4 Software License << 
  8 // * LICENSE and available at  http://cern.ch/ << 
  9 // * include a list of copyright holders.      << 
 10 // *                                           << 
 11 // * Neither the authors of this software syst << 
 12 // * institutes,nor the agencies providing fin << 
 13 // * work  make  any representation or  warran << 
 14 // * regarding  this  software system or assum << 
 15 // * use.  Please see the license in the file  << 
 16 // * for the full disclaimer and the limitatio << 
 17 // *                                           << 
 18 // * This  code  implementation is the result  << 
 19 // * technical work of the GEANT4 collaboratio << 
 20 // * By using,  copying,  modifying or  distri << 
 21 // * any work based  on the software)  you  ag << 
 22 // * use  in  resulting  scientific  publicati << 
 23 // * acceptance of all terms of the Geant4 Sof << 
 24 // ******************************************* << 
 25 //                                                  7 //
 26 // ------------------------------------------- <<   8 // $Id: G4hIonisation.cc,v 1.12 2000/08/10 22:13:01 vnivanch Exp $
                                                   >>   9 // GEANT4 tag $Name: geant4-03-00 $
 27 //                                                 10 //
 28 // GEANT4 Class file                           <<  11 // -------------------------------------------------------------
                                                   >>  12 //      GEANT 4 class implementation file 
 29 //                                                 13 //
 30 //                                             <<  14 //      For information related to this code contact:
 31 // File name:     G4hIonisation                <<  15 //      CERN, IT Division, ASD group
 32 //                                             <<  16 //      History: based on object model of
 33 // Author:        Laszlo Urban                 <<  17 //      2nd December 1995, G.Cosmo
 34 //                                             <<  18 //      ---------- G4hIonisation physics process -----------
 35 // Creation date: 30.05.1997                   <<  19 //                by Laszlo Urban, 30 May 1997 
 36 //                                             <<  20 // **************************************************************
 37 // Modified by Laszlo Urban, Michel Maire and  <<  21 // It is the first implementation of the NEW IONISATION PROCESS.
 38 //                                             <<  22 // It calculates the ionisation of charged hadrons.
 39 // ------------------------------------------- <<  23 // **************************************************************
 40 //                                             <<  24 // corrected by L.Urban on 24/09/97
 41 //....oooOO0OOooo........oooOO0OOooo........oo <<  25 // several bugs corrected by L.Urban on 13/01/98
 42 //....oooOO0OOooo........oooOO0OOooo........oo <<  26 // 07-04-98: remove 'tracking cut' of the ionizing particle, MMa
                                                   >>  27 // 22/10/98: cleanup L.Urban
                                                   >>  28 // 02/02/99: bugs fixed , L.Urban
                                                   >>  29 // 29/07/99: correction in BuildLossTable for low energy, L.Urban
                                                   >>  30 // 10/02/00  modifications , new e.m. structure, L.Urban
                                                   >>  31 // 10/08/00 : V.Ivanchenko change BuildLambdaTable, in order to 
                                                   >>  32 //            simulate energy losses of ions; correction to
                                                   >>  33 //            cross section for particles with spin 1 is inserted
                                                   >>  34 //            as well
                                                   >>  35 // --------------------------------------------------------------
                                                   >>  36  
 43                                                    37 
 44 #include "G4hIonisation.hh"                        38 #include "G4hIonisation.hh"
 45 #include "G4PhysicalConstants.hh"              <<  39 #include "G4UnitsTable.hh"
 46 #include "G4SystemOfUnits.hh"                  << 
 47 #include "G4Electron.hh"                       << 
 48 #include "G4Proton.hh"                         << 
 49 #include "G4AntiProton.hh"                     << 
 50 #include "G4BraggModel.hh"                     << 
 51 #include "G4BetheBlochModel.hh"                << 
 52 #include "G4EmStandUtil.hh"                    << 
 53 #include "G4PionPlus.hh"                       << 
 54 #include "G4PionMinus.hh"                      << 
 55 #include "G4KaonPlus.hh"                       << 
 56 #include "G4KaonMinus.hh"                      << 
 57 #include "G4ICRU73QOModel.hh"                  << 
 58 #include "G4EmParameters.hh"                   << 
 59                                                << 
 60 //....oooOO0OOooo........oooOO0OOooo........oo << 
 61                                                    40 
 62 G4hIonisation::G4hIonisation(const G4String& n <<  41 G4double G4hIonisation::LowerBoundLambda = 1.*keV ;
 63   : G4VEnergyLossProcess(name)                 <<  42 G4double G4hIonisation::UpperBoundLambda = 100.*TeV ;
                                                   >>  43 G4int  G4hIonisation::NbinLambda = 100 ;
                                                   >>  44 
                                                   >>  45 G4double G4hIonisation::Tmincut = 1.*keV  ;
                                                   >>  46 
                                                   >>  47 // constructor and destructor
                                                   >>  48  
                                                   >>  49 G4hIonisation::G4hIonisation(const G4String& processName)
                                                   >>  50    : G4VhEnergyLoss(processName),
                                                   >>  51      theMeanFreePathTable(NULL),
                                                   >>  52      theProton (G4Proton::Proton()),
                                                   >>  53      theAntiProton (G4AntiProton::AntiProton()),
                                                   >>  54      theElectron ( G4Electron::Electron() )
                                                   >>  55 { }
                                                   >>  56      
                                                   >>  57 G4hIonisation::~G4hIonisation() 
 64 {                                                  58 {
 65   SetProcessSubType(fIonisation);              <<  59      if (theMeanFreePathTable) {
 66   SetSecondaryParticle(G4Electron::Electron()) <<  60         theMeanFreePathTable->clearAndDestroy();
 67   eth = 2*CLHEP::MeV;                          <<  61         delete theMeanFreePathTable;
                                                   >>  62      }
 68 }                                                  63 }
                                                   >>  64  
                                                   >>  65 // methods.............................................
 69                                                    66 
 70 //....oooOO0OOooo........oooOO0OOooo........oo <<  67 void G4hIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
 71                                                <<  68 //  just call BuildLossTable+BuildLambdaTable
 72 G4bool G4hIonisation::IsApplicable(const G4Par << 
 73 {                                                  69 {
 74   return true;                                 <<  70     // get bining from EnergyLoss
 75 }                                              <<  71     LowestKineticEnergy  = GetLowerBoundEloss() ;
                                                   >>  72     HighestKineticEnergy = GetUpperBoundEloss() ;
                                                   >>  73     TotBin               = GetNbinEloss() ;
 76                                                    74 
 77 //....oooOO0OOooo........oooOO0OOooo........oo << 
 78                                                    75 
 79 G4double G4hIonisation::MinPrimaryEnergy(const <<  76   ParticleMass = aParticleType.GetPDGMass() ;
 80            const G4Material*,                  << 
 81            G4double cut)                       << 
 82 {                                              << 
 83   G4double x = 0.5*cut/electron_mass_c2;       << 
 84   G4double gam = x*ratio + std::sqrt((1. + x)* << 
 85   return mass*(gam - 1.0);                     << 
 86 }                                              << 
 87                                                    77 
 88 //....oooOO0OOooo........oooOO0OOooo........oo <<  78   Charge = (aParticleType.GetPDGCharge())/eplus;
 89                                                    79 
 90 void G4hIonisation::InitialiseEnergyLossProces <<  80   G4double ElectronCutInRange = G4Electron::Electron()->GetCuts(); 
 91         const G4ParticleDefinition* part,      <<  81 
 92         const G4ParticleDefinition* bpart)     <<  82   DeltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
                                                   >>  83 
                                                   >>  84   if(Charge>0.)
                                                   >>  85   {
                                                   >>  86     if( (ptableElectronCutInRange != ElectronCutInRange)  
                                                   >>  87                        || (theDEDXpTable == NULL))
                                                   >>  88     {
                                                   >>  89       BuildLossTable(aParticleType) ;
                                                   >>  90       RecorderOfpProcess[CounterOfpProcess] = theLossTable ;
                                                   >>  91       CounterOfpProcess++;
                                                   >>  92     }
                                                   >>  93   }
                                                   >>  94   else
                                                   >>  95   {
                                                   >>  96     if( (pbartableElectronCutInRange != ElectronCutInRange)  
                                                   >>  97                         || (theDEDXpbarTable == NULL))
                                                   >>  98     {
                                                   >>  99       BuildLossTable(aParticleType) ;
                                                   >> 100       RecorderOfpbarProcess[CounterOfpbarProcess] = theLossTable ;
                                                   >> 101       CounterOfpbarProcess++;
                                                   >> 102     }
                                                   >> 103   }
                                                   >> 104  
                                                   >> 105   BuildLambdaTable(aParticleType) ;
                                                   >> 106 
                                                   >> 107   BuildDEDXTable(aParticleType) ;
                                                   >> 108 
                                                   >> 109   if(&aParticleType == G4Proton::Proton())
                                                   >> 110     PrintInfoDefinition();
                                                   >> 111 
                                                   >> 112 }
                                                   >> 113 
                                                   >> 114 void G4hIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
 93 {                                                 115 {
 94   if(!isInitialised) {                         << 116   // cuts for  electron ....................
                                                   >> 117   DeltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
 95                                                   118 
 96     const G4ParticleDefinition* theBaseParticl << 119   G4double LowEdgeEnergy , ionloss ;
 97     G4String pname = part->GetParticleName();  << 120   G4double deltaloss ;
 98     G4double q = part->GetPDGCharge();         << 121   G4double  RateMass ;
                                                   >> 122   G4bool isOutRange ;
                                                   >> 123   static const G4MaterialTable* theMaterialTable=
                                                   >> 124                                    G4Material::GetMaterialTable();
                                                   >> 125   const G4double twoln10 = 2.*log(10.) ;
                                                   >> 126   const G4double Factor = twopi_mc2_rcl2 ;
                                                   >> 127   const G4double bg2lim = 0.0169 , taulim = 8.4146e-3 ;
                                                   >> 128 
                                                   >> 129   RateMass = electron_mass_c2/proton_mass_c2 ;
                                                   >> 130 
                                                   >> 131   //  create table
                                                   >> 132 
                                                   >> 133   G4int numOfMaterials = theMaterialTable->length();
                                                   >> 134 
                                                   >> 135   if ( theLossTable) {
                                                   >> 136      theLossTable->clearAndDestroy();
                                                   >> 137      delete theLossTable;
                                                   >> 138   }
                                                   >> 139   theLossTable = new G4PhysicsTable(numOfMaterials);
 99                                                   140 
100     //G4cout << " G4hIonisation::InitialiseEne << 141   //  loop for materials
101     //   << "  " << bpart << G4endl;           << 
102                                                   142 
103     // define base particle                    << 143   for (G4int J=0; J<numOfMaterials; J++)
104     if(part == bpart) {                        << 144   {
105       theBaseParticle = nullptr;               << 
106     } else if(nullptr != bpart) {              << 
107       theBaseParticle = bpart;                 << 
108                                                   145 
109     } else if(pname == "proton" || pname == "a << 146     // create physics vector and fill it
110         pname == "pi+" || pname == "pi-" ||    << 
111         pname == "kaon+" || pname == "kaon-" | << 
112         pname == "GenericIon" || pname == "alp << 
113       // no base particles                     << 
114       theBaseParticle = nullptr;               << 
115                                                   147 
116     } else {                                   << 148     G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
117       // select base particle                  << 149                     LowestKineticEnergy, HighestKineticEnergy, TotBin);
118       if(part->GetPDGSpin() == 0.0) {          << 150  
119   if(q > 0.0) { theBaseParticle = G4KaonPlus:: << 151     // get material parameters needed for the energy loss calculation
120   else { theBaseParticle = G4KaonMinus::KaonMi << 152 
121       } else {                                 << 153     G4double ElectronDensity,Eexc,Eexc2,Cden,Mden,Aden,X0den,X1den,taul ;
122   if(q > 0.0) { theBaseParticle = G4Proton::Pr << 154     G4double* ShellCorrectionVector;
123   else { theBaseParticle = G4AntiProton::AntiP << 155    
                                                   >> 156     const G4Material* material= (*theMaterialTable)[J];
                                                   >> 157 
                                                   >> 158     ElectronDensity = material->GetElectronDensity();
                                                   >> 159     Eexc = material->GetIonisation()->GetMeanExcitationEnergy();
                                                   >> 160     Eexc2 = Eexc*Eexc ;
                                                   >> 161     Cden = material->GetIonisation()->GetCdensity();
                                                   >> 162     Mden = material->GetIonisation()->GetMdensity();
                                                   >> 163     Aden = material->GetIonisation()->GetAdensity();
                                                   >> 164     X0den = material->GetIonisation()->GetX0density();
                                                   >> 165     X1den = material->GetIonisation()->GetX1density();
                                                   >> 166     taul = material->GetIonisation()->GetTaul() ;
                                                   >> 167     ShellCorrectionVector = material->GetIonisation()->
                                                   >> 168                                           GetShellCorrectionVector();
                                                   >> 169 
                                                   >> 170     // get elements in the actual material,
                                                   >> 171     // they are needed for the low energy part ....
                                                   >> 172 
                                                   >> 173     const G4ElementVector* theElementVector=
                                                   >> 174                    material->GetElementVector() ;
                                                   >> 175     const G4double* theAtomicNumDensityVector=
                                                   >> 176                    material->GetAtomicNumDensityVector() ;
                                                   >> 177     const G4int NumberOfElements=
                                                   >> 178                    material->GetNumberOfElements() ;
                                                   >> 179  
                                                   >> 180     // get  electron cut in kin. energy for the material
                                                   >> 181 
                                                   >> 182     DeltaCutInKineticEnergyNow = G4std::max(DeltaCutInKineticEnergy[J],Tmincut) ;
                                                   >> 183 
                                                   >> 184     // some local variables -------------------
                                                   >> 185     G4double tau,tau0,Tmax,gamma,bg2,beta2,rcut,delta,x,sh ;
                                                   >> 186 
                                                   >> 187     // now comes the loop for the kinetic energy values*****************
                                                   >> 188 
                                                   >> 189     for (G4int i = 0 ; i < TotBin ; i++)
                                                   >> 190     {
                                                   >> 191       LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
                                                   >> 192       tau = LowEdgeEnergy/proton_mass_c2 ;
                                                   >> 193 
                                                   >> 194       gamma = tau +1. ;
                                                   >> 195       bg2 = tau*(tau+2.) ;
                                                   >> 196       beta2 = bg2/(gamma*gamma) ;
                                                   >> 197       Tmax = 2.*electron_mass_c2*bg2
                                                   >> 198              /(1.+2.*gamma*RateMass+RateMass*RateMass) ;
                                                   >> 199 
                                                   >> 200       if ( tau < taul )
                                                   >> 201       //  low energy part , parametrized energy loss formulae
                                                   >> 202       {
                                                   >> 203         ionloss = 0. ;
                                                   >> 204         deltaloss = 0. ;
                                                   >> 205 
                                                   >> 206         //  loop for the elements in the material
                                                   >> 207         for (G4int iel=0; iel<NumberOfElements; iel++)
                                                   >> 208         {
                                                   >> 209           const G4Element* element = (*theElementVector)(iel);
                                                   >> 210           
                                                   >> 211           if ( tau < element->GetIonisation()->GetTau0())  
                                                   >> 212             ionloss += theAtomicNumDensityVector[iel]
                                                   >> 213                        *( element->GetIonisation()->GetAlow()*sqrt(tau)
                                                   >> 214                        +element->GetIonisation()->GetBlow()*tau) ;
                                                   >> 215           else
                                                   >> 216             ionloss += theAtomicNumDensityVector[iel]
                                                   >> 217                        *  element->GetIonisation()->GetClow()/sqrt(tau) ;
                                                   >> 218         }
                                                   >> 219         if ( DeltaCutInKineticEnergyNow < Tmax)
                                                   >> 220         {
                                                   >> 221           deltaloss = log(Tmax/DeltaCutInKineticEnergyNow)-
                                                   >> 222                       beta2*(1.-DeltaCutInKineticEnergyNow/Tmax) ; 
                                                   >> 223           if(aParticleType.GetPDGSpin() == 0.5)
                                                   >> 224             deltaloss += 0.25*(Tmax-DeltaCutInKineticEnergyNow)*
                                                   >> 225                               (Tmax-DeltaCutInKineticEnergyNow)/
                                                   >> 226                         (LowEdgeEnergy*LowEdgeEnergy+proton_mass_c2*proton_mass_c2) ;
                                                   >> 227             deltaloss *= Factor*ElectronDensity/beta2 ;
                                                   >> 228         }
                                                   >> 229         ionloss -= deltaloss ;
124       }                                           230       }
125     }                                          << 231       else
126     SetBaseParticle(theBaseParticle);          << 232       // high energy part , Bethe-Bloch formula 
                                                   >> 233       {
                                                   >> 234         if ( DeltaCutInKineticEnergyNow < Tmax)
                                                   >> 235           rcut = DeltaCutInKineticEnergyNow/Tmax ;
                                                   >> 236         else
                                                   >> 237           rcut = 1.;
                                                   >> 238 
                                                   >> 239         ionloss = log(2.*electron_mass_c2*bg2*Tmax/Eexc2)
                                                   >> 240                   +log(rcut)-(1.+rcut)*beta2 ;
                                                   >> 241 
                                                   >> 242         // density correction 
                                                   >> 243 
                                                   >> 244         x = log(bg2)/twoln10 ;
                                                   >> 245         if ( x < X0den )
                                                   >> 246           delta = 0. ;
                                                   >> 247         else 
                                                   >> 248         {
                                                   >> 249           delta = twoln10*x - Cden ;
                                                   >> 250           if ( x < X1den )
                                                   >> 251             delta += Aden*pow((X1den-x),Mden) ;
                                                   >> 252         } 
                                                   >> 253 
                                                   >> 254         // shell correction 
                                                   >> 255          
                                                   >> 256         if ( bg2 > bg2lim ) {
                                                   >> 257           sh = 0. ;      
                                                   >> 258           x = 1. ;
                                                   >> 259           for (G4int k=0; k<=2; k++) {
                                                   >> 260             x *= bg2 ;
                                                   >> 261             sh += ShellCorrectionVector[k]/x;
                                                   >> 262           }
                                                   >> 263         }
                                                   >> 264         else {
                                                   >> 265           sh = 0. ;      
                                                   >> 266           x = 1. ;
                                                   >> 267           for (G4int k=0; k<=2; k++) {
                                                   >> 268              x *= bg2lim ;
                                                   >> 269              sh += ShellCorrectionVector[k]/x;
                                                   >> 270           }
                                                   >> 271           sh *= log(tau/taul)/log(taulim/taul) ;     
                                                   >> 272         }
127                                                   273 
128     // model limit defined for protons         << 274         // now you can compute the total ionization loss
129     mass  = part->GetPDGMass();                << 275 
130     ratio = electron_mass_c2/mass;             << 276         ionloss -= delta + sh ;
131     eth   = 2.0*MeV*mass/proton_mass_c2;       << 277         ionloss *= Factor*ElectronDensity/beta2 ;
132                                                << 278 
133     G4EmParameters* param = G4EmParameters::In << 279       }
134     G4double emin = param->MinKinEnergy();     << 280       if ( ionloss <= 0.)
135     G4double emax = param->MaxKinEnergy();     << 281         ionloss = 0. ;
136                                                << 282 
137     // define model of energy loss fluctuation << 283       aVector->PutValue(i,ionloss) ;
138     if (nullptr == FluctModel()) {             << 
139       G4bool ion = (pname == "GenericIon" || p << 
140       SetFluctModel(G4EmStandUtil::ModelOfFluc << 
141     }                                          << 
142                                                   284 
143     if (nullptr == EmModel(0)) {               << 
144       if(q > 0.0) { SetEmModel(new G4BraggMode << 
145       else        { SetEmModel(new G4ICRU73QOM << 
146     }                                          << 
147     // to compute ranges correctly we have to  << 
148     // model even if activation limit is high  << 
149     EmModel(0)->SetLowEnergyLimit(emin);       << 
150                                                << 
151     // high energy limit may be eth or DBL_MAX << 
152     G4double emax1 = (EmModel(0)->HighEnergyLi << 
153     EmModel(0)->SetHighEnergyLimit(emax1);     << 
154     AddEmModel(1, EmModel(0), FluctModel());   << 
155                                                << 
156     // second model is used if the first does  << 
157     if(emax1 < emax) {                         << 
158       if (nullptr == EmModel(1)) { SetEmModel( << 
159       EmModel(1)->SetLowEnergyLimit(emax1);    << 
160                                                << 
161       // for extremely heavy particles upper l << 
162       // should be increased                   << 
163       emax = std::max(emax, eth*10);           << 
164       EmModel(1)->SetHighEnergyLimit(emax);    << 
165       AddEmModel(2, EmModel(1), FluctModel()); << 
166     }                                             285     }
167     isInitialised = true;                      << 286     theLossTable->insert(aVector);
168   }                                               287   }
                                                   >> 288 
169 }                                                 289 }
170                                                   290 
171 //....oooOO0OOooo........oooOO0OOooo........oo << 291 void G4hIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
                                                   >> 292 {
                                                   >> 293   // Build mean free path tables for the delta ray production process
                                                   >> 294   //     tables are built for MATERIALS 
                                                   >> 295 
                                                   >> 296       G4double chargeSquare = Charge*Charge ;
                                                   >> 297       G4double LowEdgeEnergy , Value ,sigma ;
                                                   >> 298       G4bool isOutRange ;
                                                   >> 299       const G4MaterialTable* theMaterialTable=
                                                   >> 300                                          G4Material::GetMaterialTable();
                                                   >> 301 
                                                   >> 302       //create table
                                                   >> 303 
                                                   >> 304       G4int numOfMaterials = theMaterialTable->length();
                                                   >> 305 
                                                   >> 306       if (theMeanFreePathTable) {
                                                   >> 307         theMeanFreePathTable->clearAndDestroy();
                                                   >> 308         delete theMeanFreePathTable;
                                                   >> 309       }
                                                   >> 310 
                                                   >> 311       theMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
                                                   >> 312 
                                                   >> 313   // get electron and particle cuts in kinetic energy
                                                   >> 314 
                                                   >> 315       DeltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
                                                   >> 316  
                                                   >> 317   // loop for materials 
                                                   >> 318 
                                                   >> 319       for (G4int J=0 ; J < numOfMaterials; J++)
                                                   >> 320       { 
                                                   >> 321         //create physics vector then fill it ....
                                                   >> 322 
                                                   >> 323         G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
                                                   >> 324                LowerBoundLambda,UpperBoundLambda,NbinLambda);
                                                   >> 325 
                                                   >> 326   // compute the (macroscopic) cross section first
                                                   >> 327  
                                                   >> 328         const G4Material* material= (*theMaterialTable)[J];
                                                   >> 329         
                                                   >> 330         const G4ElementVector* theElementVector=
                                                   >> 331                          material->GetElementVector() ;
                                                   >> 332         const G4double* theAtomicNumDensityVector =
                                                   >> 333                          material->GetAtomicNumDensityVector();
                                                   >> 334         const G4int NumberOfElements=
                                                   >> 335                          material->GetNumberOfElements() ;
                                                   >> 336  
                                                   >> 337   // get the electron kinetic energy cut for the actual material,
                                                   >> 338   //  it will be used in ComputeMicroscopicCrossSection
                                                   >> 339   // ( it is the SAME for ALL the ELEMENTS in THIS MATERIAL )
                                                   >> 340   //   ------------------------------------------------------
                                                   >> 341 
                                                   >> 342         DeltaCutInKineticEnergyNow =G4std::max(DeltaCutInKineticEnergy[J],Tmincut) ;
                                                   >> 343 
                                                   >> 344 
                                                   >> 345         for ( G4int i = 0 ; i < NbinLambda ; i++ )
                                                   >> 346         {
                                                   >> 347            LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
                                                   >> 348 
                                                   >> 349            sigma = 0. ;
                                                   >> 350            
                                                   >> 351            for (G4int iel=0; iel<NumberOfElements; iel++ )
                                                   >> 352            {
                                                   >> 353              sigma +=  theAtomicNumDensityVector[iel]*
                                                   >> 354                        chargeSquare*
                                                   >> 355                        ComputeMicroscopicCrossSection(aParticleType,
                                                   >> 356                        LowEdgeEnergy,(*theElementVector)(iel)->GetZ() ) ;
                                                   >> 357            }
                                                   >> 358 
                                                   >> 359   // mean free path = 1./macroscopic cross section
                                                   >> 360 
                                                   >> 361            Value = sigma<=0 ? DBL_MAX : 1./sigma ;     
                                                   >> 362 
                                                   >> 363            aVector->PutValue(i, Value) ;
                                                   >> 364         }
                                                   >> 365 
                                                   >> 366 
                                                   >> 367         theMeanFreePathTable->insert(aVector);
                                                   >> 368       }
                                                   >> 369 }
                                                   >> 370 
                                                   >> 371 
                                                   >> 372 G4double G4hIonisation::ComputeMicroscopicCrossSection(
                                                   >> 373                                  const G4ParticleDefinition& aParticleType,
                                                   >> 374                                  G4double KineticEnergy,
                                                   >> 375                                  G4double AtomicNumber)
                                                   >> 376 {
                                                   >> 377   //******************************************************************
                                                   >> 378   // cross section formula is OK for spin=0 and 1/2 only !
                                                   >> 379   // *****************************************************************
                                                   >> 380 
                                                   >> 381   // calculates the microscopic cross section in GEANT4 internal units
                                                   >> 382   //    ( it is called for elements , AtomicNumber = Z )
                                                   >> 383 
                                                   >> 384     G4double TotalEnergy,
                                                   >> 385              betasquare,
                                                   >> 386              MaxKineticEnergyTransfer,TotalCrossSection,tempvar;
                                                   >> 387 
                                                   >> 388     // get particle data ...................................
                                                   >> 389 
                                                   >> 390     TotalEnergy=KineticEnergy + ParticleMass;
                                                   >> 391 
                                                   >> 392     // some kinematics......................
                                                   >> 393 
                                                   >> 394     betasquare = KineticEnergy*(TotalEnergy+ParticleMass)
                                                   >> 395                  /(TotalEnergy*TotalEnergy);
                                                   >> 396     tempvar = ParticleMass+electron_mass_c2;
                                                   >> 397     MaxKineticEnergyTransfer = 2.*electron_mass_c2*KineticEnergy
                                                   >> 398                      *(TotalEnergy+ParticleMass)
                                                   >> 399                      /(tempvar*tempvar+2.*electron_mass_c2*KineticEnergy);
                                                   >> 400 
                                                   >> 401     // now you can calculate the total cross section ------------------
                                                   >> 402 
                                                   >> 403     if( MaxKineticEnergyTransfer > DeltaCutInKineticEnergyNow )
                                                   >> 404     {
                                                   >> 405        tempvar=DeltaCutInKineticEnergyNow/MaxKineticEnergyTransfer;
                                                   >> 406        TotalCrossSection = (1.-tempvar*(1.-betasquare*log(tempvar)))
                                                   >> 407                            /DeltaCutInKineticEnergyNow;
                                                   >> 408 
                                                   >> 409        G4double spin = aParticleType.GetPDGSpin() ;
                                                   >> 410 
                                                   >> 411   // +term for spin=1/2 particle
                                                   >> 412        if(0.5 == spin)
                                                   >> 413        {
                                                   >> 414          TotalCrossSection +=  0.5
                                                   >> 415                        *(MaxKineticEnergyTransfer-DeltaCutInKineticEnergyNow)
                                                   >> 416                        /(TotalEnergy*TotalEnergy);
                                                   >> 417 
                                                   >> 418     // +term for spin=1 particle
                                                   >> 419        } else if( 0.9 < spin )
                                                   >> 420        {
                                                   >> 421          TotalCrossSection += 
                                                   >> 422              -log(tempvar)/(3.0*DeltaCutInKineticEnergyNow) +
                                                   >> 423         (MaxKineticEnergyTransfer - DeltaCutInKineticEnergyNow) * 
                                                   >> 424             ( (5.0+ 1.0/tempvar)*0.25 / (TotalEnergy*TotalEnergy) - 
                                                   >> 425          betasquare / 
                                                   >> 426               (MaxKineticEnergyTransfer * DeltaCutInKineticEnergyNow) 
                                                   >> 427             ) / 3.0 ;
                                                   >> 428        }
                                                   >> 429        TotalCrossSection = twopi_mc2_rcl2 * AtomicNumber
                                                   >> 430                            *TotalCrossSection/betasquare;
                                                   >> 431     }
                                                   >> 432     else
                                                   >> 433        TotalCrossSection= 0. ;
                                                   >> 434 
                                                   >> 435     return TotalCrossSection ;
                                                   >> 436 }
                                                   >> 437  
                                                   >> 438  
                                                   >> 439  
                                                   >> 440 G4VParticleChange* G4hIonisation::PostStepDoIt(
                                                   >> 441                                               const G4Track& trackData,   
                                                   >> 442                                               const G4Step& stepData)         
                                                   >> 443 {
                                                   >> 444   // Units are expressed in GEANT4 internal units.
                                                   >> 445 
                                                   >> 446   const G4DynamicParticle* aParticle ;
                                                   >> 447   G4Material* aMaterial;
                                                   >> 448   G4double KineticEnergy,TotalEnergy,TotalMomentum,
                                                   >> 449            betasquare,MaxKineticEnergyTransfer,
                                                   >> 450            DeltaKineticEnergy,DeltaTotalMomentum,costheta,sintheta,phi,
                                                   >> 451            dirx,diry,dirz,finalKineticEnergy,finalPx,finalPy,finalPz,
                                                   >> 452            x,xc,te2,grej,Psquare,Esquare,summass,rate,grejc,finalMomentum ;
                                                   >> 453 
                                                   >> 454   aParticleChange.Initialize(trackData) ;
                                                   >> 455   aMaterial = trackData.GetMaterial() ;
                                                   >> 456 
                                                   >> 457   aParticle = trackData.GetDynamicParticle() ;
                                                   >> 458 
                                                   >> 459   ParticleMass=aParticle->GetDefinition()->GetPDGMass();
                                                   >> 460   KineticEnergy=aParticle->GetKineticEnergy();
                                                   >> 461   TotalEnergy=KineticEnergy + ParticleMass ;
                                                   >> 462   Psquare=KineticEnergy*(TotalEnergy+ParticleMass) ;
                                                   >> 463   Esquare=TotalEnergy*TotalEnergy ;
                                                   >> 464   summass = ParticleMass + electron_mass_c2 ;    
                                                   >> 465   G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection() ;
                                                   >> 466 
                                                   >> 467   //  get kinetic energy cut for the electron....
                                                   >> 468   DeltaCutInKineticEnergyNow =
                                                   >> 469   G4std::max(DeltaCutInKineticEnergy[aMaterial->GetIndex()],Tmincut);
                                                   >> 470 
                                                   >> 471   // some kinematics......................
                                                   >> 472 
                                                   >> 473   betasquare=Psquare/Esquare ;
                                                   >> 474   MaxKineticEnergyTransfer = 2.*electron_mass_c2*Psquare
                                                   >> 475                       /(summass*summass+2.*electron_mass_c2*KineticEnergy);
                                                   >> 476 
                                                   >> 477   // sampling kinetic energy of the delta ray 
                                                   >> 478 
                                                   >> 479   if( MaxKineticEnergyTransfer <= DeltaCutInKineticEnergyNow )
                                                   >> 480   {
                                                   >> 481     // pathological case (it should not happen ,
                                                   >> 482     // there is no change at all).....
                                                   >> 483 
                                                   >> 484     // return &aParticleChange;
                                                   >> 485     return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
                                                   >> 486   }
                                                   >> 487   else
                                                   >> 488   {
                                                   >> 489    // normal case ......................................
                                                   >> 490       xc=DeltaCutInKineticEnergyNow/MaxKineticEnergyTransfer ;
                                                   >> 491       rate=MaxKineticEnergyTransfer/TotalEnergy ;
                                                   >> 492 
                                                   >> 493      if(aParticle->GetDefinition()->GetPDGSpin() == 1)     
                                                   >> 494        te2=0.5*rate*rate ;
                                                   >> 495      else
                                                   >> 496        te2=0. ;
                                                   >> 497 
                                                   >> 498    // sampling follows ...
                                                   >> 499      grejc=1.-betasquare*xc+te2*xc*xc ;
                                                   >> 500 
                                                   >> 501      do {
                                                   >> 502           x=xc/(1.-(1.-xc)*G4UniformRand());
                                                   >> 503           grej=(1.-x*(betasquare-x*te2))/grejc ;
                                                   >> 504         } while( G4UniformRand()>grej );
                                                   >> 505    }
                                                   >> 506    
                                                   >> 507    DeltaKineticEnergy = x * MaxKineticEnergyTransfer ;
                                                   >> 508 
                                                   >> 509    if(DeltaKineticEnergy <= 0.)
                                                   >> 510      return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
                                                   >> 511 
                                                   >> 512    DeltaTotalMomentum = sqrt(DeltaKineticEnergy * (DeltaKineticEnergy +
                                                   >> 513                                                2. * electron_mass_c2 )) ;
                                                   >> 514    TotalMomentum = sqrt(Psquare) ;
                                                   >> 515    costheta = DeltaKineticEnergy * (TotalEnergy + electron_mass_c2)
                                                   >> 516             /(DeltaTotalMomentum * TotalMomentum) ;
                                                   >> 517 
                                                   >> 518    //  protection against costheta > 1 or < -1   ---------------
                                                   >> 519    if ( costheta < -1. ) 
                                                   >> 520           costheta = -1. ;
                                                   >> 521    if ( costheta > +1. ) 
                                                   >> 522           costheta = +1. ;
                                                   >> 523 
                                                   >> 524    //  direction of the delta electron  ........
                                                   >> 525    phi = twopi * G4UniformRand() ; 
                                                   >> 526    sintheta = sqrt((1.+costheta)*(1.-costheta));
                                                   >> 527    dirx = sintheta * cos(phi) ;
                                                   >> 528    diry = sintheta * sin(phi) ;
                                                   >> 529    dirz = costheta ;
                                                   >> 530 
                                                   >> 531    G4ThreeVector DeltaDirection(dirx,diry,dirz) ;
                                                   >> 532    DeltaDirection.rotateUz(ParticleDirection) ;
                                                   >> 533 
                                                   >> 534    // create G4DynamicParticle object for delta ray
                                                   >> 535    G4DynamicParticle *theDeltaRay = new G4DynamicParticle;
                                                   >> 536    theDeltaRay->SetKineticEnergy( DeltaKineticEnergy );
                                                   >> 537    theDeltaRay->SetMomentumDirection(
                                                   >> 538                    DeltaDirection.x(),DeltaDirection.y(),DeltaDirection.z()); 
                                                   >> 539    theDeltaRay->SetDefinition(G4Electron::Electron());
                                                   >> 540 
                                                   >> 541    // fill aParticleChange 
                                                   >> 542    finalKineticEnergy = KineticEnergy - DeltaKineticEnergy ;
                                                   >> 543    G4double Edep = 0 ;
                                                   >> 544 
                                                   >> 545    if (finalKineticEnergy > MinKineticEnergy)
                                                   >> 546      {
                                                   >> 547       finalPx = TotalMomentum*ParticleDirection.x()
                                                   >> 548                         - DeltaTotalMomentum*DeltaDirection.x();
                                                   >> 549       finalPy = TotalMomentum*ParticleDirection.y()
                                                   >> 550                         - DeltaTotalMomentum*DeltaDirection.y();
                                                   >> 551       finalPz = TotalMomentum*ParticleDirection.z()
                                                   >> 552                         - DeltaTotalMomentum*DeltaDirection.z();
                                                   >> 553       finalMomentum =
                                                   >> 554                 sqrt(finalPx*finalPx+finalPy*finalPy+finalPz*finalPz) ;
                                                   >> 555       finalPx /= finalMomentum ;
                                                   >> 556       finalPy /= finalMomentum ;
                                                   >> 557       finalPz /= finalMomentum ;
                                                   >> 558 
                                                   >> 559       aParticleChange.SetMomentumChange( finalPx,finalPy,finalPz );
                                                   >> 560      }
                                                   >> 561    else
                                                   >> 562      {
                                                   >> 563        finalKineticEnergy = 0. ;
                                                   >> 564        Edep = finalKineticEnergy ;
                                                   >> 565        if (aParticle->GetDefinition()->GetParticleName() == "proton")
                                                   >> 566              aParticleChange.SetStatusChange(fStopAndKill);
                                                   >> 567        else  aParticleChange.SetStatusChange(fStopButAlive);
                                                   >> 568      }
                                                   >> 569 
                                                   >> 570    aParticleChange.SetEnergyChange( finalKineticEnergy );
                                                   >> 571    aParticleChange.SetNumberOfSecondaries(1);   
                                                   >> 572    aParticleChange.AddSecondary( theDeltaRay );
                                                   >> 573    aParticleChange.SetLocalEnergyDeposit (Edep);
                                                   >> 574       
                                                   >> 575    //ResetNumberOfInteractionLengthLeft();
                                                   >> 576   return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
                                                   >> 577 }
172                                                   578 
173 void G4hIonisation::ProcessDescription(std::os << 579 void G4hIonisation::PrintInfoDefinition()
174 {                                                 580 {
175   out << "  Hadron ionisation";                << 581   G4String comments = "  Knock-on electron cross sections . ";
176   G4VEnergyLossProcess::ProcessDescription(out << 582            comments += "\n         Good description above the mean excitation energy.\n";
                                                   >> 583            comments += "         delta ray energy sampled from  differential Xsection.";
                                                   >> 584 
                                                   >> 585   G4cout << G4endl << GetProcessName() << ":  " << comments
                                                   >> 586          << "\n        PhysicsTables from " << G4BestUnit(LowestKineticEnergy,
                                                   >> 587                                                   "Energy")
                                                   >> 588          << " to " << G4BestUnit(HighestKineticEnergy,"Energy")
                                                   >> 589          << " in " << TotBin << " bins. \n";
177 }                                                 590 }
178                                                   591 
179 //....oooOO0OOooo........oooOO0OOooo........oo << 
180                                                   592