Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // 27 // ------------------------------------------- 27 // ------------------------------------------------------------------- 28 // 28 // 29 // GEANT4 Class header file 29 // GEANT4 Class header file 30 // 30 // 31 // 31 // 32 // File name: G4mplIonisationModel 32 // File name: G4mplIonisationModel 33 // 33 // 34 // Author: Vladimir Ivanchenko 34 // Author: Vladimir Ivanchenko 35 // 35 // 36 // Creation date: 06.09.2005 36 // Creation date: 06.09.2005 37 // 37 // 38 // Modifications: 38 // Modifications: 39 // 12.08.2007 Changing low energy approximatio 39 // 12.08.2007 Changing low energy approximation and extrapolation. 40 // Small bug fixing and refactoring 40 // Small bug fixing and refactoring (M. Vladymyrov) 41 // 13.11.2007 Use low-energy asymptotic from [ 41 // 13.11.2007 Use low-energy asymptotic from [3] (V.Ivanchenko) 42 // 42 // 43 // 43 // 44 // ------------------------------------------- 44 // ------------------------------------------------------------------- 45 // References 45 // References 46 // [1] Steven P. Ahlen: Energy loss of relativ 46 // [1] Steven P. Ahlen: Energy loss of relativistic heavy ionizing particles, 47 // S.P. Ahlen, Rev. Mod. Phys 52(1980), p1 47 // S.P. Ahlen, Rev. Mod. Phys 52(1980), p121 48 // [2] K.A. Milton arXiv:hep-ex/0602040 48 // [2] K.A. Milton arXiv:hep-ex/0602040 49 // [3] S.P. Ahlen and K. Kinoshita, Phys. Rev. 49 // [3] S.P. Ahlen and K. Kinoshita, Phys. Rev. D26 (1982) 2347 50 50 51 51 52 //....oooOO0OOooo........oooOO0OOooo........oo 52 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 53 //....oooOO0OOooo........oooOO0OOooo........oo 53 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 54 54 55 #include "G4mplIonisationModel.hh" 55 #include "G4mplIonisationModel.hh" 56 #include "Randomize.hh" 56 #include "Randomize.hh" 57 #include "G4PhysicalConstants.hh" 57 #include "G4PhysicalConstants.hh" 58 #include "G4SystemOfUnits.hh" 58 #include "G4SystemOfUnits.hh" 59 #include "G4ParticleChangeForLoss.hh" 59 #include "G4ParticleChangeForLoss.hh" 60 #include "G4ProductionCutsTable.hh" 60 #include "G4ProductionCutsTable.hh" 61 #include "G4MaterialCutsCouple.hh" 61 #include "G4MaterialCutsCouple.hh" 62 #include "G4Log.hh" 62 #include "G4Log.hh" 63 #include "G4Pow.hh" 63 #include "G4Pow.hh" 64 64 65 //....oooOO0OOooo........oooOO0OOooo........oo 65 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 66 66 >> 67 using namespace std; >> 68 67 std::vector<G4double>* G4mplIonisationModel::d 69 std::vector<G4double>* G4mplIonisationModel::dedx0 = nullptr; 68 70 69 G4mplIonisationModel::G4mplIonisationModel(G4d 71 G4mplIonisationModel::G4mplIonisationModel(G4double mCharge, const G4String& nam) 70 : G4VEmModel(nam),G4VEmFluctuationModel(nam) 72 : G4VEmModel(nam),G4VEmFluctuationModel(nam), 71 magCharge(mCharge), 73 magCharge(mCharge), 72 twoln10(G4Log(100.0)), << 74 twoln10(log(100.0)), 73 betalow(0.01), 75 betalow(0.01), 74 betalim(0.1), 76 betalim(0.1), 75 beta2lim(betalim*betalim), 77 beta2lim(betalim*betalim), 76 bg2lim(beta2lim*(1.0 + beta2lim)) 78 bg2lim(beta2lim*(1.0 + beta2lim)) 77 { 79 { 78 nmpl = G4int(std::abs(magCharge) * 2 * CLHEP << 80 nmpl = G4int(abs(magCharge) * 2 * fine_structure_const + 0.5); 79 if(nmpl > 6) { nmpl = 6; } 81 if(nmpl > 6) { nmpl = 6; } 80 else if(nmpl < 1) { nmpl = 1; } 82 else if(nmpl < 1) { nmpl = 1; } 81 pi_hbarc2_over_mc2 = CLHEP::pi*CLHEP::hbarc* << 83 pi_hbarc2_over_mc2 = pi * hbarc * hbarc / electron_mass_c2; 82 chargeSquare = magCharge * magCharge; 84 chargeSquare = magCharge * magCharge; 83 dedxlim = 45.*nmpl*nmpl*CLHEP::GeV*CLHEP::cm << 85 dedxlim = 45.*nmpl*nmpl*GeV*cm2/g; >> 86 fParticleChange = nullptr; >> 87 monopole = nullptr; >> 88 mass = 0.0; 84 } 89 } 85 90 86 //....oooOO0OOooo........oooOO0OOooo........oo 91 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 87 92 88 G4mplIonisationModel::~G4mplIonisationModel() 93 G4mplIonisationModel::~G4mplIonisationModel() 89 { 94 { 90 if(IsMaster()) { delete dedx0; } 95 if(IsMaster()) { delete dedx0; } 91 } 96 } 92 97 93 //....oooOO0OOooo........oooOO0OOooo........oo 98 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 94 99 95 void G4mplIonisationModel::SetParticle(const G 100 void G4mplIonisationModel::SetParticle(const G4ParticleDefinition* p) 96 { 101 { 97 monopole = p; 102 monopole = p; 98 mass = monopole->GetPDGMass(); 103 mass = monopole->GetPDGMass(); 99 G4double emin = 104 G4double emin = 100 std::min(LowEnergyLimit(),0.1*mass*(1./std << 105 std::min(LowEnergyLimit(),0.1*mass*(1./sqrt(1. - betalow*betalow) - 1.)); 101 G4double emax = 106 G4double emax = 102 std::max(HighEnergyLimit(),10.*mass*(1./st << 107 std::max(HighEnergyLimit(),10.*mass*(1./sqrt(1. - beta2lim) - 1.)); 103 SetLowEnergyLimit(emin); 108 SetLowEnergyLimit(emin); 104 SetHighEnergyLimit(emax); 109 SetHighEnergyLimit(emax); 105 } 110 } 106 111 107 //....oooOO0OOooo........oooOO0OOooo........oo 112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 108 113 109 void G4mplIonisationModel::Initialise(const G4 114 void G4mplIonisationModel::Initialise(const G4ParticleDefinition* p, 110 const G4DataVector&) 115 const G4DataVector&) 111 { 116 { 112 if(nullptr == monopole) { SetParticle(p); } << 117 if(!monopole) { SetParticle(p); } 113 if(nullptr == fParticleChange) { fParticleCh << 118 if(!fParticleChange) { fParticleChange = GetParticleChangeForLoss(); } 114 if(IsMaster()) { 119 if(IsMaster()) { 115 if(nullptr == dedx0) { dedx0 = new std::ve << 120 if(!dedx0) { dedx0 = new std::vector<G4double>; } 116 G4ProductionCutsTable* theCoupleTable= 121 G4ProductionCutsTable* theCoupleTable= 117 G4ProductionCutsTable::GetProductionCuts 122 G4ProductionCutsTable::GetProductionCutsTable(); 118 G4int numOfCouples = (G4int)theCoupleTable << 123 G4int numOfCouples = theCoupleTable->GetTableSize(); 119 G4int n = (G4int)dedx0->size(); << 124 G4int n = dedx0->size(); 120 if(n < numOfCouples) { dedx0->resize(numOf 125 if(n < numOfCouples) { dedx0->resize(numOfCouples); } 121 126 122 G4Pow* g4calc = G4Pow::GetInstance(); 127 G4Pow* g4calc = G4Pow::GetInstance(); 123 128 124 // initialise vector assuming low conducti 129 // initialise vector assuming low conductivity 125 for(G4int i=0; i<numOfCouples; ++i) { 130 for(G4int i=0; i<numOfCouples; ++i) { 126 131 127 const G4Material* material = 132 const G4Material* material = 128 theCoupleTable->GetMaterialCutsCouple( 133 theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial(); 129 G4double eDensity = material->GetElectro 134 G4double eDensity = material->GetElectronDensity(); 130 G4double vF2 = 2*electron_Compton_length 135 G4double vF2 = 2*electron_Compton_length*g4calc->A13(3.*pi*pi*eDensity); 131 (*dedx0)[i] = pi_hbarc2_over_mc2*eDensit 136 (*dedx0)[i] = pi_hbarc2_over_mc2*eDensity*nmpl*nmpl* 132 (G4Log(vF2/fine_structure_const) - 0.5 137 (G4Log(vF2/fine_structure_const) - 0.5)/vF2; 133 } 138 } 134 } 139 } 135 } 140 } 136 141 137 //....oooOO0OOooo........oooOO0OOooo........oo 142 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 138 143 139 G4double G4mplIonisationModel::ComputeDEDXPerV 144 G4double G4mplIonisationModel::ComputeDEDXPerVolume(const G4Material* material, 140 const G4ParticleDefinition* p, 145 const G4ParticleDefinition* p, 141 G4double kineticEnergy, 146 G4double kineticEnergy, 142 G4double) 147 G4double) 143 { 148 { 144 if(nullptr == monopole) { SetParticle(p); } << 149 if(!monopole) { SetParticle(p); } 145 G4double tau = kineticEnergy / mass; 150 G4double tau = kineticEnergy / mass; 146 G4double gam = tau + 1.0; 151 G4double gam = tau + 1.0; 147 G4double bg2 = tau * (tau + 2.0); 152 G4double bg2 = tau * (tau + 2.0); 148 G4double beta2 = bg2 / (gam * gam); 153 G4double beta2 = bg2 / (gam * gam); 149 G4double beta = std::sqrt(beta2); << 154 G4double beta = sqrt(beta2); 150 155 151 // low-energy asymptotic formula 156 // low-energy asymptotic formula 152 //G4double dedx = dedxlim*beta*material->Ge 157 //G4double dedx = dedxlim*beta*material->GetDensity(); 153 G4double dedx = (*dedx0)[CurrentCouple()->Ge 158 G4double dedx = (*dedx0)[CurrentCouple()->GetIndex()]*beta; 154 159 155 // above asymptotic 160 // above asymptotic 156 if(beta > betalow) { 161 if(beta > betalow) { 157 162 158 // high energy 163 // high energy 159 if(beta >= betalim) { 164 if(beta >= betalim) { 160 dedx = ComputeDEDXAhlen(material, bg2); 165 dedx = ComputeDEDXAhlen(material, bg2); 161 166 162 } else { 167 } else { 163 168 164 //G4double dedx1 = dedxlim*betalow*mater 169 //G4double dedx1 = dedxlim*betalow*material->GetDensity(); 165 G4double dedx1 = (*dedx0)[CurrentCouple( 170 G4double dedx1 = (*dedx0)[CurrentCouple()->GetIndex()]*betalow; 166 G4double dedx2 = ComputeDEDXAhlen(materi 171 G4double dedx2 = ComputeDEDXAhlen(material, bg2lim); 167 172 168 // extrapolation between two formula 173 // extrapolation between two formula 169 G4double kapa2 = beta - betalow; 174 G4double kapa2 = beta - betalow; 170 G4double kapa1 = betalim - beta; 175 G4double kapa1 = betalim - beta; 171 dedx = (kapa1*dedx1 + kapa2*dedx2)/(kapa 176 dedx = (kapa1*dedx1 + kapa2*dedx2)/(kapa1 + kapa2); 172 } 177 } 173 } 178 } 174 return dedx; 179 return dedx; 175 } 180 } 176 181 177 //....oooOO0OOooo........oooOO0OOooo........oo 182 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 178 183 179 G4double G4mplIonisationModel::ComputeDEDXAhle 184 G4double G4mplIonisationModel::ComputeDEDXAhlen(const G4Material* material, 180 G4double bg2) 185 G4double bg2) 181 { 186 { 182 G4double eDensity = material->GetElectronDen 187 G4double eDensity = material->GetElectronDensity(); 183 G4double eexc = material->GetIonisation()-> 188 G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy(); 184 G4double cden = material->GetIonisation()-> 189 G4double cden = material->GetIonisation()->GetCdensity(); 185 G4double mden = material->GetIonisation()-> 190 G4double mden = material->GetIonisation()->GetMdensity(); 186 G4double aden = material->GetIonisation()-> 191 G4double aden = material->GetIonisation()->GetAdensity(); 187 G4double x0den = material->GetIonisation()-> 192 G4double x0den = material->GetIonisation()->GetX0density(); 188 G4double x1den = material->GetIonisation()-> 193 G4double x1den = material->GetIonisation()->GetX1density(); 189 194 190 // Ahlen's formula for nonconductors, [1]p15 195 // Ahlen's formula for nonconductors, [1]p157, f(5.7) 191 G4double dedx = std::log(2.0 * electron_mass << 196 G4double dedx = log(2.0 * electron_mass_c2 * bg2 / eexc) - 0.5; 192 197 193 // Kazama et al. cross-section correction 198 // Kazama et al. cross-section correction 194 G4double k = 0.406; 199 G4double k = 0.406; 195 if(nmpl > 1) k = 0.346; 200 if(nmpl > 1) k = 0.346; 196 201 197 // Bloch correction 202 // Bloch correction 198 const G4double B[7] = { 0.0, 0.248, 0.672, 1 203 const G4double B[7] = { 0.0, 0.248, 0.672, 1.022, 1.243, 1.464, 1.685}; 199 204 200 dedx += 0.5 * k - B[nmpl]; 205 dedx += 0.5 * k - B[nmpl]; 201 206 202 // density effect correction 207 // density effect correction 203 G4double deltam; 208 G4double deltam; 204 G4double x = std::log(bg2) / twoln10; << 209 G4double x = log(bg2) / twoln10; 205 if ( x >= x0den ) { 210 if ( x >= x0den ) { 206 deltam = twoln10 * x - cden; 211 deltam = twoln10 * x - cden; 207 if ( x < x1den ) deltam += aden * std::pow << 212 if ( x < x1den ) deltam += aden * pow((x1den-x), mden); 208 dedx -= 0.5 * deltam; 213 dedx -= 0.5 * deltam; 209 } 214 } 210 215 211 // now compute the total ionization loss 216 // now compute the total ionization loss 212 dedx *= pi_hbarc2_over_mc2 * eDensity * nmp 217 dedx *= pi_hbarc2_over_mc2 * eDensity * nmpl * nmpl; 213 218 214 if (dedx < 0.0) dedx = 0.; 219 if (dedx < 0.0) dedx = 0.; 215 return dedx; 220 return dedx; 216 } 221 } 217 222 218 //....oooOO0OOooo........oooOO0OOooo........oo 223 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 219 224 220 void G4mplIonisationModel::SampleSecondaries(s 225 void G4mplIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>*, 221 const G4MaterialCutsCouple*, 226 const G4MaterialCutsCouple*, 222 const G4DynamicParticle*, 227 const G4DynamicParticle*, 223 G4double, 228 G4double, 224 G4double) 229 G4double) 225 {} 230 {} 226 231 227 //....oooOO0OOooo........oooOO0OOooo........oo 232 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 228 233 229 G4double G4mplIonisationModel::SampleFluctuati 234 G4double G4mplIonisationModel::SampleFluctuations( 230 const G4MaterialCutsCouple* cou 235 const G4MaterialCutsCouple* couple, 231 const G4DynamicParticle* dp, 236 const G4DynamicParticle* dp, 232 const G << 237 G4double tmax, 233 const G << 238 G4double length, 234 const G4double length, << 239 G4double meanLoss) 235 const G4double meanLoss) << 236 { 240 { 237 G4double siga = Dispersion(couple->GetMateri << 241 G4double siga = Dispersion(couple->GetMaterial(),dp,tmax,length); 238 G4double loss = meanLoss; 242 G4double loss = meanLoss; 239 siga = std::sqrt(siga); << 243 siga = sqrt(siga); 240 G4double twomeanLoss = meanLoss + meanLoss; 244 G4double twomeanLoss = meanLoss + meanLoss; 241 245 242 if(twomeanLoss < siga) { 246 if(twomeanLoss < siga) { 243 G4double x; 247 G4double x; 244 do { 248 do { 245 loss = twomeanLoss*G4UniformRand(); 249 loss = twomeanLoss*G4UniformRand(); 246 x = (loss - meanLoss)/siga; 250 x = (loss - meanLoss)/siga; 247 // Loop checking, 07-Aug-2015, Vladimir 251 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko 248 } while (1.0 - 0.5*x*x < G4UniformRand()); 252 } while (1.0 - 0.5*x*x < G4UniformRand()); 249 } else { 253 } else { 250 do { 254 do { 251 loss = G4RandGauss::shoot(meanLoss,siga) 255 loss = G4RandGauss::shoot(meanLoss,siga); 252 // Loop checking, 07-Aug-2015, Vladimir 256 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko 253 } while (0.0 > loss || loss > twomeanLoss) 257 } while (0.0 > loss || loss > twomeanLoss); 254 } 258 } 255 return loss; 259 return loss; 256 } 260 } 257 261 258 //....oooOO0OOooo........oooOO0OOooo........oo 262 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 259 263 260 G4double G4mplIonisationModel::Dispersion(cons 264 G4double G4mplIonisationModel::Dispersion(const G4Material* material, 261 const G4DynamicParticle* dp, 265 const G4DynamicParticle* dp, 262 const G4double tcut, << 266 G4double tmax, 263 const G4double tmax, << 267 G4double length) 264 const G4double length) << 265 { 268 { 266 G4double siga = 0.0; 269 G4double siga = 0.0; 267 G4double tau = dp->GetKineticEnergy()/mass 270 G4double tau = dp->GetKineticEnergy()/mass; 268 if(tau > 0.0) { 271 if(tau > 0.0) { 269 const G4double beta = dp->GetBeta(); << 272 G4double electronDensity = material->GetElectronDensity(); 270 siga = (tmax/(beta*beta) - 0.5*tcut) * tw << 273 G4double gam = tau + 1.0; 271 * material->GetElectronDensity() * charg << 274 G4double invbeta2 = (gam*gam)/(tau * (tau+2.0)); >> 275 siga = (invbeta2 - 0.5) * twopi_mc2_rcl2 * tmax * length >> 276 * electronDensity * chargeSquare; 272 } 277 } 273 return siga; 278 return siga; 274 } 279 } 275 280 276 //....oooOO0OOooo........oooOO0OOooo........oo 281 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 277 282