Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4BraggModel.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: G4BraggModel
34//
35// Author: Vladimir Ivanchenko
36//
37// Creation date: 03.01.2002
38//
39// Modifications:
40//
41// 04-12-02 Fix problem of G4DynamicParticle constructor (V.Ivanchenko)
42// 23-12-02 Change interface in order to move to cut per region (V.Ivanchenko)
43// 27-01-03 Make models region aware (V.Ivanchenko)
44// 13-02-03 Add name (V.Ivanchenko)
45// 04-06-03 Fix compilation warnings (V.Ivanchenko)
46// 12-09-04 Add lowestKinEnergy and change order of if in DEDX method (VI)
47// 11-04-05 Major optimisation of internal interfaces (V.Ivantchenko)
48// 16-06-05 Fix problem of chemical formula (V.Ivantchenko)
49// 15-02-06 ComputeCrossSectionPerElectron, ComputeCrossSectionPerAtom (mma)
50// 25-04-06 Add stopping data from PSTAR (V.Ivanchenko)
51// 12-08-08 Added methods GetParticleCharge, GetChargeSquareRatio,
52// CorrectionsAlongStep needed for ions(V.Ivanchenko)
53
54// Class Description:
55//
56// Implementation of energy loss and delta-electron production by
57// slow charged heavy particles
58
59// -------------------------------------------------------------------
60//
61
62
63//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
64//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
65
66#include "G4BraggModel.hh"
68#include "G4SystemOfUnits.hh"
69#include "Randomize.hh"
70#include "G4Electron.hh"
72#include "G4LossTableManager.hh"
73#include "G4EmCorrections.hh"
74
75//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
76
77using namespace std;
78
80 : G4VEmModel(nam),
81 particle(0),
82 currentMaterial(0),
83 protonMassAMU(1.007276),
84 iMolecula(-1),
85 iPSTAR(-1),
86 isIon(false),
87 isInitialised(false)
88{
89 fParticleChange = 0;
90 SetHighEnergyLimit(2.0*MeV);
91
92 lowestKinEnergy = 1.0*keV;
93 theZieglerFactor = eV*cm2*1.0e-15;
94 theElectron = G4Electron::Electron();
95 expStopPower125 = 0.0;
96
98 if(p) { SetParticle(p); }
99 else { SetParticle(theElectron); }
100}
101
102//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
103
105{}
106
107//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
108
110 const G4DataVector&)
111{
112 if(p != particle) { SetParticle(p); }
113
114 // always false before the run
115 SetDeexcitationFlag(false);
116
117 if(!isInitialised) {
118 isInitialised = true;
119
120 G4String pname = particle->GetParticleName();
121 if(particle->GetParticleType() == "nucleus" &&
122 pname != "deuteron" && pname != "triton" &&
123 pname != "alpha+" && pname != "helium" &&
124 pname != "hydrogen") { isIon = true; }
125
126 fParticleChange = GetParticleChangeForLoss();
127 }
128}
129
130//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
131
133 const G4Material* mat,
134 G4double kineticEnergy)
135{
136 // this method is called only for ions
137 G4double q2 = corr->EffectiveChargeSquareRatio(p,mat,kineticEnergy);
139 return q2*corr->EffectiveChargeCorrection(p,mat,kineticEnergy);
140}
141
142//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
143
145 const G4Material* mat,
146 G4double kineticEnergy)
147{
148 // this method is called only for ions, so no check if it is an ion
149 return corr->GetParticleCharge(p,mat,kineticEnergy);
150}
151
152//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
153
155 const G4ParticleDefinition* p,
156 G4double kineticEnergy,
157 G4double cutEnergy,
158 G4double maxKinEnergy)
159{
160 G4double cross = 0.0;
161 G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
162 G4double maxEnergy = std::min(tmax,maxKinEnergy);
163 if(cutEnergy < maxEnergy) {
164
165 G4double energy = kineticEnergy + mass;
166 G4double energy2 = energy*energy;
167 G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
168 cross = 1.0/cutEnergy - 1.0/maxEnergy - beta2*log(maxEnergy/cutEnergy)/tmax;
169
170 cross *= twopi_mc2_rcl2*chargeSquare/beta2;
171 }
172 // G4cout << "BR: e= " << kineticEnergy << " tmin= " << cutEnergy
173 // << " tmax= " << tmax << " cross= " << cross << G4endl;
174
175 return cross;
176}
177
178//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
179
181 const G4ParticleDefinition* p,
182 G4double kineticEnergy,
184 G4double cutEnergy,
185 G4double maxEnergy)
186{
188 (p,kineticEnergy,cutEnergy,maxEnergy);
189 return cross;
190}
191
192//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
193
195 const G4Material* material,
196 const G4ParticleDefinition* p,
197 G4double kineticEnergy,
198 G4double cutEnergy,
199 G4double maxEnergy)
200{
201 G4double eDensity = material->GetElectronDensity();
203 (p,kineticEnergy,cutEnergy,maxEnergy);
204 return cross;
205}
206
207//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
208
210 const G4ParticleDefinition* p,
211 G4double kineticEnergy,
212 G4double cutEnergy)
213{
214 G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
215 G4double tkin = kineticEnergy/massRate;
216 G4double dedx = 0.0;
217
218 if(tkin < lowestKinEnergy) {
219 dedx = DEDX(material, lowestKinEnergy)*sqrt(tkin/lowestKinEnergy);
220 } else {
221 dedx = DEDX(material, tkin);
222 }
223
224 if (cutEnergy < tmax) {
225
226 G4double tau = kineticEnergy/mass;
227 G4double gam = tau + 1.0;
228 G4double bg2 = tau * (tau+2.0);
229 G4double beta2 = bg2/(gam*gam);
230 G4double x = cutEnergy/tmax;
231
232 dedx += (log(x) + (1.0 - x)*beta2) * twopi_mc2_rcl2
233 * (material->GetElectronDensity())/beta2;
234 }
235
236 // now compute the total ionization loss
237
238 if (dedx < 0.0) { dedx = 0.0; }
239
240 dedx *= chargeSquare;
241
242 //G4cout << "E(MeV)= " << tkin/MeV << " dedx= " << dedx
243 // << " " << material->GetName() << G4endl;
244
245 return dedx;
246}
247
248//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
249
250void G4BraggModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
252 const G4DynamicParticle* dp,
253 G4double xmin,
254 G4double maxEnergy)
255{
257 G4double xmax = std::min(tmax, maxEnergy);
258 if(xmin >= xmax) { return; }
259
260 G4double kineticEnergy = dp->GetKineticEnergy();
261 G4double energy = kineticEnergy + mass;
262 G4double energy2 = energy*energy;
263 G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
264 G4double grej = 1.0;
265 G4double deltaKinEnergy, f;
266
267 G4ThreeVector direction = dp->GetMomentumDirection();
268
269 // sampling follows ...
270 do {
272 deltaKinEnergy = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
273
274 f = 1.0 - beta2*deltaKinEnergy/tmax;
275
276 if(f > grej) {
277 G4cout << "G4BraggModel::SampleSecondary Warning! "
278 << "Majorant " << grej << " < "
279 << f << " for e= " << deltaKinEnergy
280 << G4endl;
281 }
282
283 } while( grej*G4UniformRand() >= f );
284
285 G4double deltaMomentum =
286 sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
287 G4double totMomentum = energy*sqrt(beta2);
288 G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
289 (deltaMomentum * totMomentum);
290 if(cost > 1.0) cost = 1.0;
291 G4double sint = sqrt((1.0 - cost)*(1.0 + cost));
292
293 G4double phi = twopi * G4UniformRand() ;
294
295 G4ThreeVector deltaDirection(sint*cos(phi),sint*sin(phi), cost) ;
296 deltaDirection.rotateUz(direction);
297
298 // Change kinematics of primary particle
299 kineticEnergy -= deltaKinEnergy;
300 G4ThreeVector finalP = direction*totMomentum - deltaDirection*deltaMomentum;
301 finalP = finalP.unit();
302
303 fParticleChange->SetProposedKineticEnergy(kineticEnergy);
304 fParticleChange->SetProposedMomentumDirection(finalP);
305
306 // create G4DynamicParticle object for delta ray
307 G4DynamicParticle* delta = new G4DynamicParticle(theElectron,deltaDirection,
308 deltaKinEnergy);
309
310 vdp->push_back(delta);
311}
312
313//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
314
316 G4double kinEnergy)
317{
318 if(pd != particle) { SetParticle(pd); }
319 G4double tau = kinEnergy/mass;
320 G4double tmax = 2.0*electron_mass_c2*tau*(tau + 2.) /
321 (1. + 2.0*(tau + 1.)*ratio + ratio*ratio);
322 return tmax;
323}
324
325//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
326
327G4bool G4BraggModel::HasMaterial(const G4Material* material)
328{
329 G4String chFormula = material->GetChemicalFormula();
330 if("" == chFormula) { return false; }
331
332 // ICRU Report N49, 1993. Power's model for He.
333 const size_t numberOfMolecula = 11;
334 const G4String molName[numberOfMolecula] = {
335 "Al_2O_3", "CO_2", "CH_4",
336 "(C_2H_4)_N-Polyethylene", "(C_2H_4)_N-Polypropylene", "(C_8H_8)_N",
337 "C_3H_8", "SiO_2", "H_2O",
338 "H_2O-Gas", "Graphite" } ;
339 const G4int idxPSTAR[numberOfMolecula] = {
340 6, 16, 36,
341 52, 55, 56,
342 59, 62, 71,
343 72, 13};
344
345 // Special treatment for water in gas state
346 const G4State theState = material->GetState() ;
347
348 if( theState == kStateGas && "H_2O" == chFormula) {
349 chFormula = G4String("H_2O-Gas");
350 }
351
352 // Search for the material in the table
353 for (size_t i=0; i<numberOfMolecula; ++i) {
354 if (chFormula == molName[i]) {
355 iMolecula = -1;
356 iPSTAR = idxPSTAR[i];
357 return true;
358 }
359 }
360 return false;
361}
362
363//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
364
365G4double G4BraggModel::StoppingPower(const G4Material* material,
366 G4double kineticEnergy)
367{
368 G4double ionloss = 0.0 ;
369
370 if (iMolecula >= 0) {
371
372 // The data and the fit from:
373 // ICRU Report N49, 1993. Ziegler's model for protons.
374 // Proton kinetic energy for parametrisation (keV/amu)
375
376 G4double T = kineticEnergy/(keV*protonMassAMU) ;
377
378 static G4double a[11][5] = {
379 {1.187E+1, 1.343E+1, 1.069E+4, 7.723E+2, 2.153E-2},
380 {7.802E+0, 8.814E+0, 8.303E+3, 7.446E+2, 7.966E-3},
381 {7.294E+0, 8.284E+0, 5.010E+3, 4.544E+2, 8.153E-3},
382 {8.646E+0, 9.800E+0, 7.066E+3, 4.581E+2, 9.383E-3},
383 {1.286E+1, 1.462E+1, 5.625E+3, 2.621E+3, 3.512E-2},
384 {3.229E+1, 3.696E+1, 8.918E+3, 3.244E+3, 1.273E-1},
385 {1.604E+1, 1.825E+1, 6.967E+3, 2.307E+3, 3.775E-2},
386 {8.049E+0, 9.099E+0, 9.257E+3, 3.846E+2, 1.007E-2},
387 {4.015E+0, 4.542E+0, 3.955E+3, 4.847E+2, 7.904E-3},
388 {4.571E+0, 5.173E+0, 4.346E+3, 4.779E+2, 8.572E-3},
389 {2.631E+0, 2.601E+0, 1.701E+3, 1.279E+3, 1.638E-2} };
390
391 static G4double atomicWeight[11] = {
392 101.96128, 44.0098, 16.0426, 28.0536, 42.0804,
393 104.1512, 44.665, 60.0843, 18.0152, 18.0152, 12.0};
394
395 if ( T < 10.0 ) {
396 ionloss = a[iMolecula][0] * sqrt(T) ;
397
398 } else if ( T < 10000.0 ) {
399 G4double slow = a[iMolecula][1] * pow(T, 0.45) ;
400 G4double shigh = log( 1.0 + a[iMolecula][3]/T
401 + a[iMolecula][4]*T ) * a[iMolecula][2]/T ;
402 ionloss = slow*shigh / (slow + shigh) ;
403 }
404
405 if ( ionloss < 0.0) ionloss = 0.0 ;
406 if ( 10 == iMolecula ) {
407 if (T < 100.0) {
408 ionloss *= (1.0+0.023+0.0066*log10(T));
409 }
410 else if (T < 700.0) {
411 ionloss *=(1.0+0.089-0.0248*log10(T-99.));
412 }
413 else if (T < 10000.0) {
414 ionloss *=(1.0+0.089-0.0248*log10(700.-99.));
415 }
416 }
417 ionloss /= atomicWeight[iMolecula];
418
419 // pure material (normally not the case for this function)
420 } else if(1 == (material->GetNumberOfElements())) {
421 G4double z = material->GetZ() ;
422 ionloss = ElectronicStoppingPower( z, kineticEnergy ) ;
423 }
424
425 return ionloss;
426}
427
428//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
429
430G4double G4BraggModel::ElectronicStoppingPower(G4double z,
431 G4double kineticEnergy) const
432{
433 G4double ionloss ;
434 G4int i = G4int(z)-1 ; // index of atom
435 if(i < 0) i = 0 ;
436 if(i > 91) i = 91 ;
437
438 // The data and the fit from:
439 // ICRU Report 49, 1993. Ziegler's type of parametrisations.
440 // Proton kinetic energy for parametrisation (keV/amu)
441
442 G4double T = kineticEnergy/(keV*protonMassAMU) ;
443
444 static G4double a[92][5] = {
445 {1.254E+0, 1.440E+0, 2.426E+2, 1.200E+4, 1.159E-1},
446 {1.229E+0, 1.397E+0, 4.845E+2, 5.873E+3, 5.225E-2},
447 {1.411E+0, 1.600E+0, 7.256E+2, 3.013E+3, 4.578E-2},
448 {2.248E+0, 2.590E+0, 9.660E+2, 1.538E+2, 3.475E-2},
449 {2.474E+0, 2.815E+0, 1.206E+3, 1.060E+3, 2.855E-2},
450 {2.631E+0, 2.601E+0, 1.701E+3, 1.279E+3, 1.638E-2},
451 {2.954E+0, 3.350E+0, 1.683E+3, 1.900E+3, 2.513E-2},
452 {2.652E+0, 3.000E+0, 1.920E+3, 2.000E+3, 2.230E-2},
453 {2.085E+0, 2.352E+0, 2.157E+3, 2.634E+3, 1.816E-2},
454 {1.951E+0, 2.199E+0, 2.393E+3, 2.699E+3, 1.568E-2},
455 // Z= 11-20
456 {2.542E+0, 2.869E+0, 2.628E+3, 1.854E+3, 1.472E-2},
457 {3.791E+0, 4.293E+0, 2.862E+3, 1.009E+3, 1.397E-2},
458 {4.154E+0, 4.739E+0, 2.766E+3, 1.645E+2, 2.023E-2},
459 {4.914E+0, 5.598E+0, 3.193E+3, 2.327E+2, 1.419E-2},
460 {3.232E+0, 3.647E+0, 3.561E+3, 1.560E+3, 1.267E-2},
461 {3.447E+0, 3.891E+0, 3.792E+3, 1.219E+3, 1.211E-2},
462 {5.301E+0, 6.008E+0, 3.969E+3, 6.451E+2, 1.183E-2},
463 {5.731E+0, 6.500E+0, 4.253E+3, 5.300E+2, 1.123E-2},
464 {5.152E+0, 5.833E+0, 4.482E+3, 5.457E+2, 1.129E-2},
465 {5.521E+0, 6.252E+0, 4.710E+3, 5.533E+2, 1.112E-2},
466 // Z= 21-30
467 {5.201E+0, 5.884E+0, 4.938E+3, 5.609E+2, 9.995E-3},
468 {4.858E+0, 5.489E+0, 5.260E+3, 6.511E+2, 8.930E-3},
469 {4.479E+0, 5.055E+0, 5.391E+3, 9.523E+2, 9.117E-3},
470 {3.983E+0, 4.489E+0, 5.616E+3, 1.336E+3, 8.413E-3},
471 {3.469E+0, 3.907E+0, 5.725E+3, 1.461E+3, 8.829E-3},
472 {3.519E+0, 3.963E+0, 6.065E+3, 1.243E+3, 7.782E-3},
473 {3.140E+0, 3.535E+0, 6.288E+3, 1.372E+3, 7.361E-3},
474 {3.553E+0, 4.004E+0, 6.205E+3, 5.551E+2, 8.763E-3},
475 {3.696E+0, 4.194E+0, 4.649E+3, 8.113E+1, 2.242E-2},
476 {4.210E+0, 4.750E+0, 6.953E+3, 2.952E+2, 6.809E-3},
477 // Z= 31-40
478 {5.041E+0, 5.697E+0, 7.173E+3, 2.026E+2, 6.725E-3},
479 {5.554E+0, 6.300E+0, 6.496E+3, 1.100E+2, 9.689E-3},
480 {5.323E+0, 6.012E+0, 7.611E+3, 2.925E+2, 6.447E-3},
481 {5.874E+0, 6.656E+0, 7.395E+3, 1.175E+2, 7.684E-3},
482 {6.658E+0, 7.536E+0, 7.694E+3, 2.223E+2, 6.509E-3},
483 {6.413E+0, 7.240E+0, 1.185E+4, 1.537E+2, 2.880E-3},
484 {5.694E+0, 6.429E+0, 8.478E+3, 2.929E+2, 6.087E-3},
485 {6.339E+0, 7.159E+0, 8.693E+3, 3.303E+2, 6.003E-3},
486 {6.407E+0, 7.234E+0, 8.907E+3, 3.678E+2, 5.889E-3},
487 {6.734E+0, 7.603E+0, 9.120E+3, 4.052E+2, 5.765E-3},
488 // Z= 41-50
489 {6.901E+0, 7.791E+0, 9.333E+3, 4.427E+2, 5.587E-3},
490 {6.424E+0, 7.248E+0, 9.545E+3, 4.802E+2, 5.376E-3},
491 {6.799E+0, 7.671E+0, 9.756E+3, 5.176E+2, 5.315E-3},
492 {6.109E+0, 6.887E+0, 9.966E+3, 5.551E+2, 5.151E-3},
493 {5.924E+0, 6.677E+0, 1.018E+4, 5.925E+2, 4.919E-3},
494 {5.238E+0, 5.900E+0, 1.038E+4, 6.300E+2, 4.758E-3},
495 // {5.623, 6.354, 7160.0, 337.6, 0.013940}, // Ag Ziegler77
496 {5.345E+0, 6.038E+0, 6.790E+3, 3.978E+2, 1.676E-2}, // Ag ICRU49
497 {5.814E+0, 6.554E+0, 1.080E+4, 3.555E+2, 4.626E-3},
498 {6.229E+0, 7.024E+0, 1.101E+4, 3.709E+2, 4.540E-3},
499 {6.409E+0, 7.227E+0, 1.121E+4, 3.864E+2, 4.474E-3},
500 // Z= 51-60
501 {7.500E+0, 8.480E+0, 8.608E+3, 3.480E+2, 9.074E-3},
502 {6.979E+0, 7.871E+0, 1.162E+4, 3.924E+2, 4.402E-3},
503 {7.725E+0, 8.716E+0, 1.183E+4, 3.948E+2, 4.376E-3},
504 {8.337E+0, 9.425E+0, 1.051E+4, 2.696E+2, 6.206E-3},
505 {7.287E+0, 8.218E+0, 1.223E+4, 3.997E+2, 4.447E-3},
506 {7.899E+0, 8.911E+0, 1.243E+4, 4.021E+2, 4.511E-3},
507 {8.041E+0, 9.071E+0, 1.263E+4, 4.045E+2, 4.540E-3},
508 {7.488E+0, 8.444E+0, 1.283E+4, 4.069E+2, 4.420E-3},
509 {7.291E+0, 8.219E+0, 1.303E+4, 4.093E+2, 4.298E-3},
510 {7.098E+0, 8.000E+0, 1.323E+4, 4.118E+2, 4.182E-3},
511 // Z= 61-70
512 {6.909E+0, 7.786E+0, 1.343E+4, 4.142E+2, 4.058E-3},
513 {6.728E+0, 7.580E+0, 1.362E+4, 4.166E+2, 3.976E-3},
514 {6.551E+0, 7.380E+0, 1.382E+4, 4.190E+2, 3.877E-3},
515 {6.739E+0, 7.592E+0, 1.402E+4, 4.214E+2, 3.863E-3},
516 {6.212E+0, 6.996E+0, 1.421E+4, 4.239E+2, 3.725E-3},
517 {5.517E+0, 6.210E+0, 1.440E+4, 4.263E+2, 3.632E-3},
518 {5.220E+0, 5.874E+0, 1.460E+4, 4.287E+2, 3.498E-3},
519 {5.071E+0, 5.706E+0, 1.479E+4, 4.330E+2, 3.405E-3},
520 {4.926E+0, 5.542E+0, 1.498E+4, 4.335E+2, 3.342E-3},
521 {4.788E+0, 5.386E+0, 1.517E+4, 4.359E+2, 3.292E-3},
522 // Z= 71-80
523 {4.893E+0, 5.505E+0, 1.536E+4, 4.384E+2, 3.243E-3},
524 {5.028E+0, 5.657E+0, 1.555E+4, 4.408E+2, 3.195E-3},
525 {4.738E+0, 5.329E+0, 1.574E+4, 4.432E+2, 3.186E-3},
526 {4.587E+0, 5.160E+0, 1.541E+4, 4.153E+2, 3.406E-3},
527 {5.201E+0, 5.851E+0, 1.612E+4, 4.416E+2, 3.122E-3},
528 {5.071E+0, 5.704E+0, 1.630E+4, 4.409E+2, 3.082E-3},
529 {4.946E+0, 5.563E+0, 1.649E+4, 4.401E+2, 2.965E-3},
530 {4.477E+0, 5.034E+0, 1.667E+4, 4.393E+2, 2.871E-3},
531 // {4.856, 5.460, 18320.0, 438.5, 0.002542}, //Ziegler77
532 {4.844E+0, 5.458E+0, 7.852E+3, 9.758E+2, 2.077E-2}, //ICRU49
533 {4.307E+0, 4.843E+0, 1.704E+4, 4.878E+2, 2.882E-3},
534 // Z= 81-90
535 {4.723E+0, 5.311E+0, 1.722E+4, 5.370E+2, 2.913E-3},
536 {5.319E+0, 5.982E+0, 1.740E+4, 5.863E+2, 2.871E-3},
537 {5.956E+0, 6.700E+0, 1.780E+4, 6.770E+2, 2.660E-3},
538 {6.158E+0, 6.928E+0, 1.777E+4, 5.863E+2, 2.812E-3},
539 {6.203E+0, 6.979E+0, 1.795E+4, 5.863E+2, 2.776E-3},
540 {6.181E+0, 6.954E+0, 1.812E+4, 5.863E+2, 2.748E-3},
541 {6.949E+0, 7.820E+0, 1.830E+4, 5.863E+2, 2.737E-3},
542 {7.506E+0, 8.448E+0, 1.848E+4, 5.863E+2, 2.727E-3},
543 {7.648E+0, 8.609E+0, 1.866E+4, 5.863E+2, 2.697E-3},
544 {7.711E+0, 8.679E+0, 1.883E+4, 5.863E+2, 2.641E-3},
545 // Z= 91-92
546 {7.407E+0, 8.336E+0, 1.901E+4, 5.863E+2, 2.603E-3},
547 {7.290E+0, 8.204E+0, 1.918E+4, 5.863E+2, 2.673E-3}
548 };
549
550 G4double fac = 1.0 ;
551
552 // Carbon specific case for E < 40 keV
553 if ( T < 40.0 && 5 == i) {
554 fac = sqrt(T/40.0) ;
555 T = 40.0 ;
556
557 // Free electron gas model
558 } else if ( T < 10.0 ) {
559 fac = sqrt(T*0.1) ;
560 T =10.0 ;
561 }
562
563 // Main parametrisation
564 G4double slow = a[i][1] * pow(T, 0.45) ;
565 G4double shigh = log( 1.0 + a[i][3]/T + a[i][4]*T ) * a[i][2]/T ;
566 ionloss = slow*shigh*fac / (slow + shigh) ;
567
568 if ( ionloss < 0.0) { ionloss = 0.0; }
569
570 return ionloss;
571}
572
573//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
574
575G4double G4BraggModel::DEDX(const G4Material* material, G4double kineticEnergy)
576{
577 G4double eloss = 0.0;
578
579 // check DB
580 if(material != currentMaterial) {
581 currentMaterial = material;
582 iPSTAR = -1;
583 iMolecula = -1;
584 if( !HasMaterial(material) ) { iPSTAR = pstar.GetIndex(material); }
585
586 //G4cout << "%%% " <<material->GetName() << " iMolecula= "
587 // << iMolecula << " iPSTAR= " << iPSTAR << G4endl;
588
589 }
590
591 const G4int numberOfElements = material->GetNumberOfElements();
592 const G4double* theAtomicNumDensityVector =
593 material->GetAtomicNumDensityVector();
594
595 if( iPSTAR >= 0 ) {
596 return pstar.GetElectronicDEDX(iPSTAR, kineticEnergy)*material->GetDensity();
597
598 } else if(iMolecula >= 0) {
599
600 eloss = StoppingPower(material, kineticEnergy)*
601 material->GetDensity()/amu;
602
603 // Pure material ICRU49 paralmeterisation
604 } else if(1 == numberOfElements) {
605
606 G4double z = material->GetZ();
607 eloss = ElectronicStoppingPower(z, kineticEnergy)
608 * (material->GetTotNbOfAtomsPerVolume());
609
610
611 // Experimental data exist only for kinetic energy 125 keV
612 } else if( MolecIsInZiegler1988(material) ) {
613
614 // Loop over elements - calculation based on Bragg's rule
615 G4double eloss125 = 0.0 ;
616 const G4ElementVector* theElementVector =
617 material->GetElementVector();
618
619 // Loop for the elements in the material
620 for (G4int i=0; i<numberOfElements; i++) {
621 const G4Element* element = (*theElementVector)[i] ;
622 G4double z = element->GetZ() ;
623 eloss += ElectronicStoppingPower(z,kineticEnergy)
624 * theAtomicNumDensityVector[i] ;
625 eloss125 += ElectronicStoppingPower(z,125.0*keV)
626 * theAtomicNumDensityVector[i] ;
627 }
628
629 // Chemical factor is taken into account
630 eloss *= ChemicalFactor(kineticEnergy, eloss125) ;
631
632 // Brugg's rule calculation
633 } else {
634 const G4ElementVector* theElementVector =
635 material->GetElementVector() ;
636
637 // loop for the elements in the material
638 for (G4int i=0; i<numberOfElements; i++)
639 {
640 const G4Element* element = (*theElementVector)[i] ;
641 eloss += ElectronicStoppingPower(element->GetZ(), kineticEnergy)
642 * theAtomicNumDensityVector[i];
643 }
644 }
645 return eloss*theZieglerFactor;
646}
647
648//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
649
650G4bool G4BraggModel::MolecIsInZiegler1988(const G4Material* material)
651{
652 // The list of molecules from
653 // J.F.Ziegler and J.M.Manoyan, The stopping of ions in compaunds,
654 // Nucl. Inst. & Meth. in Phys. Res. B35 (1988) 215-228.
655
656 G4String myFormula = G4String(" ") ;
657 const G4String chFormula = material->GetChemicalFormula() ;
658 if (myFormula == chFormula ) { return false; }
659
660 // There are no evidence for difference of stopping power depended on
661 // phase of the compound except for water. The stopping power of the
662 // water in gas phase can be predicted using Bragg's rule.
663 //
664 // No chemical factor for water-gas
665
666 myFormula = G4String("H_2O") ;
667 const G4State theState = material->GetState() ;
668 if( theState == kStateGas && myFormula == chFormula) return false ;
669
670 const size_t numberOfMolecula = 53 ;
671
672 // The coffecient from Table.4 of Ziegler & Manoyan
673 const G4double HeEff = 2.8735 ;
674
675 static G4String nameOfMol[numberOfMolecula] = {
676 "H_2O", "C_2H_4O", "C_3H_6O", "C_2H_2", "C_H_3OH",
677 "C_2H_5OH", "C_3H_7OH", "C_3H_4", "NH_3", "C_14H_10",
678 "C_6H_6", "C_4H_10", "C_4H_6", "C_4H_8O", "CCl_4",
679 "CF_4", "C_6H_8", "C_6H_12", "C_6H_10O", "C_6H_10",
680 "C_8H_16", "C_5H_10", "C_5H_8", "C_3H_6-Cyclopropane","C_2H_4F_2",
681 "C_2H_2F_2", "C_4H_8O_2", "C_2H_6", "C_2F_6", "C_2H_6O",
682 "C_3H_6O", "C_4H_10O", "C_2H_4", "C_2H_4O", "C_2H_4S",
683 "SH_2", "CH_4", "CCLF_3", "CCl_2F_2", "CHCl_2F",
684 "(CH_3)_2S", "N_2O", "C_5H_10O", "C_8H_6", "(CH_2)_N",
685 "(C_3H_6)_N","(C_8H_8)_N", "C_3H_8", "C_3H_6-Propylene", "C_3H_6O",
686 "C_3H_6S", "C_4H_4S", "C_7H_8"
687 } ;
688
689 static G4double expStopping[numberOfMolecula] = {
690 66.1, 190.4, 258.7, 42.2, 141.5,
691 210.9, 279.6, 198.8, 31.0, 267.5,
692 122.8, 311.4, 260.3, 328.9, 391.3,
693 206.6, 374.0, 422.0, 432.0, 398.0,
694 554.0, 353.0, 326.0, 74.6, 220.5,
695 197.4, 362.0, 170.0, 330.5, 211.3,
696 262.3, 349.6, 51.3, 187.0, 236.9,
697 121.9, 35.8, 247.0, 292.6, 268.0,
698 262.3, 49.0, 398.9, 444.0, 22.91,
699 68.0, 155.0, 84.0, 74.2, 254.7,
700 306.8, 324.4, 420.0
701 } ;
702
703 static G4double expCharge[numberOfMolecula] = {
704 HeEff, HeEff, HeEff, 1.0, HeEff,
705 HeEff, HeEff, HeEff, 1.0, 1.0,
706 1.0, HeEff, HeEff, HeEff, HeEff,
707 HeEff, HeEff, HeEff, HeEff, HeEff,
708 HeEff, HeEff, HeEff, 1.0, HeEff,
709 HeEff, HeEff, HeEff, HeEff, HeEff,
710 HeEff, HeEff, 1.0, HeEff, HeEff,
711 HeEff, 1.0, HeEff, HeEff, HeEff,
712 HeEff, 1.0, HeEff, HeEff, 1.0,
713 1.0, 1.0, 1.0, 1.0, HeEff,
714 HeEff, HeEff, HeEff
715 } ;
716
717 static G4double numberOfAtomsPerMolecula[numberOfMolecula] = {
718 3.0, 7.0, 10.0, 4.0, 6.0,
719 9.0, 12.0, 7.0, 4.0, 24.0,
720 12.0, 14.0, 10.0, 13.0, 5.0,
721 5.0, 14.0, 18.0, 17.0, 17.0,
722 24.0, 15.0, 13.0, 9.0, 8.0,
723 6.0, 14.0, 8.0, 8.0, 9.0,
724 10.0, 15.0, 6.0, 7.0, 7.0,
725 3.0, 5.0, 5.0, 5.0, 5.0,
726 9.0, 3.0, 16.0, 14.0, 3.0,
727 9.0, 16.0, 11.0, 9.0, 10.0,
728 10.0, 9.0, 15.0
729 } ;
730
731 // Search for the compaund in the table
732 for (size_t i=0; i<numberOfMolecula; i++)
733 {
734 if(chFormula == nameOfMol[i]) {
735 G4double exp125 = expStopping[i] *
736 (material->GetTotNbOfAtomsPerVolume()) /
737 (expCharge[i] * numberOfAtomsPerMolecula[i]) ;
738 SetExpStopPower125(exp125);
739 return true;
740 }
741 }
742
743 return false;
744}
745
746//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
747
748G4double G4BraggModel::ChemicalFactor(G4double kineticEnergy,
749 G4double eloss125) const
750{
751 // Approximation of Chemical Factor according to
752 // J.F.Ziegler and J.M.Manoyan, The stopping of ions in compaunds,
753 // Nucl. Inst. & Meth. in Phys. Res. B35 (1988) 215-228.
754
755 G4double gamma = 1.0 + kineticEnergy/proton_mass_c2 ;
756 G4double gamma25 = 1.0 + 25.0*keV /proton_mass_c2 ;
757 G4double gamma125 = 1.0 + 125.0*keV/proton_mass_c2 ;
758 G4double beta = sqrt(1.0 - 1.0/(gamma*gamma)) ;
759 G4double beta25 = sqrt(1.0 - 1.0/(gamma25*gamma25)) ;
760 G4double beta125 = sqrt(1.0 - 1.0/(gamma125*gamma125)) ;
761
762 G4double factor = 1.0 + (expStopPower125/eloss125 - 1.0) *
763 (1.0 + exp( 1.48 * ( beta125/beta25 - 7.0 ) ) ) /
764 (1.0 + exp( 1.48 * ( beta/beta25 - 7.0 ) ) ) ;
765
766 return factor ;
767}
768
769//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
770
std::vector< G4Element * > G4ElementVector
G4State
Definition: G4Material.hh:114
@ kStateGas
Definition: G4Material.hh:114
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector unit() const
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:72
virtual G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy)
virtual G4double MaxSecondaryEnergy(const G4ParticleDefinition *, G4double kinEnergy)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
virtual G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy)
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kineticEnergy, G4double Z, G4double A, G4double cutEnergy, G4double maxEnergy)
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
virtual G4double GetParticleCharge(const G4ParticleDefinition *p, const G4Material *mat, G4double kineticEnergy)
G4double GetChargeSquareRatio() const
virtual G4double ComputeCrossSectionPerElectron(const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy)
G4BraggModel(const G4ParticleDefinition *p=0, const G4String &nam="Bragg")
Definition: G4BraggModel.cc:79
virtual ~G4BraggModel()
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition: G4Electron.cc:94
G4double GetZ() const
Definition: G4Element.hh:131
G4double EffectiveChargeSquareRatio(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
G4double GetParticleCharge(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
G4double EffectiveChargeCorrection(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
static G4LossTableManager * Instance()
G4EmCorrections * EmCorrections()
G4double GetDensity() const
Definition: G4Material.hh:179
const G4String & GetChemicalFormula() const
Definition: G4Material.hh:178
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:189
G4double GetTotNbOfAtomsPerVolume() const
Definition: G4Material.hh:208
G4State GetState() const
Definition: G4Material.hh:180
G4double GetZ() const
Definition: G4Material.cc:604
size_t GetNumberOfElements() const
Definition: G4Material.hh:185
const G4double * GetAtomicNumDensityVector() const
Definition: G4Material.hh:215
G4double GetElectronDensity() const
Definition: G4Material.hh:216
G4int GetIndex(const G4Material *)
G4double GetElectronicDEDX(G4int idx, G4double energy)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void SetProposedMomentumDirection(const G4ThreeVector &dir)
const G4String & GetParticleType() const
const G4String & GetParticleName() const
virtual void SetParticleAndCharge(const G4ParticleDefinition *, G4double q2)
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:585
G4VEmFluctuationModel * GetModelOfFluctuations()
Definition: G4VEmModel.hh:501
void SetDeexcitationFlag(G4bool val)
Definition: G4VEmModel.hh:641
G4double MaxSecondaryKinEnergy(const G4DynamicParticle *dynParticle)
Definition: G4VEmModel.hh:399
G4ParticleChangeForLoss * GetParticleChangeForLoss()
Definition: G4VEmModel.cc:95