Geant4  10.03
G4IonisParamMat.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: G4IonisParamMat.cc 97248 2016-05-30 15:00:11Z gcosmo $
27 //
28 //
29 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
30 
31 // 09-07-98, data moved from G4Material, M.Maire
32 // 18-07-98, bug corrected in ComputeDensityEffect() for gas
33 // 16-01-01, bug corrected in ComputeDensityEffect() E100eV (L.Urban)
34 // 08-02-01, fShellCorrectionVector correctly handled (mma)
35 // 28-10-02, add setMeanExcitationEnergy (V.Ivanchenko)
36 // 06-09-04, factor 2 to shell correction term (V.Ivanchenko)
37 // 10-05-05, add a missing coma in FindMeanExcitationEnergy() - Bug#746 (mma)
38 // 27-09-07, add computation of parameters for ions (V.Ivanchenko)
39 // 04-03-08, remove reference to G4NistManager. Add fBirks constant (mma)
40 // 30-10-09, add G4DensityEffectData class and density effect computation (VI)
41 
42 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
43 
44 #include "G4IonisParamMat.hh"
45 #include "G4Material.hh"
46 #include "G4DensityEffectData.hh"
47 #include "G4NistManager.hh"
48 #include "G4Pow.hh"
49 #include "G4PhysicalConstants.hh"
50 #include "G4SystemOfUnits.hh"
51 
53 
54 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
55 
57  : fMaterial(material)
58 {
59  fBirks = 0.;
60  fMeanEnergyPerIon = 0.0;
61  twoln10 = 2.*G4Pow::GetInstance()->logZ(10);
62 
63  // minimal set of default parameters for density effect
64  fCdensity = 0.0;
65  fD0density = 0.0;
66  fAdjustmentFactor = 1.0;
67  if(fDensityData == nullptr) { fDensityData = new G4DensityEffectData(); }
68 
69  // compute parameters
74 }
75 
76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
77 
78 // Fake default constructor - sets only member data and allocates memory
79 // for usage restricted to object persistency
80 
82  : fMaterial(nullptr), fShellCorrectionVector(nullptr)
83 {
85  fLogMeanExcEnergy = 0.0;
86  fTaul = 0.0;
87  fCdensity = 0.0;
88  fMdensity = 0.0;
89  fAdensity = 0.0;
90  fX0density = 0.0;
91  fX1density = 0.0;
92  fD0density = 0.0;
93  fPlasmaEnergy = 0.0;
94  fAdjustmentFactor = 0.0;
95  fF1fluct = 0.0;
96  fF2fluct = 0.0;
97  fEnergy1fluct = 0.0;
98  fLogEnergy1fluct = 0.0;
99  fEnergy2fluct = 0.0;
100  fLogEnergy2fluct = 0.0;
101  fEnergy0fluct = 0.0;
102  fRateionexcfluct = 0.0;
103  fZeff = 0.0;
104  fFermiEnergy = 0.0;
105  fLfactor = 0.0;
106  fInvA23 = 0.0;
107  fBirks = 0.0;
108  fMeanEnergyPerIon = 0.0;
109  twoln10 = 2.*G4Pow::GetInstance()->logZ(10);
110 
111  if(fDensityData == nullptr) { fDensityData = new G4DensityEffectData(); }
112 }
113 
114 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
115 
117 {
119  if (fDensityData) { delete fDensityData; }
120  fDensityData = nullptr;
121  fShellCorrectionVector = nullptr;
122 }
123 
124 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
125 
127 {
128  // compute mean excitation energy and shell correction vector
129  fTaul = (*(fMaterial->GetElementVector()))[0]->GetIonisation()->GetTaul();
130 
132  fLogMeanExcEnergy = 0.;
133 
134  size_t nElements = fMaterial->GetNumberOfElements();
135  const G4ElementVector* elmVector = fMaterial->GetElementVector();
136  const G4double* nAtomsPerVolume = fMaterial->GetVecNbOfAtomsPerVolume();
137 
139 
140  // Chemical formula defines mean excitation energy
141  if(fMeanExcitationEnergy > 0.0) {
143 
144  // Compute average
145  } else {
146  for (size_t i=0; i < nElements; i++) {
147  const G4Element* elm = (*elmVector)[i];
148  fLogMeanExcEnergy += nAtomsPerVolume[i]*elm->GetZ()
150  }
153  }
154 
156 
157  for (G4int j=0; j<=2; j++)
158  {
159  fShellCorrectionVector[j] = 0.;
160 
161  for (size_t k=0; k<nElements; k++) {
162  fShellCorrectionVector[j] += nAtomsPerVolume[k]
163  *(((*elmVector)[k])->GetIonisation()->GetShellCorrectionVector())[j];
164  }
166  }
167 }
168 
169 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
170 
172 {
173  return fDensityData;
174 }
175 
176 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
177 
179 {
181 
182  // Check if density effect data exist in the table
183  // R.M. Sternheimer, Atomic Data and Nuclear Data Tables, 30: 261 (1984)
186  G4int Z0 = ((*(fMaterial->GetElementVector()))[0])->GetZasInt();
187 
188  // for simple non-NIST materials
189  G4double corr = 0.0;
190  if(idx < 0 && 1 == nelm) {
192 
193  // Correction for base material or for non-nominal density
194  // Except cases of very different density defined in user code
195  if(idx >= 0) {
196  const G4Material* bmat = fMaterial->GetBaseMaterial();
197  if(bmat) {
198  corr = G4Log(bmat->GetDensity()/fMaterial->GetDensity());
199  } else {
201  if(dens <= 0.0) { idx = -1; }
202  else {
203  corr = G4Log(dens/fMaterial->GetDensity());
204  }
205  }
206  // 1.0 is an arbitrary empirical limit
207  // parameterisation with very different density is not applicable
208  if(std::abs(corr) > 1.0) { idx = -1; }
209  }
210  }
211 
212  //G4cout<<"DensityEffect for "<<fMaterial->GetName()<<" "<< idx << G4endl;
213 
214  if(idx >= 0) {
215 
216  // Take parameters for the density effect correction from
217  // R.M. Sternheimer et al. Density Effect For The Ionization Loss
218  // of Charged Particles in Various Substances.
219  // Atom. Data Nucl. Data Tabl. 30 (1984) 261-271.
220 
229 
230  // parameter C is computed and not taken from Sternheimer tables
231  //fCdensity = 1. + 2*G4Log(fMeanExcitationEnergy/fPlasmaEnergy);
232  //G4cout << "IonisParamMat: " << fMaterial->GetName()
233  // << " Cst= " << Cdensity << " C= " << fCdensity << G4endl;
234 
235  // correction on nominal density
236  fCdensity += corr;
237  fX0density += corr/twoln10;
238  fX1density += corr/twoln10;
239 
240  } else {
241 
242  static const G4double Cd2 = 4*pi*hbarc_squared*classic_electr_radius;
244 
245  // Compute parameters for the density effect correction in DE/Dx formula.
246  // The parametrization is from R.M. Sternheimer, Phys. Rev.B,3:3681 (1971)
247  G4int icase;
248 
250  //
251  // condensed materials
252  //
253  if ((State == kStateSolid)||(State == kStateLiquid)) {
254 
255  static const G4double E100eV = 100.*eV;
256  static const G4double ClimiS[] = {3.681 , 5.215 };
257  static const G4double X0valS[] = {1.0 , 1.5 };
258  static const G4double X1valS[] = {2.0 , 3.0 };
259 
260  if(fMeanExcitationEnergy < E100eV) { icase = 0; }
261  else { icase = 1; }
262 
263  if(fCdensity < ClimiS[icase]) { fX0density = 0.2; }
264  else { fX0density = 0.326*fCdensity - X0valS[icase]; }
265 
266  fX1density = X1valS[icase]; fMdensity = 3.0;
267 
268  //special: Hydrogen
269  if (1 == nelm && 1 == Z0) {
270  fX0density = 0.425; fX1density = 2.0; fMdensity = 5.949;
271  }
272  }
273  //
274  // gases
275  //
276  if (State == kStateGas) {
277 
278  fMdensity = 3.;
279  fX1density = 4.0;
280  //static const G4double ClimiG[] = {10.,10.5,11.,11.5,12.25,13.804};
281  //static const G4double X0valG[] = {1.6,1.7,1.8,1.9,2.0,2.0};
282  //static const G4double X1valG[] = {4.0,4.0,4.0,4.0,4.0,5.0};
283 
284  if(fCdensity < 10.) {
285  fX0density = 1.6;
286  } else if(fCdensity < 11.5) {
287  fX0density = 1.6 + 0.2*(fCdensity - 10.);
288  } else if(fCdensity < 12.25) {
289  fX0density = 1.9 + (fCdensity - 11.5)/7.5;
290  } else if(fCdensity < 13.804) {
291  fX0density = 2.0;
292  fX1density = 4.0 + (fCdensity - 12.25)/1.554;
293  } else {
294  fX0density = 0.326*fCdensity-2.5; fX1density = 5.0;
295  }
296 
297  //special: Hydrogen
298  if (1 == nelm && 1 == Z0) {
299  fX0density = 1.837; fX1density = 3.0; fMdensity = 4.754;
300  }
301 
302  //special: Helium
303  if (1 == nelm && 2 == Z0) {
304  fX0density = 2.191; fX1density = 3.0; fMdensity = 3.297;
305  }
306  }
307  }
308 
309  // change parameters if the gas is not in STP.
310  // For the correction the density(STP) is needed.
311  // Density(STP) is calculated here :
312 
313 
314  if (State == kStateGas) {
315  G4double Density = fMaterial->GetDensity();
316  G4double Pressure = fMaterial->GetPressure();
318 
319  G4double DensitySTP = Density*STP_Pressure*Temp/(Pressure*NTP_Temperature);
320 
321  G4double ParCorr = G4Log(Density/DensitySTP);
322 
323  fCdensity -= ParCorr;
324  fX0density -= ParCorr/twoln10;
325  fX1density -= ParCorr/twoln10;
326  }
327 
328  // fAdensity parameter can be fixed for not conductive materials
329  if(0.0 == fD0density) {
332  /std::pow((fX1density-fX0density),fMdensity);
333  }
334  /*
335  G4cout << "G4IonisParamMat: density effect data for <"
336  << fMaterial->GetName()
337  << "> " << G4endl;
338  G4cout << "Eplasma(eV)= " << fPlasmaEnergy/eV
339  << " rho= " << fAdjustmentFactor
340  << " -C= " << fCdensity
341  << " x0= " << fX0density
342  << " x1= " << fX1density
343  << " a= " << fAdensity
344  << " m= " << fMdensity
345  << G4endl;
346  */
347 }
348 
349 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
350 
352 {
353  // compute parameters for the energy loss fluctuation model
354  // needs an 'effective Z'
355  G4double Zeff = 0.;
356  for (size_t i=0;i<fMaterial->GetNumberOfElements();i++) {
357  Zeff += (fMaterial->GetFractionVector())[i]
358  *((*(fMaterial->GetElementVector()))[i]->GetZ());
359  }
360  if (Zeff > 2.) { fF2fluct = 2./Zeff; }
361  else { fF2fluct = 0.; }
362 
363  fF1fluct = 1. - fF2fluct;
364  fEnergy2fluct = 10.*Zeff*Zeff*eV;
367  /fF1fluct;
369  fEnergy0fluct = 10.*eV;
370  fRateionexcfluct = 0.4;
371 }
372 
373 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
374 
376 {
377  // get elements in the actual material,
378  const G4ElementVector* theElementVector = fMaterial->GetElementVector() ;
379  const G4double* theAtomicNumDensityVector =
381  const G4int NumberOfElements = fMaterial->GetNumberOfElements() ;
382 
383  // loop for the elements in the material
384  // to find out average values Z, vF, lF
385  G4double z(0.0), vF(0.0), lF(0.0), norm(0.0), a23(0.0);
386 
387  G4Pow* g4pow = G4Pow::GetInstance();
388  if( 1 == NumberOfElements ) {
389  const G4Element* element = (*theElementVector)[0];
390  z = element->GetZ();
391  vF= element->GetIonisation()->GetFermiVelocity();
392  lF= element->GetIonisation()->GetLFactor();
393  a23 = 1.0/g4pow->A23(element->GetN());
394 
395  } else {
396  for (G4int iel=0; iel<NumberOfElements; iel++)
397  {
398  const G4Element* element = (*theElementVector)[iel];
399  const G4double weight = theAtomicNumDensityVector[iel];
400  norm += weight ;
401  z += element->GetZ() * weight;
402  vF += element->GetIonisation()->GetFermiVelocity() * weight;
403  lF += element->GetIonisation()->GetLFactor() * weight;
404  a23 += weight/g4pow->A23(element->GetN());
405  }
406  z /= norm;
407  vF /= norm;
408  lF /= norm;
409  a23 /= norm;
410  }
411  fZeff = z;
412  fLfactor = lF;
413  fFermiEnergy = 25.*keV*vF*vF;
414  fInvA23 = a23;
415 }
416 
417 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
418 
420 {
421  if(value == fMeanExcitationEnergy || value <= 0.0) { return; }
422  if (G4NistManager::Instance()->GetVerbose() > 1) {
423  G4cout << "G4Material: Mean excitation energy is changed for "
424  << fMaterial->GetName()
425  << " Iold= " << fMeanExcitationEnergy/eV
426  << "eV; Inew= " << value/eV << " eV;"
427  << G4endl;
428  }
429 
430  fMeanExcitationEnergy = value;
431 
432  // add corrections to density effect
433  G4double newlog = G4Log(value);
434  G4double corr = 2*(newlog - fLogMeanExcEnergy);
435  fCdensity += corr;
436  fX0density += corr/twoln10;
437  fX1density += corr/twoln10;
438 
439  // recompute parameters of fluctuation model
440  fLogMeanExcEnergy = newlog;
442 }
443 
444 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
445 
447 {
448  G4double res = 0.0;
449  // data from density effect data
450  if(fDensityData) {
451  G4int idx = fDensityData->GetIndex(mat->GetName());
452  if(idx >= 0) {
454  }
455  }
456 
457  // The data on mean excitation energy for compaunds
458  // from "Stopping Powers for Electrons and Positrons"
459  // ICRU Report N#37, 1984 (energy in eV)
460  // this value overwrites Density effect data
461  G4String chFormula = mat->GetChemicalFormula();
462  if(chFormula != "") {
463 
464  static const size_t numberOfMolecula = 54;
465  static const G4String name[numberOfMolecula] = {
466  // gas 0 - 12
467  "NH_3", "C_4H_10", "CO_2", "C_2H_6", "C_7H_16-Gas",
468  // "G4_AMMONIA", "G4_BUTANE","G4_CARBON_DIOXIDE","G4_ETHANE", "G4_N-HEPTANE"
469  "C_6H_14-Gas", "CH_4", "NO", "N_2O", "C_8H_18-Gas",
470  // "G4_N-HEXANE" , "G4_METHANE", "x", "G4_NITROUS_OXIDE", "G4_OCTANE"
471  "C_5H_12-Gas", "C_3H_8", "H_2O-Gas",
472  // "G4_N-PENTANE", "G4_PROPANE", "G4_WATER_VAPOR"
473 
474  // liquid 13 - 39
475  "C_3H_6O", "C_6H_5NH_2", "C_6H_6", "C_4H_9OH", "CCl_4",
476  //"G4_ACETONE","G4_ANILINE","G4_BENZENE","G4_N-BUTYL_ALCOHOL","G4_CARBON_TETRACHLORIDE"
477  "C_6H_5Cl", "CHCl_3", "C_6H_12", "C_6H_4Cl_2", "C_4Cl_2H_8O",
478  //"G4_CHLOROBENZENE","G4_CHLOROFORM","G4_CYCLOHEXANE","G4_1,2-DICHLOROBENZENE",
479  //"G4_DICHLORODIETHYL_ETHER"
480  "C_2Cl_2H_4", "(C_2H_5)_2O", "C_2H_5OH", "C_3H_5(OH)_3","C_7H_16",
481  //"G4_1,2-DICHLOROETHANE","G4_DIETHYL_ETHER","G4_ETHYL_ALCOHOL","G4_GLYCEROL","G4_N-HEPTANE"
482  "C_6H_14", "CH_3OH", "C_6H_5NO_2","C_5H_12", "C_3H_7OH",
483  //"G4_N-HEXANE","G4_METHANOL","G4_NITROBENZENE","G4_N-PENTANE","G4_N-PROPYL_ALCOHOL",
484  "C_5H_5N", "C_8H_8", "C_2Cl_4", "C_7H_8", "C_2Cl_3H",
485  //"G4_PYRIDINE","G4_POLYSTYRENE","G4_TETRACHLOROETHYLENE","G4_TOLUENE","G4_TRICHLOROETHYLENE"
486  "H_2O", "C_8H_10",
487  // "G4_WATER", "G4_XYLENE"
488 
489  // solid 40 - 53
490  "C_5H_5N_5", "C_5H_5N_5O", "(C_6H_11NO)-nylon", "C_25H_52",
491  // "G4_ADENINE", "G4_GUANINE", "G4_NYLON-6-6", "G4_PARAFFIN"
492  "(C_2H_4)-Polyethylene", "(C_5H_8O_2)-Polymethil_Methacrylate",
493  // "G4_ETHYLENE", "G4_PLEXIGLASS"
494  "(C_8H_8)-Polystyrene", "A-150-tissue", "Al_2O_3", "CaF_2",
495  // "G4_POLYSTYRENE", "G4_A-150_TISSUE", "G4_ALUMINUM_OXIDE", "G4_CALCIUM_FLUORIDE"
496  "LiF", "Photo_Emulsion", "(C_2F_4)-Teflon", "SiO_2"
497  // "G4_LITHIUM_FLUORIDE", "G4_PHOTO_EMULSION", "G4_TEFLON", "G4_SILICON_DIOXIDE"
498  } ;
499 
500  static const G4double meanExcitation[numberOfMolecula] = {
501 
502  53.7, 48.3, 85.0, 45.4, 49.2,
503  49.1, 41.7, 87.8, 84.9, 49.5,
504  48.2, 47.1, 71.6,
505 
506  64.2, 66.2, 63.4, 59.9, 166.3,
507  89.1, 156.0, 56.4, 106.5, 103.3,
508  111.9, 60.0, 62.9, 72.6, 54.4,
509  54.0, 67.6, 75.8, 53.6, 61.1,
510  66.2, 64.0, 159.2, 62.5, 148.1,
511  75.0, 61.8,
512 
513  71.4, 75.0, 63.9, 48.3, 57.4,
514  74.0, 68.7, 65.1, 145.2, 166.,
515  94.0, 331.0, 99.1, 139.2
516  };
517 
518  for(size_t i=0; i<numberOfMolecula; i++) {
519  if(chFormula == name[i]) {
520  res = meanExcitation[i]*eV;
521  break;
522  }
523  }
524  }
525  return res;
526 }
527 
528 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... ....oooOO0OOooo....
529 
G4double GetPressure() const
Definition: G4Material.hh:183
G4int GetIndex(const G4String &matName) const
static G4Pow * GetInstance()
Definition: G4Pow.cc:55
G4double GetX0density(G4int idx) const
G4double fLogEnergy2fluct
G4double GetTotNbOfElectPerVolume() const
Definition: G4Material.hh:212
std::vector< G4Element * > G4ElementVector
Definition: G4Pow.hh:56
G4double GetMeanIonisationPotential(G4int idx) const
G4double GetN() const
Definition: G4Element.hh:135
G4State
Definition: G4Material.hh:114
G4double GetX1density(G4int idx) const
G4double GetPlasmaEnergy(G4int idx) const
static const G4int numberOfMolecula
const G4String & GetChemicalFormula() const
Definition: G4Material.hh:179
G4double GetCdensity(G4int idx) const
void SetMeanExcitationEnergy(G4double value)
const G4String & GetName() const
Definition: G4Material.hh:178
G4double GetZ() const
Definition: G4Element.hh:131
#define State(X)
G4double fAdjustmentFactor
G4int GetElementIndex(G4int Z, G4State mState) const
G4double GetDensity() const
Definition: G4Material.hh:180
G4IonisParamMat(const G4Material *)
const char * name(G4int ptype)
G4double GetLFactor() const
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:190
int G4int
Definition: G4Types.hh:78
static G4NistManager * Instance()
G4double GetDelta0density(G4int idx) const
const G4Material * fMaterial
G4double FindMeanExcitationEnergy(const G4Material *) const
G4double logZ(G4int Z) const
Definition: G4Pow.hh:166
G4double GetFermiVelocity() const
const G4double * GetVecNbOfAtomsPerVolume() const
Definition: G4Material.hh:206
G4double GetMeanExcitationEnergy() const
G4double A23(G4double A) const
Definition: G4Pow.hh:160
G4double fRateionexcfluct
G4GLOB_DLL std::ostream G4cout
static constexpr double eV
Definition: G4SIunits.hh:215
G4double fLogMeanExcEnergy
const G4double * GetAtomicNumDensityVector() const
Definition: G4Material.hh:216
G4double fMeanEnergyPerIon
G4double fLogEnergy1fluct
static G4DensityEffectData * GetDensityEffectData()
G4double G4Log(G4double x)
Definition: G4Log.hh:230
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:183
G4double fMeanExcitationEnergy
G4double GetAdensity(G4int idx) const
G4double * fShellCorrectionVector
G4double GetAdjustmentFactor(G4int idx) const
G4double GetMdensity(G4int idx) const
G4IonisParamElm * GetIonisation() const
Definition: G4Element.hh:199
const G4Material * GetBaseMaterial() const
Definition: G4Material.hh:233
static const G4double NTP_Temperature
Definition: G4Material.hh:116
G4double GetTemperature() const
Definition: G4Material.hh:182
#define G4endl
Definition: G4ios.hh:61
static constexpr double pi
Definition: G4SIunits.hh:75
size_t GetNumberOfElements() const
Definition: G4Material.hh:186
G4State GetState() const
Definition: G4Material.hh:181
G4double GetNominalDensity(G4int Z) const
double G4double
Definition: G4Types.hh:76
const G4double * GetFractionVector() const
Definition: G4Material.hh:194
static constexpr double keV
Definition: G4SIunits.hh:216
static G4DensityEffectData * fDensityData
void ComputeMeanParameters()