Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4Element.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//
27//
28//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
29
30// 26-06-96: Code uses operators (+=, *=, ++, -> etc.) correctly, P. Urban
31// 09-07-96: new data members added by L.Urban
32// 17-01-97: aesthetic rearrangement, M.Maire
33// 20-01-97: Compute Tsai's formula for the rad length, M.Maire
34// 21-01-97: remove mixture flag, M.Maire
35// 24-01-97: ComputeIonisationParameters().
36// new data member: fTaul, M.Maire
37// 29-01-97: Forbidden to create Element with Z<1 or N<Z, M.Maire
38// 20-03-97: corrected initialization of pointers, M.Maire
39// 28-04-98: atomic subshell binding energies stuff, V. Grichine
40// 09-07-98: Ionisation parameters removed from the class, M.Maire
41// 16-11-98: name Subshell -> Shell; GetBindingEnergy() (mma)
42// 09-03-01: assignement operator revised (mma)
43// 02-05-01: check identical Z in AddIsotope (marc)
44// 03-05-01: flux.precision(prec) at begin/end of operator<<
45// 13-09-01: suppression of the data member fIndexInTable
46// 14-09-01: fCountUse: nb of materials which use this element
47// 26-02-02: fIndexInTable renewed
48// 30-03-05: warning in GetElement(elementName)
49// 15-11-05: GetElement(elementName, G4bool warning=true)
50// 17-10-06: Add fNaturalAbundances (V.Ivanchenko)
51// 27-07-07: improve destructor (V.Ivanchenko)
52// 18-10-07: move definition of material index to ComputeDerivedQuantities (VI)
53// 25.10.11: new scheme for G4Exception (mma)
54// 05-03-12: always create isotope vector (V.Ivanchenko)
55
56//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
57
58#include <iomanip>
59#include <sstream>
60
61#include "G4Element.hh"
62#include "G4AtomicShells.hh"
63#include "G4NistManager.hh"
65#include "G4SystemOfUnits.hh"
66#include "G4Log.hh"
67
68G4ElementTable G4Element::theElementTable;
69
70//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
71
72// Constructor to Generate an element from scratch
73
74G4Element::G4Element(const G4String& name, const G4String& symbol,
75 G4double zeff, G4double aeff)
76 : fName(name), fSymbol(symbol)
77{
78 G4int iz = G4lrint(zeff);
79 if (iz < 1) {
81 ed << "Failed to create G4Element " << name
82 << " Z= " << zeff << " < 1 !";
83 G4Exception ("G4Element::G4Element()", "mat011", FatalException, ed);
84 }
85 if (std::abs(zeff - iz) > perMillion) {
87 ed << "G4Element Warning: " << name << " Z= " << zeff
88 << " A= " << aeff/(g/mole);
89 G4Exception("G4Element::G4Element()", "mat017", JustWarning, ed);
90 }
91
92 InitializePointers();
93
94 fZeff = zeff;
95 fAeff = aeff;
96 fNeff = fAeff/(g/mole);
97
98 if(fNeff < 1.0)
99 {
100 fNeff = 1.0;
101 }
102
103 if (fNeff < zeff) {
105 ed << "Failed to create G4Element " << name
106 << " with Z= " << zeff << " N= " << fNeff
107 << " N < Z is not allowed" << G4endl;
108 G4Exception("G4Element::G4Element()", "mat012", FatalException, ed);
109 }
110
111 fNbOfAtomicShells = G4AtomicShells::GetNumberOfShells(iz);
112 fAtomicShells = new G4double[fNbOfAtomicShells];
113 fNbOfShellElectrons = new G4int[fNbOfAtomicShells];
114
115 AddNaturalIsotopes();
116
117 for (G4int i=0; i<fNbOfAtomicShells; ++i)
118 {
119 fAtomicShells[i] = G4AtomicShells::GetBindingEnergy(iz, i);
120 fNbOfShellElectrons[i] = G4AtomicShells::GetNumberOfElectrons(iz, i);
121 }
122 ComputeDerivedQuantities();
123}
124
125//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
126
127// Constructor to Generate element from a List of 'nIsotopes' isotopes, added
128// via AddIsotope
129
131 const G4String& symbol, G4int nIsotopes)
132 : fName(name),fSymbol(symbol)
133{
134 InitializePointers();
135
136 size_t n = size_t(nIsotopes);
137
138 if(0 >= nIsotopes) {
140 ed << "Failed to create G4Element " << name
141 << " <" << symbol << "> with " << nIsotopes
142 << " isotopes.";
143 G4Exception ("G4Element::G4Element()", "mat012", FatalException, ed);
144 } else {
145 theIsotopeVector = new G4IsotopeVector(n, nullptr);
146 fRelativeAbundanceVector = new G4double[nIsotopes];
147 }
148}
149
150//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
151
152// Add an isotope to the element
153
154void G4Element::AddIsotope(G4Isotope* isotope, G4double abundance)
155{
156 if(theIsotopeVector == nullptr)
157 {
159 ed << "Failed to add Isotope to G4Element " << fName
160 << " with Z= " << fZeff << " N= " << fNeff;
161 G4Exception ("G4Element::AddIsotope()", "mat013", FatalException, ed);
162 return;
163 }
164 G4int iz = isotope->GetZ();
165
166 // filling ...
167 if ( fNumberOfIsotopes < (G4int)theIsotopeVector->size() ) {
168 // check same Z
169 if (fNumberOfIsotopes==0) { fZeff = G4double(iz); }
170 else if (G4double(iz) != fZeff) {
172 ed << "Failed to add Isotope Z= " << iz << " to G4Element " << fName
173 << " with different Z= " << fZeff << fNeff;
174 G4Exception ("G4Element::AddIsotope()", "mat014", FatalException, ed);
175 return;
176 }
177 //Z ok
178 fRelativeAbundanceVector[fNumberOfIsotopes] = abundance;
179 (*theIsotopeVector)[fNumberOfIsotopes] = isotope;
180 ++fNumberOfIsotopes;
181
182 } else {
184 ed << "Failed to add Isotope Z= " << iz << " to G4Element " << fName
185 << " - more isotopes than declared.";
186 G4Exception ("G4Element::AddIsotope()", "mat015", FatalException, ed);
187 return;
188 }
189
190 // filled.
191 if ( fNumberOfIsotopes == (G4int)theIsotopeVector->size() ) {
192 G4double wtSum=0.0;
193 fAeff = 0.0;
194 for (G4int i=0; i<fNumberOfIsotopes; ++i) {
195 fAeff += fRelativeAbundanceVector[i]*(*theIsotopeVector)[i]->GetA();
196 wtSum += fRelativeAbundanceVector[i];
197 }
198 if(wtSum > 0.0) { fAeff /= wtSum; }
199 fNeff = fAeff/(g/mole);
200
201 if(wtSum != 1.0) {
202 for (G4int i=0; i<fNumberOfIsotopes; ++i) {
203 fRelativeAbundanceVector[i] /= wtSum;
204 }
205 }
206
207 fNbOfAtomicShells = G4AtomicShells::GetNumberOfShells(iz);
208 fAtomicShells = new G4double[fNbOfAtomicShells];
209 fNbOfShellElectrons = new G4int[fNbOfAtomicShells];
210
211 for (G4int j = 0; j < fNbOfAtomicShells; ++j)
212 {
213 fAtomicShells[j] = G4AtomicShells::GetBindingEnergy(iz, j);
214 fNbOfShellElectrons[j] = G4AtomicShells::GetNumberOfElectrons(iz, j);
215 }
216 ComputeDerivedQuantities();
217 }
218}
219
220//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
221
222void G4Element::InitializePointers()
223{
224 theIsotopeVector = nullptr;
225 fRelativeAbundanceVector = nullptr;
226 fAtomicShells = nullptr;
227 fNbOfShellElectrons = nullptr;
228 fIonisation = nullptr;
229 fNumberOfIsotopes = 0;
230 fNaturalAbundance = false;
231
232 // add initialisation of all remaining members
233 fZeff = 0;
234 fNeff = 0;
235 fAeff = 0;
236 fNbOfAtomicShells = 0;
237 fIndexInTable = 0;
238 fCoulomb = 0.0;
239 fRadTsai = 0.0;
240 fZ = 0;
241}
242
243//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
244
245// Fake default constructor - sets only member data and allocates memory
246// for usage restricted to object persistency
247
249 : fZeff(0), fNeff(0), fAeff(0)
250{
251 InitializePointers();
252}
253
254//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
255
257{
258 delete theIsotopeVector;
259 delete[] fRelativeAbundanceVector;
260 delete[] fAtomicShells;
261 delete[] fNbOfShellElectrons;
262 delete fIonisation;
263
264 //remove this element from theElementTable
265 theElementTable[fIndexInTable] = nullptr;
266}
267
268//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
269
270void G4Element::ComputeDerivedQuantities()
271{
272 // some basic functions of the atomic number
273
274 // Store in table
275 theElementTable.push_back(this);
276 fIndexInTable = theElementTable.size() - 1;
277
278 // Radiation Length
279 ComputeCoulombFactor();
280 ComputeLradTsaiFactor();
281
282 // parameters for energy loss by ionisation
283 delete fIonisation;
284 fIonisation = new G4IonisParamElm(fZeff);
285 fZ = G4lrint(fZeff);
286}
287
288//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
289
290void G4Element::ComputeCoulombFactor()
291{
292 //
293 // Compute Coulomb correction factor (Phys Rev. D50 3-1 (1994) page 1254)
294
295 static const G4double k1 = 0.0083 , k2 = 0.20206 ,k3 = 0.0020 , k4 = 0.0369 ;
296
297 G4double az2 = (fine_structure_const*fZeff)*(fine_structure_const*fZeff);
298 G4double az4 = az2 * az2;
299
300 fCoulomb = (k1*az4 + k2 + 1./(1.+az2))*az2 - (k3*az4 + k4)*az4;
301}
302
303//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
304
305void G4Element::ComputeLradTsaiFactor()
306{
307 //
308 // Compute Tsai's Expression for the Radiation Length
309 // (Phys Rev. D50 3-1 (1994) page 1254)
310
311 static const G4double Lrad_light[] = {5.31 , 4.79 , 4.74 , 4.71} ;
312 static const G4double Lprad_light[] = {6.144 , 5.621 , 5.805 , 5.924} ;
313
314 const G4double logZ3 = G4Log(fZeff)/3.;
315
316 G4double Lrad, Lprad;
317 G4int iz = G4lrint(fZeff) - 1 ;
318 static const G4double log184 = G4Log(184.15);
319 static const G4double log1194 = G4Log(1194.);
320 if (iz <= 3) { Lrad = Lrad_light[iz] ; Lprad = Lprad_light[iz] ; }
321 else { Lrad = log184 - logZ3 ; Lprad = log1194 - 2*logZ3;}
322
323 fRadTsai = 4*alpha_rcl2*fZeff*(fZeff*(Lrad-fCoulomb) + Lprad);
324}
325
326//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
327
328void G4Element::AddNaturalIsotopes()
329{
330 G4int Z = G4lrint(fZeff);
333 G4int N0 = nist->GetNistFirstIsotopeN(Z);
334
335 if(fSymbol.empty())
336 {
337 const std::vector<G4String> elmnames =
339 if(Z < (G4int)elmnames.size()) { fSymbol = elmnames[Z]; }
340 else { fSymbol = fName; }
341 }
342
343 fNumberOfIsotopes = 0;
344 for(G4int i=0; i<n; ++i) {
345 if(nist->GetIsotopeAbundance(Z, N0+i) > 0.0) { ++fNumberOfIsotopes; }
346 }
347 theIsotopeVector =
348 new G4IsotopeVector((unsigned int) fNumberOfIsotopes, nullptr);
349 fRelativeAbundanceVector = new G4double[fNumberOfIsotopes];
350 G4int idx = 0;
351 G4double xsum = 0.0;
352 for(G4int i=0; i<n; ++i) {
353 G4int N = N0 + i;
354 G4double x = nist->GetIsotopeAbundance(Z, N);
355 if(x > 0.0) {
356 std::ostringstream strm;
357 strm << fSymbol << N;
358 (*theIsotopeVector)[idx] = new G4Isotope(strm.str(), Z, N, 0.0, 0);
359 fRelativeAbundanceVector[idx] = x;
360 xsum += x;
361 ++idx;
362 }
363 }
364 if(xsum != 0.0 && xsum != 1.0) {
365 for(G4int i=0; i<idx; ++i) { fRelativeAbundanceVector[i] /= xsum; }
366 }
367 fNaturalAbundance = true;
368}
369
370//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
371
373{
374 if (i<0 || i>=fNbOfAtomicShells) {
376 ed << "Invalid argument " << i << " in for G4Element " << fName
377 << " with Z= " << fZeff
378 << " and Nshells= " << fNbOfAtomicShells;
379 G4Exception("G4Element::GetAtomicShell()", "mat016", FatalException, ed);
380 return 0.0;
381 }
382 return fAtomicShells[i];
383}
384
385//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
386
388{
389 if (i<0 || i>=fNbOfAtomicShells) {
391 ed << "Invalid argument " << i << " for G4Element " << fName
392 << " with Z= " << fZeff
393 << " and Nshells= " << fNbOfAtomicShells;
394 G4Exception("G4Element::GetNbOfShellElectrons()", "mat016",
395 FatalException, ed);
396 return 0;
397 }
398 return fNbOfShellElectrons[i];
399}
400
401//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
402
404{
405 return &theElementTable;
406}
407
408//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
409
411{
412 return theElementTable.size();
413}
414
415//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
416
417G4Element* G4Element::GetElement(const G4String& elementName, G4bool warning)
418{
419 // search the element by its name
420 for(auto J : theElementTable)
421 {
422 if(J->GetName() == elementName)
423 {
424 return J;
425 }
426 }
427
428 // the element does not exist in the table
429 if (warning) {
430 G4cout << "\n---> warning from G4Element::GetElement(). The element: "
431 << elementName << " does not exist in the table. Return NULL pointer."
432 << G4endl;
433 }
434 return nullptr;
435}
436
437//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
438
439std::ostream& operator<<(std::ostream& flux, const G4Element* element)
440{
441 std::ios::fmtflags mode = flux.flags();
442 flux.setf(std::ios::fixed,std::ios::floatfield);
443 G4long prec = flux.precision(3);
444
445 flux
446 << " Element: " << element->fName << " (" << element->fSymbol << ")"
447 << " Z = " << std::setw(4) << std::setprecision(1) << element->fZeff
448 << " N = " << std::setw(5) << std::setprecision(1)
449 << G4lrint(element->fNeff)
450 << " A = " << std::setw(6) << std::setprecision(3)
451 << (element->fAeff)/(g/mole) << " g/mole";
452
453 for(G4int i = 0; i < element->fNumberOfIsotopes; i++)
454 {
455 flux << "\n ---> " << (*(element->theIsotopeVector))[i]
456 << " abundance: " << std::setw(6) << std::setprecision(3)
457 << (element->fRelativeAbundanceVector[i]) / perCent << " %";
458 }
459
460 flux.precision(prec);
461 flux.setf(mode,std::ios::floatfield);
462 return flux;
463}
464
465//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
466
467 std::ostream& operator<<(std::ostream& flux, const G4Element& element)
468{
469 flux << &element;
470 return flux;
471}
472
473//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
474
475std::ostream& operator<<(std::ostream& flux, const G4ElementTable& ElementTable)
476{
477 //Dump info for all known elements
478 flux << "\n***** Table : Nb of elements = " << ElementTable.size()
479 << " *****\n" << G4endl;
480
481 for(auto i : ElementTable)
482 {
483 flux << i << G4endl << G4endl;
484 }
485
486 return flux;
487}
488
489//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
490
491std::ostream& operator<<(std::ostream& flux, const G4ElementVector& ElementVector)
492{
493 //Dump info for all known elements
494 flux << "\n***** Vector : Nb of elements = " << ElementVector.size()
495 << " *****\n" << G4endl;
496
497 for(auto i : ElementVector)
498 {
499 flux << i << G4endl << G4endl;
500 }
501
502 return flux;
503}
504
505//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
std::vector< G4Element * > G4ElementTable
std::vector< const G4Element * > G4ElementVector
std::ostream & operator<<(std::ostream &flux, const G4Element *element)
Definition: G4Element.cc:439
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
std::vector< G4Isotope * > G4IsotopeVector
G4double G4Log(G4double x)
Definition: G4Log.hh:227
double G4double
Definition: G4Types.hh:83
long G4long
Definition: G4Types.hh:87
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4int GetNumberOfElectrons(G4int Z, G4int SubshellNb)
static G4double GetBindingEnergy(G4int Z, G4int SubshellNb)
static G4int GetNumberOfShells(G4int Z)
static G4ElementTable * GetElementTable()
Definition: G4Element.cc:403
virtual ~G4Element()
Definition: G4Element.cc:256
static size_t GetNumberOfElements()
Definition: G4Element.cc:410
void AddIsotope(G4Isotope *isotope, G4double RelativeAbundance)
Definition: G4Element.cc:154
G4Element(const G4String &name, const G4String &symbol, G4double Zeff, G4double Aeff)
Definition: G4Element.cc:74
G4int GetNbOfShellElectrons(G4int index) const
Definition: G4Element.cc:387
static G4Element * GetElement(const G4String &name, G4bool warning=true)
Definition: G4Element.cc:417
G4double GetAtomicShell(G4int index) const
Definition: G4Element.cc:372
G4int GetZ() const
Definition: G4Isotope.hh:90
G4int GetNumberOfNistIsotopes(G4int Z) const
const std::vector< G4String > & GetNistElementNames() const
G4int GetNistFirstIsotopeN(G4int Z) const
static G4NistManager * Instance()
G4double GetIsotopeAbundance(G4int Z, G4int N) const
#define N
Definition: crc32.c:56
int G4lrint(double ad)
Definition: templates.hh:134