Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4IonFluctuations.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// $Id$
27//
28// -------------------------------------------------------------------
29//
30// GEANT4 Class file
31//
32//
33// File name: G4IonFluctuation
34//
35// Author: Vladimir Ivanchenko
36//
37// Creation date: 03.01.2002
38//
39// Modifications:
40//
41// 28-12-02 add method Dispersion (V.Ivanchenko)
42// 07-02-03 change signature (V.Ivanchenko)
43// 13-02-03 Add name (V.Ivanchenko)
44// 23-05-03 Add control on parthalogical cases (V.Ivanchenko)
45// 16-10-03 Changed interface to Initialisation (V.Ivanchenko)
46// 27-09-07 Use FermiEnergy from material, add cut dependence (V.Ivanchenko)
47// 01-02-08 Add protection for small energies and optimise the code (V.Ivanchenko)
48// 01-06-08 Added initialisation of effective charge prestep (V.Ivanchenko)
49//
50// Class Description:
51//
52// -------------------------------------------------------------------
53//
54
55//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
56//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
57
58#include "G4IonFluctuations.hh"
60#include "G4SystemOfUnits.hh"
61#include "Randomize.hh"
62#include "G4Poisson.hh"
63#include "G4Material.hh"
64#include "G4DynamicParticle.hh"
65
66//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
67
68using namespace std;
69
72 particle(0),
73 particleMass(proton_mass_c2),
74 charge(1.0),
75 chargeSquare(1.0),
76 effChargeSquare(1.0),
77 parameter(10.0*CLHEP::MeV/CLHEP::proton_mass_c2),
78 minNumberInteractionsBohr(0.0),
79 theBohrBeta2(50.0*keV/CLHEP::proton_mass_c2),
80 minFraction(0.2),
81 xmin(0.2),
82 minLoss(0.001*eV)
83{
84 kineticEnergy = 0.0;
85 beta2 = 0.0;
86}
87
88//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
89
91{}
92
93//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
94
96{
97 particle = part;
98 particleMass = part->GetPDGMass();
99 charge = part->GetPDGCharge()/eplus;
100 chargeSquare = charge*charge;
101 effChargeSquare= chargeSquare;
102 uniFluct.InitialiseMe(part);
103}
104
105//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
106
108 const G4DynamicParticle* dp,
109 G4double& tmax,
110 G4double& length,
111 G4double& meanLoss)
112{
113 // G4cout << "### meanLoss= " << meanLoss << G4endl;
114 if(meanLoss <= minLoss) return meanLoss;
115
116 //G4cout << "G4IonFluctuations::SampleFluctuations E(MeV)= " << dp->GetKineticEnergy()
117 // << " Elim(MeV)= " << parameter*charge*particleMass << G4endl;
118
119 // Vavilov fluctuations
120 if(dp->GetKineticEnergy() > parameter*charge*particleMass) {
121 return uniFluct.SampleFluctuations(material,dp,tmax,length,meanLoss);
122 }
123
124 G4double siga = Dispersion(material,dp,tmax,length);
125 G4double loss = meanLoss;
126
127 //G4cout << "### siga= " << sqrt(siga) << " navr= " << navr << G4endl;
128
129 // Gaussian fluctuation
130
131 // Increase fluctuations for big fractional energy loss
132 //G4cout << "siga= " << siga << G4endl;
133 if ( meanLoss > minFraction*kineticEnergy ) {
134 G4double gam = (kineticEnergy - meanLoss)/particleMass + 1.0;
135 G4double b2 = 1.0 - 1.0/(gam*gam);
136 if(b2 < xmin*beta2) b2 = xmin*beta2;
137 G4double x = b2/beta2;
138 G4double x3 = 1.0/(x*x*x);
139 siga *= 0.25*(1.0 + x)*(x3 + (1.0/b2 - 0.5)/(1.0/beta2 - 0.5) );
140 }
141 siga = sqrt(siga);
142 G4double sn = meanLoss/siga;
143 G4double twomeanLoss = meanLoss + meanLoss;
144 // G4cout << "siga= " << siga << " sn= " << sn << G4endl;
145
146 // thick target case
147 if (sn >= 2.0) {
148
149 do {
150 loss = G4RandGauss::shoot(meanLoss,siga);
151 } while (0.0 > loss || twomeanLoss < loss);
152
153 // Gamma distribution
154 } else if(sn > 0.1) {
155
156 G4double neff = sn*sn;
157 loss = meanLoss*CLHEP::RandGamma::shoot(neff,1.0)/neff;
158
159 // uniform distribution for very small steps
160 } else {
161 loss = twomeanLoss*G4UniformRand();
162 }
163
164 //G4cout << "meanLoss= " << meanLoss << " loss= " << loss << G4endl;
165 return loss;
166}
167
168//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
169
171 const G4DynamicParticle* dp,
172 G4double& tmax,
173 G4double& length)
174{
175 kineticEnergy = dp->GetKineticEnergy();
176 G4double etot = kineticEnergy + particleMass;
177 beta2 = kineticEnergy*(kineticEnergy + 2.*particleMass)/(etot*etot);
178
179 G4double electronDensity = material->GetElectronDensity();
180
181 /*
182 G4cout << "e= " << kineticEnergy << " m= " << particleMass
183 << " tmax= " << tmax << " l= " << length
184 << " q^2= " << effChargeSquare << " beta2=" << beta2<< G4endl;
185 */
186 G4double siga = (1. - beta2*0.5)*tmax*length*electronDensity*
187 twopi_mc2_rcl2*chargeSquare/beta2;
188
189 // Low velocity - additional ion charge fluctuations according to
190 // Q.Yang et al., NIM B61(1991)149-155.
191 //G4cout << "sigE= " << sqrt(siga) << " charge= " << charge <<G4endl;
192
193 G4double Z = electronDensity/material->GetTotNbOfAtomsPerVolume();
194
195 G4double fac = Factor(material, Z);
196
197 // heavy ion correction
198// G4double f1 = 1.065e-4*chargeSquare;
199// if(beta2 > theBohrBeta2) f1/= beta2;
200// else f1/= theBohrBeta2;
201// if(f1 > 2.5) f1 = 2.5;
202// fac *= (1.0 + f1);
203
204 // taking into account the cut
205 G4double fac_cut = 1.0 + (fac - 1.0)*2.0*electron_mass_c2*beta2/(tmax*(1.0 - beta2));
206 if(fac_cut > 0.01 && fac > 0.01) {
207 siga *= fac_cut;
208 }
209
210 //G4cout << "siga(keV)= " << sqrt(siga)/keV << " fac= " << fac
211 // << " f1= " << f1 << G4endl;
212
213 return siga;
214}
215
216//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
217
218G4double G4IonFluctuations::Factor(const G4Material* material, G4double Z)
219{
220 // The aproximation of energy loss fluctuations
221 // Q.Yang et al., NIM B61(1991)149-155.
222
223 // Reduced energy in MeV/AMU
224 G4double energy = kineticEnergy *amu_c2/(particleMass*MeV) ;
225
226 // simple approximation for higher beta2
227 G4double s1 = RelativisticFactor(material, Z);
228
229 // tabulation for lower beta2
230 if( beta2 < 3.0*theBohrBeta2*Z ) {
231
232 static G4double a[96][4] = {
233 {-0.3291, -0.8312, 0.2460, -1.0220},
234 {-0.5615, -0.5898, 0.5205, -0.7258},
235 {-0.5280, -0.4981, 0.5519, -0.5865},
236 {-0.5125, -0.4625, 0.5660, -0.5190},
237 {-0.5127, -0.8595, 0.5626, -0.8721},
238 {-0.5174, -1.1930, 0.5565, -1.1980},
239 {-0.5179, -1.1850, 0.5560, -1.2070},
240 {-0.5209, -0.9355, 0.5590, -1.0250},
241 {-0.5255, -0.7766, 0.5720, -0.9412},
242
243 {-0.5776, -0.6665, 0.6598, -0.8484},
244 {-0.6013, -0.6045, 0.7321, -0.7671},
245 {-0.5781, -0.5518, 0.7605, -0.6919},
246 {-0.5587, -0.4981, 0.7835, -0.6195},
247 {-0.5466, -0.4656, 0.7978, -0.5771},
248 {-0.5406, -0.4690, 0.8031, -0.5718},
249 {-0.5391, -0.5061, 0.8024, -0.5974},
250 {-0.5380, -0.6483, 0.7962, -0.6970},
251 {-0.5355, -0.7722, 0.7962, -0.7839},
252 {-0.5329, -0.7720, 0.7988, -0.7846},
253
254 {-0.5335, -0.7671, 0.7984, -0.7933},
255 {-0.5324, -0.7612, 0.7998, -0.8031},
256 {-0.5305, -0.7300, 0.8031, -0.7990},
257 {-0.5307, -0.7178, 0.8049, -0.8216},
258 {-0.5248, -0.6621, 0.8165, -0.7919},
259 {-0.5180, -0.6502, 0.8266, -0.7986},
260 {-0.5084, -0.6408, 0.8396, -0.8048},
261 {-0.4967, -0.6331, 0.8549, -0.8093},
262 {-0.4861, -0.6508, 0.8712, -0.8432},
263 {-0.4700, -0.6186, 0.8961, -0.8132},
264
265 {-0.4545, -0.5720, 0.9227, -0.7710},
266 {-0.4404, -0.5226, 0.9481, -0.7254},
267 {-0.4288, -0.4778, 0.9701, -0.6850},
268 {-0.4199, -0.4425, 0.9874, -0.6539},
269 {-0.4131, -0.4188, 0.9998, -0.6332},
270 {-0.4089, -0.4057, 1.0070, -0.6218},
271 {-0.4039, -0.3913, 1.0150, -0.6107},
272 {-0.3987, -0.3698, 1.0240, -0.5938},
273 {-0.3977, -0.3608, 1.0260, -0.5852},
274 {-0.3972, -0.3600, 1.0260, -0.5842},
275
276 {-0.3985, -0.3803, 1.0200, -0.6013},
277 {-0.3985, -0.3979, 1.0150, -0.6168},
278 {-0.3968, -0.3990, 1.0160, -0.6195},
279 {-0.3971, -0.4432, 1.0050, -0.6591},
280 {-0.3944, -0.4665, 1.0010, -0.6825},
281 {-0.3924, -0.5109, 0.9921, -0.7235},
282 {-0.3882, -0.5158, 0.9947, -0.7343},
283 {-0.3838, -0.5125, 0.9999, -0.7370},
284 {-0.3786, -0.4976, 1.0090, -0.7310},
285 {-0.3741, -0.4738, 1.0200, -0.7155},
286
287 {-0.3969, -0.4496, 1.0320, -0.6982},
288 {-0.3663, -0.4297, 1.0430, -0.6828},
289 {-0.3630, -0.4120, 1.0530, -0.6689},
290 {-0.3597, -0.3964, 1.0620, -0.6564},
291 {-0.3555, -0.3809, 1.0720, -0.6454},
292 {-0.3525, -0.3607, 1.0820, -0.6289},
293 {-0.3505, -0.3465, 1.0900, -0.6171},
294 {-0.3397, -0.3570, 1.1020, -0.6384},
295 {-0.3314, -0.3552, 1.1130, -0.6441},
296 {-0.3235, -0.3531, 1.1230, -0.6498},
297
298 {-0.3150, -0.3483, 1.1360, -0.6539},
299 {-0.3060, -0.3441, 1.1490, -0.6593},
300 {-0.2968, -0.3396, 1.1630, -0.6649},
301 {-0.2935, -0.3225, 1.1760, -0.6527},
302 {-0.2797, -0.3262, 1.1940, -0.6722},
303 {-0.2704, -0.3202, 1.2100, -0.6770},
304 {-0.2815, -0.3227, 1.2480, -0.6775},
305 {-0.2880, -0.3245, 1.2810, -0.6801},
306 {-0.3034, -0.3263, 1.3270, -0.6778},
307 {-0.2936, -0.3215, 1.3430, -0.6835},
308
309 {-0.3282, -0.3200, 1.3980, -0.6650},
310 {-0.3260, -0.3070, 1.4090, -0.6552},
311 {-0.3511, -0.3074, 1.4470, -0.6442},
312 {-0.3501, -0.3064, 1.4500, -0.6442},
313 {-0.3490, -0.3027, 1.4550, -0.6418},
314 {-0.3487, -0.3048, 1.4570, -0.6447},
315 {-0.3478, -0.3074, 1.4600, -0.6483},
316 {-0.3501, -0.3283, 1.4540, -0.6669},
317 {-0.3494, -0.3373, 1.4550, -0.6765},
318 {-0.3485, -0.3373, 1.4570, -0.6774},
319
320 {-0.3462, -0.3300, 1.4630, -0.6728},
321 {-0.3462, -0.3225, 1.4690, -0.6662},
322 {-0.3453, -0.3094, 1.4790, -0.6553},
323 {-0.3844, -0.3134, 1.5240, -0.6412},
324 {-0.3848, -0.3018, 1.5310, -0.6303},
325 {-0.3862, -0.2955, 1.5360, -0.6237},
326 {-0.4262, -0.2991, 1.5860, -0.6115},
327 {-0.4278, -0.2910, 1.5900, -0.6029},
328 {-0.4303, -0.2817, 1.5940, -0.5927},
329 {-0.4315, -0.2719, 1.6010, -0.5829},
330
331 {-0.4359, -0.2914, 1.6050, -0.6010},
332 {-0.4365, -0.2982, 1.6080, -0.6080},
333 {-0.4253, -0.3037, 1.6120, -0.6150},
334 {-0.4335, -0.3245, 1.6160, -0.6377},
335 {-0.4307, -0.3292, 1.6210, -0.6447},
336 {-0.4284, -0.3204, 1.6290, -0.6380},
337 {-0.4227, -0.3217, 1.6360, -0.6438}
338 } ;
339
340 G4int iz = G4int(Z) - 2;
341 if( 0 > iz ) iz = 0;
342 else if(95 < iz ) iz = 95;
343
344 G4double ss = 1.0 + a[iz][0]*pow(energy,a[iz][1])+
345 + a[iz][2]*pow(energy,a[iz][3]);
346
347 // protection for the validity range for low beta
348 G4double slim = 0.001;
349 if(ss < slim) s1 = 1.0/slim;
350 // for high value of beta
351 else if(s1*ss < 1.0) s1 = 1.0/ss;
352 }
353
354 G4int i = 0 ;
355 G4double factor = 1.0 ;
356
357 // The index of set of parameters i = 0 for protons(hadrons) in gases
358 // 1 for protons(hadrons) in solids
359 // 2 for ions in atomic gases
360 // 3 for ions in molecular gases
361 // 4 for ions in solids
362 static G4double b[5][4] = {
363 {0.1014, 0.3700, 0.9642, 3.987},
364 {0.1955, 0.6941, 2.522, 1.040},
365 {0.05058, 0.08975, 0.1419, 10.80},
366 {0.05009, 0.08660, 0.2751, 3.787},
367 {0.01273, 0.03458, 0.3951, 3.812}
368 } ;
369
370 // protons (hadrons)
371 if(1.5 > charge) {
372 if( kStateGas != material->GetState() ) i = 1 ;
373
374 // ions
375 } else {
376
377 factor = charge * pow(charge/Z, 0.33333333);
378
379 if( kStateGas == material->GetState() ) {
380 energy /= (charge * sqrt(charge)) ;
381
382 if(1 == (material->GetNumberOfElements())) {
383 i = 2 ;
384 } else {
385 i = 3 ;
386 }
387
388 } else {
389 energy /= (charge * sqrt(charge*Z)) ;
390 i = 4 ;
391 }
392 }
393
394 G4double x = b[i][2];
395 G4double y = energy * b[i][3];
396 if(y <= 0.2) x *= (y*(1.0 - 0.5*y));
397 else x *= (1.0 - exp(-y));
398
399 y = energy - b[i][1];
400
401 G4double s2 = factor * x * b[i][0] / (y*y + x*x);
402 /*
403 G4cout << "s1= " << s1 << " s2= " << s2 << " q^2= " << effChargeSquare
404 << " e= " << energy << G4endl;
405 */
406 return s1*effChargeSquare/chargeSquare + s2;
407}
408
409//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
410
411G4double G4IonFluctuations::RelativisticFactor(const G4Material* mat,
412 G4double Z)
413{
416
417 // H.Geissel et al. NIM B, 195 (2002) 3.
418 G4double bF2= 2.0*eF/electron_mass_c2;
419 G4double f = 0.4*(1.0 - beta2)/((1.0 - 0.5*beta2)*Z);
420 if(beta2 > bF2) f *= log(2.0*electron_mass_c2*beta2/I)*bF2/beta2;
421 else f *= log(4.0*eF/I);
422
423 // G4cout << "f= " << f << " beta2= " << beta2
424 // << " bf2= " << bF2 << " q^2= " << chargeSquare << G4endl;
425
426 return 1.0 + f;
427}
428
429//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
430
432 G4double q2)
433{
434 if(part != particle) {
435 particle = part;
436 particleMass = part->GetPDGMass();
437 charge = part->GetPDGCharge()/eplus;
438 chargeSquare = charge*charge;
439 }
440 effChargeSquare = q2;
441 uniFluct.SetParticleAndCharge(part, q2);
442}
443
444//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@ kStateGas
Definition: G4Material.hh:114
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4UniformRand()
Definition: Randomize.hh:53
static double shoot()
G4double GetKineticEnergy() const
G4double Dispersion(const G4Material *, const G4DynamicParticle *, G4double &tmax, G4double &length)
virtual ~G4IonFluctuations()
G4double SampleFluctuations(const G4Material *, const G4DynamicParticle *, G4double &tmax, G4double &length, G4double &meanLoss)
G4IonFluctuations(const G4String &nam="IonFluc")
void InitialiseMe(const G4ParticleDefinition *)
void SetParticleAndCharge(const G4ParticleDefinition *, G4double q2)
G4double GetMeanExcitationEnergy() const
G4double GetFermiEnergy() const
G4double GetTotNbOfAtomsPerVolume() const
Definition: G4Material.hh:208
G4State GetState() const
Definition: G4Material.hh:180
G4IonisParamMat * GetIonisation() const
Definition: G4Material.hh:225
size_t GetNumberOfElements() const
Definition: G4Material.hh:185
G4double GetElectronDensity() const
Definition: G4Material.hh:216
G4double GetPDGCharge() const
virtual void SetParticleAndCharge(const G4ParticleDefinition *, G4double q2)
virtual void InitialiseMe(const G4ParticleDefinition *)
virtual G4double SampleFluctuations(const G4Material *, const G4DynamicParticle *, G4double &, G4double &, G4double &)
Definition: DoubConv.h:17