<!-- ******************************************************** -->
<!--                                                          -->
<!--  [History]                                               -->
<!--    Converted to DocBook: Katsuya Amako, Aug-2006         -->
<!--    Changed by: Katsuya Amako, 14-Jul-1998                -->
<!--    Proof read by: Joe Chuma,  29-Jun-1999                -->
<!--                                                          -->
<!-- ******************************************************** -->


<!-- ******************* Section (Level#1) ****************** -->
<sect1 id="sect.Mate">
<title>
Material
</title>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Mate.GenCons">
<title>
General considerations
</title>

<para>
In nature, materials (chemical compounds, mixtures) are made of
elements, and elements are made of isotopes. Geant4 has three main
classes designed to reflect this organization. Each of these
classes has a table, which is a static data member, used to keep
track of the instances of the respective classes created.

<variablelist><title></title>
<varlistentry>
  <term>
    <emphasis>G4Isotope</emphasis>
  </term>
  <listitem><para>
    This class describes the properties of atoms: atomic number,
    number of nucleons, mass per mole, etc.
  </para></listitem>
</varlistentry>
<varlistentry>
  <term>
    <emphasis>G4Element</emphasis>
  </term>
  <listitem><para>
    This class describes the properties of elements: effective
    atomic number, effective number of nucleons, effective mass per
    mole, number of isotopes, shell energy, and quantities like cross
    section per atom, etc.
  </para></listitem>
</varlistentry>
<varlistentry>
  <term>
    <emphasis>G4Material</emphasis>
  </term>
  <listitem><para>
    This class describes the macroscopic properties of matter:
    density, state, temperature, pressure, and macroscopic quantities
    like radiation length, mean free path, dE/dx, etc.
  </para></listitem>
</varlistentry>
</variablelist>
</para>

<para>
Only the <emphasis>G4Material</emphasis> class is visible to the rest of the
toolkit and used by the tracking, the geometry and the physics. It
contains all the information relevant to its constituent elements
and isotopes, while at the same time hiding their implementation
details.
</para>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Mate.Intro">
<title>
Introduction to the Classes
</title>


<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.Mate.Intro.Iso">
<title>
G4Isotope
</title>

<para>
A <emphasis>G4Isotope</emphasis> object has a name, atomic number, number of
nucleons, mass per mole, and an index in the table. The constructor
automatically stores "this" isotope in the isotopes table, which
will assign it an index number.
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.Mate.Intro.Ele">
<title>
G4Element
</title>

<para>
A <emphasis>G4Element</emphasis> object has a name, symbol, effective atomic
number, effective number of nucleons, effective mass of a mole, an
index in the elements table, the number of isotopes, a vector of
pointers to such isotopes, and a vector of relative abundances
referring to such isotopes (where relative abundance means the
number of atoms per volume). In addition, the class has methods to
add, one by one, the isotopes which are to form the element.
</para>

<para>
A <emphasis>G4Element</emphasis> object can be constructed by directly
providing the effective atomic number, effective number of
nucleons, and effective mass of a mole, if the user explicitly
wants to do so. Alternatively, a <emphasis>G4Element</emphasis> object can be
constructed by declaring the number of isotopes of which it will be
composed. The constructor will "new" a vector of pointers to
<emphasis>G4Isotopes</emphasis> and a vector of doubles to store their relative
abundances. Finally, the method to add an isotope must be invoked
for each of the desired (pre-existing) isotope objects, providing
their addresses and relative abundances. At the last isotope entry,
the system will automatically compute the effective atomic number,
effective number of nucleons and effective mass of a mole, and will
store "this" element in the elements table.
</para>

<para>
A few quantities, with physical meaning or not, which are
constant in a given element, are computed and stored here as
"derived data members".
</para>

<para>
Using the internal Geant4 database, a <emphasis>G4Element</emphasis> can be accessed
by atomic number or by atomic symbol ("Al", "Fe", "Pb"...). In that
case <emphasis>G4Element</emphasis> will be found from the list of existing elements or
will be constructed using data from the Geant4 database, which is
derived from the
<ulink url="http://physics.nist.gov/PhysRefData/Compositions/index.html">NIST database
of elements and isotope compositions</ulink>.
Thus, the natural isotope composition can be built by default.
The same element 
can be created as using the NIST database with the 
natural composition of isotopes
and from scratch in user code with user defined isotope composition.
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.Mate.Intro.Mate">
<title>
G4Material
</title>

<para>
A <emphasis>G4Material</emphasis> object has a name, density, physical state,
temperature and pressure (by default the standard conditions), the
number of elements and a vector of pointers to such elements, a
vector of the fraction of mass for each element, a vector of the
atoms (or molecules) numbers of each element, and an index in the
materials table. In addition, the class has methods to add, one by
one, the elements which will comprise the material.
</para>

<para>
A <emphasis>G4Material</emphasis> object can be constructed by directly
providing the resulting effective numbers, if the user explicitly
wants to do so (an underlying element will be created with these
numbers). Alternatively, a <emphasis>G4Material</emphasis> object can be
constructed by declaring the number of elements of which it will be
composed. The constructor will "new" a vector of pointers to
<emphasis>G4Element</emphasis> and a vector of doubles to store their fraction of
mass. Finally, the method to add an element must be invoked for
each of the desired (pre-existing) element objects, providing their
addresses and mass fractions. At the last element entry, the system
will automatically compute the vector of the number of atoms of
each element per volume, the total number of electrons per volume,
and will store "this" material in the materials table. In the same
way, a material can be constructed as a mixture of other materials
and elements.
</para>

<para>
It should be noted that if the user provides the number of atoms
(or molecules) for each element comprising the chemical compound,
the system automatically computes the mass fraction. A few
quantities, with physical meaning or not, which are constant in a
given material, are computed and stored here as "derived data
members".
</para>

<para>
Some materials are included in the internal Geant4 database,
which were derived from the
<ulink url="http://physics.nist.gov/PhysRefData/Star/Text/method.html">NIST database
of material properties</ulink>.
Additionally a number of materials friquently used in HEP is
included in the database. Materials are interrogated or constructed
by their <emphasis>names</emphasis> (<xref linkend="sect.G4MatrDb" />).  
There are UI commands for the material category, which provide 
an interactive access to the database. If material is created 
using the NIST database by it will
consist by default of elements with the natural composition of isotopes. 
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.Mate.Intro.Fin">
<title>
Final Considerations
</title>

<para>
The classes will automatically decide
if the total of the mass fractions is correct, and perform the
necessary checks. The main reason why a fixed index is kept as a
data member is that many cross section and energy tables will be
built in the physics processes "by rows of materials (or elements,
or even isotopes)". The tracking gives the physics process the
address of a material object (the material of the current volume).
If the material has an index according to which the cross section
table has been built, then direct access is available when a number
in such a table must be accessed. We get directly to the correct
row, and the energy of the particle will tell us the column.
Without such an index, every access to the cross section or energy
tables would imply a search to get to the correct material's row.
More details will be given in the section on processes.
</para>

