source: trunk/source/processes/electromagnetic/standard/src/G4BraggModel.cc@ 969

Last change on this file since 969 was 961, checked in by garnier, 17 years ago

update processes

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