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
G4Material.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//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
28//
29// 26-06-96, Code uses operators (+=, *=, ++, -> etc.) correctly, P. Urban
30// 10-07-96, new data members added by L.Urban
31// 12-12-96, new data members added by L.Urban
32// 20-01-97, aesthetic rearrangement. RadLength calculation modified.
33// Data members Zeff and Aeff REMOVED (i.e. passed to the Elements).
34// (local definition of Zeff in DensityEffect and FluctModel...)
35// Vacuum defined as a G4State. Mixture flag removed, M.Maire.
36// 29-01-97, State=Vacuum automatically set density=0 in the contructors.
37// Subsequent protections have been put in the calculation of
38// MeanExcEnergy, ShellCorrectionVector, DensityEffect, M.Maire.
39// 11-02-97, ComputeDensityEffect() rearranged, M.Maire.
40// 20-03-97, corrected initialization of pointers, M.Maire.
41// 28-05-98, the kState=kVacuum has been removed.
42// automatic check for a minimal density, M.Maire
43// 12-06-98, new method AddMaterial() allowing mixture of materials, M.Maire
44// 09-07-98, ionisation parameters removed from the class, M.Maire
45// 05-10-98, change names: NumDensity -> NbOfAtomsPerVolume
46// 18-11-98, new interface to SandiaTable
47// 19-01-99 enlarge tolerance on test of coherence of gas conditions
48// 19-07-99, Constructors with chemicalFormula added by V.Ivanchenko
49// 16-01-01, Nuclear interaction length, M.Maire
50// 12-03-01, G4bool fImplicitElement;
51// copy constructor and assignement operator revised (mma)
52// 03-05-01, flux.precision(prec) at begin/end of operator<<
53// 17-07-01, migration to STL. M. Verderi.
54// 14-09-01, Suppression of the data member fIndexInTable
55// 26-02-02, fIndexInTable renewed
56// 16-04-02, G4Exception put in constructor with chemical formula
57// 06-05-02, remove the check of the ideal gas state equation
58// 06-08-02, remove constructors with chemical formula (mma)
59// 22-01-04, proper STL handling of theElementVector (Hisaya)
60// 30-03-05, warning in GetMaterial(materialName)
61// 09-03-06, minor change of printout (V.Ivanchenko)
62// 10-01-07, compute fAtomVector in the case of mass fraction (V.Ivanchenko)
63// 27-07-07, improve destructor (V.Ivanchenko)
64// 18-10-07, moved definition of mat index to InitialisePointers (V.Ivanchenko)
65// 13-08-08, do not use fixed size arrays (V.Ivanchenko)
66// 26-10-11, new scheme for G4Exception (mma)
67// 13-04-12, map<G4Material*,G4double> fMatComponents, filled in AddMaterial()
68// 21-04-12, fMassOfMolecule, computed for AtomsCount (mma)
69//
70//
71//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
72
73#include <iomanip>
74
75#include "G4Material.hh"
76#include "G4NistManager.hh"
77#include "G4UnitsTable.hh"
79#include "G4SystemOfUnits.hh"
80#include "G4ExtendedMaterial.hh"
81#include "G4AtomicShells.hh"
82#include "G4ApplicationState.hh"
83#include "G4StateManager.hh"
84#include "G4Exp.hh"
85#include "G4Log.hh"
86
87G4MaterialTable G4Material::theMaterialTable;
88
89//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
90
91// Constructor to create a material from scratch
92
94 G4double a, G4double density,
95 G4State state, G4double temp, G4double pressure)
96 : fName(name)
97{
98 InitializePointers();
99
100 if (density < universe_mean_density)
101 {
102 G4cout << " G4Material WARNING:"
103 << " define a material with density=0 is not allowed. \n"
104 << " The material " << name << " will be constructed with the"
105 << " default minimal density: " << universe_mean_density/(g/cm3)
106 << "g/cm3" << G4endl;
107 density = universe_mean_density;
108 }
109
110 fDensity = density;
111 fState = state;
112 fTemp = temp;
113 fPressure = pressure;
114
115 // Initialize theElementVector allocating one
116 // element corresponding to this material
117 fNbComponents = fNumberOfElements = 1;
118 theElementVector = new G4ElementVector();
119
120 // take element from DB
122 G4int iz = G4lrint(z);
123 auto elm = nist->FindOrBuildElement(iz);
124 if(elm == nullptr)
125 {
126 elm = new G4Element("ELM_" + name, name, z, a);
127 }
128 theElementVector->push_back(elm);
129
130 fMassFractionVector = new G4double[1];
131 fMassFractionVector[0] = 1.;
132 fMassOfMolecule = a/CLHEP::Avogadro;
133
134 if (fState == kStateUndefined)
135 {
136 if (fDensity > kGasThreshold) { fState = kStateSolid; }
137 else { fState = kStateGas; }
138 }
139
140 ComputeDerivedQuantities();
141}
142
143//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
144
145// Constructor to create a material from a List of constituents
146// (elements and/or materials) added with AddElement or AddMaterial
147
149 G4int nComponents,
150 G4State state, G4double temp, G4double pressure)
151 : fName(name)
152{
153 InitializePointers();
154
155 if (density < universe_mean_density)
156 {
157 G4cout << "--- Warning from G4Material::G4Material()"
158 << " define a material with density=0 is not allowed. \n"
159 << " The material " << name << " will be constructed with the"
160 << " default minimal density: " << universe_mean_density/(g/cm3)
161 << "g/cm3" << G4endl;
162 density = universe_mean_density;
163 }
164
165 fDensity = density;
166 fState = state;
167 fTemp = temp;
168 fPressure = pressure;
169
170 fNbComponents = nComponents;
171 fMassFraction = true;
172
173 if (fState == kStateUndefined)
174 {
175 if (fDensity > kGasThreshold) { fState = kStateSolid; }
176 else { fState = kStateGas; }
177 }
178}
179
180//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
181
182// Constructor to create a material from base material
183
185 const G4Material* bmat,
186 G4State state, G4double temp, G4double pressure)
187 : fName(name)
188{
189 InitializePointers();
190
191 if (density < universe_mean_density)
192 {
193 G4cout << "--- Warning from G4Material::G4Material()"
194 << " define a material with density=0 is not allowed. \n"
195 << " The material " << name << " will be constructed with the"
196 << " default minimal density: " << universe_mean_density/(g/cm3)
197 << "g/cm3" << G4endl;
198 density = universe_mean_density;
199 }
200
201 fDensity = density;
202 fState = state;
203 fTemp = temp;
204 fPressure = pressure;
205
206 fBaseMaterial = bmat;
207 auto ptr = bmat;
208 if(nullptr != ptr) {
209 while(1) {
210 ptr = ptr->GetBaseMaterial();
211 if(nullptr == ptr) { break; }
212 else { fBaseMaterial = ptr; }
213 }
214 }
215
216 fChemicalFormula = fBaseMaterial->GetChemicalFormula();
217 fMassOfMolecule = fBaseMaterial->GetMassOfMolecule();
218
219 fNumberOfElements = (G4int)fBaseMaterial->GetNumberOfElements();
220 fNbComponents = fNumberOfElements;
221
222 CopyPointersOfBaseMaterial();
223}
224
225//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
226
227// Fake default constructor - sets only member data and allocates memory
228// for usage restricted to object persistency
229
231 : fName("")
232{
233 InitializePointers();
234}
235
236//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
237
239{
240 // G4cout << "### Destruction of material " << fName << " started" <<G4endl;
241 if(fBaseMaterial == nullptr) {
242 delete theElementVector;
243 delete fSandiaTable;
244 delete [] fMassFractionVector;
245 delete [] fAtomsVector;
246 }
247 delete fIonisation;
248 delete [] fVecNbOfAtomsPerVolume;
249
250 // Remove this material from theMaterialTable.
251 //
252 theMaterialTable[fIndexInTable] = nullptr;
253}
254
255//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
256
257void G4Material::InitializePointers()
258{
259 fBaseMaterial = nullptr;
260 fMaterialPropertiesTable = nullptr;
261 theElementVector = nullptr;
262 fAtomsVector = nullptr;
263 fMassFractionVector = nullptr;
264 fVecNbOfAtomsPerVolume = nullptr;
265
266 fIonisation = nullptr;
267 fSandiaTable = nullptr;
268
269 fDensity = fFreeElecDensity = fTemp = fPressure = 0.0;
270 fTotNbOfAtomsPerVolume = 0.0;
271 fTotNbOfElectPerVolume = 0.0;
272 fRadlen = fNuclInterLen = fMassOfMolecule = 0.0;
273
274 fState = kStateUndefined;
275 fNumberOfElements = fNbComponents = fIdxComponent = 0;
276 fMassFraction = true;
277 fChemicalFormula = "";
278
279 // Store in the static Table of Materials
280 fIndexInTable = theMaterialTable.size();
281 for(size_t i=0; i<fIndexInTable; ++i) {
282 if(theMaterialTable[i]->GetName() == fName) {
283 G4cout << "G4Material WARNING: duplicate name of material "
284 << fName << G4endl;
285 break;
286 }
287 }
288 theMaterialTable.push_back(this);
289}
290
291//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
292
293void G4Material::ComputeDerivedQuantities()
294{
295 // Header routine to compute various properties of material.
296 //
297 // Number of atoms per volume (per element), total nb of electrons per volume
298 G4double Zi, Ai;
299 fTotNbOfAtomsPerVolume = 0.;
300 delete[] fVecNbOfAtomsPerVolume;
301 fVecNbOfAtomsPerVolume = new G4double[fNumberOfElements];
302 fTotNbOfElectPerVolume = 0.;
303 fFreeElecDensity = 0.;
304 const G4double elecTh = 15.*CLHEP::eV; // threshold for conductivity e-
305 for (G4int i=0; i<fNumberOfElements; ++i) {
306 Zi = (*theElementVector)[i]->GetZ();
307 Ai = (*theElementVector)[i]->GetA();
308 fVecNbOfAtomsPerVolume[i] = Avogadro*fDensity*fMassFractionVector[i]/Ai;
309 fTotNbOfAtomsPerVolume += fVecNbOfAtomsPerVolume[i];
310 fTotNbOfElectPerVolume += fVecNbOfAtomsPerVolume[i]*Zi;
311 if(fState != kStateGas) {
312 fFreeElecDensity += fVecNbOfAtomsPerVolume[i]*
314 }
315 }
316
317 ComputeRadiationLength();
318 ComputeNuclearInterLength();
319
320 if(fIonisation == nullptr)
321 {
322 fIonisation = new G4IonisParamMat(this);
323 }
324 if(fSandiaTable == nullptr)
325 {
326 fSandiaTable = new G4SandiaTable(this);
327 }
328}
329
330//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
331
332void G4Material::CopyPointersOfBaseMaterial()
333{
334 G4double factor = fDensity/fBaseMaterial->GetDensity();
335 fTotNbOfAtomsPerVolume = factor*fBaseMaterial->GetTotNbOfAtomsPerVolume();
336 fTotNbOfElectPerVolume = factor*fBaseMaterial->GetTotNbOfElectPerVolume();
337 fFreeElecDensity = factor*fBaseMaterial->GetFreeElectronDensity();
338
339 if(fState == kStateUndefined) { fState = fBaseMaterial->GetState(); }
340
341 theElementVector =
342 const_cast<G4ElementVector*>(fBaseMaterial->GetElementVector());
343 fMassFractionVector =
344 const_cast<G4double*>(fBaseMaterial->GetFractionVector());
345 fAtomsVector = const_cast<G4int*>(fBaseMaterial->GetAtomsVector());
346
347 const G4double* v = fBaseMaterial->GetVecNbOfAtomsPerVolume();
348 delete[] fVecNbOfAtomsPerVolume;
349 fVecNbOfAtomsPerVolume = new G4double[fNumberOfElements];
350 for (G4int i=0; i<fNumberOfElements; ++i) {
351 fVecNbOfAtomsPerVolume[i] = factor*v[i];
352 }
353 fRadlen = fBaseMaterial->GetRadlen()/factor;
354 fNuclInterLen = fBaseMaterial->GetNuclearInterLength()/factor;
355
356 if(fIonisation == nullptr)
357 {
358 fIonisation = new G4IonisParamMat(this);
359 }
360 fIonisation->SetMeanExcitationEnergy(fBaseMaterial->GetIonisation()->GetMeanExcitationEnergy());
361 if(fBaseMaterial->GetIonisation()->GetDensityEffectCalculator() != nullptr)
362 {
364 }
365
366 fSandiaTable = fBaseMaterial->GetSandiaTable();
367 fMaterialPropertiesTable = fBaseMaterial->GetMaterialPropertiesTable();
368}
369
370//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
371
372void
374{
375 // perform checks consistency
376 if(0 == fIdxComponent) {
377 fMassFraction = false;
378 fAtoms = new std::vector<G4int>;
379 fElm = new std::vector<const G4Element*>;
380 }
381 if(fIdxComponent >= fNbComponents) {
383 ed << "For material " << fName << " and added element "
384 << elm->GetName() << " with Natoms=" << nAtoms
385 << " wrong attempt to add more than the declared number of elements "
386 << fIdxComponent << " >= " << fNbComponents;
387 G4Exception ("G4Material::AddElementByNumberOfAtoms()", "mat031",
388 FatalException, ed, "");
389 }
390 if(fMassFraction) {
392 ed << "For material " << fName << " and added element "
393 << elm->GetName() << " with Natoms=" << nAtoms
394 << " problem: cannot add by number of atoms after "
395 << "addition of elements by mass fraction";
396 G4Exception ("G4Material::AddElementByNumberOfAtoms()", "mat031",
397 FatalException, ed, "");
398 }
399 if(0 >= nAtoms) {
401 ed << "For material " << fName << " and added element "
402 << elm->GetName() << " with Natoms=" << nAtoms
403 << " problem: number of atoms should be above zero";
404 G4Exception ("G4Material::AddElementByNumberOfAtoms()", "mat031",
405 FatalException, ed, "");
406 }
407
408 // filling
409 G4bool isAdded = false;
410 if(!fElm->empty()) {
411 for (G4int i=0; i<fNumberOfElements; ++i) {
412 if ( elm == (*fElm)[i] ) {
413 (*fAtoms)[i] += nAtoms;
414 isAdded = true;
415 break;
416 }
417 }
418 }
419 if(!isAdded) {
420 fElm->push_back(elm);
421 fAtoms->push_back(nAtoms);
422 ++fNumberOfElements;
423 }
424 ++fIdxComponent;
425
426 // is filled - complete composition of atoms
427 if (fIdxComponent == fNbComponents) {
428 theElementVector = new G4ElementVector();
429 theElementVector->reserve(fNumberOfElements);
430 fAtomsVector = new G4int[fNumberOfElements];
431 fMassFractionVector = new G4double[fNumberOfElements];
432
433 G4double Amol = 0.;
434 for (G4int i=0; i<fNumberOfElements; ++i) {
435 theElementVector->push_back((*fElm)[i]);
436 fAtomsVector[i] = (*fAtoms)[i];
437 G4double w = fAtomsVector[i]*(*fElm)[i]->GetA();
438 Amol += w;
439 fMassFractionVector[i] = w;
440 }
441 for (G4int i=0; i<fNumberOfElements; ++i) {
442 fMassFractionVector[i] /= Amol;
443 }
444 delete fAtoms;
445 delete fElm;
446 fMassOfMolecule = Amol/CLHEP::Avogadro;
447 ComputeDerivedQuantities();
448 }
449}
450
451//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
452
453void
455{
456 // perform checks consistency
457 if(fraction < 0.0 || fraction > 1.0) {
459 ed << "For material " << fName << " and added element "
460 << elm->GetName() << " massFraction= " << fraction
461 << " is wrong ";
462 G4Exception ("G4Material::AddElementByMassFraction()", "mat031",
463 FatalException, ed, "");
464 }
465 if(!fMassFraction) {
467 ed << "For material " << fName << " and added element "
468 << elm->GetName() << ", massFraction= " << fraction
469 << ", fIdxComponent=" << fIdxComponent
470 << " problem: cannot add by mass fraction after "
471 << "addition of elements by number of atoms";
472 G4Exception ("G4Material::AddElementByMassFraction()", "mat031",
473 FatalException, ed, "");
474 }
475 if(fIdxComponent >= fNbComponents) {
477 ed << "For material " << fName << " and added element "
478 << elm->GetName() << ", massFraction= " << fraction
479 << ", fIdxComponent=" << fIdxComponent
480 << "; attempt to add more than the declared number of components "
481 << fIdxComponent << " >= " << fNbComponents;
482 G4Exception ("G4Material::AddElementByMassFraction()", "mat031",
483 FatalException, ed, "");
484 }
485 if(0 == fIdxComponent) {
486 fElmFrac = new std::vector<G4double>;
487 fElm = new std::vector<const G4Element*>;
488 }
489
490 // filling
491 G4bool isAdded = false;
492 if(!fElm->empty()) {
493 for (G4int i=0; i<fNumberOfElements; ++i) {
494 if ( elm == (*fElm)[i] ) {
495 (*fElmFrac)[i] += fraction;
496 isAdded = true;
497 break;
498 }
499 }
500 }
501 if(!isAdded) {
502 fElm->push_back(elm);
503 fElmFrac->push_back(fraction);
504 ++fNumberOfElements;
505 }
506 ++fIdxComponent;
507
508 // is filled
509 if(fIdxComponent == fNbComponents) { FillVectors(); }
510}
511
512//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
513
514// composition by fraction of mass
516{
517 if(fraction < 0.0 || fraction > 1.0) {
519 ed << "For material " << fName << " and added material "
520 << material->GetName() << ", massFraction= " << fraction
521 << " is wrong ";
522 G4Exception ("G4Material::AddMaterial()", "mat031", FatalException,
523 ed, "");
524 }
525 if(!fMassFraction) {
527 ed << "For material " << fName << " and added material "
528 << material->GetName() << ", massFraction= " << fraction
529 << ", fIdxComponent=" << fIdxComponent
530 << " problem: cannot add by mass fraction after "
531 << "addition of elements by number of atoms";
532 G4Exception ("G4Material::AddMaterial()", "mat031", FatalException,
533 ed, "");
534 }
535 if(fIdxComponent >= fNbComponents) {
537 ed << "For material " << fName << " and added material "
538 << material->GetName() << ", massFraction= " << fraction
539 << "; attempt to add more than the declared number of components "
540 << fIdxComponent << " >= " << fNbComponents;
541 G4Exception ("G4Material::AddMaterial()", "mat031", FatalException,
542 ed, "");
543 }
544 if(0 == fIdxComponent) {
545 fElmFrac = new std::vector<G4double>;
546 fElm = new std::vector<const G4Element*>;
547 }
548
549 // filling
550 G4int nelm = (G4int)material->GetNumberOfElements();
551 for(G4int j=0; j<nelm; ++j) {
552 auto elm = material->GetElement(j);
553 auto frac = material->GetFractionVector();
554 G4bool isAdded = false;
555 if(!fElm->empty()) {
556 for (G4int i=0; i<fNumberOfElements; ++i) {
557 if ( elm == (*fElm)[i] ) {
558 (*fElmFrac)[i] += fraction*frac[j];
559 isAdded = true;
560 break;
561 }
562 }
563 }
564 if(!isAdded) {
565 fElm->push_back(elm);
566 fElmFrac->push_back(fraction*frac[j]);
567 ++fNumberOfElements;
568 }
569 }
570
571 fMatComponents[material] = fraction;
572 ++fIdxComponent;
573
574 // is filled
575 if(fIdxComponent == fNbComponents) { FillVectors(); }
576}
577
578//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
579
580void G4Material::FillVectors()
581{
582 // there are material components
583 theElementVector = new G4ElementVector();
584 theElementVector->reserve(fNumberOfElements);
585 fAtomsVector = new G4int[fNumberOfElements];
586 fMassFractionVector = new G4double[fNumberOfElements];
587
588 G4double wtSum(0.0);
589 for (G4int i=0; i<fNumberOfElements; ++i) {
590 theElementVector->push_back((*fElm)[i]);
591 fMassFractionVector[i] = (*fElmFrac)[i];
592 wtSum += fMassFractionVector[i];
593 }
594 delete fElmFrac;
595 delete fElm;
596
597 // check sum of weights -- OK?
598 if (std::abs(1.-wtSum) > perThousand) {
600 ed << "For material " << fName << " sum of fractional masses "
601 << wtSum << " is not 1 - results may be wrong";
602 G4Exception ("G4Material::FillVectors()", "mat031", JustWarning,
603 ed, "");
604 }
605 G4double coeff = (wtSum > 0.0) ? 1./wtSum : 1.0;
606 G4double Amol(0.);
607 for (G4int i=0; i<fNumberOfElements; ++i) {
608 fMassFractionVector[i] *= coeff;
609 Amol += fMassFractionVector[i]*(*theElementVector)[i]->GetA();
610 }
611 for (G4int i=0; i<fNumberOfElements; ++i) {
612 fAtomsVector[i] =
613 G4lrint(fMassFractionVector[i]*Amol/(*theElementVector)[i]->GetA());
614 }
615 ComputeDerivedQuantities();
616}
617
618//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
619
620void G4Material::ComputeRadiationLength()
621{
622 G4double radinv = 0.0 ;
623 for (G4int i=0; i<fNumberOfElements; ++i) {
624 radinv += fVecNbOfAtomsPerVolume[i]*((*theElementVector)[i]->GetfRadTsai());
625 }
626 fRadlen = (radinv <= 0.0 ? DBL_MAX : 1./radinv);
627}
628
629//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
630
631void G4Material::ComputeNuclearInterLength()
632{
633 const G4double lambda0 = 35*CLHEP::g/CLHEP::cm2;
634 const G4double twothird = 2.0/3.0;
635 G4double NILinv = 0.0;
636 for (G4int i=0; i<fNumberOfElements; ++i) {
637 G4int Z = (*theElementVector)[i]->GetZasInt();
638 G4double A = (*theElementVector)[i]->GetN();
639 if(1 == Z) {
640 NILinv += fVecNbOfAtomsPerVolume[i]*A;
641 } else {
642 NILinv += fVecNbOfAtomsPerVolume[i]*G4Exp(twothird*G4Log(A));
643 }
644 }
645 NILinv *= amu/lambda0;
646 fNuclInterLen = (NILinv <= 0.0 ? DBL_MAX : 1./NILinv);
647}
648
649//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
650
652{
653 if(!IsLocked()) { fChemicalFormula = chF; }
654}
655
656//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
657
659{
660 if(val >= 0. && !IsLocked()) { fFreeElecDensity = val; }
661}
662
663//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
664
666{
667 if(!IsLocked()) {
668 if (nullptr == fIonisation) {
669 fIonisation = new G4IonisParamMat(this);
670 }
671 fIonisation->ComputeDensityEffectOnFly(val);
672 }
673}
674
675//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
676
678{
679 return &theMaterialTable;
680}
681
682//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
683
685{
686 return theMaterialTable.size();
687}
688
689//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
690
692{
693 // search the material by its name
694 for(auto& j : theMaterialTable)
695 {
696 if(j->GetName() == materialName)
697 {
698 return j;
699 }
700 }
701
702 // the material does not exist in the table
703 if (warn) {
704 G4cout << "G4Material::GetMaterial() WARNING: The material: "
705 << materialName
706 << " does not exist in the table. Return NULL pointer."
707 << G4endl;
708 }
709 return nullptr;
710}
711
712//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
713
715{
716 // search the material by its name
717 for(auto mat : theMaterialTable)
718 {
719 if(1 == mat->GetNumberOfElements() && z == mat->GetZ() &&
720 a == mat->GetA() && dens == mat->GetDensity())
721 {
722 return mat;
723 }
724 }
725 return nullptr;
726}
727
728//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
729
731{
732 // search the material by its name
733 for(auto mat : theMaterialTable)
734 {
735 if(nComp == mat->GetNumberOfElements() && dens == mat->GetDensity())
736 {
737 return mat;
738 }
739 }
740 return nullptr;
741}
742
743//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
744
746{
747 if (fNumberOfElements > 1) {
749 ed << "For material " << fName << " ERROR in GetZ() - Nelm="
750 << fNumberOfElements << " > 1, which is not allowed";
751 G4Exception ("G4Material::GetZ()", "mat036", FatalException,
752 ed, "");
753 }
754 return (*theElementVector)[0]->GetZ();
755}
756
757//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
758
760{
761 if (fNumberOfElements > 1) {
763 ed << "For material " << fName << " ERROR in GetA() - Nelm="
764 << fNumberOfElements << " > 1, which is not allowed";
765 G4Exception ("G4Material::GetA()", "mat036", FatalException,
766 ed, "");
767 }
768 return (*theElementVector)[0]->GetA();
769}
770
771//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
772
773std::ostream& operator<<(std::ostream& flux, const G4Material* material)
774{
775 std::ios::fmtflags mode = flux.flags();
776 flux.setf(std::ios::fixed,std::ios::floatfield);
777 G4long prec = flux.precision(3);
778
779 flux
780 << " Material: " << std::setw(8) << material->fName
781 << " " << material->fChemicalFormula << " "
782 << " density: " << std::setw(6) << std::setprecision(3)
783 << G4BestUnit(material->fDensity,"Volumic Mass")
784 << " RadL: " << std::setw(7) << std::setprecision(3)
785 << G4BestUnit(material->fRadlen,"Length")
786 << " Nucl.Int.Length: " << std::setw(7) << std::setprecision(3)
787 << G4BestUnit(material->fNuclInterLen,"Length")
788 << "\n" << std::setw(30)
789 << " Imean: " << std::setw(7) << std::setprecision(3)
790 << G4BestUnit(material->GetIonisation()->GetMeanExcitationEnergy(),"Energy")
791 << " temperature: " << std::setw(6) << std::setprecision(2)
792 << (material->fTemp)/CLHEP::kelvin << " K"
793 << " pressure: " << std::setw(6) << std::setprecision(2)
794 << (material->fPressure)/CLHEP::atmosphere << " atm" << "\n";
795
796 for (G4int i=0; i<material->fNumberOfElements; i++) {
797 flux
798 << "\n ---> " << (*(material->theElementVector))[i]
799 << "\n ElmMassFraction: "
800 << std::setw(6)<< std::setprecision(2)
801 << (material->fMassFractionVector[i])/perCent << " %"
802 << " ElmAbundance " << std::setw(6)<< std::setprecision(2)
803 << 100*(material->fVecNbOfAtomsPerVolume[i])
804 /(material->fTotNbOfAtomsPerVolume)
805 << " % \n";
806 }
807 flux.precision(prec);
808 flux.setf(mode,std::ios::floatfield);
809
810 if(material->IsExtended())
811 { static_cast<const G4ExtendedMaterial*>(material)->Print(flux); }
812
813 return flux;
814}
815
816//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
817
818std::ostream& operator<<(std::ostream& flux, const G4Material& material)
819{
820 flux << &material;
821 return flux;
822}
823
824//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
825
826std::ostream& operator<<(std::ostream& flux, const G4MaterialTable& MaterialTable)
827{
828 //Dump info for all known materials
829 flux << "\n***** Table : Nb of materials = " << MaterialTable.size()
830 << " *****\n" << G4endl;
831
832 for(auto i : MaterialTable)
833 {
834 flux << i << G4endl << G4endl;
835 }
836
837 return flux;
838}
839
840//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
841
843{
844 return false;
845}
846
847//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
848
850{
851 if(fMaterialPropertiesTable != anMPT && !IsLocked()) {
852 delete fMaterialPropertiesTable;
853 fMaterialPropertiesTable = anMPT;
854 }
855}
856
857//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
858
859G4bool G4Material::IsLocked()
860{
862 return !(state == G4State_PreInit ||
863 state == G4State_Init ||
864 state == G4State_Idle);
865}
866
867//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@ G4State_Init
@ G4State_Idle
@ G4State_PreInit
std::vector< const G4Element * > G4ElementVector
@ 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
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:180
G4double G4Log(G4double x)
Definition: G4Log.hh:227
std::vector< G4Material * > G4MaterialTable
std::ostream & operator<<(std::ostream &flux, const G4Material *material)
Definition: G4Material.cc:773
G4State
Definition: G4Material.hh:110
@ kStateSolid
Definition: G4Material.hh:110
@ kStateGas
Definition: G4Material.hh:110
@ kStateUndefined
Definition: G4Material.hh:110
#define G4BestUnit(a, b)
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]
const G4double A[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4int GetNumberOfFreeElectrons(G4int Z, G4double th)
const G4String & GetName() const
Definition: G4Element.hh:127
G4DensityEffectCalculator * GetDensityEffectCalculator() const
G4double GetMeanExcitationEnergy() const
void ComputeDensityEffectOnFly(G4bool)
void SetMeanExcitationEnergy(G4double value)
G4double GetDensity() const
Definition: G4Material.hh:175
const G4String & GetChemicalFormula() const
Definition: G4Material.hh:173
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:185
const G4Material * GetBaseMaterial() const
Definition: G4Material.hh:228
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
Definition: G4Material.hh:251
G4double GetTotNbOfAtomsPerVolume() const
Definition: G4Material.hh:204
static size_t GetNumberOfMaterials()
Definition: G4Material.cc:684
G4State GetState() const
Definition: G4Material.hh:176
const G4Element * GetElement(G4int iel) const
Definition: G4Material.hh:197
virtual G4bool IsExtended() const
Definition: G4Material.cc:842
G4double GetZ() const
Definition: G4Material.cc:745
const G4double * GetFractionVector() const
Definition: G4Material.hh:189
G4double GetTotNbOfElectPerVolume() const
Definition: G4Material.hh:207
G4IonisParamMat * GetIonisation() const
Definition: G4Material.hh:221
G4double GetFreeElectronDensity() const
Definition: G4Material.hh:174
virtual ~G4Material()
Definition: G4Material.cc:238
size_t GetNumberOfElements() const
Definition: G4Material.hh:181
void SetChemicalFormula(const G4String &chF)
Definition: G4Material.cc:651
const G4int * GetAtomsVector() const
Definition: G4Material.hh:193
G4double GetA() const
Definition: G4Material.cc:759
G4SandiaTable * GetSandiaTable() const
Definition: G4Material.hh:224
void AddElementByNumberOfAtoms(const G4Element *elm, G4int nAtoms)
Definition: G4Material.cc:373
G4double GetRadlen() const
Definition: G4Material.hh:215
G4double GetMassOfMolecule() const
Definition: G4Material.hh:236
const G4double * GetVecNbOfAtomsPerVolume() const
Definition: G4Material.hh:201
G4Material(const G4String &name, G4double z, G4double a, G4double density, G4State state=kStateUndefined, G4double temp=NTP_Temperature, G4double pressure=CLHEP::STP_Pressure)
Definition: G4Material.cc:93
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:677
void AddMaterial(G4Material *material, G4double fraction)
Definition: G4Material.cc:515
const G4String & GetName() const
Definition: G4Material.hh:172
void SetMaterialPropertiesTable(G4MaterialPropertiesTable *anMPT)
Definition: G4Material.cc:849
void SetFreeElectronDensity(G4double val)
Definition: G4Material.cc:658
void AddElementByMassFraction(const G4Element *elm, G4double fraction)
Definition: G4Material.cc:454
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
Definition: G4Material.cc:691
void ComputeDensityEffectOnFly(G4bool)
Definition: G4Material.cc:665
G4double GetNuclearInterLength() const
Definition: G4Material.hh:218
static G4NistManager * Instance()
G4Element * FindOrBuildElement(G4int Z, G4bool isotopes=true)
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
int G4lrint(double ad)
Definition: templates.hh:134
#define DBL_MAX
Definition: templates.hh:62