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 4.0)


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