95 if (density < universe_mean_density)
97 G4cout <<
"--- Warning from G4Material::G4Material()"
98 <<
" define a material with density=0 is not allowed. \n"
99 <<
" The material " << name <<
" will be constructed with the"
100 <<
" default minimal density: " << universe_mean_density/(g/cm3)
102 density = universe_mean_density;
108 fPressure = pressure;
112 maxNbComponents = fNumberOfComponents = fNumberOfElements = 1;
113 fArrayLength = maxNbComponents;
114 fImplicitElement =
true;
116 theElementVector->push_back(
new G4Element(name,
" ", z, a));
117 fMassFractionVector =
new G4double[1];
118 fMassFractionVector[0] = 1. ;
119 fMassOfMolecule = a/Avogadro;
121 (*theElementVector)[0] -> increaseCountUse();
125 if (fDensity > kGasThreshold) { fState =
kStateSolid; }
129 ComputeDerivedQuantities();
142 InitializePointers();
144 if (density < universe_mean_density)
146 G4cout <<
"--- Warning from G4Material::G4Material()"
147 <<
" define a material with density=0 is not allowed. \n"
148 <<
" The material " << name <<
" will be constructed with the"
149 <<
" default minimal density: " << universe_mean_density/(g/cm3)
151 density = universe_mean_density;
157 fPressure = pressure;
159 maxNbComponents = nComponents;
160 fArrayLength = maxNbComponents;
161 fNumberOfComponents = fNumberOfElements = 0;
163 theElementVector->reserve(maxNbComponents);
167 if (fDensity > kGasThreshold) { fState =
kStateSolid; }
181 InitializePointers();
183 if (density < universe_mean_density)
185 G4cout <<
"--- Warning from G4Material::G4Material()"
186 <<
" define a material with density=0 is not allowed. \n"
187 <<
" The material " << name <<
" will be constructed with the"
188 <<
" default minimal density: " << universe_mean_density/(g/cm3)
190 density = universe_mean_density;
196 fPressure = pressure;
198 fBaseMaterial = bmat;
203 maxNbComponents = fNumberOfElements;
204 fNumberOfComponents = fNumberOfElements;
208 CopyPointersOfBaseMaterial();
217 : fNumberOfComponents(0), fNumberOfElements(0), theElementVector(0),
218 fImplicitElement(false), fMassFractionVector(0), fAtomsVector(0),
219 fMaterialPropertiesTable(0), fIndexInTable(0),
220 VecNbOfAtomsPerVolume(0),
fIonisation(0), fSandiaTable(0)
222 InitializePointers();
231 if (theElementVector) {
delete theElementVector; }
232 if (fMassFractionVector) {
delete [] fMassFractionVector; }
233 if (fAtomsVector) {
delete [] fAtomsVector; }
234 if (fSandiaTable) {
delete fSandiaTable; }
236 if (fIonisation) {
delete fIonisation; }
237 if (VecNbOfAtomsPerVolume) {
delete [] VecNbOfAtomsPerVolume; }
241 theMaterialTable[fIndexInTable] = 0;
246void G4Material::InitializePointers()
248 theElementVector = 0;
249 fMassFractionVector = 0;
251 fMaterialPropertiesTable = 0;
253 VecNbOfAtomsPerVolume = 0;
259 fImplicitElement =
false;
260 fChemicalFormula =
"";
269 TotNbOfAtomsPerVolume = 0;
270 TotNbOfElectPerVolume = 0;
273 fMassOfMolecule = 0.0;
276 theMaterialTable.push_back(
this);
277 fIndexInTable = theMaterialTable.size() - 1;
282void G4Material::ComputeDerivedQuantities()
289 TotNbOfAtomsPerVolume = 0.;
290 if (VecNbOfAtomsPerVolume) {
delete [] VecNbOfAtomsPerVolume; }
291 VecNbOfAtomsPerVolume =
new G4double[fNumberOfElements];
292 TotNbOfElectPerVolume = 0.;
293 for (
size_t i=0; i<fNumberOfElements; ++i) {
294 Zi = (*theElementVector)[i]->GetZ();
295 Ai = (*theElementVector)[i]->GetA();
296 VecNbOfAtomsPerVolume[i] = Avogadro*fDensity*fMassFractionVector[i]/Ai;
297 TotNbOfAtomsPerVolume += VecNbOfAtomsPerVolume[i];
298 TotNbOfElectPerVolume += VecNbOfAtomsPerVolume[i]*Zi;
301 ComputeRadiationLength();
302 ComputeNuclearInterLength();
304 if (fIonisation) {
delete fIonisation; }
306 if (fSandiaTable) {
delete fSandiaTable; }
312void G4Material::CopyPointersOfBaseMaterial()
323 if (VecNbOfAtomsPerVolume) {
delete [] VecNbOfAtomsPerVolume; }
324 VecNbOfAtomsPerVolume =
new G4double[fNumberOfElements];
325 for (
size_t i=0; i<fNumberOfElements; ++i) {
326 VecNbOfAtomsPerVolume[i] = factor*v[i];
328 fRadlen = fBaseMaterial->
GetRadlen()/factor;
330 if (fIonisation) {
delete fIonisation; }
344 if ( fNumberOfElements == 0 ) {
345 fAtomsVector =
new G4int [fArrayLength];
346 fMassFractionVector =
new G4double[fArrayLength];
350 if (
G4int(fNumberOfElements) < maxNbComponents ) {
351 theElementVector->push_back(element);
352 fAtomsVector[fNumberOfElements] = nAtoms;
353 fNumberOfComponents = ++fNumberOfElements;
356 G4cout <<
"G4Material::AddElement ERROR for " << fName <<
" nElement= "
357 << fNumberOfElements <<
G4endl;
359 "Attempt to add more than the declared number of elements.");
362 if (
G4int(fNumberOfElements) == maxNbComponents ) {
366 for (i=0; i<fNumberOfElements; ++i) {
367 G4double w = fAtomsVector[i]*(*theElementVector)[i]->GetA();
369 fMassFractionVector[i] = w;
371 for (i=0; i<fNumberOfElements; ++i) {
372 fMassFractionVector[i] /= Amol;
375 fMassOfMolecule = Amol/Avogadro;
376 ComputeDerivedQuantities();
386 if(fraction < 0.0 || fraction > 1.0) {
387 G4cout <<
"G4Material::AddElement ERROR for " << fName <<
" and "
388 << element->
GetName() <<
" mass fraction= " << fraction
389 <<
" is wrong " <<
G4endl;
391 "Attempt to add element with wrong mass fraction");
394 if (fNumberOfComponents == 0) {
395 fMassFractionVector =
new G4double[fArrayLength];
396 fAtomsVector =
new G4int [fArrayLength];
399 if (
G4int(fNumberOfComponents) < maxNbComponents) {
401 while ((el<fNumberOfElements)&&(element!=(*theElementVector)[el])) { ++el; }
402 if (el<fNumberOfElements) fMassFractionVector[el] += fraction;
404 theElementVector->push_back(element);
405 fMassFractionVector[el] = fraction;
409 ++fNumberOfComponents;
411 G4cout <<
"G4Material::AddElement ERROR for " << fName <<
" nElement= "
412 << fNumberOfElements <<
G4endl;
414 "Attempt to add more than the declared number of elements.");
418 if (
G4int(fNumberOfComponents) == maxNbComponents) {
424 for (i=0; i<fNumberOfElements; ++i) {
425 wtSum += fMassFractionVector[i];
426 Zmol += fMassFractionVector[i]*(*theElementVector)[i]->GetZ();
427 Amol += fMassFractionVector[i]*(*theElementVector)[i]->GetA();
429 if (std::fabs(1.-wtSum) > perThousand) {
430 G4cerr <<
"WARNING !! for " << fName <<
" sum of fractional masses "
431 << wtSum <<
" is not 1 - results may be wrong"
434 for (i=0; i<fNumberOfElements; ++i) {
436 G4int(fMassFractionVector[i]*Amol/(*theElementVector)[i]->
GetA()+0.5);
439 ComputeDerivedQuantities();
449 if(fraction < 0.0 || fraction > 1.0) {
450 G4cout <<
"G4Material::AddMaterial ERROR for " << fName <<
" and "
451 << material->
GetName() <<
" mass fraction= " << fraction
452 <<
" is wrong " <<
G4endl;
454 "Attempt to add material with wrong mass fraction");
457 if (fNumberOfComponents == 0) {
458 fMassFractionVector =
new G4double[fArrayLength];
459 fAtomsVector =
new G4int [fArrayLength];
466 G4int nold = fArrayLength;
467 fArrayLength += nelm - 1;
470 for(
G4int i=0; i<nold; ++i) {
471 v1[i] = fMassFractionVector[i];
472 i1[i] = fAtomsVector[i];
474 delete [] fAtomsVector;
475 delete [] fMassFractionVector;
476 fMassFractionVector = v1;
481 if (
G4int(fNumberOfComponents) < maxNbComponents) {
482 for (
size_t elm=0; elm<nelm; ++elm)
486 while ((el<fNumberOfElements)&&(element!=(*theElementVector)[el])) el++;
487 if (el < fNumberOfElements) fMassFractionVector[el] += fraction
490 theElementVector->push_back(element);
491 fMassFractionVector[el] = fraction
497 ++fNumberOfComponents;
499 fMatComponents[material] = fraction;
502 G4cout <<
"G4Material::AddMaterial ERROR for " << fName <<
" nElement= "
503 << fNumberOfElements <<
G4endl;
505 "Attempt to add more than the declared number of components.");
509 if (
G4int(fNumberOfComponents) == maxNbComponents) {
514 for (i=0; i<fNumberOfElements; ++i) {
515 wtSum += fMassFractionVector[i];
516 Zmol += fMassFractionVector[i]*(*theElementVector)[i]->GetZ();
517 Amol += fMassFractionVector[i]*(*theElementVector)[i]->GetA();
519 if (std::fabs(1.-wtSum) > perThousand) {
520 G4cout <<
"G4Material::AddMaterial WARNING !! for " << fName
521 <<
" sum of fractional masses "
522 << wtSum <<
" is not 1 - results may be wrong"
525 for (i=0;i<fNumberOfElements;i++) {
527 G4int(fMassFractionVector[i]*Amol/(*theElementVector)[i]->
GetA()+0.5);
530 ComputeDerivedQuantities();
536void G4Material::ComputeRadiationLength()
539 for (
size_t i=0;i<fNumberOfElements;++i) {
540 radinv += VecNbOfAtomsPerVolume[i]*((*theElementVector)[i]->GetfRadTsai());
542 fRadlen = (radinv <= 0.0 ?
DBL_MAX : 1./radinv);
547void G4Material::ComputeNuclearInterLength()
552 for (
size_t i=0; i<fNumberOfElements; ++i) {
554 VecNbOfAtomsPerVolume[i]*g4pow->
Z23(
G4int((*theElementVector)[i]->GetN()+0.5));
556 NILinv *= amu/lambda0;
557 fNuclInterLen = (NILinv <= 0.0 ?
DBL_MAX : 1./NILinv);
564 return &theMaterialTable;
571 return theMaterialTable.size();
579 for (
size_t J=0 ; J<theMaterialTable.size() ; ++J)
581 if (theMaterialTable[J]->
GetName() == materialName)
582 {
return theMaterialTable[J]; }
587 G4cout <<
"G4Material::GetMaterial() WARNING: The material: "
588 << materialName <<
" does not exist in the table. Return NULL pointer."
598 InitializePointers();
606 if (fNumberOfElements > 1) {
607 G4cout <<
"G4Material ERROR in GetZ. The material: " << fName <<
" is a mixture."
610 "the Atomic number is not well defined." );
612 return (*theElementVector)[0]->GetZ();
619 if (fNumberOfElements > 1) {
620 G4cout <<
"G4Material ERROR in GetA. The material: " << fName <<
" is a mixture."
623 "the Atomic mass is not well defined." );
625 return (*theElementVector)[0]->GetA();
635 fChemicalFormula = right.fChemicalFormula;
636 fDensity = right.fDensity;
637 fState = right.fState;
639 fPressure = right.fPressure;
642 if (theElementVector) {
delete theElementVector; }
643 if (fMassFractionVector) {
delete [] fMassFractionVector; }
644 if (fAtomsVector) {
delete [] fAtomsVector; }
645 if (fIonisation) {
delete fIonisation; }
646 if (fSandiaTable) {
delete fSandiaTable; }
649 if (VecNbOfAtomsPerVolume) {
delete [] VecNbOfAtomsPerVolume; }
651 maxNbComponents = right.maxNbComponents;
652 fNumberOfComponents = right.fNumberOfComponents;
653 fNumberOfElements = right.fNumberOfElements;
654 fImplicitElement = right.fImplicitElement;
656 fMaterialPropertiesTable = right.fMaterialPropertiesTable;
657 fBaseMaterial = right.fBaseMaterial;
658 fMassOfMolecule= right.fMassOfMolecule;
659 fMatComponents= right.fMatComponents;
662 CopyPointersOfBaseMaterial();
666 fMassFractionVector =
new G4double[fNumberOfElements];
667 fAtomsVector =
new G4int[fNumberOfElements];
668 for (
size_t i=0; i<fNumberOfElements; ++i) {
669 (*theElementVector)[i] = (*right.theElementVector)[i];
670 fMassFractionVector[i] = right.fMassFractionVector[i];
671 fAtomsVector[i] = right.fAtomsVector[i];
673 ComputeDerivedQuantities();
699 std::ios::fmtflags mode = flux.flags();
700 flux.setf(std::ios::fixed,std::ios::floatfield);
701 G4long prec = flux.precision(3);
704 <<
" Material: " << std::setw(8) << material->fName
705 <<
" " << material->fChemicalFormula <<
" "
706 <<
" density: " << std::setw(6) << std::setprecision(3)
707 <<
G4BestUnit(material->fDensity,
"Volumic Mass")
708 <<
" RadL: " << std::setw(7) << std::setprecision(3)
710 <<
" Nucl.Int.Length: " << std::setw(7) << std::setprecision(3)
711 <<
G4BestUnit(material->fNuclInterLen,
"Length")
712 <<
" Imean: " << std::setw(7) << std::setprecision(3)
717 <<
" temperature: " << std::setw(6) << std::setprecision(2)
718 << (material->fTemp)/kelvin <<
" K"
719 <<
" pressure: " << std::setw(6) << std::setprecision(2)
720 << (material->fPressure)/atmosphere <<
" atm";
722 for (
size_t i=0; i<material->fNumberOfElements; i++) {
724 <<
"\n ---> " << (*(material->theElementVector))[i]
725 <<
"\n ElmMassFraction: "
726 << std::setw(6)<< std::setprecision(2)
727 << (material->fMassFractionVector[i])/perCent <<
" %"
728 <<
" ElmAbundance " << std::setw(6)<< std::setprecision(2)
729 << 100*(material->VecNbOfAtomsPerVolume[i])/(material->TotNbOfAtomsPerVolume)
732 flux.precision(prec);
733 flux.setf(mode,std::ios::floatfield);
751 flux <<
"\n***** Table : Nb of materials = " << MaterialTable.size()
754 for (
size_t i=0; i<MaterialTable.size(); ++i) {
std::vector< G4Element * > G4ElementVector
std::vector< G4Material * > G4MaterialTable
std::ostream & operator<<(std::ostream &flux, G4Material *material)
#define G4BestUnit(a, b)
#define G4_USE_G4BESTUNIT_FOR_VERBOSE 1
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
const G4String & GetName() const
G4double GetMeanExcitationEnergy() const
void SetMeanExcitationEnergy(G4double value)
G4double GetDensity() const
const G4String & GetChemicalFormula() const
static const G4MaterialTable * GetMaterialTable()
const G4ElementVector * GetElementVector() const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
G4double GetTotNbOfAtomsPerVolume() const
static size_t GetNumberOfMaterials()
const G4double * GetFractionVector() const
G4double GetTotNbOfElectPerVolume() const
G4IonisParamMat * GetIonisation() const
void AddElement(G4Element *element, G4int nAtoms)
size_t GetNumberOfElements() const
const G4int * GetAtomsVector() const
G4int operator!=(const G4Material &) const
G4SandiaTable * GetSandiaTable() const
G4Material(const G4String &name, G4double z, G4double a, G4double density, G4State state=kStateUndefined, G4double temp=CLHEP::STP_Temperature, G4double pressure=CLHEP::STP_Pressure)
G4double GetRadlen() const
G4double GetMassOfMolecule() const
const G4double * GetVecNbOfAtomsPerVolume() const
G4int operator==(const G4Material &) const
void AddMaterial(G4Material *material, G4double fraction)
const G4String & GetName() const
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
G4double GetNuclearInterLength() const
static G4Pow * GetInstance()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)