source: trunk/source/processes/electromagnetic/lowenergy/src/G4FinalStateIonisationRudd.cc @ 846

Last change on this file since 846 was 819, checked in by garnier, 16 years ago

import all except CVS

  • Property svn:executable set to *
File size: 17.4 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//
27// $Id: G4FinalStateIonisationRudd.cc,v 1.5 2007/11/26 17:27:09 pia Exp $
28// GEANT4 tag $Name:  $
29//
30// Contact Author: Sebastien Incerti (incerti@cenbg.in2p3.fr)
31//                 Maria Grazia Pia  (Maria.Grazia.Pia@cern.ch)
32//
33///
34// Reference: TNS Geant4-DNA paper
35// Reference for implementation model: NIM. 155, pp. 145-156, 1978
36//
37// History:
38// -----------
39// Date         Name              Modification
40// 28 Apr 2007  M.G. Pia          Created in compliance with design described in TNS paper
41//    Nov 2007  S. Incerti        Implementation
42// 26 Nov 2007  MGP               Cleaned up std::
43//
44// -------------------------------------------------------------------
45
46// Class description:
47// Reference: TNS Geant4-DNA paper
48// S. Chauvie et al., Geant4 physics processes for microdosimetry simulation:
49// design foundation and implementation of the first set of models,
50// IEEE Trans. Nucl. Sci., vol. 54, no. 6, Dec. 2007.
51// Further documentation available from http://www.ge.infn.it/geant4/dna
52
53// -------------------------------------------------------------------
54
55
56#include "G4FinalStateIonisationRudd.hh"
57#include "G4Track.hh"
58#include "G4Step.hh"
59#include "G4DynamicParticle.hh"
60#include "Randomize.hh"
61
62#include "G4ParticleTypes.hh"
63#include "G4ParticleDefinition.hh"
64#include "G4Electron.hh"
65#include "G4Proton.hh"
66#include "G4SystemOfUnits.hh"
67#include "G4ParticleMomentum.hh"
68#include "G4DNAGenericIonsManager.hh"
69
70
71G4FinalStateIonisationRudd::G4FinalStateIonisationRudd()
72{
73  name = "IonisationBorn";
74  // Default energy limits (defined for protection against anomalous behaviour only)
75  lowEnergyLimitDefault = 100 * eV;
76  highEnergyLimitDefault = 100 * MeV;
77
78  G4DNAGenericIonsManager *instance;
79  instance = G4DNAGenericIonsManager::Instance();
80
81  G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
82  G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen");
83  G4ParticleDefinition* alphaPlusPlusDef = instance->GetIon("alpha++");
84  G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+");
85  G4ParticleDefinition* heliumDef = instance->GetIon("helium");
86
87  G4String proton;
88  G4String hydrogen;
89  G4String alphaPlusPlus;
90  G4String alphaPlus;
91  G4String helium;
92
93  proton = protonDef->GetParticleName();
94  lowEnergyLimit[proton] = 100. * eV;
95  highEnergyLimit[proton] = 500. * keV;
96
97  hydrogen = hydrogenDef->GetParticleName();
98  lowEnergyLimit[hydrogen] = 100. * eV;
99  highEnergyLimit[hydrogen] = 100. * MeV;
100
101  alphaPlusPlus = alphaPlusPlusDef->GetParticleName();
102  lowEnergyLimit[alphaPlusPlus] = 1. * keV;
103  highEnergyLimit[alphaPlusPlus] = 10. * MeV;
104
105  alphaPlus = alphaPlusDef->GetParticleName();
106  lowEnergyLimit[alphaPlus] = 1. * keV;
107  highEnergyLimit[alphaPlus] = 10. * MeV;
108
109  helium = heliumDef->GetParticleName();
110  lowEnergyLimit[helium] = 1. * keV;
111  highEnergyLimit[helium] = 10. * MeV;
112}
113
114
115G4FinalStateIonisationRudd::~G4FinalStateIonisationRudd()
116{ }
117
118
119
120const G4FinalStateProduct& G4FinalStateIonisationRudd::GenerateFinalState(const G4Track& track, const G4Step& /* step */)
121{
122  // Clear previous secondaries, energy deposit and particle kill status
123  product.Clear();
124
125  const G4DynamicParticle* particle = track.GetDynamicParticle();
126
127  G4double lowLim = lowEnergyLimitDefault;
128  G4double highLim = highEnergyLimitDefault;
129
130  G4double k = particle->GetKineticEnergy();
131
132  const G4String& particleName = particle->GetDefinition()->GetParticleName();
133
134  // Retrieve energy limits for the current particle type
135
136  std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
137  pos1 = lowEnergyLimit.find(particleName);
138
139  // Lower limit
140  if (pos1 != lowEnergyLimit.end())
141    {
142      lowLim = pos1->second;
143    }
144
145  // Upper limit
146  std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
147  pos2 = highEnergyLimit.find(particleName);
148
149  if (pos2 != highEnergyLimit.end())
150    {
151      highLim = pos2->second;
152    }
153
154  // Verify that the current track is within the energy limits of validity of the cross section model
155
156  if (k >= lowLim && k <= highLim)
157    {
158      // Kinetic energy of primary particle
159
160      G4ParticleDefinition* definition = particle->GetDefinition();
161      G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
162      G4double particleMass = definition->GetPDGMass();
163      G4double totalEnergy = k + particleMass;
164      G4double pSquare = k*(totalEnergy+particleMass);
165      G4double totalMomentum = std::sqrt(pSquare);
166
167      const G4String& particleName = definition->GetParticleName();
168 
169      G4int ionizationShell = cross.RandomSelect(k,particleName);
170 
171      G4double secondaryKinetic = RandomizeEjectedElectronEnergy(definition,k,ionizationShell);
172 
173      G4double bindingEnergy = waterStructure.IonisationEnergy(ionizationShell);
174
175      G4double cosTheta = 0.;
176      G4double phi = 0.; 
177      RandomizeEjectedElectronDirection(definition, k,secondaryKinetic, cosTheta, phi);
178
179      G4double sinTheta = std::sqrt(1.-cosTheta*cosTheta);
180      G4double dirX = sinTheta*std::cos(phi);
181      G4double dirY = sinTheta*std::sin(phi);
182      G4double dirZ = cosTheta;
183      G4ThreeVector deltaDirection(dirX,dirY,dirZ);
184      deltaDirection.rotateUz(primaryDirection);
185
186      G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
187
188      // Primary Particle Direction
189      G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
190      G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
191      G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
192      G4double finalMomentum = std::sqrt(finalPx*finalPx+finalPy*finalPy+finalPz*finalPz);
193      finalPx /= finalMomentum;
194      finalPy /= finalMomentum;
195      finalPz /= finalMomentum;
196
197      product.ModifyPrimaryParticle(finalPx,finalPy,finalPz,k-bindingEnergy-secondaryKinetic);
198      product.AddEnergyDeposit(bindingEnergy);
199
200      G4DynamicParticle* aElectron = new G4DynamicParticle(G4Electron::Electron(),deltaDirection,secondaryKinetic);
201      product.AddSecondary(aElectron);
202    }
203
204  if (k < lowLim) {product.KillPrimaryParticle();product.AddEnergyDeposit(k);}
205 
206  return product;
207}
208
209
210
211G4double G4FinalStateIonisationRudd::RandomizeEjectedElectronEnergy(G4ParticleDefinition* particleDefinition, 
212                                                                    G4double k, 
213                                                                    G4int shell)
214{
215  G4double maximumKineticEnergyTransfer = 0.;
216 
217  G4DNAGenericIonsManager *instance;
218  instance = G4DNAGenericIonsManager::Instance();
219
220  if (particleDefinition == G4Proton::ProtonDefinition() 
221      || particleDefinition == instance->GetIon("hydrogen"))
222         
223    { 
224      maximumKineticEnergyTransfer= 4.* (electron_mass_c2 / proton_mass_c2) * k;
225    }
226
227  if (particleDefinition == instance->GetIon("helium") 
228      || particleDefinition == instance->GetIon("alpha+")
229      || particleDefinition == instance->GetIon("alpha++"))
230    { 
231      maximumKineticEnergyTransfer= 4.* (0.511 / 3728) * k;
232    }
233
234  G4double crossSectionMaximum = 0.;
235  for(G4double value=waterStructure.IonisationEnergy(shell); value<=4.*waterStructure.IonisationEnergy(shell) ; value+=0.1*eV)
236    {
237      G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k, value, shell);
238      if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
239    }
240  G4double secElecKinetic = 0.;
241  do{
242    secElecKinetic = G4UniformRand() * maximumKineticEnergyTransfer;
243  } while(G4UniformRand()*crossSectionMaximum > DifferentialCrossSection(particleDefinition, 
244                                                                         k,
245                                                                         secElecKinetic+waterStructure.IonisationEnergy(shell),
246                                                                         shell));
247
248  return(secElecKinetic);
249}
250
251
252void G4FinalStateIonisationRudd::RandomizeEjectedElectronDirection(G4ParticleDefinition* particleDefinition, 
253                                                                   G4double k, 
254                                                                   G4double secKinetic, 
255                                                                   G4double cosTheta, 
256                                                                   G4double phi )
257{
258  G4DNAGenericIonsManager *instance;
259  instance = G4DNAGenericIonsManager::Instance();
260
261  G4double maxSecKinetic = 0.;
262 
263  if (particleDefinition == G4Proton::ProtonDefinition() 
264      || particleDefinition == instance->GetIon("hydrogen")) 
265    { 
266      maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
267    }
268 
269  if (particleDefinition == instance->GetIon("helium") 
270      || particleDefinition == instance->GetIon("alpha+")
271      || particleDefinition == instance->GetIon("alpha++"))
272    { 
273      maxSecKinetic = 4.* (0.511 / 3728) * k;
274    }
275 
276  phi = twopi * G4UniformRand();
277  cosTheta = std::sqrt(secKinetic / maxSecKinetic);
278}
279
280
281G4double G4FinalStateIonisationRudd::DifferentialCrossSection(G4ParticleDefinition* particleDefinition, 
282                                                              G4double k, 
283                                                              G4double energyTransfer, 
284                                                              G4int ionizationLevelIndex)
285{
286  // Shells ids are 0 1 2 3 4 (4 is k shell)
287  // !!Attention, "energyTransfer" here is the energy transfered to the electron which means
288  //             that the secondary kinetic energy is w = energyTransfer - bindingEnergy
289  //
290  //   ds            S                F1(nu) + w * F2(nu)
291  //  ---- = G(k) * ----     -------------------------------------------
292  //   dw            Bj       (1+w)^3 * [1 + exp{alpha * (w - wc) / nu}]
293  //
294  // w is the secondary electron kinetic Energy in eV
295  //
296  // All the other parameters can be found in Rudd's Papers
297  //
298  // M.Eugene Rudd, 1988, User-Friendly model for the energy distribution of
299  // electrons from protons or electron collisions. Nucl. Tracks Rad. Meas.Vol 16 N0 2/3 pp 219-218
300  //
301
302  const G4int j=ionizationLevelIndex;
303
304  G4double A1 ; 
305  G4double B1 ; 
306  G4double C1 ; 
307  G4double D1 ; 
308  G4double E1 ;
309  G4double A2 ; 
310  G4double B2 ; 
311  G4double C2 ; 
312  G4double D2 ; 
313  G4double alphaConst ;
314
315  if (j == 4) 
316    {
317      //Data For Liquid Water K SHELL from Dingfelder (Protons in Water)
318      A1 = 1.25; 
319      B1 = 0.5; 
320      C1 = 1.00; 
321      D1 = 1.00; 
322      E1 = 3.00; 
323      A2 = 1.10; 
324      B2 = 1.30;
325      C2 = 1.00; 
326      D2 = 0.00; 
327      alphaConst = 0.66;
328    }
329  else 
330    {
331      //Data For Liquid Water from Dingfelder (Protons in Water)
332      A1 = 1.02; 
333      B1 = 82.0; 
334      C1 = 0.45; 
335      D1 = -0.80; 
336      E1 = 0.38; 
337      A2 = 1.07; 
338      B2 = 14.6;
339      C2 = 0.60; 
340      D2 = 0.04; 
341      alphaConst = 0.64;
342    }
343 
344  const G4double n = 2.;
345  const G4double Gj[5] = {0.99, 1.11, 1.11, 0.52, 1.};
346
347  //const G4double I[5]={12.61*eV, 14.73*eV, 18.55*eV, 32.2*eV, 539.7*eV}; // for water Vapor
348  //const G4double energyConstant[]={10.79*eV, 13.39*eV, 16.05*eV, 32.30*eV, 539.*eV};
349
350  G4DNAGenericIonsManager* instance;
351  instance = G4DNAGenericIonsManager::Instance();
352
353  G4double wBig = (energyTransfer - waterStructure.IonisationEnergy(ionizationLevelIndex));
354  G4double w = wBig / waterStructure.IonisationEnergy(ionizationLevelIndex);
355  G4double Ry = 13.6*eV;
356
357  G4double tau = 0.;
358
359  if (particleDefinition == G4Proton::ProtonDefinition() 
360      || particleDefinition == instance->GetIon("hydrogen")) 
361    {
362      tau = (electron_mass_c2/proton_mass_c2) * k ;
363    }
364   
365  if ( particleDefinition == instance->GetIon("helium") 
366       || particleDefinition == instance->GetIon("alpha+")
367       || particleDefinition == instance->GetIon("alpha++")) 
368    {
369      tau = (0.511/3728.) * k ;
370    }
371 
372  G4double S = 4.*pi * Bohr_radius*Bohr_radius * n * std::pow((Ry/waterStructure.IonisationEnergy(ionizationLevelIndex)),2);
373  G4double v2 = tau / waterStructure.IonisationEnergy(ionizationLevelIndex);
374  G4double v = std::sqrt(v2);
375  G4double wc = 4.*v2 - 2.*v - (Ry/(4.*waterStructure.IonisationEnergy(ionizationLevelIndex)));
376
377  G4double L1 = (C1* std::pow(v,(D1))) / (1.+ E1*std::pow(v, (D1+4.)));
378  G4double L2 = C2*std::pow(v,(D2));
379  G4double H1 = (A1*std::log(1.+v2)) / (v2+(B1/v2));
380  G4double H2 = (A2/v2) + (B2/(v2*v2));
381
382  G4double F1 = L1+H1;
383  G4double F2 = (L2*H2)/(L2+H2);
384
385  G4double sigma = CorrectionFactor(particleDefinition, k/eV) 
386    * Gj[j] * (S/waterStructure.IonisationEnergy(ionizationLevelIndex)) 
387    * ( (F1+w*F2) / ( std::pow((1.+w),3) * ( 1.+std::exp(alphaConst*(w-wc)/v))) );
388   
389  if (    particleDefinition == G4Proton::ProtonDefinition() 
390          || particleDefinition == instance->GetIon("hydrogen")
391          ) 
392    {
393      return(sigma);
394    }
395
396  // ------------
397 
398  if (particleDefinition == instance->GetIon("alpha++") ) 
399    {
400      slaterEffectiveCharge[0]=0.;
401      slaterEffectiveCharge[1]=0.;
402      slaterEffectiveCharge[2]=0.;
403      sCoefficient[0]=0.;
404      sCoefficient[1]=0.;
405      sCoefficient[2]=0.;
406    }
407
408  if (particleDefinition == instance->GetIon("alpha+") ) 
409    {
410      slaterEffectiveCharge[0]=2.0;
411      slaterEffectiveCharge[1]=1.15;
412      slaterEffectiveCharge[2]=1.15;
413      sCoefficient[0]=0.7;
414      sCoefficient[1]=0.15;
415      sCoefficient[2]=0.15;
416    }
417
418  if (particleDefinition == instance->GetIon("helium") ) 
419    {
420      slaterEffectiveCharge[0]=1.7;
421      slaterEffectiveCharge[1]=1.15;
422      slaterEffectiveCharge[2]=1.15;
423      sCoefficient[0]=0.5;
424      sCoefficient[1]=0.25;
425      sCoefficient[2]=0.25;
426    }
427 
428  if (    particleDefinition == instance->GetIon("helium") 
429          || particleDefinition == instance->GetIon("alpha+")
430          || particleDefinition == instance->GetIon("alpha++")
431          ) 
432    {
433      sigma = Gj[j] * (S/waterStructure.IonisationEnergy(ionizationLevelIndex)) * ( (F1+w*F2) / ( std::pow((1.+w),3) * ( 1.+std::exp(alphaConst*(w-wc)/v))) );
434   
435      G4double zEff = particleDefinition->GetPDGCharge() / eplus + particleDefinition->GetLeptonNumber();
436 
437      zEff -= ( sCoefficient[0] * S_1s(k, energyTransfer, slaterEffectiveCharge[0], 1.) +
438                sCoefficient[1] * S_2s(k, energyTransfer, slaterEffectiveCharge[1], 2.) +
439                sCoefficient[2] * S_2p(k, energyTransfer, slaterEffectiveCharge[2], 2.) );
440           
441      return zEff * zEff * sigma ;
442    } 
443 
444  return 0;
445}
446
447G4double G4FinalStateIonisationRudd::S_1s(G4double t, 
448                                          G4double energyTransferred, 
449                                          G4double slaterEffectiveChg, 
450                                          G4double shellNumber)
451{
452  // 1 - e^(-2r) * ( 1 + 2 r + 2 r^2)
453  // Dingfelder, in Chattanooga 2005 proceedings, formula (7)
454 
455  G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
456  G4double value = 1. - std::exp(-2 * r) * ( ( 2. * r + 2. ) * r + 1. );
457 
458  return value;
459}
460
461
462
463G4double G4FinalStateIonisationRudd::S_2s(G4double t,
464                                          G4double energyTransferred, 
465                                          G4double slaterEffectiveChg, 
466                                          G4double shellNumber)
467{
468  // 1 - e^(-2 r) * ( 1 + 2 r + 2 r^2 + 2 r^4)
469  // Dingfelder, in Chattanooga 2005 proceedings, formula (8)
470
471  G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
472  G4double value =  1. - std::exp(-2 * r) * (((2. * r * r + 2.) * r + 2.) * r + 1.);
473
474  return value;
475 
476}
477
478
479
480G4double G4FinalStateIonisationRudd::S_2p(G4double t, 
481                                          G4double energyTransferred,
482                                          G4double slaterEffectiveChg, 
483                                          G4double shellNumber)
484{
485  // 1 - e^(-2 r) * ( 1 + 2 r + 2 r^2 + 4/3 r^3 + 2/3 r^4)
486  // Dingfelder, in Chattanooga 2005 proceedings, formula (9)
487
488  G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
489  G4double value =  1. - std::exp(-2 * r) * (((( 2./3. * r + 4./3.) * r + 2.) * r + 2.) * r  + 1.);
490
491  return value;
492}
493
494
495
496G4double G4FinalStateIonisationRudd::R(G4double t,
497                                       G4double energyTransferred,
498                                       G4double slaterEffectiveChg,
499                                       G4double shellNumber) 
500{
501  // tElectron = m_electron / m_alpha * t
502  // Hardcoded in Riccardo's implementation; to be corrected
503  // Dingfelder, in Chattanooga 2005 proceedings, p 4
504
505  G4double tElectron = 0.511/3728. * t;
506  G4double value = 2. * tElectron * slaterEffectiveChg / (energyTransferred * shellNumber);
507 
508  return value;
509}
510
511
512
513G4double G4FinalStateIonisationRudd::CorrectionFactor(G4ParticleDefinition* particleDefinition, G4double k) 
514{
515  G4DNAGenericIonsManager *instance;
516  instance = G4DNAGenericIonsManager::Instance();
517
518  if (particleDefinition == G4Proton::Proton()) 
519    {
520      return(1.);
521    }
522  else 
523    if (particleDefinition == instance->GetIon("hydrogen")) 
524      { 
525        G4double value = (std::log(k/eV)-4.2)/0.5;
526        return((0.8/(1+std::exp(value))) + 0.9);
527      }
528    else 
529      {   
530        return(1.);
531      }
532}
Note: See TracBrowser for help on using the repository browser.