- Timestamp:
- Apr 6, 2009, 12:21:12 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/electromagnetic/standard/src/G4IonFluctuations.cc
r819 r961 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4IonFluctuations.cc,v 1. 5.2.1 2008/04/25 00:22:53vnivanch Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4IonFluctuations.cc,v 1.25 2009/02/19 19:17:50 vnivanch Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // ------------------------------------------------------------------- … … 46 46 // 16-10-03 Changed interface to Initialisation (V.Ivanchenko) 47 47 // 27-09-07 Use FermiEnergy from material, add cut dependence (V.Ivanchenko) 48 // 01-02-08 Add protection for small energies and optimise the code (V.Ivanchenko) 49 // 01-06-08 Added initialisation of effective charge prestep (V.Ivanchenko) 48 50 // 49 51 // Class Description: … … 60 62 #include "G4Material.hh" 61 63 #include "G4DynamicParticle.hh" 62 #include "G4ParticleDefinition.hh"63 64 64 65 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... … … 67 68 68 69 G4IonFluctuations::G4IonFluctuations(const G4String& nam) 69 :G4VEmFluctuationModel(nam), 70 particle(0), 71 minNumberInteractionsBohr(10.0), 72 theBohrBeta2(50.0*keV/proton_mass_c2), 73 minFraction(0.2), 74 xmin(0.2), 75 minLoss(0.001*eV) 70 : G4VEmFluctuationModel(nam), 71 particle(0), 72 particleMass(proton_mass_c2), 73 charge(1.0), 74 chargeSquare(1.0), 75 effChargeSquare(1.0), 76 parameter(10.0*CLHEP::MeV/CLHEP::proton_mass_c2), 77 minNumberInteractionsBohr(0.0), 78 theBohrBeta2(50.0*keV/CLHEP::proton_mass_c2), 79 minFraction(0.2), 80 xmin(0.2), 81 minLoss(0.001*eV) 76 82 {} 77 83 … … 89 95 charge = part->GetPDGCharge()/eplus; 90 96 chargeSquare = charge*charge; 91 chargeSqRatio = 1.0; 97 effChargeSquare= chargeSquare; 98 uniFluct.InitialiseMe(part); 92 99 } 93 100 … … 96 103 G4double G4IonFluctuations::SampleFluctuations(const G4Material* material, 97 104 const G4DynamicParticle* dp, 98 G4double& tmax, 99 G4double& length, 100 G4double& meanLoss) 101 { 105 G4double& tmax, 106 G4double& length, 107 G4double& meanLoss) 108 { 109 // G4cout << "### meanLoss= " << meanLoss << G4endl; 102 110 if(meanLoss <= minLoss) return meanLoss; 103 // G4cout << "### meanLoss= " << meanLoss << G4endl; 111 112 //G4cout << "G4IonFluctuations::SampleFluctuations E(MeV)= " << dp->GetKineticEnergy() 113 // << " Elim(MeV)= " << parameter*charge*particleMass << G4endl; 114 115 // Vavilov fluctuations 116 if(dp->GetKineticEnergy() > parameter*charge*particleMass) { 117 return uniFluct.SampleFluctuations(material,dp,tmax,length,meanLoss); 118 } 104 119 105 120 G4double siga = Dispersion(material,dp,tmax,length); … … 107 122 108 123 G4double navr = minNumberInteractionsBohr; 109 110 124 navr = meanLoss*meanLoss/siga; 111 // 125 //G4cout << "### siga= " << sqrt(siga) << " navr= " << navr << G4endl; 112 126 113 127 // Gaussian fluctuation … … 126 140 // G4cout << "siga= " << siga << G4endl; 127 141 siga = sqrt(siga); 128 129 142 G4double lossmax = meanLoss+meanLoss; 130 do { 131 loss = G4RandGauss::shoot(meanLoss,siga); 132 } while (0.0 > loss || loss > lossmax); 133 143 144 if(siga > 5.0*meanLoss) { 145 loss = lossmax*G4UniformRand(); 146 } else { 147 do { 148 loss = G4RandGauss::shoot(meanLoss,siga); 149 } while (0.0 > loss || loss > lossmax); 150 } 134 151 // Poisson fluctuations 135 152 } else { … … 139 156 } 140 157 141 // 158 //G4cout << "meanLoss= " << meanLoss << " loss= " << loss << G4endl; 142 159 return loss; 143 160 } … … 145 162 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 146 163 147 G4double G4IonFluctuations::Dispersion( 148 const G4Material* material, 149 const G4DynamicParticle* dp, 150 G4double& tmax, 151 G4double& length) 152 { 153 particle = dp->GetDefinition(); 154 charge = particle->GetPDGCharge()/eplus; 155 G4double Q2 = charge*charge; 156 particleMass = particle->GetPDGMass(); 157 G4double q = dp->GetCharge()/eplus; 158 chargeSquare = q*q; 159 chargeSqRatio = chargeSquare/Q2; 160 161 //chargeSquare = charge*charge; 162 //chargeSqRatio = 1.0; 164 G4double G4IonFluctuations::Dispersion(const G4Material* material, 165 const G4DynamicParticle* dp, 166 G4double& tmax, 167 G4double& length) 168 { 169 kineticEnergy = dp->GetKineticEnergy(); 170 G4double etot = kineticEnergy + particleMass; 171 beta2 = kineticEnergy*(kineticEnergy + 2.*particleMass)/(etot*etot); 163 172 164 173 G4double electronDensity = material->GetElectronDensity(); 165 kineticEnergy = dp->GetKineticEnergy(); 166 G4double etot = kineticEnergy + particleMass;167 //G4cout << "e= " << kineticEnergy << " m= " << particleMass168 // << " tmax= " << tmax << " l= " << length << " q^2= " << chargeSquare << G4endl;169 beta2 = kineticEnergy*(kineticEnergy + 2.*particleMass)/(etot*etot);170 174 175 /* 176 G4cout << "e= " << kineticEnergy << " m= " << particleMass 177 << " tmax= " << tmax << " l= " << length 178 << " q^2= " << effChargeSquare << " beta2=" << beta2<< G4endl; 179 */ 171 180 G4double siga = (1. - beta2*0.5)*tmax*length*electronDensity* 172 twopi_mc2_rcl2* Q2/beta2;181 twopi_mc2_rcl2*chargeSquare/beta2; 173 182 174 183 // Low velocity - additional ion charge fluctuations according to 175 184 // Q.Yang et al., NIM B61(1991)149-155. 176 G4double zeff = electronDensity/(material->GetTotNbOfAtomsPerVolume()); 177 //G4cout << "siga= " << siga << " zeff= " << zeff << " c= " << c << G4endl; 178 179 G4double f = 0.0; 180 181 // correction factors with cut dependence 182 if ( beta2 < 3.0*theBohrBeta2*zeff ) { 183 184 G4double a = CoeffitientA (zeff); 185 G4double b = CoeffitientB (material, zeff); 186 // G4cout << "a= " << a << " b= " << b << G4endl; 187 f = a*chargeSqRatio + b; 188 } else { 189 190 // H.Geissel et al. NIM B, 195 (2002) 3. 191 f = RelativisticFactor(material, zeff); 192 } 185 //G4cout << "sigE= " << sqrt(siga) << " charge= " << charge <<G4endl; 186 187 G4double Z = electronDensity/material->GetTotNbOfAtomsPerVolume(); 188 189 G4double fac = Factor(material, Z); 193 190 194 191 // heavy ion correction … … 196 193 if(beta2 > theBohrBeta2) f1/= beta2; 197 194 else f1/= theBohrBeta2; 198 if(f1 > 2.0) f1 = 2.0; 199 f *= (1.0 + f1); 200 201 if(f > 1.0) { 202 siga *= (1. + (f - 1.0)*2.0*electron_mass_c2*beta2/(tmax*(1.0 - beta2))); 203 } 204 // G4cout << "siga= " << siga << G4endl; 195 if(f1 > 2.5) f1 = 2.5; 196 fac *= (1.0 + f1); 197 198 // taking into account the cut 199 if(fac > 1.0) { 200 siga *= (1.0 + (fac - 1.0)*2.0*electron_mass_c2*beta2/(tmax*(1.0 - beta2))); 201 } 202 //G4cout << "siga(keV)= " << sqrt(siga)/keV << " fac= " << fac 203 // << " f1= " << f1 << G4endl; 205 204 206 205 return siga; … … 209 208 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 210 209 211 G4double G4IonFluctuations:: CoeffitientA(G4double& zeff)210 G4double G4IonFluctuations::Factor(const G4Material* material, G4double Z) 212 211 { 213 212 // The aproximation of energy loss fluctuations … … 215 214 216 215 // Reduced energy in MeV/AMU 217 G4double energy = kineticEnergy * amu_c2/(particleMass*MeV) ; 218 static G4double a[96][4] = { 216 G4double energy = kineticEnergy *amu_c2/(particleMass*MeV) ; 217 218 // simple approximation for higher beta2 219 G4double s1 = RelativisticFactor(material, Z); 220 221 // tabulation for lower beta2 222 if( beta2 < 3.0*theBohrBeta2*Z ) { 223 224 static G4double a[96][4] = { 219 225 {-0.3291, -0.8312, 0.2460, -1.0220}, 220 226 {-0.5615, -0.5898, 0.5205, -0.7258}, … … 260 266 {-0.3972, -0.3600, 1.0260, -0.5842}, 261 267 262 {-0.3985, -0.3803, 1.0200, -0.6013},268 {-0.3985, -0.3803, 1.0200, -0.6013}, 263 269 {-0.3985, -0.3979, 1.0150, -0.6168}, 264 270 {-0.3968, -0.3990, 1.0160, -0.6195}, … … 322 328 {-0.4284, -0.3204, 1.6290, -0.6380}, 323 329 {-0.4227, -0.3217, 1.6360, -0.6438} 324 } ; 325 326 G4int iz = (G4int)zeff - 2 ; 327 if( 0 > iz ) iz = 0 ; 328 if(95 < iz ) iz = 95 ; 329 330 G4double q = 1.0 / (1.0 + a[iz][0]*pow(energy,a[iz][1])+ 331 + a[iz][2]*pow(energy,a[iz][3])) ; 332 333 return q ; 334 } 335 336 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 337 338 G4double G4IonFluctuations::CoeffitientB(const G4Material* material, G4double& zeff) 339 { 340 // The aproximation of energy loss fluctuations 341 // Q.Yang et al., NIM B61(1991)149-155. 342 343 // Reduced energy in MeV/AMU 344 G4double energy = kineticEnergy *amu_c2/(particleMass*MeV) ; 330 } ; 331 332 G4int iz = G4int(Z) - 2; 333 if( 0 > iz ) iz = 0; 334 else if(95 < iz ) iz = 95; 335 336 G4double ss = 1.0 + a[iz][0]*pow(energy,a[iz][1])+ 337 + a[iz][2]*pow(energy,a[iz][3]); 338 339 // protection for the validity range for low beta 340 G4double slim = 0.001; 341 if(ss < slim) s1 = 1.0/slim; 342 // for high value of beta 343 else if(s1*ss < 1.0) s1 = 1.0/ss; 344 } 345 345 346 346 G4int i = 0 ; … … 366 366 // ions 367 367 } else { 368 factor = charge * pow(charge/zeff, 0.3333) ; 368 369 factor = charge * pow(charge/Z, 0.33333333); 369 370 370 371 if( kStateGas == material->GetState() ) { … … 378 379 379 380 } else { 380 energy /= (charge * sqrt(charge* zeff)) ;381 energy /= (charge * sqrt(charge*Z)) ; 381 382 i = 4 ; 382 383 } 383 384 } 384 385 385 G4double x = b[i][2] * (1.0 - exp( - energy * b[i][3] )) ; 386 387 G4double q = factor * x * b[i][0] / 388 ((energy - b[i][1])*(energy - b[i][1]) + x*x) ; 389 390 return q ; 391 } 392 393 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 394 395 G4double G4IonFluctuations::RelativisticFactor(const G4Material* material, 396 G4double& zeff) 397 { 386 G4double x = b[i][2]; 387 G4double y = energy * b[i][3]; 388 if(y <= 0.2) x *= (y*(1.0 - 0.5*y)); 389 else x *= (1.0 - exp(-y)); 390 391 y = energy - b[i][1]; 392 393 G4double s2 = factor * x * b[i][0] / (y*y + x*x); 394 /* 395 G4cout << "s1= " << s1 << " s2= " << s2 << " q^2= " << effChargeSquare 396 << " e= " << energy << G4endl; 397 */ 398 return s1*effChargeSquare/chargeSquare + s2; 399 } 400 401 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 402 403 G4double G4IonFluctuations::RelativisticFactor(const G4Material* mat, 404 G4double Z) 405 { 406 G4double eF = mat->GetIonisation()->GetFermiEnergy(); 407 G4double I = mat->GetIonisation()->GetMeanExcitationEnergy(); 408 398 409 // H.Geissel et al. NIM B, 195 (2002) 3. 399 G4double eF = material->GetIonisation()->GetFermiEnergy();400 410 G4double bF2= 2.0*eF/electron_mass_c2; 401 G4double I = material->GetIonisation()->GetMeanExcitationEnergy(); 402 G4double f = 0.4*(1.0 - beta2)/((1.0 - 0.5*beta2)*zeff); 411 G4double f = 0.4*(1.0 - beta2)/((1.0 - 0.5*beta2)*Z); 403 412 if(beta2 > bF2) f *= log(2.0*electron_mass_c2*beta2/I)*bF2/beta2; 404 413 else f *= log(4.0*eF/I); 405 414 415 // G4cout << "f= " << f << " beta2= " << beta2 416 // << " bf2= " << bF2 << " q^2= " << chargeSquare << G4endl; 417 406 418 return 1.0 + f; 407 419 } 408 420 409 421 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 422 423 void G4IonFluctuations::SetParticleAndCharge(const G4ParticleDefinition* part, 424 G4double q2) 425 { 426 if(part != particle) { 427 particle = part; 428 particleMass = part->GetPDGMass(); 429 charge = part->GetPDGCharge()/eplus; 430 chargeSquare = charge*charge; 431 } 432 effChargeSquare = q2; 433 uniFluct.SetParticleAndCharge(part, q2); 434 } 435 436 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
Note: See TracChangeset
for help on using the changeset viewer.