<para>
Isotopes, elements and materials must be instantiated dynamically
in the user application; they are automatically registered in
internal stores and the system takes care to free the memory
allocated at the end of the job.
</para>

</sect3>
</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Mate.Recep">
<title>
Recipes for Building Elements and Materials
</title>

<para>
<xref linkend="programlist_Mate_1" /> illustrates the different ways to define
materials.
</para>

<example id="programlist_Mate_1">
<title>
A program which illustrates the different ways to define materials.
</title>

<programlisting>
#include "G4Isotope.hh"
#include "G4Element.hh"
#include "G4Material.hh"
#include "G4UnitsTable.hh"

int main() {
G4String name, symbol;             // a=mass of a mole;
G4double a, z, density;            // z=mean number of protons;  
G4int iz, n;                       // iz=nb of protons  in an isotope; 
                                   // n=nb of nucleons in an isotope;
G4int ncomponents, natoms;
G4double abundance, fractionmass;
G4double temperature, pressure;

G4UnitDefinition::BuildUnitsTable();

// define Elements
a = 1.01*g/mole;
G4Element* elH  = new G4Element(name="Hydrogen",symbol="H" , z= 1., a);

a = 12.01*g/mole;
G4Element* elC  = new G4Element(name="Carbon"  ,symbol="C" , z= 6., a);

a = 14.01*g/mole;
G4Element* elN  = new G4Element(name="Nitrogen",symbol="N" , z= 7., a);

a = 16.00*g/mole;
G4Element* elO  = new G4Element(name="Oxygen"  ,symbol="O" , z= 8., a);

a = 28.09*g/mole;
G4Element* elSi = new G4Element(name="Silicon", symbol="Si", z=14., a);

a = 55.85*g/mole;
G4Element* elFe = new G4Element(name="Iron"    ,symbol="Fe", z=26., a);

a = 183.84*g/mole;
G4Element* elW = new G4Element(name="Tungsten" ,symbol="W",  z=74., a);

a = 207.20*g/mole;
G4Element* elPb = new G4Element(name="Lead"    ,symbol="Pb", z=82., a);

// define an Element from isotopes, by relative abundance 
G4Isotope* U5 = new G4Isotope(name="U235", iz=92, n=235, a=235.01*g/mole);
G4Isotope* U8 = new G4Isotope(name="U238", iz=92, n=238, a=238.03*g/mole);

G4Element* elU  = new G4Element(name="enriched Uranium", symbol="U", ncomponents=2);
elU-&gt;AddIsotope(U5, abundance= 90.*perCent);
elU-&gt;AddIsotope(U8, abundance= 10.*perCent);

cout &lt;&lt; *(G4Isotope::GetIsotopeTable()) &lt;&lt; endl;
cout &lt;&lt; *(G4Element::GetElementTable()) &lt;&lt; endl;
</programlisting>
</example>
<informalexample>
<programlisting>
// define simple materials
density = 2.700*g/cm3;
a = 26.98*g/mole;
G4Material* Al = new G4Material(name="Aluminum", z=13., a, density);

density = 1.390*g/cm3;
a = 39.95*g/mole;
vG4Material* lAr = new G4Material(name="liquidArgon", z=18., a, density);

density = 8.960*g/cm3;
a = 63.55*g/mole;
G4Material* Cu = new G4Material(name="Copper"   , z=29., a, density);

// define a material from elements.   case 1: chemical molecule
density = 1.000*g/cm3;
G4Material* H2O = new G4Material(name="Water", density, ncomponents=2);
H2O-&gt;AddElement(elH, natoms=2);
H2O-&gt;AddElement(elO, natoms=1);

density = 1.032*g/cm3;
G4Material* Sci = new G4Material(name="Scintillator", density, ncomponents=2);
Sci-&gt;AddElement(elC, natoms=9);
Sci-&gt;AddElement(elH, natoms=10);

density = 2.200*g/cm3;
G4Material* SiO2 = new G4Material(name="quartz", density, ncomponents=2);
SiO2-&gt;AddElement(elSi, natoms=1);
SiO2-&gt;AddElement(elO , natoms=2);

density = 8.280*g/cm3;
G4Material* PbWO4= new G4Material(name="PbWO4", density, ncomponents=3);
PbWO4-&gt;AddElement(elO , natoms=4);
PbWO4-&gt;AddElement(elW , natoms=1);
PbWO4-&gt;AddElement(elPb, natoms=1);

// define a material from elements.   case 2: mixture by fractional mass
density = 1.290*mg/cm3;
G4Material* Air = new G4Material(name="Air  "  , density, ncomponents=2);
Air-&gt;AddElement(elN, fractionmass=0.7);
Air-&gt;AddElement(elO, fractionmass=0.3);

// define a material from elements and/or others materials (mixture of mixtures)
density = 0.200*g/cm3;
G4Material* Aerog = new G4Material(name="Aerogel", density, ncomponents=3);
Aerog-&gt;AddMaterial(SiO2, fractionmass=62.5*perCent);
Aerog-&gt;AddMaterial(H2O , fractionmass=37.4*perCent);
Aerog-&gt;AddElement (elC , fractionmass= 0.1*perCent);
</programlisting>
</informalexample>
<informalexample>
<programlisting>
// examples of gas in non STP conditions
density     = 27.*mg/cm3;
pressure    = 50.*atmosphere;
temperature = 325.*kelvin;
G4Material* CO2 = new G4Material(name="Carbonic gas", density, ncomponents=2,
                                     kStateGas,temperature,pressure);
CO2-&gt;AddElement(elC, natoms=1);
CO2-&gt;AddElement(elO, natoms=2);
 
density     = 0.3*mg/cm3;
pressure    = 2.*atmosphere;
temperature = 500.*kelvin;
G4Material* steam = new G4Material(name="Water steam ", density, ncomponents=1,
                                      kStateGas,temperature,pressure);
steam-&gt;AddMaterial(H2O, fractionmass=1.);

// What about vacuum ?  Vacuum is an ordinary gas with very low density
density     = universe_mean_density;                //from PhysicalConstants.h
pressure    = 1.e-19*pascal;
temperature = 0.1*kelvin;
new G4Material(name="Galactic", z=1., a=1.01*g/mole, density,
                   kStateGas,temperature,pressure);

density     = 1.e-5*g/cm3;
pressure    = 2.e-2*bar;
temperature = STP_Temperature;                      //from PhysicalConstants.h
G4Material* beam = new G4Material(name="Beam ", density, ncomponents=1,
                                      kStateGas,temperature,pressure);
beam-&gt;AddMaterial(Air, fractionmass=1.);

// print the table of materials
G4cout &lt;&lt; *(G4Material::GetMaterialTable()) &lt;&lt; endl;

return EXIT_SUCCESS;
}
</programlisting>
</informalexample>
<para>
As can be seen in the later examples, a material has a state:
solid (the default), liquid, or gas. The constructor checks the
density and automatically sets the state to gas below a given
threshold (10 mg/cm3).
</para>

