Import Geant4 7.0.0 source tree
This commit is contained in:
@@ -20,9 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ComptonScattering.cc,v 1.18 2004/03/10 16:48:45 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-01 $
|
||||
// $Id: G4ComptonScattering.cc,v 1.23 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//
|
||||
//------------ G4ComptonScattering physics process -----------------------------
|
||||
@@ -48,20 +47,24 @@
|
||||
// 20-09-01, DoIt: fminimalEnergy = 1*eV (mma)
|
||||
// 01-10-01, come back to BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// 17-04-02, LowestEnergyLimit = 1*keV
|
||||
// 26-05-04, cross section parametrization improved for low energy :
|
||||
// Egamma <~ 15 keV (Laszlo)
|
||||
// 08-11-04, Remove Store/Retrieve tables (V.Ivantchenko)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "G4ComptonScattering.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4PhysicsTableHelper.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// constructor
|
||||
|
||||
G4ComptonScattering::G4ComptonScattering(const G4String& processName,
|
||||
using namespace std;
|
||||
|
||||
G4ComptonScattering::G4ComptonScattering(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type),
|
||||
theCrossSectionTable(NULL),
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestEnergyLimit ( 1*keV),
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestEnergyLimit ( 1*keV),
|
||||
HighestEnergyLimit(100*GeV),
|
||||
NumbBinTable(80),
|
||||
fminimalEnergy(1*eV)
|
||||
@@ -86,6 +89,13 @@ G4ComptonScattering::~G4ComptonScattering()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4ComptonScattering::IsApplicable( const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4ComptonScattering::SetPhysicsTableBining(
|
||||
G4double lowE, G4double highE, G4int nBins)
|
||||
{
|
||||
@@ -110,17 +120,17 @@ void G4ComptonScattering::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
G4double AtomicNumber;
|
||||
size_t J;
|
||||
|
||||
for ( J=0 ; J < G4Element::GetNumberOfElements(); 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++ )
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
|
||||
Value = ComputeCrossSectionPerAtom(LowEdgeEnergy, AtomicNumber);
|
||||
Value = ComputeCrossSectionPerAtom(LowEdgeEnergy, AtomicNumber);
|
||||
ptrVector->PutValue(i,Value);
|
||||
}
|
||||
|
||||
@@ -143,7 +153,7 @@ void G4ComptonScattering::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
ptrVector = new G4PhysicsLogVector(LowestEnergyLimit,HighestEnergyLimit,
|
||||
NumbBinTable ) ;
|
||||
material = (*theMaterialTable)[J];
|
||||
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
|
||||
@@ -155,7 +165,7 @@ void G4ComptonScattering::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
}
|
||||
|
||||
PrintInfoDefinition();
|
||||
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -167,6 +177,7 @@ G4double G4ComptonScattering::ComputeCrossSectionPerAtom
|
||||
// A parametrized formula from L. Urban is used to estimate
|
||||
// the total cross section.
|
||||
// It gives a good description of the data from 10 keV to 100/Z GeV.
|
||||
// lower limit 1 keV now with a correction for low energy
|
||||
|
||||
{
|
||||
G4double CrossSection = 0.0 ;
|
||||
@@ -184,16 +195,99 @@ G4double G4ComptonScattering::ComputeCrossSectionPerAtom
|
||||
G4double p1Z = Z*(d1 + e1*Z + f1*Z*Z), p2Z = Z*(d2 + e2*Z + f2*Z*Z),
|
||||
p3Z = Z*(d3 + e3*Z + f3*Z*Z), p4Z = Z*(d4 + e4*Z + f4*Z*Z);
|
||||
|
||||
G4double X = GammaEnergy / electron_mass_c2 ;
|
||||
G4double T0 = 15*keV; if (Z == 1.) T0 = 40*keV;
|
||||
|
||||
return CrossSection = p1Z*log(1.+2*X)/X
|
||||
+ (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
|
||||
}
|
||||
G4double X = max(GammaEnergy, T0) / electron_mass_c2;
|
||||
CrossSection = p1Z*log(1.+2*X)/X
|
||||
+ (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
|
||||
|
||||
// modification for low energy. (special case for Hydrogen)
|
||||
if (GammaEnergy < T0) {
|
||||
G4double dT0 = 1.*keV;
|
||||
X = (T0+dT0) / electron_mass_c2 ;
|
||||
G4double sigma = p1Z*log(1.+2*X)/X
|
||||
+ (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
|
||||
G4double c1 = -T0*(sigma-CrossSection)/(CrossSection*dT0);
|
||||
G4double c2 = 0.150; if (Z > 1.) c2 = 0.375-0.0556*log(Z);
|
||||
G4double y = log(GammaEnergy/T0);
|
||||
CrossSection *= exp(-y*(c1+c2*y));
|
||||
}
|
||||
|
||||
return CrossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4ComptonScattering::ComputeMeanFreePath(G4double GammaEnergy,
|
||||
G4Material* aMaterial)
|
||||
|
||||
// returns the gamma mean free path in GEANT4 internal units
|
||||
|
||||
{
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector() ;
|
||||
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double SIGMA = 0.;
|
||||
|
||||
for ( size_t elm=0 ; elm < aMaterial->GetNumberOfElements() ; elm++ )
|
||||
{
|
||||
SIGMA += NbOfAtomsPerVolume[elm] *
|
||||
ComputeCrossSectionPerAtom(GammaEnergy,
|
||||
(*theElementVector)[elm]->GetZ());
|
||||
}
|
||||
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4ComptonScattering::GetCrossSectionPerAtom(
|
||||
G4DynamicParticle* aDynamicGamma,
|
||||
G4Element* anElement)
|
||||
|
||||
// gives the microscopic total cross section in GEANT4 internal units
|
||||
|
||||
{
|
||||
G4double crossSection;
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4bool isOutRange ;
|
||||
if (GammaEnergy < LowestEnergyLimit || GammaEnergy > HighestEnergyLimit)
|
||||
crossSection = 0.;
|
||||
else
|
||||
crossSection = (*theCrossSectionTable)(anElement->GetIndex())->
|
||||
GetValue(GammaEnergy, isOutRange);
|
||||
|
||||
return crossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
G4double G4ComptonScattering::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double,
|
||||
G4ForceCondition*)
|
||||
|
||||
// returns the gamma mean free path in GEANT4 internal units
|
||||
|
||||
{
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
G4double MeanFreePath;
|
||||
G4bool isOutRange;
|
||||
|
||||
if (GammaEnergy > HighestEnergyLimit || GammaEnergy < LowestEnergyLimit)
|
||||
MeanFreePath = DBL_MAX;
|
||||
else
|
||||
MeanFreePath = (*theMeanFreePathTable)(aMaterial->GetIndex())->
|
||||
GetValue(GammaEnergy, isOutRange);
|
||||
return MeanFreePath;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
const G4Step& aStep)
|
||||
//
|
||||
// The scattered gamma energy is sampled according to Klein - Nishina formula.
|
||||
// The random number techniques of Butcher & Messel are used
|
||||
@@ -214,7 +308,7 @@ G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
//
|
||||
// sample the energy rate of the scattered gamma
|
||||
//
|
||||
|
||||
|
||||
G4double epsilon, epsilonsq, onecost, sint2, greject ;
|
||||
|
||||
G4double epsilon0 = 1./(1. + 2*E0_m) , epsilon0sq = epsilon0*epsilon0;
|
||||
@@ -242,24 +336,24 @@ G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double dirx = sinTeta*cos(Phi), diry = sinTeta*sin(Phi), dirz = cosTeta;
|
||||
|
||||
//
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
//
|
||||
|
||||
G4ThreeVector GammaDirection1 ( dirx,diry,dirz );
|
||||
GammaDirection1.rotateUz(GammaDirection0);
|
||||
aParticleChange.SetMomentumChange( GammaDirection1 );
|
||||
aParticleChange.ProposeMomentumDirection( GammaDirection1 );
|
||||
G4double GammaEnergy1 = epsilon*GammaEnergy0;
|
||||
G4double localEnergyDeposit = 0.;
|
||||
|
||||
if (GammaEnergy1 > fminimalEnergy)
|
||||
{
|
||||
aParticleChange.SetEnergyChange( GammaEnergy1 );
|
||||
aParticleChange.ProposeEnergy( GammaEnergy1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
localEnergyDeposit += GammaEnergy1;
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.ProposeEnergy(0.) ;
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -275,8 +369,8 @@ G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
G4ThreeVector ElecDirection (
|
||||
(GammaEnergy0*GammaDirection0 - GammaEnergy1*GammaDirection1)
|
||||
*(1./ElecMomentum) );
|
||||
|
||||
// create G4DynamicParticle object for the electron.
|
||||
|
||||
// create G4DynamicParticle object for the electron.
|
||||
G4DynamicParticle* aElectron= new G4DynamicParticle(
|
||||
G4Electron::Electron(),ElecDirection,ElecKineEnergy);
|
||||
|
||||
@@ -287,18 +381,18 @@ G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
{
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
localEnergyDeposit += ElecKineEnergy;
|
||||
}
|
||||
aParticleChange.SetLocalEnergyDeposit (localEnergyDeposit);
|
||||
|
||||
}
|
||||
aParticleChange.ProposeLocalEnergyDeposit (localEnergyDeposit);
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4ComptonScattering::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
G4bool G4ComptonScattering::StorePhysicsTable(const G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4String filename;
|
||||
|
||||
@@ -317,17 +411,17 @@ G4bool G4ComptonScattering::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4ComptonScattering::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
/*
|
||||
G4bool G4ComptonScattering::RetrievePhysicsTable(const G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
// delete theCrossSectionTable and theMeanFreePathTable
|
||||
@@ -345,27 +439,27 @@ G4bool G4ComptonScattering::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
// retreive cross section table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"CrossSection",ascii);
|
||||
theCrossSectionTable = new G4PhysicsTable(G4Element::GetNumberOfElements());
|
||||
if ( !theCrossSectionTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
if ( !G4PhysicsTableHelper::RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theCrossSectionTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// retreive mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
theMeanFreePathTable = new G4PhysicsTable(G4Material::GetNumberOfMaterials());
|
||||
if ( !theMeanFreePathTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
if ( !G4PhysicsTableHelper::RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to retrieve the PhysicsTables from "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
*/
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4ComptonScattering::PrintInfoDefinition()
|
||||
|
||||
Reference in New Issue
Block a user