100 InitializePointers();
102 if (density < universe_mean_density)
104 G4cout <<
" G4Material WARNING:"
105 <<
" define a material with density=0 is not allowed. \n"
106 <<
" The material " << name <<
" will be constructed with the"
107 <<
" default minimal density: " << universe_mean_density/(g/cm3)
109 density = universe_mean_density;
115 fPressure = pressure;
119 maxNbComponents = fNumberOfComponents = fNumberOfElements = 1;
120 fArrayLength = maxNbComponents;
127 if(!elm) { elm =
new G4Element(
"ELM_" + name, name, z, a); }
128 theElementVector->push_back(elm);
130 fMassFractionVector =
new G4double[1];
131 fMassFractionVector[0] = 1.;
132 fMassOfMolecule = a/CLHEP::Avogadro;
136 if (fDensity > kGasThreshold) { fState =
kStateSolid; }
140 ComputeDerivedQuantities();
153 InitializePointers();
155 if (density < universe_mean_density)
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)
162 density = universe_mean_density;
168 fPressure = pressure;
170 maxNbComponents = nComponents;
171 fArrayLength = maxNbComponents;
172 fNumberOfComponents = fNumberOfElements = 0;
174 theElementVector->reserve(maxNbComponents);
178 if (fDensity > kGasThreshold) { fState =
kStateSolid; }
192 InitializePointers();
194 if (density < universe_mean_density)
196 G4cout <<
"--- Warning from G4Material::G4Material()"
197 <<
" define a material with density=0 is not allowed. \n"
198 <<
" The material " << name <<
" will be constructed with the"
199 <<
" default minimal density: " << universe_mean_density/(g/cm3)
201 density = universe_mean_density;
207 fPressure = pressure;
209 fBaseMaterial = bmat;
214 maxNbComponents = fNumberOfElements;
215 fNumberOfComponents = fNumberOfElements;
217 CopyPointersOfBaseMaterial();
228 InitializePointers();
236 if(fBaseMaterial ==
nullptr) {
237 delete theElementVector;
240 delete [] fMassFractionVector;
241 delete [] fAtomsVector;
244 delete [] fVecNbOfAtomsPerVolume;
248 theMaterialTable[fIndexInTable] =
nullptr;
253void G4Material::InitializePointers()
255 theElementVector =
nullptr;
256 fMassFractionVector =
nullptr;
257 fAtomsVector =
nullptr;
258 fMaterialPropertiesTable =
nullptr;
260 fVecNbOfAtomsPerVolume =
nullptr;
261 fBaseMaterial =
nullptr;
263 fChemicalFormula =
"";
267 fFreeElecDensity = 0.0;
273 fNumberOfComponents = 0;
274 fNumberOfElements = 0;
275 fTotNbOfAtomsPerVolume = 0.0;
276 fTotNbOfElectPerVolume = 0.0;
279 fMassOfMolecule = 0.0;
281 fIonisation =
nullptr;
282 fSandiaTable =
nullptr;
285 fIndexInTable = theMaterialTable.size();
286 for(
size_t i=0; i<fIndexInTable; ++i) {
287 if(theMaterialTable[i]->
GetName() == fName) {
288 G4cout <<
"G4Material WARNING: duplicate name of material "
293 theMaterialTable.push_back(
this);
298void G4Material::ComputeDerivedQuantities()
304 fTotNbOfAtomsPerVolume = 0.;
305 if (fVecNbOfAtomsPerVolume) {
delete [] fVecNbOfAtomsPerVolume; }
306 fVecNbOfAtomsPerVolume =
new G4double[fNumberOfElements];
307 fTotNbOfElectPerVolume = 0.;
308 fFreeElecDensity = 0.;
309 const G4double elecTh = 15.*CLHEP::eV;
310 for (
G4int i=0; i<fNumberOfElements; ++i) {
311 Zi = (*theElementVector)[i]->GetZ();
312 Ai = (*theElementVector)[i]->GetA();
313 fVecNbOfAtomsPerVolume[i] = Avogadro*fDensity*fMassFractionVector[i]/Ai;
314 fTotNbOfAtomsPerVolume += fVecNbOfAtomsPerVolume[i];
315 fTotNbOfElectPerVolume += fVecNbOfAtomsPerVolume[i]*Zi;
317 fFreeElecDensity += fVecNbOfAtomsPerVolume[i]*
322 ComputeRadiationLength();
323 ComputeNuclearInterLength();
326 if (!fSandiaTable){ fSandiaTable =
new G4SandiaTable(
this); }
331void G4Material::CopyPointersOfBaseMaterial()
342 fMassFractionVector =
347 if (fVecNbOfAtomsPerVolume) {
delete [] fVecNbOfAtomsPerVolume; }
348 fVecNbOfAtomsPerVolume =
new G4double[fNumberOfElements];
349 for (
G4int i=0; i<fNumberOfElements; ++i) {
350 fVecNbOfAtomsPerVolume[i] = factor*v[i];
352 fRadlen = fBaseMaterial->
GetRadlen()/factor;
372 if ( fNumberOfElements == 0 ) {
373 fAtomsVector =
new G4int [fArrayLength];
374 fMassFractionVector =
new G4double[fArrayLength];
378 if ( fNumberOfElements < maxNbComponents ) {
379 theElementVector->push_back(element);
380 fAtomsVector[fNumberOfElements] = nAtoms;
381 fNumberOfComponents = ++fNumberOfElements;
383 G4cout <<
"G4Material::AddElement ERROR for " << fName <<
" nElement= "
384 << fNumberOfElements <<
G4endl;
386 "Attempt to add more than the declared number of elements.");
389 if ( fNumberOfElements == maxNbComponents ) {
393 for (i=0; i<fNumberOfElements; ++i) {
394 G4double w = fAtomsVector[i]*(*theElementVector)[i]->GetA();
396 fMassFractionVector[i] = w;
398 for (i=0; i<fNumberOfElements; ++i) {
399 fMassFractionVector[i] /= Amol;
402 fMassOfMolecule = Amol/Avogadro;
403 ComputeDerivedQuantities();
413 if(fraction < 0.0 || fraction > 1.0) {
414 G4cout <<
"G4Material::AddElement ERROR for " << fName <<
" and "
415 << element->
GetName() <<
" mass fraction= " << fraction
416 <<
" is wrong " <<
G4endl;
418 "Attempt to add element with wrong mass fraction");
421 if (fNumberOfComponents == 0) {
422 fMassFractionVector =
new G4double[fArrayLength];
423 fAtomsVector =
new G4int [fArrayLength];
426 if (fNumberOfComponents < maxNbComponents) {
429 while ((el<fNumberOfElements)&&(element!=(*theElementVector)[el])) { ++el; }
430 if (el<fNumberOfElements) fMassFractionVector[el] += fraction;
432 theElementVector->push_back(element);
433 fMassFractionVector[el] = fraction;
436 ++fNumberOfComponents;
438 G4cout <<
"G4Material::AddElement ERROR for " << fName <<
" nElement= "
439 << fNumberOfElements <<
G4endl;
441 "Attempt to add more than the declared number of elements.");
445 if (fNumberOfComponents == maxNbComponents) {
451 for (i=0; i<fNumberOfElements; ++i) {
452 wtSum += fMassFractionVector[i];
453 Zmol += fMassFractionVector[i]*(*theElementVector)[i]->GetZ();
454 Amol += fMassFractionVector[i]*(*theElementVector)[i]->GetA();
456 if (std::abs(1.-wtSum) > perThousand) {
457 G4cout <<
"WARNING !! for " << fName <<
" sum of fractional masses "
458 << wtSum <<
" is not 1 - results may be wrong" <<
G4endl;
460 "Fractional masses are incorrect.");
462 for (i=0; i<fNumberOfElements; ++i) {
464 G4lrint(fMassFractionVector[i]*Amol/(*theElementVector)[i]->
GetA());
467 ComputeDerivedQuantities();
477 if(fraction < 0.0 || fraction > 1.0) {
478 G4cout <<
"G4Material::AddMaterial ERROR for " << fName <<
" and "
479 << material->
GetName() <<
" mass fraction= " << fraction
482 "Attempt to add material with wrong mass fraction");
485 if (fNumberOfComponents == 0) {
486 fMassFractionVector =
new G4double[fArrayLength];
487 fAtomsVector =
new G4int [fArrayLength];
494 G4int nold = fArrayLength;
495 fArrayLength += nelm - 1;
498 for(
G4int i=0; i<nold; ++i) {
499 v1[i] = fMassFractionVector[i];
500 i1[i] = fAtomsVector[i];
502 delete [] fAtomsVector;
503 delete [] fMassFractionVector;
504 fMassFractionVector = v1;
509 if (fNumberOfComponents < maxNbComponents) {
510 for (
G4int elm=0; elm<nelm; ++elm)
515 while ((el<fNumberOfElements)&&(element!=(*theElementVector)[el])) el++;
516 if (el < fNumberOfElements) fMassFractionVector[el] += fraction
519 theElementVector->push_back(element);
520 fMassFractionVector[el] = fraction
525 ++fNumberOfComponents;
527 fMatComponents[material] = fraction;
530 G4cout <<
"G4Material::AddMaterial ERROR for " << fName <<
" nElement= "
531 << fNumberOfElements <<
G4endl;
533 "Attempt to add more than the declared number of components.");
537 if (fNumberOfComponents == maxNbComponents) {
542 for (i=0; i<fNumberOfElements; ++i) {
543 wtSum += fMassFractionVector[i];
544 Zmol += fMassFractionVector[i]*(*theElementVector)[i]->GetZ();
545 Amol += fMassFractionVector[i]*(*theElementVector)[i]->GetA();
547 if (std::abs(1.-wtSum) > perThousand) {
548 G4cout <<
"G4Material::AddMaterial WARNING !! for " << fName
549 <<
" sum of fractional masses "
550 << wtSum <<
" is not 1 - results may be wrong"
553 "Fractional masses are incorrect.");
555 for (i=0; i<fNumberOfElements; ++i) {
557 G4lrint(fMassFractionVector[i]*Amol/(*theElementVector)[i]->
GetA());
560 ComputeDerivedQuantities();
566void G4Material::ComputeRadiationLength()
569 for (
G4int i=0;i<fNumberOfElements;++i) {
570 radinv += fVecNbOfAtomsPerVolume[i]*((*theElementVector)[i]->GetfRadTsai());
572 fRadlen = (radinv <= 0.0 ?
DBL_MAX : 1./radinv);
577void G4Material::ComputeNuclearInterLength()
579 const G4double lambda0 = 35*CLHEP::g/CLHEP::cm2;
582 for (
G4int i=0; i<fNumberOfElements; ++i) {
583 G4int Z = (*theElementVector)[i]->GetZasInt();
584 G4double A = (*theElementVector)[i]->GetN();
586 NILinv += fVecNbOfAtomsPerVolume[i]*
A;
588 NILinv += fVecNbOfAtomsPerVolume[i]*
G4Exp(twothird*
G4Log(A));
591 NILinv *= amu/lambda0;
592 fNuclInterLen = (NILinv <= 0.0 ?
DBL_MAX : 1./NILinv);
599#ifdef G4MULTITHREADED
602 fChemicalFormula = chF;
603#ifdef G4MULTITHREADED
612#ifdef G4MULTITHREADED
615 if(val >= 0.) { fFreeElecDensity = val; }
616#ifdef G4MULTITHREADED
625#ifdef G4MULTITHREADED
630#ifdef G4MULTITHREADED
639 return &theMaterialTable;
646 return theMaterialTable.size();
654 for (
size_t j=0; j<theMaterialTable.size(); ++j) {
655 if (theMaterialTable[j]->
GetName() == materialName) {
656 return theMaterialTable[j];
662 G4cout <<
"G4Material::GetMaterial() WARNING: The material: "
664 <<
" does not exist in the table. Return NULL pointer."
675 for (
size_t j=0; j<theMaterialTable.size(); ++j) {
690 for (
size_t j=0; j<theMaterialTable.size(); ++j) {
703 if (fNumberOfElements > 1) {
704 G4cout <<
"G4Material ERROR in GetZ. The material: " << fName
707 "the Atomic number is not well defined." );
709 return (*theElementVector)[0]->GetZ();
716 if (fNumberOfElements > 1) {
717 G4cout <<
"G4Material ERROR in GetA. The material: " << fName
720 "the Atomic mass is not well defined." );
722 return (*theElementVector)[0]->GetA();
729 std::ios::fmtflags mode = flux.flags();
730 flux.setf(std::ios::fixed,std::ios::floatfield);
731 G4long prec = flux.precision(3);
734 <<
" Material: " << std::setw(8) << material->fName
735 <<
" " << material->fChemicalFormula <<
" "
736 <<
" density: " << std::setw(6) << std::setprecision(3)
737 <<
G4BestUnit(material->fDensity,
"Volumic Mass")
738 <<
" RadL: " << std::setw(7) << std::setprecision(3)
740 <<
" Nucl.Int.Length: " << std::setw(7) << std::setprecision(3)
741 <<
G4BestUnit(material->fNuclInterLen,
"Length")
742 <<
"\n" << std::setw(30)
743 <<
" Imean: " << std::setw(7) << std::setprecision(3)
745 <<
" temperature: " << std::setw(6) << std::setprecision(2)
746 << (material->fTemp)/CLHEP::kelvin <<
" K"
747 <<
" pressure: " << std::setw(6) << std::setprecision(2)
748 << (material->fPressure)/CLHEP::atmosphere <<
" atm" <<
"\n";
750 for (
G4int i=0; i<material->fNumberOfElements; i++) {
752 <<
"\n ---> " << (*(material->theElementVector))[i]
753 <<
"\n ElmMassFraction: "
754 << std::setw(6)<< std::setprecision(2)
755 << (material->fMassFractionVector[i])/perCent <<
" %"
756 <<
" ElmAbundance " << std::setw(6)<< std::setprecision(2)
757 << 100*(material->fVecNbOfAtomsPerVolume[i])
758 /(material->fTotNbOfAtomsPerVolume)
761 flux.precision(prec);
762 flux.setf(mode,std::ios::floatfield);
783 flux <<
"\n***** Table : Nb of materials = " << MaterialTable.size()
786 for (
size_t i=0; i<MaterialTable.size(); ++i) {
804 if(anMPT && fMaterialPropertiesTable != anMPT) {
805#ifdef G4MULTITHREADED
807 if(fMaterialPropertiesTable != anMPT) {
809 delete fMaterialPropertiesTable;
810 fMaterialPropertiesTable = anMPT;
811#ifdef G4MULTITHREADED
double A(double temperature)
std::vector< G4Element * > G4ElementVector
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
std::vector< G4Material * > G4MaterialTable
std::ostream & operator<<(std::ostream &flux, const G4Material *material)
#define G4MUTEX_INITIALIZER
#define G4MUTEXLOCK(mutex)
#define G4MUTEXUNLOCK(mutex)
G4GLOB_DLL std::ostream G4cout
static G4int GetNumberOfFreeElectrons(G4int Z, G4double th)
const G4String & GetName() const
G4double GetMeanExcitationEnergy() const
void ComputeDensityEffectOnFly(G4bool)
void SetMeanExcitationEnergy(G4double value)
G4DensityEffectCalculator * GetDensityEffectCalculator()
G4double GetDensity() const
const G4String & GetChemicalFormula() const
void SetFreeElectronDensity(G4double)
const G4ElementVector * GetElementVector() const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
G4double GetTotNbOfAtomsPerVolume() const
static size_t GetNumberOfMaterials()
virtual G4bool IsExtended() const
const G4double * GetFractionVector() const
G4double GetTotNbOfElectPerVolume() const
G4IonisParamMat * GetIonisation() const
G4double GetFreeElectronDensity() const
void AddElement(G4Element *element, G4int nAtoms)
size_t GetNumberOfElements() const
void SetChemicalFormula(const G4String &chF)
const G4int * GetAtomsVector() const
G4SandiaTable * GetSandiaTable() const
G4double GetRadlen() const
G4double GetMassOfMolecule() const
const G4double * GetVecNbOfAtomsPerVolume() const
G4Material(const G4String &name, G4double z, G4double a, G4double density, G4State state=kStateUndefined, G4double temp=NTP_Temperature, G4double pressure=CLHEP::STP_Pressure)
static G4MaterialTable * GetMaterialTable()
void AddMaterial(G4Material *material, G4double fraction)
const G4String & GetName() const
void SetMaterialPropertiesTable(G4MaterialPropertiesTable *anMPT)
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
void ComputeDensityEffectOnFly(G4bool)
G4double GetNuclearInterLength() const
static G4NistManager * Instance()
G4Element * FindOrBuildElement(G4int Z, G4bool isotopes=true)