Import Geant4 4.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 16:39:52 +02:00
parent 921d3b1cda
commit 330b82b769
4524 changed files with 178689 additions and 43575 deletions
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4PhotoElectricEffect.cc,v 1.22 2001/10/01 15:00:29 maire Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4PhotoElectricEffect.cc,v 1.27 2002/05/02 11:37:22 maire Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -48,9 +48,14 @@
// 06-08-01, new methods Store/Retrieve PhysicsTable (mma)
// 06-08-01, BuildThePhysicsTable() called from constructor (mma)
// 17-09-01, migration of Materials to pure STL (mma)
// 20-09-01, DoIt: fminimalEnergy = 1*eV (mma)
// 20-09-01, DoIt: fminimalEnergy of generated electron = 1*eV (mma)
// 01-10-01, come back to BuildPhysicsTable(const G4ParticleDefinition&)
//
// 10-01-02, moved few function from icc to cc
// 17-04-02, Keep only Sandia crossSections. Remove BuildPhysicsTables.
// Simplify public interface (mma)
// 29-04-02, Generate theta angle of the photoelectron from Sauter-Gavrila
// distribution (mma)
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -62,180 +67,56 @@
// constructor
G4PhotoElectricEffect::G4PhotoElectricEffect(const G4String& processName)
: G4VDiscreteProcess (processName), // initialization
theCrossSectionTable(NULL),
theMeanFreePathTable(NULL),
LowestEnergyLimit (50*keV),
HighestEnergyLimit(50*MeV),
NumbBinTable(100),
: G4VDiscreteProcess (processName),
fminimalEnergy(1*eV)
{}
{ PrintInfoDefinition();}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// destructor
G4PhotoElectricEffect::~G4PhotoElectricEffect()
{
if (theCrossSectionTable) {
theCrossSectionTable->clearAndDestroy();
delete theCrossSectionTable;
}
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
}
{ }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PhotoElectricEffect::SetPhysicsTableBining(
G4double lowE, G4double highE, G4int nBins)
{
LowestEnergyLimit = lowE; HighestEnergyLimit = highE; NumbBinTable = nBins;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PhotoElectricEffect::BuildPhysicsTable(const G4ParticleDefinition&)
// Build cross section per atom and mean free path tables
{
G4double LowEdgeEnergy, Value;
G4PhysicsLogVector* ptrVector;
// Build cross section per atom tables for the Photo Electric Effect
if (theCrossSectionTable) {
theCrossSectionTable->clearAndDestroy(); delete theCrossSectionTable;}
theCrossSectionTable = new G4PhysicsTable( G4Element::GetNumberOfElements());
const G4ElementTable* theElementTable = G4Element::GetElementTable();
G4double AtomicNumber;
size_t J;
for ( J=0 ; J < G4Element::GetNumberOfElements(); J++ )
{
//create physics vector then fill it ....
ptrVector = new G4PhysicsLogVector(LowestEnergyLimit,HighestEnergyLimit,
NumbBinTable ) ;
AtomicNumber = (*theElementTable)[J]->GetZ();
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
{
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
Value = ComputeCrossSectionPerAtom( LowEdgeEnergy, AtomicNumber);
ptrVector->PutValue( i , Value ) ;
}
theCrossSectionTable->insertAt( J , ptrVector ) ;
}
// Build mean free path table for the Photo Electric Effect
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable;}
theMeanFreePathTable= new G4PhysicsTable(G4Material::GetNumberOfMaterials());
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
G4Material* material;
for ( J=0 ; J < G4Material::GetNumberOfMaterials(); J++ )
{
//create physics vector then fill it ....
ptrVector = new G4PhysicsLogVector(LowestEnergyLimit,HighestEnergyLimit,
NumbBinTable );
material = (*theMaterialTable)[J];
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
{
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
Value = ComputeMeanFreePath( LowEdgeEnergy, material);
ptrVector->PutValue( i , Value ) ;
}
theMeanFreePathTable->insertAt( J , ptrVector ) ;
}
PrintInfoDefinition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PhotoElectricEffect::ComputeCrossSectionPerAtom(
G4double PhotonEnergy,
G4double AtomicNumber)
// Calculates the cross section per atom in GEANT4 internal units.
// A parametrized formula from L. Urban is used to estimate the
// total cross section.
// It gives a good description of the elements : 5 < Atomic Number < 100 and
// from 10 keV to 50 MeV.
{
G4double CrossSection = 0.0 ;
if ( AtomicNumber < 1. ) return CrossSection;
if ( PhotonEnergy > 50.*MeV ) return CrossSection;
static const G4double
p1K =-8.8893e+2*nanobarn, p2K = 2.4394 *nanobarn, p3K = 2.8835e+2*nanobarn,
p4K = 1.2133e+1*nanobarn, p5K =-3.1104e+2*nanobarn, p6K =-1.7284e-1*nanobarn,
p7K = 1.4400e+1*nanobarn, p8K = 6.8357e+1*nanobarn, p9K = 7.3945e-4*nanobarn,
p10K=-4.8149e-2*nanobarn, p11K= 5.5823e-1*nanobarn, p12K=-1.0089e-1*nanobarn;
static const G4double
p1L1=-1.0927e+3*nanobarn, p2L1=-9.7897e-1*nanobarn, p3L1= 1.2854e+2*nanobarn;
static const G4double
p1L2=-4.5803e+3*nanobarn, p2L2= 1.6858e-3*nanobarn, p3L2= 1.2013e+2*nanobarn;
static const G4double
p1M = 1.6924e+1*nanobarn;
const G4double pwZ = 3.845 , pwE = 2.975 ;
G4double Z = AtomicNumber, Z2 = Z*Z, Z3 = Z*Z*Z;
G4double Em = PhotonEnergy/electron_mass_c2, Em2 = Em*Em, Em3 = Em*Em*Em;
CrossSection = pow(Z,pwZ)/pow(Em,pwE);
if (PhotonEnergy > ComputeKBindingEnergy(Z) ) {
CrossSection *= (p1K/Z + p2K/Em + p3K + p4K*Z + p5K*Em
+ p6K*Z2 + p7K *Z *Em + p8K *Em2
+ p9K*Z3 + p10K*Z2*Em + p11K*Z*Em2 + p12K*Em3);
if (CrossSection < 0.) CrossSection = 0. ;
}
else if (PhotonEnergy > ComputeL1BindingEnergy(Z) ) {
CrossSection *= (p1L1/Z + p2L1/Em + p3L1 );
if (CrossSection < 0.) CrossSection = 0. ;
}
else if (PhotonEnergy > ComputeL2BindingEnergy(Z) ) {
CrossSection *= (p1L2/Z + p2L2/Em + p3L2 );
if (CrossSection < 0.) CrossSection = 0. ;
}
else CrossSection *= p1M;
return CrossSection;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PhotoElectricEffect::ComputeSandiaCrossSection(G4double PhotonEnergy,
G4double G4PhotoElectricEffect::ComputeCrossSectionPerAtom(G4double GammaEnergy,
G4double AtomicNumber)
{
G4double energy2 = PhotonEnergy*PhotonEnergy, energy3 = PhotonEnergy*energy2,
energy4 = energy2*energy2;
G4double* SandiaCof
= G4SandiaTable::GetSandiaCofPerAtom((int)AtomicNumber,PhotonEnergy);
// returns the photoElectric cross Section in GEANT4 internal units
{
G4double* SandiaCof
= G4SandiaTable::GetSandiaCofPerAtom((int)AtomicNumber,GammaEnergy);
G4double energy2 = GammaEnergy*GammaEnergy, energy3 = GammaEnergy*energy2,
energy4 = energy2*energy2;
return SandiaCof[0]/PhotonEnergy + SandiaCof[1]/energy2 +
SandiaCof[2]/energy3 + SandiaCof[3]/energy4;
return SandiaCof[0]/GammaEnergy + SandiaCof[1]/energy2 +
SandiaCof[2]/energy3 + SandiaCof[3]/energy4;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4PhotoElectricEffect::ComputeMeanFreePath(G4double GammaEnergy,
G4Material* aMaterial)
// returns the gamma mean free path in GEANT4 internal units
{
G4double* SandiaCof = aMaterial->GetSandiaTable()
->GetSandiaCofForMaterial(GammaEnergy);
G4double energy2 = GammaEnergy*GammaEnergy, energy3 = GammaEnergy*energy2,
energy4 = energy2*energy2;
G4double SIGMA = SandiaCof[0]/GammaEnergy + SandiaCof[1]/energy2 +
SandiaCof[2]/energy3 + SandiaCof[3]/energy4;
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VParticleChange* G4PhotoElectricEffect::PostStepDoIt(const G4Track& aTrack,
@@ -271,11 +152,19 @@ G4VParticleChange* G4PhotoElectricEffect::PostStepDoIt(const G4Track& aTrack,
if (ElecKineEnergy > fminimalEnergy)
{
// the electron is created in the direction of the incident photon ...
// direction of the photo electron
//
G4double cosTeta = ElecThetaDistribution(ElecKineEnergy);
G4double sinTeta = sqrt(1.-cosTeta*cosTeta);
G4double Phi = twopi * G4UniformRand();
G4double dirx = sinTeta*cos(Phi),diry = sinTeta*sin(Phi),dirz = cosTeta;
G4ThreeVector ElecDirection(dirx,diry,dirz);
ElecDirection.rotateUz(PhotonDirection);
//
G4DynamicParticle* aElectron = new G4DynamicParticle (
G4Electron::Electron(),PhotonDirection, ElecKineEnergy);
G4Electron::Electron(),ElecDirection, ElecKineEnergy);
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary( aElectron );
aParticleChange.AddSecondary(aElectron);
}
else
{
@@ -306,6 +195,7 @@ G4Element* G4PhotoElectricEffect::SelectRandomAtom(
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
if (NumberOfElements == 1) return (*theElementVector)[0];
G4double GammaEnergy = aDynamicPhoton->GetKineticEnergy();
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
G4double PartialSumSigma = 0. ;
@@ -313,8 +203,8 @@ G4Element* G4PhotoElectricEffect::SelectRandomAtom(
for ( G4int elm=0 ; elm < NumberOfElements ; elm++ )
{PartialSumSigma += NbOfAtomsPerVolume[elm] *
GetCrossSectionPerAtom(aDynamicPhoton,
(*theElementVector)[elm]);
ComputeCrossSectionPerAtom(GammaEnergy,
(*theElementVector)[elm]->GetZ());
if (rval<=PartialSumSigma*MeanFreePath) return ((*theElementVector)[elm]);
}
return ((*theElementVector)[NumberOfElements-1]);
@@ -322,90 +212,37 @@ G4Element* G4PhotoElectricEffect::SelectRandomAtom(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool G4PhotoElectricEffect::StorePhysicsTable(G4ParticleDefinition* particle,
const G4String& directory,
G4bool ascii)
G4double G4PhotoElectricEffect::ElecThetaDistribution(G4double kineEnergy)
{
G4String filename;
// store cross section table
filename = GetPhysicsTableFileName(particle,directory,"CrossSection",ascii);
if ( !theCrossSectionTable->StorePhysicsTable(filename, ascii) ){
G4cout << " FAIL theCrossSectionTable->StorePhysicsTable in " << filename
<< G4endl;
return false;
}
// store mean free path table
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
if ( !theMeanFreePathTable->StorePhysicsTable(filename, ascii) ){
G4cout << " FAIL theMeanFreePathTable->StorePhysicsTable in " << filename
<< G4endl;
return false;
}
// Compute Theta distribution of the emitted electron, with respect to the
// incident Gamma.
// The Sauter-Gavrila distribution for the K-shell is used.
//
G4double gamma = 1. + kineEnergy/electron_mass_c2;
G4double beta = sqrt(gamma*gamma-1.)/gamma;
G4double b = 0.5*gamma*(gamma-1.)*(gamma-2);
G4double rndm,costeta,term,greject,grejsup;
if (gamma < 2.) grejsup = gamma*gamma*(1.+b-beta*b);
else grejsup = gamma*gamma*(1.+b+beta*b);
G4cout << GetProcessName() << " for " << particle->GetParticleName()
<< ": Success to store the PhysicsTables in "
<< directory << G4endl;
return true;
}
do { rndm = 1.-2*G4UniformRand();
costeta = (rndm+beta)/(rndm*beta+1.);
term = 1.-beta*costeta;
greject = (1.-costeta*costeta)*(1.+b*term)/(term*term);
} while(greject < G4UniformRand()*grejsup);
return costeta;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4bool G4PhotoElectricEffect::RetrievePhysicsTable(
G4ParticleDefinition* particle,
const G4String& directory,
G4bool ascii)
{
// delete theCrossSectionTable and theMeanFreePathTable
if (theCrossSectionTable != 0) {
theCrossSectionTable->clearAndDestroy();
delete theCrossSectionTable;
}
if (theMeanFreePathTable != 0) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
G4String filename;
// retreive cross section table
filename = GetPhysicsTableFileName(particle,directory,"CrossSection",ascii);
theCrossSectionTable = new G4PhysicsTable(G4Element::GetNumberOfElements());
if ( !theCrossSectionTable->RetrievePhysicsTable(filename, ascii) ){
G4cout << " FAIL theCrossSectionTable->RetrievePhysicsTable in " << filename
<< G4endl;
return false;
}
// retreive mean free path table
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
theMeanFreePathTable = new G4PhysicsTable(G4Material::GetNumberOfMaterials());
if ( !theMeanFreePathTable->RetrievePhysicsTable(filename, ascii) ){
G4cout << " FAIL theMeanFreePathTable->RetrievePhysicsTable in " << filename
<< G4endl;
return false;
}
G4cout << GetProcessName() << " for " << particle->GetParticleName()
<< ": Success to retrieve the PhysicsTables from "
<< directory << G4endl;
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4PhotoElectricEffect::PrintInfoDefinition()
{
G4String comments = "Total cross sections from a parametrisation. ";
comments += "Good description from 10 KeV to 50 MeV for all Z";
comments += "\n Sandia crossSection below 50 KeV";
G4String comments = "Total cross sections from Sandia parametrisation. ";
G4cout << G4endl << GetProcessName() << ": " << comments
<< "\n PhysicsTables from "
<< G4BestUnit(LowestEnergyLimit, "Energy")
<< " to " << G4BestUnit(HighestEnergyLimit,"Energy")
<< " in " << NumbBinTable << " bins. \n";
G4cout << G4endl << GetProcessName() << ": " << comments << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......