Import Geant4 2.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 15:42:07 +02:00
parent 103bda00c8
commit e7d7193284
3106 changed files with 171117 additions and 90550 deletions
@@ -5,9 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.21 2000/02/18 12:34:30 lefebure Exp $
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.21 2000/02/18 12:34:30 lefebure Exp $
// GEANT4 tag $Name: geant4-01-01 $
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.25 2000/06/22 02:38:12 pia Exp $
// GEANT4 tag $Name: geant4-02-00 $
//
//
// --------------------------------------------------------------
@@ -20,6 +19,9 @@
// by Alessandra Forti, March 1999
//
// **************************************************************
//
// 18.04.2000 V.L.
// - First implementation of continuous energy loss.
// 17.02.2000 Veronique Lefebure
// - correct bug : the gamma energy was not deposited when the gamma was
// not produced when its energy was < CutForLowEnergySecondaryPhotons
@@ -31,12 +33,10 @@
// Added map of the elements A. Forti
// --------------------------------------------------------------
// This Class Header
#include "G4LowEnergyBremsstrahlung.hh"
// Collaborating Class Headers
#include "G4EnergyLossTables.hh"
#include "G4UnitsTable.hh"
#include "G4Electron.hh"
#include "G4Gamma.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -44,20 +44,18 @@
// constructor
G4LowEnergyBremsstrahlung::G4LowEnergyBremsstrahlung(const G4String& processName)
: G4eEnergyLoss(processName), // initialization
: G4eLowEnergyLoss(processName), // initialization
theCrossSectionTable(0),
theMeanFreePathTable(0),
ATable(0),
BTable(0),
ZNumVec(0),
LowestKineticEnergy (250.*eV),
HighestKineticEnergy(100.*GeV),
lowEnergyCut(0.1*eV),
CutForLowEnergySecondaryPhotons(0.),
TotBin(200)
CutForLowEnergySecondaryPhotons(0.)
{
LowestKineticEnergy = GetLowerBoundEloss();
HighestKineticEnergy = GetUpperBoundEloss();
TotBin = GetNbinEloss();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -97,12 +95,6 @@ G4LowEnergyBremsstrahlung::~G4LowEnergyBremsstrahlung()
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4LowEnergyBremsstrahlung::SetPhysicsTableBining(G4double lowE, G4double highE, G4int nBins)
{
LowestKineticEnergy = lowE; HighestKineticEnergy = highE; TotBin = nBins;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// SET CUT FOR LOW ENERGY SECONDARY PHOTONS A. FORTI
@@ -115,12 +107,20 @@ void G4LowEnergyBremsstrahlung::SetCutForLowEnSecPhotons(G4double cut){
void G4LowEnergyBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
{
BuildLossTable(aParticleType) ;
BuildZVec();
// energy sampling formula coefficient
BuildATable();
BuildBTable();
BuildCrossSectionTable() ;
BuildLossTable(aParticleType) ;
if (&aParticleType==G4Electron::Electron()){
RecorderOfElectronProcess[CounterOfElectronProcess] = (*this).theLossTable ;
CounterOfElectronProcess++;
PrintInfoDefinition();
}
else{
@@ -128,16 +128,13 @@ void G4LowEnergyBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aP
CounterOfPositronProcess++;
}
BuildZVec();
BuildCrossSectionTable() ;
BuildMeanFreePathTable() ;
BuildDEDXTable(aParticleType) ;
BuildDEDXTable (aParticleType) ;
// energy sampling formula coefficient
BuildATable();
BuildBTable();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -225,323 +222,58 @@ void G4LowEnergyBremsstrahlung::BuildZVec(){
}
}
// Build table for energy loss due to soft brems
// tables are built for *MATERIALS* already in the standard processes
// to be changed when the new energy loss will be calculated.
//
// // METHOD BELOW FROM STANDARD E_M PROCESSES LEFT BUT AT THE MOMENT NOT USED
//
void G4LowEnergyBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType)
{
G4double KineticEnergy,TotalEnergy,bremloss,Z,x,
losslim,loss,rate,natom,Cut;
const G4double MinKinEnergy = 1.*keV;
const G4double MinCut = 1.*keV;
const G4double Thigh = 100.*GeV;
const G4double Cuthigh = 50.*GeV;
const G4double Factorhigh = 36./(1450.*GeV);
const G4double coef1 = -0.5, coef2 = 2./9.;
ParticleMass = aParticleType.GetPDGMass() ;
G4double* GammaCutInKineticEnergy = G4Gamma::Gamma()->GetEnergyCuts();
// Build table for energy loss due to soft brems
// the tables are built for *MATERIALS*
// create table
if (theLossTable) {
theLossTable->clearAndDestroy();
delete theLossTable;
}
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length() ;
if (theLossTable) { theLossTable->clearAndDestroy();
delete theLossTable;
}
const G4int numOfMaterials = theMaterialTable->length();
theLossTable = new G4PhysicsTable(numOfMaterials);
// loop for materials
for (G4int J=0; J<numOfMaterials; J++)
{
// create physics vector and fill it
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
LowestKineticEnergy,HighestKineticEnergy,TotBin);
// get elements in the material
const G4Material* material = (*theMaterialTable)[J];
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomicNumDensityVector = material->GetAtomicNumDensityVector();
const G4int NumberOfElements = material->GetNumberOfElements();
// loop for the kinetic energy values
for (G4int i=0; i<TotBin; i++){
KineticEnergy = aVector->GetLowEdgeEnergy(i) ;
TotalEnergy = KineticEnergy+ParticleMass ;
Cut = GammaCutInKineticEnergy[J] ;
if (Cut < MinCut) Cut = MinCut ;
if (Cut > KineticEnergy) Cut = KineticEnergy ;
bremloss = 0.;
if (KineticEnergy>MinKinEnergy)
{
if (Cut > KineticEnergy) Cut = KineticEnergy ;
// loop for elements in the material
for (G4int iel=0; iel<NumberOfElements; iel++)
{
Z=(*theElementVector)(iel)->GetZ();
natom = theAtomicNumDensityVector[iel] ;
if (KineticEnergy <= Thigh)
{
//loss for MinKineticEnergy<KineticEnergy<=100 GeV
x=log(TotalEnergy/ParticleMass);
loss = ComputeBremLoss(Z,natom,KineticEnergy,Cut,x) ;
if (&aParticleType==G4Positron::Positron())
loss *= ComputePositronCorrFactorLoss(Z,KineticEnergy,Cut) ;
}
else
{
// extrapolation for KineticEnergy>100 GeV
x=log(Thigh/ParticleMass) ;
if (Cut<Thigh)
{
losslim = ComputeBremLoss(Z,natom,Thigh,Cut,x) ;
if (&aParticleType==G4Positron::Positron())
loss *= ComputePositronCorrFactorLoss(Z,Thigh,Cut) ;
rate = Cut/TotalEnergy ;
loss = losslim*(1.+coef1*rate+coef2*rate*rate) ;
rate = Cut/Thigh ;
loss /= (1.+coef1*rate+coef2*rate*rate) ;
}
else
{
losslim = ComputeBremLoss(Z,natom,Thigh,Cuthigh,x) ;
if (&aParticleType==G4Positron::Positron())
loss *= ComputePositronCorrFactorLoss(Z,Thigh,Cuthigh) ;
rate = Cut/TotalEnergy ;
loss = losslim*(1.+coef1*rate+coef2*rate*rate) ;
loss *= Factorhigh*Cut ;
}
}
bremloss += natom*loss;
}
}
// now compute the correction due to the LPM effect
const G4double MigdalConstant = classic_electr_radius*
electron_Compton_length*
electron_Compton_length/pi ;
const G4double LPMconstant = fine_structure_const*electron_mass_c2*
electron_mass_c2/(8.*pi*hbarc) ;
const G4double kmin = 1.*eV ;
const G4double klim = 1.*keV ;
G4double LPMEnergy = LPMconstant*(material->GetRadlen()) ;
G4double TotalEnergysquare = TotalEnergy*TotalEnergy ;
G4double LPMGammaEnergyLimit = TotalEnergysquare/LPMEnergy ;
if(LPMGammaEnergyLimit > klim)
{
G4double kmax = G4std::min(Cut,LPMGammaEnergyLimit) ;
G4double floss = 0. ;
G4int nmax = 1000 ;
G4int nn ;
G4double vmin=log(kmin);
G4double vmax=log(Cut) ;
nn = int(nmax*(vmax-vmin)/(log(HighestKineticEnergy)-vmin)) ;
G4double u,uu,s2lpm,sp,fac,c,v,dv,w ;
dv = (vmax-vmin)/nn ;
v = vmin-dv ;
for(G4int n=0; n<=nn; n++)
{
v += dv ;
u = exp(v) ;
uu = u*u ;
if(u<=kmax)
{
s2lpm=LPMEnergy*u/TotalEnergysquare ;
sp=uu/(uu+MigdalConstant*TotalEnergysquare*
(material->GetElectronDensity())) ;
w=s2lpm*(1.+1./sp) ;
fac=0.5*(sqrt(w*w+4.*s2lpm)-w)/sp;
if(fac>1.)
fac=1. ;
}
else
{
fac=1. ;
}
fac *= uu*u ;
if((n==0)||(n==nn))
c=0.5;
else
c=1.;
fac *= c ;
floss += fac ;
}
floss *=dv*3./(Cut*Cut*Cut-kmin*kmin*kmin) ;
if(floss > 1.) floss = 1. ;
// correct the loss
bremloss *= floss ;
}
if(bremloss < 0.) bremloss = 0. ;
aVector->PutValue(i,bremloss);
}
// loop for materials
for (G4int J=0; J<numOfMaterials; J++){
// create physics vector and fill it
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(LowestKineticEnergy,
HighestKineticEnergy,
TotBin);
// get material parameters needed for the energy loss calculation
const G4Material* material= (*theMaterialTable)[J];
theLossTable->insert(aVector);
const G4double Tcut = G4Gamma::Gamma()->GetCutsInEnergy()[material->GetIndex()] ;
G4cout<<"*** LE Bremsstrahlung using Gamma Tcut = "<<Tcut
<<" for material "<< material->GetName()
<<G4endl;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4int NumberOfElements = material->GetNumberOfElements() ;
const G4double* theAtomicNumDensityVector = material->GetAtomicNumDensityVector();
// now comes the loop for the kinetic energy values
for (G4int i = 0 ; i < TotBin ; i++){
const G4double LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
G4double ionloss = 0.;
// loop for elements in the material
for (G4int iel=0; iel<NumberOfElements; iel++ ){
const G4double Z = (*theElementVector)(iel)->GetZ();
ionloss += GetEnergyLossWithCut(Z,LowEdgeEnergy,Tcut)*
theAtomicNumDensityVector[iel] ;
}
aVector->PutValue(i,ionloss) ;
}
theLossTable->insert(aVector);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE LEFT BUT AT THE MOMENT NOT USED
//
G4double G4LowEnergyBremsstrahlung::ComputeXYPolynomial(G4double x, G4double y,
G4int xSize, G4int ySize,
const G4double coeff[])
{
// Computes the polynomial (1 y y^2 ...) * matrix * (1 x x^2 ...) .
// xSize and ySize are the dimensions of the matrix,
// coeff containts the elements, stored row-wise.
G4double* a= new G4double[xSize];
G4int i, j;
for (i=0; i<xSize; i++) a[i]= 0.0;
G4int index= 0; G4double yy= 1.0;
for (j=0; j<ySize; j++)
{ for (i=0; i<xSize; i++) a[i]+= coeff[index++]*yy;
yy*= y;
}
G4double r= a[0]; G4double xx= x;
for (i=1; i<xSize; i++) { r+= a[i]*xx; xx*= x;}
delete[] a;
return r;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE LEFT BUT AT THE MOMENT NOT USED
//
G4double G4LowEnergyBremsstrahlung::ComputeBremLoss(G4double Z,G4double natom,
G4double T,G4double Cut,G4double x)
// compute loss due to soft brems
// 'Migdal' version , this is the default in GEANT3
{
const G4double beta=0.99,ksi=2.51,ve=0.00004 ;
const G4double corrfac = classic_electr_radius*electron_Compton_length*electron_Compton_length/pi ;
static const G4double
CMbarn[]= {
-0.960613e-1, 0.631029e-1,-0.142819e-1, 0.150437e-2,-0.733286e-4, 0.131404e-5,
0.859343e-1,-0.529023e-1, 0.131899e-1,-0.159201e-2, 0.926958e-4,-0.208439e-5,
-0.684096e+1, 0.370364e+1,-0.786752e0, 0.822670e-1,-0.424710e-2, 0.867980e-4,
-0.200856e+1, 0.129573e+1,-0.306533e0, 0.343682e-1,-0.185931e-2, 0.392432e-4,
0.127538e+1,-0.515705e0, 0.820644e-1,-0.641997e-2, 0.245913e-3,-0.365789e-5,
0.115792e0, -0.463143e-1, 0.725442e-2,-0.556266e-3, 0.208049e-4,-0.300895e-6};
static const G4double
CPbarn[]= {
-0.960613e-1, 0.631029e-1,-0.142819e-1, 0.150437e-2,-0.733286e-4, 0.131404e-5,
0.859343e-1,-0.529023e-1, 0.131899e-1,-0.159201e-2, 0.926958e-4,-0.208439e-5,
-0.271082e-1, 0.173949e-1,-0.452531e-2, 0.569405e-3,-0.344856e-4, 0.803964e-6,
0.419855e-2,-0.277188e-2, 0.737658e-3,-0.939463e-4, 0.569748e-5,-0.131737e-6,
-0.318752e-3, 0.215144e-3,-0.579787e-4, 0.737972e-5,-0.441485e-6, 0.994726e-8,
0.938233e-5,-0.651642e-5, 0.177303e-5,-0.224680e-6, 0.132080e-7,-0.288593e-9};
static const G4double
CCMbarn[]= {
-0.245667e-3, 0.833406e-4,-0.129217e-4, 0.915099e-6,-0.247179e-7,
0.147696e-3,-0.498793e-4, 0.402375e-5, 0.989281e-7,-0.133378e-7,
-0.737702e-2, 0.333057e-2,-0.553141e-3, 0.402464e-4,-0.107977e-5,
-0.641533e-2, 0.290113e-2,-0.477641e-3, 0.342008e-4,-0.900582e-6,
0.574303e-5, 0.908521e-4,-0.256900e-4, 0.239921e-5,-0.741271e-7};
static const G4double
CCPbarn[]= {
-0.245667e-3, 0.833406e-4,-0.129217e-4, 0.915099e-6,-0.247179e-7,
0.147696e-3,-0.498793e-4, 0.402375e-5, 0.989281e-7,-0.133378e-7,
-0.341260e-4, 0.971711e-5,-0.172031e-6,-0.119455e-6, 0.704166e-8,
0.341740e-5,-0.775867e-6,-0.653231e-7, 0.225605e-7,-0.114860e-8,
-0.119391e-6, 0.194885e-7, 0.588959e-8,-0.127589e-8, 0.608247e-10};
G4double CM[36],CP[36],CCM[25],CCP[25]; //Set the unit: barn
for (G4int i=0; i<36; i++) { CM[i] = CMbarn[i]*barn;
CP[i] = CPbarn[i]*barn;
}
for (G4int ii=0; ii<25; ii++) { CCM[ii] = CCMbarn[ii]*barn;
CCP[ii] = CCPbarn[ii]*barn;
}
// -----------------------------------------------------------
G4double TotalEnergy = T + electron_mass_c2;
G4double y=log(Cut/(ve*TotalEnergy));
G4double loss;
if (y <= 0.) loss = ComputeXYPolynomial(x, y, 6, 6, CM)
+ Z * ComputeXYPolynomial(x, y, 5, 5, CCM);
else loss = ComputeXYPolynomial(x, y, 6, 6, CP)
+ Z * ComputeXYPolynomial(x, y, 5, 5, CCP);
G4double rate = TotalEnergy/Cut ;
G4double corr = 1./(1.+corrfac*natom*rate*rate) ;
G4double factor = pow(Cut*corr/T,beta);
factor *= Z*(Z+ksi)*TotalEnergy*TotalEnergy/(TotalEnergy+electron_mass_c2) ;
loss *= factor ;
return loss ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//
// METHOD BELOW FROM STANDARD E_M PROCESSES LEFT BUT AT THE MOMENT NOT USED
//
G4double G4LowEnergyBremsstrahlung::ComputePositronCorrFactorLoss(
G4double Z,G4double KineticEnergy,G4double GammaCut)
//calculates the correction factor for the energy loss due to bremsstrahlung for positrons
//the same correction is in the (discrete) bremsstrahlung
{
static const G4double K = 132.9416*eV ;
static const G4double a1=4.15e-1, a3=2.10e-3, a5=54.0e-5 ;
G4double x = log(KineticEnergy/(K*Z*Z)), x2 = x*x, x3 = x2*x;
G4double eta = 0.5+atan(a1*x+a3*x3+a5*x3*x2)/pi;
G4double e0 = GammaCut/KineticEnergy;
G4double factor(0.);
if (e0!=1.0) { factor=log(1.-e0)/eta; factor=exp(factor);}
factor = eta*(1.-factor)/e0;
return factor;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -558,13 +290,15 @@ void G4LowEnergyBremsstrahlung::BuildMeanFreePathTable()
G4double FixedEnergy = (LowestKineticEnergy + HighestKineticEnergy)/2.;
//create table
if (theMeanFreePathTable) {theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
G4Material* material;
G4double* CutInKineticEnergy = G4Gamma::Gamma()->GetCutsInEnergy() ;
PartialSumSigma.resize(NumbOfMaterials);
@@ -581,7 +315,8 @@ void G4LowEnergyBremsstrahlung::BuildMeanFreePathTable()
material= (*theMaterialTable)(J);
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
const G4double Threshold = CutInKineticEnergy[J] ;
for ( G4int i = 0 ; i < TotBin ; i++ ){
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
@@ -591,13 +326,7 @@ void G4LowEnergyBremsstrahlung::BuildMeanFreePathTable()
for ( G4int k=0 ; k < material->GetNumberOfElements() ; k++ ){
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
G4double interCrsSec = GetCrossSectionWithCut(AtomIndex, LowEdgeEnergy,Threshold);
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
}
@@ -609,7 +338,7 @@ void G4LowEnergyBremsstrahlung::BuildMeanFreePathTable()
theMeanFreePathTable->insert( ptrVector );
// Compute the PartialSumSigma table at a given fixed energy
ComputePartialSumSigma(FixedEnergy, material) ;
ComputePartialSumSigma(FixedEnergy, material,Threshold) ;
}
}
@@ -619,8 +348,9 @@ void G4LowEnergyBremsstrahlung::BuildMeanFreePathTable()
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
//
void G4LowEnergyBremsstrahlung::ComputePartialSumSigma(G4double KineticEnergy,
const G4Material* aMaterial)
void G4LowEnergyBremsstrahlung::ComputePartialSumSigma(const G4double KineticEnergy,
const G4Material* aMaterial,
const G4double Threshold)
// Build the table of cross section per element. The table is built for MATERIALS.
// This table is used by DoIt to select randomly an element in the material.
@@ -638,12 +368,8 @@ void G4LowEnergyBremsstrahlung::ComputePartialSumSigma(G4double KineticEnergy,
for ( G4int Ielem=0 ; Ielem < NbOfElements ; Ielem++ ){
G4int AtomIndex = (G4int) (*theElementVector)(Ielem)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
G4double interCrsSec = util.DataLogInterpolation(KineticEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
G4double interCrsSec = GetCrossSectionWithCut(AtomIndex,KineticEnergy,Threshold);
SIGMA += theAtomNumDensityVector[Ielem]*interCrsSec;
@@ -659,28 +385,24 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
// This parametrization is derived from :
// Migdal corrections (dielectric suppression).
// Migdal: Phys Rev 103:1811 (1956); Messel & Crawford: Pergamon Press (1970)
// MIGDAL constant and LPM effect LEFT FROM STANDARD PROCESS
//
const G4double MigdalConstant = classic_electr_radius
*electron_Compton_length
*electron_Compton_length/pi;
const G4double LPMconstant = fine_structure_const*electron_mass_c2*
electron_mass_c2/(8.*pi*hbarc) ;
aParticleChange.Initialize(trackData);
G4Material* aMaterial=trackData.GetMaterial() ;
G4double LPMEnergy = LPMconstant*(aMaterial->GetRadlen()) ;
const G4DynamicParticle* aDynamicParticle=trackData.GetDynamicParticle();
G4double charge = aDynamicParticle->GetDefinition()->GetPDGCharge();
G4double ElectKinEn = aDynamicParticle->GetKineticEnergy();
// MGP debug
// G4cout << "G4LowEnergyBremsstrahlung::PostStepDoIt - ElectKinEn "
// << ElectKinEn/keV << " keV " << G4endl;
// MGP end
if(ElectKinEn <= LowestKineticEnergy){
aParticleChange.SetStatusChange(fStopAndKill);
@@ -696,15 +418,12 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
// Gamma production cut in this material
G4double GammaEnergyCut = (G4Gamma::GetCutsInEnergy())[aMaterial->GetIndex()];
// check against insufficient energy
if (ElectKinEn < GammaEnergyCut){
aParticleChange.SetMomentumChange( ElectDirection );
aParticleChange.SetEnergyChange( ElectKinEn );
aParticleChange.SetLocalEnergyDeposit (0.);
aParticleChange.SetNumberOfSecondaries(0);
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
if (ElectKinEn < GammaEnergyCut){
aParticleChange.SetEnergyChange(ElectKinEn);
aParticleChange.SetLocalEnergyDeposit(0.);
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
}
// select randomly one element constituing the material
@@ -713,7 +432,6 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
// limits of the energy sampling
G4double TotalEnergy = ElectKinEn + electron_mass_c2;
G4double TotalEnergysquare = TotalEnergy*TotalEnergy ;
G4double LPMGammaEnergyLimit = TotalEnergysquare/LPMEnergy ;
//
// The emitted gamma energy is from EEDL data fitted with A/E+B function.
@@ -721,7 +439,7 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
// formula has been modified by A. Forti and S. Giani.
//
// sample the energy of the emitted gamma for electron kinetic energy
// sample the energy of the emitted gamma
//
G4double p1 = 0, p2 = 0;
G4double coeffA = 0, coeffB = 0;
@@ -729,8 +447,12 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
coeffA = ComputeA(AtomicNum, ElectKinEn);
coeffB = ComputeB(AtomicNum, ElectKinEn);
p1 = coeffA*log(ElectKinEn/lowEnergyCut);
p2 = coeffB*(ElectKinEn - lowEnergyCut);
//const G4double minEn = lowEnergyCut;
const G4double minEn = GammaEnergyCut;
p1 = coeffA*log(ElectKinEn/minEn);
p2 = coeffB*(ElectKinEn - minEn);
G4double IntegrProb = p1+p2;
G4double R1 = G4UniformRand()*IntegrProb;
@@ -740,36 +462,30 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
if(R1 <= p1){
G4double R2 = G4UniformRand();
GammaEnergy = ElectKinEn*pow((lowEnergyCut/ElectKinEn),R2);
GammaEnergy = ElectKinEn*pow((minEn/ElectKinEn),R2);
/// stepanek does: GammaEnergy = exp(R2*log(ElectKinEn/minEn)+log(ElectKinEn));
}
else if ((p1 < R1) && (R1 <= p1+p2)){
G4double R2 = G4UniformRand();
GammaEnergy = ElectKinEn - R2*(ElectKinEn - lowEnergyCut);
GammaEnergy = ElectKinEn - R2*(ElectKinEn - minEn);
}
// now comes the supression due to the LPM effect (gamma production suppression
// due to the multiple scattering of the electron) SEE ABOVE
if(GammaEnergy < LPMGammaEnergyLimit){
G4double S2LPM = LPMEnergy*GammaEnergy/TotalEnergysquare ;
G4double Spol = GammaEnergy*GammaEnergy/(GammaEnergy*GammaEnergy +
MigdalConstant*(aMaterial->GetElectronDensity())*
TotalEnergysquare) ;
G4double w = S2LPM*(1.+1./Spol) ;
G4double Supr = 0.5*(sqrt(w*w+4.*S2LPM)-w)/Spol ;
if (G4UniformRand() > Supr )
GammaEnergy = 0. ;
}
//protection: DO NOT PRODUCE a gamma with energy 0. !
if (GammaEnergy <= 0.){
// MGP debug
// if (GammaEnergy > 10*keV)
// G4cout << "MGP BremPostStepDoIt eGamma = " << GammaEnergy/keV << " keV" << G4endl;
/*
G4double R1 = minEn + G4UniformRand()*(ElectKinEn- minEn);
G4double Max = coeffA/minEn + coeffB;
G4double R2 = G4UniformRand()*Max;
while (coeffA/R1 + coeffB < R2){
R1 = minEn + G4UniformRand()*(ElectKinEn- minEn);
R2 = G4UniformRand()*Max;
}
G4double GammaEnergy = R1;
*/
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
}
//**********************//
// Angular distribution //
//**********************//
@@ -778,8 +494,12 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
// universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
// derived from Tsai distribution (Rev Mod Phys 49,421(1977))
if(GammaEnergy > CutForLowEnergySecondaryPhotons){
if(GammaEnergy < minEn){
G4cerr<<"Problem with bremsstrahlung gamma energy sampling: Energy<cut:"
<<GammaEnergy<<" < "<<minEn
<<G4endl;
}
G4double u;
const G4double a1 = 0.625 , a2 = 3.*a1 , d = 27. ;
@@ -800,30 +520,18 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
G4double NewKinEnergy = ElectKinEn - GammaEnergy;
//
///final state electron:
//
if (NewKinEnergy > 0.){
aParticleChange.SetMomentumChange( ElectDirection );
aParticleChange.SetEnergyChange( NewKinEnergy );
if(GammaEnergy < GammaEnergyCut){
aParticleChange.SetLocalEnergyDeposit(GammaEnergy);
}
else{
// create G4DynamicParticle object for the Gamma
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
GammaDirection, GammaEnergy);
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary(aGamma);
aParticleChange.SetLocalEnergyDeposit(0);
}
}
else{
aParticleChange.SetEnergyChange( 0. );
aParticleChange.SetLocalEnergyDeposit (0.);
if (charge<0.){
aParticleChange.SetStatusChange(fStopAndKill);
@@ -832,13 +540,25 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
aParticleChange.SetStatusChange(fStopButAlive);
}
}
}
else{
}
//
///emitted photon:
//
if(GammaEnergy < GammaEnergyCut){
aParticleChange.SetNumberOfSecondaries(0);
aParticleChange.SetLocalEnergyDeposit(GammaEnergy);
}
aParticleChange.SetLocalEnergyDeposit(GammaEnergy);
}
else{
// create G4DynamicParticle object for the Gamma
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
GammaDirection, GammaEnergy);
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary(aGamma);
aParticleChange.SetLocalEnergyDeposit(0.);
}
#ifdef G4VERBOSE
if(verboseLevel > 15){
@@ -849,6 +569,86 @@ G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackD
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
}
G4double G4LowEnergyBremsstrahlung::GetEnergyLossWithCut(const G4double AtomicNumber,
const G4double KineticEnergy,
const G4double Tcut){
const G4double minEn = lowEnergyCut ;
if(minEn == 0.) G4cerr<<"Minimum Gamma energy should be finite"<<G4endl;
// shortcut ..........................
if(Tcut <= minEn) return 0. ;
G4double CrossSection = GetCrossSection(AtomicNumber,KineticEnergy) ;
// shortcut ..........................
if(CrossSection <= 0.) return 0. ;
G4double loss = 0.;
//
// energy spectrum of the emitted gamma
//
G4double MeanTinc;
MeanTinc = KineticEnergy;
const G4double MeanCS = GetCrossSection(AtomicNumber,MeanTinc);
const G4double coeffA = ComputeA(AtomicNumber, MeanTinc);
const G4double coeffB = ComputeB(AtomicNumber, MeanTinc);
//
//integration of T*dSigma/dT between Tmin = minEn and Tcut
//
G4double Tmax;
//
//integration of T*dSigma/dT between Tmin = minEn and Tcut
//
Tmax = Tcut;
if(Tmax>MeanTinc) Tmax = MeanTinc;
G4double SmallLoss = 0.;
SmallLoss = 0.5*coeffB*(Tmax*Tmax - minEn*minEn) + coeffA*(Tmax-minEn);
if(SmallLoss < 0.) G4cerr<<"Problem with integration of gamma spectrum: SmallLoss = "<<SmallLoss<<G4endl;
//
//integration of dSigma/dT between Tmin = minEn and KineticEnergy
//
Tmax = MeanTinc;
G4double norm = coeffB*(Tmax-minEn) + coeffA*log(Tmax/minEn);
if(norm <= 0.) G4cerr<<"Problem with integration of gamma spectrum: norm = "<<norm<<G4endl;
SmallLoss *= MeanCS/norm ;
loss+=SmallLoss;
return loss ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4LowEnergyBremsstrahlung::GetCrossSection(const G4double AtomicNumber,
const G4double KineticEnergy){
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomicNumber)];
return util.DataLogInterpolation(KineticEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]) )*barn;
}
G4double G4LowEnergyBremsstrahlung::GetCrossSectionWithCut(const G4double AtomicNumber,
const G4double KineticEnergy,
const G4double Tcut){
if(KineticEnergy<=Tcut) return 0.;
G4double Tmin = Tcut;
if(Tcut<lowEnergyCut) Tmin = lowEnergyCut;
G4double Tmax = KineticEnergy;
G4double CrossSection = GetCrossSection(AtomicNumber,KineticEnergy) ;
if(CrossSection <= 0.) return 0.;
const G4double coeffA = ComputeA(AtomicNumber, KineticEnergy);
const G4double coeffB = ComputeB(AtomicNumber, KineticEnergy);
G4double fraction = coeffB*(Tmax-Tmin) + coeffA*log(Tmax/Tmin);
if(fraction <= 0.) G4cerr<<"Problem with integration of gamma spectrum: fraction = "<<fraction<<G4endl;
G4double norm = coeffB*(Tmax-lowEnergyCut) + coeffA*log(Tmax/lowEnergyCut);
if(norm <= 0.) G4cerr<<"Problem with integration of gamma spectrum: norm = "<<norm<<G4endl;
fraction /= norm;
return CrossSection*fraction;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
@@ -870,10 +670,11 @@ G4Element* G4LowEnergyBremsstrahlung::SelectRandomAtom(G4Material* aMaterial) co
void G4LowEnergyBremsstrahlung::PrintInfoDefinition()
{
G4String comments = "Total cross sections from EEDL database";
comments += "\n At present it can be used for electrons only ";
comments += "Good description from 250 eV to 100 GeV.\n";
G4String comments = "Total cross sections from EEDL database,";
comments += "Gamma energy sampled from a parametrised formula.";
comments += "Implementation of the continuous dE/dx part.";
comments += "\n At present it can be used for electrons ";
comments += " in the energy range [250eV,100GeV]";
G4cout << G4endl << GetProcessName() << ": " << comments<<G4endl;
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4LowEnergyCompton.cc,v 1.17 2000/01/26 09:50:00 lefebure Exp $
// GEANT4 tag $Name: geant4-01-01 $
// $Id: G4LowEnergyCompton.cc,v 1.19 2000/03/13 11:15:13 lefebure Exp $
// GEANT4 tag $Name: geant4-02-00 $
//
//
// --------------------------------------------------------------
@@ -238,18 +238,17 @@ G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack, const
onecost = (1.- epsilon)/(epsilon*E0_m);
sint2 = onecost*(2.-onecost);
x = sqrt(onecost/2)/wlGamma;
x = sqrt(onecost/2)/(wlGamma/cm);
const G4FirstLevel* oneAtomSF
= (*theScatteringFunctionTable)[ZNumVec->index(elementZ)];
ScatteringFunction = util.DataLogInterpolation(x, (*(*oneAtomSF)[0]),
(*(*oneAtomSF)[1]))/cm;
(*(*oneAtomSF)[1]));
greject = (1. - epsilon*sint2/(1.+ epsilonsq))*ScatteringFunction;
} while(greject < G4UniformRand()*elementZ);
G4double cosTeta = 1. - onecost , sinTeta = sqrt (sint2);
G4double Phi = twopi * G4UniformRand() ;
G4double dirx = sinTeta*cos(Phi) , diry = sinTeta*sin(Phi) , dirz = cosTeta ;
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4LowEnergyGammaConversion.cc,v 1.11 2000/01/26 09:50:00 lefebure Exp $
// GEANT4 tag $Name: geant4-01-01 $
// $Id: G4LowEnergyGammaConversion.cc,v 1.13 2000/05/04 17:54:04 flongo Exp $
// GEANT4 tag $Name: geant4-02-00 $
//
//
// --------------------------------------------------------------
@@ -17,6 +17,12 @@
// CERN, IT Division, ASD group
// ------------ G4LowEnergyGammaConversion physics process --------
// by A.Forti 1999/03/02
//
// 14.03.2000 Veronique Lefebure;
// Change initialisation of LowestEnergyLimit from 1.22 to 1.022.
// Note that the hard coded value 1.022 should be used instead of
// 2*electron_mass_c2 in order to agree with the value of the data bank EPDL97
//
// **************************************************************
// This Class Header
@@ -34,7 +40,8 @@ G4LowEnergyGammaConversion::G4LowEnergyGammaConversion(const G4String& processNa
theCrossSectionTable(0),
theMeanFreePathTable(0),
ZNumVec(0),
LowestEnergyLimit (1.2200),
//Use lowest limit of EPDL97 which is larger than 2*electron_mass_c2 = 1.02199812 MeV
LowestEnergyLimit (1.022000*MeV),
HighestEnergyLimit(100*GeV),
NumbBinTable(200)
{
File diff suppressed because it is too large Load Diff
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4LowEnergyPhotoElectric.cc,v 1.24 2000/02/18 10:27:53 lefebure Exp $
// GEANT4 tag $Name: geant4-01-01 $
// $Id: G4LowEnergyPhotoElectric.cc,v 1.25 2000/04/10 10:26:56 lefebure Exp $
// GEANT4 tag $Name: geant4-02-00 $
//
//
// --------------------------------------------------------------
@@ -18,6 +18,9 @@
// ------------ G4LowEnergyPhotoelctric: low energy modifications --------
// by Alessandra Forti, October 1998
// **************************************************************
// 10.04.2000 VL
// - Correcting Fluorescence transition probabilities in order to take into account
// non-radiative transitions. No Auger electron simulated yet: energy is locally deposited.
// 17.02.2000 Veronique Lefebure
// - bugs corrected in fluorescence simulation:
// . when final use of binding energy: no photon was ever created
@@ -297,7 +300,7 @@ G4double G4LowEnergyPhotoElectric::ComputeCrossSection(const G4double AtomIndex,
else{
crossSec = util.DataLogInterpolation(IncEnergy, (*EnergyVector), (*CrossSecVector));
crossSec = util.DataLogInterpolation(IncEnergy, (*EnergyVector), (*CrossSecVector))*barn;
}
@@ -478,7 +481,7 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
diry = newsinTh*cos(newPhi);
dirx = newsinTh*sin(newPhi);
G4ThreeVector newPartDirection(dirx, diry, dirz);
newPartDirection.rotateUz(PhotonDirection);
/////newPartDirection.rotateUz(PhotonDirection);
if(ThereAreShells != FALSE){
@@ -496,6 +499,10 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
}
else{
/////Energy deposition vl
////=================NEW================vl
/*
G4int k = 0;
while(thePrimaryShell != (*(*theBindEnVec)[0])[k]) k++;
@@ -510,11 +517,12 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
newPartDirection,
lastTransEnergy) ;
photvec.append(newPart);
}
thePrimShVec.insert(thePrimaryShell);
*/
}
thePrimShVec.insert(thePrimaryShell);
}
} //END OF THE CHECK ON ATOMIC NUMBER
@@ -579,7 +587,7 @@ G4int G4LowEnergyPhotoElectric::SelectRandomShell(const G4int AtomIndex,
else{
crossSec = util.DataLogInterpolation(IncEnergy, (*EnergyVector), (*CrossSecVector));
crossSec = util.DataLogInterpolation(IncEnergy, (*EnergyVector), (*CrossSecVector))*barn;
}
@@ -652,11 +660,15 @@ G4bool G4LowEnergyPhotoElectric::SelectRandomTransition(G4int thePrimShell,
// loop on subshell is inside the method.
// when the last subshell is reached CollIsFull becomes FALSE.
G4bool ColIsFull = TRUE;
G4bool ColIsFull = FALSE;
G4int ShellNum = 0;
G4double TotalSum = 0;
G4int maxNumOfShells = TransitionTable->entries()-1;
if(thePrimShell <= 0) {
G4cerr<<"*** Unvalid Primary shell: "<<thePrimShell<<G4endl;
return FALSE;
}
if(thePrimShell <= (*(*(*TransitionTable)[maxNumOfShells])[0])[0]){
while(thePrimShell != (*(*(*TransitionTable)[ShellNum])[0])[0]){
@@ -673,12 +685,19 @@ G4bool G4LowEnergyPhotoElectric::SelectRandomTransition(G4int thePrimShell,
// transition probability: it must not be added to TotalSum.
G4int TransProb = 1;
for(TransProb = 1; TransProb < (*(*TransitionTable)[ShellNum])[ProbCol]->length(); TransProb++){
TotalSum += (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
}
G4double PartialProb = G4UniformRand()*TotalSum;
// Include non-radiative transitions (vl):
//// for(TransProb = 1; TransProb < (*(*TransitionTable)[ShellNum])[ProbCol]->length(); TransProb++){
//// TotalSum += (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
//// }
////G4double PartialProb = G4UniformRand()*TotalSum;
////
G4double PartialProb = G4UniformRand();
//vl.
G4double PartSum = 0;
TransProb = 1;
@@ -691,6 +710,7 @@ G4bool G4LowEnergyPhotoElectric::SelectRandomTransition(G4int thePrimShell,
TransParam[0] = (*(*(*TransitionTable)[ShellNum])[SubShellCol])[TransProb];
TransParam[1] = (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
TransParam[2] = (*(*(*TransitionTable)[ShellNum])[EnergyCol])[TransProb];
ColIsFull = TRUE;
break;
}
@@ -5,8 +5,8 @@
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4LowEnergyRayleigh.cc,v 1.15 2000/01/26 09:50:01 lefebure Exp $
// GEANT4 tag $Name: geant4-01-01 $
// $Id: G4LowEnergyRayleigh.cc,v 1.17 2000/03/13 11:15:32 lefebure Exp $
// GEANT4 tag $Name: geant4-02-00 $
//
//
// --------------------------------------------------------------
@@ -220,13 +220,13 @@ G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack, cons
Theta_Half = G4UniformRand()*pi/2;
SinThHalf = sin(Theta_Half);
x = SinThHalf/wlGamma;
x = SinThHalf/(wlGamma/cm);
const G4FirstLevel* oneAtomFF
= (*theFormFactorTable)[ZNumVec->index(elementZ)];
DataFormFactor = util.DataLogInterpolation(x, (*(*oneAtomFF)[0]),
(*(*oneAtomFF)[1]))/cm;
(*(*oneAtomFF)[1]));
RandomFormFactor = G4UniformRand()*elementZ*elementZ;
Theta = Theta_Half*2;
@@ -6,7 +6,7 @@
// and all its terms.
//
// $Id: G4LowEnergyUtilities.cc,v 1.4 2000/01/26 09:50:01 lefebure Exp $
// GEANT4 tag $Name: geant4-01-01 $
// GEANT4 tag $Name: geant4-02-00 $
//
//
// --------------------------------------------------------------
@@ -0,0 +1,398 @@
// 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.
//
// -------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// History: New Implementation
//
// ---------- G4QAOLowEnergyLoss physics process -------
// by Stephane Chauvie, 5 May 2000
// Modified:
// 24/05/2000 MGP Modified to remove compilation warnings on Linux and DEC
// Introduced sizes of L0, L1, L2 arrays
// 23/05/2000 MGP Made compliant to design
//
//
// ************************************************************
// It is the Quantal Harmonic Oscillator Model for energy loss
// of slow antiproton
// ************************************************************
// --------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4QAOLowEnergyLoss.hh"
#include "PhysicalConstants.h"
#include "SystemOfUnits.h"
#include "G4DynamicParticle.hh"
#include "G4Material.hh"
#include "G4ParticleDefinition.hh"
#include "G4AntiProton.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4QAOLowEnergyLoss::G4QAOLowEnergyLoss()
{
numberOfMaterials = 6;
sizeL0 = 67;
sizeL1 = 22;
sizeL2 = 14;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4QAOLowEnergyLoss::~G4QAOLowEnergyLoss()
{
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4QAOLowEnergyLoss::IsInCharge(G4double energy,
const G4ParticleDefinition* particleDefinition,
const G4Material* material) const
{
G4bool isInCharge = false;
G4bool hasMaterial = false;
for (G4int m = 0; m < numberOfMaterials; m++)
{
G4String matName = material->GetName();
if (matName == materialAvailable[m]){
hasMaterial = true;
break;}
}
if (particleDefinition == G4AntiProton::AntiProtonDefinition()
&&
hasMaterial)
//&& energy >= LowEnergyLimit() && energy <= HighEnergyLimit() )
isInCharge = true;
return isInCharge;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4QAOLowEnergyLoss::EnergyLoss(const G4DynamicParticle* particle,
const G4Material* material) const
{
G4int nbOfShell = GetNumberOfShell(material);
G4double ionisationEnergy = material->GetIonisation()->GetMeanExcitationEnergy();
G4double kineticEnergy = particle->GetKineticEnergy();
G4int zParticle = (G4int) particle->GetCharge();
G4double dedx=0;
G4double v=0;
v= c_light * sqrt( 2 * kineticEnergy / proton_mass_c2 );
G4double coeff=0;
coeff= (twopi * proton_mass_c2 * material-> GetTotNbOfElectPerVolume()) / ( electron_mass_c2);
coeff*= ( fine_structure_const * fine_structure_const * hbarc_squared ) / ( kineticEnergy );
G4double fractionOfBetheVelocity = 0;
fractionOfBetheVelocity = ( fine_structure_const * c_light) / v;
G4double stoppingNumber = 0, l0Term = 0, l1Term = 0, l2Term = 0;
for (G4int nos = 0 ; nos < nbOfShell ; nos++){
G4double l0 = 0, l1 = 0, l2 = 0;
G4double NormalizedEnergy = 0;
NormalizedEnergy = ( 2 * electron_mass_c2 * v * v ) / ( c_squared * GetShellEnergy(material,nos) );
l0 = GetL0(NormalizedEnergy);
l0Term += GetShellStrength(material,nos) * l0;
l1 = GetL1(NormalizedEnergy);
l1Term += GetShellStrength(material,nos) * l1;
l2 = GetL2(NormalizedEnergy);
l2Term += GetShellStrength(material,nos) * l2;
}
stoppingNumber = zParticle * zParticle * ( l0Term + zParticle * fractionOfBetheVelocity * l1Term + zParticle * zParticle * fractionOfBetheVelocity * fractionOfBetheVelocity * l2Term);
dedx = ( coeff * stoppingNumber);
return dedx ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4int G4QAOLowEnergyLoss::GetNumberOfShell(const G4Material* material) const
{
// Set default return value
G4int nShell = nbofShellForMaterial[0];
if(material->GetName() == "Aluminium") nShell = nbofShellForMaterial[0];
else if (material->GetName() == "Silicon" ) nShell = nbofShellForMaterial[1] ;
else if (material->GetName()== "Copper") nShell = nbofShellForMaterial[2];
else if (material->GetName() == "Tantalum") nShell = nbofShellForMaterial[3];
else if (material->GetName() == "Gold" ) nShell = nbofShellForMaterial[4];
else if (material->GetName() == "Platinum") nShell = nbofShellForMaterial[5];
else G4cout << "WARNING - G4QAOLowEnergyLoss::GetNumberOfShell - "
<< "The model is not available for "
<< material->GetName()
<< G4endl;
return nShell;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4QAOLowEnergyLoss::GetShellEnergy(const G4Material* material,G4int nbOfTheShell) const
{
//
G4double shellEnergy = alShellEnergy[0];
if(material->GetName() == "Aluminium") shellEnergy = alShellEnergy[nbOfTheShell];
else if (material->GetName() == "Silicon" ) shellEnergy = siShellEnergy[nbOfTheShell];
else if (material->GetName() == "Copper") shellEnergy = cuShellEnergy[nbOfTheShell];
else if (material->GetName() == "Tantalum") shellEnergy = taShellEnergy[nbOfTheShell];
else if (material->GetName() == "Gold" ) shellEnergy = auShellEnergy[nbOfTheShell];
else if (material->GetName() == "Platinum") shellEnergy = ptShellEnergy[nbOfTheShell];
else G4cout << "WARNING - G4QAOLowEnergyLoss::GetShellEnergy - "
<< "The model is not available for "
<< material->GetName()
<< G4endl;
return shellEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4QAOLowEnergyLoss::GetShellStrength(const G4Material* material,G4int nbOfTheShell) const
{
G4double shellStrength = alShellStrength[0];
if(material->GetName() == "Aluminium") shellStrength = alShellStrength[nbOfTheShell];
else if (material->GetName() == "Silicon" ) shellStrength = siShellStrength[nbOfTheShell];
else if (material->GetName() == "Copper") shellStrength = cuShellStrength[nbOfTheShell];
else if (material->GetName() == "Tantalum") shellStrength = taShellStrength[nbOfTheShell];
else if (material->GetName() == "Gold" ) shellStrength = auShellStrength[nbOfTheShell];
else if (material->GetName() == "Platinum") shellStrength = ptShellStrength[nbOfTheShell];
else G4cout << "WARNING - G4QAOLowEnergyLoss::GetShellEnergy - "
<< "The model is not available for "
<< material->GetName()
<< G4endl;
return shellStrength;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4QAOLowEnergyLoss::GetL0(G4double normEnergy) const
{
G4double l0 = 0, l0p = 0;
G4double bethe = 0;
G4int n = 0;
do{
n++;
if ( n >= sizeL0 ) break;
l0 = L0[n][1];
l0p = L0[n-1][1];
bethe = (l0 - l0p) * ( normEnergy - L0[n-1][0]) / (L0[n][0] - L0[n-1][0]);
bethe+= l0p;
} while( normEnergy >= L0[n][0] );
return bethe ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4QAOLowEnergyLoss::GetL1(G4double normEnergy) const
{
G4double l1 = 0, l1p = 0 ;
G4double barkas = 0;
G4int n = 0;
do{
n++;
if ( n >= sizeL1 ) break;
l1 = L1[n][1];
l1p = L1[n-1][1];
barkas = (l1 - l1p) * ( normEnergy - L1[n-1][0]) / (L1[n][0] - L1[n-1][0]);
barkas+= l1p;
} while( normEnergy >= L1[n][0]);
return barkas;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4QAOLowEnergyLoss::GetL2(G4double normEnergy) const
{
G4double l2 = 0, l2p = 0;
G4double bloch = 0;
G4int n = 0;
do{
n++;
if ( n >= sizeL2 ) break;
l2 = L2[n][1];
l2p = L2[n-1][1];
bloch = (l2 - l2p) * ( normEnergy - L2[n-1][0]) / (L2[n][0] - L2[n-1][0]);
bloch+= l2p;
} while( normEnergy >= L2[n][0] );
return bloch;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4String G4QAOLowEnergyLoss::materialAvailable[6] = {
"Aluminium",
"Silicon",
"Copper",
"Tantalum",
"Gold",
"Platinum"};
const G4int G4QAOLowEnergyLoss::nbofShellForMaterial[6] = {3,3,4,6,6,6 };
G4double G4QAOLowEnergyLoss::alShellEnergy[3] ={ 2795e-6, 202e-6, 16.9e-6};
G4double G4QAOLowEnergyLoss::alShellStrength[3]={ 0.1349, 0.6387, 0.2264};
G4double G4QAOLowEnergyLoss::siShellEnergy[3] ={ 3179e-6, 249e-6, 20.3e-6 };
G4double G4QAOLowEnergyLoss::siShellStrength[3]={ 0.1222, 0.5972, 0.2806};
G4double G4QAOLowEnergyLoss::cuShellEnergy[4] ={ 16931e-6, 1930e-6, 199e-6, 39.6e-6};
G4double G4QAOLowEnergyLoss::cuShellStrength[4]={ 0.0505, 0.2561, 0.4913, 0.2021};
G4double G4QAOLowEnergyLoss::taShellEnergy[6] ={ 88926e-6, 18012e-6, 3210e-6, 575e-6, 108.7e-6, 30.8e-6};
G4double G4QAOLowEnergyLoss::taShellStrength[6]={ 0.0126, 0.0896, 0.2599, 0.3413, 0.2057, 0.0908};
G4double G4QAOLowEnergyLoss::auShellEnergy[6]={ 96235e-6, 25918e-6, 4116e-6, 599e-6, 87.3e-6, 36.9e-6};
G4double G4QAOLowEnergyLoss::auShellStrength[6]={ 0.0139, 0.0803, 0.2473, 0.423, 0.1124, 0.1231};
G4double G4QAOLowEnergyLoss::ptShellEnergy[6]={ 95017e-6, 25590e-6, 4063e-6, 576e-6, 81.9e-6, 31.4e-6};
G4double G4QAOLowEnergyLoss::ptShellStrength[6]={ 0.0129, 0.0745, 0.2295, 0.4627, 0.1324, 0.0879};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4double G4QAOLowEnergyLoss::L0[67][2] =
{
0.00, 0.000001,
0.10, 0.000001,
0.12, 0.00001,
0.14, 0.00005,
0.16, 0.00014,
0.18, 0.00030,
0.20, 0.00057,
0.25, 0.00189,
0.30, 0.00429,
0.35, 0.00784,
0.40, 0.01248,
0.45, 0.01811,
0.50, 0.02462,
0.60, 0.03980,
0.70, 0.05731,
0.80, 0.07662,
0.90, 0.09733,
1.00, 0.11916,
1.20, 0.16532,
1.40, 0.21376,
1.60, 0.26362,
1.80, 0.31428,
2.00, 0.36532,
2.50, 0.49272,
3.00, 0.61765,
3.50, 0.73863,
4.00, 0.85496,
4.50, 0.96634,
5.00, 1.07272,
6.00, 1.27086,
7.00, 1.45075,
8.00, 1.61412,
9.00, 1.76277,
10.00, 1.89836,
12.00, 2.13625,
14.00, 2.33787,
16.00, 2.51093,
18.00, 2.66134,
20.00, 2.79358,
25.00, 3.06539,
30.00, 3.27902,
35.00, 3.45430,
40.00, 3.60281,
45.00, 3.73167,
50.00, 3.84555,
60.00, 4.04011,
70.00, 4.20264,
80.00, 4.34229,
90.00, 4.46474,
100.00, 4.57378,
120.00, 4.76155,
140.00, 4.91953,
160.00, 5.05590,
180.00, 5.17588,
200.00, 5.28299,
250.00, 5.50925,
300.00, 5.69364,
350.00, 5.84926,
400.00, 5.98388,
450.00, 6.10252,
500.00, 6.20856,
600.00, 6.39189,
700.00, 6.54677,
800.00, 6.68084,
900.00, 6.79905,
1000.00, 6.90474
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4double G4QAOLowEnergyLoss::L1[22][2] =
{
0.00, -0.000001,
0.10, -0.00001,
0.20, -0.00049,
0.30, -0.00084,
0.40, 0.00085,
0.50, 0.00519,
0.60, 0.01198,
0.70, 0.02074,
0.80, 0.03133,
0.90, 0.04369,
1.00, 0.06035,
2.00, 0.24023,
3.00, 0.44284,
4.00, 0.62012,
5.00, 0.77031,
6.00, 0.90390,
7.00, 1.02705,
8.00, 1.10867,
9.00, 1.17546,
10.00, 1.21599,
15.00, 1.24349,
20.00, 1.16752
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4double G4QAOLowEnergyLoss::L2[14][2] =
{
0.00, 0.000001,
0.10, 0.00001,
0.20, 0.00000,
0.40, -0.00120,
0.60, -0.00036,
0.80, 0.00372,
1.00, 0.01298,
2.00, 0.08296,
4.00, 0.21953,
6.00, 0.23903,
8.00, 0.20893,
10.00, 0.10879,
20.00, -0.88409,
40.00, -1.13902
};
G4double G4QAOLowEnergyLoss::HighEnergyLimit() const
{
G4double eMax = 2. * MeV;
return eMax;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,395 @@
// 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: G4eLowEnergyLoss.cc,v 1.5 2000/06/22 02:38:13 pia Exp $
// GEANT4 tag $Name: geant4-02-00 $
//
// -----------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// History: based on object model of
// 2nd December 1995, G.Cosmo
// ---------- G4eLowEnergyLoss physics process -----------
// by Laszlo Urban, 20 March 1997
// **************************************************************
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
// It calculates the energy loss of e+/e-.
// --------------------------------------------------------------
//
// 08-05-97: small changes by L.Urban
// 27-05-98: several bugs and inconsistencies are corrected,
// new table (the inverse of the range table) added ,
// AlongStepDoit uses now this new table. L.Urban
// 08-09-98: cleanup
// 24-09-98: rndmStepFlag false by default (no randomization of the step)
// 14-10-98: messenger file added.
// 16-10-98: public method SetStepFunction()
// 20-01-99: important correction in AlongStepDoIt , L.Urban
// 10/02/00 modifications , new e.m. structure, L.Urban
// 11/04/00: Bug fix in dE/dx fluctuation simulation, Veronique Lefebure
// --------------------------------------------------------------
#include "G4eLowEnergyLoss.hh"
#include "G4EnergyLossMessenger.hh"
#include "G4Poisson.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Initialisation of static data members
// -------------------------------------
// Contributing processes : ion.loss + soft brems->NbOfProcesses is initialized
// to 2 . YOU DO NOT HAVE TO CHANGE this variable for a 'normal' run.
//
// You have to change NbOfProcesses if you invent a new process contributing
// to the continuous energy loss.
// The NbOfProcesses data member can be changed using the (public static)
// functions Get/Set/Plus/MinusNbOfProcesses (see G4eLowEnergyLoss.hh)
G4int G4eLowEnergyLoss::NbOfProcesses = 2;
G4int G4eLowEnergyLoss::CounterOfElectronProcess = 0;
G4int G4eLowEnergyLoss::CounterOfPositronProcess = 0;
G4PhysicsTable** G4eLowEnergyLoss::RecorderOfElectronProcess =
new G4PhysicsTable*[10];
G4PhysicsTable** G4eLowEnergyLoss::RecorderOfPositronProcess =
new G4PhysicsTable*[10];
G4PhysicsTable* G4eLowEnergyLoss::theDEDXElectronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theDEDXPositronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theRangeElectronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theRangePositronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theInverseRangeElectronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theInverseRangePositronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theLabTimeElectronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theLabTimePositronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theProperTimeElectronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theProperTimePositronTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theeRangeCoeffATable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theeRangeCoeffBTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::theeRangeCoeffCTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::thepRangeCoeffATable = 0;
G4PhysicsTable* G4eLowEnergyLoss::thepRangeCoeffBTable = 0;
G4PhysicsTable* G4eLowEnergyLoss::thepRangeCoeffCTable = 0;
G4double G4eLowEnergyLoss::LowerBoundEloss = 250.*eV ;
G4double G4eLowEnergyLoss::UpperBoundEloss = 100.*GeV ;
G4int G4eLowEnergyLoss::NbinEloss = 1000 ;
G4double G4eLowEnergyLoss::RTable ;
G4double G4eLowEnergyLoss::LOGRTable ;
G4EnergyLossMessenger* G4eLowEnergyLoss::eLossMessenger = 0;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// constructor and destructor
G4eLowEnergyLoss::G4eLowEnergyLoss(const G4String& processName)
: G4VeLowEnergyLoss (processName),
theLossTable(0),
theDEDXTable(0),
Charge(-1.),lastCharge(0.),
MinKineticEnergy(1.*eV),
//linLossLimit(0.02)
linLossLimit(0.05),
RecorderOfProcess(0),
fdEdx(0),
fRangeNow(0),
CounterOfProcess(0)
{
//create (only once) EnergyLoss messenger
if(!eLossMessenger) eLossMessenger = new G4EnergyLossMessenger();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4eLowEnergyLoss::~G4eLowEnergyLoss()
{
if (theLossTable)
{
theLossTable->clearAndDestroy();
delete theLossTable;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4eLowEnergyLoss::BuildDEDXTable(
const G4ParticleDefinition& aParticleType)
{
ParticleMass = aParticleType.GetPDGMass();
Charge = aParticleType.GetPDGCharge()/eplus;
// calculate data members LOGRTable,RTable first
G4double lrate = log(UpperBoundEloss/LowerBoundEloss);
LOGRTable=lrate/NbinEloss;
RTable =exp(LOGRTable);
// Build energy loss table as a sum of the energy loss due to the
// different processes.
//
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
// create table for the total energy loss
if (&aParticleType==G4Electron::Electron())
{
RecorderOfProcess=RecorderOfElectronProcess;
CounterOfProcess=CounterOfElectronProcess;
if (CounterOfProcess == NbOfProcesses)
{
if (theDEDXElectronTable)
{
theDEDXElectronTable->clearAndDestroy();
delete theDEDXElectronTable;
}
theDEDXElectronTable = new G4PhysicsTable(numOfMaterials);
theDEDXTable = theDEDXElectronTable;
}
}
if (&aParticleType==G4Positron::Positron())
{
RecorderOfProcess=RecorderOfPositronProcess;
CounterOfProcess=CounterOfPositronProcess;
if (CounterOfProcess == NbOfProcesses)
{
if (theDEDXPositronTable)
{
theDEDXPositronTable->clearAndDestroy();
delete theDEDXPositronTable;
}
theDEDXPositronTable = new G4PhysicsTable(numOfMaterials);
theDEDXTable = theDEDXPositronTable;
}
}
if (CounterOfProcess == NbOfProcesses)
{
// fill the tables
// loop for materials
G4double LowEdgeEnergy , Value;
G4bool isOutRange;
G4PhysicsTable* pointer;
for (G4int J=0; J<numOfMaterials; J++)
{
// create physics vector and fill it
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
LowerBoundEloss, UpperBoundEloss, NbinEloss);
// loop for the kinetic energy
for (G4int i=0; i<NbinEloss; i++)
{
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
//here comes the sum of the different tables created by the
//processes (ionisation,bremsstrahlung,etc...)
Value = 0.;
for (G4int process=0; process < NbOfProcesses; process++)
{
pointer= RecorderOfProcess[process];
Value += (*pointer)[J]->GetValue(LowEdgeEnergy,isOutRange);
}
aVector->PutValue(i,Value) ;
}
theDEDXTable->insert(aVector) ;
}
//reset counter to zero
if (&aParticleType==G4Electron::Electron()) CounterOfElectronProcess=0;
if (&aParticleType==G4Positron::Positron()) CounterOfPositronProcess=0;
ParticleMass = aParticleType.GetPDGMass();
if (&aParticleType==G4Electron::Electron())
{
// Build range table
theRangeElectronTable = BuildRangeTable(theDEDXElectronTable,
theRangeElectronTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
// Build lab/proper time tables
theLabTimeElectronTable = BuildLabTimeTable(theDEDXElectronTable,
theLabTimeElectronTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
theProperTimeElectronTable = BuildProperTimeTable(theDEDXElectronTable,
theProperTimeElectronTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
// Build coeff tables for the energy loss calculation
theeRangeCoeffATable = BuildRangeCoeffATable(theRangeElectronTable,
theeRangeCoeffATable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
theeRangeCoeffBTable = BuildRangeCoeffBTable(theRangeElectronTable,
theeRangeCoeffBTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
theeRangeCoeffCTable = BuildRangeCoeffCTable(theRangeElectronTable,
theeRangeCoeffCTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
// invert the range table
theInverseRangeElectronTable = BuildInverseRangeTable(theRangeElectronTable,
theeRangeCoeffATable,
theeRangeCoeffBTable,
theeRangeCoeffCTable,
theInverseRangeElectronTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
}
if (&aParticleType==G4Positron::Positron())
{
// Build range table
theRangePositronTable = BuildRangeTable(theDEDXPositronTable,
theRangePositronTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
// Build lab/proper time tables
theLabTimePositronTable = BuildLabTimeTable(theDEDXPositronTable,
theLabTimePositronTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
theProperTimePositronTable = BuildProperTimeTable(theDEDXPositronTable,
theProperTimePositronTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
// Build coeff tables for the energy loss calculation
thepRangeCoeffATable = BuildRangeCoeffATable(theRangePositronTable,
thepRangeCoeffATable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
thepRangeCoeffBTable = BuildRangeCoeffBTable(theRangePositronTable,
thepRangeCoeffBTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
thepRangeCoeffCTable = BuildRangeCoeffCTable(theRangePositronTable,
thepRangeCoeffCTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
// invert the range table
theInverseRangePositronTable = BuildInverseRangeTable(theRangePositronTable,
thepRangeCoeffATable,
thepRangeCoeffBTable,
thepRangeCoeffCTable,
theInverseRangePositronTable,
LowerBoundEloss,UpperBoundEloss,NbinEloss);
}
// make the energy loss and the range table available
G4EnergyLossTables::Register(&aParticleType,
(&aParticleType==G4Electron::Electron())?
theDEDXElectronTable: theDEDXPositronTable,
(&aParticleType==G4Electron::Electron())?
theRangeElectronTable: theRangePositronTable,
(&aParticleType==G4Electron::Electron())?
theInverseRangeElectronTable: theInverseRangePositronTable,
(&aParticleType==G4Electron::Electron())?
theLabTimeElectronTable: theLabTimePositronTable,
(&aParticleType==G4Electron::Electron())?
theProperTimeElectronTable: theProperTimePositronTable,
LowerBoundEloss, UpperBoundEloss, 1.,NbinEloss);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
const G4Step& stepData)
{
// compute the energy loss after a Step
static const G4double faclow = 1.5 ;
// get particle and material pointers from trackData
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
G4double E = aParticle->GetKineticEnergy() ;
// G4cout << "MGP -- Along eInit " << E/keV << " keV " << G4endl;
G4Material* aMaterial = trackData.GetMaterial();
G4int index = aMaterial->GetIndex();
G4double Step = stepData.GetStepLength();
fParticleChange.Initialize(trackData);
G4double MeanLoss, finalT;
if (E < MinKineticEnergy) finalT = 0.;
else if ( E< faclow*LowerBoundEloss)
{
if (Step >= fRangeNow) finalT = 0.;
// else finalT = E*(1.-Step/fRangeNow) ;
else finalT = E*(1.-sqrt(Step/fRangeNow)) ;
}
else if (E>=UpperBoundEloss) finalT = E - Step*fdEdx;
else if (Step >= fRangeNow) finalT = 0.;
else
{
if(Step/fRangeNow < linLossLimit) finalT = E-Step*fdEdx ;
else
{
if (Charge<0.) finalT = G4EnergyLossTables::GetPreciseEnergyFromRange
(G4Electron::Electron(),fRangeNow-Step,aMaterial);
else finalT = G4EnergyLossTables::GetPreciseEnergyFromRange
(G4Positron::Positron(),fRangeNow-Step,aMaterial);
}
}
if(finalT < MinKineticEnergy) finalT = 0. ;
MeanLoss = E-finalT ;
// G4cout << "MGP AlongStepDoIt finalT before fluct = " << finalT/keV << " keV" << G4endl;
G4double fluc = GetLossWithFluct(aParticle,aMaterial,MeanLoss);
// G4cout << "LowerBoundEloss = " << LowerBoundEloss/keV = << " Fluc = " << fluc/keV << G4endl;
//now the loss with fluctuation
if ((EnlossFlucFlag) && (finalT > 0.) && (finalT < E)&&(E > LowerBoundEloss))
{
finalT = E-GetLossWithFluct(aParticle,aMaterial,MeanLoss);
if (finalT < 0.) finalT = 0.;
}
// kill the particle if the kinetic energy <= 0
if (finalT <= 0. )
{
finalT = 0.;
if (Charge < 0.) fParticleChange.SetStatusChange(fStopAndKill);
else fParticleChange.SetStatusChange(fStopButAlive);
}
// MGP debug
// G4cout << "MGP AlongStepDoIt finalT = " << finalT/keV << " keV" << G4endl;
fParticleChange.SetEnergyChange(finalT);
fParticleChange.SetLocalEnergyDeposit(E-finalT);
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff