G4Material.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // $Id: G4Material.cc 67044 2013-01-30 08:50:06Z gcosmo $
00027 //
00028 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00029 //
00030 // 26-06-96, Code uses operators (+=, *=, ++, -> etc.) correctly, P. Urban
00031 // 10-07-96, new data members added by L.Urban
00032 // 12-12-96, new data members added by L.Urban
00033 // 20-01-97, aesthetic rearrangement. RadLength calculation modified.
00034 //           Data members Zeff and Aeff REMOVED (i.e. passed to the Elements).
00035 //           (local definition of Zeff in DensityEffect and FluctModel...)
00036 //           Vacuum defined as a G4State. Mixture flag removed, M.Maire. 
00037 // 29-01-97, State=Vacuum automatically set density=0 in the contructors.
00038 //           Subsequent protections have been put in the calculation of 
00039 //           MeanExcEnergy, ShellCorrectionVector, DensityEffect, M.Maire.
00040 // 11-02-97, ComputeDensityEffect() rearranged, M.Maire.
00041 // 20-03-97, corrected initialization of pointers, M.Maire.
00042 // 28-05-98, the kState=kVacuum has been removed.
00043 //           automatic check for a minimal density, M.Maire 
00044 // 12-06-98, new method AddMaterial() allowing mixture of materials, M.Maire  
00045 // 09-07-98, ionisation parameters removed from the class, M.Maire
00046 // 05-10-98, change names: NumDensity -> NbOfAtomsPerVolume
00047 // 18-11-98, new interface to SandiaTable
00048 // 19-01-99  enlarge tolerance on test of coherence of gas conditions
00049 // 19-07-99, Constructors with chemicalFormula added by V.Ivanchenko
00050 // 16-01-01, Nuclear interaction length, M.Maire
00051 // 12-03-01, G4bool fImplicitElement;
00052 //           copy constructor and assignement operator revised (mma)
00053 // 03-05-01, flux.precision(prec) at begin/end of operator<<
00054 // 17-07-01, migration to STL. M. Verderi.
00055 // 14-09-01, Suppression of the data member fIndexInTable
00056 // 26-02-02, fIndexInTable renewed
00057 // 16-04-02, G4Exception put in constructor with chemical formula
00058 // 06-05-02, remove the check of the ideal gas state equation
00059 // 06-08-02, remove constructors with chemical formula (mma)
00060 // 22-01-04, proper STL handling of theElementVector (Hisaya)
00061 // 30-03-05, warning in GetMaterial(materialName) 
00062 // 09-03-06, minor change of printout (V.Ivanchenko) 
00063 // 10-01-07, compute fAtomVector in the case of mass fraction (V.Ivanchenko) 
00064 // 27-07-07, improve destructor (V.Ivanchenko) 
00065 // 18-10-07, move definition of material index to InitialisePointers (V.Ivanchenko) 
00066 // 13-08-08, do not use fixed size arrays (V.Ivanchenko)
00067 // 26-10-11, new scheme for G4Exception  (mma)
00068 // 13-04-12, map<G4Material*,G4double> fMatComponents, filled in AddMaterial()
00069 // 21-04-12, fMassOfMolecule, computed for AtomsCount (mma)
00070 // 
00071 // 
00072 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00073 
00074 #include <iomanip>
00075 
00076 #include "G4Material.hh"
00077 #include "G4UnitsTable.hh"
00078 #include "G4Pow.hh"
00079 #include "G4PhysicalConstants.hh"
00080 #include "G4SystemOfUnits.hh"
00081 
00082 G4MaterialTable G4Material::theMaterialTable;
00083 
00084 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00085 
00086 // Constructor to create a material from scratch
00087 
00088 G4Material::G4Material(const G4String& name, G4double z,
00089                        G4double a, G4double density, 
00090                        G4State state, G4double temp, G4double pressure)
00091   : fName(name)                
00092 {
00093   InitializePointers();
00094     
00095   if (density < universe_mean_density)
00096     { 
00097       G4cout << "--- Warning from G4Material::G4Material()"
00098              << " define a material with density=0 is not allowed. \n"
00099              << " The material " << name << " will be constructed with the"
00100              << " default minimal density: " << universe_mean_density/(g/cm3) 
00101              << "g/cm3" << G4endl;
00102       density = universe_mean_density;
00103     } 
00104 
00105   fDensity  = density;
00106   fState    = state;
00107   fTemp     = temp;
00108   fPressure = pressure;
00109 
00110   // Initialize theElementVector allocating one
00111   // element corresponding to this material
00112   maxNbComponents        = fNumberOfComponents = fNumberOfElements = 1;
00113   fArrayLength           = maxNbComponents;
00114   fImplicitElement       = true;
00115   theElementVector       = new G4ElementVector();
00116   theElementVector->push_back( new G4Element(name, " ", z, a));  
00117   fMassFractionVector    = new G4double[1];
00118   fMassFractionVector[0] = 1. ;
00119   fMassOfMolecule        = a/Avogadro;
00120   
00121   (*theElementVector)[0] -> increaseCountUse();
00122   
00123   if (fState == kStateUndefined)
00124     {
00125       if (fDensity > kGasThreshold) { fState = kStateSolid; }
00126       else                          { fState = kStateGas; }
00127     }
00128 
00129   ComputeDerivedQuantities();
00130 }
00131 
00132 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00133 
00134 // Constructor to create a material from a List of constituents
00135 // (elements and/or materials)  added with AddElement or AddMaterial
00136 
00137 G4Material::G4Material(const G4String& name, G4double density,
00138                        G4int nComponents,
00139                        G4State state, G4double temp, G4double pressure)
00140   : fName(name)                
00141 {
00142   InitializePointers();
00143     
00144   if (density < universe_mean_density)
00145     {
00146       G4cout << "--- Warning from G4Material::G4Material()"
00147              << " define a material with density=0 is not allowed. \n"
00148              << " The material " << name << " will be constructed with the"
00149              << " default minimal density: " << universe_mean_density/(g/cm3) 
00150              << "g/cm3" << G4endl;
00151       density = universe_mean_density;
00152     }
00153         
00154   fDensity  = density;
00155   fState    = state;
00156   fTemp     = temp;
00157   fPressure = pressure;
00158     
00159   maxNbComponents     = nComponents;
00160   fArrayLength        = maxNbComponents;
00161   fNumberOfComponents = fNumberOfElements = 0;
00162   theElementVector    = new G4ElementVector();
00163   theElementVector->reserve(maxNbComponents);  
00164     
00165   if (fState == kStateUndefined) 
00166     {
00167       if (fDensity > kGasThreshold) { fState = kStateSolid; }
00168       else                          { fState = kStateGas; }
00169     }
00170 }
00171 
00172 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00173 
00174 // Constructor to create a material from base material
00175 
00176 G4Material::G4Material(const G4String& name, G4double density,
00177                        const G4Material* bmat,
00178                        G4State state, G4double temp, G4double pressure)
00179   : fName(name)                
00180 {
00181   InitializePointers();
00182     
00183   if (density < universe_mean_density)
00184     {
00185       G4cout << "--- Warning from G4Material::G4Material()"
00186              << " define a material with density=0 is not allowed. \n"
00187              << " The material " << name << " will be constructed with the"
00188              << " default minimal density: " << universe_mean_density/(g/cm3) 
00189              << "g/cm3" << G4endl;
00190       density = universe_mean_density;
00191     }
00192 
00193   fDensity  = density;
00194   fState    = state;
00195   fTemp     = temp;
00196   fPressure = pressure;
00197 
00198   fBaseMaterial = bmat;
00199   fChemicalFormula = fBaseMaterial->GetChemicalFormula();
00200   fMassOfMolecule  = fBaseMaterial->GetMassOfMolecule();
00201 
00202   fNumberOfElements = fBaseMaterial->GetNumberOfElements();     
00203   maxNbComponents = fNumberOfElements;
00204   fNumberOfComponents = fNumberOfElements;
00205 
00206   fMaterialPropertiesTable = fBaseMaterial->GetMaterialPropertiesTable();
00207 
00208   CopyPointersOfBaseMaterial();
00209 }
00210 
00211 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00212 
00213 // Fake default constructor - sets only member data and allocates memory
00214 //                            for usage restricted to object persistency
00215 
00216 G4Material::G4Material(__void__&)
00217   : fNumberOfComponents(0), fNumberOfElements(0), theElementVector(0), 
00218     fImplicitElement(false), fMassFractionVector(0), fAtomsVector(0), 
00219     fMaterialPropertiesTable(0), fIndexInTable(0), 
00220     VecNbOfAtomsPerVolume(0), fIonisation(0), fSandiaTable(0)
00221 {
00222   InitializePointers();
00223 }
00224 
00225 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00226 
00227 G4Material::~G4Material()
00228 {
00229   //  G4cout << "### Destruction of material " << fName << " started" <<G4endl;
00230   if(!fBaseMaterial) {
00231     if (theElementVector)       { delete    theElementVector; }
00232     if (fMassFractionVector)    { delete [] fMassFractionVector; }
00233     if (fAtomsVector)           { delete [] fAtomsVector; }
00234     if (fSandiaTable)           { delete    fSandiaTable; }
00235   }
00236   if (fIonisation)            { delete    fIonisation; }
00237   if (VecNbOfAtomsPerVolume)  { delete [] VecNbOfAtomsPerVolume; }
00238 
00239   // Remove this material from theMaterialTable.
00240   //
00241   theMaterialTable[fIndexInTable] = 0;
00242 }
00243 
00244 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00245 
00246 void G4Material::InitializePointers()
00247 {
00248   theElementVector         = 0;
00249   fMassFractionVector      = 0;
00250   fAtomsVector             = 0;
00251   fMaterialPropertiesTable = 0;
00252     
00253   VecNbOfAtomsPerVolume    = 0;
00254   fIonisation              = 0;
00255   fSandiaTable             = 0;
00256 
00257   fBaseMaterial            = 0;
00258 
00259   fImplicitElement         = false;
00260   fChemicalFormula         = "";
00261 
00262   // initilized data members
00263   fDensity  = 0.0;
00264   fState    = kStateUndefined;
00265   fTemp     = 0.0;
00266   fPressure = 0.0;
00267   maxNbComponents     = 0;
00268   fArrayLength        = 0;
00269   TotNbOfAtomsPerVolume = 0;
00270   TotNbOfElectPerVolume = 0; 
00271   fRadlen = 0.0;
00272   fNuclInterLen = 0.0;
00273   fMassOfMolecule = 0.0;
00274 
00275   // Store in the static Table of Materials
00276   theMaterialTable.push_back(this);
00277   fIndexInTable = theMaterialTable.size() - 1;
00278 }
00279 
00280 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00281 
00282 void G4Material::ComputeDerivedQuantities()
00283 {
00284   // Header routine to compute various properties of material.
00285   // 
00286 
00287   // Number of atoms per volume (per element), total nb of electrons per volume
00288   G4double Zi, Ai;
00289   TotNbOfAtomsPerVolume = 0.;
00290   if (VecNbOfAtomsPerVolume) { delete [] VecNbOfAtomsPerVolume; }
00291   VecNbOfAtomsPerVolume = new G4double[fNumberOfElements];
00292   TotNbOfElectPerVolume = 0.;
00293   for (size_t i=0; i<fNumberOfElements; ++i) {
00294      Zi = (*theElementVector)[i]->GetZ();
00295      Ai = (*theElementVector)[i]->GetA();
00296      VecNbOfAtomsPerVolume[i] = Avogadro*fDensity*fMassFractionVector[i]/Ai;
00297      TotNbOfAtomsPerVolume += VecNbOfAtomsPerVolume[i];
00298      TotNbOfElectPerVolume += VecNbOfAtomsPerVolume[i]*Zi;
00299   }
00300         
00301   ComputeRadiationLength();
00302   ComputeNuclearInterLength();
00303 
00304   if (fIonisation) { delete fIonisation; }
00305   fIonisation  = new G4IonisParamMat(this);
00306   if (fSandiaTable) { delete fSandiaTable; }
00307   fSandiaTable = new G4SandiaTable(this);
00308 }
00309 
00310 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00311 
00312 void G4Material::CopyPointersOfBaseMaterial()
00313 {
00314   G4double factor = fDensity/fBaseMaterial->GetDensity();
00315   TotNbOfAtomsPerVolume = factor*fBaseMaterial->GetTotNbOfAtomsPerVolume();
00316   TotNbOfElectPerVolume = factor*fBaseMaterial->GetTotNbOfElectPerVolume();
00317 
00318   theElementVector = const_cast<G4ElementVector*>(fBaseMaterial->GetElementVector());
00319   fMassFractionVector = const_cast<G4double*>(fBaseMaterial->GetFractionVector());
00320   fAtomsVector = const_cast<G4int*>(fBaseMaterial->GetAtomsVector());
00321 
00322   const G4double* v = fBaseMaterial->GetVecNbOfAtomsPerVolume();
00323   if (VecNbOfAtomsPerVolume)  { delete [] VecNbOfAtomsPerVolume; }
00324   VecNbOfAtomsPerVolume = new G4double[fNumberOfElements];
00325   for (size_t i=0; i<fNumberOfElements; ++i) {
00326     VecNbOfAtomsPerVolume[i] = factor*v[i];
00327   }
00328   fRadlen = fBaseMaterial->GetRadlen()/factor;
00329   fNuclInterLen = fBaseMaterial->GetNuclearInterLength()/factor;
00330   if (fIonisation) { delete fIonisation; }
00331   fIonisation  = new G4IonisParamMat(this);
00332 
00333   fSandiaTable = fBaseMaterial->GetSandiaTable();
00334   fIonisation->SetMeanExcitationEnergy(fBaseMaterial->GetIonisation()->GetMeanExcitationEnergy());
00335 }
00336 
00337 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00338 
00339 // AddElement -- composition by atom count
00340 
00341 void G4Material::AddElement(G4Element* element, G4int nAtoms)
00342 {   
00343   // initialization
00344   if ( fNumberOfElements == 0 ) {
00345      fAtomsVector        = new G4int   [fArrayLength];
00346      fMassFractionVector = new G4double[fArrayLength];
00347   }
00348 
00349   // filling ...
00350   if ( G4int(fNumberOfElements) < maxNbComponents ) {
00351      theElementVector->push_back(element);     
00352      fAtomsVector[fNumberOfElements] = nAtoms;
00353      fNumberOfComponents = ++fNumberOfElements;
00354      element->increaseCountUse();
00355   } else {
00356     G4cout << "G4Material::AddElement ERROR for " << fName << " nElement= " 
00357            <<  fNumberOfElements << G4endl;
00358     G4Exception ("G4Material::AddElement()", "mat031", FatalException, 
00359            "Attempt to add more than the declared number of elements.");
00360   } 
00361   // filled.
00362   if ( G4int(fNumberOfElements) == maxNbComponents ) {     
00363     // compute proportion by mass
00364     size_t i=0;
00365     G4double Amol = 0.;
00366     for (i=0; i<fNumberOfElements; ++i) {
00367       G4double w = fAtomsVector[i]*(*theElementVector)[i]->GetA(); 
00368       Amol += w;
00369       fMassFractionVector[i] = w;
00370     }
00371     for (i=0; i<fNumberOfElements; ++i) {
00372       fMassFractionVector[i] /= Amol;
00373     }
00374 
00375     fMassOfMolecule = Amol/Avogadro;
00376     ComputeDerivedQuantities();
00377   }
00378 }
00379 
00380 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00381 
00382 // AddElement -- composition by fraction of mass
00383 
00384 void G4Material::AddElement(G4Element* element, G4double fraction)
00385 {
00386   if(fraction < 0.0 || fraction > 1.0) {
00387     G4cout << "G4Material::AddElement ERROR for " << fName << " and " 
00388            << element->GetName() << "  mass fraction= " << fraction 
00389            << " is wrong " << G4endl;
00390     G4Exception ("G4Material::AddElement()", "mat032", FatalException,     
00391                  "Attempt to add element with wrong mass fraction");
00392   }
00393   // initialization
00394   if (fNumberOfComponents == 0) {
00395     fMassFractionVector = new G4double[fArrayLength];
00396     fAtomsVector        = new G4int   [fArrayLength];
00397   }
00398   // filling ...
00399   if (G4int(fNumberOfComponents) < maxNbComponents) {
00400     size_t el = 0;
00401     while ((el<fNumberOfElements)&&(element!=(*theElementVector)[el])) { ++el; }
00402     if (el<fNumberOfElements) fMassFractionVector[el] += fraction;
00403     else {
00404       theElementVector->push_back(element); 
00405       fMassFractionVector[el] = fraction;
00406       ++fNumberOfElements;
00407       element->increaseCountUse();
00408     }
00409     ++fNumberOfComponents;  
00410   } else {
00411     G4cout << "G4Material::AddElement ERROR for " << fName << " nElement= " 
00412            <<  fNumberOfElements << G4endl;
00413     G4Exception ("G4Material::AddElement()", "mat033", FatalException, 
00414            "Attempt to add more than the declared number of elements.");
00415   }    
00416 
00417   // filled.
00418   if (G4int(fNumberOfComponents) == maxNbComponents) {
00419 
00420     size_t i=0;
00421     G4double Zmol(0.), Amol(0.);
00422     // check sum of weights -- OK?
00423     G4double wtSum(0.0);
00424     for (i=0; i<fNumberOfElements; ++i) {
00425       wtSum += fMassFractionVector[i];
00426       Zmol +=  fMassFractionVector[i]*(*theElementVector)[i]->GetZ();
00427       Amol +=  fMassFractionVector[i]*(*theElementVector)[i]->GetA();
00428     }
00429     if (std::fabs(1.-wtSum) > perThousand) {
00430       G4cerr << "WARNING !! for " << fName << " sum of fractional masses "
00431              <<  wtSum << " is not 1 - results may be wrong" 
00432              << G4endl;
00433     }
00434     for (i=0; i<fNumberOfElements; ++i) {
00435       fAtomsVector[i] = 
00436         G4int(fMassFractionVector[i]*Amol/(*theElementVector)[i]->GetA()+0.5);
00437     }
00438      
00439     ComputeDerivedQuantities();
00440   }
00441 }
00442 
00443 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00444 
00445 // AddMaterial -- composition by fraction of mass
00446 
00447 void G4Material::AddMaterial(G4Material* material, G4double fraction)
00448 {
00449   if(fraction < 0.0 || fraction > 1.0) {
00450     G4cout << "G4Material::AddMaterial ERROR for " << fName << " and " 
00451            << material->GetName() << "  mass fraction= " << fraction 
00452            << " is wrong " << G4endl;
00453     G4Exception ("G4Material::AddMaterial()", "mat034", FatalException,            
00454                  "Attempt to add material with wrong mass fraction");      
00455   }
00456   // initialization
00457   if (fNumberOfComponents == 0) {
00458     fMassFractionVector = new G4double[fArrayLength];
00459     fAtomsVector        = new G4int   [fArrayLength];
00460   }
00461 
00462   size_t nelm = material->GetNumberOfElements();
00463 
00464   // arrays should be extended
00465   if(nelm > 1) {
00466     G4int nold    = fArrayLength;
00467     fArrayLength += nelm - 1;
00468     G4double* v1 = new G4double[fArrayLength];
00469     G4int* i1    = new G4int[fArrayLength];
00470     for(G4int i=0; i<nold; ++i) {
00471       v1[i] = fMassFractionVector[i];
00472       i1[i] = fAtomsVector[i];
00473     }
00474     delete [] fAtomsVector;
00475     delete [] fMassFractionVector;
00476     fMassFractionVector = v1;
00477     fAtomsVector = i1;
00478   }
00479 
00480   // filling ...
00481   if (G4int(fNumberOfComponents) < maxNbComponents) {
00482     for (size_t elm=0; elm<nelm; ++elm)
00483       {
00484         G4Element* element = (*(material->GetElementVector()))[elm];
00485         size_t el = 0;
00486         while ((el<fNumberOfElements)&&(element!=(*theElementVector)[el])) el++;
00487         if (el < fNumberOfElements) fMassFractionVector[el] += fraction
00488                                           *(material->GetFractionVector())[elm];
00489         else {
00490           theElementVector->push_back(element); 
00491           fMassFractionVector[el] = fraction
00492                                           *(material->GetFractionVector())[elm];
00493           ++fNumberOfElements;
00494           element->increaseCountUse();
00495         }
00496       } 
00497     ++fNumberOfComponents;
00499     fMatComponents[material] = fraction;
00500       
00501   } else {
00502     G4cout << "G4Material::AddMaterial ERROR for " << fName << " nElement= " 
00503            <<  fNumberOfElements << G4endl;
00504     G4Exception ("G4Material::AddMaterial()", "mat035", FatalException, 
00505            "Attempt to add more than the declared number of components.");
00506   }    
00507 
00508   // filled.
00509   if (G4int(fNumberOfComponents) == maxNbComponents) {
00510     size_t i=0;
00511     G4double Zmol(0.), Amol(0.);
00512     // check sum of weights -- OK?
00513     G4double wtSum(0.0);
00514     for (i=0; i<fNumberOfElements; ++i) {
00515       wtSum += fMassFractionVector[i];
00516       Zmol +=  fMassFractionVector[i]*(*theElementVector)[i]->GetZ();
00517       Amol +=  fMassFractionVector[i]*(*theElementVector)[i]->GetA();
00518     }
00519     if (std::fabs(1.-wtSum) > perThousand) {
00520       G4cout << "G4Material::AddMaterial WARNING !! for " << fName 
00521              << " sum of fractional masses "
00522              <<  wtSum << " is not 1 - results may be wrong" 
00523              << G4endl;
00524     }
00525     for (i=0;i<fNumberOfElements;i++) {
00526       fAtomsVector[i] = 
00527         G4int(fMassFractionVector[i]*Amol/(*theElementVector)[i]->GetA()+0.5);
00528     }
00529      
00530     ComputeDerivedQuantities();
00531   }
00532 }
00533 
00534 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00535 
00536 void G4Material::ComputeRadiationLength()
00537 {
00538   G4double radinv = 0.0 ;
00539   for (size_t i=0;i<fNumberOfElements;++i) {
00540      radinv += VecNbOfAtomsPerVolume[i]*((*theElementVector)[i]->GetfRadTsai());
00541   }
00542   fRadlen = (radinv <= 0.0 ? DBL_MAX : 1./radinv);
00543 }
00544 
00545 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00546 
00547 void G4Material::ComputeNuclearInterLength()
00548 {
00549   const G4double lambda0 = 35*g/cm2;
00550   G4double NILinv = 0.0;
00551   G4Pow* g4pow = G4Pow::GetInstance();
00552   for (size_t i=0; i<fNumberOfElements; ++i) {
00553     NILinv +=
00554       VecNbOfAtomsPerVolume[i]*g4pow->Z23(G4int((*theElementVector)[i]->GetN()+0.5)); 
00555   }
00556   NILinv *= amu/lambda0; 
00557   fNuclInterLen = (NILinv <= 0.0 ? DBL_MAX : 1./NILinv);
00558 }
00559 
00560 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00561 
00562 const G4MaterialTable* G4Material::GetMaterialTable()
00563 {
00564   return &theMaterialTable;
00565 }
00566 
00567 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00568 
00569 size_t G4Material::GetNumberOfMaterials()
00570 {
00571   return theMaterialTable.size();
00572 }
00573 
00574 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00575 
00576 G4Material* G4Material::GetMaterial(const G4String& materialName, G4bool warning)
00577 {  
00578   // search the material by its name 
00579   for (size_t J=0 ; J<theMaterialTable.size() ; ++J)
00580     {
00581       if (theMaterialTable[J]->GetName() == materialName)
00582         { return theMaterialTable[J]; }
00583     }
00584    
00585   // the material does not exist in the table
00586   if (warning) {
00587     G4cout << "G4Material::GetMaterial() WARNING: The material: "
00588            << materialName << " does not exist in the table. Return NULL pointer."
00589            << G4endl;
00590   }      
00591   return 0;          
00592 }
00593 
00594 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00595 
00596 G4Material::G4Material(const G4Material& right)
00597 {
00598   InitializePointers();
00599   *this = right;
00600 }
00601 
00602 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00603 
00604 G4double G4Material::GetZ() const
00605 { 
00606   if (fNumberOfElements > 1) {
00607      G4cout << "G4Material ERROR in GetZ. The material: " << fName << " is a mixture."
00608             << G4endl;
00609      G4Exception ("G4Material::GetZ()", "mat036", FatalException, 
00610                   "the Atomic number is not well defined." );
00611   } 
00612   return (*theElementVector)[0]->GetZ();      
00613 }
00614 
00615 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00616 
00617 G4double G4Material::GetA() const
00618 { 
00619   if (fNumberOfElements > 1) { 
00620      G4cout << "G4Material ERROR in GetA. The material: " << fName << " is a mixture."
00621             << G4endl;
00622      G4Exception ("G4Material::GetA()", "mat037", FatalException,  
00623                   "the Atomic mass is not well defined." );
00624   } 
00625   return  (*theElementVector)[0]->GetA();      
00626 }
00627 
00628 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00629 
00630 const G4Material& G4Material::operator=(const G4Material& right)
00631 {
00632   if (this != &right)
00633     {
00634       fName                    = right.fName;
00635       fChemicalFormula         = right.fChemicalFormula;
00636       fDensity                 = right.fDensity;
00637       fState                   = right.fState;
00638       fTemp                    = right.fTemp;
00639       fPressure                = right.fPressure;
00640            
00641       if(!fBaseMaterial) {
00642         if (theElementVector)       { delete    theElementVector; }
00643         if (fMassFractionVector)    { delete [] fMassFractionVector; }
00644         if (fAtomsVector)           { delete [] fAtomsVector; }
00645         if (fIonisation)            { delete    fIonisation; }
00646         if (fSandiaTable)           { delete    fSandiaTable; }
00647       }
00648 
00649       if (VecNbOfAtomsPerVolume)  { delete [] VecNbOfAtomsPerVolume; }
00650 
00651       maxNbComponents          = right.maxNbComponents;
00652       fNumberOfComponents      = right.fNumberOfComponents;
00653       fNumberOfElements        = right.fNumberOfElements;     
00654       fImplicitElement         = right.fImplicitElement;
00655 
00656       fMaterialPropertiesTable = right.fMaterialPropertiesTable;
00657       fBaseMaterial = right.fBaseMaterial;
00658       fMassOfMolecule= right.fMassOfMolecule;
00659       fMatComponents= right.fMatComponents;
00660 
00661       if(fBaseMaterial) {
00662         CopyPointersOfBaseMaterial();
00663 
00664       } else {                  
00665         theElementVector    = new G4ElementVector(fNumberOfElements,0);
00666         fMassFractionVector = new G4double[fNumberOfElements];     
00667         fAtomsVector        = new G4int[fNumberOfElements];
00668         for (size_t i=0; i<fNumberOfElements; ++i) {
00669           (*theElementVector)[i] = (*right.theElementVector)[i];
00670           fMassFractionVector[i] = right.fMassFractionVector[i];
00671           fAtomsVector[i]        = right.fAtomsVector[i];
00672         }
00673         ComputeDerivedQuantities();
00674       }
00675            
00676     } 
00677   return *this;
00678 }
00679 
00680 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00681 
00682 G4int G4Material::operator==(const G4Material& right) const
00683 {
00684   return (this == (G4Material *) &right);
00685 }
00686 
00687 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00688 
00689 G4int G4Material::operator!=(const G4Material& right) const
00690 {
00691   return (this != (G4Material *) &right);
00692 }
00693 
00694 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00695 
00696 
00697 std::ostream& operator<<(std::ostream& flux, G4Material* material)
00698 {
00699   std::ios::fmtflags mode = flux.flags();
00700   flux.setf(std::ios::fixed,std::ios::floatfield);
00701   G4long prec = flux.precision(3);
00702   
00703   flux
00704     << " Material: "         << std::setw(8) <<  material->fName
00705     << " " << material->fChemicalFormula << " "
00706     << "  density: "         << std::setw(6) << std::setprecision(3)  
00707     << G4BestUnit(material->fDensity,"Volumic Mass") 
00708     << "  RadL: "            << std::setw(7)  << std::setprecision(3)  
00709     << G4BestUnit(material->fRadlen,"Length")
00710     << "  Nucl.Int.Length: " << std::setw(7)  << std::setprecision(3)  
00711     << G4BestUnit(material->fNuclInterLen,"Length")    
00712     << "  Imean: "           << std::setw(7)  << std::setprecision(3)  
00713     << G4BestUnit(material->GetIonisation()->GetMeanExcitationEnergy(),"Energy");
00714     
00715   if(material->fState == kStateGas) {
00716     flux
00717       << "  temperature: " << std::setw(6) << std::setprecision(2)  
00718       << (material->fTemp)/kelvin << " K"
00719       << "  pressure: "    << std::setw(6) << std::setprecision(2)   
00720       << (material->fPressure)/atmosphere << " atm";
00721   }
00722   for (size_t i=0; i<material->fNumberOfElements; i++) {
00723     flux 
00724       << "\n   ---> " << (*(material->theElementVector))[i] 
00725       << "\n          ElmMassFraction: " 
00726       << std::setw(6)<< std::setprecision(2) 
00727       << (material->fMassFractionVector[i])/perCent << " %" 
00728       << "  ElmAbundance "     << std::setw(6)<< std::setprecision(2) 
00729       << 100*(material->VecNbOfAtomsPerVolume[i])/(material->TotNbOfAtomsPerVolume)
00730       << " % \n";
00731   }
00732   flux.precision(prec);    
00733   flux.setf(mode,std::ios::floatfield);
00734             
00735   return flux;
00736 }
00737 
00738 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00739 
00740 std::ostream& operator<<(std::ostream& flux, G4Material& material)
00741 {
00742   flux << &material;        
00743   return flux;
00744 }
00745 
00746 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
00747      
00748 std::ostream& operator<<(std::ostream& flux, G4MaterialTable MaterialTable)
00749 {
00750   //Dump info for all known materials
00751   flux << "\n***** Table : Nb of materials = " << MaterialTable.size() 
00752        << " *****\n" << G4endl;
00753         
00754   for (size_t i=0; i<MaterialTable.size(); ++i) { 
00755     flux << MaterialTable[i] << G4endl << G4endl; 
00756   }
00757 
00758   return flux;
00759 }      
00760 
00761 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

Generated on Mon May 27 17:48:50 2013 for Geant4 by  doxygen 1.4.7