Import Geant4 2.0.0 source tree
This commit is contained in:
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4ComptonScattering.cc,v 1.2.8.1.2.1 1999/12/08 17:34:22 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4ComptonScattering.cc,v 1.3 1999/12/15 14:51:50 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -28,7 +28,7 @@
|
||||
// 05-03-97, new Physics scheme, M.Maire
|
||||
// 28-03-97, protection in BuildPhysicsTable, M.Maire
|
||||
// 07-04-98, remove 'tracking cut' of the scattered gamma, MMa
|
||||
// 04-06-98, in DoIt, secondary production condition: range>min(threshold,safety)
|
||||
// 04-06-98, in DoIt, secondary production condition: range>G4std::min(threshold,safety)
|
||||
// 13-08-98, new methods SetBining() PrintInfo()
|
||||
// 15-12-98, cross section=0 below 10 keV
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4EnergyLossMessenger.cc,v 1.2.6.1.2.5 1999/12/14 09:16:48 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4EnergyLossMessenger.cc,v 1.5 2000/05/23 14:42:21 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
|
||||
#include "G4eEnergyLoss.hh"
|
||||
#include "G4hEnergyLoss.hh"
|
||||
#include "G4eEnergyLossPlus.hh"
|
||||
#include "G4hEnergyLossPlus.hh"
|
||||
#include "G4VeEnergyLoss.hh"
|
||||
#include "G4VhEnergyLoss.hh"
|
||||
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4UIparameter.hh"
|
||||
@@ -42,6 +40,12 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
|
||||
EnlossFlucCmd->SetDefaultValue(true);
|
||||
EnlossFlucCmd->AvailableForStates(Idle);
|
||||
|
||||
SubSecCmd = new G4UIcmdWithABool("/process/Loss/subsec",this);
|
||||
SubSecCmd->SetGuidance("Switch on/off the subcutoff generation.");
|
||||
SubSecCmd->SetParameterName("choice",true);
|
||||
SubSecCmd->SetDefaultValue(true);
|
||||
SubSecCmd->AvailableForStates(Idle);
|
||||
|
||||
StepFuncCmd = new G4UIcommand("/process/eLoss/StepFunction",this);
|
||||
StepFuncCmd->SetGuidance("Set the energy loss step limitation parameters.");
|
||||
StepFuncCmd->SetGuidance(" dRoverR : max Range variation per step");
|
||||
@@ -69,6 +73,7 @@ G4EnergyLossMessenger::~G4EnergyLossMessenger()
|
||||
{
|
||||
delete RndmStepCmd;
|
||||
delete EnlossFlucCmd;
|
||||
delete SubSecCmd;
|
||||
delete StepFuncCmd;
|
||||
}
|
||||
|
||||
@@ -77,17 +82,18 @@ G4EnergyLossMessenger::~G4EnergyLossMessenger()
|
||||
void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
{
|
||||
if (command == RndmStepCmd)
|
||||
{ G4eEnergyLoss::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
G4hEnergyLoss::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
G4eEnergyLossPlus::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
G4hEnergyLossPlus::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
{ G4VeEnergyLoss::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
G4VhEnergyLoss::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == EnlossFlucCmd)
|
||||
{ G4eEnergyLoss::SetEnlossFluc(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
G4hEnergyLoss::SetEnlossFluc(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
G4eEnergyLossPlus::SetEnlossFluc(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
G4hEnergyLossPlus::SetEnlossFluc(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
{ G4VeEnergyLoss::SetEnlossFluc(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
G4VhEnergyLoss::SetEnlossFluc(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == SubSecCmd)
|
||||
{ G4VeEnergyLoss::SetSubSec(SubSecCmd->GetNewBoolValue(newValue));
|
||||
G4VhEnergyLoss::SetSubSec(SubSecCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == StepFuncCmd)
|
||||
@@ -99,10 +105,8 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
is >> v1 >> v2 >> unts;
|
||||
G4String unt = unts;
|
||||
v2 *= G4UIcommand::ValueOf(unt);
|
||||
G4eEnergyLoss::SetStepFunction(v1,v2);
|
||||
G4hEnergyLoss::SetStepFunction(v1,v2);
|
||||
G4eEnergyLossPlus::SetStepFunction(v1,v2);
|
||||
G4hEnergyLossPlus::SetStepFunction(v1,v2);
|
||||
G4VeEnergyLoss::SetStepFunction(v1,v2);
|
||||
G4VhEnergyLoss::SetStepFunction(v1,v2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4GammaConversion.cc,v 1.2.8.1.2.2 1999/12/10 15:41:58 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4GammaConversion.cc,v 1.3 1999/12/15 14:51:50 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -35,7 +35,7 @@
|
||||
// 14-03-97, new Physics scheme for geant4alpha, M.Maire
|
||||
// 28-03-97, protection in BuildPhysicsTable, M.Maire
|
||||
// 19-06-97, correction in ComputeMicroscopicCrossSection, L.Urban
|
||||
// 04-06-98, in DoIt, secondary production condition: range>min(threshold,safety)
|
||||
// 04-06-98, in DoIt, secondary production condition: range>G4std::min(threshold,safety)
|
||||
// 13-08-98, new methods SetBining() PrintInfo()
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -341,7 +341,7 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double PositKineEnergy = G4std::max(0.,PositTotEnergy - electron_mass_c2) ;
|
||||
|
||||
// if (G4EnergyLossTables::GetRange(G4Positron::Positron(),PositKineEnergy,aMaterial)
|
||||
// < min(G4Positron::GetCuts(), aStep.GetPostStepPoint()->GetSafety()) )
|
||||
// < G4std::min(G4Positron::GetCuts(), aStep.GetPostStepPoint()->GetSafety()) )
|
||||
if((G4EnergyLossTables::GetRange(G4Positron::Positron(),
|
||||
PositKineEnergy,aMaterial)<aStep.GetPostStepPoint()->GetSafety())
|
||||
&&
|
||||
|
||||
@@ -1,820 +0,0 @@
|
||||
// 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: G4IMultipleScattering.cc,v 1.2.8.1.2.1 1999/12/08 17:34:22 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
//
|
||||
// $Id:
|
||||
// --------------------------------------------------------------
|
||||
// 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
|
||||
// -------- G4IMultipleScattering physics process ------------
|
||||
// by Laszlo Urban, October 1997
|
||||
// **************************************************************
|
||||
// 09/12/98: charge can be != +- 1 !!!! L.Urban
|
||||
// ************************************************************
|
||||
// It is the first implementation of the
|
||||
// MULTIPLESCATTERING PROCESS
|
||||
// using an INTEGRAL APPROACH instead of the differential
|
||||
// one used in the standard implementation .
|
||||
// ************************************************************
|
||||
// by Laszlo Urban, 23 June 1998
|
||||
// ---------------------------------------------------------------
|
||||
// 27/10/98: cleanup , L. Urban
|
||||
|
||||
#include "G4IMultipleScattering.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
G4IMultipleScattering::G4IMultipleScattering(const G4String& processName)
|
||||
: G4VContinuousDiscreteProcess(processName),
|
||||
theTransportMeanFreePathTable(NULL),
|
||||
theIntegralITable(NULL),
|
||||
theIntegralJTable(NULL),
|
||||
lastMaterial(NULL),
|
||||
lastKineticEnergy(-1.*MeV),
|
||||
fTransportMeanFreePath(1.e12),
|
||||
LowestKineticEnergy(0.1*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
TotBin(100),
|
||||
NumberOfBuildPhysicsTableCalls(0),
|
||||
theElectron(G4Electron::Electron()),
|
||||
thePositron(G4Positron::Positron()),
|
||||
plowloss ( 0.5 ),
|
||||
plowlambda ( 0.4 ),
|
||||
tLast (0.0),
|
||||
zLast (0.0),
|
||||
CosTheta (1.0),
|
||||
biglambda ( 1.e10*mm),
|
||||
tuning(1.0)
|
||||
{ }
|
||||
|
||||
G4IMultipleScattering::~G4IMultipleScattering()
|
||||
{
|
||||
if(theTransportMeanFreePathTable)
|
||||
{
|
||||
theTransportMeanFreePathTable->clearAndDestroy() ;
|
||||
delete theTransportMeanFreePathTable ;
|
||||
}
|
||||
if(theIntegralITable)
|
||||
{
|
||||
theIntegralITable->clearAndDestroy() ;
|
||||
delete theIntegralITable ;
|
||||
}
|
||||
if(theIntegralJTable)
|
||||
{
|
||||
theIntegralJTable->clearAndDestroy() ;
|
||||
delete theIntegralJTable ;
|
||||
}
|
||||
}
|
||||
|
||||
void G4IMultipleScattering::BuildPhysicsTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
|
||||
{
|
||||
NumberOfBuildPhysicsTableCalls += 1 ;
|
||||
if(NumberOfBuildPhysicsTableCalls == 1)
|
||||
{ ; }
|
||||
else
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable =
|
||||
G4Material::GetMaterialTable() ;
|
||||
const G4double sigmafactor = twopi*classic_electr_radius*
|
||||
classic_electr_radius ;
|
||||
G4double KineticEnergy,AtomicNumber,sigma,lambda ;
|
||||
G4double density ;
|
||||
|
||||
if(theTransportMeanFreePathTable)
|
||||
{
|
||||
theTransportMeanFreePathTable->clearAndDestroy() ;
|
||||
delete theTransportMeanFreePathTable ;
|
||||
}
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length() ;
|
||||
|
||||
theTransportMeanFreePathTable = new G4PhysicsTable(numOfMaterials) ;
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy,HighestKineticEnergy,TotBin) ;
|
||||
|
||||
const G4Material* material = (*theMaterialTable)(J) ;
|
||||
const G4ElementVector* theElementVector =
|
||||
material->GetElementVector() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector() ;
|
||||
const G4int NumberOfElements =
|
||||
material->GetNumberOfElements() ;
|
||||
density = material->GetDensity() ;
|
||||
|
||||
for (G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
KineticEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
|
||||
sigma = 0. ;
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++)
|
||||
{
|
||||
AtomicNumber = (*theElementVector)(iel)->GetZ() ;
|
||||
sigma += theAtomicNumDensityVector[iel]*
|
||||
ComputeTransportCrossSection(aParticleType,
|
||||
KineticEnergy,AtomicNumber) ;
|
||||
}
|
||||
|
||||
sigma *= sigmafactor ;
|
||||
|
||||
lambda = 1./sigma ;
|
||||
|
||||
aVector->PutValue(i,lambda) ;
|
||||
|
||||
}
|
||||
|
||||
theTransportMeanFreePathTable->insert(aVector) ;
|
||||
|
||||
}
|
||||
|
||||
BuildIntegralITable(aParticleType) ;
|
||||
BuildIntegralJTable(aParticleType) ;
|
||||
|
||||
NumberOfBuildPhysicsTableCalls = 0 ;
|
||||
|
||||
if( (&aParticleType == G4Electron::Electron()) ||
|
||||
(&aParticleType == G4MuonPlus::MuonPlus()) ||
|
||||
(&aParticleType == G4Proton::Proton()) )
|
||||
{
|
||||
PrintInfoDefinition() ;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void G4IMultipleScattering::BuildIntegralITable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable =
|
||||
G4Material::GetMaterialTable() ;
|
||||
G4Material* aMaterial ;
|
||||
G4double fmin,lmin,Value,KineticEnergy,lambda,Tlast,Vlast ;
|
||||
G4double u,umax,du,t,coeff,dEdx ;
|
||||
G4int n,nmax ;
|
||||
G4bool isOut ;
|
||||
const G4int nb = 100 ;
|
||||
G4double rmin ;
|
||||
|
||||
if(theIntegralITable)
|
||||
{
|
||||
theIntegralITable->clearAndDestroy() ;
|
||||
delete theIntegralITable ;
|
||||
}
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length() ;
|
||||
|
||||
theIntegralITable = new G4PhysicsTable(numOfMaterials) ;
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy,HighestKineticEnergy,TotBin) ;
|
||||
|
||||
aMaterial = (*theMaterialTable)(J) ;
|
||||
|
||||
rmin = G4EnergyLossTables::GetPreciseRangeFromEnergy(
|
||||
&aParticleType,
|
||||
LowestKineticEnergy,
|
||||
aMaterial) ;
|
||||
|
||||
lmin = (*theTransportMeanFreePathTable)(J)->
|
||||
GetValue(LowestKineticEnergy,isOut) ;
|
||||
|
||||
// this value comes from z=r*l/(r+l) = exp(-I) !!!
|
||||
Value = -log(rmin*lmin/(rmin+lmin)) ;
|
||||
|
||||
aVector->PutValue(0,Value) ;
|
||||
Tlast = LowestKineticEnergy ;
|
||||
Vlast = Value ;
|
||||
for (G4int i=1; i<TotBin; i++)
|
||||
{
|
||||
KineticEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
umax = log(KineticEnergy/Tlast) ;
|
||||
nmax = int(nb*umax + 0.5) ;
|
||||
if(nmax<1)
|
||||
nmax = 1 ;
|
||||
du = umax/nmax ;
|
||||
Value = 0. ;
|
||||
u = -du ;
|
||||
for(n=0; n<=nmax; n++)
|
||||
{
|
||||
u += du ;
|
||||
t = Tlast*exp(u) ;
|
||||
lambda = (*theTransportMeanFreePathTable)(J)->
|
||||
GetValue(t,isOut) ;
|
||||
dEdx = G4EnergyLossTables::GetPreciseDEDX(&aParticleType,
|
||||
t,aMaterial) ;
|
||||
if((n == 0) || (n == nmax))
|
||||
coeff = 0.5 ;
|
||||
else
|
||||
coeff = 1. ;
|
||||
Value += coeff*t/(dEdx*lambda) ;
|
||||
}
|
||||
Value *= du ;
|
||||
Value += Vlast ;
|
||||
aVector->PutValue(i,Value) ;
|
||||
Tlast = KineticEnergy ;
|
||||
Vlast = Value ;
|
||||
}
|
||||
theIntegralITable->insert(aVector) ;
|
||||
}
|
||||
}
|
||||
|
||||
void G4IMultipleScattering::BuildIntegralJTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable =
|
||||
G4Material::GetMaterialTable() ;
|
||||
G4Material* aMaterial ;
|
||||
G4double rmin,lmin,Value,KineticEnergy,lambda,Tlast,Vlast ;
|
||||
G4double u,umax,du,t,coeff,dEdx,w,ww ;
|
||||
G4double cmin,lndu ;
|
||||
G4int n,nmax ;
|
||||
G4bool isOut ;
|
||||
const G4int nb = 100 ;
|
||||
|
||||
if(theIntegralJTable)
|
||||
{
|
||||
theIntegralJTable->clearAndDestroy() ;
|
||||
delete theIntegralJTable ;
|
||||
}
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length() ;
|
||||
theIntegralJTable = new G4PhysicsTable(numOfMaterials) ;
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy,HighestKineticEnergy,TotBin) ;
|
||||
aMaterial = (*theMaterialTable)(J) ;
|
||||
|
||||
rmin = G4EnergyLossTables::GetPreciseRangeFromEnergy(
|
||||
&aParticleType,
|
||||
LowestKineticEnergy,
|
||||
aMaterial) ;
|
||||
lmin = (*theTransportMeanFreePathTable)(J)->
|
||||
GetValue(LowestKineticEnergy,isOut) ;
|
||||
Value = rmin*lmin/(rmin+lmin) ;
|
||||
aVector->PutValue(0,Value) ;
|
||||
Tlast = LowestKineticEnergy ;
|
||||
Vlast = Value ;
|
||||
for (G4int i=1; i<TotBin; i++)
|
||||
{
|
||||
KineticEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
umax = log(KineticEnergy/Tlast) ;
|
||||
nmax =int(nb*umax + 0.5) ;
|
||||
if(nmax<1)
|
||||
nmax = 1 ;
|
||||
du = umax/nmax ;
|
||||
Value = 0. ;
|
||||
u = -du ;
|
||||
for(n=0; n<=nmax; n++)
|
||||
{
|
||||
u += du ;
|
||||
t = Tlast*exp(u) ;
|
||||
w = (*theIntegralITable)(J)->
|
||||
GetValue(t,isOut) ;
|
||||
dEdx = G4EnergyLossTables::GetPreciseDEDX(&aParticleType,
|
||||
t,aMaterial) ;
|
||||
if((n == 0) || (n == nmax))
|
||||
coeff = 0.5 ;
|
||||
else
|
||||
coeff = 1. ;
|
||||
Value += coeff*t*exp(w)/dEdx ;
|
||||
}
|
||||
Value *= du ;
|
||||
w = (*theIntegralITable)(J)->
|
||||
GetValue(Tlast,isOut) ;
|
||||
ww = (*theIntegralITable)(J)->
|
||||
GetValue(KineticEnergy,isOut) ;
|
||||
Value *= exp(-ww) ;
|
||||
Value += exp(w-ww)*Vlast ;
|
||||
aVector->PutValue(i,Value) ;
|
||||
Tlast = KineticEnergy ;
|
||||
Vlast = Value ;
|
||||
}
|
||||
theIntegralJTable->insert(aVector) ;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4IMultipleScattering::GetIntegralI(
|
||||
const G4ParticleDefinition *aParticle,
|
||||
G4double KineticEnergy,
|
||||
G4Material* aMaterial)
|
||||
{
|
||||
G4double intI ;
|
||||
G4bool isOut ;
|
||||
if(KineticEnergy < LowestKineticEnergy)
|
||||
{
|
||||
intI = (*theIntegralITable)(aMaterial->GetIndex())->
|
||||
GetValue(LowestKineticEnergy,isOut) ;
|
||||
intI *= exp((1.-plowloss-plowlambda)*
|
||||
log(KineticEnergy/LowestKineticEnergy)) ;
|
||||
}
|
||||
else if(KineticEnergy <= HighestKineticEnergy)
|
||||
{
|
||||
intI = (*theIntegralITable)(aMaterial->GetIndex())->
|
||||
GetValue(KineticEnergy,isOut) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
intI = (*theIntegralITable)(aMaterial->GetIndex())->
|
||||
GetValue(HighestKineticEnergy,isOut) ;
|
||||
intI += (KineticEnergy-HighestKineticEnergy)/
|
||||
((*theTransportMeanFreePathTable)(aMaterial->GetIndex())->
|
||||
GetValue(HighestKineticEnergy,isOut)
|
||||
*
|
||||
G4EnergyLossTables::GetPreciseDEDX(aParticle,
|
||||
HighestKineticEnergy,aMaterial)) ;
|
||||
}
|
||||
return intI ;
|
||||
}
|
||||
|
||||
G4double G4IMultipleScattering::GetIntegralJ(
|
||||
const G4ParticleDefinition *aParticle,
|
||||
G4double KineticEnergy,
|
||||
G4Material* aMaterial)
|
||||
{
|
||||
G4double intJ,lmin,lmax,fmax,Imin,Imin2,t ;
|
||||
G4bool isOut ;
|
||||
|
||||
if(KineticEnergy < LowestKineticEnergy)
|
||||
{
|
||||
lmin = (*theTransportMeanFreePathTable)(aMaterial->GetIndex())->
|
||||
GetValue(KineticEnergy,isOut) ;
|
||||
Imin = (*theIntegralITable)(aMaterial->GetIndex())->
|
||||
GetValue(LowestKineticEnergy,isOut) ;
|
||||
Imin2= Imin*Imin ;
|
||||
t = exp(0.1*log(KineticEnergy/LowestKineticEnergy)) ;
|
||||
|
||||
intJ = (((t-4./Imin)*t+12./Imin2)*t-24./(Imin*Imin2))*t+24./(Imin2*Imin2);
|
||||
intJ -= 24.*exp(-Imin*t)/(Imin2*Imin2) ;
|
||||
intJ *= lmin ;
|
||||
}
|
||||
else if(KineticEnergy <= HighestKineticEnergy)
|
||||
{
|
||||
intJ = (*theIntegralJTable)(aMaterial->GetIndex())->
|
||||
GetValue(KineticEnergy,isOut) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
lmax = (*theTransportMeanFreePathTable)(aMaterial->GetIndex())->
|
||||
GetValue(HighestKineticEnergy,isOut) ;
|
||||
fmax = G4EnergyLossTables::GetPreciseDEDX(aParticle,
|
||||
HighestKineticEnergy,aMaterial) ;
|
||||
intJ = lmax - (lmax-(*theIntegralJTable)(aMaterial->GetIndex())->
|
||||
GetValue(HighestKineticEnergy,isOut))*
|
||||
exp((HighestKineticEnergy-KineticEnergy)/(fmax*lmax)) ;
|
||||
}
|
||||
|
||||
return intJ ;
|
||||
}
|
||||
|
||||
G4double G4IMultipleScattering::ComputeTransportCrossSection(
|
||||
const G4ParticleDefinition& aParticleType,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber)
|
||||
{
|
||||
const G4double epsfactor = 2.*electron_mass_c2*electron_mass_c2*
|
||||
Bohr_radius*Bohr_radius/(hbarc*hbarc) ;
|
||||
const G4double epsmin = 1.e-4 , epsmax = 1.e10 ;
|
||||
|
||||
const G4double cpar=1.50 ;
|
||||
|
||||
const G4double Zdat[15] = {4.,6.,13.,20.,26.,29.,32.,38.,47.,
|
||||
50.,56.,64.,74.,79.,82. } ;
|
||||
|
||||
const G4double Tdat[22] =
|
||||
{ 0.0001*MeV,0.0002*MeV,0.0004*MeV,0.0007*MeV,
|
||||
0.001*MeV,0.002*MeV,0.004*MeV,0.007*MeV,0.01*MeV,
|
||||
0.02*MeV,0.04*MeV,0.07*MeV,0.1*MeV,0.2*MeV,
|
||||
0.4*MeV,0.7*MeV,1.*MeV,2.*MeV,4.*MeV,
|
||||
7.*MeV,10.*MeV,20.*MeV} ;
|
||||
|
||||
// corr. factors for e-/e+ lambda
|
||||
|
||||
const G4double celectron[15][22] =
|
||||
{{1.125,1.072,1.051,1.047,1.047,1.050,1.052,1.054,
|
||||
1.054,1.057,1.062,1.069,1.075,1.090,1.105,1.111,
|
||||
1.112,1.108,1.100,1.093,1.089,1.087 },
|
||||
{1.408,1.246,1.143,1.096,1.077,1.059,1.053,1.051,
|
||||
1.052,1.053,1.058,1.065,1.072,1.087,1.101,1.108,
|
||||
1.109,1.105,1.097,1.090,1.086,1.082 },
|
||||
{2.833,2.268,1.861,1.612,1.486,1.309,1.204,1.156,
|
||||
1.136,1.114,1.106,1.106,1.109,1.119,1.129,1.132,
|
||||
1.131,1.124,1.113,1.104,1.099,1.098 },
|
||||
{3.879,3.016,2.380,2.007,1.818,1.535,1.340,1.236,
|
||||
1.190,1.133,1.107,1.099,1.098,1.103,1.110,1.113,
|
||||
1.112,1.105,1.096,1.089,1.085,1.098 },
|
||||
{6.937,4.330,2.886,2.256,1.987,1.628,1.395,1.265,
|
||||
1.203,1.122,1.080,1.065,1.061,1.063,1.070,1.073,
|
||||
1.073,1.070,1.064,1.059,1.056,1.056 },
|
||||
{9.616,5.708,3.424,2.551,2.204,1.762,1.485,1.330,
|
||||
1.256,1.155,1.099,1.077,1.070,1.068,1.072,1.074,
|
||||
1.074,1.070,1.063,1.059,1.056,1.052 },
|
||||
{11.72,6.364,3.811,2.806,2.401,1.884,1.564,1.386,
|
||||
1.300,1.180,1.112,1.082,1.073,1.066,1.068,1.069,
|
||||
1.068,1.064,1.059,1.054,1.051,1.050 },
|
||||
{18.08,8.601,4.569,3.183,2.662,2.025,1.646,1.439,
|
||||
1.339,1.195,1.108,1.068,1.053,1.040,1.039,1.039,
|
||||
1.039,1.037,1.034,1.031,1.030,1.036 },
|
||||
{18.22,10.48,5.333,3.713,3.115,2.367,1.898,1.631,
|
||||
1.498,1.301,1.171,1.105,1.077,1.048,1.036,1.033,
|
||||
1.031,1.028,1.024,1.022,1.021,1.024 },
|
||||
{14.14,10.65,5.710,3.929,3.266,2.453,1.951,1.669,
|
||||
1.528,1.319,1.178,1.106,1.075,1.040,1.027,1.022,
|
||||
1.020,1.017,1.015,1.013,1.013,1.020 },
|
||||
{14.11,11.73,6.312,4.240,3.478,2.566,2.022,1.720,
|
||||
1.569,1.342,1.186,1.102,1.065,1.022,1.003,0.997,
|
||||
0.995,0.993,0.993,0.993,0.993,1.011 },
|
||||
{22.76,20.01,8.835,5.287,4.144,2.901,2.219,1.855,
|
||||
1.677,1.410,1.224,1.121,1.073,1.014,0.986,0.976,
|
||||
0.974,0.972,0.973,0.974,0.975,0.987 },
|
||||
{50.77,40.85,14.13,7.184,5.284,3.435,2.520,2.059,
|
||||
1.837,1.512,1.283,1.153,1.091,1.010,0.969,0.954,
|
||||
0.950,0.947,0.949,0.952,0.954,0.963 },
|
||||
{65.87,59.06,15.87,7.570,5.567,3.650,2.682,2.182,
|
||||
1.939,1.579,1.325,1.178,1.108,1.014,0.965,0.947,
|
||||
0.941,0.938,0.940,0.944,0.946,0.954 },
|
||||
// {45.60,47.34,15.92,7.810,5.755,3.767,2.760,2.239, misprint?
|
||||
{55.60,47.34,15.92,7.810,5.755,3.767,2.760,2.239,
|
||||
1.985,1.609,1.343,1.188,1.113,1.013,0.960,0.939,
|
||||
0.933,0.930,0.933,0.936,0.939,0.949 }};
|
||||
|
||||
const G4double cpositron[15][22] = {
|
||||
{2.589,2.044,1.658,1.446,1.347,1.217,1.144,1.110,
|
||||
1.097,1.083,1.080,1.086,1.092,1.108,1.123,1.131,
|
||||
1.131,1.126,1.117,1.108,1.103,1.100 },
|
||||
{3.904,2.794,2.079,1.710,1.543,1.325,1.202,1.145,
|
||||
1.122,1.096,1.089,1.092,1.098,1.114,1.130,1.137,
|
||||
1.138,1.132,1.122,1.113,1.108,1.102 },
|
||||
{7.970,6.080,4.442,3.398,2.872,2.127,1.672,1.451,
|
||||
1.357,1.246,1.194,1.179,1.178,1.188,1.201,1.205,
|
||||
1.203,1.190,1.173,1.159,1.151,1.145 },
|
||||
{9.714,7.607,5.747,4.493,3.815,2.777,2.079,1.715,
|
||||
1.553,1.353,1.253,1.219,1.211,1.214,1.225,1.228,
|
||||
1.225,1.210,1.191,1.175,1.166,1.174 },
|
||||
{17.97,12.95,8.628,6.065,4.849,3.222,2.275,1.820,
|
||||
1.624,1.382,1.259,1.214,1.202,1.202,1.214,1.219,
|
||||
1.217,1.203,1.184,1.169,1.160,1.151 },
|
||||
{24.83,17.06,10.84,7.355,5.767,3.707,2.546,1.996,
|
||||
1.759,1.465,1.311,1.252,1.234,1.228,1.238,1.241,
|
||||
1.237,1.222,1.201,1.184,1.174,1.159 },
|
||||
{23.26,17.15,11.52,8.049,6.375,4.114,2.792,2.155,
|
||||
1.880,1.535,1.353,1.281,1.258,1.247,1.254,1.256,
|
||||
1.252,1.234,1.212,1.194,1.183,1.170 },
|
||||
{22.33,18.01,12.86,9.212,7.336,4.702,3.117,2.348,
|
||||
2.015,1.602,1.385,1.297,1.268,1.251,1.256,1.258,
|
||||
1.254,1.237,1.214,1.195,1.185,1.179 },
|
||||
{33.91,24.13,15.71,10.80,8.507,5.467,3.692,2.808,
|
||||
2.407,1.873,1.564,1.425,1.374,1.330,1.324,1.320,
|
||||
1.312,1.288,1.258,1.235,1.221,1.205 },
|
||||
{32.14,24.11,16.30,11.40,9.015,5.782,3.868,2.917,
|
||||
2.490,1.925,1.596,1.447,1.391,1.342,1.332,1.327,
|
||||
1.320,1.294,1.264,1.240,1.226,1.214 },
|
||||
{29.51,24.07,17.19,12.28,9.766,6.238,4.112,3.066,
|
||||
2.602,1.995,1.641,1.477,1.414,1.356,1.342,1.336,
|
||||
1.328,1.302,1.270,1.245,1.231,1.233 },
|
||||
{38.19,30.85,21.76,15.35,12.07,7.521,4.812,3.498,
|
||||
2.926,2.188,1.763,1.563,1.484,1.405,1.382,1.371,
|
||||
1.361,1.330,1.294,1.267,1.251,1.239 },
|
||||
{49.71,39.80,27.96,19.63,15.36,9.407,5.863,4.155,
|
||||
3.417,2.478,1.944,1.692,1.589,1.480,1.441,1.423,
|
||||
1.409,1.372,1.330,1.298,1.280,1.258 },
|
||||
{59.25,45.08,30.36,20.83,16.15,9.834,6.166,4.407,
|
||||
3.641,2.648,2.064,1.779,1.661,1.531,1.482,1.459,
|
||||
1.442,1.400,1.354,1.319,1.299,1.272 },
|
||||
{56.38,44.29,30.50,21.18,16.51,10.11,6.354,4.542,
|
||||
3.752,2.724,2.116,1.817,1.692,1.554,1.499,1.474,
|
||||
1.456,1.412,1.364,1.328,1.307,1.282 }};
|
||||
G4double Z23,ParticleMass,rat2,Charge,TotalEnergy,beta2,bg2,
|
||||
eps,Z1,Z2,ratZ,T,E,b2small,b2big,ratb2,c1,c2,cc1,cc2,
|
||||
corr,sigma,corrfactor,ChargeSquare ;
|
||||
G4int iZ,iT ;
|
||||
|
||||
Z23 = 2.*log(AtomicNumber)/3. ;
|
||||
Z23 = exp(Z23) ;
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
rat2 = ParticleMass/electron_mass_c2 ;
|
||||
rat2 = rat2*rat2 ;
|
||||
|
||||
Charge = aParticleType.GetPDGCharge() ;
|
||||
ChargeSquare = Charge*Charge/(eplus*eplus) ;
|
||||
|
||||
TotalEnergy = KineticEnergy + ParticleMass ;
|
||||
|
||||
beta2 = KineticEnergy*(TotalEnergy+ParticleMass)/
|
||||
(TotalEnergy*TotalEnergy) ;
|
||||
bg2 = KineticEnergy*(TotalEnergy+ParticleMass)/
|
||||
(ParticleMass*ParticleMass) ;
|
||||
|
||||
eps = rat2*epsfactor*bg2/Z23 ;
|
||||
|
||||
if(eps<epsmin)
|
||||
sigma = 2.*eps*eps*eps/3. ;
|
||||
else if(eps<epsmax)
|
||||
sigma = log(1.+2.*eps)-2.*eps/(1.+eps) ;
|
||||
else
|
||||
sigma = log(2.*eps)-2.+2.5/eps ;
|
||||
|
||||
sigma *= ChargeSquare*AtomicNumber*AtomicNumber/rat2 ;
|
||||
sigma /= beta2*bg2 ;
|
||||
|
||||
// correct this value using the corrections computed for e+/e-
|
||||
KineticEnergy *= electron_mass_c2/ParticleMass ;
|
||||
|
||||
// interpolate in AtomicNumber and beta2
|
||||
|
||||
// get bin number in Z
|
||||
iZ = 14 ;
|
||||
|
||||
while ((iZ>=0)&&(Zdat[iZ]>=AtomicNumber))
|
||||
{
|
||||
iZ -= 1 ;
|
||||
}
|
||||
if(iZ==14)
|
||||
{
|
||||
iZ = 13 ;
|
||||
}
|
||||
if(iZ==-1)
|
||||
{
|
||||
iZ = 0 ;
|
||||
}
|
||||
|
||||
Z1 = Zdat[iZ] ;
|
||||
Z2 = Zdat[iZ+1] ;
|
||||
ratZ = (AtomicNumber-Z1)/(Z2-Z1) ;
|
||||
|
||||
// get bin number in T (beta2)
|
||||
iT = 21 ;
|
||||
while ((iT>=0)&&(Tdat[iT]>=KineticEnergy))
|
||||
iT -= 1 ;
|
||||
if(iT==21)
|
||||
iT = 20 ;
|
||||
if(iT==-1)
|
||||
iT = 0 ;
|
||||
|
||||
// calculate betasquare values
|
||||
T = Tdat[iT] ;
|
||||
E = T + electron_mass_c2 ;
|
||||
b2small = T*(E+electron_mass_c2)/(E*E) ;
|
||||
T = Tdat[iT+1] ;
|
||||
E = T + electron_mass_c2 ;
|
||||
b2big = T*(E+electron_mass_c2)/(E*E) ;
|
||||
ratb2 = (beta2-b2small)/(b2big-b2small) ;
|
||||
|
||||
corrfactor = tuning*(1.+cpar)/(1.+cpar*beta2) ;
|
||||
|
||||
if(Charge < 0.)
|
||||
{
|
||||
c1 = celectron[iZ][iT] ;
|
||||
c2 = celectron[iZ+1][iT] ;
|
||||
cc1 = c1+ratZ*(c2-c1) ;
|
||||
|
||||
c1 = celectron[iZ][iT+1] ;
|
||||
c2 = celectron[iZ+1][iT+1] ;
|
||||
cc2 = c1+ratZ*(c2-c1) ;
|
||||
|
||||
corr = cc1+ratb2*(cc2-cc1) ;
|
||||
|
||||
sigma /= corr ;
|
||||
|
||||
}
|
||||
|
||||
if(Charge > 0.)
|
||||
{
|
||||
c1 = cpositron[iZ][iT] ;
|
||||
c2 = cpositron[iZ+1][iT] ;
|
||||
cc1 = c1+ratZ*(c2-c1) ;
|
||||
|
||||
c1 = cpositron[iZ][iT+1] ;
|
||||
c2 = cpositron[iZ+1][iT+1] ;
|
||||
cc2 = c1+ratZ*(c2-c1) ;
|
||||
|
||||
corr = cc1+ratb2*(cc2-cc1) ;
|
||||
|
||||
sigma /= corr ;
|
||||
}
|
||||
|
||||
sigma *= corrfactor ;
|
||||
|
||||
return sigma ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4VParticleChange* G4IMultipleScattering::PostStepDoIt(
|
||||
const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
G4double lambdasave ;
|
||||
const G4double taulim = 1.e-10 , randlim = 0.25*taulim*taulim ;
|
||||
const G4double tausmall = 5.e-5,taubig =50.;
|
||||
|
||||
const G4double scatteringparameter=1.00 ,
|
||||
kappa = 2.5, kappapl1 = kappa+1., kappami1 = kappa-1. ;
|
||||
|
||||
const G4DynamicParticle* aParticle ;
|
||||
G4Material* aMaterial ;
|
||||
G4int materialIndex ;
|
||||
G4double KineticEnergy,truestep,tau,prob,cth,sth,phi,
|
||||
dirx,diry,dirz,w,w1,etau,rmean,safetyminustolerance,
|
||||
xnew,ynew,znew ;
|
||||
G4double rand,rmax2 ;
|
||||
G4bool isOut;
|
||||
|
||||
aParticleChange.Initialize(trackData) ;
|
||||
|
||||
aMaterial = stepData.GetPreStepPoint()->GetMaterial() ;
|
||||
|
||||
|
||||
truestep = stepData.GetStepLength() ;
|
||||
|
||||
// there is no scattering for truestep=0. !
|
||||
if(truestep == 0.)
|
||||
return &aParticleChange ;
|
||||
|
||||
aParticle = trackData.GetDynamicParticle() ;
|
||||
|
||||
materialIndex = aMaterial->GetIndex() ;
|
||||
KineticEnergy = aParticle->GetKineticEnergy() ;
|
||||
|
||||
// shortcut if the particle is not Alive (e.g. stopped in energy loss)
|
||||
if(trackData.GetTrackStatus() != fAlive)
|
||||
return &aParticleChange ;
|
||||
|
||||
if ((lastMaterial == aMaterial) && (lastKineticEnergy == KineticEnergy))
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastMaterial=aMaterial;
|
||||
lastKineticEnergy=KineticEnergy;
|
||||
if(KineticEnergy<LowestKineticEnergy)
|
||||
{
|
||||
fTransportMeanFreePath =
|
||||
exp(plowlambda*log(KineticEnergy/LowestKineticEnergy))*
|
||||
(*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(LowestKineticEnergy,isOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TransportMeanFreePath taken at kin.energy after the energy loss!
|
||||
if(KineticEnergy>HighestKineticEnergy)
|
||||
KineticEnergy = HighestKineticEnergy ;
|
||||
fTransportMeanFreePath = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(KineticEnergy,isOut);
|
||||
}
|
||||
}
|
||||
|
||||
// effective lambda used in scattering .....................
|
||||
lambdasave = fTransportMeanFreePath ;
|
||||
|
||||
if(CosTheta == 1.)
|
||||
{
|
||||
fTransportMeanFreePath = biglambda ;
|
||||
tau = 0.;
|
||||
cth = 1. ;
|
||||
}
|
||||
else if(CosTheta == 0.)
|
||||
{
|
||||
fTransportMeanFreePath = 0. ;
|
||||
tau = biglambda ;
|
||||
cth = -1.+2.*G4UniformRand() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fTransportMeanFreePath = -truestep/log(CosTheta) ;
|
||||
tau = truestep/fTransportMeanFreePath ;
|
||||
prob = exp(-tau)*(1.+scatteringparameter*tau) ;
|
||||
|
||||
if(G4UniformRand()<prob)
|
||||
{
|
||||
if(tau<taulim)
|
||||
{
|
||||
rand = G4UniformRand() ;
|
||||
if(rand > randlim)
|
||||
cth = 1.-tau*(1./sqrt(rand)-1.) ;
|
||||
else
|
||||
cth = -1. ;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = 1.+scatteringparameter*tau ;
|
||||
w1 = w-1. ;
|
||||
cth = w-w1*(w+1.)/sqrt(w1*w1+4.*w*G4UniformRand()) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
cth = -1.+2.*G4UniformRand() ;
|
||||
}
|
||||
|
||||
sth = sqrt(1.-cth*cth) ;
|
||||
phi = twopi*G4UniformRand() ;
|
||||
|
||||
dirx = sth*cos(phi) ;
|
||||
diry = sth*sin(phi) ;
|
||||
dirz = cth ;
|
||||
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection();
|
||||
G4ThreeVector newDirection(dirx,diry,dirz) ;
|
||||
newDirection.rotateUz(ParticleDirection) ;
|
||||
aParticleChange.SetNumberOfSecondaries(0) ;
|
||||
aParticleChange.SetEnergyChange( KineticEnergy ) ;
|
||||
aParticleChange.SetMomentumChange(newDirection.x(),
|
||||
newDirection.y(),
|
||||
newDirection.z()) ;
|
||||
|
||||
// compute lateral displacement
|
||||
// only for safety > tolerance !!!!!
|
||||
safetyminustolerance = stepData.GetPostStepPoint()->GetSafety()
|
||||
-kCarTolerance ;
|
||||
if(safetyminustolerance > 0.)
|
||||
{
|
||||
if(truestep == GeomStepFinal)
|
||||
{ ; }
|
||||
else
|
||||
{
|
||||
rmax2 = (truestep+GeomStepFinal)*(truestep-GeomStepFinal) ;
|
||||
if(tau<tausmall)
|
||||
rmean = 5.*tau*tau*tau/12. ;
|
||||
else
|
||||
{
|
||||
if(tau<taubig)
|
||||
etau = exp(-tau) ;
|
||||
else
|
||||
etau = 0. ;
|
||||
rmean = -kappa*tau ;
|
||||
rmean = -exp(rmean)/(kappa*kappami1) ;
|
||||
rmean += tau-kappapl1/kappa+kappa*etau/kappami1 ;
|
||||
}
|
||||
rmean *= 4.*fTransportMeanFreePath*fTransportMeanFreePath/3.;
|
||||
if(rmean>rmax2)
|
||||
rmean = rmax2 ;
|
||||
|
||||
if(rmean>0.)
|
||||
{
|
||||
rmean = sqrt(rmean) ;
|
||||
|
||||
if(rmean>safetyminustolerance)
|
||||
rmean = safetyminustolerance ;
|
||||
|
||||
fMeanLateralDisplacement = rmean ;
|
||||
|
||||
// sample direction of lateral displacement
|
||||
phi = twopi*G4UniformRand() ;
|
||||
dirx = cos(phi) ;
|
||||
diry = sin(phi) ;
|
||||
dirz = 0. ;
|
||||
G4ThreeVector latDirection(dirx,diry,dirz);
|
||||
latDirection.rotateUz(ParticleDirection) ;
|
||||
|
||||
// compute new endpoint of the Step
|
||||
xnew = stepData.GetPostStepPoint()->GetPosition().x()+
|
||||
rmean*latDirection.x() ;
|
||||
ynew = stepData.GetPostStepPoint()->GetPosition().y()+
|
||||
rmean*latDirection.y() ;
|
||||
znew = stepData.GetPostStepPoint()->GetPosition().z()+
|
||||
rmean*latDirection.z() ;
|
||||
|
||||
aParticleChange.SetPositionChange(xnew,ynew,znew) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fTransportMeanFreePath = lambdasave ;
|
||||
|
||||
return &aParticleChange ;
|
||||
|
||||
}
|
||||
|
||||
void G4IMultipleScattering::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = " Tables of transport mean free paths.";
|
||||
comments += "\n New model of MSC , computes the lateral \n";
|
||||
comments += " displacement of the particle , too.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,
|
||||
"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IeBremsstrahlung.cc,v 1.3.8.1.2.3 1999/12/10 15:41:59 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4IeBremsstrahlung.cc,v 1.5 2000/04/25 14:33:08 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// $Id:
|
||||
// --------------------------------------------------------------
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
|
||||
G4IeBremsstrahlung::G4IeBremsstrahlung(const G4String& processName)
|
||||
: G4IeEnergyLoss(processName),
|
||||
: G4VIeEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
theNlambdaTable(NULL),
|
||||
theInverseNlambdaTable(NULL),
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IeIonisation.cc,v 1.3.8.1.2.3 1999/12/10 15:41:59 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4IeIonisation.cc,v 1.5 2000/04/25 14:33:08 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// $Id:
|
||||
// -------------------------------------------------------------
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
|
||||
G4IeIonisation::G4IeIonisation(const G4String& processName)
|
||||
: G4IeEnergyLoss(processName),
|
||||
: G4VIeEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
theNlambdaTable(NULL),
|
||||
theInverseNlambdaTable(NULL),
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IeplusAnnihilation.cc,v 1.5.8.1.2.2 1999/12/09 16:18:04 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4IeplusAnnihilation.cc,v 1.6 1999/12/15 14:51:50 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// $Id:
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IhIonisation.cc,v 1.5.8.1.2.2 1999/12/09 16:18:04 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4IhIonisation.cc,v 1.7 2000/04/25 14:33:09 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -34,7 +34,7 @@
|
||||
// constructor and destructor
|
||||
|
||||
G4IhIonisation::G4IhIonisation(const G4String& processName)
|
||||
: G4IhEnergyLoss(processName),
|
||||
: G4VIhEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
NumberOfBuildPhysicsTableCalls(0),
|
||||
theProton (G4Proton::Proton()),
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
// Implementation of class for selecting ionisation model depending on
|
||||
// logical volume
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4IonisationByLogicalVolume.hh"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4IonisationByLogicalVolume::
|
||||
G4IonisationByLogicalVolume( const G4String& particleName,
|
||||
G4LogicalVolume* volumeForPAImodel,
|
||||
const G4String& processName ) :
|
||||
G4VContinuousDiscreteProcess(processName),
|
||||
fPAIonisation(NULL),feIonisation(NULL),fMuIonisation(NULL),fhIonisation(NULL)
|
||||
{
|
||||
fParticleName = particleName ;
|
||||
fVolumeForPAImodel = volumeForPAImodel ;
|
||||
fMaterialNameForPAI = volumeForPAImodel->GetMaterial()->GetName() ;
|
||||
|
||||
fPAIonisation = new G4PAIonisation(fMaterialNameForPAI);
|
||||
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
feIonisation = new G4eIonisation() ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
fMuIonisation = new G4MuIonisation() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fhIonisation = new G4hIonisation() ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4IonisationByLogicalVolume::~G4IonisationByLogicalVolume()
|
||||
{
|
||||
if(fPAIonisation) delete fPAIonisation ;
|
||||
if(feIonisation) delete feIonisation ;
|
||||
if(fMuIonisation) delete fMuIonisation ;
|
||||
if(fhIonisation) delete fhIonisation ;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Methods
|
||||
|
||||
G4bool G4IonisationByLogicalVolume::
|
||||
IsApplicable( const G4ParticleDefinition& particle )
|
||||
{
|
||||
return( particle.GetPDGCharge() != 0.) ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
/* ***********************************************
|
||||
|
||||
G4double G4IonisationByLogicalVolume::
|
||||
GetConstraints(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial )
|
||||
{
|
||||
if ( aMaterial->GetName() == fMaterialNameForPAI )
|
||||
{
|
||||
return fPAIonisation->GetConstraints(aParticle,aMaterial) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
return feIonisation->GetConstraints(aParticle,aMaterial) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
return fMuIonisation->GetConstraints(aParticle,aMaterial) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fhIonisation->GetConstraints(aParticle,aMaterial) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
************************************** */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4VParticleChange*
|
||||
G4IonisationByLogicalVolume::PostStepDoIt( const G4Track& track,
|
||||
const G4Step& step )
|
||||
{
|
||||
if ( track.GetVolume()->GetLogicalVolume() == fVolumeForPAImodel )
|
||||
{
|
||||
return fPAIonisation->PostStepDoIt(track,step) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
return feIonisation->PostStepDoIt(track,step) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
return fMuIonisation->PostStepDoIt(track,step) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fhIonisation->PostStepDoIt(track,step) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
void G4IonisationByLogicalVolume::
|
||||
BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
fPAIonisation->BuildPhysicsTable(aParticleType) ;
|
||||
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
feIonisation->BuildPhysicsTable(aParticleType) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
fMuIonisation->BuildPhysicsTable(aParticleType) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fhIonisation->BuildPhysicsTable(aParticleType) ;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4IonisationByLogicalVolume::
|
||||
GetContinuousStepLimit( const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& currentSafety )
|
||||
{
|
||||
if ( track.GetVolume()->GetLogicalVolume() == fVolumeForPAImodel )
|
||||
{
|
||||
return fPAIonisation->GetContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimumStep,currentSafety) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
return feIonisation->GetContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimumStep,currentSafety) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
return fMuIonisation->GetContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimumStep,currentSafety) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fhIonisation->GetContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimumStep,currentSafety) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4IonisationByLogicalVolume::
|
||||
GetMeanFreePath( const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition )
|
||||
{
|
||||
if ( track.GetVolume()->GetLogicalVolume() == fVolumeForPAImodel )
|
||||
{
|
||||
return fPAIonisation->GetMeanFreePath(track,previousStepSize,condition) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
return feIonisation->GetMeanFreePath(track,previousStepSize,condition) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
return fMuIonisation->GetMeanFreePath(track,previousStepSize,condition) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fhIonisation->GetMeanFreePath(track,previousStepSize,condition) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4VParticleChange*
|
||||
G4IonisationByLogicalVolume::AlongStepDoIt( const G4Track& track ,
|
||||
const G4Step& step )
|
||||
{
|
||||
if ( track.GetVolume()->GetLogicalVolume() == fVolumeForPAImodel )
|
||||
{
|
||||
return fPAIonisation->AlongStepDoIt(track,step) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
return feIonisation->AlongStepDoIt(track,step) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
return fMuIonisation->AlongStepDoIt(track,step) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fhIonisation->AlongStepDoIt(track,step) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
void G4IonisationByLogicalVolume::
|
||||
SetVolumeForPAImodel( G4LogicalVolume* volumeForPAImodel )
|
||||
{
|
||||
fVolumeForPAImodel = volumeForPAImodel ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1,579 +0,0 @@
|
||||
// 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: G4MultipleScattering.cc,v 1.16.6.1.2.1 1999/12/08 17:34:24 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
//
|
||||
// $Id:
|
||||
// --------------------------------------------------------------
|
||||
// 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
|
||||
// -------- G4MultipleScattering physics process ------------
|
||||
// by Laszlo Urban, October 1997
|
||||
// **************************************************************
|
||||
// 24/10/97 correction in PostStepDoIt for tau << 1. L.Urban
|
||||
// 09/12/98: charge can be different from +-1 !!!! L.Urban
|
||||
// 29/07/99: corr. for low energy , L.Urban
|
||||
// 17/09/99: corr. for high energy and/or small step , L.Urban
|
||||
// 30/09/99: nuclear size effect correction, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4MultipleScattering.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
G4MultipleScattering::G4MultipleScattering(const G4String& processName)
|
||||
: G4VContinuousDiscreteProcess(processName),
|
||||
theTransportMeanFreePathTable(NULL),
|
||||
lastMaterial(NULL),
|
||||
lastKineticEnergy(0.),
|
||||
materialIndex(0),
|
||||
fTransportMeanFreePath (1.e12),
|
||||
range(1.e10*mm),
|
||||
alpha1(5.),
|
||||
stepFlag(0),
|
||||
biglambda (1.e10*mm),
|
||||
LowestKineticEnergy(0.1*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
TotBin(100),
|
||||
theElectron(G4Electron::Electron()),
|
||||
thePositron(G4Positron::Positron()),
|
||||
tLast (0.0),
|
||||
zLast (0.0),
|
||||
Tlimit(0.*keV),
|
||||
scatteringparameter(0.9),
|
||||
tuning (1.00),
|
||||
cpar (1.5),
|
||||
NuclCorrPar (0.0615),FactPar(0.40),
|
||||
fLatDisplFlag(true)
|
||||
{ }
|
||||
|
||||
G4MultipleScattering::~G4MultipleScattering()
|
||||
{
|
||||
if(theTransportMeanFreePathTable)
|
||||
{
|
||||
theTransportMeanFreePathTable->clearAndDestroy() ;
|
||||
delete theTransportMeanFreePathTable ;
|
||||
}
|
||||
}
|
||||
|
||||
// .........methods..............................
|
||||
|
||||
void G4MultipleScattering::BuildPhysicsTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
|
||||
// tables are built for MATERIALS
|
||||
{
|
||||
// parameter for "low energy" msc (not for ions)
|
||||
if((&aParticleType == G4Electron::Electron()) ||
|
||||
(&aParticleType == G4Positron::Positron()) )
|
||||
// Tlimit = 100.*keV ;
|
||||
;
|
||||
|
||||
const G4double sigmafactor = twopi*classic_electr_radius*
|
||||
classic_electr_radius ;
|
||||
G4double KineticEnergy,AtomicNumber,AtomicWeight,
|
||||
sigma,lambda ;
|
||||
G4double density ;
|
||||
|
||||
// destroy old tables if any
|
||||
if(theTransportMeanFreePathTable)
|
||||
{
|
||||
theTransportMeanFreePathTable->clearAndDestroy() ;
|
||||
delete theTransportMeanFreePathTable ;
|
||||
}
|
||||
|
||||
// create table
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length() ;
|
||||
|
||||
theTransportMeanFreePathTable = 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() ;
|
||||
density = material->GetDensity() ;
|
||||
|
||||
// loop for kinetic energy values
|
||||
for (G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
KineticEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
sigma = 0. ;
|
||||
|
||||
// loop for element in the material
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++)
|
||||
{
|
||||
AtomicNumber = (*theElementVector)(iel)->GetZ() ;
|
||||
AtomicWeight = (*theElementVector)(iel)->GetA() ;
|
||||
sigma += theAtomicNumDensityVector[iel]*
|
||||
ComputeTransportCrossSection(aParticleType,
|
||||
KineticEnergy,
|
||||
AtomicNumber,AtomicWeight) ;
|
||||
}
|
||||
sigma *= sigmafactor ;
|
||||
|
||||
lambda = 1./sigma ;
|
||||
|
||||
aVector->PutValue(i,lambda) ;
|
||||
}
|
||||
|
||||
theTransportMeanFreePathTable->insert(aVector) ;
|
||||
|
||||
}
|
||||
|
||||
if( (&aParticleType == G4Electron::Electron()) ||
|
||||
(&aParticleType == G4MuonPlus::MuonPlus()) ||
|
||||
(&aParticleType == G4Proton::Proton()) )
|
||||
{
|
||||
PrintInfoDefinition() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4double G4MultipleScattering::ComputeTransportCrossSection(
|
||||
const G4ParticleDefinition& aParticleType,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber,G4double AtomicWeight)
|
||||
{
|
||||
const G4double epsfactor = 2.*electron_mass_c2*electron_mass_c2*
|
||||
Bohr_radius*Bohr_radius/(hbarc*hbarc) ;
|
||||
const G4double epsmin = 1.e-4 , epsmax = 1.e10 ;
|
||||
|
||||
|
||||
const G4double Zdat[15] = {4.,6.,13.,20.,26.,29.,32.,38.,47.,
|
||||
50.,56.,64.,74.,79.,82. } ;
|
||||
|
||||
const G4double Tdat[22] =
|
||||
{ 0.0001*MeV,0.0002*MeV,0.0004*MeV,0.0007*MeV,
|
||||
0.001*MeV,0.002*MeV,0.004*MeV,0.007*MeV,0.01*MeV,
|
||||
0.02*MeV,0.04*MeV,0.07*MeV,0.1*MeV,0.2*MeV,
|
||||
0.4*MeV,0.7*MeV,1.*MeV,2.*MeV,4.*MeV,
|
||||
7.*MeV,10.*MeV,20.*MeV} ;
|
||||
|
||||
// corr. factors for e-/e+ lambda
|
||||
|
||||
const G4double celectron[15][22] =
|
||||
{{1.125,1.072,1.051,1.047,1.047,1.050,1.052,1.054,
|
||||
1.054,1.057,1.062,1.069,1.075,1.090,1.105,1.111,
|
||||
1.112,1.108,1.100,1.093,1.089,1.087 },
|
||||
{1.408,1.246,1.143,1.096,1.077,1.059,1.053,1.051,
|
||||
1.052,1.053,1.058,1.065,1.072,1.087,1.101,1.108,
|
||||
1.109,1.105,1.097,1.090,1.086,1.082 },
|
||||
{2.833,2.268,1.861,1.612,1.486,1.309,1.204,1.156,
|
||||
1.136,1.114,1.106,1.106,1.109,1.119,1.129,1.132,
|
||||
1.131,1.124,1.113,1.104,1.099,1.098 },
|
||||
{3.879,3.016,2.380,2.007,1.818,1.535,1.340,1.236,
|
||||
1.190,1.133,1.107,1.099,1.098,1.103,1.110,1.113,
|
||||
1.112,1.105,1.096,1.089,1.085,1.098 },
|
||||
{6.937,4.330,2.886,2.256,1.987,1.628,1.395,1.265,
|
||||
1.203,1.122,1.080,1.065,1.061,1.063,1.070,1.073,
|
||||
1.073,1.070,1.064,1.059,1.056,1.056 },
|
||||
{9.616,5.708,3.424,2.551,2.204,1.762,1.485,1.330,
|
||||
1.256,1.155,1.099,1.077,1.070,1.068,1.072,1.074,
|
||||
1.074,1.070,1.063,1.059,1.056,1.052 },
|
||||
{11.72,6.364,3.811,2.806,2.401,1.884,1.564,1.386,
|
||||
1.300,1.180,1.112,1.082,1.073,1.066,1.068,1.069,
|
||||
1.068,1.064,1.059,1.054,1.051,1.050 },
|
||||
{18.08,8.601,4.569,3.183,2.662,2.025,1.646,1.439,
|
||||
1.339,1.195,1.108,1.068,1.053,1.040,1.039,1.039,
|
||||
1.039,1.037,1.034,1.031,1.030,1.036 },
|
||||
{18.22,10.48,5.333,3.713,3.115,2.367,1.898,1.631,
|
||||
1.498,1.301,1.171,1.105,1.077,1.048,1.036,1.033,
|
||||
1.031,1.028,1.024,1.022,1.021,1.024 },
|
||||
{14.14,10.65,5.710,3.929,3.266,2.453,1.951,1.669,
|
||||
1.528,1.319,1.178,1.106,1.075,1.040,1.027,1.022,
|
||||
1.020,1.017,1.015,1.013,1.013,1.020 },
|
||||
{14.11,11.73,6.312,4.240,3.478,2.566,2.022,1.720,
|
||||
1.569,1.342,1.186,1.102,1.065,1.022,1.003,0.997,
|
||||
0.995,0.993,0.993,0.993,0.993,1.011 },
|
||||
{22.76,20.01,8.835,5.287,4.144,2.901,2.219,1.855,
|
||||
1.677,1.410,1.224,1.121,1.073,1.014,0.986,0.976,
|
||||
0.974,0.972,0.973,0.974,0.975,0.987 },
|
||||
{50.77,40.85,14.13,7.184,5.284,3.435,2.520,2.059,
|
||||
1.837,1.512,1.283,1.153,1.091,1.010,0.969,0.954,
|
||||
0.950,0.947,0.949,0.952,0.954,0.963 },
|
||||
{65.87,59.06,15.87,7.570,5.567,3.650,2.682,2.182,
|
||||
1.939,1.579,1.325,1.178,1.108,1.014,0.965,0.947,
|
||||
0.941,0.938,0.940,0.944,0.946,0.954 },
|
||||
// {45.60,47.34,15.92,7.810,5.755,3.767,2.760,2.239, misprint?
|
||||
{55.60,47.34,15.92,7.810,5.755,3.767,2.760,2.239,
|
||||
1.985,1.609,1.343,1.188,1.113,1.013,0.960,0.939,
|
||||
0.933,0.930,0.933,0.936,0.939,0.949 }};
|
||||
|
||||
const G4double cpositron[15][22] = {
|
||||
{2.589,2.044,1.658,1.446,1.347,1.217,1.144,1.110,
|
||||
1.097,1.083,1.080,1.086,1.092,1.108,1.123,1.131,
|
||||
1.131,1.126,1.117,1.108,1.103,1.100 },
|
||||
{3.904,2.794,2.079,1.710,1.543,1.325,1.202,1.145,
|
||||
1.122,1.096,1.089,1.092,1.098,1.114,1.130,1.137,
|
||||
1.138,1.132,1.122,1.113,1.108,1.102 },
|
||||
{7.970,6.080,4.442,3.398,2.872,2.127,1.672,1.451,
|
||||
1.357,1.246,1.194,1.179,1.178,1.188,1.201,1.205,
|
||||
1.203,1.190,1.173,1.159,1.151,1.145 },
|
||||
{9.714,7.607,5.747,4.493,3.815,2.777,2.079,1.715,
|
||||
1.553,1.353,1.253,1.219,1.211,1.214,1.225,1.228,
|
||||
1.225,1.210,1.191,1.175,1.166,1.174 },
|
||||
{17.97,12.95,8.628,6.065,4.849,3.222,2.275,1.820,
|
||||
1.624,1.382,1.259,1.214,1.202,1.202,1.214,1.219,
|
||||
1.217,1.203,1.184,1.169,1.160,1.151 },
|
||||
{24.83,17.06,10.84,7.355,5.767,3.707,2.546,1.996,
|
||||
1.759,1.465,1.311,1.252,1.234,1.228,1.238,1.241,
|
||||
1.237,1.222,1.201,1.184,1.174,1.159 },
|
||||
{23.26,17.15,11.52,8.049,6.375,4.114,2.792,2.155,
|
||||
1.880,1.535,1.353,1.281,1.258,1.247,1.254,1.256,
|
||||
1.252,1.234,1.212,1.194,1.183,1.170 },
|
||||
{22.33,18.01,12.86,9.212,7.336,4.702,3.117,2.348,
|
||||
2.015,1.602,1.385,1.297,1.268,1.251,1.256,1.258,
|
||||
1.254,1.237,1.214,1.195,1.185,1.179 },
|
||||
{33.91,24.13,15.71,10.80,8.507,5.467,3.692,2.808,
|
||||
2.407,1.873,1.564,1.425,1.374,1.330,1.324,1.320,
|
||||
1.312,1.288,1.258,1.235,1.221,1.205 },
|
||||
{32.14,24.11,16.30,11.40,9.015,5.782,3.868,2.917,
|
||||
2.490,1.925,1.596,1.447,1.391,1.342,1.332,1.327,
|
||||
1.320,1.294,1.264,1.240,1.226,1.214 },
|
||||
{29.51,24.07,17.19,12.28,9.766,6.238,4.112,3.066,
|
||||
2.602,1.995,1.641,1.477,1.414,1.356,1.342,1.336,
|
||||
1.328,1.302,1.270,1.245,1.231,1.233 },
|
||||
{38.19,30.85,21.76,15.35,12.07,7.521,4.812,3.498,
|
||||
2.926,2.188,1.763,1.563,1.484,1.405,1.382,1.371,
|
||||
1.361,1.330,1.294,1.267,1.251,1.239 },
|
||||
{49.71,39.80,27.96,19.63,15.36,9.407,5.863,4.155,
|
||||
3.417,2.478,1.944,1.692,1.589,1.480,1.441,1.423,
|
||||
1.409,1.372,1.330,1.298,1.280,1.258 },
|
||||
{59.25,45.08,30.36,20.83,16.15,9.834,6.166,4.407,
|
||||
3.641,2.648,2.064,1.779,1.661,1.531,1.482,1.459,
|
||||
1.442,1.400,1.354,1.319,1.299,1.272 },
|
||||
{56.38,44.29,30.50,21.18,16.51,10.11,6.354,4.542,
|
||||
3.752,2.724,2.116,1.817,1.692,1.554,1.499,1.474,
|
||||
1.456,1.412,1.364,1.328,1.307,1.282 }};
|
||||
|
||||
G4double Z23,ParticleMass,rat2,Charge,TotalEnergy,beta2,bg2,
|
||||
eps,Z1,Z2,ratZ,T,E,b2small,b2big,ratb2,c1,c2,cc1,cc2,
|
||||
corr,sigma,corrfactor,ChargeSquare ;
|
||||
G4int iZ,iT ;
|
||||
|
||||
Z23 = 2.*log(AtomicNumber)/3. ;
|
||||
Z23 = exp(Z23) ;
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
rat2 = ParticleMass/electron_mass_c2 ;
|
||||
rat2 = rat2*rat2 ;
|
||||
|
||||
Charge = aParticleType.GetPDGCharge() ;
|
||||
ChargeSquare = Charge*Charge/(eplus*eplus) ;
|
||||
|
||||
TotalEnergy = KineticEnergy + ParticleMass ;
|
||||
|
||||
beta2 = KineticEnergy*(TotalEnergy+ParticleMass)/
|
||||
(TotalEnergy*TotalEnergy) ;
|
||||
bg2 = KineticEnergy*(TotalEnergy+ParticleMass)/
|
||||
(ParticleMass*ParticleMass) ;
|
||||
|
||||
eps = rat2*epsfactor*bg2/Z23 ;
|
||||
|
||||
if(eps<epsmin)
|
||||
sigma = 2.*eps*eps*eps/3. ;
|
||||
else if(eps<epsmax)
|
||||
sigma = log(1.+2.*eps)-2.*eps/(1.+eps) ;
|
||||
else
|
||||
sigma = log(2.*eps)-2.+2.5/eps ;
|
||||
|
||||
sigma *=ChargeSquare*AtomicNumber*AtomicNumber/rat2 ;
|
||||
sigma /= beta2*bg2 ;
|
||||
|
||||
// nuclear size effect correction for high energy
|
||||
// ( a simple approximation at present)
|
||||
G4double corrnuclsize,a,x0,w1,w2,w ;
|
||||
|
||||
x0 = 1. - NuclCorrPar*ParticleMass/(KineticEnergy*
|
||||
exp(log(AtomicWeight/(g/mole))/3.)) ;
|
||||
if((x0 < -1.) || (KineticEnergy <= 10.*MeV))
|
||||
{
|
||||
x0=-1. ;
|
||||
corrnuclsize = 1. ;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = 1.+1./eps ;
|
||||
if(eps > epsmax)
|
||||
w1=log(2.*eps)+1./eps-3./(8.*eps*eps) ;
|
||||
else
|
||||
w1=log((a+1.)/(a-1.))-2./(a+1.) ;
|
||||
|
||||
w = 1./((1.-x0)*eps) ;
|
||||
if(w < epsmin)
|
||||
w2=-log(w)-1.+2.*w-1.5*w*w ;
|
||||
else
|
||||
w2 = log((a-x0)/(a-1.))-(1.-x0)/(a-x0) ;
|
||||
|
||||
corrnuclsize = w1/w2 ;
|
||||
|
||||
// ####################################################
|
||||
corrnuclsize = exp(-FactPar*proton_mass_c2/KineticEnergy)*
|
||||
(corrnuclsize-1.)+1. ;
|
||||
}
|
||||
|
||||
// correct this value using the corrections computed for e+/e-
|
||||
KineticEnergy *= electron_mass_c2/ParticleMass ;
|
||||
|
||||
// interpolate in AtomicNumber and beta2
|
||||
|
||||
// get bin number in Z
|
||||
iZ = 14 ;
|
||||
|
||||
while ((iZ>=0)&&(Zdat[iZ]>=AtomicNumber)) iZ -= 1 ;
|
||||
if (iZ==14) iZ = 13 ;
|
||||
if (iZ==-1) iZ = 0 ;
|
||||
|
||||
Z1 = Zdat[iZ] ;
|
||||
Z2 = Zdat[iZ+1] ;
|
||||
ratZ = (AtomicNumber-Z1)/(Z2-Z1) ;
|
||||
|
||||
// get bin number in T (beta2)
|
||||
iT = 21 ;
|
||||
while ((iT>=0)&&(Tdat[iT]>=KineticEnergy))
|
||||
iT -= 1 ;
|
||||
if(iT==21)
|
||||
iT = 20 ;
|
||||
if(iT==-1)
|
||||
iT = 0 ;
|
||||
|
||||
// calculate betasquare values
|
||||
T = Tdat[iT] ;
|
||||
E = T + electron_mass_c2 ;
|
||||
b2small = T*(E+electron_mass_c2)/(E*E) ;
|
||||
T = Tdat[iT+1] ;
|
||||
E = T + electron_mass_c2 ;
|
||||
b2big = T*(E+electron_mass_c2)/(E*E) ;
|
||||
ratb2 = (beta2-b2small)/(b2big-b2small) ;
|
||||
|
||||
corrfactor = tuning*(1.+cpar)/(1.+cpar*beta2) ;
|
||||
|
||||
if(Charge < 0.)
|
||||
{
|
||||
c1 = celectron[iZ][iT] ;
|
||||
c2 = celectron[iZ+1][iT] ;
|
||||
cc1 = c1+ratZ*(c2-c1) ;
|
||||
|
||||
c1 = celectron[iZ][iT+1] ;
|
||||
c2 = celectron[iZ+1][iT+1] ;
|
||||
cc2 = c1+ratZ*(c2-c1) ;
|
||||
|
||||
corr = cc1+ratb2*(cc2-cc1) ;
|
||||
|
||||
sigma /= corr ;
|
||||
|
||||
}
|
||||
|
||||
if(Charge > 0.)
|
||||
{
|
||||
c1 = cpositron[iZ][iT] ;
|
||||
c2 = cpositron[iZ+1][iT] ;
|
||||
cc1 = c1+ratZ*(c2-c1) ;
|
||||
|
||||
c1 = cpositron[iZ][iT+1] ;
|
||||
c2 = cpositron[iZ+1][iT+1] ;
|
||||
cc2 = c1+ratZ*(c2-c1) ;
|
||||
|
||||
corr = cc1+ratb2*(cc2-cc1) ;
|
||||
|
||||
sigma /= corr ;
|
||||
}
|
||||
|
||||
sigma *= corrfactor ;
|
||||
|
||||
sigma /= corrnuclsize ;
|
||||
|
||||
return sigma ;
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
static G4double taulim=1.e-6 , randlim = 0.25*taulim*taulim ;
|
||||
static const G4double tausmall = 5.e-5,taubig =50.,
|
||||
kappa = 2.5, kappapl1 = kappa+1., kappami1 = kappa-1. ;
|
||||
const G4DynamicParticle* aParticle ;
|
||||
G4Material* aMaterial ;
|
||||
G4double KineticEnergy,truestep,tau,prob,cth,sth,phi,
|
||||
dirx,diry,dirz,w,w1,etau,rmean,safetyminustolerance,
|
||||
xnew,ynew,znew ;
|
||||
G4double rand ;
|
||||
G4bool isOut;
|
||||
|
||||
fParticleChange.Initialize(trackData) ;
|
||||
|
||||
truestep = stepData.GetStepLength() ;
|
||||
|
||||
aParticle = trackData.GetDynamicParticle() ;
|
||||
|
||||
KineticEnergy = aParticle->GetKineticEnergy() ;
|
||||
|
||||
if(stepFlag == 0)
|
||||
{
|
||||
fTransportMeanFreePath = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(KineticEnergy,isOut);
|
||||
}
|
||||
|
||||
// change direction first ( scattering ) ..........................
|
||||
if(stepFlag == 0)
|
||||
{
|
||||
tau = truestep/fTransportMeanFreePath ;
|
||||
|
||||
if(tau > taulim)
|
||||
prob = exp(-tau)*(1.+scatteringparameter*tau) ;
|
||||
else
|
||||
prob=1.-(1.-scatteringparameter)*tau ;
|
||||
}
|
||||
else
|
||||
{
|
||||
tau = truestep/range ;
|
||||
if(tau < taulim)
|
||||
prob = exp(-(alpha1-1.)*tau)*(1.+scatteringparameter*tau) ;
|
||||
else
|
||||
prob = exp((alpha1-1.)*log(1.-tau))*(1.+scatteringparameter*tau) ;
|
||||
}
|
||||
|
||||
if(G4UniformRand()<prob)
|
||||
{
|
||||
if(tau<taulim)
|
||||
{
|
||||
rand = G4UniformRand() ;
|
||||
if(rand > randlim)
|
||||
{
|
||||
cth = 1.-scatteringparameter*tau*(1./sqrt(rand)-1.) ;
|
||||
if(cth < -1.) cth = -1. ;
|
||||
}
|
||||
else
|
||||
cth = -1. ;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = 1.+scatteringparameter*tau ;
|
||||
w1 = w-1. ;
|
||||
cth = w-w1*(w+1.)/sqrt(w1*w1+4.*w*G4UniformRand()) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
cth = -1.+2.*G4UniformRand() ;
|
||||
|
||||
sth = sqrt(1.-cth*cth) ;
|
||||
|
||||
phi = twopi*G4UniformRand() ;
|
||||
|
||||
dirx = sth*cos(phi) ;
|
||||
diry = sth*sin(phi) ;
|
||||
dirz = cth ;
|
||||
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection();
|
||||
|
||||
G4ThreeVector newDirection(dirx,diry,dirz) ;
|
||||
|
||||
|
||||
newDirection.rotateUz(ParticleDirection) ;
|
||||
|
||||
fParticleChange.SetMomentumChange(newDirection.x(),
|
||||
newDirection.y(),
|
||||
newDirection.z()) ;
|
||||
|
||||
if(fLatDisplFlag)
|
||||
{
|
||||
// compute mean lateral displacement ...............
|
||||
// only for safety > tolerance !!!!!!!!!
|
||||
safetyminustolerance = stepData.GetPostStepPoint()->GetSafety();
|
||||
|
||||
if(safetyminustolerance > 0.)
|
||||
{
|
||||
if(tau<tausmall)
|
||||
rmean = 5.*tau*tau*tau/12. ;
|
||||
else
|
||||
{
|
||||
if(tau<taubig)
|
||||
etau = exp(-tau) ;
|
||||
else
|
||||
etau = 0. ;
|
||||
rmean = -kappa*tau ;
|
||||
rmean = -exp(rmean)/(kappa*kappami1) ;
|
||||
rmean += tau-kappapl1/kappa+kappa*etau/kappami1 ;
|
||||
}
|
||||
|
||||
if(rmean>0.)
|
||||
rmean = 2.*fTransportMeanFreePath*sqrt(rmean/3.) ;
|
||||
else
|
||||
rmean = 0. ;
|
||||
|
||||
// for rmean > 0) only
|
||||
if(rmean>0.)
|
||||
{
|
||||
if(rmean>safetyminustolerance)
|
||||
rmean = safetyminustolerance ;
|
||||
|
||||
// sample direction of lateral displacement
|
||||
phi = twopi*G4UniformRand() ;
|
||||
|
||||
dirx = cos(phi) ;
|
||||
diry = sin(phi) ;
|
||||
dirz = 0. ;
|
||||
|
||||
G4ThreeVector latDirection(dirx,diry,dirz);
|
||||
|
||||
latDirection.rotateUz(ParticleDirection) ;
|
||||
|
||||
// compute new endpoint of the Step
|
||||
G4ThreeVector newPosition=
|
||||
stepData.GetPostStepPoint()->GetPosition()+
|
||||
rmean*latDirection;
|
||||
|
||||
G4Navigator *navigator=
|
||||
G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
navigator->LocateGlobalPointWithinVolume( newPosition );
|
||||
|
||||
fParticleChange.SetPositionChange(newPosition) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &fParticleChange ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void G4MultipleScattering::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = " Tables of transport mean free paths.";
|
||||
comments += "\n New model of MSC , computes the lateral \n";
|
||||
comments += " displacement of the particle , too.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,
|
||||
"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
}
|
||||
|
||||
@@ -1,845 +0,0 @@
|
||||
// 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: G4PAIenergyLoss.cc,v 1.2.8.1 1999/12/07 20:50:59 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
//
|
||||
// $Id:
|
||||
// -----------------------------------------------------------
|
||||
// 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
|
||||
// ---------- G4PAIenergyLoss physics process -----------
|
||||
// by V. Grichine, 30 Nov 1997
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
|
||||
// It calculates the energy loss of charged hadrons.
|
||||
// **************************************************************
|
||||
//
|
||||
// corrected by V. Grichine on 24/11/97
|
||||
// corrected by L. Urban on 27/05/98 ( other corrections come soon!)
|
||||
//
|
||||
|
||||
|
||||
#include "G4PAIenergyLoss.hh"
|
||||
#include "G4PAIonisation.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialisation of static members
|
||||
// ( this stuff should be defined later using RW ..........)
|
||||
// contributing processes : ion.loss ->NUMBEROFPROCESSES is initialized
|
||||
// to 1 . YOU DO NOT HAVE TO CHANGE this variable for a 'normal' run.
|
||||
// You have to change NUMBEROFPROCESSES
|
||||
// if you invent a new process contributing to the cont. energy loss,
|
||||
// NUMBEROFPROCESSES should be 2 in this case,
|
||||
// or for debugging purposes.
|
||||
// The NUMBEROFPROCESSES data member can be changed using the (public static)
|
||||
// functions Get/Set/Plus/MinusNUMBEROFPROCESSES (see G4hEnergyLoss.hh)
|
||||
|
||||
G4int G4PAIenergyLoss::NUMBEROFPROCESSES = 1 ;
|
||||
G4PhysicsTable** G4PAIenergyLoss::RecorderOfpProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
G4int G4PAIenergyLoss::CounterOfpProcess = 0 ;
|
||||
|
||||
G4PhysicsTable* G4PAIenergyLoss::theDEDXpTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::theRangepTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::theInverseRangepTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::theLabTimepTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::theProperTimepTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4PAIenergyLoss::thepRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::thepRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::thepRangeCoeffCTable = NULL ;
|
||||
|
||||
G4PhysicsTable** G4PAIenergyLoss::RecorderOfpbarProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
G4int G4PAIenergyLoss::CounterOfpbarProcess = 0 ;
|
||||
|
||||
G4PhysicsTable* G4PAIenergyLoss::theDEDXpbarTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::theRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::theInverseRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::theLabTimepbarTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::theProperTimepbarTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4PAIenergyLoss::thepbarRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::thepbarRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4PAIenergyLoss::thepbarRangeCoeffCTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4PAIenergyLoss::theDEDXTable = NULL;
|
||||
|
||||
// G4PhysicsTable* G4PAIenergyLoss::fPAItransferBank = NULL ;
|
||||
|
||||
G4double G4PAIenergyLoss::Mass,
|
||||
G4PAIenergyLoss::taulow,
|
||||
G4PAIenergyLoss::tauhigh,
|
||||
G4PAIenergyLoss::ltaulow,
|
||||
G4PAIenergyLoss::ltauhigh;
|
||||
|
||||
G4double G4PAIenergyLoss::CutInRange = 0;
|
||||
|
||||
const G4double G4PAIenergyLoss::LowestKineticEnergy= 1.00*keV ;
|
||||
const G4double G4PAIenergyLoss::HighestKineticEnergy= 100.*TeV ;
|
||||
G4int G4PAIenergyLoss::TotBin ;
|
||||
G4double G4PAIenergyLoss::RTable,G4PAIenergyLoss::LOGRTable;
|
||||
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4PAIenergyLoss::G4PAIenergyLoss(const G4String& processName)
|
||||
: G4VContinuousDiscreteProcess (processName),
|
||||
dToverTini(0.20), // max.relative range loss in one Step = 20%
|
||||
// LowestKineticEnergy(1.00*keV),
|
||||
// HighestKineticEnergy(100.*TeV),
|
||||
MaxExcitationNumber (1.e6),
|
||||
probLimFluct (0.01),
|
||||
nmaxDirectFluct (100),
|
||||
nmaxCont1(4),
|
||||
nmaxCont2(16),
|
||||
theElectron ( G4Electron::Electron() ),
|
||||
theProton ( G4Proton::Proton() ),
|
||||
theAntiProton ( G4AntiProton::AntiProton() )
|
||||
{
|
||||
theLossTable = NULL ;
|
||||
lastMaterial = NULL ;
|
||||
|
||||
// calculate data members TotBin,LOGRTable,RTable first
|
||||
G4double lrate ;
|
||||
G4int nbin ;
|
||||
// binning corresponds to 2.*dToverTini........................
|
||||
G4double binning = 2.*dToverTini ;
|
||||
|
||||
lrate = log(HighestKineticEnergy/LowestKineticEnergy) ;
|
||||
// nbin = G4int((lrate/log(1.+dToverTini) + lrate/log(1.+2.*dToverTini))/2.);
|
||||
nbin = G4int((lrate/log(1.+binning) + lrate/log(1.+2.*binning))/2.);
|
||||
nbin = (nbin+25)/50 ;
|
||||
TotBin = 50*nbin ;
|
||||
if(TotBin<50)
|
||||
TotBin = 50 ;
|
||||
if(TotBin>500)
|
||||
TotBin = 500 ;
|
||||
LOGRTable=lrate/TotBin;
|
||||
RTable =exp(LOGRTable);
|
||||
|
||||
}
|
||||
|
||||
G4PAIenergyLoss::~G4PAIenergyLoss()
|
||||
{
|
||||
if(theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
void G4PAIenergyLoss::BuildDEDXTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
G4bool MakeTable = false ;
|
||||
|
||||
G4double newCutInRange = aParticleType.GetLengthCuts();
|
||||
|
||||
// Create tables only if there is a new cut value !
|
||||
|
||||
// create/fill proton or antiproton tables depending on the charge of the particle
|
||||
G4double Charge = aParticleType.GetPDGCharge();
|
||||
|
||||
if (Charge>0.)
|
||||
{
|
||||
theDEDXTable= theDEDXpTable;
|
||||
}
|
||||
else
|
||||
{
|
||||
theDEDXTable= theDEDXpbarTable;
|
||||
}
|
||||
|
||||
if ((CutInRange != newCutInRange) || (theDEDXTable==NULL))
|
||||
{
|
||||
MakeTable = true ;
|
||||
CutInRange = newCutInRange ;
|
||||
}
|
||||
|
||||
if( MakeTable )
|
||||
{
|
||||
|
||||
// Build energy loss table as a sum of the energy loss due to the
|
||||
// different processes.
|
||||
//
|
||||
// different processes.
|
||||
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
|
||||
// create table for the total energy loss
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4PhysicsTable** RecorderOfProcess;
|
||||
int CounterOfProcess;
|
||||
|
||||
if( Charge >0.)
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpProcess;
|
||||
CounterOfProcess=CounterOfpProcess;
|
||||
|
||||
if(CounterOfProcess == NUMBEROFPROCESSES)
|
||||
{
|
||||
// create tables
|
||||
if(theDEDXpTable)
|
||||
{ theDEDXpTable->clearAndDestroy();
|
||||
delete theDEDXpTable; }
|
||||
theDEDXpTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXTable = theDEDXpTable;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpbarProcess;
|
||||
CounterOfProcess=CounterOfpbarProcess;
|
||||
|
||||
if(CounterOfProcess == NUMBEROFPROCESSES)
|
||||
{
|
||||
// create tables
|
||||
if(theDEDXpbarTable)
|
||||
{ theDEDXpbarTable->clearAndDestroy();
|
||||
delete theDEDXpbarTable; }
|
||||
theDEDXpbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXTable = theDEDXpbarTable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(CounterOfProcess == NUMBEROFPROCESSES)
|
||||
{
|
||||
// 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(
|
||||
LowestKineticEnergy, HighestKineticEnergy, TotBin);
|
||||
|
||||
// loop for the kinetic energy
|
||||
|
||||
for (G4int i=0; i<TotBin; i++)
|
||||
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
// here comes the sum of the different tables created by the
|
||||
// processes (ionisation,etc...)
|
||||
|
||||
Value = 0. ;
|
||||
|
||||
for (G4int process=0; process < NUMBEROFPROCESSES; process++)
|
||||
{
|
||||
pointer= RecorderOfProcess[process];
|
||||
Value += (*pointer)[J]->
|
||||
GetValue(LowEdgeEnergy,isOutRange) ;
|
||||
}
|
||||
|
||||
aVector->PutValue(i,Value) ;
|
||||
|
||||
}
|
||||
|
||||
theDEDXTable->insert(aVector) ;
|
||||
}
|
||||
|
||||
// reset counter to zero
|
||||
|
||||
if( Charge >0.) CounterOfpProcess=0 ;
|
||||
else CounterOfpbarProcess=0 ;
|
||||
|
||||
// Build range table
|
||||
|
||||
BuildRangeTable( aParticleType);
|
||||
|
||||
// Build coeff tables for the energy loss calculation
|
||||
|
||||
BuildRangeCoeffATable( aParticleType);
|
||||
BuildRangeCoeffBTable( aParticleType);
|
||||
BuildRangeCoeffCTable( aParticleType);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// make the energy loss and the range table available
|
||||
|
||||
const G4double lowestKineticEnergy(1.00*keV);
|
||||
const G4double highestKineticEnergy(100.*TeV);
|
||||
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
(Charge>0)?
|
||||
theDEDXpTable: theDEDXpbarTable,
|
||||
(Charge>0)?
|
||||
theRangepTable: theRangepbarTable,
|
||||
(Charge>0)?
|
||||
theInverseRangepTable: theInverseRangepbarTable,
|
||||
(Charge>0)?
|
||||
theLabTimepTable: theLabTimepbarTable,
|
||||
(Charge>0)?
|
||||
theProperTimepTable: theProperTimepbarTable,
|
||||
lowestKineticEnergy, highestKineticEnergy,
|
||||
proton_mass_c2/aParticleType.GetPDGMass(),TotBin);
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Build range table from the energy loss table
|
||||
|
||||
void G4PAIenergyLoss::BuildRangeTable( const G4ParticleDefinition& aParticleType)
|
||||
|
||||
{
|
||||
G4double Charge = aParticleType.GetPDGCharge() ;
|
||||
|
||||
Mass = proton_mass_c2;
|
||||
|
||||
// create table
|
||||
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4PhysicsTable* theRangeTable;
|
||||
|
||||
if( Charge >0.)
|
||||
{
|
||||
if(theRangepTable)
|
||||
{ theRangepTable->clearAndDestroy();
|
||||
delete theRangepTable; }
|
||||
theRangepTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeTable = theRangepTable ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(theRangepbarTable)
|
||||
{ theRangepbarTable->clearAndDestroy();
|
||||
delete theRangepbarTable; }
|
||||
theRangepbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeTable = theRangepbarTable ;
|
||||
}
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
// create vector
|
||||
G4PhysicsLogVector* aVector;
|
||||
|
||||
aVector = new G4PhysicsLogVector(LowestKineticEnergy,
|
||||
HighestKineticEnergy,TotBin);
|
||||
|
||||
// fill the vector ( ranges for the actual material)
|
||||
|
||||
BuildRangeVector(J, aVector);
|
||||
|
||||
// insert vector to the table
|
||||
|
||||
theRangeTable->insert(aVector);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// create range vector for a material
|
||||
//
|
||||
|
||||
void G4PAIenergyLoss::BuildRangeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* rangeVector)
|
||||
{
|
||||
static G4int nbin;
|
||||
const G4double BigRange = DBL_MAX ;
|
||||
G4int maxbint=100;
|
||||
G4bool isOut;
|
||||
G4double tlim=2.*MeV,t1=0.1*MeV,t2=0.025*MeV ;
|
||||
G4double loss1,loss2,ca,cb,cba ;
|
||||
G4double taulim,rangelim,ltaulim,ltaumax,
|
||||
LowEdgeEnergy,tau,Value,tau1,sqtau1 ;
|
||||
|
||||
G4PhysicsVector* physicsVector= (*theDEDXTable)[materialIndex];
|
||||
|
||||
const G4MaterialTable* theMaterialTable =
|
||||
G4Material::GetMaterialTable() ;
|
||||
|
||||
// low energy part first...
|
||||
|
||||
loss1 = physicsVector->GetValue(t1,isOut);
|
||||
loss2 = physicsVector->GetValue(t2,isOut);
|
||||
tau1 = t1/Mass ;
|
||||
sqtau1 = sqrt(tau1) ;
|
||||
ca = (4.*loss2-loss1)/sqtau1 ;
|
||||
cb = (2.*loss1-4.*loss2)/tau1 ;
|
||||
cba = cb/ca ;
|
||||
taulim = tlim/Mass ;
|
||||
ltaulim = log(taulim) ;
|
||||
ltaumax = log(HighestKineticEnergy/Mass) ;
|
||||
|
||||
// loop for kinetic energy
|
||||
|
||||
for (G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
LowEdgeEnergy = rangeVector->GetLowEdgeEnergy(i);
|
||||
tau = LowEdgeEnergy/Mass;
|
||||
if ( tau <= tau1 )
|
||||
{
|
||||
Value = 2.*Mass*log(1.+cba*sqrt(tau))/cb ;
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = 2.*Mass*log(1.+cba*sqtau1)/cb ;
|
||||
if(tau<=taulim)
|
||||
{
|
||||
nbin = (G4int)(maxbint*(tau-tau1)/(taulim-tau1)) ;
|
||||
if(nbin<1) nbin = 1;
|
||||
taulow = tau1 ;
|
||||
tauhigh = tau ;
|
||||
Value += RangeIntLin(physicsVector,nbin);
|
||||
}
|
||||
else
|
||||
{
|
||||
taulow = tau1 ;
|
||||
tauhigh = taulim ;
|
||||
Value += RangeIntLin(physicsVector,maxbint) ;
|
||||
ltaulow = ltaulim ;
|
||||
ltauhigh = log(tau) ;
|
||||
nbin = (G4int)(maxbint*(ltauhigh-ltaulow)/(ltaumax-ltaulow)) ;
|
||||
if(nbin<1) nbin= 1 ;
|
||||
Value += RangeIntLog(physicsVector,nbin);
|
||||
}
|
||||
}
|
||||
rangeVector->PutValue(i,Value);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// num. integration, linear binning
|
||||
//
|
||||
|
||||
G4double G4PAIenergyLoss::RangeIntLin(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
{
|
||||
G4double dtau,Value,taui,ti,lossi,ci;
|
||||
G4bool isOut;
|
||||
|
||||
dtau = (tauhigh-taulow)/nbin;
|
||||
Value = 0.;
|
||||
|
||||
for (G4int i=0; i<=nbin; i++)
|
||||
{
|
||||
taui = taulow + dtau*i ;
|
||||
ti = Mass*taui;
|
||||
lossi = physicsVector->GetValue(ti,isOut);
|
||||
|
||||
if(i==0)
|
||||
ci=0.5;
|
||||
else
|
||||
{
|
||||
if(i<nbin)
|
||||
ci=1.;
|
||||
else
|
||||
ci=0.5;
|
||||
}
|
||||
|
||||
Value += ci/lossi;
|
||||
}
|
||||
|
||||
Value *= Mass*dtau;
|
||||
|
||||
return Value;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// num. integration, logarithmic binning
|
||||
//
|
||||
|
||||
G4double G4PAIenergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
{
|
||||
G4double ltt,dltau,Value,ui,taui,ti,lossi,ci;
|
||||
G4bool isOut;
|
||||
|
||||
ltt = ltauhigh-ltaulow;
|
||||
dltau = ltt/nbin;
|
||||
Value = 0.;
|
||||
|
||||
for (G4int i=0; i<=nbin; i++)
|
||||
{
|
||||
ui = ltaulow+dltau*i;
|
||||
taui = exp(ui);
|
||||
ti = Mass*taui;
|
||||
lossi = physicsVector->GetValue(ti,isOut);
|
||||
|
||||
if(i==0)
|
||||
ci=0.5;
|
||||
else
|
||||
{
|
||||
if(i<nbin)
|
||||
ci=1.;
|
||||
else
|
||||
ci=0.5;
|
||||
}
|
||||
|
||||
Value += ci*taui/lossi;
|
||||
}
|
||||
|
||||
Value *= Mass*dltau;
|
||||
|
||||
return Value;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// returns the range of a particle in a given material
|
||||
//
|
||||
|
||||
G4double G4PAIenergyLoss::OldGetRange(const G4DynamicParticle *aParticle,
|
||||
G4Material *aMaterial)
|
||||
{
|
||||
G4int materialIndex;
|
||||
G4double KineticEnergy,Range;
|
||||
G4double BigRange = DBL_MAX;
|
||||
G4bool isOut;
|
||||
G4double Charge = aParticle->GetDefinition()->GetPDGCharge() ;
|
||||
G4double Chargesquare = Charge*Charge ;
|
||||
G4double MassRatio = proton_mass_c2/aParticle->GetDefinition()->GetPDGMass() ;
|
||||
|
||||
G4PhysicsTable* theRangeTable;
|
||||
|
||||
if(Charge>0.) theRangeTable=theRangepTable ;
|
||||
|
||||
else theRangeTable=theRangepbarTable ;
|
||||
|
||||
materialIndex = aMaterial->GetIndex();
|
||||
KineticEnergy = aParticle->GetKineticEnergy()*MassRatio;
|
||||
|
||||
if(KineticEnergy<LowestKineticEnergy)
|
||||
Range = BigRange ;
|
||||
|
||||
else
|
||||
{
|
||||
if(KineticEnergy>HighestKineticEnergy) Range = BigRange ;
|
||||
|
||||
else Range = (*theRangeTable)[materialIndex]->GetValue(KineticEnergy,isOut) ;
|
||||
|
||||
}
|
||||
return Range/Chargesquare ;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
//
|
||||
|
||||
void G4PAIenergyLoss::
|
||||
BuildRangeCoeffATable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
|
||||
// create table for coefficients "A"
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
G4double Charge = aParticleType.GetPDGCharge() ;
|
||||
|
||||
G4PhysicsTable* theRangeTable;
|
||||
G4PhysicsTable* theRangeCoeffATable;
|
||||
if(Charge>0.)
|
||||
{
|
||||
if(thepRangeCoeffATable)
|
||||
{
|
||||
thepRangeCoeffATable->clearAndDestroy() ;
|
||||
delete thepRangeCoeffATable ;
|
||||
}
|
||||
thepRangeCoeffATable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffATable = thepRangeCoeffATable ;
|
||||
theRangeTable = theRangepTable ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(thepbarRangeCoeffATable)
|
||||
{
|
||||
thepbarRangeCoeffATable->clearAndDestroy() ;
|
||||
delete thepbarRangeCoeffATable ;
|
||||
}
|
||||
thepbarRangeCoeffATable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffATable = thepbarRangeCoeffATable ;
|
||||
theRangeTable = theRangepbarTable ;
|
||||
}
|
||||
G4double R2 = RTable*RTable ;
|
||||
G4double R1 = RTable+1.;
|
||||
G4double w = R1*(RTable-1.)*(RTable-1.);
|
||||
G4double w1 = RTable/w , w2 = -RTable*R1/w , w3 = R2/w ;
|
||||
G4double Ti , Tim , Tip , Ri , Rim , Rip , Value ;
|
||||
G4bool isOut;
|
||||
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++) // loop for materials
|
||||
{
|
||||
// create vector
|
||||
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector = new G4PhysicsLinearVector(0.,binmax, TotBin);
|
||||
|
||||
// loop for kinetic energy
|
||||
|
||||
Ti = LowestKineticEnergy ;
|
||||
|
||||
G4PhysicsVector* rangeVector= (*theRangeTable)[J];
|
||||
|
||||
for ( G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
Ri = rangeVector->GetValue(Ti,isOut) ;
|
||||
|
||||
if ( i==0 ) Rim = 0. ;
|
||||
else
|
||||
{
|
||||
Tim = Ti/RTable ;
|
||||
Rim = rangeVector->GetValue(Tim,isOut);
|
||||
}
|
||||
if ( i==(TotBin-1)) Rip = Ri ;
|
||||
else
|
||||
{
|
||||
Tip = Ti*RTable ;
|
||||
Rip = rangeVector->GetValue(Tip,isOut);
|
||||
}
|
||||
Value = (w1*Rip + w2*Ri + w3*Rim)/(Ti*Ti) ;
|
||||
|
||||
aVector->PutValue(i,Value);
|
||||
|
||||
Ti = RTable*Ti ;
|
||||
}
|
||||
theRangeCoeffATable->insert(aVector);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
//
|
||||
|
||||
void G4PAIenergyLoss::
|
||||
BuildRangeCoeffBTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
|
||||
|
||||
// create table for coefficients "B"
|
||||
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
G4double Charge = aParticleType.GetPDGCharge() ;
|
||||
|
||||
G4PhysicsTable* theRangeTable;
|
||||
G4PhysicsTable* theRangeCoeffBTable;
|
||||
if(Charge>0.)
|
||||
{
|
||||
if(thepRangeCoeffBTable)
|
||||
{
|
||||
thepRangeCoeffBTable->clearAndDestroy();
|
||||
delete thepRangeCoeffBTable ;
|
||||
}
|
||||
thepRangeCoeffBTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffBTable = thepRangeCoeffBTable ;
|
||||
theRangeTable = theRangepTable ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(thepbarRangeCoeffBTable)
|
||||
{
|
||||
thepbarRangeCoeffBTable->clearAndDestroy();
|
||||
delete thepbarRangeCoeffBTable;
|
||||
}
|
||||
thepbarRangeCoeffBTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffBTable = thepbarRangeCoeffBTable ;
|
||||
theRangeTable = theRangepbarTable ;
|
||||
}
|
||||
|
||||
G4double R2 = RTable*RTable ;
|
||||
G4double R1 = RTable+1.;
|
||||
G4double w = R1*(RTable-1.)*(RTable-1.);
|
||||
G4double w1 = -R1/w , w2 = R1*(R2+1.)/w , w3 = -R2*R1/w ;
|
||||
G4double Ti , Tim , Tip , Ri , Rim , Rip , Value ;
|
||||
G4bool isOut;
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
// create vector
|
||||
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector = new G4PhysicsLinearVector(0.,binmax, TotBin);
|
||||
|
||||
// loop for kinetic energy
|
||||
|
||||
Ti = LowestKineticEnergy ;
|
||||
|
||||
G4PhysicsVector* rangeVector= (*theRangeTable)[J];
|
||||
|
||||
for ( G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
Ri = rangeVector->GetValue(Ti,isOut) ;
|
||||
|
||||
if ( i==0 ) Rim = 0. ;
|
||||
else
|
||||
{
|
||||
Tim = Ti/RTable ;
|
||||
Rim = rangeVector->GetValue(Tim,isOut);
|
||||
}
|
||||
if ( i==(TotBin-1)) Rip = Ri ;
|
||||
else
|
||||
{
|
||||
Tip = Ti*RTable ;
|
||||
Rip = rangeVector->GetValue(Tip,isOut);
|
||||
}
|
||||
Value = (w1*Rip + w2*Ri + w3*Rim)/Ti;
|
||||
|
||||
aVector->PutValue(i,Value);
|
||||
|
||||
Ti = RTable*Ti ;
|
||||
}
|
||||
theRangeCoeffBTable->insert(aVector) ;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
//
|
||||
|
||||
void G4PAIenergyLoss::BuildRangeCoeffCTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
|
||||
// create table for coefficients "C"
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
G4double Charge = aParticleType.GetPDGCharge() ;
|
||||
|
||||
G4PhysicsTable* theRangeTable;
|
||||
G4PhysicsTable* theRangeCoeffCTable;
|
||||
if(Charge>0.)
|
||||
{
|
||||
if(thepRangeCoeffCTable)
|
||||
{ thepRangeCoeffCTable->clearAndDestroy();
|
||||
delete thepRangeCoeffCTable; }
|
||||
thepRangeCoeffCTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffCTable = thepRangeCoeffCTable ;
|
||||
theRangeTable = theRangepTable ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(thepbarRangeCoeffCTable)
|
||||
{ thepbarRangeCoeffCTable->clearAndDestroy();
|
||||
delete thepbarRangeCoeffCTable; }
|
||||
thepbarRangeCoeffCTable = new G4PhysicsTable(numOfMaterials);
|
||||
theRangeCoeffCTable = thepbarRangeCoeffCTable ;
|
||||
theRangeTable = theRangepbarTable ;
|
||||
}
|
||||
|
||||
const G4double BigRange = DBL_MAX ;
|
||||
G4double R2 = RTable*RTable ;
|
||||
G4double R1 = RTable+1.;
|
||||
G4double w = R1*(RTable-1.)*(RTable-1.);
|
||||
G4double w1 = 1./w , w2 = -RTable*R1/w , w3 = RTable*R2/w ;
|
||||
G4double Ti , Tim , Tip , Ri , Rim , Rip , Value ;
|
||||
G4bool isOut;
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
// create vector
|
||||
|
||||
G4int binmax=TotBin ;
|
||||
G4PhysicsLinearVector* aVector = new G4PhysicsLinearVector(0.,binmax, TotBin);
|
||||
|
||||
// loop for kinetic energy
|
||||
|
||||
Ti = LowestKineticEnergy ;
|
||||
|
||||
G4PhysicsVector* rangeVector= (*theRangeTable)[J];
|
||||
|
||||
for ( G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
Ri = rangeVector->GetValue(Ti,isOut) ;
|
||||
|
||||
if ( i==0 ) Rim = 0. ;
|
||||
else
|
||||
{
|
||||
Tim = Ti/RTable ;
|
||||
Rim = rangeVector->GetValue(Tim,isOut);
|
||||
}
|
||||
if ( i==(TotBin-1)) Rip = Ri ;
|
||||
else
|
||||
{
|
||||
Tip = Ti*RTable ;
|
||||
Rip = rangeVector->GetValue(Tip,isOut);
|
||||
}
|
||||
Value = w1*Rip + w2*Ri + w3*Rim ;
|
||||
|
||||
aVector->PutValue(i,Value);
|
||||
|
||||
Ti = RTable*Ti ;
|
||||
}
|
||||
theRangeCoeffCTable->insert(aVector) ;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4PAIonisation.cc,v 1.2.8.1.2.1 1999/12/08 17:34:24 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4PAIonisation.cc,v 1.8 2000/05/02 15:12:45 grichine Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
@@ -52,7 +52,7 @@ G4PAIonisation::fProtonEnergyVector = new G4PhysicsLogVector(LowestKineticEnergy
|
||||
|
||||
G4PAIonisation::G4PAIonisation( const G4String& materialName,
|
||||
const G4String& processName)
|
||||
: G4PAIenergyLoss(processName),
|
||||
: G4VPAIenergyLoss(processName),
|
||||
theElectron ( G4Electron::Electron() )
|
||||
{
|
||||
G4int numberOfMat, iMat ;
|
||||
@@ -85,12 +85,17 @@ G4PAIonisation::G4PAIonisation( const G4String& materialName,
|
||||
|
||||
G4PAIonisation::~G4PAIonisation()
|
||||
{
|
||||
if (theMeanFreePathTable)
|
||||
{
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
if ( theMeanFreePathTable )
|
||||
{
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
if( fPAItransferBank )
|
||||
{
|
||||
fPAItransferBank->clearAndDestroy() ;
|
||||
delete fPAItransferBank ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
@@ -179,7 +184,7 @@ G4PAIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
lastCutInRange = CutInRange ;
|
||||
BuildLambdaTable(aParticleType) ;
|
||||
}
|
||||
// G4PAIenergyLoss::BuildDEDXTable(aParticleType) ;
|
||||
// G4VPAIenergyLoss::BuildDEDXTable(aParticleType) ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -195,7 +200,7 @@ G4PAIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
G4double Charge = aParticleType.GetPDGCharge() ;
|
||||
|
||||
G4double LowEdgeEnergy , ionloss ;
|
||||
G4double ParticleMass , RateMass ;
|
||||
G4double RateMass ;
|
||||
G4bool isOutRange ;
|
||||
static const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const G4double SmallIonLoss = DBL_MIN ;
|
||||
@@ -304,7 +309,9 @@ G4PAIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
tau = 0.01 ;
|
||||
}
|
||||
gamma = tau +1. ;
|
||||
G4cout<<"gamma = "<<gamma<<G4endl ;
|
||||
|
||||
// G4cout<<"gamma = "<<gamma<<endl ;
|
||||
|
||||
bg2 = tau*(tau+2.) ;
|
||||
beta2 = bg2/(gamma*gamma) ;
|
||||
Tmax = 2.*electron_mass_c2*bg2
|
||||
@@ -319,8 +326,8 @@ G4PAIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
|
||||
ionloss = protonPAI.GetMeanEnergyLoss() ; // total <dE/dx>
|
||||
|
||||
G4cout<<"ionloss = "<<ionloss*cm/keV<<" keV/cm"<<G4endl ;
|
||||
G4cout<<"n1 = "<<protonPAI.GetIntegralPAIxSection(1)*cm<<" 1/cm"<<G4endl ;
|
||||
// G4cout<<"ionloss = "<<ionloss*cm/keV<<" keV/cm"<<endl ;
|
||||
// G4cout<<"n1 = "<<protonPAI.GetIntegralPAIxSection(1)*cm<<" 1/cm"<<endl ;
|
||||
// G4cout<<"protonPAI.GetSplineSize() = "<<
|
||||
// protonPAI.GetSplineSize()<<G4endl ;
|
||||
|
||||
@@ -435,7 +442,7 @@ ComputeMicroscopicCrossSection( const G4ParticleDefinition& aParticleType,
|
||||
G4double KineticEnergy ,
|
||||
G4double AtomicNumber )
|
||||
{
|
||||
G4double TotalEnergy, ParticleMass, betasquare,
|
||||
G4double TotalEnergy, betasquare,
|
||||
MaxKineticEnergyTransfer,
|
||||
TotalCrossSection, tempvar ;
|
||||
const G4double SmallCrossSection = DBL_MIN;
|
||||
@@ -487,7 +494,7 @@ G4PAIonisation::PostStepDoIt( const G4Track& trackData,
|
||||
{
|
||||
const G4DynamicParticle* aParticle ;
|
||||
G4Material* aMaterial;
|
||||
G4double KineticEnergy, TotalEnergy, ParticleMass, TotalMomentum,
|
||||
G4double KineticEnergy, TotalEnergy, TotalMomentum,
|
||||
betasquare, MaxKineticEnergyTransfer, DeltaKineticEnergy,
|
||||
DeltaTotalMomentum, costheta, sintheta, phi, dirx, diry,
|
||||
dirz, finalKineticEnergy, finalPx, finalPy, finalPz, x, xc,
|
||||
@@ -656,10 +663,7 @@ G4VParticleChange* G4PAIonisation::AlongStepDoIt( const G4Track& trackData,
|
||||
|
||||
if( Step == 0. || index != fMatIndex ) return &aParticleChange ;
|
||||
|
||||
G4cout<<"step = "<<Step/mm<<" mm"<<G4endl ;
|
||||
|
||||
|
||||
|
||||
// G4cout<<"step = "<<Step/mm<<" mm"<<endl ;
|
||||
|
||||
// get particle and material pointers from trackData
|
||||
|
||||
@@ -730,7 +734,7 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
G4int index = aMaterial->GetIndex() ;
|
||||
G4bool isOutRange ;
|
||||
|
||||
// G4cout<<"G4PAIenergyLoss::GetLossWithFluct"<<G4endl ;
|
||||
// G4cout<<"G4VPAIenergyLoss::GetLossWithFluct"<<G4endl ;
|
||||
|
||||
G4double loss = 0.0 ;
|
||||
G4double transfer, position, E1, E2, W1, W2, W, firstMu, secondMu ;
|
||||
@@ -751,7 +755,7 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
}
|
||||
G4int iPlace = iTkin - 1 ; // index*(G4PAIonisation::GetBinNumber()) +
|
||||
|
||||
G4cout<<"iPlace = "<<iPlace<<G4endl ;
|
||||
// G4cout<<"iPlace = "<<iPlace<<endl ;
|
||||
|
||||
G4PhysicsVector* firstVector = (*fPAItransferBank)(iPlace) ;
|
||||
G4PhysicsVector* secondVector = (*fPAItransferBank)(iPlace + 1) ;
|
||||
@@ -760,7 +764,7 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
{
|
||||
numOfCollisions = RandPoisson::shoot((*(*fPAItransferBank)(iPlace))(0)*Step) ;
|
||||
|
||||
G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
@@ -781,7 +785,7 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
numOfCollisions = RandPoisson::
|
||||
shoot((*(*fPAItransferBank)(iPlace+1))(0)*Step) ;
|
||||
|
||||
G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
@@ -812,7 +816,8 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
( (*(*fPAItransferBank)(iPlace))(0)*W1 +
|
||||
(*(*fPAItransferBank)(iPlace+1))(0)*W2 )*Step) ;
|
||||
|
||||
G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
@@ -835,7 +840,8 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
}
|
||||
}
|
||||
}
|
||||
G4cout<<"PAI loss = "<<loss/keV<<" keV"<<G4endl ;
|
||||
// G4cout<<"PAI loss = "<<loss/keV<<" keV"<<endl ;
|
||||
|
||||
return loss ;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4PAIxSection.cc,v 1.3.6.1.2.1 1999/12/08 17:34:24 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4PAIxSection.cc,v 1.4 1999/12/15 14:51:51 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
// G4PAIxSection.cc -- class implementation file
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4PhotoElectricEffect.cc,v 1.8.6.1.2.1 1999/12/08 17:34:25 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4PhotoElectricEffect.cc,v 1.9 1999/12/15 14:51:52 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -27,7 +27,7 @@
|
||||
// 08-01-97, crossection table + meanfreepath table, M.Maire
|
||||
// 13-03-97, adapted for the new physics scheme, M.Maire
|
||||
// 28-03-97, protection in BuildPhysicsTable, M.Maire
|
||||
// 04-06-98, in DoIt, secondary production condition: range>min(threshold,safety)
|
||||
// 04-06-98, in DoIt, secondary production condition: range>G4std::min(threshold,safety)
|
||||
// 13-08-98, new methods SetBining() PrintInfo()
|
||||
// 17-11-98, use table of Atomic shells in PostStepDoIt
|
||||
// 06-01-99, use Sandia crossSection below 50 keV, V.Grichine mma
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4PolarizedComptonScattering.cc,v 1.1.10.1 1999/12/07 20:51:01 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4PolarizedComptonScattering.cc,v 1.2 1999/12/15 14:51:52 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4SynchrotronRadiation.cc,v 1.1.10.1 1999/12/07 20:51:01 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4SynchrotronRadiation.cc,v 1.2 1999/12/15 14:51:52 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
|
||||
+50
-50
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IeEnergyLoss.cc,v 1.7.6.1 1999/12/07 20:50:58 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4VIeEnergyLoss.cc,v 1.1 2000/04/25 14:33:09 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// $Id:
|
||||
// -----------------------------------------------------------
|
||||
@@ -16,7 +16,7 @@
|
||||
// CERN, IT Division, ASD group
|
||||
// History: based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ---------- G4IeEnergyLoss physics process -----------
|
||||
// ---------- G4VIeEnergyLoss physics process -----------
|
||||
// by Laszlo Urban, 20 March 1997
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
|
||||
@@ -31,7 +31,7 @@
|
||||
// 26-10-98: revision, TOF tables L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4IeEnergyLoss.hh"
|
||||
#include "G4VIeEnergyLoss.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
#include "G4Poisson.hh"
|
||||
@@ -46,47 +46,47 @@
|
||||
// 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 G4IeEnergyLoss.hh)
|
||||
// functions Get/Set/Plus/MinusNbOfProcesses (see G4VIeEnergyLoss.hh)
|
||||
|
||||
G4int G4IeEnergyLoss::NbOfProcesses = 2;
|
||||
G4int G4VIeEnergyLoss::NbOfProcesses = 2;
|
||||
|
||||
G4int G4IeEnergyLoss::CounterOfElectronProcess = 0;
|
||||
G4int G4IeEnergyLoss::CounterOfPositronProcess = 0;
|
||||
G4PhysicsTable** G4IeEnergyLoss::RecorderOfElectronProcess =
|
||||
G4int G4VIeEnergyLoss::CounterOfElectronProcess = 0;
|
||||
G4int G4VIeEnergyLoss::CounterOfPositronProcess = 0;
|
||||
G4PhysicsTable** G4VIeEnergyLoss::RecorderOfElectronProcess =
|
||||
new G4PhysicsTable*[10];
|
||||
G4PhysicsTable** G4IeEnergyLoss::RecorderOfPositronProcess =
|
||||
G4PhysicsTable** G4VIeEnergyLoss::RecorderOfPositronProcess =
|
||||
new G4PhysicsTable*[10];
|
||||
|
||||
G4bool G4IeEnergyLoss::rndmStepFlag = false;
|
||||
G4bool G4IeEnergyLoss::EnlossFlucFlag = true;
|
||||
G4double G4IeEnergyLoss::dRoverRange = 20*perCent;
|
||||
G4double G4IeEnergyLoss::finalRange = 200*micrometer;
|
||||
G4bool G4VIeEnergyLoss::rndmStepFlag = false;
|
||||
G4bool G4VIeEnergyLoss::EnlossFlucFlag = true;
|
||||
G4double G4VIeEnergyLoss::dRoverRange = 20*perCent;
|
||||
G4double G4VIeEnergyLoss::finalRange = 200*micrometer;
|
||||
|
||||
G4PhysicsTable* G4IeEnergyLoss::theDEDXElectronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theDEDXPositronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theRangeElectronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theRangePositronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theInverseRangeElectronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theInverseRangePositronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theLabTimeElectronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theLabTimePositronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theProperTimeElectronTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theProperTimePositronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theDEDXElectronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theDEDXPositronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theRangeElectronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theRangePositronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theInverseRangeElectronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theInverseRangePositronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theLabTimeElectronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theLabTimePositronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theProperTimeElectronTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theProperTimePositronTable = NULL;
|
||||
|
||||
G4PhysicsTable* G4IeEnergyLoss::theeRangeCoeffATable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theeRangeCoeffBTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::theeRangeCoeffCTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::thepRangeCoeffATable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::thepRangeCoeffBTable = NULL;
|
||||
G4PhysicsTable* G4IeEnergyLoss::thepRangeCoeffCTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theeRangeCoeffATable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theeRangeCoeffBTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::theeRangeCoeffCTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::thepRangeCoeffATable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::thepRangeCoeffBTable = NULL;
|
||||
G4PhysicsTable* G4VIeEnergyLoss::thepRangeCoeffCTable = NULL;
|
||||
|
||||
G4EnergyLossMessenger* G4IeEnergyLoss::eLossMessenger = NULL;
|
||||
G4EnergyLossMessenger* G4VIeEnergyLoss::eLossMessenger = NULL;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4IeEnergyLoss::G4IeEnergyLoss(const G4String& processName)
|
||||
G4VIeEnergyLoss::G4VIeEnergyLoss(const G4String& processName)
|
||||
: G4IVContinuousDiscreteProcess (processName),
|
||||
theLossTable(NULL),
|
||||
theRangeCoeffATable(NULL),
|
||||
@@ -107,7 +107,7 @@ G4IeEnergyLoss::G4IeEnergyLoss(const G4String& processName)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4IeEnergyLoss::~G4IeEnergyLoss()
|
||||
G4VIeEnergyLoss::~G4VIeEnergyLoss()
|
||||
{
|
||||
if (theLossTable)
|
||||
{
|
||||
@@ -118,7 +118,7 @@ G4IeEnergyLoss::~G4IeEnergyLoss()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildDEDXTable(
|
||||
void G4VIeEnergyLoss::BuildDEDXTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
ParticleMass = aParticleType.GetPDGMass();
|
||||
@@ -252,7 +252,7 @@ void G4IeEnergyLoss::BuildDEDXTable(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildRangeTable(
|
||||
void G4VIeEnergyLoss::BuildRangeTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build range table from the energy loss table
|
||||
@@ -293,7 +293,7 @@ void G4IeEnergyLoss::BuildRangeTable(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildTimeTables(
|
||||
void G4VIeEnergyLoss::BuildTimeTables(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build time tables from the energy loss table
|
||||
@@ -355,7 +355,7 @@ void G4IeEnergyLoss::BuildTimeTables(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildRangeVector(G4int materialIndex,
|
||||
void G4VIeEnergyLoss::BuildRangeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* rangeVector)
|
||||
{
|
||||
// create range vector for a material
|
||||
@@ -412,7 +412,7 @@ void G4IeEnergyLoss::BuildRangeVector(G4int materialIndex,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildLabTimeVector(G4int materialIndex,
|
||||
void G4VIeEnergyLoss::BuildLabTimeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* timeVector)
|
||||
// create lab time vector for a material
|
||||
{
|
||||
@@ -469,7 +469,7 @@ void G4IeEnergyLoss::BuildLabTimeVector(G4int materialIndex,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildProperTimeVector(G4int materialIndex,
|
||||
void G4VIeEnergyLoss::BuildProperTimeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* timeVector)
|
||||
{
|
||||
// create lab time vector for a material
|
||||
@@ -526,7 +526,7 @@ void G4IeEnergyLoss::BuildProperTimeVector(G4int materialIndex,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IeEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4double G4VIeEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
// num. integration, logarithmic binning
|
||||
{
|
||||
@@ -550,7 +550,7 @@ G4double G4IeEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IeEnergyLoss::LabTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4double G4VIeEnergyLoss::LabTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
// num. integration, logarithmic binning
|
||||
{
|
||||
@@ -575,7 +575,7 @@ G4double G4IeEnergyLoss::LabTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IeEnergyLoss::ProperTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4double G4VIeEnergyLoss::ProperTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
// num. integration, logarithmic binning
|
||||
{
|
||||
@@ -600,7 +600,7 @@ G4double G4IeEnergyLoss::ProperTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildRangeCoeffATable(
|
||||
void G4VIeEnergyLoss::BuildRangeCoeffATable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
@@ -661,7 +661,7 @@ void G4IeEnergyLoss::BuildRangeCoeffATable(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildRangeCoeffBTable(
|
||||
void G4VIeEnergyLoss::BuildRangeCoeffBTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
@@ -722,7 +722,7 @@ void G4IeEnergyLoss::BuildRangeCoeffBTable(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildRangeCoeffCTable(
|
||||
void G4VIeEnergyLoss::BuildRangeCoeffCTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
@@ -782,7 +782,7 @@ void G4IeEnergyLoss::BuildRangeCoeffCTable(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::BuildInverseRangeTable(
|
||||
void G4VIeEnergyLoss::BuildInverseRangeTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build inverse table of the range table
|
||||
@@ -844,7 +844,7 @@ void G4IeEnergyLoss::BuildRangeCoeffCTable(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IeEnergyLoss::InvertRangeVector(G4int materialIndex,
|
||||
void G4VIeEnergyLoss::InvertRangeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* aVector)
|
||||
{
|
||||
// invert range vector for a material
|
||||
@@ -888,7 +888,7 @@ void G4IeEnergyLoss::InvertRangeVector(G4int materialIndex,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IeEnergyLoss::GetConstraints(const G4DynamicParticle* aParticle,
|
||||
G4double G4VIeEnergyLoss::GetConstraints(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial)
|
||||
{
|
||||
// returns the Step limit = range here!
|
||||
@@ -956,7 +956,7 @@ G4double G4IeEnergyLoss::GetConstraints(const G4DynamicParticle* aParticle,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4IeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
G4VParticleChange* G4VIeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
// compute the energy loss after a Step
|
||||
@@ -1039,7 +1039,7 @@ G4VParticleChange* G4IeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IeEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4double G4VIeEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial,
|
||||
G4double MeanLoss)
|
||||
// calculate actual loss from the mean loss
|
||||
+73
-73
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IhEnergyLoss.cc,v 1.7.6.1 1999/12/07 20:50:59 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4VIhEnergyLoss.cc,v 1.1 2000/04/25 14:33:10 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// $Id:
|
||||
// -----------------------------------------------------------
|
||||
@@ -16,7 +16,7 @@
|
||||
// CERN, IT Division, ASD group
|
||||
// History: based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ---------- G4IhEnergyLoss physics process -----------
|
||||
// ---------- G4VIhEnergyLoss physics process -----------
|
||||
// by Laszlo Urban, 30 May 1997
|
||||
//
|
||||
// **************************************************************
|
||||
@@ -28,7 +28,7 @@
|
||||
// 26/10/98 : cleanup + TOF tables, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4IhEnergyLoss.hh"
|
||||
#include "G4VIhEnergyLoss.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4Poisson.hh"
|
||||
|
||||
@@ -40,77 +40,77 @@
|
||||
// NumberOfProcesses should be 2 in this case,
|
||||
// or for debugging purposes.
|
||||
// The NumberOfProcesses data member can be changed using the (public static)
|
||||
// functions Get/Set/Plus/MinusNumberOfProcesses (see G4IhEnergyLoss.hh)
|
||||
// functions Get/Set/Plus/MinusNumberOfProcesses (see G4VIhEnergyLoss.hh)
|
||||
|
||||
G4int G4IhEnergyLoss::NumberOfProcesses = 1 ;
|
||||
G4int G4VIhEnergyLoss::NumberOfProcesses = 1 ;
|
||||
|
||||
G4int G4IhEnergyLoss::CounterOfProcess = 0 ;
|
||||
G4PhysicsTable** G4IhEnergyLoss::RecorderOfProcess =
|
||||
G4int G4VIhEnergyLoss::CounterOfProcess = 0 ;
|
||||
G4PhysicsTable** G4VIhEnergyLoss::RecorderOfProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
|
||||
G4int G4IhEnergyLoss::CounterOfpProcess = 0 ;
|
||||
G4PhysicsTable** G4IhEnergyLoss::RecorderOfpProcess =
|
||||
G4int G4VIhEnergyLoss::CounterOfpProcess = 0 ;
|
||||
G4PhysicsTable** G4VIhEnergyLoss::RecorderOfpProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
|
||||
G4int G4IhEnergyLoss::CounterOfpbarProcess = 0 ;
|
||||
G4PhysicsTable** G4IhEnergyLoss::RecorderOfpbarProcess =
|
||||
G4int G4VIhEnergyLoss::CounterOfpbarProcess = 0 ;
|
||||
G4PhysicsTable** G4VIhEnergyLoss::RecorderOfpbarProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
|
||||
G4PhysicsTable* G4IhEnergyLoss::theDEDXpTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theDEDXpbarTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theRangepTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theInverseRangepTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theInverseRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theLabTimepTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theLabTimepbarTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theProperTimepTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theProperTimepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theDEDXpTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theDEDXpbarTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theRangepTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theInverseRangepTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theInverseRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theLabTimepTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theLabTimepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theProperTimepTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theProperTimepbarTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4IhEnergyLoss::thepRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::thepRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::thepRangeCoeffCTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::thepbarRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::thepbarRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::thepbarRangeCoeffCTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::thepRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::thepRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::thepRangeCoeffCTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::thepbarRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::thepbarRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::thepbarRangeCoeffCTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4IhEnergyLoss::theDEDXTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theRangeTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theInverseRangeTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theLabTimeTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theProperTimeTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theDEDXTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theRangeTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theInverseRangeTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theLabTimeTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theProperTimeTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4IhEnergyLoss::theRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4IhEnergyLoss::theRangeCoeffCTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VIhEnergyLoss::theRangeCoeffCTable = NULL ;
|
||||
|
||||
const G4Proton* G4IhEnergyLoss::theProton =G4Proton::Proton() ;
|
||||
const G4AntiProton* G4IhEnergyLoss::theAntiProton=G4AntiProton::AntiProton() ;
|
||||
const G4Proton* G4VIhEnergyLoss::theProton =G4Proton::Proton() ;
|
||||
const G4AntiProton* G4VIhEnergyLoss::theAntiProton=G4AntiProton::AntiProton() ;
|
||||
|
||||
G4double G4IhEnergyLoss::ParticleMass;
|
||||
G4double G4VIhEnergyLoss::ParticleMass;
|
||||
|
||||
G4double G4IhEnergyLoss::Mass,
|
||||
G4IhEnergyLoss::taulow,
|
||||
G4IhEnergyLoss::tauhigh,
|
||||
G4IhEnergyLoss::ltaulow,
|
||||
G4IhEnergyLoss::ltauhigh;
|
||||
G4double G4VIhEnergyLoss::Mass,
|
||||
G4VIhEnergyLoss::taulow,
|
||||
G4VIhEnergyLoss::tauhigh,
|
||||
G4VIhEnergyLoss::ltaulow,
|
||||
G4VIhEnergyLoss::ltauhigh;
|
||||
|
||||
G4double G4IhEnergyLoss::CutInRange = 0. ;
|
||||
G4double G4VIhEnergyLoss::CutInRange = 0. ;
|
||||
|
||||
G4double G4IhEnergyLoss::dRoverRange = 0.20 ;
|
||||
G4double G4IhEnergyLoss::finalRange = 200.*micrometer ;
|
||||
G4double G4VIhEnergyLoss::dRoverRange = 0.20 ;
|
||||
G4double G4VIhEnergyLoss::finalRange = 200.*micrometer ;
|
||||
|
||||
G4bool G4IhEnergyLoss::rndmStepFlag = false ;
|
||||
G4bool G4IhEnergyLoss::EnlossFlucFlag = true ;
|
||||
G4bool G4VIhEnergyLoss::rndmStepFlag = false ;
|
||||
G4bool G4VIhEnergyLoss::EnlossFlucFlag = true ;
|
||||
|
||||
G4double G4IhEnergyLoss::LowestKineticEnergy;
|
||||
G4double G4IhEnergyLoss::HighestKineticEnergy;
|
||||
G4int G4IhEnergyLoss::TotBin;
|
||||
G4double G4IhEnergyLoss::RTable,G4IhEnergyLoss::LOGRTable;
|
||||
G4double G4VIhEnergyLoss::LowestKineticEnergy;
|
||||
G4double G4VIhEnergyLoss::HighestKineticEnergy;
|
||||
G4int G4VIhEnergyLoss::TotBin;
|
||||
G4double G4VIhEnergyLoss::RTable,G4VIhEnergyLoss::LOGRTable;
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4IhEnergyLoss::G4IhEnergyLoss(const G4String& processName)
|
||||
G4VIhEnergyLoss::G4VIhEnergyLoss(const G4String& processName)
|
||||
: G4IVContinuousDiscreteProcess (processName),
|
||||
theLossTable (NULL),
|
||||
lastMaterial (NULL),
|
||||
@@ -121,7 +121,7 @@ G4IhEnergyLoss::G4IhEnergyLoss(const G4String& processName)
|
||||
nmaxCont2(16)
|
||||
{ }
|
||||
|
||||
G4IhEnergyLoss::~G4IhEnergyLoss()
|
||||
G4VIhEnergyLoss::~G4VIhEnergyLoss()
|
||||
{
|
||||
if(theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
@@ -129,7 +129,7 @@ G4IhEnergyLoss::~G4IhEnergyLoss()
|
||||
}
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildDEDXTable(
|
||||
void G4VIhEnergyLoss::BuildDEDXTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// calculate data members TotBin,LOGRTable,RTable first
|
||||
@@ -276,7 +276,7 @@ void G4IhEnergyLoss::BuildDEDXTable(
|
||||
proton_mass_c2/aParticleType.GetPDGMass(),TotBin);
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildRangeTable(
|
||||
void G4VIhEnergyLoss::BuildRangeTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
// Build range table from the energy loss table
|
||||
{
|
||||
@@ -316,7 +316,7 @@ void G4IhEnergyLoss::BuildRangeTable(
|
||||
}
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildTimeTables(
|
||||
void G4VIhEnergyLoss::BuildTimeTables(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
@@ -372,7 +372,7 @@ void G4IhEnergyLoss::BuildTimeTables(
|
||||
}
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildRangeVector(G4int materialIndex,
|
||||
void G4VIhEnergyLoss::BuildRangeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* rangeVector)
|
||||
// create range vector for a material
|
||||
{
|
||||
@@ -449,7 +449,7 @@ void G4IhEnergyLoss::BuildRangeVector(G4int materialIndex,
|
||||
}
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildLabTimeVector(G4int materialIndex,
|
||||
void G4VIhEnergyLoss::BuildLabTimeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* timeVector)
|
||||
// create lab time vector for a material
|
||||
{
|
||||
@@ -509,7 +509,7 @@ void G4IhEnergyLoss::BuildLabTimeVector(G4int materialIndex,
|
||||
}
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildProperTimeVector(G4int materialIndex,
|
||||
void G4VIhEnergyLoss::BuildProperTimeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* timeVector)
|
||||
// create proper time vector for a material
|
||||
{
|
||||
@@ -568,7 +568,7 @@ void G4IhEnergyLoss::BuildProperTimeVector(G4int materialIndex,
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4IhEnergyLoss::RangeIntLin(G4PhysicsVector* physicsVector,
|
||||
G4double G4VIhEnergyLoss::RangeIntLin(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
// num. integration, linear binning
|
||||
{
|
||||
@@ -598,7 +598,7 @@ G4double G4IhEnergyLoss::RangeIntLin(G4PhysicsVector* physicsVector,
|
||||
}
|
||||
|
||||
|
||||
G4double G4IhEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4double G4VIhEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
// num. integration, logarithmic binning
|
||||
{
|
||||
@@ -629,7 +629,7 @@ G4double G4IhEnergyLoss::RangeIntLog(G4PhysicsVector* physicsVector,
|
||||
return Value;
|
||||
}
|
||||
|
||||
G4double G4IhEnergyLoss::LabTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4double G4VIhEnergyLoss::LabTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
// num. integration, logarithmic binning
|
||||
{
|
||||
@@ -660,7 +660,7 @@ G4double G4IhEnergyLoss::LabTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
return Value;
|
||||
}
|
||||
|
||||
G4double G4IhEnergyLoss::ProperTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4double G4VIhEnergyLoss::ProperTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
G4int nbin)
|
||||
// num. integration, logarithmic binning
|
||||
{
|
||||
@@ -691,7 +691,7 @@ G4double G4IhEnergyLoss::ProperTimeIntLog(G4PhysicsVector* physicsVector,
|
||||
return Value;
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildRangeCoeffATable(
|
||||
void G4VIhEnergyLoss::BuildRangeCoeffATable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "A"
|
||||
@@ -764,7 +764,7 @@ void G4IhEnergyLoss::BuildRangeCoeffATable(
|
||||
}
|
||||
|
||||
|
||||
void G4IhEnergyLoss::BuildRangeCoeffBTable(
|
||||
void G4VIhEnergyLoss::BuildRangeCoeffBTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "B"
|
||||
@@ -835,7 +835,7 @@ void G4IhEnergyLoss::BuildRangeCoeffBTable(
|
||||
}
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildRangeCoeffCTable(
|
||||
void G4VIhEnergyLoss::BuildRangeCoeffCTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "C"
|
||||
@@ -906,7 +906,7 @@ void G4IhEnergyLoss::BuildRangeCoeffCTable(
|
||||
}
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::BuildInverseRangeTable(
|
||||
void G4VIhEnergyLoss::BuildInverseRangeTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
// Build inverse table of the range table
|
||||
{
|
||||
@@ -960,7 +960,7 @@ void G4IhEnergyLoss::BuildInverseRangeTable(
|
||||
}
|
||||
}
|
||||
|
||||
void G4IhEnergyLoss::InvertRangeVector(G4int materialIndex,
|
||||
void G4VIhEnergyLoss::InvertRangeVector(G4int materialIndex,
|
||||
G4PhysicsLogVector* aVector)
|
||||
// invert range vector for a material
|
||||
{
|
||||
@@ -1008,7 +1008,7 @@ void G4IhEnergyLoss::InvertRangeVector(G4int materialIndex,
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4IhEnergyLoss::GetConstraints(const G4DynamicParticle *aParticle,
|
||||
G4double G4VIhEnergyLoss::GetConstraints(const G4DynamicParticle *aParticle,
|
||||
G4Material *aMaterial)
|
||||
{
|
||||
// returns the Step limit = range !
|
||||
@@ -1051,7 +1051,7 @@ G4double G4IhEnergyLoss::GetConstraints(const G4DynamicParticle *aParticle,
|
||||
return StepLimit ;
|
||||
}
|
||||
|
||||
G4VParticleChange* G4IhEnergyLoss::AlongStepDoIt(
|
||||
G4VParticleChange* G4VIhEnergyLoss::AlongStepDoIt(
|
||||
const G4Track& trackData,const G4Step& stepData)
|
||||
// compute the energy loss after a step
|
||||
{
|
||||
@@ -1169,7 +1169,7 @@ G4VParticleChange* G4IhEnergyLoss::AlongStepDoIt(
|
||||
}
|
||||
|
||||
|
||||
G4double G4IhEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4double G4VIhEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial,
|
||||
G4double MeanLoss)
|
||||
// calculate actual loss from the mean loss
|
||||
@@ -0,0 +1,364 @@
|
||||
// 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: G4VPAIenergyLoss.cc,v 1.1 2000/04/25 14:33:10 maire 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
|
||||
// ---------- G4VPAIenergyLoss physics process -----------
|
||||
// by V. Grichine, 30 Nov 1997
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
|
||||
// It calculates the energy loss of charged hadrons.
|
||||
// **************************************************************
|
||||
//
|
||||
// corrected by V. Grichine on 24/11/97
|
||||
// corrected by L. Urban on 27/05/98 ( other corrections come soon!)
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// 02/03/00 initialisation of theDEDXTable
|
||||
//
|
||||
|
||||
|
||||
#include "G4VPAIenergyLoss.hh"
|
||||
#include "G4PAIonisation.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialisation of static members
|
||||
|
||||
G4int G4VPAIenergyLoss::NbOfProcesses = 1 ;
|
||||
G4PhysicsTable** G4VPAIenergyLoss::RecorderOfpProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
G4int G4VPAIenergyLoss::CounterOfpProcess = 0 ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theDEDXpTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theRangepTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theInverseRangepTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theLabTimepTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theProperTimepTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepRangeCoeffCTable = NULL ;
|
||||
|
||||
G4PhysicsTable** G4VPAIenergyLoss::RecorderOfpbarProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
G4int G4VPAIenergyLoss::CounterOfpbarProcess = 0 ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theDEDXpbarTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theInverseRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theLabTimepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theProperTimepbarTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepbarRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepbarRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepbarRangeCoeffCTable = NULL ;
|
||||
|
||||
// G4PhysicsTable* G4VPAIenergyLoss::fPAItransferBank = NULL ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theDEDXTable = NULL ;
|
||||
|
||||
G4double G4VPAIenergyLoss::CutInRange = 0;
|
||||
|
||||
G4double G4VPAIenergyLoss::LowerBoundEloss= 1.00*keV ;
|
||||
G4double G4VPAIenergyLoss::UpperBoundEloss= 100.*TeV ;
|
||||
G4int G4VPAIenergyLoss::NbinEloss =100 ;
|
||||
G4double G4VPAIenergyLoss::RTable,G4VPAIenergyLoss::LOGRTable;
|
||||
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4VPAIenergyLoss::G4VPAIenergyLoss(const G4String& processName)
|
||||
: G4VEnergyLoss (processName),
|
||||
dToverTini(0.20), // max.relative range loss in one Step = 20%
|
||||
theElectron ( G4Electron::Electron() ),
|
||||
theProton ( G4Proton::Proton() ),
|
||||
theAntiProton ( G4AntiProton::AntiProton() )
|
||||
{
|
||||
theLossTable = NULL ;
|
||||
|
||||
// calculate data members LOGRTable,RTable first
|
||||
G4double lrate ;
|
||||
lrate = log(UpperBoundEloss/LowerBoundEloss) ;
|
||||
LOGRTable=lrate/NbinEloss;
|
||||
RTable =exp(LOGRTable);
|
||||
|
||||
}
|
||||
|
||||
G4VPAIenergyLoss::~G4VPAIenergyLoss()
|
||||
{
|
||||
if(theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
void G4VPAIenergyLoss::BuildDEDXTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
|
||||
G4bool MakeTable = false ;
|
||||
|
||||
G4double newCutInRange = aParticleType.GetLengthCuts();
|
||||
|
||||
// Create tables only if there is a new cut value !
|
||||
|
||||
// create/fill proton or antiproton tables depending on the charge of the particle
|
||||
G4double Charge = aParticleType.GetPDGCharge();
|
||||
|
||||
if (Charge>0.)
|
||||
{
|
||||
theDEDXTable= theDEDXpTable;
|
||||
}
|
||||
else
|
||||
{
|
||||
theDEDXTable= theDEDXpbarTable;
|
||||
}
|
||||
|
||||
if ((CutInRange != newCutInRange) || (theDEDXTable==NULL))
|
||||
{
|
||||
MakeTable = true ;
|
||||
CutInRange = newCutInRange ;
|
||||
}
|
||||
|
||||
if( MakeTable )
|
||||
{
|
||||
|
||||
// Build energy loss table as a sum of the energy loss due to the
|
||||
// different processes.
|
||||
//
|
||||
// different processes.
|
||||
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
|
||||
// create table for the total energy loss
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
G4PhysicsTable** RecorderOfProcess;
|
||||
int CounterOfProcess;
|
||||
|
||||
if( Charge >0.)
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpProcess;
|
||||
CounterOfProcess=CounterOfpProcess;
|
||||
|
||||
if(CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
// create tables
|
||||
if(theDEDXpTable)
|
||||
{ theDEDXpTable->clearAndDestroy();
|
||||
delete theDEDXpTable; }
|
||||
theDEDXpTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXTable = theDEDXpTable;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpbarProcess;
|
||||
CounterOfProcess=CounterOfpbarProcess;
|
||||
|
||||
if(CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
// create tables
|
||||
if(theDEDXpbarTable)
|
||||
{ theDEDXpbarTable->clearAndDestroy();
|
||||
delete theDEDXpbarTable; }
|
||||
theDEDXpbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXTable = theDEDXpbarTable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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,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( Charge >0.) CounterOfpProcess=0 ;
|
||||
else CounterOfpbarProcess=0 ;
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
if(Charge > 0.)
|
||||
{
|
||||
// Build range table
|
||||
theRangepTable = BuildRangeTable(theDEDXpTable,
|
||||
theRangepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
// Build lab/proper time tables
|
||||
theLabTimepTable = BuildLabTimeTable(theDEDXpTable,
|
||||
theLabTimepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
theProperTimepTable = BuildProperTimeTable(theDEDXpTable,
|
||||
theProperTimepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// Build coeff tables for the energy loss calculation
|
||||
thepRangeCoeffATable = BuildRangeCoeffATable(theRangepTable,
|
||||
thepRangeCoeffATable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepRangeCoeffBTable = BuildRangeCoeffBTable(theRangepTable,
|
||||
thepRangeCoeffBTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepRangeCoeffCTable = BuildRangeCoeffCTable(theRangepTable,
|
||||
thepRangeCoeffCTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// invert the range table
|
||||
theInverseRangepTable = BuildInverseRangeTable(theRangepTable,
|
||||
thepRangeCoeffATable,
|
||||
thepRangeCoeffBTable,
|
||||
thepRangeCoeffCTable,
|
||||
theInverseRangepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build range table
|
||||
theRangepbarTable = BuildRangeTable(theDEDXpbarTable,
|
||||
theRangepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
// Build lab/proper time tables
|
||||
theLabTimepbarTable = BuildLabTimeTable(theDEDXpbarTable,
|
||||
theLabTimepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
theProperTimepbarTable = BuildProperTimeTable(theDEDXpbarTable,
|
||||
theProperTimepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// Build coeff tables for the energy loss calculation
|
||||
thepbarRangeCoeffATable = BuildRangeCoeffATable(theRangepbarTable,
|
||||
thepbarRangeCoeffATable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepbarRangeCoeffBTable = BuildRangeCoeffBTable(theRangepbarTable,
|
||||
thepbarRangeCoeffBTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepbarRangeCoeffCTable = BuildRangeCoeffCTable(theRangepbarTable,
|
||||
thepbarRangeCoeffCTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// invert the range table
|
||||
theInverseRangepbarTable = BuildInverseRangeTable(theRangepbarTable,
|
||||
thepbarRangeCoeffATable,
|
||||
thepbarRangeCoeffBTable,
|
||||
thepbarRangeCoeffCTable,
|
||||
theInverseRangepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// make the energy loss and the range table available
|
||||
|
||||
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
(Charge>0)?
|
||||
theDEDXpTable: theDEDXpbarTable,
|
||||
(Charge>0)?
|
||||
theRangepTable: theRangepbarTable,
|
||||
(Charge>0)?
|
||||
theInverseRangepTable: theInverseRangepbarTable,
|
||||
(Charge>0)?
|
||||
theLabTimepTable: theLabTimepbarTable,
|
||||
(Charge>0)?
|
||||
theProperTimepTable: theProperTimepbarTable,
|
||||
LowerBoundEloss, UpperBoundEloss,
|
||||
proton_mass_c2/aParticleType.GetPDGMass(),NbinEloss);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,621 @@
|
||||
// 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: G4VeEnergyLoss.cc,v 1.5 2000/06/13 16:49:57 maire 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
|
||||
// ---------- G4VeEnergyLoss 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-.
|
||||
// --------------------------------------------------------------
|
||||
// 18/11/98 , L. Urban
|
||||
// It is a modified version of G4VeEnergyLoss:
|
||||
// continuous energy loss with generation of subcutoff delta rays
|
||||
// 02/02/99 important correction in AlongStepDoIt , L.Urban
|
||||
// 28/04/99 bug fixed (unit independece now),L.Urban
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4VeEnergyLoss.hh"
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// Initialisation of static data members
|
||||
// -------------------------------------
|
||||
|
||||
G4int G4VeEnergyLoss::NbOfProcesses = 2;
|
||||
G4int G4VeEnergyLoss::CounterOfElectronProcess = 0;
|
||||
G4int G4VeEnergyLoss::CounterOfPositronProcess = 0;
|
||||
G4PhysicsTable** G4VeEnergyLoss::RecorderOfElectronProcess =
|
||||
new G4PhysicsTable*[10];
|
||||
G4PhysicsTable** G4VeEnergyLoss::RecorderOfPositronProcess =
|
||||
new G4PhysicsTable*[10];
|
||||
|
||||
G4double G4VeEnergyLoss::MinDeltaCutInRange = 0.100*mm ;
|
||||
G4double* G4VeEnergyLoss::MinDeltaEnergy = NULL ;
|
||||
G4bool G4VeEnergyLoss::setMinDeltaCutInRange = false ;
|
||||
|
||||
G4PhysicsTable* G4VeEnergyLoss::theDEDXElectronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theDEDXPositronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theRangeElectronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theRangePositronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theInverseRangeElectronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theInverseRangePositronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theLabTimeElectronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theLabTimePositronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theProperTimeElectronTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theProperTimePositronTable = NULL;
|
||||
|
||||
G4PhysicsTable* G4VeEnergyLoss::theeRangeCoeffATable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theeRangeCoeffBTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::theeRangeCoeffCTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::thepRangeCoeffATable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::thepRangeCoeffBTable = NULL;
|
||||
G4PhysicsTable* G4VeEnergyLoss::thepRangeCoeffCTable = NULL;
|
||||
|
||||
G4double G4VeEnergyLoss::LowerBoundEloss =0.1*keV ;
|
||||
G4double G4VeEnergyLoss::UpperBoundEloss = 100.*TeV ;
|
||||
G4int G4VeEnergyLoss::NbinEloss = 150 ;
|
||||
G4double G4VeEnergyLoss::RTable,G4VeEnergyLoss::LOGRTable;
|
||||
|
||||
G4EnergyLossMessenger* G4VeEnergyLoss::eLossMessenger = NULL;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4VeEnergyLoss::G4VeEnergyLoss(const G4String& processName)
|
||||
: G4VEnergyLoss (processName),
|
||||
theLossTable(NULL),
|
||||
theDEDXTable(NULL),
|
||||
Charge(-1.),lastCharge(0.),
|
||||
MinKineticEnergy(1.*eV),
|
||||
linLossLimit(0.05),
|
||||
c1N(2.86e-23*MeV*mm*mm),
|
||||
c2N(c1N*MeV/10.),
|
||||
Ndeltamax(100)
|
||||
{
|
||||
//create (only once) EnergyLoss messenger
|
||||
if(!eLossMessenger) eLossMessenger = new G4EnergyLossMessenger();
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VeEnergyLoss::~G4VeEnergyLoss()
|
||||
{
|
||||
if (theLossTable)
|
||||
{
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable; theLossTable = NULL;
|
||||
/// if(MinDeltaEnergy) delete MinDeltaEnergy;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VeEnergyLoss::BuildDEDXTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
ParticleMass = aParticleType.GetPDGMass();
|
||||
|
||||
// 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);
|
||||
|
||||
// create array for the min. delta cuts in kinetic energy
|
||||
G4double absLowerLimit = 1.*keV ;
|
||||
|
||||
// set default MinDeltaCutInRange to rcut/10.
|
||||
if(!setMinDeltaCutInRange )
|
||||
MinDeltaCutInRange = G4Electron::Electron()->GetCuts()/10. ;
|
||||
|
||||
if(&aParticleType==G4Electron::Electron())
|
||||
{
|
||||
G4cout << G4endl;
|
||||
G4cout.precision(5) ;
|
||||
G4cout << " eIoni Minimum Delta cut in range=" << MinDeltaCutInRange/mm
|
||||
<< " mm." << G4endl;
|
||||
G4cout << G4endl;
|
||||
G4cout << " material min.delta energy(keV) " << G4endl;
|
||||
G4cout << G4endl;
|
||||
}
|
||||
|
||||
if(MinDeltaEnergy) delete MinDeltaEnergy ;
|
||||
MinDeltaEnergy = new G4double [numOfMaterials] ;
|
||||
for(G4int mat=0; mat<numOfMaterials; mat++)
|
||||
{
|
||||
MinDeltaEnergy[mat] = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4Electron::Electron(),MinDeltaCutInRange,
|
||||
(*theMaterialTable)(mat)) ;
|
||||
|
||||
if(MinDeltaEnergy[mat]<absLowerLimit)
|
||||
MinDeltaEnergy[mat] = absLowerLimit ;
|
||||
|
||||
if(MinDeltaEnergy[mat]>G4Electron::Electron()->GetCutsInEnergy()[mat])
|
||||
MinDeltaEnergy[mat]=G4Electron::Electron()->GetCutsInEnergy()[mat] ;
|
||||
|
||||
if(&aParticleType==G4Electron::Electron())
|
||||
{
|
||||
G4cout << G4std::setw(20) << (*theMaterialTable)(mat)->GetName()
|
||||
<< G4std::setw(15) << MinDeltaEnergy[mat]/keV << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4VeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
// compute the energy loss after a Step
|
||||
|
||||
static const G4double faclow = 1.5 ;
|
||||
static const G4double Tlow = 1.0*keV;
|
||||
|
||||
// get particle and material pointers from trackData
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
|
||||
G4double E = aParticle->GetKineticEnergy() ;
|
||||
|
||||
G4Material* aMaterial = trackData.GetMaterial();
|
||||
G4int index = aMaterial->GetIndex();
|
||||
G4double Step = stepData.GetStepLength();
|
||||
|
||||
aParticleChange.Initialize(trackData);
|
||||
|
||||
G4double MeanLoss, finalT;
|
||||
|
||||
if (E < MinKineticEnergy) finalT = 0.;
|
||||
|
||||
else if (E<faclow*LowerBoundEloss)
|
||||
{
|
||||
if (Step >= fRangeNow) finalT = 0.;
|
||||
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)||(E < Tlow)) 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 ;
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// start of subcutoff generation
|
||||
|
||||
if(subSecFlag)
|
||||
{
|
||||
G4double MinDeltaEnergyNow = MinDeltaEnergy[index] ;
|
||||
G4double TmintoProduceDelta=0.5*(3.-Charge)*MinDeltaEnergyNow ;
|
||||
if((E > TmintoProduceDelta) && (MeanLoss > MinDeltaEnergyNow)
|
||||
&& (finalT > MinKineticEnergy))
|
||||
{
|
||||
G4double rcut,Tc,T0,presafety,postsafety,safety,
|
||||
delta,fragment ;
|
||||
G4double frperstep,x1,y1,z1,dx,dy,dz,dTime,time0,DeltaTime;
|
||||
G4double epsil= MinKineticEnergy/2. ;
|
||||
|
||||
if(Charge < 0.)
|
||||
{
|
||||
rcut=G4Electron::Electron()->GetCuts();
|
||||
Tc=G4Electron::Electron()->GetCutsInEnergy()[index];
|
||||
// threshold !
|
||||
if(Tc > 0.5*E) Tc=0.5*E ;
|
||||
}
|
||||
else
|
||||
{
|
||||
rcut=G4Positron::Positron()->GetCuts();
|
||||
Tc=G4Positron::Positron()->GetCutsInEnergy()[index];
|
||||
// threshold !
|
||||
if(Tc > E) Tc=E ;
|
||||
}
|
||||
// generate subcutoff delta rays only if Tc>MinDeltaEnergy!
|
||||
if(Tc > MinDeltaEnergyNow)
|
||||
{
|
||||
presafety = stepData.GetPreStepPoint()->GetSafety() ;
|
||||
|
||||
// postsafety = stepData.GetPostStepPoint()->GetSafety() ;
|
||||
|
||||
G4Navigator *navigator=
|
||||
G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
postsafety =
|
||||
navigator->ComputeSafety(stepData.GetPostStepPoint()->GetPosition());
|
||||
|
||||
safety=G4std::min(presafety,postsafety);
|
||||
|
||||
if(safety<rcut)
|
||||
{
|
||||
T0=G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4Electron::Electron(),safety,aMaterial) ;
|
||||
|
||||
// absolute lower limit for T0
|
||||
if(T0<MinDeltaEnergyNow) T0=MinDeltaEnergyNow ;
|
||||
// ..................................................................
|
||||
|
||||
x1=stepData.GetPreStepPoint()->GetPosition().x();
|
||||
y1=stepData.GetPreStepPoint()->GetPosition().y();
|
||||
z1=stepData.GetPreStepPoint()->GetPosition().z();
|
||||
dx=stepData.GetPostStepPoint()->GetPosition().x()-x1 ;
|
||||
dy=stepData.GetPostStepPoint()->GetPosition().y()-y1 ;
|
||||
dz=stepData.GetPostStepPoint()->GetPosition().z()-z1 ;
|
||||
time0=stepData.GetPreStepPoint()->GetGlobalTime();
|
||||
dTime=stepData.GetPostStepPoint()->GetGlobalTime()-time0;
|
||||
|
||||
if((presafety<rcut)&&(postsafety<rcut))
|
||||
{
|
||||
fragment = Step ;
|
||||
frperstep=1. ;
|
||||
}
|
||||
else if(presafety<rcut)
|
||||
{
|
||||
delta=presafety*Step/(postsafety-presafety) ;
|
||||
fragment=rcut*(Step+delta)/postsafety-delta ;
|
||||
frperstep=fragment/Step;
|
||||
}
|
||||
else if(postsafety<rcut)
|
||||
{
|
||||
delta=postsafety*Step/(presafety-postsafety) ;
|
||||
fragment=rcut*(Step+delta)/presafety-delta ;
|
||||
x1 += dx;
|
||||
y1 += dy;
|
||||
z1 += dz;
|
||||
time0 += dTime ;
|
||||
frperstep=-fragment/Step;
|
||||
}
|
||||
|
||||
if(fragment>0.)
|
||||
{
|
||||
// compute nb of delta rays to be generated
|
||||
G4int N=int(fragment*(c1N*(1.-T0/Tc)+c2N/E)*
|
||||
(aMaterial->GetTotNbOfElectPerVolume())/T0+0.5) ;
|
||||
if(N > Ndeltamax)
|
||||
N = Ndeltamax ;
|
||||
G4double Px,Py,Pz ;
|
||||
G4ThreeVector ParticleDirection ;
|
||||
ParticleDirection=stepData.GetPostStepPoint()->
|
||||
GetMomentumDirection() ;
|
||||
Px =ParticleDirection.x() ;
|
||||
Py =ParticleDirection.y() ;
|
||||
Pz =ParticleDirection.z() ;
|
||||
|
||||
G4int subdelta = 0;
|
||||
|
||||
if(N > 0)
|
||||
{
|
||||
G4double Tkin,Etot,P,T,p,costheta,sintheta,phi,dirx,diry,dirz,
|
||||
Pnew,delToverTc,
|
||||
sumT,delTkin,delLoss,rate,
|
||||
urandom ;
|
||||
G4StepPoint *point ;
|
||||
|
||||
sumT=0.;
|
||||
|
||||
Tkin = E ;
|
||||
Etot = Tkin+electron_mass_c2 ;
|
||||
P = sqrt(Tkin*(Etot+electron_mass_c2)) ;
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(N);
|
||||
do {
|
||||
subdelta += 1 ;
|
||||
|
||||
if((Charge<0.)&&(Tc>0.5*Tkin)) Tc=0.5*Tkin ;
|
||||
if((Charge>0.)&&(Tc> Tkin)) Tc= Tkin ;
|
||||
|
||||
//check if there is enough energy ....
|
||||
if((Tkin>TmintoProduceDelta)&&(Tc > T0)&&(MeanLoss>0.))
|
||||
{
|
||||
delToverTc=1.-T0/Tc ;
|
||||
T=T0/(1.-delToverTc*G4UniformRand()) ;
|
||||
if(T > MeanLoss) T=MeanLoss ;
|
||||
MeanLoss -= T ;
|
||||
p=sqrt(T*(T+2.*electron_mass_c2)) ;
|
||||
|
||||
costheta = T*(Etot+electron_mass_c2)/(P*p) ;
|
||||
if(costheta<-1.) costheta=-1.;
|
||||
if(costheta> 1.) costheta= 1.;
|
||||
|
||||
phi=twopi*G4UniformRand() ;
|
||||
sintheta=sqrt(1.-costheta*costheta);
|
||||
dirx=sintheta*cos(phi);
|
||||
diry=sintheta*sin(phi);
|
||||
dirz=costheta;
|
||||
|
||||
sumT += T ;
|
||||
|
||||
urandom = G4UniformRand() ;
|
||||
// distribute x,y,z along Pre-Post !
|
||||
G4double xd,yd,zd ;
|
||||
xd=x1+frperstep*dx*urandom ;
|
||||
yd=y1+frperstep*dy*urandom ;
|
||||
zd=z1+frperstep*dz*urandom ;
|
||||
G4ThreeVector DeltaPosition(xd,yd,zd) ;
|
||||
DeltaTime=time0+frperstep*dTime*urandom ;
|
||||
ParticleDirection=stepData.GetPostStepPoint()->
|
||||
GetMomentumDirection() ;
|
||||
|
||||
G4ThreeVector DeltaDirection(dirx,diry,dirz) ;
|
||||
DeltaDirection.rotateUz(ParticleDirection);
|
||||
|
||||
G4DynamicParticle* theDelta = new G4DynamicParticle ;
|
||||
theDelta->SetDefinition(G4Electron::Electron());
|
||||
theDelta->SetKineticEnergy(T);
|
||||
|
||||
theDelta->SetMomentumDirection(DeltaDirection.x(),
|
||||
DeltaDirection.y(),DeltaDirection.z());
|
||||
|
||||
// update initial particle,fill ParticleChange
|
||||
Tkin -= T ;
|
||||
Px =(P*ParticleDirection.x()-p*DeltaDirection.x()) ;
|
||||
Py =(P*ParticleDirection.y()-p*DeltaDirection.y()) ;
|
||||
Pz =(P*ParticleDirection.z()-p*DeltaDirection.z()) ;
|
||||
Pnew = sqrt(Px*Px+Py*Py+Pz*Pz) ;
|
||||
Px /= Pnew ;
|
||||
Py /= Pnew ;
|
||||
Pz /= Pnew ;
|
||||
P = Pnew ;
|
||||
G4ThreeVector ParticleDirectionnew(Px,Py,Pz) ;
|
||||
ParticleDirection = ParticleDirectionnew;
|
||||
|
||||
G4Track* deltaTrack =
|
||||
new G4Track(theDelta,DeltaTime,DeltaPosition);
|
||||
deltaTrack->
|
||||
SetTouchable(stepData.GetPostStepPoint()->GetTouchable()) ;
|
||||
deltaTrack->SetParentID(trackData.GetTrackID()) ;
|
||||
|
||||
aParticleChange.AddSecondary(deltaTrack) ;
|
||||
|
||||
}
|
||||
|
||||
} while (subdelta<N) ;
|
||||
|
||||
// update the particle direction and kinetic energy
|
||||
if(subdelta > 0)
|
||||
aParticleChange.SetMomentumChange(Px,Py,Pz) ;
|
||||
E = Tkin ;
|
||||
|
||||
}
|
||||
}
|
||||
// ................................................................
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// end of subcutoff generation
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
finalT = E - MeanLoss ;
|
||||
if(finalT < MinKineticEnergy) finalT = 0. ;
|
||||
|
||||
//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.) aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange(finalT);
|
||||
aParticleChange.SetLocalEnergyDeposit(E-finalT);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,702 @@
|
||||
// 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: G4VhEnergyLoss.cc,v 1.5 2000/06/13 16:49:58 maire 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
|
||||
// ---------- G4VhEnergyLoss physics process -----------
|
||||
// by Laszlo Urban, 30 May 1997
|
||||
//
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
|
||||
// It calculates the energy loss of charged hadrons.
|
||||
// **************************************************************
|
||||
//
|
||||
// 7/10/98: bug fixes + some cleanup , L.Urban
|
||||
// 22/10/98 : cleanup , L.Urban
|
||||
// 07/12/98 : works for ions as well+ bug corrected, L.Urban
|
||||
// 02/02/99 : several bugs fixed, L.Urban
|
||||
// 01/03/99 : creation of sub-cutoff delta rays, L.Urban
|
||||
// 28/04/99 : bug fixed in DoIt , L.Urban
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4VhEnergyLoss.hh"
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
// Initialisation of static members ******************************************
|
||||
G4int G4VhEnergyLoss::NbOfProcesses = 1 ;
|
||||
|
||||
G4int G4VhEnergyLoss::CounterOfProcess = 0 ;
|
||||
G4PhysicsTable** G4VhEnergyLoss::RecorderOfProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
|
||||
G4int G4VhEnergyLoss::CounterOfpProcess = 0 ;
|
||||
G4PhysicsTable** G4VhEnergyLoss::RecorderOfpProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
|
||||
G4int G4VhEnergyLoss::CounterOfpbarProcess = 0 ;
|
||||
G4PhysicsTable** G4VhEnergyLoss::RecorderOfpbarProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
|
||||
G4PhysicsTable* G4VhEnergyLoss::theDEDXpTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theDEDXpbarTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theRangepTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theInverseRangepTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theInverseRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theLabTimepTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theLabTimepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theProperTimepTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::theProperTimepbarTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4VhEnergyLoss::thepRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::thepRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::thepRangeCoeffCTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::thepbarRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::thepbarRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VhEnergyLoss::thepbarRangeCoeffCTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4VhEnergyLoss::theDEDXTable = NULL ;
|
||||
|
||||
const G4Proton* G4VhEnergyLoss::theProton=G4Proton::Proton() ;
|
||||
const G4AntiProton* G4VhEnergyLoss::theAntiProton=G4AntiProton::AntiProton() ;
|
||||
|
||||
G4double G4VhEnergyLoss::ptableElectronCutInRange = 0.0*mm ;
|
||||
G4double G4VhEnergyLoss::pbartableElectronCutInRange = 0.0*mm ;
|
||||
|
||||
G4double G4VhEnergyLoss::MinDeltaCutInRange = 0.1*mm ;
|
||||
G4double* G4VhEnergyLoss::MinDeltaEnergy = NULL ;
|
||||
G4bool G4VhEnergyLoss::setMinDeltaCutInRange = false ;
|
||||
|
||||
G4double G4VhEnergyLoss::Charge ;
|
||||
|
||||
G4double G4VhEnergyLoss::LowerBoundEloss = 1.*keV ;
|
||||
G4double G4VhEnergyLoss::UpperBoundEloss = 100.*TeV;
|
||||
G4int G4VhEnergyLoss::NbinEloss = 100 ;
|
||||
G4double G4VhEnergyLoss::RTable,G4VhEnergyLoss::LOGRTable;
|
||||
|
||||
G4double G4VhEnergyLoss::c0N = 9.0e-21*MeV*MeV*mm*mm ;
|
||||
G4double G4VhEnergyLoss::c1N = 25.0e-21*keV*mm*mm ;
|
||||
G4double G4VhEnergyLoss::c2N = 13.25e-21*keV*mm*mm ;
|
||||
G4double G4VhEnergyLoss::c3N = 0.500e-21*mm*mm ;
|
||||
G4int G4VhEnergyLoss::Ndeltamax = 100 ;
|
||||
|
||||
G4EnergyLossMessenger* G4VhEnergyLoss::hLossMessenger = NULL;
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4VhEnergyLoss::G4VhEnergyLoss(const G4String& processName)
|
||||
: G4VEnergyLoss (processName),
|
||||
theLossTable (NULL),
|
||||
MinKineticEnergy(1.*eV),
|
||||
linLossLimit(0.05)
|
||||
{
|
||||
//create (only once) EnergyLoss messenger
|
||||
if(!hLossMessenger) hLossMessenger = new G4EnergyLossMessenger();
|
||||
|
||||
}
|
||||
G4VhEnergyLoss::~G4VhEnergyLoss()
|
||||
{
|
||||
if(theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable; theLossTable = NULL;
|
||||
}
|
||||
/// if(MinDeltaEnergy) delete MinDeltaEnergy;
|
||||
}
|
||||
|
||||
void G4VhEnergyLoss::BuildDEDXTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// calculate data members LOGRTable,RTable first
|
||||
G4double lrate = log(UpperBoundEloss/LowerBoundEloss);
|
||||
LOGRTable=lrate/NbinEloss;
|
||||
RTable =exp(LOGRTable);
|
||||
|
||||
// create table if there is no table or there is a new cut value
|
||||
G4bool MakeTable = false ;
|
||||
|
||||
G4double ElectronCutInRange = G4Electron::Electron()->GetCuts();
|
||||
|
||||
// create/fill proton or antiproton tables depending on the charge
|
||||
Charge = aParticleType.GetPDGCharge()/eplus;
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
if (Charge>0.) {theDEDXTable= theDEDXpTable;}
|
||||
else {theDEDXTable= theDEDXpbarTable;}
|
||||
|
||||
if(
|
||||
((Charge>0.) && ((theDEDXTable==NULL) ||
|
||||
(ElectronCutInRange != ptableElectronCutInRange)))
|
||||
||
|
||||
((Charge<0.) && ((theDEDXTable==NULL) ||
|
||||
(ElectronCutInRange != pbartableElectronCutInRange)))
|
||||
)
|
||||
MakeTable = true ;
|
||||
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if( MakeTable )
|
||||
{
|
||||
|
||||
// Build energy loss table as a sum of the energy loss due to the
|
||||
// different processes.
|
||||
if( Charge >0.)
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpProcess;
|
||||
CounterOfProcess=CounterOfpProcess;
|
||||
|
||||
if(CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
if(theDEDXpTable)
|
||||
{ theDEDXpTable->clearAndDestroy();
|
||||
delete theDEDXpTable; }
|
||||
theDEDXpTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXTable = theDEDXpTable;
|
||||
ptableElectronCutInRange = ElectronCutInRange ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpbarProcess;
|
||||
CounterOfProcess=CounterOfpbarProcess;
|
||||
|
||||
if(CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
if(theDEDXpbarTable)
|
||||
{ theDEDXpbarTable->clearAndDestroy();
|
||||
delete theDEDXpbarTable; }
|
||||
theDEDXpbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXTable = theDEDXpbarTable;
|
||||
pbartableElectronCutInRange = ElectronCutInRange ;
|
||||
}
|
||||
}
|
||||
|
||||
if(CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
// 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) ;
|
||||
Value = 0. ;
|
||||
|
||||
// loop for the contributing processes
|
||||
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( Charge >0.)
|
||||
CounterOfpProcess=0 ;
|
||||
else
|
||||
CounterOfpbarProcess=0 ;
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
if(Charge > 0.)
|
||||
{
|
||||
// Build range table
|
||||
theRangepTable = BuildRangeTable(theDEDXpTable,
|
||||
theRangepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
// Build lab/proper time tables
|
||||
theLabTimepTable = BuildLabTimeTable(theDEDXpTable,
|
||||
theLabTimepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
theProperTimepTable = BuildProperTimeTable(theDEDXpTable,
|
||||
theProperTimepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// Build coeff tables for the energy loss calculation
|
||||
thepRangeCoeffATable = BuildRangeCoeffATable(theRangepTable,
|
||||
thepRangeCoeffATable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepRangeCoeffBTable = BuildRangeCoeffBTable(theRangepTable,
|
||||
thepRangeCoeffBTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepRangeCoeffCTable = BuildRangeCoeffCTable(theRangepTable,
|
||||
thepRangeCoeffCTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// invert the range table
|
||||
theInverseRangepTable = BuildInverseRangeTable(theRangepTable,
|
||||
thepRangeCoeffATable,
|
||||
thepRangeCoeffBTable,
|
||||
thepRangeCoeffCTable,
|
||||
theInverseRangepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build range table
|
||||
theRangepbarTable = BuildRangeTable(theDEDXpbarTable,
|
||||
theRangepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
// Build lab/proper time tables
|
||||
theLabTimepbarTable = BuildLabTimeTable(theDEDXpbarTable,
|
||||
theLabTimepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
theProperTimepbarTable = BuildProperTimeTable(theDEDXpbarTable,
|
||||
theProperTimepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// Build coeff tables for the energy loss calculation
|
||||
thepbarRangeCoeffATable = BuildRangeCoeffATable(theRangepbarTable,
|
||||
thepbarRangeCoeffATable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepbarRangeCoeffBTable = BuildRangeCoeffBTable(theRangepbarTable,
|
||||
thepbarRangeCoeffBTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepbarRangeCoeffCTable = BuildRangeCoeffCTable(theRangepbarTable,
|
||||
thepbarRangeCoeffCTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// invert the range table
|
||||
theInverseRangepbarTable = BuildInverseRangeTable(theRangepbarTable,
|
||||
thepbarRangeCoeffATable,
|
||||
thepbarRangeCoeffBTable,
|
||||
thepbarRangeCoeffCTable,
|
||||
theInverseRangepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// make the energy loss and the range table available
|
||||
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
(Charge>0)?
|
||||
theDEDXpTable: theDEDXpbarTable,
|
||||
(Charge>0)?
|
||||
theRangepTable: theRangepbarTable,
|
||||
(Charge>0)?
|
||||
theInverseRangepTable: theInverseRangepbarTable,
|
||||
(Charge>0)?
|
||||
theLabTimepTable: theLabTimepbarTable,
|
||||
(Charge>0)?
|
||||
theProperTimepTable: theProperTimepbarTable,
|
||||
LowerBoundEloss, UpperBoundEloss,
|
||||
proton_mass_c2/aParticleType.GetPDGMass(),NbinEloss);
|
||||
|
||||
// create array for the min. delta cuts in kinetic energy
|
||||
if(!setMinDeltaCutInRange)
|
||||
MinDeltaCutInRange = G4Electron::Electron()->GetCuts()/10.;
|
||||
|
||||
if(aParticleType.GetParticleName()=="proton")
|
||||
{
|
||||
G4cout << G4endl;
|
||||
G4cout.precision(5) ;
|
||||
G4cout << " hIoni Minimum Delta cut in range=" << MinDeltaCutInRange/mm
|
||||
<< " mm." << G4endl;
|
||||
G4cout << G4endl;
|
||||
G4cout << " material min.delta energy(keV) " << G4endl;
|
||||
G4cout << G4endl;
|
||||
}
|
||||
|
||||
if(MinDeltaEnergy) delete MinDeltaEnergy ;
|
||||
MinDeltaEnergy = new G4double [numOfMaterials] ;
|
||||
G4double Tlowerlimit = 1.*keV ;
|
||||
for(G4int mat=0; mat<numOfMaterials; mat++)
|
||||
{
|
||||
MinDeltaEnergy[mat] = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4Electron::Electron(),MinDeltaCutInRange,
|
||||
(*theMaterialTable)(mat)) ;
|
||||
if(MinDeltaEnergy[mat]<Tlowerlimit) MinDeltaEnergy[mat]=Tlowerlimit ;
|
||||
|
||||
if(MinDeltaEnergy[mat]>G4Electron::Electron()->GetCutsInEnergy()[mat])
|
||||
MinDeltaEnergy[mat]=G4Electron::Electron()->GetCutsInEnergy()[mat] ;
|
||||
|
||||
if(aParticleType.GetParticleName()=="proton")
|
||||
G4cout << G4std::setw(20) << (*theMaterialTable)(mat)->GetName()
|
||||
<< G4std::setw(15) << MinDeltaEnergy[mat]/keV << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4double G4VhEnergyLoss::GetConstraints(const G4DynamicParticle *aParticle,
|
||||
G4Material *aMaterial)
|
||||
{
|
||||
// returns the Step limit
|
||||
// dRoverRange is the max. allowed relative range loss in one step
|
||||
// it calculates dEdx and the range as well....
|
||||
|
||||
G4double KineticEnergy,StepLimit;
|
||||
G4bool isOut ;
|
||||
|
||||
Charge = aParticle->GetDefinition()->GetPDGCharge()/eplus ;
|
||||
|
||||
KineticEnergy = aParticle->GetKineticEnergy();
|
||||
|
||||
G4double massratio=proton_mass_c2/
|
||||
aParticle->GetDefinition()->GetPDGMass() ;
|
||||
|
||||
G4double Tscaled= KineticEnergy*massratio ;
|
||||
G4double ChargeSquare = Charge*Charge ;
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
fRangeNow = G4EnergyLossTables::GetRange( theProton,
|
||||
Tscaled,aMaterial) ;
|
||||
fdEdx = G4EnergyLossTables::GetDEDX( theProton,
|
||||
Tscaled,aMaterial) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fRangeNow = G4EnergyLossTables::GetRange( theAntiProton,
|
||||
Tscaled,aMaterial) ;
|
||||
fdEdx = G4EnergyLossTables::GetDEDX( theAntiProton,
|
||||
Tscaled,aMaterial) ;
|
||||
}
|
||||
fdEdx *= ChargeSquare ;
|
||||
fRangeNow /= (ChargeSquare*massratio) ;
|
||||
|
||||
// compute the (random) Step limit ..............
|
||||
if(fRangeNow > finalRange)
|
||||
{
|
||||
StepLimit = (c1lim*fRangeNow+c2lim+c3lim/fRangeNow) ;
|
||||
|
||||
// randomise this value
|
||||
if(rndmStepFlag) StepLimit =
|
||||
finalRange+(StepLimit-finalRange)*G4UniformRand() ;
|
||||
if(StepLimit > fRangeNow) StepLimit = fRangeNow ;
|
||||
}
|
||||
else StepLimit = fRangeNow ;
|
||||
|
||||
return StepLimit ;
|
||||
}
|
||||
|
||||
G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
const G4Track& trackData,const G4Step& stepData)
|
||||
// compute the energy loss after a step
|
||||
{
|
||||
const G4DynamicParticle* aParticle;
|
||||
G4Material* aMaterial;
|
||||
G4double E,finalT,Step,ChargeSquare,MeanLoss ;
|
||||
|
||||
aParticleChange.Initialize(trackData) ;
|
||||
aMaterial = trackData.GetMaterial() ;
|
||||
|
||||
// get the actual (true) Step length from stepData
|
||||
Step = stepData.GetStepLength() ;
|
||||
|
||||
aParticle = trackData.GetDynamicParticle() ;
|
||||
ChargeSquare = Charge*Charge ;
|
||||
|
||||
G4int index = aMaterial->GetIndex() ;
|
||||
E = aParticle->GetKineticEnergy() ;
|
||||
|
||||
if(E < MinKineticEnergy) MeanLoss = E ;
|
||||
else
|
||||
{
|
||||
if(Step >= fRangeNow ) MeanLoss = E ;
|
||||
|
||||
else if(( E > UpperBoundEloss)||( E <= LowerBoundEloss))
|
||||
MeanLoss = Step*fdEdx ;
|
||||
|
||||
else
|
||||
{
|
||||
if(Step>linLossLimit*fRangeNow)
|
||||
{
|
||||
G4double massratio=proton_mass_c2/
|
||||
aParticle->GetDefinition()->GetPDGMass() ;
|
||||
|
||||
G4double rscaled= fRangeNow*massratio*ChargeSquare ;
|
||||
G4double sscaled= Step *massratio*ChargeSquare ;
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
MeanLoss = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
theProton,
|
||||
rscaled ,aMaterial) -
|
||||
G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
theProton,
|
||||
rscaled-sscaled,aMaterial) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
MeanLoss = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
theAntiProton,
|
||||
rscaled ,aMaterial) -
|
||||
G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
theAntiProton,
|
||||
rscaled-sscaled,aMaterial) ;
|
||||
}
|
||||
MeanLoss /= (massratio*ChargeSquare) ;
|
||||
}
|
||||
else MeanLoss = Step*fdEdx ;
|
||||
}
|
||||
}
|
||||
finalT = E - MeanLoss ;
|
||||
|
||||
// subcutoff delta ray production start
|
||||
if(subSecFlag)
|
||||
{
|
||||
G4double MinDeltaEnergyNow,Tc,TmintoProduceDelta,w,ww ;
|
||||
G4double rcut,T0,presafety,postsafety,safety,
|
||||
delta,fragment,Tmax,mass ;
|
||||
G4double frperstep,x1,y1,z1,dx,dy,dz,dTime,time0,DeltaTime;
|
||||
G4double epsil = MinKineticEnergy/2. ;
|
||||
|
||||
MinDeltaEnergyNow = MinDeltaEnergy[index] ;
|
||||
Tc=G4Electron::Electron()->GetCutsInEnergy()[index];
|
||||
const G4ParticleDefinition* aParticleType=aParticle->GetDefinition() ;
|
||||
mass=aParticleType->GetPDGMass() ;
|
||||
w=mass+electron_mass_c2 ;
|
||||
ww=2.*mass-MinDeltaEnergyNow ;
|
||||
TmintoProduceDelta=0.5*(sqrt(ww*ww+2.*w*w*MinDeltaEnergyNow/
|
||||
electron_mass_c2)-ww) ;
|
||||
|
||||
if((E > TmintoProduceDelta) && (MeanLoss > MinDeltaEnergyNow)
|
||||
&& (finalT > MinKineticEnergy))
|
||||
{
|
||||
// max. possible delta energy
|
||||
Tmax = 2.*electron_mass_c2*E*(E+2.*mass)/
|
||||
(mass*mass+2.*electron_mass_c2*(E+mass)+
|
||||
electron_mass_c2*electron_mass_c2) ;
|
||||
|
||||
rcut=G4Electron::Electron()->GetCuts();
|
||||
|
||||
if(Tc > Tmax) Tc=Tmax ;
|
||||
// generate subcutoff delta rays only if Tc>MinDeltaEnergyNow!
|
||||
if((Tc > MinDeltaEnergyNow) && (Tmax > MinDeltaEnergyNow))
|
||||
{
|
||||
presafety = stepData.GetPreStepPoint()->GetSafety() ;
|
||||
// postsafety = stepData.GetPostStepPoint()->GetSafety() ;
|
||||
|
||||
G4Navigator *navigator=
|
||||
G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
postsafety =
|
||||
navigator->ComputeSafety(stepData.GetPostStepPoint()->GetPosition());
|
||||
|
||||
safety = G4std::min(presafety,postsafety) ;
|
||||
|
||||
if(safety < rcut)
|
||||
{
|
||||
|
||||
x1=stepData.GetPreStepPoint()->GetPosition().x();
|
||||
y1=stepData.GetPreStepPoint()->GetPosition().y();
|
||||
z1=stepData.GetPreStepPoint()->GetPosition().z();
|
||||
dx=stepData.GetPostStepPoint()->GetPosition().x()-x1 ;
|
||||
dy=stepData.GetPostStepPoint()->GetPosition().y()-y1 ;
|
||||
dz=stepData.GetPostStepPoint()->GetPosition().z()-z1 ;
|
||||
time0=stepData.GetPreStepPoint()->GetGlobalTime();
|
||||
dTime=stepData.GetPostStepPoint()->GetGlobalTime()-time0;
|
||||
|
||||
if((presafety<rcut)&&(postsafety<rcut))
|
||||
{
|
||||
fragment = Step ;
|
||||
frperstep=1. ;
|
||||
}
|
||||
else if(presafety<rcut)
|
||||
{
|
||||
delta=presafety*Step/(postsafety-presafety) ;
|
||||
fragment=rcut*(Step+delta)/postsafety-delta ;
|
||||
frperstep=fragment/Step;
|
||||
}
|
||||
else if(postsafety<rcut)
|
||||
{
|
||||
delta=postsafety*Step/(presafety-postsafety) ;
|
||||
fragment=rcut*(Step+delta)/presafety-delta ;
|
||||
x1 += dx;
|
||||
y1 += dy;
|
||||
z1 += dz;
|
||||
time0 += dTime ;
|
||||
|
||||
frperstep=-fragment/Step;
|
||||
}
|
||||
|
||||
if(fragment>0.)
|
||||
{
|
||||
T0=G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4Electron::Electron(),
|
||||
G4std::min(presafety,postsafety),
|
||||
aMaterial) ;
|
||||
|
||||
// absolute lower limit for T0
|
||||
if(T0<MinDeltaEnergyNow) T0=MinDeltaEnergyNow ;
|
||||
|
||||
// compute nb of delta rays to be generated
|
||||
G4int N=int(fragment*(c0N/(E*T0)+c1N/T0-(c2N+c3N*T0)/Tc)*
|
||||
(aMaterial->GetTotNbOfElectPerVolume())+0.5) ;
|
||||
|
||||
G4double Px,Py,Pz ;
|
||||
G4ThreeVector ParticleDirection ;
|
||||
ParticleDirection=stepData.GetPostStepPoint()->
|
||||
GetMomentumDirection() ;
|
||||
Px =ParticleDirection.x() ;
|
||||
Py =ParticleDirection.y() ;
|
||||
Pz =ParticleDirection.z() ;
|
||||
|
||||
G4int subdelta = 0;
|
||||
|
||||
if(N > 0)
|
||||
{
|
||||
G4double Tkin,Etot,P,T,p,costheta,sintheta,phi,dirx,diry,dirz,
|
||||
Pnew,delToverTc,
|
||||
delTkin,delLoss,rate,
|
||||
urandom ;
|
||||
G4StepPoint *point ;
|
||||
|
||||
Tkin = E ;
|
||||
Etot = Tkin+mass ;
|
||||
P = sqrt(Tkin*(Etot+mass)) ;
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(N);
|
||||
do {
|
||||
subdelta += 1 ;
|
||||
|
||||
Tmax = 2.*electron_mass_c2*Tkin*(Tkin+2.*mass)/
|
||||
(mass*mass+2.*electron_mass_c2*(Tkin+mass)+
|
||||
electron_mass_c2*electron_mass_c2) ;
|
||||
|
||||
if(Tc>Tmax) Tc = Tmax ;
|
||||
|
||||
//check if there is enough energy ....
|
||||
if((Tkin>TmintoProduceDelta)&&(Tc > T0)&&(MeanLoss>0.))
|
||||
{
|
||||
delToverTc=1.-T0/Tc ;
|
||||
T=T0/(1.-delToverTc*G4UniformRand()) ;
|
||||
if(T > MeanLoss) T=MeanLoss ;
|
||||
MeanLoss -= T ;
|
||||
p=sqrt(T*(T+2.*electron_mass_c2)) ;
|
||||
|
||||
costheta = T*(Etot+electron_mass_c2)/(P*p) ;
|
||||
if(costheta<-1.) costheta=-1.;
|
||||
if(costheta> 1.) costheta= 1.;
|
||||
|
||||
phi=twopi*G4UniformRand() ;
|
||||
sintheta=sqrt(1.-costheta*costheta);
|
||||
dirx=sintheta*cos(phi);
|
||||
diry=sintheta*sin(phi);
|
||||
dirz=costheta;
|
||||
|
||||
urandom = G4UniformRand() ;
|
||||
// distribute x,y,z along Pre-Post !
|
||||
G4double xd,yd,zd ;
|
||||
xd=x1+frperstep*dx*urandom ;
|
||||
yd=y1+frperstep*dy*urandom ;
|
||||
zd=z1+frperstep*dz*urandom ;
|
||||
G4ThreeVector DeltaPosition(xd,yd,zd) ;
|
||||
DeltaTime=time0+frperstep*dTime*urandom ;
|
||||
|
||||
G4ThreeVector DeltaDirection(dirx,diry,dirz) ;
|
||||
DeltaDirection.rotateUz(ParticleDirection);
|
||||
|
||||
G4DynamicParticle* theDelta = new G4DynamicParticle ;
|
||||
theDelta->SetDefinition(G4Electron::Electron());
|
||||
theDelta->SetKineticEnergy(T);
|
||||
|
||||
theDelta->SetMomentumDirection(DeltaDirection.x(),
|
||||
DeltaDirection.y(),DeltaDirection.z());
|
||||
|
||||
// update initial particle,fill ParticleChange
|
||||
Tkin -= T ;
|
||||
Px =(P*ParticleDirection.x()-p*DeltaDirection.x()) ;
|
||||
Py =(P*ParticleDirection.y()-p*DeltaDirection.y()) ;
|
||||
Pz =(P*ParticleDirection.z()-p*DeltaDirection.z()) ;
|
||||
Pnew = sqrt(Px*Px+Py*Py+Pz*Pz) ;
|
||||
Px /= Pnew ;
|
||||
Py /= Pnew ;
|
||||
Pz /= Pnew ;
|
||||
P = Pnew ;
|
||||
G4ThreeVector ParticleDirectionnew(Px,Py,Pz) ;
|
||||
ParticleDirection = ParticleDirectionnew;
|
||||
|
||||
G4Track* deltaTrack =
|
||||
new G4Track(theDelta,DeltaTime,DeltaPosition);
|
||||
deltaTrack->
|
||||
SetTouchable(stepData.GetPostStepPoint()->GetTouchable()) ;
|
||||
|
||||
deltaTrack->SetParentID(trackData.GetTrackID()) ;
|
||||
|
||||
aParticleChange.AddSecondary(deltaTrack) ;
|
||||
|
||||
}
|
||||
|
||||
} while (subdelta<N) ;
|
||||
|
||||
// update the particle direction and kinetic energy
|
||||
if(subdelta > 0)
|
||||
aParticleChange.SetMomentumChange(Px,Py,Pz) ;
|
||||
E = Tkin ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// end of subcutoff business
|
||||
|
||||
finalT = E - MeanLoss ;
|
||||
if(finalT < MinKineticEnergy) finalT = 0. ;
|
||||
|
||||
// now the loss with fluctuation
|
||||
if((EnlossFlucFlag) && (finalT > 0.) && (finalT < E)&&(E > LowerBoundEloss))
|
||||
{
|
||||
MeanLoss /= ChargeSquare ;
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,MeanLoss)*ChargeSquare ;
|
||||
if (finalT < 0.) finalT = 0. ;
|
||||
}
|
||||
|
||||
// kill the particle if the kinetic energy <= 0
|
||||
if (finalT <= 0. )
|
||||
{
|
||||
finalT = 0.;
|
||||
if(aParticle->GetDefinition()->GetParticleName() == "proton")
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else
|
||||
aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
// aParticleChange.SetNumberOfSecondaries(0);
|
||||
aParticleChange.SetEnergyChange( finalT ) ;
|
||||
aParticleChange.SetLocalEnergyDeposit(E-finalT) ;
|
||||
|
||||
return &aParticleChange ;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4eBremsstrahlung.cc,v 1.6.8.1.2.2 1999/12/10 15:41:59 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4eBremsstrahlung.cc,v 1.11 2000/05/23 15:44:29 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -29,6 +29,7 @@
|
||||
// 07-04-98 : remove 'tracking cut' of the diffracted particle, MMa
|
||||
// 13-08-98 : new methods SetBining() PrintInfo()
|
||||
// 03-03-99 : Bug fixed in LPM effect, L.Urban
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4eBremsstrahlung.hh"
|
||||
@@ -36,17 +37,19 @@
|
||||
#include "G4ios.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
G4double G4eBremsstrahlung::LowerBoundLambda = 1.*keV ;
|
||||
G4double G4eBremsstrahlung::UpperBoundLambda = 100.*TeV ;
|
||||
G4int G4eBremsstrahlung::NbinLambda = 100 ;
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// constructor
|
||||
|
||||
G4eBremsstrahlung::G4eBremsstrahlung(const G4String& processName)
|
||||
: G4eEnergyLoss(processName), // initialization
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestKineticEnergy (1.*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
TotBin(100)
|
||||
{ }
|
||||
: G4VeEnergyLoss(processName), // initialization
|
||||
theMeanFreePathTable(NULL)
|
||||
{MinThreshold = 10*keV; }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -66,16 +69,13 @@ G4eBremsstrahlung::~G4eBremsstrahlung()
|
||||
|
||||
//....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
|
||||
{
|
||||
// get bining from EnergyLoss
|
||||
LowestKineticEnergy = GetLowerBoundEloss() ;
|
||||
HighestKineticEnergy = GetUpperBoundEloss() ;
|
||||
TotBin = GetNbinEloss() ;
|
||||
|
||||
BuildLossTable(aParticleType) ;
|
||||
|
||||
@@ -108,7 +108,6 @@ void G4eBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType
|
||||
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);
|
||||
@@ -151,15 +150,13 @@ void G4eBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType
|
||||
TotalEnergy = KineticEnergy+ParticleMass ;
|
||||
|
||||
Cut = GammaCutInKineticEnergy[J] ;
|
||||
if (Cut < MinCut) Cut = MinCut ;
|
||||
if (Cut > KineticEnergy) Cut = KineticEnergy ;
|
||||
if (Cut < MinThreshold) Cut = MinThreshold;
|
||||
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++)
|
||||
{
|
||||
@@ -418,7 +415,7 @@ void G4eBremsstrahlung::BuildLambdaTable(const G4ParticleDefinition& ParticleTyp
|
||||
// tables are Build for MATERIALS.
|
||||
{
|
||||
G4double LowEdgeEnergy , Value;
|
||||
G4double FixedEnergy = (LowestKineticEnergy + HighestKineticEnergy)/2.;
|
||||
G4double FixedEnergy = (LowerBoundLambda + UpperBoundLambda)/2.;
|
||||
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
|
||||
@@ -433,12 +430,12 @@ void G4eBremsstrahlung::BuildLambdaTable(const G4ParticleDefinition& ParticleTyp
|
||||
for ( G4int J=0 ; J < G4Material::GetNumberOfMaterials(); J++ )
|
||||
{
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(LowestKineticEnergy, HighestKineticEnergy,
|
||||
TotBin ) ;
|
||||
ptrVector = new G4PhysicsLogVector(LowerBoundLambda, UpperBoundLambda,
|
||||
NbinLambda ) ;
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
|
||||
for ( G4int i = 0 ; i < TotBin ; i++ )
|
||||
for ( G4int i = 0 ; i < NbinLambda ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
|
||||
Value = ComputeMeanFreePath( &ParticleType, LowEdgeEnergy,
|
||||
@@ -456,31 +453,27 @@ void G4eBremsstrahlung::BuildLambdaTable(const G4ParticleDefinition& ParticleTyp
|
||||
|
||||
//....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.
|
||||
G4double G4eBremsstrahlung::ComputeMeanFreePath(
|
||||
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 GammaEnergyCut = (G4Gamma::GetCutsInEnergy())[Imate];
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector() ;
|
||||
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
|
||||
G4double GammaEnergyCut = (G4Gamma::GetCutsInEnergy())[aMaterial->GetIndex()];
|
||||
if (GammaEnergyCut < MinThreshold) GammaEnergyCut = MinThreshold;
|
||||
|
||||
G4double SIGMA = 0 ;
|
||||
|
||||
PartialSumSigma(Imate) = new G4ValVector(NbOfElements);
|
||||
|
||||
G4double SIGMA = 0. ;
|
||||
|
||||
for ( G4int Ielem=0 ; Ielem < NbOfElements ; Ielem++ )
|
||||
for ( G4int i=0 ; i < aMaterial->GetNumberOfElements() ; i++ )
|
||||
{
|
||||
SIGMA += theAtomNumDensityVector[Ielem] *
|
||||
ComputeMicroscopicCrossSection( ParticleType, KineticEnergy,
|
||||
(*theElementVector)(Ielem)->GetZ(),
|
||||
GammaEnergyCut );
|
||||
PartialSumSigma(Imate)->insertAt(Ielem, SIGMA);
|
||||
}
|
||||
SIGMA += theAtomNumDensityVector[i] *
|
||||
ComputeMicroscopicCrossSection( ParticleType, KineticEnergy,
|
||||
(*theElementVector)(i)->GetZ(),
|
||||
GammaEnergyCut );
|
||||
}
|
||||
|
||||
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -677,6 +670,35 @@ G4double G4eBremsstrahlung::ComputePositronCorrFactorSigma( G4double AtomicNumbe
|
||||
|
||||
//....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....
|
||||
|
||||
G4VParticleChange* G4eBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
//
|
||||
@@ -734,7 +756,8 @@ G4VParticleChange* G4eBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
|
||||
// Gamma production cut in this material
|
||||
G4double GammaEnergyCut = (G4Gamma::GetCutsInEnergy())[aMaterial->GetIndex()];
|
||||
|
||||
if (GammaEnergyCut < MinThreshold) GammaEnergyCut = MinThreshold;
|
||||
|
||||
// check against insufficient energy
|
||||
if (KineticEnergy < GammaEnergyCut)
|
||||
{
|
||||
@@ -933,14 +956,14 @@ G4Element* G4eBremsstrahlung::SelectRandomAtom(G4Material* aMaterial) const
|
||||
void G4eBremsstrahlung::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "Total cross sections from a parametrisation. ";
|
||||
comments += "Good description from 1 KeV to 100 GeV.\n";
|
||||
comments += "Good description from 10 KeV to 100 GeV.\n";
|
||||
comments += " log scale extrapolation above 100 GeV \n";
|
||||
comments += " Gamma energy sampled from a parametrised formula.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowerBoundLambda,"Energy")
|
||||
<< " to " << G4BestUnit(UpperBoundLambda,"Energy")
|
||||
<< " in " << NbinLambda << " bins. \n";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -1,947 +0,0 @@
|
||||
// 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: G4eBremsstrahlungPlus.cc,v 1.6.8.1.2.2 1999/12/10 15:41:59 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// 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
|
||||
// ------------ G4eBremsstrahlungPlus 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()
|
||||
// 03-03-99 : Bug fixed in LPM effect, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4eBremsstrahlungPlus.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// constructor
|
||||
|
||||
G4eBremsstrahlungPlus::G4eBremsstrahlungPlus(const G4String& processName)
|
||||
: G4eEnergyLossPlus(processName), // initialization
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestKineticEnergy (1.*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
TotBin(100)
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// destructor
|
||||
|
||||
G4eBremsstrahlungPlus::~G4eBremsstrahlungPlus()
|
||||
{
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
if (&PartialSumSigma) {
|
||||
PartialSumSigma.clearAndDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlungPlus::SetPhysicsTableBining(G4double lowE, G4double highE, G4int nBins)
|
||||
{
|
||||
LowestKineticEnergy = lowE; HighestKineticEnergy = highE; TotBin = nBins;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlungPlus::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 G4eBremsstrahlungPlus::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 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();
|
||||
|
||||
// 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>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 MinKinEnergy<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)
|
||||
{
|
||||
sp=uu/(uu+MigdalConstant*TotalEnergysquare*
|
||||
(material->GetElectronDensity())) ;
|
||||
s2lpm=LPMEnergy*u/TotalEnergysquare ;
|
||||
if(s2lpm<1.)
|
||||
{
|
||||
w=s2lpm*(1.+sp) ;
|
||||
fac=sp*(sqrt(w*w+4.*s2lpm*sp*sp)-w)/
|
||||
(sqrt(1.+2.*sp+5.*sp*sp)-1.-sp) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fac=sp ;
|
||||
}
|
||||
}
|
||||
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 G4eBremsstrahlungPlus::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 G4eBremsstrahlungPlus::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 G4eBremsstrahlungPlus::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 G4eBremsstrahlungPlus::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 G4eBremsstrahlungPlus::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 G4eBremsstrahlungPlus::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 G4eBremsstrahlungPlus::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* G4eBremsstrahlungPlus::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 = G4std::max(ScreenFunction1(screenmin) - FZ ,0.);
|
||||
G4double F2 = G4std::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 = G4std::max(ScreenFunction1(screenvar) - FZ ,0.);
|
||||
F2 = G4std::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 = G4std::max(1. + xmin* (al + bl*xmin), 1.+al+bl);
|
||||
G4double xm = -al/(2.*bl);
|
||||
if ((xmin < xm)&&(xm < 1.)) grejmax = G4std::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.+Spol) ;
|
||||
G4double Supr=Spol*(sqrt(w*w+4.*S2LPM*Spol*Spol)-w)/
|
||||
(sqrt(1.+2.*Spol+5.*Spol*Spol)-1.-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* G4eBremsstrahlungPlus::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." << G4endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlungPlus::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "Total cross sections from a parametrisation. ";
|
||||
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 << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
File diff suppressed because it is too large
Load Diff
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: G4eIonisation.cc,v 1.3.8.1.2.2 1999/12/10 15:42:00 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4eIonisation.cc,v 1.10 2000/05/23 14:42:21 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
@@ -27,22 +27,23 @@
|
||||
// 04-09-98: new methods SetBining() PrintInfo()
|
||||
// 07-09-98: Cleanup
|
||||
// 02/02/99: correction inDoIt , L.Urban
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
|
||||
#include "G4eIonisation.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
G4double G4eIonisation::LowerBoundLambda = 1.*keV ;
|
||||
G4double G4eIonisation::UpperBoundLambda = 100.*TeV ;
|
||||
G4int G4eIonisation::NbinLambda = 100 ;
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4eIonisation::G4eIonisation(const G4String& processName)
|
||||
: G4eEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestKineticEnergy(1.*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
TotBin(100)
|
||||
: G4VeEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL)
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -58,16 +59,13 @@ G4eIonisation::~G4eIonisation()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eIonisation::SetPhysicsTableBining(G4double lowE, G4double highE, G4int nBins)
|
||||
{
|
||||
LowestKineticEnergy = lowE; HighestKineticEnergy = highE; TotBin = nBins;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
// just call BuildLossTable+BuildLambdaTable
|
||||
{
|
||||
// get bining from EnergyLoss
|
||||
LowestKineticEnergy = GetLowerBoundEloss() ;
|
||||
HighestKineticEnergy = GetUpperBoundEloss() ;
|
||||
TotBin = GetNbinEloss() ;
|
||||
|
||||
BuildLossTable(aParticleType) ;
|
||||
|
||||
@@ -100,6 +98,8 @@ void G4eIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
const G4double twoln10 = 2.*log(10.);
|
||||
const G4double Factor = twopi_mc2_rcl2;
|
||||
|
||||
static const G4double Tl = 0.2*keV ;
|
||||
|
||||
G4double LowEdgeEnergy, ionloss;
|
||||
|
||||
// material properties
|
||||
@@ -142,11 +142,27 @@ void G4eIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
X0den = material->GetIonisation()->GetX0density();
|
||||
X1den = material->GetIonisation()->GetX1density();
|
||||
|
||||
// for the lowenergy extrapolation
|
||||
G4double Zeff = material->GetTotNbOfElectPerVolume()/
|
||||
material->GetTotNbOfAtomsPerVolume() ;
|
||||
G4double Th = 0.25*sqrt(Zeff)*keV ;
|
||||
|
||||
G4double Tsav ;
|
||||
|
||||
// now comes the loop for the kinetic energy values
|
||||
|
||||
for (G4int i = 0 ; i < TotBin ; i++)
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
// low energy ?
|
||||
if(LowEdgeEnergy < Th)
|
||||
{
|
||||
Tsav = LowEdgeEnergy ;
|
||||
LowEdgeEnergy = Th ;
|
||||
}
|
||||
else
|
||||
Tsav = 0. ;
|
||||
|
||||
tau = LowEdgeEnergy/ParticleMass ;
|
||||
|
||||
// Seltzer-Berger formula
|
||||
@@ -185,6 +201,15 @@ void G4eIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
ionloss *= Factor*ElectronDensity/beta2 ;
|
||||
if (ionloss <= 0.) ionloss = 0.;
|
||||
|
||||
// low energy ?
|
||||
if(Tsav > 0.)
|
||||
{
|
||||
if(Tsav >= Tl)
|
||||
ionloss *= sqrt(LowEdgeEnergy/Tsav) ;
|
||||
else
|
||||
ionloss *= sqrt(LowEdgeEnergy*Tsav)/Tl ;
|
||||
}
|
||||
|
||||
aVector->PutValue(i,ionloss) ;
|
||||
}
|
||||
theLossTable->insert(aVector);
|
||||
@@ -211,9 +236,19 @@ void G4eIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
theMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
// get electron cuts in kinetic energy
|
||||
// The electron cuts needed in the case of the positron , too!
|
||||
// This is the reason why SetCut has to be called for electron first !!!!!!!
|
||||
|
||||
if((G4Electron::Electron()->GetCutsInEnergy() == 0) &&
|
||||
( &aParticleType == G4Positron::Positron()))
|
||||
{
|
||||
G4cout << " The ELECTRON energy cuts needed to compute energy loss/mean free path "
|
||||
" for POSITRON , too. " << G4endl;
|
||||
G4Exception(" Call SetCut for e- first !!!!!!") ;
|
||||
}
|
||||
|
||||
G4double* DeltaCutInKineticEnergy = G4Electron::Electron()->GetCutsInEnergy() ;
|
||||
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int J=0 ; J < numOfMaterials; J++)
|
||||
@@ -221,7 +256,7 @@ void G4eIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
//create physics vector then fill it ....
|
||||
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy, HighestKineticEnergy, TotBin);
|
||||
LowerBoundLambda, UpperBoundLambda, NbinLambda);
|
||||
|
||||
// compute the (macroscopic) cross section first
|
||||
|
||||
@@ -238,7 +273,7 @@ void G4eIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
// (--> it will be the same for all the elements in this material )
|
||||
G4double DeltaThreshold = DeltaCutInKineticEnergy[J] ;
|
||||
|
||||
for (G4int i = 0 ; i < TotBin ; i++)
|
||||
for (G4int i = 0 ; i < NbinLambda ; i++)
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
SIGMA = 0.;
|
||||
@@ -257,7 +292,6 @@ void G4eIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
}
|
||||
theMeanFreePathTable->insert(aVector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -450,9 +484,9 @@ void G4eIonisation::PrintInfoDefinition()
|
||||
comments += " delta ray energy sampled from differential Xsection.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowerBoundLambda,"Energy")
|
||||
<< " to " << G4BestUnit(UpperBoundLambda,"Energy")
|
||||
<< " in " << NbinLambda << " bins. \n";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -1,458 +0,0 @@
|
||||
// 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: G4eIonisationPlus.cc,v 1.3.8.1.2.2 1999/12/10 15:42:00 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
// 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
|
||||
// ---------- G4eIonisationPlus physics process -----------
|
||||
// by Laszlo Urban, 20 March 1997
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW IONISATION PROCESS.
|
||||
// It calculates the ionisation of e+/e-.
|
||||
// **************************************************************
|
||||
//
|
||||
// 07-04-98: remove 'tracking cut' of the ionizing particle, MMa
|
||||
// 04-09-98: new methods SetBining() PrintInfo()
|
||||
// 07-09-98: Cleanup
|
||||
// 02/02/99: correction in DoIt , L.urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
|
||||
#include "G4eIonisationPlus.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4eIonisationPlus::G4eIonisationPlus(const G4String& processName)
|
||||
: G4eEnergyLossPlus(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestKineticEnergy(1.*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
TotBin(100)
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4eIonisationPlus::~G4eIonisationPlus()
|
||||
{
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eIonisationPlus::SetPhysicsTableBining(G4double lowE, G4double highE, G4int nBins)
|
||||
{
|
||||
LowestKineticEnergy = lowE; HighestKineticEnergy = highE; TotBin = nBins;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eIonisationPlus::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 G4eIonisationPlus::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build tables for the ionization energy loss
|
||||
// the tables are built for *MATERIALS*
|
||||
|
||||
const G4double twoln10 = 2.*log(10.);
|
||||
const G4double Factor = twopi_mc2_rcl2;
|
||||
|
||||
G4double LowEdgeEnergy, ionloss;
|
||||
|
||||
// material properties
|
||||
G4double ElectronDensity,Eexc,Eexcm2,Cden,Mden,Aden,X0den,X1den ;
|
||||
// some local variables
|
||||
G4double tau,Tmax,gamma,gamma2,bg2,beta2,d,d2,d3,d4,delta,x,y ;
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass();
|
||||
G4double* ParticleCutInKineticEnergy = aParticleType.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 material parameters needed for the energy loss calculation
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
|
||||
ElectronDensity = material->GetElectronDensity();
|
||||
Eexc = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
Eexc /= ParticleMass; Eexcm2 = Eexc*Eexc;
|
||||
Cden = material->GetIonisation()->GetCdensity();
|
||||
Mden = material->GetIonisation()->GetMdensity();
|
||||
Aden = material->GetIonisation()->GetAdensity();
|
||||
X0den = material->GetIonisation()->GetX0density();
|
||||
X1den = material->GetIonisation()->GetX1density();
|
||||
|
||||
// now comes the loop for the kinetic energy values
|
||||
|
||||
for (G4int i = 0 ; i < TotBin ; i++)
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
tau = LowEdgeEnergy/ParticleMass ;
|
||||
|
||||
// Seltzer-Berger formula
|
||||
gamma = tau + 1.; gamma2 = gamma*gamma;
|
||||
bg2 = tau*(tau+2.);
|
||||
beta2 = bg2/gamma2;
|
||||
|
||||
// electron
|
||||
if (&aParticleType==G4Electron::Electron())
|
||||
{
|
||||
Tmax = LowEdgeEnergy/2.;
|
||||
d = G4std::min(ParticleCutInKineticEnergy[J], Tmax)/ParticleMass;
|
||||
ionloss = log(2.*(tau+2.)/Eexcm2)-1.-beta2
|
||||
+ log((tau-d)*d)+tau/(tau-d)
|
||||
+ (0.5*d*d+(2.*tau+1.)*log(1.-d/tau))/gamma2;
|
||||
}
|
||||
else //positron
|
||||
{
|
||||
Tmax = LowEdgeEnergy ;
|
||||
d = G4std::min(ParticleCutInKineticEnergy[J], Tmax)/ParticleMass;
|
||||
d2=d*d/2.; d3=d*d*d/3.; d4=d*d*d*d/4.;
|
||||
y=1./(1.+gamma);
|
||||
ionloss = log(2.*(tau+2.)/Eexcm2)+log(tau*d)
|
||||
- beta2*(tau+2.*d-y*(3.*d2+y*(d-d3+y*(d2-tau*d3+d4))))/tau;
|
||||
}
|
||||
|
||||
//density correction
|
||||
x = log(bg2)/twoln10;
|
||||
if (x < X0den) delta = 0.;
|
||||
else { delta = twoln10*x - Cden;
|
||||
if (x < X1den) delta += Aden*pow((X1den-x),Mden);
|
||||
}
|
||||
|
||||
//now you can compute the total ionization loss
|
||||
ionloss -= delta ;
|
||||
ionloss *= Factor*ElectronDensity/beta2 ;
|
||||
if (ionloss <= 0.) ionloss = 0.;
|
||||
|
||||
aVector->PutValue(i,ionloss) ;
|
||||
}
|
||||
theLossTable->insert(aVector);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eIonisationPlus::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build mean free path tables for the delta ray production process
|
||||
// tables are built for MATERIALS
|
||||
|
||||
G4double LowEdgeEnergy, Value, SIGMA;
|
||||
|
||||
//create table
|
||||
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if (theMeanFreePathTable) { theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
theMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
// get electron cuts in kinetic energy
|
||||
G4double* DeltaCutInKineticEnergy = G4Electron::Electron()->GetCutsInEnergy() ;
|
||||
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int J=0 ; J < numOfMaterials; J++)
|
||||
{
|
||||
//create physics vector then fill it ....
|
||||
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy, HighestKineticEnergy, TotBin);
|
||||
|
||||
// compute the (macroscopic) cross section first
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
const
|
||||
G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const
|
||||
G4double* theAtomicNumDensityVector = material->GetAtomicNumDensityVector();
|
||||
const
|
||||
G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
|
||||
// get the electron kinetic energy cut for the actual material,
|
||||
// it will be used in ComputeMicroscopicCrossSection
|
||||
// (--> it will be the same for all the elements in this material )
|
||||
G4double DeltaThreshold = DeltaCutInKineticEnergy[J] ;
|
||||
|
||||
for (G4int i = 0 ; i < TotBin ; i++)
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
SIGMA = 0.;
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ )
|
||||
{
|
||||
SIGMA += theAtomicNumDensityVector[iel]*
|
||||
ComputeMicroscopicCrossSection( aParticleType,
|
||||
LowEdgeEnergy,
|
||||
(*theElementVector)(iel)->GetZ(),
|
||||
DeltaThreshold);
|
||||
}
|
||||
|
||||
// mean free path = 1./macroscopic cross section
|
||||
Value = SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
aVector->PutValue(i, Value) ;
|
||||
}
|
||||
theMeanFreePathTable->insert(aVector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eIonisationPlus::ComputeMicroscopicCrossSection(
|
||||
const G4ParticleDefinition& aParticleType,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber ,
|
||||
G4double DeltaThreshold)
|
||||
{
|
||||
// calculates the microscopic cross section
|
||||
//(it is called for elements , AtomicNumber = Z )
|
||||
|
||||
G4double MaxKineticEnergyTransfer, TotalCrossSection(0.);
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass();
|
||||
G4double TotalEnergy = KineticEnergy + ParticleMass;
|
||||
|
||||
G4double betasquare = KineticEnergy*(TotalEnergy+ParticleMass)
|
||||
/(TotalEnergy*TotalEnergy);
|
||||
G4double gamma = TotalEnergy/ParticleMass, gamma2 = gamma*gamma;
|
||||
G4double x=DeltaThreshold/KineticEnergy, x2 = x*x;
|
||||
|
||||
if (&aParticleType==G4Electron::Electron())
|
||||
MaxKineticEnergyTransfer = 0.5*KineticEnergy;
|
||||
else MaxKineticEnergyTransfer = KineticEnergy;
|
||||
|
||||
// now you can calculate the total cross section
|
||||
|
||||
if (MaxKineticEnergyTransfer > DeltaThreshold)
|
||||
{
|
||||
if (&aParticleType==G4Electron::Electron()) //Moller (e-e-) scattering
|
||||
{
|
||||
TotalCrossSection = (gamma-1.)*(gamma-1.)*(0.5-x)/gamma2 + 1./x
|
||||
- 1./(1.-x)-(2.*gamma-1.)*log((1.-x)/x)/gamma2;
|
||||
TotalCrossSection /= betasquare;
|
||||
}
|
||||
else //Bhabha (e+e-) scattering
|
||||
{
|
||||
G4double y=1./(1.+gamma), y2 =y*y, y12=1.-2.*y;
|
||||
G4double b1=2.-y2, b2=y12*(3.+y2), b4=y12*y12*y12, b3=b4+y12*y12;
|
||||
TotalCrossSection = (1./x-1.)/betasquare+b1*log(x)+b2*(1.-x)
|
||||
- b3*(1.-x2)/2.+b4*(1.-x2*x)/3.;
|
||||
}
|
||||
TotalCrossSection *= (twopi_mc2_rcl2*AtomicNumber/KineticEnergy);
|
||||
}
|
||||
return TotalCrossSection ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4eIonisationPlus::PostStepDoIt( const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
aParticleChange.Initialize(trackData) ;
|
||||
|
||||
G4Material* aMaterial = trackData.GetMaterial() ;
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle() ;
|
||||
|
||||
ParticleMass = aParticle->GetDefinition()->GetPDGMass();
|
||||
G4double KineticEnergy = aParticle->GetKineticEnergy();
|
||||
G4double TotalEnergy = KineticEnergy + ParticleMass;
|
||||
G4double Psquare = KineticEnergy*(TotalEnergy+ParticleMass);
|
||||
G4double TotalMomentum = sqrt(Psquare);
|
||||
G4double Esquare=TotalEnergy*TotalEnergy;
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection();
|
||||
|
||||
// get kinetic energy cut for the electron
|
||||
G4double* DeltaCutInKineticEnergy = G4Electron::Electron()->GetCutsInEnergy() ;
|
||||
G4double DeltaThreshold = DeltaCutInKineticEnergy[aMaterial->GetIndex()];
|
||||
|
||||
// some kinematics
|
||||
G4double MaxKineticEnergyTransfer;
|
||||
if (Charge < 0.) MaxKineticEnergyTransfer = 0.5*KineticEnergy;
|
||||
else MaxKineticEnergyTransfer = KineticEnergy;
|
||||
|
||||
// sampling kinetic energy of the delta ray
|
||||
|
||||
if (MaxKineticEnergyTransfer <= DeltaThreshold) // pathological case (should not happen,
|
||||
// there is no change at all)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
|
||||
|
||||
// normal case
|
||||
G4double cc,y,y2,c2,b0,b1,b2,b3,b4,x,x1,grej,grejc;
|
||||
|
||||
G4double tau = KineticEnergy/ParticleMass;
|
||||
G4double gamma = tau+1., gamma2=gamma*gamma;
|
||||
G4double xc = DeltaThreshold/KineticEnergy, xc1=1.-xc;
|
||||
|
||||
if (Charge < 0.) // Moller (e-e-) scattering
|
||||
{
|
||||
b1=4./(9.*gamma2-10.*gamma+5.);
|
||||
b2=tau*tau*b1; b3=(2.*gamma2+2.*gamma-1.)*b1;
|
||||
cc=1.-2.*xc;
|
||||
do {
|
||||
x = xc/(1.-cc*G4UniformRand()); x1 = 1.-x;
|
||||
grej = b2*x*x-b3*x/x1+b1*gamma2/(x1*x1);
|
||||
} while (G4UniformRand()>grej) ;
|
||||
}
|
||||
else // Bhabha (e+e-) scattering
|
||||
{
|
||||
y=1./(gamma+1.); y2=y*y; cc=1.-2.*y;
|
||||
b1=2.-y2; b2=cc*(3.+y2);
|
||||
c2=cc*cc; b4=c2*cc; b3=c2+b4;
|
||||
b0=gamma2/(gamma2-1.);
|
||||
grejc=(((b4*xc-b3)*xc+b2)*xc-b1)*xc+b0;
|
||||
do {
|
||||
x = xc/(1.-xc1*G4UniformRand());
|
||||
grej = ((((b4*x-b3)*x+b2)*x-b1)*x+b0)/grejc;
|
||||
} while (G4UniformRand()>grej);
|
||||
}
|
||||
|
||||
G4double DeltaKineticEnergy = x * KineticEnergy;
|
||||
|
||||
// protection :do not produce a secondary with 0. kinetic energy !
|
||||
if (DeltaKineticEnergy <= 0.)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
|
||||
G4double DeltaTotalMomentum = sqrt(DeltaKineticEnergy * (DeltaKineticEnergy +
|
||||
2. * electron_mass_c2 ));
|
||||
|
||||
G4double costheta = DeltaKineticEnergy * (TotalEnergy + electron_mass_c2)
|
||||
/(DeltaTotalMomentum * TotalMomentum);
|
||||
|
||||
if (costheta < -1.) costheta = -1.;
|
||||
if (costheta > +1.) costheta = +1.;
|
||||
|
||||
// direction of the delta electron
|
||||
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
G4double sintheta = sqrt((1.+costheta)*(1.-costheta));
|
||||
G4double dirx = sintheta * cos(phi), diry = sintheta * sin(phi), dirz = costheta;
|
||||
|
||||
G4ThreeVector DeltaDirection(dirx,diry,dirz);
|
||||
DeltaDirection.rotateUz(ParticleDirection);
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
|
||||
G4DynamicParticle* theDeltaRay = new G4DynamicParticle;
|
||||
theDeltaRay->SetKineticEnergy( DeltaKineticEnergy );
|
||||
theDeltaRay->SetMomentumDirection(
|
||||
DeltaDirection.x(),DeltaDirection.y(),DeltaDirection.z());
|
||||
theDeltaRay->SetDefinition(G4Electron::Electron());
|
||||
|
||||
// fill aParticleChange
|
||||
// changed energy and momentum of the actual particle
|
||||
G4double finalKineticEnergy = KineticEnergy - DeltaKineticEnergy;
|
||||
|
||||
G4double Edep = 0. ;
|
||||
|
||||
if (finalKineticEnergy > MinKineticEnergy)
|
||||
{
|
||||
G4double finalPx = TotalMomentum*ParticleDirection.x()
|
||||
- DeltaTotalMomentum*DeltaDirection.x();
|
||||
G4double finalPy = TotalMomentum*ParticleDirection.y()
|
||||
- DeltaTotalMomentum*DeltaDirection.y();
|
||||
G4double finalPz = TotalMomentum*ParticleDirection.z()
|
||||
- DeltaTotalMomentum*DeltaDirection.z();
|
||||
G4double finalMomentum =
|
||||
sqrt(finalPx*finalPx+finalPy*finalPy+finalPz*finalPz) ;
|
||||
finalPx /= finalMomentum ;
|
||||
finalPy /= finalMomentum ;
|
||||
finalPz /= finalMomentum ;
|
||||
|
||||
aParticleChange.SetMomentumChange( finalPx,finalPy,finalPz );
|
||||
}
|
||||
else
|
||||
{
|
||||
finalKineticEnergy = 0.;
|
||||
Edep = finalKineticEnergy ;
|
||||
if (Charge < 0.) aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange( finalKineticEnergy );
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary( theDeltaRay );
|
||||
aParticleChange.SetLocalEnergyDeposit (Edep);
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eIonisationPlus::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "delta cross sections from Moller+Bhabha. ";
|
||||
comments += "Good description from 1 KeV to 100 GeV.\n";
|
||||
comments += " delta ray energy sampled from differential Xsection.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4eplusAnnihilation.cc,v 1.1.10.1.2.1 1999/12/08 17:34:26 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4eplusAnnihilation.cc,v 1.2 1999/12/15 14:51:53 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
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: G4hIonisation.cc,v 1.6.8.1.2.1 1999/12/08 17:34:27 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4hIonisation.cc,v 1.11 2000/05/23 14:42:22 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -27,16 +27,23 @@
|
||||
// 22/10/98: cleanup L.Urban
|
||||
// 02/02/99: bugs fixed , L.Urban
|
||||
// 29/07/99: correction in BuildLossTable for low energy, L.Urban
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
|
||||
#include "G4hIonisation.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
G4double G4hIonisation::LowerBoundLambda = 1.*keV ;
|
||||
G4double G4hIonisation::UpperBoundLambda = 100.*TeV ;
|
||||
G4int G4hIonisation::NbinLambda = 100 ;
|
||||
|
||||
G4double G4hIonisation::Tmincut = 1.*keV ;
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4hIonisation::G4hIonisation(const G4String& processName)
|
||||
: G4hEnergyLoss(processName),
|
||||
: G4VhEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
theProton (G4Proton::Proton()),
|
||||
theAntiProton (G4AntiProton::AntiProton()),
|
||||
@@ -51,24 +58,16 @@ G4hIonisation::~G4hIonisation()
|
||||
}
|
||||
}
|
||||
|
||||
void G4hIonisation::SetPhysicsTableBining(G4double lowE, G4double highE,
|
||||
G4int nBins)
|
||||
{
|
||||
LowestKineticEnergy = lowE; HighestKineticEnergy = highE;
|
||||
TotBin = nBins ;
|
||||
}
|
||||
|
||||
// methods.............................................
|
||||
|
||||
void G4hIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
// just call BuildLossTable+BuildLambdaTable
|
||||
{
|
||||
if(&aParticleType == G4Proton::Proton())
|
||||
{
|
||||
LowestKineticEnergy= 1.00*keV;
|
||||
HighestKineticEnergy= 100.*TeV;
|
||||
TotBin=100 ;
|
||||
}
|
||||
// get bining from EnergyLoss
|
||||
LowestKineticEnergy = GetLowerBoundEloss() ;
|
||||
HighestKineticEnergy = GetUpperBoundEloss() ;
|
||||
TotBin = GetNbinEloss() ;
|
||||
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
@@ -176,7 +175,7 @@ void G4hIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
|
||||
// get electron cut in kin. energy for the material
|
||||
|
||||
DeltaCutInKineticEnergyNow = DeltaCutInKineticEnergy[J] ;
|
||||
DeltaCutInKineticEnergyNow = G4std::max(DeltaCutInKineticEnergy[J],Tmincut) ;
|
||||
|
||||
// some local variables -------------------
|
||||
G4double tau,tau0,Tmax,gamma,bg2,beta2,rcut,delta,x,sh ;
|
||||
@@ -317,7 +316,7 @@ void G4hIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
//create physics vector then fill it ....
|
||||
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy, HighestKineticEnergy, TotBin);
|
||||
LowerBoundLambda,UpperBoundLambda,NbinLambda);
|
||||
|
||||
// compute the (macroscopic) cross section first
|
||||
|
||||
@@ -335,9 +334,10 @@ void G4hIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
// ( it is the SAME for ALL the ELEMENTS in THIS MATERIAL )
|
||||
// ------------------------------------------------------
|
||||
|
||||
DeltaCutInKineticEnergyNow = DeltaCutInKineticEnergy[J] ;
|
||||
DeltaCutInKineticEnergyNow =G4std::max(DeltaCutInKineticEnergy[J],Tmincut) ;
|
||||
|
||||
for ( G4int i = 0 ; i < TotBin ; i++ )
|
||||
|
||||
for ( G4int i = 0 ; i < NbinLambda ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
|
||||
@@ -450,7 +450,8 @@ G4VParticleChange* G4hIonisation::PostStepDoIt(
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection() ;
|
||||
|
||||
// get kinetic energy cut for the electron....
|
||||
DeltaCutInKineticEnergyNow = DeltaCutInKineticEnergy[aMaterial->GetIndex()];
|
||||
DeltaCutInKineticEnergyNow =
|
||||
G4std::max(DeltaCutInKineticEnergy[aMaterial->GetIndex()],Tmincut);
|
||||
|
||||
// some kinematics......................
|
||||
|
||||
|
||||
@@ -1,574 +0,0 @@
|
||||
// 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: G4hIonisationPlus.cc,v 1.3.8.1.2.1 1999/12/08 17:34:27 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
// 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
|
||||
// ---------- G4hIonisationPlus physics process -----------
|
||||
// by Laszlo Urban, 30 May 1997
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW IONISATION PROCESS.
|
||||
// It calculates the ionisation of charged hadrons.
|
||||
// **************************************************************
|
||||
// corrected by L.Urban on 24/09/97
|
||||
// several bugs corrected by L.Urban on 13/01/98
|
||||
// 07-04-98: remove 'tracking cut' of the ionizing particle, MMa
|
||||
// 22/10/98: cleanup L.Urban
|
||||
// 02/02/99: bugs fixed , L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
|
||||
#include "G4hIonisationPlus.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4hIonisationPlus::G4hIonisationPlus(const G4String& processName)
|
||||
: G4hEnergyLossPlus(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
theProton (G4Proton::Proton()),
|
||||
theAntiProton (G4AntiProton::AntiProton()),
|
||||
theElectron ( G4Electron::Electron() )
|
||||
{ }
|
||||
|
||||
G4hIonisationPlus::~G4hIonisationPlus()
|
||||
{
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
}
|
||||
|
||||
void G4hIonisationPlus::SetPhysicsTableBining(G4double lowE, G4double highE,
|
||||
G4int nBins)
|
||||
{
|
||||
LowestKineticEnergy = lowE; HighestKineticEnergy = highE;
|
||||
TotBin = nBins ;
|
||||
}
|
||||
|
||||
// methods.............................................
|
||||
|
||||
void G4hIonisationPlus::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
// just call BuildLossTable+BuildLambdaTable
|
||||
{
|
||||
if(&aParticleType == G4Proton::Proton())
|
||||
{
|
||||
LowestKineticEnergy= 1.00*keV;
|
||||
HighestKineticEnergy= 100.*TeV;
|
||||
TotBin=100 ;
|
||||
}
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
Charge = aParticleType.GetPDGCharge();
|
||||
|
||||
G4double ElectronCutInRange = G4Electron::Electron()->GetCuts();
|
||||
|
||||
DeltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
if( (ptableElectronCutInRange != ElectronCutInRange)
|
||||
|| (theDEDXpTable == NULL))
|
||||
{
|
||||
BuildLossTable(aParticleType) ;
|
||||
RecorderOfpProcess[CounterOfpProcess] = theLossTable ;
|
||||
CounterOfpProcess++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (pbartableElectronCutInRange != ElectronCutInRange)
|
||||
|| (theDEDXpbarTable == NULL))
|
||||
{
|
||||
BuildLossTable(aParticleType) ;
|
||||
RecorderOfpbarProcess[CounterOfpbarProcess] = theLossTable ;
|
||||
CounterOfpbarProcess++;
|
||||
}
|
||||
}
|
||||
|
||||
BuildLambdaTable(aParticleType) ;
|
||||
|
||||
BuildDEDXTable(aParticleType) ;
|
||||
|
||||
if(&aParticleType == G4Proton::Proton())
|
||||
PrintInfoDefinition();
|
||||
|
||||
}
|
||||
|
||||
void G4hIonisationPlus::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// cuts for electron ....................
|
||||
DeltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
|
||||
|
||||
G4double LowEdgeEnergy , ionloss ;
|
||||
G4double RateMass ;
|
||||
G4double deltaloss ;
|
||||
G4bool isOutRange ;
|
||||
static const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
const G4double twoln10 = 2.*log(10.) ;
|
||||
const G4double Factor = twopi_mc2_rcl2 ;
|
||||
const G4double bg2lim = 0.0169 , taulim = 8.4146e-3 ;
|
||||
|
||||
RateMass = electron_mass_c2/proton_mass_c2 ;
|
||||
|
||||
// create table
|
||||
|
||||
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 material parameters needed for the energy loss calculation
|
||||
|
||||
G4double ElectronDensity,Eexc,Eexc2,Cden,Mden,Aden,X0den,X1den,taul ;
|
||||
G4double* ShellCorrectionVector;
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
|
||||
ElectronDensity = material->GetElectronDensity();
|
||||
Eexc = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
Eexc2 = Eexc*Eexc ;
|
||||
Cden = material->GetIonisation()->GetCdensity();
|
||||
Mden = material->GetIonisation()->GetMdensity();
|
||||
Aden = material->GetIonisation()->GetAdensity();
|
||||
X0den = material->GetIonisation()->GetX0density();
|
||||
X1den = material->GetIonisation()->GetX1density();
|
||||
taul = material->GetIonisation()->GetTaul() ;
|
||||
ShellCorrectionVector = material->GetIonisation()->
|
||||
GetShellCorrectionVector();
|
||||
|
||||
// get elements in the actual material,
|
||||
// they are needed for the low energy part ....
|
||||
|
||||
const G4ElementVector* theElementVector=
|
||||
material->GetElementVector() ;
|
||||
const G4double* theAtomicNumDensityVector=
|
||||
material->GetAtomicNumDensityVector() ;
|
||||
const G4int NumberOfElements=
|
||||
material->GetNumberOfElements() ;
|
||||
|
||||
// get electron cut in kin. energy for the material
|
||||
|
||||
DeltaCutInKineticEnergyNow = DeltaCutInKineticEnergy[J] ;
|
||||
|
||||
// some local variables -------------------
|
||||
G4double tau,tau0,Tmax,gamma,bg2,beta2,rcut,delta,x,sh ;
|
||||
|
||||
// now comes the loop for the kinetic energy values*****************
|
||||
|
||||
for (G4int i = 0 ; i < TotBin ; i++)
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
tau = LowEdgeEnergy/proton_mass_c2 ;
|
||||
|
||||
gamma = tau +1. ;
|
||||
bg2 = tau*(tau+2.) ;
|
||||
beta2 = bg2/(gamma*gamma) ;
|
||||
Tmax = 2.*electron_mass_c2*bg2
|
||||
/(1.+2.*gamma*RateMass+RateMass*RateMass) ;
|
||||
|
||||
if ( tau < taul )
|
||||
// low energy part , parametrized energy loss formulae
|
||||
{
|
||||
ionloss = 0. ;
|
||||
deltaloss = 0. ;
|
||||
|
||||
// loop for the elements in the material
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++)
|
||||
{
|
||||
const G4Element* element = (*theElementVector)(iel);
|
||||
|
||||
if ( tau < element->GetIonisation()->GetTau0())
|
||||
ionloss += theAtomicNumDensityVector[iel]
|
||||
*( element->GetIonisation()->GetAlow()*sqrt(tau)
|
||||
+element->GetIonisation()->GetBlow()*tau) ;
|
||||
else
|
||||
ionloss += theAtomicNumDensityVector[iel]
|
||||
* element->GetIonisation()->GetClow()/sqrt(tau) ;
|
||||
}
|
||||
if ( DeltaCutInKineticEnergyNow < Tmax)
|
||||
{
|
||||
deltaloss = log(Tmax/DeltaCutInKineticEnergyNow)-
|
||||
beta2*(1.-DeltaCutInKineticEnergyNow/Tmax) ;
|
||||
if(aParticleType.GetPDGSpin() == 0.5)
|
||||
deltaloss += 0.25*(Tmax-DeltaCutInKineticEnergyNow)*
|
||||
(Tmax-DeltaCutInKineticEnergyNow)/
|
||||
(LowEdgeEnergy*LowEdgeEnergy+proton_mass_c2*proton_mass_c2) ;
|
||||
deltaloss *= Factor*ElectronDensity/beta2 ;
|
||||
}
|
||||
ionloss -= deltaloss ;
|
||||
}
|
||||
else
|
||||
// high energy part , Bethe-Bloch formula
|
||||
{
|
||||
if ( DeltaCutInKineticEnergyNow < Tmax)
|
||||
rcut = DeltaCutInKineticEnergyNow/Tmax ;
|
||||
else
|
||||
rcut = 1.;
|
||||
|
||||
ionloss = log(2.*electron_mass_c2*bg2*Tmax/Eexc2)
|
||||
+log(rcut)-(1.+rcut)*beta2 ;
|
||||
|
||||
// density correction
|
||||
|
||||
x = log(bg2)/twoln10 ;
|
||||
if ( x < X0den )
|
||||
delta = 0. ;
|
||||
else
|
||||
{
|
||||
delta = twoln10*x - Cden ;
|
||||
if ( x < X1den )
|
||||
delta += Aden*pow((X1den-x),Mden) ;
|
||||
}
|
||||
|
||||
// shell correction
|
||||
|
||||
if ( bg2 > bg2lim ) {
|
||||
sh = 0. ;
|
||||
x = 1. ;
|
||||
for (G4int k=0; k<=2; k++) {
|
||||
x *= bg2 ;
|
||||
sh += ShellCorrectionVector[k]/x;
|
||||
}
|
||||
}
|
||||
else {
|
||||
sh = 0. ;
|
||||
x = 1. ;
|
||||
for (G4int k=0; k<=2; k++) {
|
||||
x *= bg2lim ;
|
||||
sh += ShellCorrectionVector[k]/x;
|
||||
}
|
||||
sh *= log(tau/taul)/log(taulim/taul) ;
|
||||
}
|
||||
|
||||
// now you can compute the total ionization loss
|
||||
|
||||
ionloss -= delta + sh ;
|
||||
ionloss *= Factor*ElectronDensity/beta2 ;
|
||||
|
||||
}
|
||||
if ( ionloss <= 0.)
|
||||
ionloss = 0. ;
|
||||
|
||||
aVector->PutValue(i,ionloss) ;
|
||||
|
||||
}
|
||||
theLossTable->insert(aVector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void G4hIonisationPlus::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// Build mean free path tables for the delta ray production process
|
||||
// tables are built for MATERIALS
|
||||
|
||||
G4double LowEdgeEnergy , Value ,sigma ;
|
||||
G4bool isOutRange ;
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
G4Material::GetMaterialTable();
|
||||
|
||||
//create table
|
||||
|
||||
G4int numOfMaterials = theMaterialTable->length();
|
||||
|
||||
if (theMeanFreePathTable) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
theMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
// get electron and particle cuts in kinetic energy
|
||||
|
||||
DeltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int J=0 ; J < numOfMaterials; J++)
|
||||
{
|
||||
//create physics vector then fill it ....
|
||||
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy, HighestKineticEnergy, TotBin);
|
||||
|
||||
// compute the (macroscopic) cross section first
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
|
||||
const G4ElementVector* theElementVector=
|
||||
material->GetElementVector() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector();
|
||||
const G4int NumberOfElements=
|
||||
material->GetNumberOfElements() ;
|
||||
|
||||
// get the electron kinetic energy cut for the actual material,
|
||||
// it will be used in ComputeMicroscopicCrossSection
|
||||
// ( it is the SAME for ALL the ELEMENTS in THIS MATERIAL )
|
||||
// ------------------------------------------------------
|
||||
|
||||
DeltaCutInKineticEnergyNow = DeltaCutInKineticEnergy[J] ;
|
||||
|
||||
for ( G4int i = 0 ; i < TotBin ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
|
||||
sigma = 0. ;
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ )
|
||||
{
|
||||
sigma += theAtomicNumDensityVector[iel]*
|
||||
ComputeMicroscopicCrossSection(aParticleType,
|
||||
LowEdgeEnergy,
|
||||
(*theElementVector)(iel)->GetZ() ) ;
|
||||
}
|
||||
|
||||
// mean free path = 1./macroscopic cross section
|
||||
|
||||
Value = sigma<=0 ? DBL_MAX : 1./sigma ;
|
||||
|
||||
aVector->PutValue(i, Value) ;
|
||||
}
|
||||
|
||||
|
||||
theMeanFreePathTable->insert(aVector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4double G4hIonisationPlus::ComputeMicroscopicCrossSection(
|
||||
const G4ParticleDefinition& aParticleType,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber)
|
||||
{
|
||||
//******************************************************************
|
||||
// cross section formula is OK for spin=0 and 1/2 only !
|
||||
// *****************************************************************
|
||||
|
||||
// calculates the microscopic cross section in GEANT4 internal units
|
||||
// ( it is called for elements , AtomicNumber = Z )
|
||||
|
||||
G4double TotalEnergy,
|
||||
betasquare,
|
||||
MaxKineticEnergyTransfer,TotalCrossSection,tempvar;
|
||||
|
||||
// get particle data ...................................
|
||||
|
||||
TotalEnergy=KineticEnergy + ParticleMass;
|
||||
|
||||
// some kinematics......................
|
||||
|
||||
betasquare = KineticEnergy*(TotalEnergy+ParticleMass)
|
||||
/(TotalEnergy*TotalEnergy);
|
||||
tempvar = ParticleMass+electron_mass_c2;
|
||||
MaxKineticEnergyTransfer = 2.*electron_mass_c2*KineticEnergy
|
||||
*(TotalEnergy+ParticleMass)
|
||||
/(tempvar*tempvar+2.*electron_mass_c2*KineticEnergy);
|
||||
|
||||
// now you can calculate the total cross section ------------------
|
||||
|
||||
if( MaxKineticEnergyTransfer > DeltaCutInKineticEnergyNow )
|
||||
{
|
||||
tempvar=DeltaCutInKineticEnergyNow/MaxKineticEnergyTransfer;
|
||||
TotalCrossSection = (1.-tempvar*(1.-betasquare*log(tempvar)))
|
||||
/DeltaCutInKineticEnergyNow;
|
||||
|
||||
// +term for spin=1/2 particle
|
||||
if(aParticleType.GetPDGSpin() == 0.5)
|
||||
{
|
||||
TotalCrossSection += 0.5
|
||||
*(MaxKineticEnergyTransfer-DeltaCutInKineticEnergyNow)
|
||||
/(TotalEnergy*TotalEnergy);
|
||||
G4double Section = 0.5
|
||||
*(MaxKineticEnergyTransfer-DeltaCutInKineticEnergyNow)
|
||||
/(TotalEnergy*TotalEnergy);
|
||||
}
|
||||
TotalCrossSection = twopi_mc2_rcl2 * AtomicNumber
|
||||
*TotalCrossSection/betasquare;
|
||||
}
|
||||
else
|
||||
TotalCrossSection= 0. ;
|
||||
|
||||
return TotalCrossSection ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
G4VParticleChange* G4hIonisationPlus::PostStepDoIt(
|
||||
const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
// Units are expressed in GEANT4 internal units.
|
||||
|
||||
const G4DynamicParticle* aParticle ;
|
||||
G4Material* aMaterial;
|
||||
G4double KineticEnergy,TotalEnergy,TotalMomentum,
|
||||
betasquare,MaxKineticEnergyTransfer,
|
||||
DeltaKineticEnergy,DeltaTotalMomentum,costheta,sintheta,phi,
|
||||
dirx,diry,dirz,finalKineticEnergy,finalPx,finalPy,finalPz,
|
||||
x,xc,te2,grej,Psquare,Esquare,summass,rate,grejc,finalMomentum ;
|
||||
|
||||
aParticleChange.Initialize(trackData) ;
|
||||
aMaterial = trackData.GetMaterial() ;
|
||||
|
||||
aParticle = trackData.GetDynamicParticle() ;
|
||||
|
||||
ParticleMass=aParticle->GetDefinition()->GetPDGMass();
|
||||
KineticEnergy=aParticle->GetKineticEnergy();
|
||||
TotalEnergy=KineticEnergy + ParticleMass ;
|
||||
Psquare=KineticEnergy*(TotalEnergy+ParticleMass) ;
|
||||
Esquare=TotalEnergy*TotalEnergy ;
|
||||
summass = ParticleMass + electron_mass_c2 ;
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection() ;
|
||||
|
||||
// get kinetic energy cut for the electron....
|
||||
DeltaCutInKineticEnergyNow = DeltaCutInKineticEnergy[aMaterial->GetIndex()];
|
||||
|
||||
// some kinematics......................
|
||||
|
||||
betasquare=Psquare/Esquare ;
|
||||
MaxKineticEnergyTransfer = 2.*electron_mass_c2*Psquare
|
||||
/(summass*summass+2.*electron_mass_c2*KineticEnergy);
|
||||
|
||||
// sampling kinetic energy of the delta ray
|
||||
|
||||
if( MaxKineticEnergyTransfer <= DeltaCutInKineticEnergyNow )
|
||||
{
|
||||
// pathological case (it should not happen ,
|
||||
// there is no change at all).....
|
||||
|
||||
// return &aParticleChange;
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal case ......................................
|
||||
xc=DeltaCutInKineticEnergyNow/MaxKineticEnergyTransfer ;
|
||||
rate=MaxKineticEnergyTransfer/TotalEnergy ;
|
||||
|
||||
if(aParticle->GetDefinition()->GetPDGSpin() == 1)
|
||||
te2=0.5*rate*rate ;
|
||||
else
|
||||
te2=0. ;
|
||||
|
||||
// sampling follows ...
|
||||
grejc=1.-betasquare*xc+te2*xc*xc ;
|
||||
|
||||
do {
|
||||
x=xc/(1.-(1.-xc)*G4UniformRand());
|
||||
grej=(1.-x*(betasquare-x*te2))/grejc ;
|
||||
} while( G4UniformRand()>grej );
|
||||
}
|
||||
|
||||
DeltaKineticEnergy = x * MaxKineticEnergyTransfer ;
|
||||
|
||||
if(DeltaKineticEnergy <= 0.)
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
|
||||
DeltaTotalMomentum = sqrt(DeltaKineticEnergy * (DeltaKineticEnergy +
|
||||
2. * electron_mass_c2 )) ;
|
||||
TotalMomentum = sqrt(Psquare) ;
|
||||
costheta = DeltaKineticEnergy * (TotalEnergy + electron_mass_c2)
|
||||
/(DeltaTotalMomentum * TotalMomentum) ;
|
||||
|
||||
// protection against costheta > 1 or < -1 ---------------
|
||||
if ( costheta < -1. )
|
||||
costheta = -1. ;
|
||||
if ( costheta > +1. )
|
||||
costheta = +1. ;
|
||||
|
||||
// direction of the delta electron ........
|
||||
phi = twopi * G4UniformRand() ;
|
||||
sintheta = sqrt((1.+costheta)*(1.-costheta));
|
||||
dirx = sintheta * cos(phi) ;
|
||||
diry = sintheta * sin(phi) ;
|
||||
dirz = costheta ;
|
||||
|
||||
G4ThreeVector DeltaDirection(dirx,diry,dirz) ;
|
||||
DeltaDirection.rotateUz(ParticleDirection) ;
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
G4DynamicParticle *theDeltaRay = new G4DynamicParticle;
|
||||
theDeltaRay->SetKineticEnergy( DeltaKineticEnergy );
|
||||
theDeltaRay->SetMomentumDirection(
|
||||
DeltaDirection.x(),DeltaDirection.y(),DeltaDirection.z());
|
||||
theDeltaRay->SetDefinition(G4Electron::Electron());
|
||||
|
||||
// fill aParticleChange
|
||||
finalKineticEnergy = KineticEnergy - DeltaKineticEnergy ;
|
||||
G4double Edep = 0 ;
|
||||
|
||||
if (finalKineticEnergy > MinKineticEnergy)
|
||||
{
|
||||
finalPx = TotalMomentum*ParticleDirection.x()
|
||||
- DeltaTotalMomentum*DeltaDirection.x();
|
||||
finalPy = TotalMomentum*ParticleDirection.y()
|
||||
- DeltaTotalMomentum*DeltaDirection.y();
|
||||
finalPz = TotalMomentum*ParticleDirection.z()
|
||||
- DeltaTotalMomentum*DeltaDirection.z();
|
||||
finalMomentum =
|
||||
sqrt(finalPx*finalPx+finalPy*finalPy+finalPz*finalPz) ;
|
||||
finalPx /= finalMomentum ;
|
||||
finalPy /= finalMomentum ;
|
||||
finalPz /= finalMomentum ;
|
||||
|
||||
aParticleChange.SetMomentumChange( finalPx,finalPy,finalPz );
|
||||
}
|
||||
else
|
||||
{
|
||||
finalKineticEnergy = 0. ;
|
||||
Edep = finalKineticEnergy ;
|
||||
if (aParticle->GetDefinition()->GetParticleName() == "proton")
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange( finalKineticEnergy );
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary( theDeltaRay );
|
||||
aParticleChange.SetLocalEnergyDeposit (Edep);
|
||||
|
||||
//ResetNumberOfInteractionLengthLeft();
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
void G4hIonisationPlus::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = " Knock-on electron cross sections . ";
|
||||
comments += "\n Good description above the mean excitation energy.\n";
|
||||
comments += " delta ray energy sampled from differential Xsection.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from " << G4BestUnit(LowestKineticEnergy,
|
||||
"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4ionIonisation.cc,v 1.3.8.1.2.1 1999/12/08 17:34:27 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-01-01 $
|
||||
// $Id: G4ionIonisation.cc,v 1.4 1999/12/15 14:51:54 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
|
||||
Reference in New Issue
Block a user