Import Geant4 4.1.0 source tree
This commit is contained in:
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ComptonScattering.cc,v 1.14 2001/10/01 15:00:29 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4ComptonScattering.cc,v 1.16 2002/04/18 10:12:01 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//
|
||||
//------------ G4ComptonScattering physics process -----------------------------
|
||||
@@ -46,7 +46,8 @@
|
||||
// 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)
|
||||
// 01-10-01, come back to BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// 01-10-01, come back to BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// 17-04-02, LowestEnergyLimit = 1*keV
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "G4ComptonScattering.hh"
|
||||
@@ -60,9 +61,9 @@ G4ComptonScattering::G4ComptonScattering(const G4String& processName)
|
||||
: G4VDiscreteProcess (processName),
|
||||
theCrossSectionTable(NULL),
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestEnergyLimit ( 10*keV),
|
||||
LowestEnergyLimit ( 1*keV),
|
||||
HighestEnergyLimit(100*GeV),
|
||||
NumbBinTable(100),
|
||||
NumbBinTable(80),
|
||||
fminimalEnergy(1*eV)
|
||||
{}
|
||||
|
||||
@@ -170,7 +171,7 @@ G4double G4ComptonScattering::ComputeCrossSectionPerAtom
|
||||
{
|
||||
G4double CrossSection = 0.0 ;
|
||||
if ( Z < 1. ) return CrossSection;
|
||||
if ( GammaEnergy < 10.*keV ) return CrossSection;
|
||||
if ( GammaEnergy < 1.*keV ) return CrossSection;
|
||||
if ( GammaEnergy > (100.*GeV/Z) ) return CrossSection;
|
||||
|
||||
static const G4double a = 20.0 , b = 230.0 , c = 440.0;
|
||||
|
||||
@@ -21,38 +21,40 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4GammaConversion.cc,v 1.14 2001/10/01 15:00:29 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4GammaConversion.cc,v 1.17 2002/04/09 17:34:41 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//------------------ G4GammaConversion physics process -------------------------
|
||||
// by Michel Maire, 24 May 1996
|
||||
//
|
||||
// 11-06-96, Added SelectRandomAtom() method, M.Maire
|
||||
// 21-06-96, SetCuts implementation, M.Maire
|
||||
// 24-06-96, simplification in ComputeCrossSectionPerAtom, M.Maire
|
||||
// 24-06-96, in DoIt : change the particleType stuff, M.Maire
|
||||
// 25-06-96, modification in the generation of the teta angle, M.Maire
|
||||
// 16-09-96, minors optimisations in DoIt. Thanks to P.Urban
|
||||
// dynamical array PartialSumSigma
|
||||
// 13-12-96, fast sampling of epsil below 2 MeV, L.Urban
|
||||
// 14-01-97, crossection table + meanfreepath table.
|
||||
// PartialSumSigma removed, M.Maire
|
||||
// 14-01-97, in DoIt the positron is always created, even with Ekine=0,
|
||||
// for further annihilation, M.Maire
|
||||
// 14-03-97, new Physics scheme for geant4alpha, M.Maire
|
||||
// 28-03-97, protection in BuildPhysicsTable, M.Maire
|
||||
// 19-06-97, correction in ComputeCrossSectionPerAtom, L.Urban
|
||||
// 04-06-98, in DoIt, secondary production condition:
|
||||
// range>G4std::min(threshold,safety)
|
||||
// 13-08-98, new methods SetBining() PrintInfo()
|
||||
// 28-05-01, V.Ivanchenko minor changes to provide ANSI -wall compilation
|
||||
// 11-07-01, PostStepDoIt - sampling epsil: power(rndm,0.333333)
|
||||
// 13-07-01, DoIt: suppression of production cut for the (e-,e+) (mma)
|
||||
// 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)
|
||||
// 01-10-01, come back to BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// 11-06-96 Added SelectRandomAtom() method, M.Maire
|
||||
// 21-06-96 SetCuts implementation, M.Maire
|
||||
// 24-06-96 simplification in ComputeCrossSectionPerAtom, M.Maire
|
||||
// 24-06-96 in DoIt : change the particleType stuff, M.Maire
|
||||
// 25-06-96 modification in the generation of the teta angle, M.Maire
|
||||
// 16-09-96 minors optimisations in DoIt. Thanks to P.Urban
|
||||
// dynamical array PartialSumSigma
|
||||
// 13-12-96 fast sampling of epsil below 2 MeV, L.Urban
|
||||
// 14-01-97 crossection table + meanfreepath table.
|
||||
// PartialSumSigma removed, M.Maire
|
||||
// 14-01-97 in DoIt the positron is always created, even with Ekine=0,
|
||||
// for further annihilation, M.Maire
|
||||
// 14-03-97 new Physics scheme for geant4alpha, M.Maire
|
||||
// 28-03-97 protection in BuildPhysicsTable, M.Maire
|
||||
// 19-06-97 correction in ComputeCrossSectionPerAtom, L.Urban
|
||||
// 04-06-98 in DoIt, secondary production condition:
|
||||
// range>G4std::min(threshold,safety)
|
||||
// 13-08-98 new methods SetBining() PrintInfo()
|
||||
// 28-05-01 V.Ivanchenko minor changes to provide ANSI -wall compilation
|
||||
// 11-07-01 PostStepDoIt - sampling epsil: power(rndm,0.333333)
|
||||
// 13-07-01 DoIt: suppression of production cut for the (e-,e+) (mma)
|
||||
// 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)
|
||||
// 01-10-01 come back to BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// 11-01-02 ComputeCrossSection: correction of extrapolation below EnergyLimit
|
||||
// 21-03-02 DoIt: correction of the e+e- angular distribution (bug 363) mma
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "G4GammaConversion.hh"
|
||||
@@ -208,7 +210,8 @@ G4double G4GammaConversion::ComputeCrossSectionPerAtom
|
||||
|
||||
if (GammaEnergySave < GammaEnergyLimit)
|
||||
{
|
||||
X=GammaEnergySave-2.*electron_mass_c2;
|
||||
X = (GammaEnergySave - 2.*electron_mass_c2)
|
||||
/(GammaEnergyLimit- 2.*electron_mass_c2);
|
||||
CrossSection *= X*X;
|
||||
}
|
||||
|
||||
@@ -325,24 +328,26 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
if (9./(9.+d) >G4UniformRand()) u= - log(G4UniformRand()*G4UniformRand())/a1;
|
||||
else u= - log(G4UniformRand()*G4UniformRand())/a2;
|
||||
|
||||
G4double Teta = u*electron_mass_c2/GammaEnergy;
|
||||
G4double TetEl = u*electron_mass_c2/ElectTotEnergy;
|
||||
G4double TetPo = u*electron_mass_c2/PositTotEnergy;
|
||||
G4double Phi = twopi * G4UniformRand();
|
||||
G4double dirx=sin(Teta)*cos(Phi), diry=sin(Teta)*sin(Phi), dirz=cos(Teta);
|
||||
|
||||
G4double dxEl= sin(TetEl)*cos(Phi),dyEl= sin(TetEl)*sin(Phi),dzEl=cos(TetEl);
|
||||
G4double dxPo=-sin(TetPo)*cos(Phi),dyPo=-sin(TetPo)*sin(Phi),dzPo=cos(TetPo);
|
||||
|
||||
//
|
||||
// kinematic of the created pair
|
||||
//
|
||||
// the electron and positron are assumed to have a symetric
|
||||
// angular distribution with respect to the Z axis along the parent photon.
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(2) ;
|
||||
aParticleChange.SetNumberOfSecondaries(2);
|
||||
|
||||
G4double ElectKineEnergy = G4std::max(0.,ElectTotEnergy - electron_mass_c2);
|
||||
G4double localEnergyDeposit = 0.;
|
||||
|
||||
if (ElectKineEnergy > fminimalEnergy)
|
||||
{
|
||||
G4ThreeVector ElectDirection (dirx, diry, dirz);
|
||||
G4ThreeVector ElectDirection (dxEl, dyEl, dzEl);
|
||||
ElectDirection.rotateUz(GammaDirection);
|
||||
|
||||
// create G4DynamicParticle object for the particle1
|
||||
@@ -359,7 +364,7 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
if (PositKineEnergy < fminimalEnergy)
|
||||
{ localEnergyDeposit += PositKineEnergy; PositKineEnergy = 0.;}
|
||||
|
||||
G4ThreeVector PositDirection (-dirx, -diry, dirz);
|
||||
G4ThreeVector PositDirection (dxPo, dyPo, dzPo);
|
||||
PositDirection.rotateUz(GammaDirection);
|
||||
|
||||
// create G4DynamicParticle object for the particle2
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4GammaConversionToMuons.cc,v 1.3 2002/05/06 09:32:41 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
// ------------ G4GammaConversionToMuons physics process ------
|
||||
// by H.Burkhardt, S. Kelner and R. Kokoulin, April 2002
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include "G4GammaConversionToMuons.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4MuonPlus.hh"
|
||||
#include "G4MuonMinus.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
// constructor
|
||||
|
||||
G4GammaConversionToMuons::G4GammaConversionToMuons(const G4String& processName)
|
||||
: G4VDiscreteProcess (processName),
|
||||
LowestEnergyLimit (4*G4MuonPlus::MuonPlus()->GetPDGMass()), // 4*Mmuon
|
||||
HighestEnergyLimit(1e21*eV), // ok to 1e21eV=1e12GeV, then LPM suppression
|
||||
CrossSecFactor(1.)
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
// destructor
|
||||
|
||||
G4GammaConversionToMuons::~G4GammaConversionToMuons() // (empty) destructor
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4GammaConversionToMuons::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// Build cross section and mean free path tables
|
||||
{ //here no tables, just calling PrintInfoDefinition
|
||||
PrintInfoDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4GammaConversionToMuons::SetCrossSecFactor(G4double fac)
|
||||
// Set the factor to artificially increase the cross section
|
||||
{ CrossSecFactor=fac;
|
||||
G4cout << "The cross section for GammaConversionToMuons is artificially "
|
||||
<< "increased by the CrossSecFactor=" << CrossSecFactor << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4double G4GammaConversionToMuons::ComputeCrossSectionPerAtom(
|
||||
G4double Egam, G4double Z, G4double A)
|
||||
// Calculates the microscopic cross section in GEANT4 internal units.
|
||||
// Total cross section parametrisation from H.Burkhardt
|
||||
// It gives a good description at any energy (from 0 to 10**21 eV)
|
||||
{ static const G4double Mmuon=G4MuonPlus::MuonPlus()->GetPDGMass();
|
||||
static const G4double Mele=electron_mass_c2;
|
||||
static const G4double GammaEnergyLimit=4* Mmuon;
|
||||
static const G4double Rc=elm_coupling/Mmuon; // classical particle radius
|
||||
static const G4double sqrte=sqrt(exp(1.));
|
||||
static const G4double PowSat=-0.88;
|
||||
|
||||
static G4double CrossSection = 0.0 ;
|
||||
|
||||
if ( A < 1. ) return 0;
|
||||
if ( Egam < 4*Mmuon ) return 0 ; // below threshold return 0
|
||||
|
||||
static G4double EgamLast=0,Zlast=0,PowThres,Ecor,B,Dn,Zthird,Winfty,WMedAppr,
|
||||
Wsatur,sigfac;
|
||||
|
||||
if(Zlast==Z && Egam==EgamLast) return CrossSection; // already calculated
|
||||
EgamLast=Egam;
|
||||
|
||||
if(Zlast!=Z) // new element
|
||||
{ Zlast=Z;
|
||||
if(Z==1) // special case of Hydrogen
|
||||
{ B=202.4;
|
||||
Dn=1.49;
|
||||
}
|
||||
else
|
||||
{ B=183.;
|
||||
Dn=1.54*pow(A,0.27);
|
||||
}
|
||||
Zthird=pow(Z,-1./3.); // Z**(-1/3)
|
||||
Winfty=B*Zthird*Mmuon/(Dn*Mele);
|
||||
WMedAppr=1./(4.*Dn*sqrte*Mmuon);
|
||||
Wsatur=Winfty/WMedAppr;
|
||||
sigfac=4.*fine_structure_const*Z*Z*Rc*Rc;
|
||||
PowThres=1.479+0.00799*Dn;
|
||||
Ecor=-18.+4347./(B*Zthird);
|
||||
}
|
||||
G4double CorFuc=1.+.04*log(1.+Ecor/Egam);
|
||||
G4double Eg=pow(1.-4.*Mmuon/Egam,PowThres)*pow( pow(Wsatur,PowSat)+
|
||||
pow(Egam,PowSat),1./PowSat); // threshold and saturation
|
||||
CrossSection=7./9.*sigfac*log(1.+WMedAppr*CorFuc*Eg);
|
||||
CrossSection*=CrossSecFactor; // increase the CrossSection by (by default 1)
|
||||
return CrossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4VParticleChange* G4GammaConversionToMuons::PostStepDoIt(
|
||||
const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
//
|
||||
// generation of gamma->mu+mu-
|
||||
//
|
||||
{
|
||||
aParticleChange.Initialize(aTrack);
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
static const G4double Mmuon=G4MuonPlus::MuonPlus()->GetPDGMass();
|
||||
static const G4double Mele=electron_mass_c2;
|
||||
static const G4double sqrte=sqrt(exp(1.));
|
||||
|
||||
// current Gamma energy and direction, return if energy too low
|
||||
const G4DynamicParticle *aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double Egam = aDynamicGamma->GetKineticEnergy();
|
||||
if (Egam < 4*Mmuon) return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
G4ParticleMomentum GammaDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
// select randomly one element constituting the material
|
||||
const G4Element& anElement = *SelectRandomAtom(aDynamicGamma, aMaterial);
|
||||
G4double Z = anElement.GetZ();
|
||||
G4double A = anElement.GetA()/(g/mole);
|
||||
|
||||
static G4double Zlast=0,B,Dn,Zthird,Winfty,A027,C1Num2,C2Term2;
|
||||
if(Zlast!=Z) // the element has changed
|
||||
{ Zlast=Z;
|
||||
if(Z==1) // special case of Hydrogen
|
||||
{ B=202.4;
|
||||
Dn=1.49;
|
||||
}
|
||||
else
|
||||
{ B=183.;
|
||||
Dn=1.54*pow(A,0.27);
|
||||
}
|
||||
Zthird=pow(Z,-1./3.); // Z**(-1/3)
|
||||
Winfty=B*Zthird*Mmuon/(Dn*Mele);
|
||||
A027=pow(A,0.27);
|
||||
G4double C1Num=0.35*A027;
|
||||
C1Num2=C1Num*C1Num;
|
||||
C2Term2=Mele/(183.*Zthird*Mmuon);
|
||||
}
|
||||
|
||||
G4double GammaMuonInv=Mmuon/Egam;
|
||||
G4double sqrtx=sqrt(.25-GammaMuonInv);
|
||||
G4double xmax=.5+sqrtx;
|
||||
G4double xmin=.5-sqrtx;
|
||||
|
||||
// generate xPlus according to the differential cross section by rejection
|
||||
G4double Ds2=(Dn*sqrte-2.);
|
||||
G4double sBZ=sqrte*B*Zthird/Mele;
|
||||
G4double LogWmaxInv=1./log(Winfty*(1.+2.*Ds2*GammaMuonInv)
|
||||
/(1.+2.*sBZ*Mmuon*GammaMuonInv));
|
||||
G4double xPlus,xMinus,xPM,result,W;
|
||||
do
|
||||
{ xPlus=xmin+G4UniformRand()*(xmax-xmin);
|
||||
xMinus=1.-xPlus;
|
||||
xPM=xPlus*xMinus;
|
||||
G4double del=Mmuon*Mmuon/(2.*Egam*xPM);
|
||||
W=Winfty*(1.+Ds2*del/Mmuon)/(1.+sBZ*del);
|
||||
if(W<1.) W=1.; // to avoid negative cross section at xmin
|
||||
G4double xxp=1.-4./3.*xPM; // the main xPlus dependence
|
||||
result=xxp*log(W)*LogWmaxInv;
|
||||
if(result>1.)
|
||||
{ G4cout << "error in dSigxPlusGen, result=" << result << " is >1" << '\n';
|
||||
exit(10);
|
||||
}
|
||||
}
|
||||
while (G4UniformRand() > result);
|
||||
|
||||
// now generate the angular variables via the auxilary variables t,psi,rho
|
||||
G4double t;
|
||||
G4double psi;
|
||||
G4double rho;
|
||||
|
||||
G4double thetaPlus,thetaMinus,phiHalf; // final angular variables
|
||||
|
||||
do // t, psi, rho generation start (while angle < pi)
|
||||
{
|
||||
//generate t by the rejection method
|
||||
G4double C1=C1Num2* GammaMuonInv/xPM;
|
||||
G4double f1_max=(1.-xPM) / (1.+C1);
|
||||
G4double f1; // the probability density
|
||||
do
|
||||
{ t=G4UniformRand();
|
||||
f1=(1.-2.*xPM+4.*xPM*t*(1.-t)) / (1.+C1/(t*t));
|
||||
if(f1<0 | f1> f1_max) // should never happend
|
||||
{ G4cout << "outside allowed range f1=" << f1 << G4endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
while ( G4UniformRand()*f1_max > f1);
|
||||
// generate psi by the rejection method
|
||||
G4double f2_max=1.-2.*xPM*(1.-4.*t*(1.-t));
|
||||
|
||||
// long version
|
||||
G4double f2;
|
||||
do
|
||||
{ psi=2.*pi*G4UniformRand();
|
||||
f2=1.-2.*xPM+4.*xPM*t*(1.-t)*(1.+cos(2.*psi));
|
||||
if(f2<0 | f2> f2_max) // should never happend
|
||||
{ G4cout << "outside allowed range f2=" << f2 << G4endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
while ( G4UniformRand()*f2_max > f2);
|
||||
|
||||
// generate rho by direct transformation
|
||||
G4double C2Term1=GammaMuonInv/(2.*xPM*t);
|
||||
G4double C2=4./sqrt(xPM)*pow(C2Term1*C2Term1+C2Term2*C2Term2,2);
|
||||
G4double rhomax=1.9/A027*(1./t-1.);
|
||||
G4double beta=log( (C2+pow(rhomax,4))/C2 );
|
||||
rho=pow(C2 *( exp(beta*G4UniformRand())-1. ) ,0.25);
|
||||
|
||||
//now get from t and psi the kinematical variables
|
||||
G4double u=sqrt(1./t-1.);
|
||||
G4double xiHalf=0.5*rho*cos(psi);
|
||||
phiHalf=0.5*rho/u*sin(psi);
|
||||
|
||||
thetaPlus =GammaMuonInv*(u+xiHalf)/xPlus;
|
||||
thetaMinus=GammaMuonInv*(u-xiHalf)/xMinus;
|
||||
|
||||
} while ( abs(thetaPlus)>pi | abs(thetaMinus) >pi);
|
||||
|
||||
// now construct the vectors
|
||||
// azimuthal symmetry, take phi0 at random between 0 and 2 pi
|
||||
G4double phi0=2.*pi*G4UniformRand();
|
||||
G4double EPlus=xPlus*Egam;
|
||||
G4double EMinus=xMinus*Egam;
|
||||
|
||||
// mu+ mu- directions for gamma in z-direction
|
||||
G4ThreeVector MuPlusDirection ( sin(thetaPlus) *cos(phi0+phiHalf),
|
||||
sin(thetaPlus) *sin(phi0+phiHalf), cos(thetaPlus) );
|
||||
G4ThreeVector MuMinusDirection (-sin(thetaMinus)*cos(phi0-phiHalf),
|
||||
-sin(thetaMinus) *sin(phi0-phiHalf), cos(thetaMinus) );
|
||||
// rotate to actual gamma direction
|
||||
MuPlusDirection.rotateUz(GammaDirection);
|
||||
MuMinusDirection.rotateUz(GammaDirection);
|
||||
aParticleChange.SetNumberOfSecondaries(2);
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1= new G4DynamicParticle(
|
||||
G4MuonPlus::MuonPlus(),MuPlusDirection,EPlus-Mmuon);
|
||||
aParticleChange.AddSecondary(aParticle1);
|
||||
// create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* aParticle2= new G4DynamicParticle(
|
||||
G4MuonMinus::MuonMinus(),MuMinusDirection,EMinus-Mmuon);
|
||||
aParticleChange.AddSecondary(aParticle2);
|
||||
//
|
||||
// Kill the incident photon
|
||||
//
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. ) ;
|
||||
aParticleChange.SetEnergyChange( 0. ) ;
|
||||
aParticleChange.SetStatusChange( fStopAndKill ) ;
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4Element* G4GammaConversionToMuons::SelectRandomAtom(
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4Material* aMaterial)
|
||||
{
|
||||
// select randomly 1 element within the material, invoked by PostStepDoIt
|
||||
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
if (NumberOfElements == 1) return (*theElementVector)[0];
|
||||
|
||||
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double PartialSumSigma = 0. ;
|
||||
G4double rval = G4UniformRand()/MeanFreePath;
|
||||
|
||||
|
||||
for ( G4int i=0 ; i < NumberOfElements ; i++ )
|
||||
{ PartialSumSigma += NbOfAtomsPerVolume[i] *
|
||||
GetCrossSectionPerAtom(aDynamicGamma, (*theElementVector)[i]);
|
||||
if (rval <= PartialSumSigma) return ((*theElementVector)[i]);
|
||||
}
|
||||
G4cout << " WARNING !!! - The Material '"<< aMaterial->GetName()
|
||||
<< "' has no elements, NULL pointer returned." << G4endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4GammaConversionToMuons::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments ="gamma->mu+mu- Bethe Heitler process.\n";
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< " good cross section parametrization from "
|
||||
<< G4BestUnit(LowestEnergyLimit,"Energy")
|
||||
<< " to " << HighestEnergyLimit/GeV << " GeV for all Z." << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4PAIonisation.cc,v 1.22 2001/11/09 13:59:46 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4PAIonisation.cc,v 1.23 2002/04/09 17:34:41 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//
|
||||
// **************************************************************
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4PAIxSection.cc,v 1.8 2001/10/17 14:01:11 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4PAIxSection.cc,v 1.10 2002/04/09 17:34:42 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//
|
||||
// G4PAIxSection.cc -- class implementation file
|
||||
@@ -298,8 +298,12 @@ G4PAIxSection::G4PAIxSection( G4int materialIndex,
|
||||
for(i = 1 ; i <= fSplineNumber ; i++)
|
||||
{
|
||||
fDifPAIxSection[i] = DifPAIxSection(i,betaGammaSq);
|
||||
fdNdxCerenkov[i] = PAIdNdxCerenkov(i,betaGammaSq);
|
||||
fdNdxPlasmon[i] = PAIdNdxPlasmon(i,betaGammaSq);
|
||||
}
|
||||
IntegralPAIxSection() ;
|
||||
IntegralCerenkov() ;
|
||||
IntegralPlasmon() ;
|
||||
|
||||
delete[] fEnergyInterval ;
|
||||
delete[] fA1 ;
|
||||
@@ -428,8 +432,12 @@ G4PAIxSection::G4PAIxSection( G4int materialIndex,
|
||||
for(i = 1 ; i <= fSplineNumber ; i++)
|
||||
{
|
||||
fDifPAIxSection[i] = DifPAIxSection(i,betaGammaSq);
|
||||
fdNdxCerenkov[i] = PAIdNdxCerenkov(i,betaGammaSq);
|
||||
fdNdxPlasmon[i] = PAIdNdxPlasmon(i,betaGammaSq);
|
||||
}
|
||||
IntegralPAIxSection() ;
|
||||
IntegralCerenkov() ;
|
||||
IntegralPlasmon() ;
|
||||
|
||||
// delete[] fEnergyInterval ;
|
||||
delete[] fA1 ;
|
||||
@@ -470,7 +478,10 @@ void G4PAIxSection::InitPAI()
|
||||
|
||||
NormShift(betaGammaSq) ;
|
||||
SplainPAI(betaGammaSq) ;
|
||||
|
||||
IntegralPAIxSection() ;
|
||||
IntegralCerenkov() ;
|
||||
IntegralPlasmon() ;
|
||||
|
||||
for(i = 0 ; i<=fSplineNumber ; i++)
|
||||
{
|
||||
@@ -484,17 +495,19 @@ void G4PAIxSection::InitPAI()
|
||||
|
||||
for(G4int j = 1 ; j < 112 ; j++) // for other gammas
|
||||
{
|
||||
if(j == fRefGammaNumber)
|
||||
{
|
||||
continue ;
|
||||
}
|
||||
if( j == fRefGammaNumber ) continue ;
|
||||
|
||||
betaGammaSq = fLorentzFactor[j]*fLorentzFactor[j] - 1 ;
|
||||
|
||||
for(i = 1 ; i <= fSplineNumber ; i++)
|
||||
{
|
||||
fDifPAIxSection[i] = DifPAIxSection(i,betaGammaSq);
|
||||
fdNdxCerenkov[i] = PAIdNdxCerenkov(i,betaGammaSq);
|
||||
fdNdxPlasmon[i] = PAIdNdxPlasmon(i,betaGammaSq);
|
||||
}
|
||||
IntegralPAIxSection() ;
|
||||
IntegralCerenkov() ;
|
||||
IntegralPlasmon() ;
|
||||
|
||||
for(i = 0 ; i <= fSplineNumber ; i++)
|
||||
{
|
||||
@@ -511,46 +524,43 @@ void G4PAIxSection::InitPAI()
|
||||
|
||||
void G4PAIxSection::NormShift(G4double betaGammaSq)
|
||||
{
|
||||
G4int i,j;
|
||||
for(i=1;i<=fIntervalNumber-1;i++)
|
||||
{
|
||||
for(j=1;j<=2;j++)
|
||||
{
|
||||
fSplineNumber = (i-1)*2 + j ;
|
||||
G4int i, j ;
|
||||
|
||||
if(j==1)
|
||||
{
|
||||
fSplineEnergy[fSplineNumber]=fEnergyInterval[i]*(1+fDelta);
|
||||
}
|
||||
else
|
||||
{
|
||||
fSplineEnergy[fSplineNumber]=fEnergyInterval[i+1]*(1-fDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
fIntegralTerm[1]=RutherfordIntegral(1,fEnergyInterval[1],fSplineEnergy[1]);
|
||||
j=1;
|
||||
for(i=2;i<=fSplineNumber;i++)
|
||||
{
|
||||
if(fSplineEnergy[i]<fEnergyInterval[j+1])
|
||||
{
|
||||
for( i = 1 ; i <= fIntervalNumber-1 ; i++ )
|
||||
{
|
||||
for(j=1;j<=2;j++)
|
||||
{
|
||||
fSplineNumber = (i-1)*2 + j ;
|
||||
|
||||
if( j == 1 ) fSplineEnergy[fSplineNumber] = fEnergyInterval[i]*(1+fDelta);
|
||||
else fSplineEnergy[fSplineNumber] = fEnergyInterval[i+1]*(1-fDelta);
|
||||
}
|
||||
}
|
||||
fIntegralTerm[1]=RutherfordIntegral(1,fEnergyInterval[1],fSplineEnergy[1]);
|
||||
|
||||
j = 1 ;
|
||||
|
||||
for(i=2;i<=fSplineNumber;i++)
|
||||
{
|
||||
if(fSplineEnergy[i]<fEnergyInterval[j+1])
|
||||
{
|
||||
fIntegralTerm[i] = fIntegralTerm[i-1] +
|
||||
RutherfordIntegral(j,fSplineEnergy[i-1],
|
||||
fSplineEnergy[i] ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double x = RutherfordIntegral(j,fSplineEnergy[i-1],
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double x = RutherfordIntegral(j,fSplineEnergy[i-1],
|
||||
fEnergyInterval[j+1] ) ;
|
||||
j++;
|
||||
fIntegralTerm[i] = fIntegralTerm[i-1] + x +
|
||||
RutherfordIntegral(j,fEnergyInterval[j],
|
||||
fSplineEnergy[i] ) ;
|
||||
}
|
||||
}
|
||||
// G4cout<<i<<"\t"<<fSplineEnergy[i]<<"\t"<<fIntegralTerm[i]<<"\n"<<G4endl;
|
||||
}
|
||||
fNormalizationCof = 2*pi*pi*hbarc*hbarc*fine_structure_const/electron_mass_c2 ;
|
||||
fNormalizationCof *= fElectronDensity/fIntegralTerm[fSplineNumber] ;
|
||||
}
|
||||
fNormalizationCof = 2*pi*pi*hbarc*hbarc*fine_structure_const/electron_mass_c2 ;
|
||||
fNormalizationCof *= fElectronDensity/fIntegralTerm[fSplineNumber] ;
|
||||
|
||||
// G4cout<<"fNormalizationCof = "<<fNormalizationCof<<G4endl ;
|
||||
|
||||
@@ -567,7 +577,10 @@ void G4PAIxSection::NormShift(G4double betaGammaSq)
|
||||
fRePartDielectricConst[i] = fNormalizationCof*
|
||||
RePartDielectricConst(fSplineEnergy[i]);
|
||||
fIntegralTerm[i] *= fNormalizationCof;
|
||||
|
||||
fDifPAIxSection[i] = DifPAIxSection(i,betaGammaSq);
|
||||
fdNdxCerenkov[i] = PAIdNdxCerenkov(i,betaGammaSq);
|
||||
fdNdxPlasmon[i] = PAIdNdxPlasmon(i,betaGammaSq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,13 +610,16 @@ void
|
||||
// average of 'i' and 'i+1' energy points to 'i+1' place
|
||||
fSplineNumber++;
|
||||
|
||||
for(G4int j=fSplineNumber;j>=i+2;j--)
|
||||
for(G4int j = fSplineNumber; j >= i+2 ; j-- )
|
||||
{
|
||||
fSplineEnergy[j] = fSplineEnergy[j-1];
|
||||
fSplineEnergy[j] = fSplineEnergy[j-1];
|
||||
fImPartDielectricConst[j] = fImPartDielectricConst[j-1];
|
||||
fRePartDielectricConst[j] = fRePartDielectricConst[j-1];
|
||||
fIntegralTerm[j] = fIntegralTerm[j-1];
|
||||
fIntegralTerm[j] = fIntegralTerm[j-1];
|
||||
|
||||
fDifPAIxSection[j] = fDifPAIxSection[j-1];
|
||||
fdNdxCerenkov[j] = fdNdxCerenkov[j-1];
|
||||
fdNdxPlasmon[j] = fdNdxPlasmon[j-1];
|
||||
}
|
||||
G4double x1 = fSplineEnergy[i];
|
||||
G4double x2 = fSplineEnergy[i+1];
|
||||
@@ -630,7 +646,10 @@ void
|
||||
fIntegralTerm[i+1] = fIntegralTerm[i] + fNormalizationCof*
|
||||
RutherfordIntegral(k,fSplineEnergy[i],
|
||||
fSplineEnergy[i+1]);
|
||||
|
||||
fDifPAIxSection[i+1] = DifPAIxSection(i+1,betaGammaSq);
|
||||
fdNdxCerenkov[i+1] = PAIdNdxCerenkov(i+1,betaGammaSq);
|
||||
fdNdxPlasmon[i+1] = PAIdNdxPlasmon(i+1,betaGammaSq);
|
||||
|
||||
// Condition for next division of this segment or to pass
|
||||
// to higher energies
|
||||
@@ -651,32 +670,6 @@ void
|
||||
|
||||
} // end of SplainPAI
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation of the PAI integral cross-section
|
||||
// fIntegralPAIxSection[1] = specific primary ionisation, 1/cm
|
||||
// and fIntegralPAIxSection[0] = mean energy loss per cm in keV/cm
|
||||
|
||||
void G4PAIxSection::IntegralPAIxSection()
|
||||
{
|
||||
fIntegralPAIxSection[fSplineNumber] = 0 ;
|
||||
fIntegralPAIxSection[0] = 0 ;
|
||||
G4int k = fIntervalNumber -1 ;
|
||||
for(G4int i=fSplineNumber-1;i>=1;i--)
|
||||
{
|
||||
if(fSplineEnergy[i] >= fEnergyInterval[k])
|
||||
{
|
||||
fIntegralPAIxSection[i] = fIntegralPAIxSection[i+1] + SumOverInterval(i) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fIntegralPAIxSection[i] = fIntegralPAIxSection[i+1] +
|
||||
SumOverBorder(i+1,fEnergyInterval[k]) ;
|
||||
k-- ;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of IntegralPAIxSection
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -722,7 +715,7 @@ G4double G4PAIxSection::ImPartDielectricConst( G4int k ,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Real part of dielectric constant minus unit
|
||||
// Real part of dielectric constant minus unit: epsilon_1 - 1
|
||||
// (G4double enb - energy point)
|
||||
//
|
||||
|
||||
@@ -836,6 +829,187 @@ G4double G4PAIxSection::DifPAIxSection( G4int i ,
|
||||
|
||||
} // end of DifPAIxSection
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation od dN/dx of collisions with creation of Cerenkov pseudo-photons
|
||||
|
||||
G4double G4PAIxSection::PAIdNdxCerenkov( G4int i ,
|
||||
G4double betaGammaSq )
|
||||
{
|
||||
G4double cof, logarithm, x3, x5, argument, modul2, dNdxC ;
|
||||
G4double be2, be4, betaBohr2,betaBohr4,cofBetaBohr ;
|
||||
|
||||
cof = 1.0 ;
|
||||
cofBetaBohr = 4.0 ;
|
||||
betaBohr2 = fine_structure_const*fine_structure_const ;
|
||||
betaBohr4 = betaBohr2*betaBohr2*cofBetaBohr ;
|
||||
|
||||
be2 = betaGammaSq/(1 + betaGammaSq) ;
|
||||
be4 = be2*be2 ;
|
||||
|
||||
if( betaGammaSq < 0.01 ) logarithm = log(1.0+betaGammaSq) ; // 0.0 ;
|
||||
else
|
||||
{
|
||||
logarithm = -log( (1/betaGammaSq - fRePartDielectricConst[i])*
|
||||
(1/betaGammaSq - fRePartDielectricConst[i]) +
|
||||
fImPartDielectricConst[i]*fImPartDielectricConst[i] )*0.5 ;
|
||||
logarithm += log(1+1.0/betaGammaSq) ;
|
||||
}
|
||||
|
||||
if( fImPartDielectricConst[i] == 0.0 || betaGammaSq < 0.01 )
|
||||
{
|
||||
argument = 0.0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
x3 = -fRePartDielectricConst[i] + 1.0/betaGammaSq ;
|
||||
x5 = -1.0 - fRePartDielectricConst[i] +
|
||||
be2*((1.0 +fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) +
|
||||
fImPartDielectricConst[i]*fImPartDielectricConst[i]) ;
|
||||
if( x3 == 0.0 ) argument = 0.5*pi;
|
||||
else argument = atan2(fImPartDielectricConst[i],x3) ;
|
||||
argument *= x5 ;
|
||||
}
|
||||
dNdxC = ( logarithm*fImPartDielectricConst[i] + argument )/hbarc ;
|
||||
|
||||
if(dNdxC < 1.0e-8) dNdxC = 1.0e-8 ;
|
||||
|
||||
dNdxC *= fine_structure_const/be2/pi ;
|
||||
|
||||
dNdxC *= (1-exp(-be4/betaBohr4)) ;
|
||||
|
||||
if(fDensity >= 0.1)
|
||||
{
|
||||
modul2 = (1.0 + fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) +
|
||||
fImPartDielectricConst[i]*fImPartDielectricConst[i] ;
|
||||
dNdxC /= modul2 ;
|
||||
}
|
||||
return dNdxC ;
|
||||
|
||||
} // end of PAIdNdxCerenkov
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation od dN/dx of collisions with creation of longitudinal EM
|
||||
// excitations (plasmons, delta-electrons)
|
||||
|
||||
G4double G4PAIxSection::PAIdNdxPlasmon( G4int i ,
|
||||
G4double betaGammaSq )
|
||||
{
|
||||
G4double cof, resonance, modul2, dNdxP ;
|
||||
G4double be2, be4, betaBohr2, betaBohr4, cofBetaBohr ;
|
||||
|
||||
cof = 1 ;
|
||||
cofBetaBohr = 4.0 ;
|
||||
betaBohr2 = fine_structure_const*fine_structure_const ;
|
||||
betaBohr4 = betaBohr2*betaBohr2*cofBetaBohr ;
|
||||
|
||||
be2 = betaGammaSq/(1 + betaGammaSq) ;
|
||||
be4 = be2*be2 ;
|
||||
|
||||
resonance = log(2*electron_mass_c2*be2/fSplineEnergy[i]) ;
|
||||
resonance *= fImPartDielectricConst[i]/hbarc ;
|
||||
|
||||
|
||||
dNdxP = ( resonance + cof*fIntegralTerm[i]/fSplineEnergy[i]/fSplineEnergy[i] ) ;
|
||||
|
||||
if( dNdxP < 1.0e-8 ) dNdxP = 1.0e-8 ;
|
||||
|
||||
dNdxP *= fine_structure_const/be2/pi ;
|
||||
dNdxP *= (1-exp(-be4/betaBohr4)) ;
|
||||
|
||||
if( fDensity >= 0.1 )
|
||||
{
|
||||
modul2 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
|
||||
fImPartDielectricConst[i]*fImPartDielectricConst[i] ;
|
||||
dNdxP /= modul2 ;
|
||||
}
|
||||
return dNdxP ;
|
||||
|
||||
} // end of PAIdNdxPlasmon
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation of the PAI integral cross-section
|
||||
// fIntegralPAIxSection[1] = specific primary ionisation, 1/cm
|
||||
// and fIntegralPAIxSection[0] = mean energy loss per cm in keV/cm
|
||||
|
||||
void G4PAIxSection::IntegralPAIxSection()
|
||||
{
|
||||
fIntegralPAIxSection[fSplineNumber] = 0 ;
|
||||
fIntegralPAIxSection[0] = 0 ;
|
||||
G4int k = fIntervalNumber -1 ;
|
||||
for(G4int i=fSplineNumber-1;i>=1;i--)
|
||||
{
|
||||
if(fSplineEnergy[i] >= fEnergyInterval[k])
|
||||
{
|
||||
fIntegralPAIxSection[i] = fIntegralPAIxSection[i+1] + SumOverInterval(i) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fIntegralPAIxSection[i] = fIntegralPAIxSection[i+1] +
|
||||
SumOverBorder(i+1,fEnergyInterval[k]) ;
|
||||
k-- ;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of IntegralPAIxSection
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation of the PAI Cerenkov integral cross-section
|
||||
// fIntegralCrenkov[1] = specific Crenkov ionisation, 1/cm
|
||||
// and fIntegralCerenkov[0] = mean Cerenkov loss per cm in keV/cm
|
||||
|
||||
void G4PAIxSection::IntegralCerenkov()
|
||||
{
|
||||
fIntegralCerenkov[fSplineNumber] = 0 ;
|
||||
fIntegralCerenkov[0] = 0 ;
|
||||
|
||||
G4int k = fIntervalNumber -1 ;
|
||||
for(G4int i=fSplineNumber-1;i>=1;i--)
|
||||
{
|
||||
if(fSplineEnergy[i] >= fEnergyInterval[k])
|
||||
{
|
||||
fIntegralCerenkov[i] = fIntegralCerenkov[i+1] + SumOverInterCerenkov(i) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fIntegralCerenkov[i] = fIntegralCerenkov[i+1] +
|
||||
SumOverBordCerenkov(i+1,fEnergyInterval[k]) ;
|
||||
k-- ;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of IntegralCerenkov
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation of the PAI Plasmon integral cross-section
|
||||
// fIntegralPlasmon[1] = splasmon primary ionisation, 1/cm
|
||||
// and fIntegralPlasmon[0] = mean plasmon loss per cm in keV/cm
|
||||
|
||||
void G4PAIxSection::IntegralPlasmon()
|
||||
{
|
||||
fIntegralPlasmon[fSplineNumber] = 0 ;
|
||||
fIntegralPlasmon[0] = 0 ;
|
||||
G4int k = fIntervalNumber -1 ;
|
||||
for(G4int i=fSplineNumber-1;i>=1;i--)
|
||||
{
|
||||
if(fSplineEnergy[i] >= fEnergyInterval[k])
|
||||
{
|
||||
fIntegralPlasmon[i] = fIntegralPlasmon[i+1] + SumOverInterPlasmon(i) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fIntegralPlasmon[i] = fIntegralPlasmon[i+1] +
|
||||
SumOverBordPlasmon(i+1,fEnergyInterval[k]) ;
|
||||
k-- ;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of IntegralPlasmon
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation the PAI integral cross-section inside
|
||||
@@ -876,6 +1050,68 @@ G4double G4PAIxSection::SumOverInterval( G4int i )
|
||||
|
||||
} // end of SumOverInterval
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation the PAI Cerenkov integral cross-section inside
|
||||
// of interval of continuous values of photo-ionisation Cerenkov
|
||||
// cross-section. Parameter 'i' is the number of interval.
|
||||
|
||||
G4double G4PAIxSection::SumOverInterCerenkov( G4int i )
|
||||
{
|
||||
G4double x0,x1,y0,yy1,a,b,result ;
|
||||
|
||||
x0 = fSplineEnergy[i] ;
|
||||
x1 = fSplineEnergy[i+1] ;
|
||||
y0 = fdNdxCerenkov[i] ;
|
||||
yy1 = fdNdxCerenkov[i+1];
|
||||
|
||||
a = log10(yy1/y0)/log10(x1/x0) ;
|
||||
b = log10(y0) - a*log10(x0) ;
|
||||
b = pow(10.0,b) ;
|
||||
|
||||
a += 1.0 ;
|
||||
if(a == 0) result = b*log(x1/x0) ;
|
||||
else result = b*(pow(x1,a) - pow(x0,a))/a ;
|
||||
a += 1.0 ;
|
||||
|
||||
if( a == 0 ) fIntegralCerenkov[0] += b*log(x1/x0) ;
|
||||
else fIntegralCerenkov[0] += b*(pow(x1,a) - pow(x0,a))/a ;
|
||||
|
||||
return result ;
|
||||
|
||||
} // end of SumOverInterCerenkov
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculation the PAI Plasmon integral cross-section inside
|
||||
// of interval of continuous values of photo-ionisation Plasmon
|
||||
// cross-section. Parameter 'i' is the number of interval.
|
||||
|
||||
G4double G4PAIxSection::SumOverInterPlasmon( G4int i )
|
||||
{
|
||||
G4double x0,x1,y0,yy1,a,b,result ;
|
||||
|
||||
x0 = fSplineEnergy[i] ;
|
||||
x1 = fSplineEnergy[i+1] ;
|
||||
y0 = fdNdxPlasmon[i] ;
|
||||
yy1 = fdNdxPlasmon[i+1];
|
||||
|
||||
a = log10(yy1/y0)/log10(x1/x0) ;
|
||||
b = log10(y0) - a*log10(x0) ;
|
||||
b = pow(10.0,b) ;
|
||||
|
||||
a += 1.0 ;
|
||||
if(a == 0) result = b*log(x1/x0) ;
|
||||
else result = b*(pow(x1,a) - pow(x0,a))/a ;
|
||||
a += 1.0 ;
|
||||
|
||||
if( a == 0 ) fIntegralPlasmon[0] += b*log(x1/x0) ;
|
||||
else fIntegralPlasmon[0] += b*(pow(x1,a) - pow(x0,a))/a ;
|
||||
|
||||
return result ;
|
||||
|
||||
} // end of SumOverInterPlasmon
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Integration of PAI cross-section for the case of
|
||||
@@ -944,6 +1180,104 @@ G4double G4PAIxSection::SumOverBorder( G4int i ,
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Integration of Cerenkov cross-section for the case of
|
||||
// passing across border between intervals
|
||||
|
||||
G4double G4PAIxSection::SumOverBordCerenkov( G4int i ,
|
||||
G4double en0 )
|
||||
{
|
||||
G4double x0,x1,y0,yy1,a,b,e0,result ;
|
||||
|
||||
e0 = en0 ;
|
||||
x0 = fSplineEnergy[i] ;
|
||||
x1 = fSplineEnergy[i+1] ;
|
||||
y0 = fdNdxCerenkov[i] ;
|
||||
yy1 = fdNdxCerenkov[i+1] ;
|
||||
|
||||
a = log10(yy1/y0)/log10(x1/x0) ;
|
||||
b = log10(y0) - a*log10(x0) ;
|
||||
b = pow(10,b) ;
|
||||
|
||||
a += 1.0 ;
|
||||
if( a == 0 ) result = b*log(x0/e0) ;
|
||||
else result = b*(pow(x0,a) - pow(e0,a))/a ;
|
||||
a += 1.0 ;
|
||||
|
||||
if( a == 0 ) fIntegralCerenkov[0] += b*log(x0/e0) ;
|
||||
else fIntegralCerenkov[0] += b*(pow(x0,a) - pow(e0,a))/a ;
|
||||
|
||||
x0 = fSplineEnergy[i - 1] ;
|
||||
x1 = fSplineEnergy[i - 2] ;
|
||||
y0 = fdNdxCerenkov[i - 1] ;
|
||||
yy1 = fdNdxCerenkov[i - 2] ;
|
||||
|
||||
a = log10(yy1/y0)/log10(x1/x0) ;
|
||||
b = log10(y0) - a*log10(x0) ;
|
||||
b = pow(10,b) ;
|
||||
|
||||
a += 1.0 ;
|
||||
if( a == 0 ) result += b*log(e0/x0) ;
|
||||
else result += b*(pow(e0,a) - pow(x0,a))/a ;
|
||||
a += 1.0 ;
|
||||
|
||||
if( a == 0 ) fIntegralCerenkov[0] += b*log(e0/x0) ;
|
||||
else fIntegralCerenkov[0] += b*(pow(e0,a) - pow(x0,a))/a ;
|
||||
|
||||
return result ;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Integration of Plasmon cross-section for the case of
|
||||
// passing across border between intervals
|
||||
|
||||
G4double G4PAIxSection::SumOverBordPlasmon( G4int i ,
|
||||
G4double en0 )
|
||||
{
|
||||
G4double x0,x1,y0,yy1,a,b,e0,result ;
|
||||
|
||||
e0 = en0 ;
|
||||
x0 = fSplineEnergy[i] ;
|
||||
x1 = fSplineEnergy[i+1] ;
|
||||
y0 = fdNdxPlasmon[i] ;
|
||||
yy1 = fdNdxPlasmon[i+1] ;
|
||||
|
||||
a = log10(yy1/y0)/log10(x1/x0) ;
|
||||
b = log10(y0) - a*log10(x0) ;
|
||||
b = pow(10,b) ;
|
||||
|
||||
a += 1.0 ;
|
||||
if( a == 0 ) result = b*log(x0/e0) ;
|
||||
else result = b*(pow(x0,a) - pow(e0,a))/a ;
|
||||
a += 1.0 ;
|
||||
|
||||
if( a == 0 ) fIntegralPlasmon[0] += b*log(x0/e0) ;
|
||||
else fIntegralPlasmon[0] += b*(pow(x0,a) - pow(e0,a))/a ;
|
||||
|
||||
x0 = fSplineEnergy[i - 1] ;
|
||||
x1 = fSplineEnergy[i - 2] ;
|
||||
y0 = fdNdxPlasmon[i - 1] ;
|
||||
yy1 = fdNdxPlasmon[i - 2] ;
|
||||
|
||||
a = log10(yy1/y0)/log10(x1/x0) ;
|
||||
b = log10(y0) - a*log10(x0) ;
|
||||
b = pow(10,b) ;
|
||||
|
||||
a += 1.0 ;
|
||||
if( a == 0 ) result += b*log(e0/x0) ;
|
||||
else result += b*(pow(e0,a) - pow(x0,a))/a ;
|
||||
a += 1.0 ;
|
||||
|
||||
if( a == 0 ) fIntegralPlasmon[0] += b*log(e0/x0) ;
|
||||
else fIntegralPlasmon[0] += b*(pow(e0,a) - pow(x0,a))/a ;
|
||||
|
||||
return result ;
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
@@ -980,6 +1314,78 @@ G4double G4PAIxSection::GetStepEnergyLoss( G4double step )
|
||||
return loss ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4PAIxSection::GetStepCerenkovLoss( G4double step )
|
||||
{
|
||||
G4int iTransfer ;
|
||||
G4long numOfCollisions ;
|
||||
G4double loss = 0.0 ;
|
||||
G4double meanNumber, position ;
|
||||
|
||||
// G4cout<<" G4PAIxSection::GetStepCreLosnkovs "<<G4endl ;
|
||||
|
||||
|
||||
|
||||
meanNumber = fIntegralCerenkov[1]*step ;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position = fIntegralCerenkov[1]*G4UniformRand() ;
|
||||
|
||||
for( iTransfer=1 ; iTransfer<=fSplineNumber ; iTransfer++ )
|
||||
{
|
||||
if( position >= fIntegralCerenkov[iTransfer] ) break ;
|
||||
}
|
||||
loss += fSplineEnergy[iTransfer] ;
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
// G4cout<<"PAI Cerenkov loss = "<<loss/keV<<" keV"<<G4endl ;
|
||||
|
||||
return loss ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4PAIxSection::GetStepPlasmonLoss( G4double step )
|
||||
{
|
||||
G4int iTransfer ;
|
||||
G4long numOfCollisions ;
|
||||
G4double loss = 0.0 ;
|
||||
G4double meanNumber, position ;
|
||||
|
||||
// G4cout<<" G4PAIxSection::GetStepCreLosnkovs "<<G4endl ;
|
||||
|
||||
|
||||
|
||||
meanNumber = fIntegralPlasmon[1]*step ;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position = fIntegralPlasmon[1]*G4UniformRand() ;
|
||||
|
||||
for( iTransfer=1 ; iTransfer<=fSplineNumber ; iTransfer++ )
|
||||
{
|
||||
if( position >= fIntegralPlasmon[iTransfer] ) break ;
|
||||
}
|
||||
loss += fSplineEnergy[iTransfer] ;
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
// G4cout<<"PAI Plasmon loss = "<<loss/keV<<" keV"<<G4endl ;
|
||||
|
||||
return loss ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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......
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4PolarizedComptonScattering.cc,v 1.8 2001/09/21 09:50:54 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4PolarizedComptonScattering.cc,v 1.9 2002/04/09 17:34:43 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//
|
||||
//---------- G4PolarizedComptonScattering physics process ----------------------
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4SynchrotronRadiation.cc,v 1.6 2001/10/24 16:27:45 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4SynchrotronRadiation.cc,v 1.7 2002/04/09 17:34:43 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VPAIenergyLoss.cc,v 1.5 2001/10/29 16:23:41 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4VPAIenergyLoss.cc,v 1.6 2002/04/09 17:34:43 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VeEnergyLoss.cc,v 1.22 2001/11/12 11:20:51 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4VeEnergyLoss.cc,v 1.25 2002/04/09 17:34:43 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -40,6 +40,8 @@
|
||||
// 17-09-01, migration of Materials to pure STL (mma)
|
||||
// 29-10-01 all static functions no more inlined (mma)
|
||||
// 08-11-01 Charge,lastCharge not data members, L.Urban
|
||||
// 06-02-02 bug fixed in MinDeltaCutInRange computation, L.Urban
|
||||
// 26-02-02 bug fixed in TouchebleHandle definition, V.Ivanchenko
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -380,7 +382,7 @@ void G4VeEnergyLoss::BuildDEDXTable(
|
||||
// set default MinDeltaCutInRange to rcut/10.
|
||||
if(!setMinDeltaCutInRange )
|
||||
MinDeltaCutInRange = (G4Electron::Electron()
|
||||
->GetEnergyCuts())[mat]/10.;
|
||||
->GetLengthCuts())[mat]/10.;
|
||||
LowerLimitForced[mat] = false ;
|
||||
|
||||
MinDeltaEnergy[mat] = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
@@ -395,7 +397,7 @@ void G4VeEnergyLoss::BuildDEDXTable(
|
||||
|
||||
// if((subSecFlag) && (&aParticleType==G4Electron::Electron()))
|
||||
// {
|
||||
// G4cout << G4std::setw(20) << (*theMaterialTable)(mat)->GetName()
|
||||
// G4cout << G4std::setw(20) << (*theMaterialTable)[mat]->GetName()
|
||||
// << G4std::setw(15) << MinDeltaEnergy[mat]/keV ;
|
||||
// if(LowerLimitForced[mat])
|
||||
// G4cout << " lower limit forced." << G4endl;
|
||||
@@ -646,7 +648,7 @@ G4VParticleChange* G4VeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
|
||||
G4Track* deltaTrack =
|
||||
new G4Track(theDelta,DeltaTime,DeltaPosition);
|
||||
deltaTrack->SetTouchableHandle(stepData.GetPostStepPoint()
|
||||
deltaTrack->SetTouchableHandle(stepData.GetPreStepPoint()
|
||||
->GetTouchableHandle());
|
||||
deltaTrack->SetParentID(trackData.GetTrackID()) ;
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VhEnergyLoss.cc,v 1.29 2001/11/12 11:20:51 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4VhEnergyLoss.cc,v 1.35 2002/06/10 15:38:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -48,6 +48,10 @@
|
||||
// 29-10-01 all static functions no more inlined (mma)
|
||||
// 08-11-01 BuildDEDXTable not static,Charge local variable, L.Urban
|
||||
// 09-11-01 cosmetics; 80 columns everywhere (mma)
|
||||
// 06-02-02 bug fixed in MinDeltaCutInRange computation, L.Urban
|
||||
// 26-02-02 bug fixed in TouchebleHandle definition, V.Ivanchenko
|
||||
// 29-05-02 bug fixed in N of subcutoff delta, V.Ivanchenko
|
||||
// 10-06-02 bug fixed for stopping hadrons, V.Ivanchenko
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -57,6 +61,7 @@
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -288,7 +293,6 @@ void G4VhEnergyLoss::BuildDEDXTable(
|
||||
// reset counter to zero
|
||||
if(Charge >0.) CounterOfpProcess=0;
|
||||
else CounterOfpbarProcess=0;
|
||||
ParticleMass = aParticleType.GetPDGMass();
|
||||
|
||||
if(Charge > 0.)
|
||||
{
|
||||
@@ -391,7 +395,7 @@ void G4VhEnergyLoss::BuildDEDXTable(
|
||||
{
|
||||
// create array for the min. delta cuts in kinetic energy
|
||||
if(!setMinDeltaCutInRange)
|
||||
MinDeltaCutInRange = (G4Electron::Electron()->GetEnergyCuts())[mat]/10.;
|
||||
MinDeltaCutInRange = (G4Electron::Electron()->GetLengthCuts())[mat]/10.;
|
||||
MinDeltaEnergy[mat] = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4Electron::Electron(),MinDeltaCutInRange,
|
||||
(*theMaterialTable)[mat]);
|
||||
@@ -412,9 +416,9 @@ G4double G4VhEnergyLoss::GetConstraints(const G4DynamicParticle *aParticle,
|
||||
// it calculates dEdx and the range as well....
|
||||
|
||||
G4double KineticEnergy = aParticle->GetKineticEnergy();
|
||||
G4double massratio=proton_mass_c2/(aParticle->GetDefinition()->GetPDGMass());
|
||||
G4double massratio=proton_mass_c2/(aParticle->GetMass());
|
||||
G4double Tscaled = KineticEnergy*massratio;
|
||||
G4double Charge = aParticle->GetDefinition()->GetPDGCharge()/eplus;
|
||||
G4double Charge = aParticle->GetCharge()/eplus;
|
||||
G4double ChargeSquare = Charge*Charge;
|
||||
|
||||
if (Charge>0.)
|
||||
@@ -461,8 +465,9 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
G4int index = aMaterial->GetIndex();
|
||||
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
|
||||
G4double Charge = aParticle->GetDefinition()->GetPDGCharge()/eplus;
|
||||
G4double Charge = aParticle->GetCharge()/eplus;
|
||||
G4double ChargeSquare = Charge*Charge;
|
||||
G4double mass=aParticle->GetMass();
|
||||
|
||||
// get the actual (true) Step length from stepData
|
||||
G4double Step = stepData.GetStepLength();
|
||||
@@ -479,8 +484,7 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
{
|
||||
if (Step>linLossLimit*fRangeNow)
|
||||
{
|
||||
G4double massratio = proton_mass_c2/
|
||||
aParticle->GetDefinition()->GetPDGMass();
|
||||
G4double massratio = proton_mass_c2/mass;
|
||||
G4double rscaled = fRangeNow*massratio*ChargeSquare;
|
||||
G4double sscaled = Step *massratio*ChargeSquare;
|
||||
|
||||
@@ -520,7 +524,6 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
|
||||
G4double MinDeltaEnergyNow = MinDeltaEnergy[index] ;
|
||||
G4double Tc=(G4Electron::Electron()->GetEnergyCuts())[index];
|
||||
G4double mass=aParticle->GetDefinition()->GetPDGMass();
|
||||
G4double w=mass+electron_mass_c2 ;
|
||||
G4double ww=2.*mass-MinDeltaEnergyNow ;
|
||||
G4double TmintoProduceDelta=0.5*(sqrt(ww*ww+2.*w*w*MinDeltaEnergyNow/
|
||||
@@ -597,7 +600,7 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
G4double deldedx=cN*aMaterial->GetDensity()*
|
||||
((E+mass)*(E+mass)*log(Tc/T0)/(E*(E+mass)));
|
||||
G4double delToverTc=1.-T0/Tc ;
|
||||
G4double N = G4int(deldedx*fragment*delToverTc/(T0*log(Tc/T0))+0.5);
|
||||
G4int N = G4int(deldedx*fragment*delToverTc/(T0*log(Tc/T0))+0.5);
|
||||
if(N > Ndeltamax) N = Ndeltamax;
|
||||
|
||||
G4ThreeVector ParticleDirection = aParticle->GetMomentumDirection();
|
||||
@@ -675,7 +678,7 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
|
||||
G4Track* deltaTrack =
|
||||
new G4Track(theDelta,DeltaTime,DeltaPosition);
|
||||
deltaTrack->SetTouchableHandle(stepData.GetPostStepPoint()
|
||||
deltaTrack->SetTouchableHandle(stepData.GetPreStepPoint()
|
||||
->GetTouchableHandle());
|
||||
|
||||
deltaTrack->SetParentID(trackData.GetTrackID());
|
||||
@@ -711,7 +714,7 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
if (finalT <= 0.)
|
||||
{
|
||||
finalT = 0.;
|
||||
if(aParticle->GetDefinition()->GetParticleName() == "proton")
|
||||
if(!aParticle->GetDefinition()->GetProcessManager()->GetAtRestProcessVector()->size())
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eBremsstrahlung.cc,v 1.24 2001/11/09 13:59:46 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4eBremsstrahlung.cc,v 1.25 2002/04/09 17:34:44 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//
|
||||
// ------------ G4eBremsstrahlung physics process --------
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eIonisation.cc,v 1.22 2001/11/09 13:59:47 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4eIonisation.cc,v 1.25 2002/04/09 17:34:44 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//--------------- G4eIonisation physics process --------------------------------
|
||||
// by Laszlo Urban, 20 March 1997
|
||||
@@ -40,6 +40,7 @@
|
||||
// 21-09-01 completion of RetrievePhysicsTable() (mma)
|
||||
// 29-10-01 all static functions no more inlined (mma)
|
||||
// 07-11-01 particleMass and Charge become local variables
|
||||
// 26-03-02 change access to cuts in BuildLossTables (V.Ivanchenko)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -59,7 +60,7 @@ G4int G4eIonisation::NbinLambda = 100;
|
||||
G4eIonisation::G4eIonisation(const G4String& processName)
|
||||
: G4VeEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL)
|
||||
{ }
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -143,9 +144,22 @@ void G4eIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
|
||||
if (theLossTable) {theLossTable->clearAndDestroy(); delete theLossTable;}
|
||||
theLossTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
|
||||
// get electron cuts in kinetic energy
|
||||
// The electron cuts needed in the case of the positron , too!
|
||||
// This is the reason why SetCut has to be called for electron first !!
|
||||
|
||||
if((G4Electron::Electron()->GetEnergyCuts() == 0) &&
|
||||
(&aParticleType == G4Positron::Positron()))
|
||||
{
|
||||
G4cout << " The ELECTRON energy cuts needed to compute energy loss"
|
||||
" and mean free path; and for POSITRON, too. " << G4endl;
|
||||
G4Exception(" Call SetCut for e- first !!");
|
||||
}
|
||||
|
||||
// get DeltaCut in energy
|
||||
G4double* DeltaCutInKineticEnergy = aParticleType.GetEnergyCuts();
|
||||
G4double* DeltaCutInKineticEnergy = G4Electron::Electron()->GetEnergyCuts();
|
||||
|
||||
// loop for materials
|
||||
//
|
||||
@@ -166,6 +180,12 @@ void G4eIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
aVector->GetLowEdgeEnergy(i),
|
||||
material,
|
||||
DeltaThreshold);
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Material= " << material->GetName()
|
||||
<< " E(MeV)= " << aVector->GetLowEdgeEnergy(i)/MeV
|
||||
<< " dEdx(MeV/mm)= " << dEdx*mm/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
aVector->PutValue(i,dEdx);
|
||||
}
|
||||
theLossTable->insert(aVector);
|
||||
@@ -201,7 +221,7 @@ void G4eIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
G4Exception(" Call SetCut for e- first !!");
|
||||
}
|
||||
|
||||
G4double* DeltaCutInKineticEnergy = G4Electron::Electron()->GetEnergyCuts() ;
|
||||
G4double* DeltaCutInKineticEnergy = G4Electron::Electron()->GetEnergyCuts();
|
||||
|
||||
// loop for materials
|
||||
|
||||
@@ -223,7 +243,7 @@ void G4eIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
// it will be used in ComputeCrossSectionPerAtom
|
||||
// (--> it will be the same for all the elements in this material )
|
||||
G4double DeltaThreshold = DeltaCutInKineticEnergy[J];
|
||||
|
||||
|
||||
for (G4int i = 0 ; i < NbinLambda ; i++)
|
||||
{
|
||||
G4double LowEdgeEnergy = aVector->GetLowEdgeEnergy(i);
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eplusAnnihilation.cc,v 1.13 2001/10/01 15:00:29 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4eplusAnnihilation.cc,v 1.14 2002/04/09 17:34:44 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4hIonisation.cc,v 1.23 2001/11/09 13:59:47 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-04-00 $
|
||||
// $Id: G4hIonisation.cc,v 1.30 2002/06/10 15:50:46 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-04-01 $
|
||||
//
|
||||
//---------------- G4hIonisation physics process -------------------------------
|
||||
// by Laszlo Urban, 30 May 1997
|
||||
@@ -46,6 +46,9 @@
|
||||
// 25-09-01 completion of RetrievePhysicsTable() (mma)
|
||||
// 29-10-01 all static functions no more inlined
|
||||
// 08-11-01 Charge renamed zparticle; added to the dedx
|
||||
// 27-03-02 Bug fix in scaling of lambda table (V.Ivanchenko)
|
||||
// 09-04-02 Update calculation of tables for GenericIons (V.Ivanchenko)
|
||||
// 10-06-02 bug fixed for stopping hadrons, V.Ivanchenko
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -53,7 +56,9 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4hIonisation.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -112,10 +117,51 @@ G4int G4hIonisation::GetNbinLambda()
|
||||
void G4hIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
// just call BuildLossTable+BuildLambdaTable
|
||||
{
|
||||
|
||||
if(verboseLevel > 0) {
|
||||
G4cout << "G4hIonisation::BuildPhysicsTable for "
|
||||
<< aParticleType.GetParticleName()
|
||||
<< " mass(MeV)= " << aParticleType.GetPDGMass()/MeV
|
||||
<< " charge= " << aParticleType.GetPDGCharge()/eplus
|
||||
<< " type= " << aParticleType.GetParticleType()
|
||||
<< G4endl;
|
||||
|
||||
if(verboseLevel > 1) {
|
||||
G4ProcessVector* pv = aParticleType.GetProcessManager()->GetProcessList();
|
||||
G4cout << " 0: " << (*pv)[0]->GetProcessName() << " " << (*pv)[0]
|
||||
<< " 1: " << (*pv)[1]->GetProcessName() << " " << (*pv)[1]
|
||||
// << " 2: " << (*pv)[2]->GetProcessName() << " " << (*pv)[2]
|
||||
<< G4endl;
|
||||
G4cout << " MFPtable= " << theMeanFreePathTable
|
||||
<< " DEDXtable= " << theDEDXpTable
|
||||
<< " iniMass= " << initialMass
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(aParticleType.GetParticleType() == "nucleus" &&
|
||||
aParticleType.GetParticleName() != "GenericIon" &&
|
||||
theMeanFreePathTable) {
|
||||
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
theDEDXpTable,
|
||||
theRangepTable,
|
||||
theInverseRangepTable,
|
||||
theLabTimepTable,
|
||||
theProperTimepTable,
|
||||
LowestKineticEnergy, HighestKineticEnergy,
|
||||
proton_mass_c2/aParticleType.GetPDGMass(),
|
||||
TotBin);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// get bining from EnergyLoss
|
||||
LowestKineticEnergy = GetLowerBoundEloss();
|
||||
HighestKineticEnergy = GetUpperBoundEloss();
|
||||
TotBin = GetNbinEloss();
|
||||
const G4ParticleDefinition* theProton = G4Proton::Proton();
|
||||
|
||||
G4double* ElectronCutInRange = G4Electron::Electron()->GetLengthCuts();
|
||||
|
||||
@@ -124,7 +170,7 @@ void G4hIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
if( !EqualCutVectors(ptableElectronCutInRange,ElectronCutInRange)
|
||||
|| (theDEDXpTable == NULL))
|
||||
{
|
||||
BuildLossTable(aParticleType);
|
||||
BuildLossTable(*theProton);
|
||||
RecorderOfpProcess[CounterOfpProcess] = theLossTable;
|
||||
CounterOfpProcess++;
|
||||
}
|
||||
@@ -134,7 +180,7 @@ void G4hIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
if( !EqualCutVectors(pbartableElectronCutInRange,ElectronCutInRange)
|
||||
|| (theDEDXpbarTable == NULL))
|
||||
{
|
||||
BuildLossTable(aParticleType) ;
|
||||
BuildLossTable(*(G4AntiProton::AntiProton())) ;
|
||||
RecorderOfpbarProcess[CounterOfpbarProcess] = theLossTable;
|
||||
CounterOfpbarProcess++;
|
||||
}
|
||||
@@ -144,7 +190,15 @@ void G4hIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
|
||||
BuildDEDXTable(aParticleType);
|
||||
|
||||
if (&aParticleType == G4Proton::Proton()) PrintInfoDefinition();
|
||||
if(2 < verboseLevel) {
|
||||
G4cout << "MeanFreePathTable is built for "
|
||||
<< aParticleType.GetParticleName() << G4endl;
|
||||
G4cout << (*theMeanFreePathTable) << G4endl;
|
||||
}
|
||||
|
||||
|
||||
if (&aParticleType == theProton) PrintInfoDefinition();
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -198,6 +252,12 @@ void G4hIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build mean free path tables for the delta ray production process
|
||||
// tables are built for MATERIALS
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4hIonisation::BuildLambdaTable() for process "
|
||||
<< GetProcessName() << " and particle "
|
||||
<< aParticleType.GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
//create table
|
||||
//
|
||||
@@ -211,7 +271,7 @@ void G4hIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
theMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
// get electron cut in kinetic energy
|
||||
G4double* DeltaCutInKinEnergy = (G4Electron::Electron())->GetEnergyCuts() ;
|
||||
G4double* DeltaCutInKinEnergy = (G4Electron::Electron())->GetEnergyCuts();
|
||||
|
||||
// loop for materials
|
||||
|
||||
@@ -232,6 +292,16 @@ void G4hIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
// it will be used in ComputeCrossSectionPerAtom
|
||||
// ( --> it will be the same for all the elements in this material)
|
||||
G4double DeltaThreshold =G4std::max(DeltaCutInKinEnergy[J],Tmincut);
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### For material " << material->GetName()
|
||||
<< " Tcut(MeV)= " << DeltaThreshold/MeV
|
||||
<< " Tmin(MeV)= " << LowerBoundLambda/MeV
|
||||
<< " Tmax(MeV)= " << UpperBoundLambda/MeV
|
||||
<< " nbins= " << NbinLambda
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
for ( G4int i = 0 ; i < NbinLambda ; i++ )
|
||||
{
|
||||
@@ -265,9 +335,7 @@ G4double G4hIonisation::ComputeRestrictedMeandEdx (
|
||||
// calculate the dE/dx due to the ionization process (Geant4 internal units)
|
||||
// Bethe-Bloch formula
|
||||
//
|
||||
G4double particleMass = aParticleType.GetPDGMass();
|
||||
G4double particleZ = aParticleType.GetPDGCharge()/eplus;
|
||||
G4double zsquare = particleZ*particleZ;
|
||||
G4double particleMass = proton_mass_c2;
|
||||
|
||||
G4double ElectronDensity = material->GetElectronDensity();
|
||||
G4double Eexc = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
@@ -319,7 +387,7 @@ G4double G4hIonisation::ComputeRestrictedMeandEdx (
|
||||
|
||||
// now you can compute the total ionization loss
|
||||
dEdx -= (delta + sh);
|
||||
dEdx *= twopi_mc2_rcl2*ElectronDensity*zsquare/beta2;
|
||||
dEdx *= twopi_mc2_rcl2*ElectronDensity/beta2;
|
||||
if (dEdx < 0.) dEdx = 0.;
|
||||
}
|
||||
//
|
||||
@@ -353,7 +421,7 @@ G4double G4hIonisation::ComputeRestrictedMeandEdx (
|
||||
if (aParticleType.GetPDGSpin() == 0.5)
|
||||
deltaloss += 0.25*(Tmax-DeltaThreshold)*(Tmax-DeltaThreshold)/
|
||||
(KineticEnergy*KineticEnergy+proton_mass_c2*proton_mass_c2);
|
||||
deltaloss *= twopi_mc2_rcl2*ElectronDensity*zsquare/beta2;
|
||||
deltaloss *= twopi_mc2_rcl2*ElectronDensity/beta2;
|
||||
}
|
||||
dEdx -= deltaloss;
|
||||
if (dEdx < 0.) dEdx = 0.;
|
||||
@@ -374,9 +442,8 @@ G4double G4hIonisation::ComputeCrossSectionPerAtom(
|
||||
//
|
||||
// nb: cross section formula is OK for spin=0 and 1/2 only !
|
||||
|
||||
G4double particleMass = aParticleType.GetPDGMass();
|
||||
G4double particleZ = aParticleType.GetPDGCharge()/eplus;
|
||||
G4double zparticle2 = particleZ*particleZ;
|
||||
initialMass = aParticleType.GetPDGMass();
|
||||
G4double particleMass = initialMass;
|
||||
|
||||
G4double TotalEnergy = KineticEnergy + particleMass;
|
||||
|
||||
@@ -405,7 +472,7 @@ G4double G4hIonisation::ComputeCrossSectionPerAtom(
|
||||
betasquare /
|
||||
(MaxKineticEnergyTransfer * DeltaThreshold)) / 3.0;
|
||||
|
||||
TotalCrossSection *= twopi_mc2_rcl2*AtomicNumber*zparticle2/betasquare;
|
||||
TotalCrossSection *= twopi_mc2_rcl2*AtomicNumber/betasquare;
|
||||
}
|
||||
return TotalCrossSection;
|
||||
}
|
||||
@@ -420,7 +487,7 @@ G4VParticleChange* G4hIonisation::PostStepDoIt(const G4Track& trackData,
|
||||
G4Material* aMaterial = trackData.GetMaterial();
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
|
||||
|
||||
G4double particleMass = aParticle->GetDefinition()->GetPDGMass();
|
||||
G4double particleMass = aParticle->GetMass();
|
||||
G4double KineticEnergy = aParticle->GetKineticEnergy();
|
||||
G4double TotalEnergy = KineticEnergy + particleMass;
|
||||
G4double Psquare = KineticEnergy*(TotalEnergy+particleMass);
|
||||
@@ -511,7 +578,7 @@ G4VParticleChange* G4hIonisation::PostStepDoIt(const G4Track& trackData,
|
||||
{
|
||||
Edep = finalKineticEnergy;
|
||||
finalKineticEnergy = 0.;
|
||||
if (aParticle->GetDefinition()->GetParticleName() == "proton")
|
||||
if (!aParticle->GetDefinition()->GetProcessManager()->GetAtRestProcessVector()->size())
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user