Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -0,0 +1,814 @@
|
||||
// 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: G4MuPairProduction.cc,v 2.10 1998/12/02 16:33:18 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-00 $
|
||||
//
|
||||
// $Id:
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, CN Division, ASD group
|
||||
// History: first implementation, based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// -------- G4MuPairProduction physics process ---------
|
||||
// by Laszlo Urban, May 1998
|
||||
// **************************************************************
|
||||
// 04-06-98, in DoIt,secondary production condition:range>min(threshold,safety)
|
||||
// 26/10/98, new stuff from R. Kokoulin + cleanup , L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4MuPairProduction.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
// static members ........
|
||||
|
||||
G4int G4MuPairProduction::nzdat = 5 ;
|
||||
G4double G4MuPairProduction::zdat[]={1.,4.,13.,26.,92.};
|
||||
G4int G4MuPairProduction::ntdat = 8 ;
|
||||
G4double G4MuPairProduction::tdat[]={1.e3,1.e4,1.e5,1.e6,1.e7,1.e8,1.e9,1.e10};
|
||||
G4int G4MuPairProduction::NBIN = 100 ; //500 ;
|
||||
G4double G4MuPairProduction::ya[1000]={0.};
|
||||
G4double G4MuPairProduction::proba[5][8][1000]={0.};
|
||||
|
||||
G4MuPairProduction::G4MuPairProduction(const G4String& processName)
|
||||
: G4MuEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestKineticEnergy (1.*GeV),
|
||||
HighestKineticEnergy (1000000.*TeV),
|
||||
TotBin(50),
|
||||
theElectron (G4Electron::Electron() ),
|
||||
thePositron (G4Positron::Positron() ),
|
||||
theMuonMinus ( G4MuonMinus::MuonMinus() ),
|
||||
theMuonPlus ( G4MuonPlus::MuonPlus() )
|
||||
{ }
|
||||
|
||||
|
||||
G4MuPairProduction::~G4MuPairProduction()
|
||||
{
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
if (&PartialSumSigma) {
|
||||
PartialSumSigma.clearAndDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
void G4MuPairProduction::SetPhysicsTableBining(G4double lowE,G4double highE,
|
||||
G4int nBins)
|
||||
{
|
||||
LowestKineticEnergy=lowE; HighestKineticEnergy=highE; TotBin=nBins;
|
||||
}
|
||||
|
||||
void G4MuPairProduction::BuildPhysicsTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
// just call BuildLossTable+BuildLambdaTable
|
||||
{
|
||||
BuildLossTable(aParticleType) ;
|
||||
|
||||
if(&aParticleType==theMuonMinus)
|
||||
{
|
||||
RecorderOfmuminusProcess[CounterOfmuminusProcess] = (*this).theLossTable ;
|
||||
CounterOfmuminusProcess++;
|
||||
}
|
||||
else
|
||||
{
|
||||
RecorderOfmuplusProcess[CounterOfmuplusProcess] = (*this).theLossTable ;
|
||||
CounterOfmuplusProcess++;
|
||||
}
|
||||
|
||||
// sampling table should be made only once !
|
||||
if(theMeanFreePathTable == NULL)
|
||||
MakeSamplingTables(&aParticleType) ;
|
||||
|
||||
BuildLambdaTable(aParticleType) ;
|
||||
|
||||
G4MuEnergyLoss::BuildDEDXTable(aParticleType) ;
|
||||
|
||||
if(&aParticleType==theMuonPlus)
|
||||
PrintInfoDefinition() ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4MuPairProduction::BuildLossTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
G4double KineticEnergy,TotalEnergy,pairloss,Z,
|
||||
loss,natom,eCut,pCut ;
|
||||
|
||||
const G4MaterialTable* theMaterialTable =
|
||||
G4Material::GetMaterialTable();
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
ElectronCutInKineticEnergy = (*theElectron).GetEnergyCuts() ;
|
||||
PositronCutInKineticEnergy = (*thePositron).GetEnergyCuts() ;
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length() ;
|
||||
|
||||
if (theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
|
||||
theLossTable = new G4PhysicsTable(numOfMaterials) ;
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy,HighestKineticEnergy,TotBin);
|
||||
ElectronCutInKineticEnergyNow = ElectronCutInKineticEnergy[J] ;
|
||||
PositronCutInKineticEnergyNow = PositronCutInKineticEnergy[J] ;
|
||||
const G4Material* material = (*theMaterialTable)[J] ;
|
||||
const G4ElementVector* theElementVector =
|
||||
material->GetElementVector() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector() ;
|
||||
const G4int NumberOfElements =
|
||||
material->GetNumberOfElements() ;
|
||||
|
||||
for (G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
KineticEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
TotalEnergy = KineticEnergy+ParticleMass ;
|
||||
eCut = ElectronCutInKineticEnergyNow ;
|
||||
pCut = PositronCutInKineticEnergyNow ;
|
||||
|
||||
if(eCut>KineticEnergy)
|
||||
eCut = KineticEnergy ;
|
||||
if(pCut>KineticEnergy)
|
||||
pCut = KineticEnergy ;
|
||||
|
||||
pairloss = 0.;
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++)
|
||||
{
|
||||
Z=(*theElementVector)(iel)->GetZ();
|
||||
natom = theAtomicNumDensityVector[iel] ;
|
||||
loss = ComputePairLoss(&aParticleType,
|
||||
Z,KineticEnergy,eCut,pCut) ;
|
||||
|
||||
pairloss += natom*loss ;
|
||||
}
|
||||
if(pairloss<0.)
|
||||
pairloss = 0. ;
|
||||
|
||||
aVector->PutValue(i,pairloss);
|
||||
}
|
||||
|
||||
theLossTable->insert(aVector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4double G4MuPairProduction::ComputePairLoss(
|
||||
const G4ParticleDefinition* ParticleType,
|
||||
G4double AtomicNumber,
|
||||
G4double KineticEnergy,
|
||||
G4double ElectronEnergyCut,
|
||||
G4double PositronEnergyCut)
|
||||
{
|
||||
static const G4double
|
||||
xgi[] ={ 0.0199,0.1017,0.2372,0.4083,0.5917,0.7628,0.8983,0.9801 };
|
||||
static const G4double
|
||||
wgi[] ={ 0.0506,0.1112,0.1569,0.1813,0.1813,0.1569,0.1112,0.0506 };
|
||||
static const G4double ak1=6.9 ;
|
||||
static const G4double ak2=1.0 ;
|
||||
G4double sqrte = sqrt(exp(1.)) ;
|
||||
G4double z13 = exp(log(AtomicNumber)/3.) ;
|
||||
|
||||
G4double loss = 0.0 ;
|
||||
|
||||
if ( AtomicNumber < 1. ) return loss;
|
||||
|
||||
G4double CutInPairEnergy = ElectronEnergyCut+PositronEnergyCut
|
||||
+2.*electron_mass_c2 ;
|
||||
G4double MinPairEnergy = 4.*electron_mass_c2 ;
|
||||
if( CutInPairEnergy <= MinPairEnergy ) return loss ;
|
||||
|
||||
G4double MaxPairEnergy = KineticEnergy+ParticleMass*(1.-0.75*sqrte*z13) ;
|
||||
if( CutInPairEnergy >= MaxPairEnergy )
|
||||
CutInPairEnergy = MaxPairEnergy ;
|
||||
|
||||
G4double aaa,bbb,hhh,x,epln,ep ;
|
||||
G4int kkk ;
|
||||
// calculate the rectricted loss
|
||||
// numerical integration in log(PairEnergy)
|
||||
aaa = log(MinPairEnergy) ;
|
||||
bbb = log(CutInPairEnergy) ;
|
||||
kkk = int((bbb-aaa)/ak1+ak2) ;
|
||||
hhh = (bbb-aaa)/kkk ;
|
||||
|
||||
for (G4int l=0 ; l<kkk; l++)
|
||||
{
|
||||
x = aaa+hhh*l ;
|
||||
for (G4int ll=0; ll<8; ll++)
|
||||
{
|
||||
epln=x+xgi[ll]*hhh ;
|
||||
ep = exp(epln) ;
|
||||
loss += wgi[ll]*ep*ep*ComputeDMicroscopicCrossSection(ParticleType,
|
||||
KineticEnergy,AtomicNumber,
|
||||
ep) ;
|
||||
}
|
||||
}
|
||||
loss *= hhh ;
|
||||
if (loss < 0.) loss = 0.;
|
||||
return loss ;
|
||||
}
|
||||
|
||||
|
||||
void G4MuPairProduction::BuildLambdaTable(
|
||||
const G4ParticleDefinition& ParticleType)
|
||||
{
|
||||
G4double LowEdgeEnergy , Value;
|
||||
G4double FixedEnergy = (LowestKineticEnergy + HighestKineticEnergy)/2. ;
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
theMeanFreePathTable = new
|
||||
G4PhysicsTable( G4Material::GetNumberOfMaterials() ) ;
|
||||
|
||||
G4PhysicsLogVector* ptrVector;
|
||||
for ( G4int J=0 ; J < G4Material::GetNumberOfMaterials(); J++ )
|
||||
{
|
||||
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) ;
|
||||
}
|
||||
}
|
||||
|
||||
void G4MuPairProduction::ComputePartialSumSigma(
|
||||
const G4ParticleDefinition* ParticleType,
|
||||
G4double KineticEnergy,
|
||||
const G4Material* aMaterial)
|
||||
{
|
||||
G4int Imate = aMaterial->GetIndex();
|
||||
G4int NbOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
const G4double* theAtomNumDensityVector = aMaterial->
|
||||
GetAtomicNumDensityVector();
|
||||
G4double ElectronEnergyCut = (G4Electron::GetCutsInEnergy())[Imate];
|
||||
G4double PositronEnergyCut = (G4Positron::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(),
|
||||
ElectronEnergyCut,PositronEnergyCut );
|
||||
|
||||
PartialSumSigma(Imate)->insertAt(Ielem, SIGMA);
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4MuPairProduction::ComputeMicroscopicCrossSection(
|
||||
const G4ParticleDefinition* ParticleType,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber,
|
||||
G4double ElectronEnergyCut,
|
||||
G4double PositronEnergyCut)
|
||||
|
||||
{
|
||||
static const G4double
|
||||
xgi[] ={ 0.0199,0.1017,0.2372,0.4083,0.5917,0.7628,0.8983,0.9801 };
|
||||
static const G4double
|
||||
wgi[] ={ 0.0506,0.1112,0.1569,0.1813,0.1813,0.1569,0.1112,0.0506 };
|
||||
static const G4double ak1=6.9 ;
|
||||
static const G4double ak2=1.0 ;
|
||||
|
||||
G4double sqrte = sqrt(exp(1.)) ;
|
||||
G4double z13 = exp(log(AtomicNumber)/3.) ;
|
||||
|
||||
G4double CrossSection = 0.0 ;
|
||||
|
||||
if ( AtomicNumber < 1. ) return CrossSection;
|
||||
|
||||
G4double CutInPairEnergy = ElectronEnergyCut+PositronEnergyCut
|
||||
+2.*electron_mass_c2 ;
|
||||
|
||||
if( CutInPairEnergy < 4.*electron_mass_c2 )
|
||||
CutInPairEnergy = 4.*electron_mass_c2 ;
|
||||
|
||||
G4double MaxPairEnergy = KineticEnergy+ParticleMass*(1.-0.75*sqrte*z13) ;
|
||||
if( CutInPairEnergy >= MaxPairEnergy ) return CrossSection ;
|
||||
|
||||
G4double aaa,bbb,hhh,x,epln,ep ;
|
||||
G4int kkk ;
|
||||
// calculate the total cross section
|
||||
// numerical integration in log(PairEnergy)
|
||||
aaa = log(CutInPairEnergy) ;
|
||||
bbb = log(MaxPairEnergy) ;
|
||||
kkk = int((bbb-aaa)/ak1+ak2) ;
|
||||
hhh = (bbb-aaa)/kkk ;
|
||||
for (G4int l=0 ; l<kkk; l++)
|
||||
{
|
||||
x = aaa+hhh*l ;
|
||||
for (G4int ll=0; ll<8; ll++)
|
||||
{
|
||||
epln = x+xgi[ll]*hhh;
|
||||
ep = exp(epln) ;
|
||||
CrossSection += wgi[ll]*ep*ComputeDMicroscopicCrossSection(ParticleType,
|
||||
KineticEnergy,AtomicNumber,
|
||||
ep) ;
|
||||
}
|
||||
}
|
||||
CrossSection *= hhh ;
|
||||
|
||||
if (CrossSection < 0.) CrossSection = 0.;
|
||||
|
||||
return CrossSection;
|
||||
}
|
||||
|
||||
void G4MuPairProduction::MakeSamplingTables(
|
||||
const G4ParticleDefinition* ParticleType)
|
||||
{
|
||||
G4double epbin[1000],xbin[1000],prbin[1000] ;
|
||||
G4int nbin;
|
||||
G4double AtomicNumber,KineticEnergy,MinPairEnergy ;
|
||||
G4double c,y,ymin,ymax,dy,yy,dx,x,ep ;
|
||||
|
||||
MinPairEnergy = 4.*electron_mass_c2 ;
|
||||
|
||||
G4double sqrte = sqrt(exp(1.)) ;
|
||||
|
||||
for (G4int iz=0; iz<nzdat; iz++)
|
||||
{
|
||||
AtomicNumber = zdat[iz];
|
||||
G4double z13 = exp(log(AtomicNumber)/3.) ;
|
||||
|
||||
for (G4int it=0; it<ntdat; it++)
|
||||
{
|
||||
KineticEnergy = tdat[it];
|
||||
G4double MaxPairEnergy = KineticEnergy+ParticleMass*(1.-0.75*sqrte*z13) ;
|
||||
|
||||
G4double CrossSection = 0.0 ;
|
||||
|
||||
G4int NbofIntervals ;
|
||||
c = log(MaxPairEnergy/MinPairEnergy) ;
|
||||
|
||||
ymin = -5. ;
|
||||
ymax = 0. ;
|
||||
dy = (ymax-ymin)/NBIN ;
|
||||
nbin=-1;
|
||||
y = ymin - 0.5*dy ;
|
||||
yy = ymin - dy ;
|
||||
for (G4int i=0 ; i<NBIN; i++)
|
||||
{
|
||||
y += dy ;
|
||||
x = exp(y) ;
|
||||
yy += dy ;
|
||||
dx = exp(yy+dy)-exp(yy) ;
|
||||
ep = MinPairEnergy*exp(c*x) ;
|
||||
CrossSection += ep*dx*ComputeDMicroscopicCrossSection(ParticleType,
|
||||
KineticEnergy,AtomicNumber,ep);
|
||||
if(nbin<NBIN)
|
||||
{
|
||||
nbin += 1 ;
|
||||
epbin[nbin]=ep;
|
||||
xbin[nbin]=x;
|
||||
prbin[nbin]=CrossSection ;
|
||||
ya[nbin]=y ;
|
||||
proba[iz][it][nbin] = CrossSection ;
|
||||
}
|
||||
}
|
||||
|
||||
if(CrossSection > 0.)
|
||||
{
|
||||
for(G4int ib=0; ib<=nbin; ib++)
|
||||
{
|
||||
prbin[ib] /= CrossSection ;
|
||||
proba[iz][it][ib] /= CrossSection ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4double G4MuPairProduction::ComputeDDMicroscopicCrossSection(
|
||||
const G4ParticleDefinition* ParticleType,
|
||||
G4double KineticEnergy, G4double AtomicNumber,
|
||||
G4double PairEnergy,G4double asymmetry)
|
||||
// Calculates the double differential (DD) microscopic cross section
|
||||
// using the cross section formula of R.P. Kokoulin (18/01/98)
|
||||
{
|
||||
G4double sqrte = sqrt(exp(1.)) ;
|
||||
|
||||
G4double bbbtf= 183. ;
|
||||
G4double bbbh = 202.4 ;
|
||||
G4double g1tf = 1.95e-5 ;
|
||||
G4double g2tf = 5.3e-5 ;
|
||||
G4double g1h = 4.4e-5 ;
|
||||
G4double g2h = 4.8e-5 ;
|
||||
|
||||
G4double massratio = ParticleMass/electron_mass_c2 ;
|
||||
G4double massratio2 = massratio*massratio ;
|
||||
G4double TotalEnergy = KineticEnergy + ParticleMass ;
|
||||
G4double z13 = exp(log(AtomicNumber)/3.) ;
|
||||
G4double z23 = z13*z13 ;
|
||||
G4double EnergyLoss = TotalEnergy - PairEnergy ;
|
||||
|
||||
G4double c3 = 3.*sqrte*ParticleMass/4. ;
|
||||
|
||||
G4double DDCrossSection = 0. ;
|
||||
|
||||
if(EnergyLoss <= c3*z13)
|
||||
return DDCrossSection ;
|
||||
|
||||
G4double c7 = 4.*electron_mass_c2 ;
|
||||
G4double c8 = 6.*ParticleMass*ParticleMass ;
|
||||
G4double alf = c7/PairEnergy ;
|
||||
G4double a3 = 1. - alf ;
|
||||
|
||||
if(a3 <= 0.)
|
||||
return DDCrossSection ;
|
||||
|
||||
// zeta calculation
|
||||
G4double bbb,g1,g2,zeta1,zeta2,zeta,z2 ;
|
||||
if( AtomicNumber < 1.5 )
|
||||
{
|
||||
bbb = bbbh ;
|
||||
g1 = g1h ;
|
||||
g2 = g2h ;
|
||||
}
|
||||
else
|
||||
{
|
||||
bbb = bbbtf ;
|
||||
g1 = g1tf ;
|
||||
g2 = g2tf ;
|
||||
}
|
||||
zeta1 = 0.073 * log(TotalEnergy/(ParticleMass+g1*z23*TotalEnergy))-0.26 ;
|
||||
if( zeta1 > 0.)
|
||||
{
|
||||
zeta2 = 0.058*log(TotalEnergy/(ParticleMass+g2*z13*TotalEnergy))-0.14 ;
|
||||
zeta = zeta1/zeta2 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
zeta = 0. ;
|
||||
}
|
||||
|
||||
z2 = AtomicNumber*(AtomicNumber+zeta) ;
|
||||
|
||||
G4double screen0 = 2.*electron_mass_c2*sqrte*bbb/(z13*PairEnergy) ;
|
||||
G4double a0 = TotalEnergy*EnergyLoss ;
|
||||
G4double a1 = PairEnergy*PairEnergy/a0 ;
|
||||
G4double bet = 0.5*a1 ;
|
||||
G4double xi0 = 0.25*massratio2*a1 ;
|
||||
G4double del = c8/a0 ;
|
||||
|
||||
G4double romin = 0. ;
|
||||
G4double romax = (1.-del)*sqrt(1.-c7/PairEnergy) ;
|
||||
|
||||
if((asymmetry < romin) || (asymmetry > romax))
|
||||
return DDCrossSection ;
|
||||
|
||||
G4double a4 = 1.-asymmetry ;
|
||||
G4double a5 = a4*(2.-a4) ;
|
||||
G4double a6 = 1.-a5 ;
|
||||
G4double a7 = 1.+a6 ;
|
||||
G4double a9 = 3.+a6 ;
|
||||
G4double xi = xi0*a5 ;
|
||||
G4double xii = 1./xi ;
|
||||
G4double xi1 = 1.+xi ;
|
||||
G4double screen = screen0*xi1/a5 ;
|
||||
|
||||
G4double yeu = 5.-a6+4.*bet*a7 ;
|
||||
G4double yed = 2.*(1.+3.*bet)*log(3.+xii)-a6-a1*(2.-a6) ;
|
||||
G4double yel = 1.+yeu/yed ;
|
||||
G4double ale=log(bbb/z13*sqrt(xi1*yel)/(1.+screen*yel)) ;
|
||||
G4double cre = 0.5*log(1.+2.25/(massratio2*z23)*xi1*yel) ;
|
||||
G4double be ;
|
||||
if(xi <= 1.e3)
|
||||
be = ((2.+a6)*(1.+bet)+xi*a9)*log(1.+xii)+(a5-bet)/xi1-a9;
|
||||
else
|
||||
be = (3.-a6+a1*a7)/(2.+xi) ;
|
||||
G4double fe = (ale-cre)*be ;
|
||||
if( fe < 0.)
|
||||
fe = 0. ;
|
||||
|
||||
G4double ymu = 4.+a6 +3.*bet*a7 ;
|
||||
G4double ymd = a7*(1.5+a1)*log(3.+xi)+1.-1.5*a6 ;
|
||||
G4double ym1 = 1.+ymu/ymd ;
|
||||
G4double alm_crm = log(bbb*massratio/(1.5*z23*(1.+screen*ym1))) ;
|
||||
G4double a10,bm ;
|
||||
if( xi >= 1.e-3)
|
||||
{
|
||||
a10 = (1.+a1)*a5 ;
|
||||
bm = (a7*(1.+1.5*bet)-a10*xii)*log(xi1)+xi*(a5-bet)/xi1+a10 ;
|
||||
}
|
||||
else
|
||||
bm = (5.-a6+bet*a9)*(xi/2.) ;
|
||||
G4double fm = alm_crm*bm ;
|
||||
if( fm < 0.)
|
||||
fm = 0. ;
|
||||
|
||||
DDCrossSection = (fe+fm/massratio2) ;
|
||||
|
||||
DDCrossSection *= 4.*fine_structure_const*fine_structure_const
|
||||
*classic_electr_radius*classic_electr_radius/(3.*pi) ;
|
||||
|
||||
DDCrossSection *= z2*EnergyLoss/(TotalEnergy*PairEnergy) ;
|
||||
|
||||
|
||||
return DDCrossSection ;
|
||||
|
||||
}
|
||||
|
||||
G4double G4MuPairProduction::ComputeDMicroscopicCrossSection(
|
||||
const G4ParticleDefinition* ParticleType,
|
||||
G4double KineticEnergy, G4double AtomicNumber,
|
||||
G4double PairEnergy)
|
||||
// Calculates the differential (D) microscopic cross section
|
||||
// using the cross section formula of R.P. Kokoulin (18/01/98)
|
||||
{
|
||||
|
||||
static const G4double
|
||||
xgi[] ={ 0.0199,0.1017,0.2372,0.4083,0.5917,0.7628,0.8983,0.9801 };
|
||||
|
||||
static const G4double
|
||||
wgi[] ={ 0.0506,0.1112,0.1569,0.1813,0.1813,0.1569,0.1112,0.0506 };
|
||||
|
||||
G4double TotalEnergy = KineticEnergy + ParticleMass ;
|
||||
G4double EnergyLoss = TotalEnergy - PairEnergy ;
|
||||
G4double a = 6.*ParticleMass*ParticleMass/(TotalEnergy*EnergyLoss) ;
|
||||
G4double b = 4.*electron_mass_c2/PairEnergy ;
|
||||
G4double tmn=log((b+2.*a*(1.-b))/(1.+(1.-a)*sqrt(1.-b))) ;
|
||||
|
||||
G4double DCrossSection = 0. ;
|
||||
G4double ro ;
|
||||
// Gaussian integration in ln(1-ro) ( with 8 points)
|
||||
for (G4int i=0; i<7; i++)
|
||||
{
|
||||
ro = 1.-exp(tmn*xgi[i]) ;
|
||||
|
||||
DCrossSection += (1.-ro)*ComputeDDMicroscopicCrossSection(
|
||||
ParticleType,KineticEnergy,
|
||||
AtomicNumber,PairEnergy,ro)
|
||||
*wgi[i] ;
|
||||
}
|
||||
|
||||
DCrossSection *= -tmn ;
|
||||
|
||||
return DCrossSection ;
|
||||
|
||||
}
|
||||
|
||||
G4VParticleChange* G4MuPairProduction::PostStepDoIt(const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
static const G4double esq = sqrt(exp(1.));
|
||||
|
||||
aParticleChange.Initialize(trackData);
|
||||
G4Material* aMaterial=trackData.GetMaterial() ;
|
||||
const G4DynamicParticle* aDynamicParticle=trackData.GetDynamicParticle();
|
||||
G4double KineticEnergy = aDynamicParticle->GetKineticEnergy();
|
||||
G4ParticleMomentum ParticleDirection =
|
||||
aDynamicParticle->GetMomentumDirection();
|
||||
|
||||
// e-e+ cut in this material
|
||||
G4double ElectronEnergyCut =
|
||||
(G4Electron::GetCutsInEnergy())[aMaterial->GetIndex()];
|
||||
G4double PositronEnergyCut =
|
||||
(G4Electron::GetCutsInEnergy())[aMaterial->GetIndex()];
|
||||
G4double CutInPairEnergy = ElectronEnergyCut + PositronEnergyCut ;
|
||||
G4double MinPairEnergy = 4.*electron_mass_c2 ;
|
||||
if (CutInPairEnergy < MinPairEnergy) CutInPairEnergy = MinPairEnergy ;
|
||||
|
||||
// check against insufficient energy
|
||||
if (KineticEnergy < CutInPairEnergy )
|
||||
{
|
||||
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);
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double TotalEnergy = KineticEnergy + ParticleMass ;
|
||||
G4double TotalMomentum = sqrt(KineticEnergy*(TotalEnergy+ParticleMass)) ;
|
||||
G4double Z3 = anElement->GetIonisation()->GetZ3() ;
|
||||
G4double MaxPairEnergy = TotalEnergy-0.75*esq*ParticleMass*Z3 ;
|
||||
|
||||
if(MinPairEnergy >= MaxPairEnergy)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
|
||||
// sample e-e+ energy, pair energy first
|
||||
G4double PairEnergy,xc,x,yc,y ;
|
||||
G4int iZ,iT,iy ;
|
||||
|
||||
// select sampling table ;
|
||||
G4double lnZ = log(anElement->GetZ()) ;
|
||||
G4double delmin = 1.e10 ;
|
||||
G4double del ;
|
||||
G4int izz,itt,NBINminus1 ;
|
||||
NBINminus1 = NBIN-1 ;
|
||||
for (G4int iz=0; iz<nzdat; iz++)
|
||||
{
|
||||
del = abs(lnZ-log(zdat[iz])) ;
|
||||
if(del<delmin)
|
||||
{
|
||||
delmin=del ;
|
||||
izz=iz ;
|
||||
}
|
||||
}
|
||||
delmin = 1.e10 ;
|
||||
for (G4int it=0; it<ntdat; it++)
|
||||
{
|
||||
del = abs(log(KineticEnergy)-log(tdat[it])) ;
|
||||
if(del<delmin)
|
||||
{
|
||||
del=delmin;
|
||||
itt=it ;
|
||||
}
|
||||
}
|
||||
|
||||
xc = log(CutInPairEnergy/MinPairEnergy)/log(MaxPairEnergy/MinPairEnergy) ;
|
||||
yc = log(xc) ;
|
||||
|
||||
iy = -1 ;
|
||||
do {
|
||||
iy += 1 ;
|
||||
} while ((ya[iy] < yc )&&(iy < NBINminus1)) ;
|
||||
G4double norm = 1./(1.-proba[izz][itt][iy]) ;
|
||||
|
||||
G4double r = G4UniformRand() ;
|
||||
|
||||
iy = -1 ;
|
||||
do {
|
||||
iy += 1 ;
|
||||
} while (((norm*proba[izz][itt][iy]) < r)&&(iy < NBINminus1)) ;
|
||||
|
||||
//sampling is uniformly in y in the bin
|
||||
if( iy < NBINminus1 )
|
||||
y = ya[iy] + G4UniformRand() * ( ya[iy+1] - ya[iy]) ;
|
||||
else
|
||||
y = ya[iy] ;
|
||||
|
||||
x = exp(y) ;
|
||||
|
||||
PairEnergy = MinPairEnergy*exp(x*log(MaxPairEnergy/MinPairEnergy)) ;
|
||||
|
||||
// sample r=(E+-E-)/PairEnergy ( uniformly .....)
|
||||
G4double rmax = (1.-6.*ParticleMass*ParticleMass/(TotalEnergy*
|
||||
(TotalEnergy-PairEnergy)))
|
||||
*sqrt(1.-MinPairEnergy/PairEnergy) ;
|
||||
r = rmax * (-1.+2.*G4UniformRand()) ;
|
||||
|
||||
// compute energies from PairEnergy,r
|
||||
G4double ElectronEnergy=(1.-r)*PairEnergy/2. ;
|
||||
G4double PositronEnergy=(1.+r)*PairEnergy/2. ;
|
||||
|
||||
// angles of the emitted particles ( Z - axis along the parent particle)
|
||||
// (mean theta for the moment)
|
||||
G4double Teta = electron_mass_c2/TotalEnergy ;
|
||||
|
||||
G4double Phi = twopi * G4UniformRand() ;
|
||||
G4double dirx = sin(Teta)*cos(Phi) , diry = sin(Teta)*sin(Phi) ,
|
||||
dirz = cos(Teta) ;
|
||||
|
||||
G4double LocalEnerDeposit = 0. ;
|
||||
G4int numberofsecondaries = 1 ;
|
||||
G4int flagelectron = 0 ;
|
||||
G4int flagpositron = 1 ;
|
||||
G4DynamicParticle *aParticle1,*aParticle2 ;
|
||||
G4double ElectronMomentum , PositronMomentum ;
|
||||
G4double finalPx,finalPy,finalPz ;
|
||||
|
||||
G4double ElectKineEnergy = ElectronEnergy - electron_mass_c2 ;
|
||||
|
||||
if((ElectKineEnergy > ElectronEnergyCut) ||
|
||||
(G4EnergyLossTables::GetRange(
|
||||
G4Electron::Electron(),ElectKineEnergy,aMaterial) >=
|
||||
stepData.GetPostStepPoint()->GetSafety()))
|
||||
{
|
||||
numberofsecondaries += 1 ;
|
||||
flagelectron = 1 ;
|
||||
ElectronMomentum = sqrt(ElectKineEnergy*
|
||||
(ElectronEnergy+electron_mass_c2));
|
||||
G4ThreeVector ElectDirection ( dirx, diry, dirz );
|
||||
ElectDirection.rotateUz(ParticleDirection);
|
||||
|
||||
// create G4DynamicParticle object for the particle1
|
||||
aParticle1= new G4DynamicParticle (G4Electron::Electron(),
|
||||
ElectDirection, ElectKineEnergy);
|
||||
}
|
||||
else
|
||||
{ LocalEnerDeposit += ElectKineEnergy ; }
|
||||
|
||||
// the e+ is always created (even with Ekine=0) for further annihilation.
|
||||
|
||||
G4double PositKineEnergy = PositronEnergy - electron_mass_c2 ;
|
||||
PositronMomentum = sqrt(PositKineEnergy*(PositronEnergy+electron_mass_c2));
|
||||
|
||||
if((PositKineEnergy < PositronEnergyCut) &&
|
||||
(G4EnergyLossTables::GetRange(
|
||||
G4Positron::Positron(),PositKineEnergy,aMaterial) <=
|
||||
stepData.GetPostStepPoint()->GetSafety()))
|
||||
{
|
||||
LocalEnerDeposit += PositKineEnergy ;
|
||||
PositKineEnergy = 0. ;
|
||||
}
|
||||
G4ThreeVector PositDirection ( -dirx, -diry, dirz );
|
||||
PositDirection.rotateUz(ParticleDirection);
|
||||
|
||||
// create G4DynamicParticle object for the particle2
|
||||
aParticle2= new G4DynamicParticle (G4Positron::Positron(),
|
||||
PositDirection, PositKineEnergy);
|
||||
|
||||
// fill particle change and update initial particle
|
||||
aParticleChange.SetNumberOfSecondaries(numberofsecondaries) ;
|
||||
if(flagelectron==1)
|
||||
aParticleChange.AddSecondary( aParticle1 ) ;
|
||||
if(flagpositron==1)
|
||||
aParticleChange.AddSecondary( aParticle2 ) ;
|
||||
|
||||
G4double NewKinEnergy = KineticEnergy - ElectronEnergy - PositronEnergy ;
|
||||
G4double finalMomentum=sqrt(NewKinEnergy*
|
||||
(NewKinEnergy+2.*ParticleMass)) ;
|
||||
|
||||
aParticleChange.SetMomentumChange( ParticleDirection );
|
||||
|
||||
G4double KinEnergyCut = (aDynamicParticle->GetDefinition()->
|
||||
GetEnergyCuts())[aMaterial->GetIndex()];
|
||||
|
||||
if (NewKinEnergy > KinEnergyCut)
|
||||
{
|
||||
aParticleChange.SetEnergyChange( NewKinEnergy );
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
LocalEnerDeposit += NewKinEnergy ;
|
||||
aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit( LocalEnerDeposit ) ;
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
G4Element* G4MuPairProduction::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));
|
||||
}
|
||||
cout << " WARNING !!! - The Material '"<< aMaterial->GetName()
|
||||
<< "' has no elements, NULL pointer returned." << endl;
|
||||
return NULL;
|
||||
}
|
||||
void G4MuPairProduction::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "cross sections from R. Kokoulin \n ";
|
||||
comments += " Good description up to 1000 TeV.";
|
||||
|
||||
G4cout << endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,
|
||||
"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user