Ignore:
Timestamp:
Apr 6, 2009, 12:21:12 PM (16 years ago)
Author:
garnier
Message:

update processes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/processes/electromagnetic/standard/src/G4IonFluctuations.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4IonFluctuations.cc,v 1.5.2.1 2008/04/25 00:22:53 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4IonFluctuations.cc,v 1.25 2009/02/19 19:17:50 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4646// 16-10-03 Changed interface to Initialisation (V.Ivanchenko)
    4747// 27-09-07 Use FermiEnergy from material, add cut dependence (V.Ivanchenko)
     48// 01-02-08 Add protection for small energies and optimise the code (V.Ivanchenko)
     49// 01-06-08 Added initialisation of effective charge prestep (V.Ivanchenko)
    4850//
    4951// Class Description:
     
    6062#include "G4Material.hh"
    6163#include "G4DynamicParticle.hh"
    62 #include "G4ParticleDefinition.hh"
    6364
    6465//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    6768
    6869G4IonFluctuations::G4IonFluctuations(const G4String& nam)
    69  :G4VEmFluctuationModel(nam),
    70   particle(0),
    71   minNumberInteractionsBohr(10.0),
    72   theBohrBeta2(50.0*keV/proton_mass_c2),
    73   minFraction(0.2),
    74   xmin(0.2),
    75   minLoss(0.001*eV)
     70  : G4VEmFluctuationModel(nam),
     71    particle(0),
     72    particleMass(proton_mass_c2),
     73    charge(1.0),
     74    chargeSquare(1.0),
     75    effChargeSquare(1.0),
     76    parameter(10.0*CLHEP::MeV/CLHEP::proton_mass_c2),
     77    minNumberInteractionsBohr(0.0),
     78    theBohrBeta2(50.0*keV/CLHEP::proton_mass_c2),
     79    minFraction(0.2),
     80    xmin(0.2),
     81    minLoss(0.001*eV)
    7682{}
    7783
     
    8995  charge         = part->GetPDGCharge()/eplus;
    9096  chargeSquare   = charge*charge;
    91   chargeSqRatio  = 1.0;
     97  effChargeSquare= chargeSquare;
     98  uniFluct.InitialiseMe(part);
    9299}
    93100
     
    96103G4double G4IonFluctuations::SampleFluctuations(const G4Material* material,
    97104                                               const G4DynamicParticle* dp,
    98                                                      G4double& tmax,
    99                                                      G4double& length,
    100                                                      G4double& meanLoss)
    101 {
     105                                               G4double& tmax,
     106                                               G4double& length,
     107                                               G4double& meanLoss)
     108{
     109  //  G4cout << "### meanLoss= " << meanLoss << G4endl;
    102110  if(meanLoss <= minLoss) return meanLoss;
    103   //  G4cout << "### meanLoss= " << meanLoss << G4endl;
     111
     112  //G4cout << "G4IonFluctuations::SampleFluctuations E(MeV)= " << dp->GetKineticEnergy()
     113  //     << "  Elim(MeV)= " << parameter*charge*particleMass << G4endl;
     114
     115  // Vavilov fluctuations
     116  if(dp->GetKineticEnergy() > parameter*charge*particleMass) {
     117    return uniFluct.SampleFluctuations(material,dp,tmax,length,meanLoss);
     118  }
    104119
    105120  G4double siga = Dispersion(material,dp,tmax,length);
     
    107122 
    108123  G4double navr = minNumberInteractionsBohr;
    109 
    110124  navr = meanLoss*meanLoss/siga;
    111   //  G4cout << "### siga= " << sqrt(siga) << "  navr= " << navr << G4endl;
     125  //G4cout << "### siga= " << sqrt(siga) << "  navr= " << navr << G4endl;
    112126
    113127  // Gaussian fluctuation
     
    126140    //       G4cout << "siga= " << siga << G4endl;
    127141    siga = sqrt(siga);
    128 
    129142    G4double lossmax = meanLoss+meanLoss;
    130     do {
    131       loss = G4RandGauss::shoot(meanLoss,siga);
    132     } while (0.0 > loss || loss > lossmax);
    133 
     143
     144    if(siga > 5.0*meanLoss) {
     145      loss = lossmax*G4UniformRand();
     146    } else {
     147      do {
     148        loss = G4RandGauss::shoot(meanLoss,siga);
     149      } while (0.0 > loss || loss > lossmax);
     150    }
    134151  // Poisson fluctuations
    135152  } else {
     
    139156  }
    140157
    141   //  G4cout << "meanLoss= " << meanLoss << " loss= " << loss << G4endl;
     158  //G4cout << "meanLoss= " << meanLoss << " loss= " << loss << G4endl;
    142159  return loss;
    143160}
     
    145162//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    146163
    147 G4double G4IonFluctuations::Dispersion(
    148                           const G4Material* material,
    149                           const G4DynamicParticle* dp,
    150                                 G4double& tmax,
    151                                 G4double& length)
    152 {
    153   particle       = dp->GetDefinition();
    154   charge         = particle->GetPDGCharge()/eplus;
    155   G4double Q2    = charge*charge;
    156   particleMass   = particle->GetPDGMass();
    157   G4double q     = dp->GetCharge()/eplus;
    158   chargeSquare   = q*q;
    159   chargeSqRatio  = chargeSquare/Q2;
    160 
    161   //chargeSquare   = charge*charge;
    162   //chargeSqRatio  = 1.0;
     164G4double G4IonFluctuations::Dispersion(const G4Material* material,
     165                                       const G4DynamicParticle* dp,
     166                                       G4double& tmax,
     167                                       G4double& length)
     168{
     169  kineticEnergy = dp->GetKineticEnergy();
     170  G4double etot = kineticEnergy + particleMass;
     171  beta2 = kineticEnergy*(kineticEnergy + 2.*particleMass)/(etot*etot);
    163172
    164173  G4double electronDensity = material->GetElectronDensity();
    165   kineticEnergy  = dp->GetKineticEnergy();
    166   G4double etot = kineticEnergy + particleMass;
    167   //G4cout << "e= " <<  kineticEnergy << " m= " << particleMass
    168   //     << " tmax= " << tmax << " l= " << length << " q^2= " << chargeSquare << G4endl;
    169   beta2 = kineticEnergy*(kineticEnergy + 2.*particleMass)/(etot*etot);
    170 
     174
     175  /*
     176  G4cout << "e= " <<  kineticEnergy << " m= " << particleMass
     177         << " tmax= " << tmax << " l= " << length
     178         << " q^2= " << effChargeSquare << " beta2=" << beta2<< G4endl;
     179  */
    171180  G4double siga = (1. - beta2*0.5)*tmax*length*electronDensity*
    172     twopi_mc2_rcl2*Q2/beta2;
     181    twopi_mc2_rcl2*chargeSquare/beta2;
    173182
    174183  // Low velocity - additional ion charge fluctuations according to
    175184  // Q.Yang et al., NIM B61(1991)149-155.
    176   G4double zeff  = electronDensity/(material->GetTotNbOfAtomsPerVolume());
    177   //G4cout << "siga= " << siga << " zeff= " << zeff << " c= " << c << G4endl;
    178 
    179   G4double f = 0.0;
    180 
    181   // correction factors with cut dependence 
    182   if ( beta2 < 3.0*theBohrBeta2*zeff ) {
    183 
    184     G4double a = CoeffitientA (zeff);
    185     G4double b = CoeffitientB (material, zeff);
    186     //     G4cout << "a= " << a <<  " b= " << b << G4endl;
    187     f = a*chargeSqRatio + b;
    188   } else {
    189  
    190     // H.Geissel et al. NIM B, 195 (2002) 3.
    191     f = RelativisticFactor(material, zeff);
    192   }
     185  //G4cout << "sigE= " << sqrt(siga) << " charge= " << charge <<G4endl;
     186
     187  G4double Z = electronDensity/material->GetTotNbOfAtomsPerVolume();
     188 
     189  G4double fac = Factor(material, Z);
    193190
    194191  // heavy ion correction
     
    196193  if(beta2 > theBohrBeta2)  f1/= beta2;
    197194  else                      f1/= theBohrBeta2;
    198   if(f1 > 2.0) f1 = 2.0;
    199   f *= (1.0 + f1);
    200 
    201   if(f > 1.0) {
    202     siga *= (1. + (f - 1.0)*2.0*electron_mass_c2*beta2/(tmax*(1.0 - beta2)));
    203   }
    204   //  G4cout << "siga= " << siga << G4endl;
     195  if(f1 > 2.5) f1 = 2.5;
     196  fac *= (1.0 + f1);
     197
     198  // taking into account the cut
     199  if(fac > 1.0) {
     200    siga *= (1.0 + (fac - 1.0)*2.0*electron_mass_c2*beta2/(tmax*(1.0 - beta2)));
     201  }
     202  //G4cout << "siga(keV)= " << sqrt(siga)/keV << " fac= " << fac
     203  //     << "  f1= " << f1 << G4endl;
    205204
    206205  return siga;
     
    209208//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    210209
    211 G4double G4IonFluctuations::CoeffitientA(G4double& zeff)
     210G4double G4IonFluctuations::Factor(const G4Material* material, G4double Z)
    212211{
    213212  // The aproximation of energy loss fluctuations
     
    215214
    216215  // Reduced energy in MeV/AMU
    217   G4double energy = kineticEnergy * amu_c2/(particleMass*MeV) ;
    218   static G4double a[96][4] = {
     216  G4double energy = kineticEnergy *amu_c2/(particleMass*MeV) ;
     217
     218  // simple approximation for higher beta2
     219  G4double s1 = RelativisticFactor(material, Z);
     220
     221  // tabulation for lower beta2
     222  if( beta2 < 3.0*theBohrBeta2*Z ) {
     223
     224    static G4double a[96][4] = {
    219225 {-0.3291, -0.8312,  0.2460, -1.0220},
    220226 {-0.5615, -0.5898,  0.5205, -0.7258},
     
    260266 {-0.3972, -0.3600,  1.0260, -0.5842},
    261267
    262 {-0.3985, -0.3803,  1.0200, -0.6013},
     268 {-0.3985, -0.3803,  1.0200, -0.6013},
    263269 {-0.3985, -0.3979,  1.0150, -0.6168},
    264270 {-0.3968, -0.3990,  1.0160, -0.6195},
     
    322328 {-0.4284, -0.3204,  1.6290, -0.6380},
    323329 {-0.4227, -0.3217,  1.6360, -0.6438}
    324   } ;
    325 
    326   G4int iz = (G4int)zeff - 2 ;
    327   if( 0 > iz ) iz = 0 ;
    328   if(95 < iz ) iz = 95 ;
    329 
    330   G4double q = 1.0 / (1.0 + a[iz][0]*pow(energy,a[iz][1])+
    331                           + a[iz][2]*pow(energy,a[iz][3])) ;
    332 
    333   return q ;
    334 }
    335 
    336 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    337 
    338 G4double G4IonFluctuations::CoeffitientB(const G4Material* material, G4double& zeff)
    339 {
    340   // The aproximation of energy loss fluctuations
    341   // Q.Yang et al., NIM B61(1991)149-155.
    342 
    343   // Reduced energy in MeV/AMU
    344   G4double energy = kineticEnergy *amu_c2/(particleMass*MeV) ;
     330    } ;
     331
     332    G4int iz = G4int(Z) - 2;
     333    if( 0 > iz )      iz = 0;
     334    else if(95 < iz ) iz = 95;
     335
     336    G4double ss = 1.0 + a[iz][0]*pow(energy,a[iz][1])+
     337      + a[iz][2]*pow(energy,a[iz][3]);
     338 
     339    // protection for the validity range for low beta
     340    G4double slim = 0.001;
     341    if(ss < slim) s1 = 1.0/slim;
     342    // for high value of beta
     343    else if(s1*ss < 1.0) s1 = 1.0/ss;
     344  }
    345345
    346346  G4int i = 0 ;
     
    366366  // ions
    367367  } else {
    368     factor = charge * pow(charge/zeff, 0.3333) ;
     368
     369    factor = charge * pow(charge/Z, 0.33333333);
    369370
    370371    if( kStateGas == material->GetState() ) {
     
    378379
    379380    } else {
    380       energy /= (charge * sqrt(charge*zeff)) ;
     381      energy /= (charge * sqrt(charge*Z)) ;
    381382      i = 4 ;
    382383    }
    383384  }
    384385
    385   G4double x = b[i][2] * (1.0 - exp( - energy * b[i][3] )) ;
    386 
    387   G4double q = factor * x * b[i][0] /
    388              ((energy - b[i][1])*(energy - b[i][1]) + x*x) ;
    389 
    390   return q ;
    391 }
    392 
    393 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    394 
    395 G4double G4IonFluctuations::RelativisticFactor(const G4Material* material,
    396                                                G4double& zeff)
    397 {
     386  G4double x = b[i][2];
     387  G4double y = energy * b[i][3];
     388  if(y <= 0.2) x *= (y*(1.0 - 0.5*y));
     389  else         x *= (1.0 - exp(-y));
     390
     391  y = energy - b[i][1];
     392
     393  G4double s2 = factor * x * b[i][0] / (y*y + x*x);
     394  /* 
     395  G4cout << "s1= " << s1 << " s2= " << s2 << " q^2= " << effChargeSquare
     396         << " e= " << energy << G4endl;
     397  */
     398  return s1*effChargeSquare/chargeSquare + s2;
     399}
     400
     401//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     402
     403G4double G4IonFluctuations::RelativisticFactor(const G4Material* mat,
     404                                               G4double Z)
     405{
     406  G4double eF = mat->GetIonisation()->GetFermiEnergy();
     407  G4double I  = mat->GetIonisation()->GetMeanExcitationEnergy();
     408
    398409  // H.Geissel et al. NIM B, 195 (2002) 3.
    399   G4double eF = material->GetIonisation()->GetFermiEnergy();
    400410  G4double bF2= 2.0*eF/electron_mass_c2;
    401   G4double I  = material->GetIonisation()->GetMeanExcitationEnergy();
    402   G4double f  = 0.4*(1.0 - beta2)/((1.0 - 0.5*beta2)*zeff);
     411  G4double f  = 0.4*(1.0 - beta2)/((1.0 - 0.5*beta2)*Z);
    403412  if(beta2 > bF2) f *= log(2.0*electron_mass_c2*beta2/I)*bF2/beta2;
    404413  else            f *= log(4.0*eF/I);
    405  
     414
     415  //  G4cout << "f= " << f << " beta2= " << beta2
     416  //     << " bf2= " << bF2 << " q^2= " << chargeSquare << G4endl;
     417
    406418  return 1.0 + f;
    407419}
    408420
    409421//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     422
     423void G4IonFluctuations::SetParticleAndCharge(const G4ParticleDefinition* part,
     424                                             G4double q2)
     425{
     426  if(part != particle) {
     427    particle       = part;
     428    particleMass   = part->GetPDGMass();
     429    charge         = part->GetPDGCharge()/eplus;
     430    chargeSquare   = charge*charge;
     431  }
     432  effChargeSquare  = q2;
     433  uniFluct.SetParticleAndCharge(part, q2);
     434}
     435
     436//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
Note: See TracChangeset for help on using the changeset viewer.