Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -0,0 +1,940 @@
|
||||
// This code implementation is the intellectual property of
|
||||
// the RD44 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: G4eBremsstrahlung.cc,v 2.11 1998/11/13 13:37:33 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, IT Division, ASD group
|
||||
// History: first implementation, based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ------------ G4eBremsstrahlung physics process --------
|
||||
// by Michel Maire, 24 July 1996
|
||||
// **************************************************************
|
||||
// 26-09-96 : extension of the total crosssection above 100 GeV, M.Maire
|
||||
// 1-10-96 : new type G4OrderedTable; ComputePartialSumSigma(), M.Maire
|
||||
// 16-10-96 : DoIt() call to the non static GetEnergyCuts(), L.Urban
|
||||
// 13-12-96 : Sign corrected in grejmax and greject
|
||||
// error definition of screenvar, L.Urban
|
||||
// 20-03-97 : new energy loss+ionisation+brems scheme, L.Urban
|
||||
// 07-04-98 : remove 'tracking cut' of the diffracted particle, MMa
|
||||
// 13-08-98 : new methods SetBining() PrintInfo()
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4eBremsstrahlung.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// constructor
|
||||
|
||||
G4eBremsstrahlung::G4eBremsstrahlung(const G4String& processName)
|
||||
: G4eEnergyLoss(processName), // initialization
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestKineticEnergy (1.*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
TotBin(100)
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// destructor
|
||||
|
||||
G4eBremsstrahlung::~G4eBremsstrahlung()
|
||||
{
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
if (&PartialSumSigma) {
|
||||
PartialSumSigma.clearAndDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlung::SetPhysicsTableBining(G4double lowE, G4double highE, G4int nBins)
|
||||
{
|
||||
LowestKineticEnergy = lowE; HighestKineticEnergy = highE; TotBin = nBins;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
// just call BuildLossTable+BuildLambdaTable
|
||||
{
|
||||
|
||||
BuildLossTable(aParticleType) ;
|
||||
|
||||
if (&aParticleType==G4Electron::Electron())
|
||||
{
|
||||
RecorderOfElectronProcess[CounterOfElectronProcess] = (*this).theLossTable ;
|
||||
CounterOfElectronProcess++;
|
||||
}
|
||||
else
|
||||
{
|
||||
RecorderOfPositronProcess[CounterOfPositronProcess] = (*this).theLossTable ;
|
||||
CounterOfPositronProcess++;
|
||||
}
|
||||
|
||||
BuildLambdaTable(aParticleType) ;
|
||||
|
||||
BuildDEDXTable (aParticleType) ;
|
||||
|
||||
if(&aParticleType==G4Electron::Electron())
|
||||
PrintInfoDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
// Build table for energy loss due to soft brems
|
||||
// tables are built for *MATERIALS*
|
||||
{
|
||||
G4double KineticEnergy,TotalEnergy,bremloss,Z,x,
|
||||
losslim,loss,rate,natom,Cut;
|
||||
|
||||
const G4double MinKineticEnergy = 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();
|
||||
|
||||
// create table
|
||||
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length() ;
|
||||
|
||||
if (theLossTable) { theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
|
||||
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>MinKineticEnergy)
|
||||
{
|
||||
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 = 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);
|
||||
}
|
||||
|
||||
theLossTable->insert(aVector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eBremsstrahlung::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....
|
||||
|
||||
G4double G4eBremsstrahlung::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....
|
||||
|
||||
G4double G4eBremsstrahlung::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....
|
||||
|
||||
void G4eBremsstrahlung::BuildLambdaTable(const G4ParticleDefinition& ParticleType)
|
||||
|
||||
// Build mean free path tables for the gamma emission by e- or e+.
|
||||
// tables are Build for MATERIALS.
|
||||
{
|
||||
G4double LowEdgeEnergy , Value;
|
||||
G4double FixedEnergy = (LowestKineticEnergy + HighestKineticEnergy)/2.;
|
||||
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
|
||||
//create table
|
||||
if (theMeanFreePathTable) {theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
theMeanFreePathTable = new G4PhysicsTable(G4Material::GetNumberOfMaterials());
|
||||
|
||||
PartialSumSigma.resize(G4Material::GetNumberOfMaterials());
|
||||
G4PhysicsLogVector* ptrVector;
|
||||
for ( G4int J=0 ; J < G4Material::GetNumberOfMaterials(); J++ )
|
||||
{
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(LowestKineticEnergy, HighestKineticEnergy,
|
||||
TotBin ) ;
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
|
||||
for ( G4int i = 0 ; i < TotBin ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
|
||||
Value = ComputeMeanFreePath( &ParticleType, LowEdgeEnergy,
|
||||
material );
|
||||
ptrVector->PutValue( i , Value ) ;
|
||||
}
|
||||
|
||||
theMeanFreePathTable->insertAt( J , ptrVector );
|
||||
|
||||
// Compute the PartialSumSigma table at a given fixed energy
|
||||
ComputePartialSumSigma( &ParticleType, FixedEnergy, material) ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlung::ComputePartialSumSigma(const G4ParticleDefinition* ParticleType,
|
||||
G4double KineticEnergy,
|
||||
const G4Material* aMaterial)
|
||||
|
||||
// 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.
|
||||
{
|
||||
G4int Imate = aMaterial->GetIndex();
|
||||
G4int NbOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
|
||||
G4double GammaEnergyCut = (G4Gamma::GetCutsInEnergy())[Imate];
|
||||
|
||||
PartialSumSigma(Imate) = new G4ValVector(NbOfElements);
|
||||
|
||||
G4double SIGMA = 0. ;
|
||||
|
||||
for ( G4int Ielem=0 ; Ielem < NbOfElements ; Ielem++ )
|
||||
{
|
||||
SIGMA += theAtomNumDensityVector[Ielem] *
|
||||
ComputeMicroscopicCrossSection( ParticleType, KineticEnergy,
|
||||
(*theElementVector)(Ielem)->GetZ(),
|
||||
GammaEnergyCut );
|
||||
PartialSumSigma(Imate)->insertAt(Ielem, SIGMA);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eBremsstrahlung::ComputeMicroscopicCrossSection(
|
||||
const G4ParticleDefinition* ParticleType,
|
||||
G4double KineticEnergy, G4double AtomicNumber,
|
||||
G4double GammaEnergyCut)
|
||||
|
||||
// Calculates the microscopic cross section in GEANT4 internal units.
|
||||
// A parametrized formula from L. Urban is used to estimate the total cross section.
|
||||
// This parametrization is derived from :
|
||||
// tabulated cross-section values of Seltzer and Berger below 10 GeV,
|
||||
// screened Bethe Heilter differential cross section above 10 GeV,
|
||||
// Migdal corrections in both case.
|
||||
// Seltzer & Berger: Nim B 12:95 (1985)
|
||||
// Nelson, Hirayama & Rogers: Technical report 265 SLAC (1985)
|
||||
// Migdal: Phys Rev 103:1811 (1956); Messel & Crawford: Pergamon Press (1970)
|
||||
//
|
||||
// Above 100 GeV the Cross section is scaled in log(KineticEnergy).
|
||||
|
||||
{
|
||||
G4double CrossSection = 0.0 ;
|
||||
if ( KineticEnergy < 1*keV ) return CrossSection;
|
||||
if ( KineticEnergy <= GammaEnergyCut ) return CrossSection;
|
||||
|
||||
G4double LocalKineticEnergy = KineticEnergy, LocalGammaEnergyCut = GammaEnergyCut;
|
||||
|
||||
const G4double KinLimitScale = 100.*GeV, CutLimitScale = 50.*GeV;
|
||||
|
||||
|
||||
const G4double Tlim = 1.*MeV;
|
||||
if (KineticEnergy < Tlim) LocalKineticEnergy = Tlim;
|
||||
|
||||
if (KineticEnergy > KinLimitScale)
|
||||
{ LocalKineticEnergy = KinLimitScale;
|
||||
if (GammaEnergyCut > KinLimitScale) LocalGammaEnergyCut = CutLimitScale;
|
||||
}
|
||||
|
||||
static const G4double
|
||||
aay0x0= 0.430748E-02*barn, aay0x1= 0.576058E-02*barn, aay0x2=-0.122564E-02*barn,
|
||||
aay0x3= 0.114843E-03*barn, aay0x4=-0.489452E-05*barn, aay0x5= 0.795991E-07*barn;
|
||||
|
||||
static const G4double
|
||||
aay1x0= 0.326746E-02*barn, aay1x1=-0.132872E-02*barn, aay1x2= 0.217197E-03*barn,
|
||||
aay1x3=-0.179769E-04*barn, aay1x4= 0.766114E-06*barn, aay1x5=-0.125603E-07*barn;
|
||||
|
||||
static const G4double
|
||||
amy2x0= 0.326452E-02*barn, amy2x1=-0.175331E-02*barn, amy2x2= 0.415488E-03*barn,
|
||||
amy2x3=-0.507652E-04*barn, amy2x4= 0.297569E-05*barn, amy2x5=-0.651741E-07*barn;
|
||||
|
||||
static const G4double
|
||||
amy3x0= 0.847189E-03*barn, amy3x1=-0.433923E-03*barn, amy3x2= 0.116672E-03*barn,
|
||||
amy3x3=-0.166799E-04*barn, amy3x4= 0.110237E-05*barn, amy3x5=-0.263383E-07*barn;
|
||||
|
||||
static const G4double
|
||||
amy4x0= 0.846052E-04*barn, amy4x1=-0.415764E-04*barn, amy4x2= 0.129610E-04*barn,
|
||||
amy4x3=-0.212844E-05*barn, amy4x4= 0.152871E-06*barn, amy4x5=-0.384393E-08*barn;
|
||||
|
||||
static const G4double
|
||||
amy5x0= 0.300838E-05*barn, amy5x1=-0.136833E-05*barn, amy5x2= 0.507296E-06*barn,
|
||||
amy5x3=-0.943623E-07*barn, amy5x4= 0.720305E-08*barn, amy5x5=-0.187210E-09*barn;
|
||||
|
||||
static const G4double
|
||||
apy2x0= 0.448230E-01*barn, apy2x1=-0.210048E-01*barn, apy2x2= 0.379434E-02*barn,
|
||||
apy2x3=-0.328431E-03*barn, apy2x4= 0.136710E-04*barn, apy2x5=-0.220593E-06*barn;
|
||||
|
||||
static const G4double
|
||||
apy3x0=-0.539248E-02*barn, apy3x1= 0.330244E-02*barn, apy3x2=-0.733726E-03*barn,
|
||||
apy3x3= 0.732312E-04*barn, apy3x4=-0.336810E-05*barn, apy3x5= 0.583913E-07*barn;
|
||||
|
||||
static const G4double
|
||||
apy4x0=-0.106983E-02*barn, apy4x1= 0.378021E-03*barn, apy4x2=-0.384854E-04*barn,
|
||||
apy4x3= 0.978156E-06*barn, apy4x4= 0.410622E-07*barn, apy4x5=-0.174250E-08*barn;
|
||||
|
||||
static const G4double
|
||||
apy5x0=-0.117501E-04*barn, apy5x1=-0.983887E-05*barn, apy5x2= 0.239644E-05*barn,
|
||||
apy5x3=-0.190104E-06*barn, apy5x4= 0.619226E-08*barn, apy5x5=-0.680932E-10*barn;
|
||||
|
||||
static const G4double
|
||||
bby0x0= 0.168074E-03*barn, bby0x1=-0.934609E-04*barn, bby0x2= 0.141293E-04*barn,
|
||||
bby0x3=-0.854216E-06*barn, bby0x4= 0.183287E-07*barn;
|
||||
|
||||
static const G4double
|
||||
bby1x0= 0.932144E-04*barn, bby1x1=-0.234926E-04*barn, bby1x2= 0.136656E-05*barn,
|
||||
bby1x3= 0.351109E-07*barn, bby1x4=-0.330189E-08*barn;
|
||||
|
||||
static const G4double
|
||||
bmy2x0= 0.174523E-04*barn, bmy2x1= 0.253854E-05*barn, bmy2x2=-0.171643E-05*barn,
|
||||
bmy2x3= 0.183074E-06*barn, bmy2x4=-0.566331E-08*barn;
|
||||
|
||||
static const G4double
|
||||
bmy3x0= 0.111970E-05*barn, bmy3x1= 0.112776E-05*barn, bmy3x2=-0.386924E-06*barn,
|
||||
bmy3x3= 0.367597E-07*barn, bmy3x4=-0.108504E-08*barn;
|
||||
|
||||
static const G4double
|
||||
bmy4x0= 0.171604E-07*barn, bmy4x1= 0.738801E-07*barn, bmy4x2=-0.218761E-07*barn,
|
||||
bmy4x3= 0.199032E-08*barn, bmy4x4=-0.576173E-10*barn;
|
||||
|
||||
static const G4double
|
||||
bpy2x0=-0.105531E-03*barn, bpy2x1= 0.362995E-04*barn, bpy2x2=-0.433334E-05*barn,
|
||||
bpy2x3= 0.207664E-06*barn, bpy2x4=-0.330250E-08*barn;
|
||||
|
||||
static const G4double
|
||||
bpy3x0=-0.168293E-05*barn, bpy3x1=-0.773204E-06*barn, bpy3x2= 0.227974E-06*barn,
|
||||
bpy3x3=-0.159385E-07*barn, bpy3x4= 0.321958E-09*barn;
|
||||
|
||||
static const G4double
|
||||
bpy4x0= 0.167046E-05*barn, bpy4x1=-0.440761E-06*barn, bpy4x2= 0.396377E-07*barn,
|
||||
bpy4x3=-0.151053E-08*barn, bpy4x4= 0.215624E-10*barn;
|
||||
|
||||
static const G4double ksi=1.8, alfa=0.98, vs= 1.E-4;
|
||||
|
||||
G4double TotalEnergy = LocalKineticEnergy + electron_mass_c2;
|
||||
G4double X = log(TotalEnergy/electron_mass_c2), X2=X*X, X3=X2*X, X4=X3*X, X5=X4*X;
|
||||
G4double Y = log(vs*TotalEnergy/LocalGammaEnergyCut), Y2=Y*Y, Y3=Y2*Y, Y4=Y3*Y, Y5=Y4*Y;
|
||||
|
||||
G4double ay0, ay1, ay2, ay3, ay4, ay5, by0, by1, by2, by3, by4;
|
||||
if (Y < 0.) {
|
||||
ay0 = aay0x0 + aay0x1*X + aay0x2*X2 + aay0x3*X3 + aay0x4*X4 + aay0x5*X5;
|
||||
ay1 = aay1x0 + aay1x1*X + aay1x2*X2 + aay1x3*X3 + aay1x4*X4 + aay1x5*X5;
|
||||
ay2 = amy2x0 + amy2x1*X + amy2x2*X2 + amy2x3*X3 + amy2x4*X4 + amy2x5*X5;
|
||||
ay3 = amy3x0 + amy3x1*X + amy3x2*X2 + amy3x3*X3 + amy3x4*X4 + amy3x5*X5;
|
||||
ay4 = amy4x0 + amy4x1*X + amy4x2*X2 + amy4x3*X3 + amy4x4*X4 + amy4x5*X5;
|
||||
ay5 = amy5x0 + amy5x1*X + amy5x2*X2 + amy5x3*X3 + amy5x4*X4 + amy5x5*X5;
|
||||
|
||||
by0 = bby0x0 + bby0x1*X + bby0x2*X2 + bby0x3*X3 + bby0x4*X4;
|
||||
by1 = bby1x0 + bby1x1*X + bby1x2*X2 + bby1x3*X3 + bby1x4*X4;
|
||||
by2 = bmy2x0 + bmy2x1*X + bmy2x2*X2 + bmy2x3*X3 + bmy2x4*X4;
|
||||
by3 = bmy3x0 + bmy3x1*X + bmy3x2*X2 + bmy3x3*X3 + bmy3x4*X4;
|
||||
by4 = bmy4x0 + bmy4x1*X + bmy4x2*X2 + bmy4x3*X3 + bmy4x4*X4;
|
||||
}
|
||||
else {
|
||||
ay0 = aay0x0 + aay0x1*X + aay0x2*X2 + aay0x3*X3 + aay0x4*X4 + aay0x5*X5;
|
||||
ay1 = aay1x0 + aay1x1*X + aay1x2*X2 + aay1x3*X3 + aay1x4*X4 + aay1x5*X5;
|
||||
ay2 = apy2x0 + apy2x1*X + apy2x2*X2 + apy2x3*X3 + apy2x4*X4 + apy2x5*X5;
|
||||
ay3 = apy3x0 + apy3x1*X + apy3x2*X2 + apy3x3*X3 + apy3x4*X4 + apy3x5*X5;
|
||||
ay4 = apy4x0 + apy4x1*X + apy4x2*X2 + apy4x3*X3 + apy4x4*X4 + apy4x5*X5;
|
||||
ay5 = apy5x0 + apy5x1*X + apy5x2*X2 + apy5x3*X3 + apy5x4*X4 + apy5x5*X5;
|
||||
|
||||
by0 = bby0x0 + bby0x1*X + bby0x2*X2 + bby0x3*X3 + bby0x4*X4;
|
||||
by1 = bby1x0 + bby1x1*X + bby1x2*X2 + bby1x3*X3 + bby1x4*X4;
|
||||
by2 = bpy2x0 + bpy2x1*X + bpy2x2*X2 + bpy2x3*X3 + bpy2x4*X4;
|
||||
by3 = bpy3x0 + bpy3x1*X + bpy3x2*X2 + bpy3x3*X3 + bpy3x4*X4;
|
||||
by4 = bpy4x0 + bpy4x1*X + bpy4x2*X2 + bpy4x3*X3 + bpy4x4*X4;
|
||||
}
|
||||
|
||||
G4double F0 = ay0 + ay1*Y + ay2*Y2 + ay3*Y3 + ay4*Y4 + ay5*Y5,
|
||||
F1 = by0 + by1*Y + by2*Y2 + by3*Y3 + by4*Y4;
|
||||
|
||||
CrossSection = AtomicNumber*(AtomicNumber+ksi)*TotalEnergy*TotalEnergy
|
||||
* pow(log(LocalKineticEnergy/LocalGammaEnergyCut),alfa)
|
||||
* (F0 + F1*AtomicNumber)
|
||||
/ (LocalKineticEnergy*(LocalKineticEnergy+2*electron_mass_c2));
|
||||
|
||||
if (ParticleType == G4Positron::Positron())
|
||||
CrossSection *= ComputePositronCorrFactorSigma(AtomicNumber, LocalKineticEnergy,
|
||||
LocalGammaEnergyCut);
|
||||
|
||||
if (KineticEnergy < Tlim) CrossSection *= log(KineticEnergy/GammaEnergyCut)
|
||||
/log(Tlim/GammaEnergyCut);
|
||||
|
||||
|
||||
// now comes the scaling above 100GeV
|
||||
if (KineticEnergy > KinLimitScale)
|
||||
{ G4double X1 = GammaEnergyCut/KineticEnergy,
|
||||
X2 = LocalGammaEnergyCut/LocalKineticEnergy;
|
||||
CrossSection *= (-log(X1) -2./3. + X1 - X1*X1/3.)/(-log(X2) -2./3. + X2 - X2*X2/3.);
|
||||
}
|
||||
|
||||
if (CrossSection < 0.) CrossSection = 0.;
|
||||
return CrossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eBremsstrahlung::ComputePositronCorrFactorSigma( G4double AtomicNumber,
|
||||
G4double KineticEnergy, G4double GammaEnergyCut)
|
||||
|
||||
// Calculates the correction factor for the total cross section of the positron bremsstrahl.
|
||||
// Eta is the ratio of positron to electron energy loss by bremstrahlung.
|
||||
// A parametrized formula from L. Urban is used to estimate eta. It is a fit to the results
|
||||
// of L. Kim & al: Phys Rev. A33,3002 (1986)
|
||||
|
||||
{
|
||||
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*AtomicNumber*AtomicNumber));
|
||||
G4double eta = 0.5 + atan(a1*x + a3*x*x*x + a5*x*x*x*x*x)/pi ;
|
||||
G4double alfa = (1. - eta)/eta;
|
||||
return eta*pow((1. - GammaEnergyCut/KineticEnergy) , alfa);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4eBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
//
|
||||
// The emitted gamma energy is sampled using a parametrized formula from L. Urban.
|
||||
// This parametrization is derived from :
|
||||
// cross-section values of Seltzer and Berger for electron energies 1 keV - 10 GeV,
|
||||
// screened Bethe Heilter differential cross section above 10 GeV,
|
||||
// Migdal corrections in both case.
|
||||
// Seltzer & Berger: Nim B 12:95 (1985)
|
||||
// Nelson, Hirayama & Rogers: Technical report 265 SLAC (1985)
|
||||
// Migdal: Phys Rev 103:1811 (1956); Messel & Crawford: Pergamon Press (1970)
|
||||
//
|
||||
// A modified version of the random number techniques of Butcher & Messel is used
|
||||
// (Nuc Phys 20(1960),15).
|
||||
//
|
||||
// GEANT4 internal units.
|
||||
//
|
||||
{
|
||||
static const G4double
|
||||
ah10 = 4.67733E+00, ah11 =-6.19012E-01, ah12 = 2.02225E-02,
|
||||
ah20 =-7.34101E+00, ah21 = 1.00462E+00, ah22 =-3.20985E-02,
|
||||
ah30 = 2.93119E+00, ah31 =-4.03761E-01, ah32 = 1.25153E-02;
|
||||
|
||||
static const G4double
|
||||
bh10 = 4.23071E+00, bh11 =-6.10995E-01, bh12 = 1.95531E-02,
|
||||
bh20 =-7.12527E+00, bh21 = 9.69160E-01, bh22 =-2.74255E-02,
|
||||
bh30 = 2.69925E+00, bh31 =-3.63283E-01, bh32 = 9.55316E-03;
|
||||
|
||||
static const G4double
|
||||
al00 =-2.05398E+00, al01 = 2.38815E-02, al02 = 5.25483E-04,
|
||||
al10 =-7.69748E-02, al11 =-6.91499E-02, al12 = 2.22453E-03,
|
||||
al20 = 4.06463E-02, al21 =-1.01281E-02, al22 = 3.40919E-04;
|
||||
|
||||
static const G4double
|
||||
bl00 = 1.04133E+00, bl01 =-9.43291E-03, bl02 =-4.54758E-04,
|
||||
bl10 = 1.19253E-01, bl11 = 4.07467E-02, bl12 =-1.30718E-03,
|
||||
bl20 =-1.59391E-02, bl21 = 7.27752E-03, bl22 =-1.94405E-04;
|
||||
|
||||
static 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 KineticEnergy = aDynamicParticle->GetKineticEnergy();
|
||||
G4ParticleMomentum ParticleDirection = aDynamicParticle->GetMomentumDirection();
|
||||
|
||||
// Gamma production cut in this material
|
||||
G4double GammaEnergyCut = (G4Gamma::GetCutsInEnergy())[aMaterial->GetIndex()];
|
||||
|
||||
// check against insufficient energy
|
||||
if (KineticEnergy < GammaEnergyCut)
|
||||
{
|
||||
aParticleChange.SetMomentumChange( ParticleDirection );
|
||||
aParticleChange.SetEnergyChange( KineticEnergy );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
// select randomly one element constituing the material
|
||||
G4Element* anElement = SelectRandomAtom(aMaterial);
|
||||
|
||||
// Extract Z factors for this Element
|
||||
G4double lnZ = 3.*(anElement->GetIonisation()->GetlogZ3());
|
||||
G4double FZ = lnZ* (4.- 0.55*lnZ);
|
||||
G4double ZZ = anElement->GetIonisation()->GetZZ3();
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double TotalEnergy = KineticEnergy + electron_mass_c2;
|
||||
G4double TotalEnergysquare = TotalEnergy*TotalEnergy ;
|
||||
G4double LPMGammaEnergyLimit = TotalEnergysquare/LPMEnergy ;
|
||||
|
||||
G4double xmin = GammaEnergyCut/KineticEnergy, epsilmin = GammaEnergyCut/TotalEnergy;
|
||||
G4double epsilmax = KineticEnergy/TotalEnergy;
|
||||
|
||||
// Migdal factor
|
||||
G4double MigdalFactor = (aMaterial->GetElectronDensity())*MigdalConstant
|
||||
/(epsilmax*epsilmax);
|
||||
|
||||
//
|
||||
G4double x, epsil, greject, migdal, grejmax;
|
||||
G4double U = log(KineticEnergy/electron_mass_c2), U2 = U*U;
|
||||
|
||||
//
|
||||
// sample the energy rate of the emitted gamma for electron kinetic energy > 1 MeV
|
||||
//
|
||||
|
||||
if (KineticEnergy > 1.*MeV)
|
||||
{
|
||||
// parameters
|
||||
G4double ah1 = ah10 + ZZ* (ah11 + ZZ* ah12),
|
||||
ah2 = ah20 + ZZ* (ah21 + ZZ* ah22),
|
||||
ah3 = ah30 + ZZ* (ah31 + ZZ* ah32);
|
||||
|
||||
G4double bh1 = bh10 + ZZ* (bh11 + ZZ* bh12),
|
||||
bh2 = bh20 + ZZ* (bh21 + ZZ* bh22),
|
||||
bh3 = bh30 + ZZ* (bh31 + ZZ* bh32);
|
||||
|
||||
G4double ah = 1. + (ah1*U2 + ah2*U + ah3) / (U2*U);
|
||||
G4double bh = 0.75 + (bh1*U2 + bh2*U + bh3) / (U2*U);
|
||||
|
||||
// limit of the screening variable
|
||||
G4double screenfac =
|
||||
136.*electron_mass_c2/((anElement->GetIonisation()->GetZ3())*TotalEnergy);
|
||||
G4double screenmin = screenfac*epsilmin/(1.-epsilmin);
|
||||
|
||||
// Compute the maximum of the rejection function
|
||||
G4double F1 = max(ScreenFunction1(screenmin) - FZ ,0.);
|
||||
G4double F2 = max(ScreenFunction2(screenmin) - FZ ,0.);
|
||||
grejmax = (F1 - epsilmin* (F1*ah - bh*epsilmin*F2))/(42.392 - FZ);
|
||||
|
||||
// sample the energy rate of the emitted Gamma
|
||||
G4double screenvar;
|
||||
|
||||
do {
|
||||
|
||||
x = pow(xmin, G4UniformRand());
|
||||
epsil = x*KineticEnergy/TotalEnergy;
|
||||
screenvar = screenfac*epsil/(1-epsil);
|
||||
F1 = max(ScreenFunction1(screenvar) - FZ ,0.);
|
||||
F2 = max(ScreenFunction2(screenvar) - FZ ,0.);
|
||||
migdal = (1. + MigdalFactor)/(1. + MigdalFactor/(x*x));
|
||||
greject = migdal*(F1 - epsil* (ah*F1 - bh*epsil*F2))/(42.392 - FZ);
|
||||
} while( greject < G4UniformRand()*grejmax );
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// sample the energy rate of the emitted gamma for electron kinetic energy < 1 MeV
|
||||
//
|
||||
// parameters
|
||||
G4double al0 = al00 + ZZ* (al01 + ZZ* al02),
|
||||
al1 = al10 + ZZ* (al11 + ZZ* al12),
|
||||
al2 = al20 + ZZ* (al21 + ZZ* al22);
|
||||
|
||||
G4double bl0 = bl00 + ZZ* (bl01 + ZZ* bl02),
|
||||
bl1 = bl10 + ZZ* (bl11 + ZZ* bl12),
|
||||
bl2 = bl20 + ZZ* (bl21 + ZZ* bl22);
|
||||
|
||||
G4double al = al0 + al1*U + al2*U2;
|
||||
G4double bl = bl0 + bl1*U + bl2*U2;
|
||||
|
||||
// Compute the maximum of the rejection function
|
||||
grejmax = max(1. + xmin* (al + bl*xmin), 1.+al+bl);
|
||||
G4double xm = -al/(2.*bl);
|
||||
if ((xmin < xm)&&(xm < 1.)) grejmax = max(grejmax, 1.+ xm* (al + bl*xm));
|
||||
|
||||
// sample the energy rate of the emitted Gamma
|
||||
|
||||
do { x = pow(xmin, G4UniformRand());
|
||||
migdal = (1. + MigdalFactor)/(1. + MigdalFactor/(x*x));
|
||||
greject = migdal*(1. + x* (al + bl*x));
|
||||
} while( greject < G4UniformRand()*grejmax );
|
||||
}
|
||||
|
||||
G4double GammaEnergy = x*KineticEnergy;
|
||||
|
||||
// now comes the supression due to the LPM effect
|
||||
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.)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
|
||||
//
|
||||
// angles of the emitted gamma. ( Z - axis along the parent particle)
|
||||
//
|
||||
// universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
|
||||
// derived from Tsai distribution (Rev Mod Phys 49,421(1977))
|
||||
|
||||
G4double u;
|
||||
const G4double a1 = 0.625 , a2 = 3.*a1 , d = 27. ;
|
||||
|
||||
if (9./(9.+d) > G4UniformRand()) u = - log(G4UniformRand()*G4UniformRand())/a1 ;
|
||||
else u = - log(G4UniformRand()*G4UniformRand())/a2 ;
|
||||
|
||||
G4double Teta = u*electron_mass_c2/TotalEnergy ;
|
||||
G4double Phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sin(Teta)*cos(Phi) , diry = sin(Teta)*sin(Phi) , dirz = cos(Teta) ;
|
||||
|
||||
G4ThreeVector GammaDirection ( dirx, diry, dirz);
|
||||
GammaDirection.rotateUz(ParticleDirection);
|
||||
|
||||
// create G4DynamicParticle object for the Gamma
|
||||
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
GammaDirection, GammaEnergy);
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(aGamma);
|
||||
|
||||
//
|
||||
// Update the incident particle
|
||||
//
|
||||
|
||||
G4double NewKinEnergy = KineticEnergy - GammaEnergy;
|
||||
if (NewKinEnergy > 0.)
|
||||
{
|
||||
aParticleChange.SetMomentumChange( ParticleDirection );
|
||||
aParticleChange.SetEnergyChange( NewKinEnergy );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetEnergyChange( 0. );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
if (charge<0.) aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4Element* G4eBremsstrahlung::SelectRandomAtom(G4Material* aMaterial) const
|
||||
{
|
||||
// select randomly 1 element within the material
|
||||
|
||||
const G4int Index = aMaterial->GetIndex();
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
|
||||
G4double rval = G4UniformRand()*((*PartialSumSigma(Index))(NumberOfElements-1));
|
||||
for ( G4int i=0; i < NumberOfElements; i++ )
|
||||
if (rval <= (*PartialSumSigma(Index))(i)) return ((*theElementVector)(i));
|
||||
G4cout << " WARNING !!! - The Material '"<< aMaterial->GetName()
|
||||
<< "' has no elements, NULL pointer returned." << endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlung::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "Total cross sections from a parametrisation(L.Urban). ";
|
||||
comments += "Good description from 1 KeV to 100 GeV.\n";
|
||||
comments += " log scale extrapolation above 100 GeV \n";
|
||||
comments += " Gamma energy sampled from a parametrised formula.";
|
||||
|
||||
G4cout << endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
Reference in New Issue
Block a user