Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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