<para>
In the case of a gas, one may specify the temperature and
pressure. The defaults are STP conditions defined in
<literal>PhysicalConstants.hh</literal>.
</para>

<para>
An element must have the number of nucleons &gt;= number of
protons &gt;= 1.
</para>

<para>
A material must have non-zero values of density, temperature and
pressure.
</para>

<para>
Materials can also be defined using the internal Geant4
database. <xref linkend="programlist_Mate_2" /> illustrates 
how to do this for the same materials used in 
<xref linkend="programlist_Mate_1" />. 
There are also UI commands which allow the database to be accessed. 
<emphasis>The list of currently avalable material names</emphasis>
(<xref linkend="sect.G4MatrDb" />) is extended permanetly.
</para>

<example id="programlist_Mate_2">
<title>
A program which shows how to define materials from the internal database.
</title>

<programlisting>
#include "globals.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"

int main() {
  G4NistManager* man = G4NistManager::Instance();
  man-&gt;SetVerbose(1);

  // define elements
  G4Element* C  = man-&gt;FindOrBuildElement("C");
  G4Element* Pb = man-&gt;FindOrBuildMaterial("Pb");

  // define pure NIST materials
  G4Material* Al = man-&gt;FindOrBuildMaterial("G4_Al");
  G4Material* Cu = man-&gt;FindOrBuildMaterial("G4_Cu");

  // define NIST materials
  G4Material* H2O  = man-&gt;FindOrBuildMaterial("G4_WATER");
  G4Material* Sci  = man-&gt;FindOrBuildMaterial("G4_PLASTIC_SC_VINYLTOLUENE");
  G4Material* SiO2 = man-&gt;FindOrBuildMaterial("G4_SILICON_DIOXIDE");
  G4Material* Air  = man-&gt;FindOrBuildMaterial("G4_AIR");

  // HEP materials
  G4Material* PbWO4  = man-&gt;FindOrBuildMaterial("G4_PbWO4");
  G4Material* lAr    = man-&gt;FindOrBuildMaterial("G4_lAr");
  G4Material* vac    = man-&gt;FindOrBuildMaterial("G4_Galactic");

  // define gas material at non STP conditions (T = 120K, P=0.5atm)
  G4Material* coldAr = man-&gt;ConstructNewGasdMaterial("ColdAr","G4_Ar",120.*kelvin,0.5*atmosphere);

  // print the table of materials
  G4cout &lt;&lt; *(G4Material::GetMaterialTable()) &lt;&lt; endl;

  return EXIT_SUCCESS;
}
</programlisting>
</example>

</sect2>


<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.Mate.Tables">
<title>
The Tables
</title>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.Mate.Tables.PrintCons">
<title>
Print a constituent
</title>

<para>
The following shows how to print a constituent:

<informalexample>
<programlisting>
  G4cout &lt;&lt; elU &lt;&lt; endl;
  G4cout &lt;&lt; Air &lt;&lt; endl;
</programlisting>
</informalexample>
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.Mate.Tables.PrintTab">
<title>
Print the table of materials
</title>

<para>
The following shows how to print the table of materials:

<informalexample>
<programlisting>
  G4cout &lt;&lt; *(G4Material::GetMaterialTable()) &lt;&lt; endl;
</programlisting>
</informalexample>
</para>


</sect3>
</sect2>
</sect1>
