Import Geant4 3.0.0 source tree
This commit is contained in:
@@ -5,21 +5,14 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4ComptonScattering.cc,v 1.3 1999/12/15 14:51:50 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4ComptonScattering.cc,v 1.4 2000/11/17 15:03:17 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, IT Division, ASD group
|
||||
// History: first implementation, based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ------------ G4ComptonScattering physics process --------
|
||||
//------------ G4ComptonScattering physics process --------
|
||||
// by Michel Maire, April 1996
|
||||
// **************************************************************
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// 28-05-96, DoIt() small change in ElecDirection, by M.Maire
|
||||
// 10-06-96, simplification in ComputeMicroscopicCrossSection(), by M.Maire
|
||||
// 21-06-96, SetCuts implementation, M.Maire
|
||||
|
||||
@@ -1,113 +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: G4EnergyLossMessenger.cc,v 1.5 2000/05/23 14:42:21 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
//
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
|
||||
#include "G4VeEnergyLoss.hh"
|
||||
#include "G4VhEnergyLoss.hh"
|
||||
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4UIparameter.hh"
|
||||
#include "G4UIcmdWithABool.hh"
|
||||
|
||||
#include "g4std/strstream"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EnergyLossMessenger::G4EnergyLossMessenger()
|
||||
{
|
||||
RndmStepCmd = new G4UIcmdWithABool("/process/eLoss/rndmStep",this);
|
||||
RndmStepCmd->SetGuidance("Randomize the proposed step for eLoss.");
|
||||
RndmStepCmd->SetParameterName("choice",true);
|
||||
RndmStepCmd->SetDefaultValue(false);
|
||||
RndmStepCmd->AvailableForStates(Idle);
|
||||
|
||||
EnlossFlucCmd = new G4UIcmdWithABool("/process/eLoss/fluct",this);
|
||||
EnlossFlucCmd->SetGuidance("Switch on/off the energy loss fluctuation.");
|
||||
EnlossFlucCmd->SetParameterName("choice",true);
|
||||
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");
|
||||
StepFuncCmd->SetGuidance(" finalRange: range for final step");
|
||||
G4UIparameter* dRoverRPrm = new G4UIparameter("dRoverR",'d',false);
|
||||
dRoverRPrm->SetGuidance("max Range variation per step (fractional number)");
|
||||
dRoverRPrm->SetParameterRange("dRoverR>0. && dRoverR<=1.");
|
||||
StepFuncCmd->SetParameter(dRoverRPrm);
|
||||
G4UIparameter* finalRangePrm = new G4UIparameter("finalRange",'d',false);
|
||||
finalRangePrm->SetGuidance("range for final step");
|
||||
finalRangePrm->SetParameterRange("finalRange>0.");
|
||||
StepFuncCmd->SetParameter(finalRangePrm);
|
||||
G4UIparameter* unitPrm = new G4UIparameter("unit",'s',true);
|
||||
unitPrm->SetGuidance("unit of finalRange");
|
||||
unitPrm->SetDefaultValue("mm");
|
||||
G4String unitCandidates = G4UIcommand::UnitsList(G4UIcommand::CategoryOf("mm"));
|
||||
unitPrm->SetParameterCandidates(unitCandidates);
|
||||
StepFuncCmd->SetParameter(unitPrm);
|
||||
StepFuncCmd->AvailableForStates(Idle);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EnergyLossMessenger::~G4EnergyLossMessenger()
|
||||
{
|
||||
delete RndmStepCmd;
|
||||
delete EnlossFlucCmd;
|
||||
delete SubSecCmd;
|
||||
delete StepFuncCmd;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
{
|
||||
if (command == RndmStepCmd)
|
||||
{ G4VeEnergyLoss::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
G4VhEnergyLoss::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == EnlossFlucCmd)
|
||||
{ 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)
|
||||
{
|
||||
G4double v1,v2;
|
||||
char unts[30];
|
||||
const char* t = newValue;
|
||||
G4std::istrstream is((char*)t);
|
||||
is >> v1 >> v2 >> unts;
|
||||
G4String unt = unts;
|
||||
v2 *= G4UIcommand::ValueOf(unt);
|
||||
G4VeEnergyLoss::SetStepFunction(v1,v2);
|
||||
G4VhEnergyLoss::SetStepFunction(v1,v2);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4GammaConversion.cc,v 1.3 1999/12/15 14:51:50 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4GammaConversion.cc,v 1.4 2000/08/03 08:36:52 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -14,7 +14,7 @@
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, IT Division, ASD group
|
||||
// GEANT4 Collaboration
|
||||
// History: first implementation, based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ------------ G4GammaConversion physics process --------
|
||||
@@ -280,7 +280,7 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
//
|
||||
|
||||
G4double ElectTotEnergy, PositTotEnergy;
|
||||
if (RandFlat::shootBit())
|
||||
if (RandBit::shootBit())
|
||||
{
|
||||
ElectTotEnergy = (1.-epsil)*GammaEnergy;
|
||||
PositTotEnergy = epsil*GammaEnergy;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IeBremsstrahlung.cc,v 1.5 2000/04/25 14:33:08 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
// $Id:
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IeIonisation.cc,v 1.5 2000/04/25 14:33:08 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
// $Id:
|
||||
// -------------------------------------------------------------
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4IeplusAnnihilation.cc,v 1.6 1999/12/15 14:51:50 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// GEANT4 tag $Name: geant4-03-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.7 2000/04/25 14:33:09 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4IhIonisation.cc,v 1.9 2000/08/01 08:12:13 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -35,7 +35,12 @@
|
||||
|
||||
G4IhIonisation::G4IhIonisation(const G4String& processName)
|
||||
: G4VIhEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL),
|
||||
theMeanFreePathTable(0),
|
||||
theNlambdaTable(0),
|
||||
theInverseNlambdaTable(0),
|
||||
theCoeffATable(0),
|
||||
theCoeffBTable(0),
|
||||
theCoeffCTable(0),
|
||||
NumberOfBuildPhysicsTableCalls(0),
|
||||
theProton (G4Proton::Proton()),
|
||||
theAntiProton (G4AntiProton::AntiProton()),
|
||||
|
||||
@@ -5,28 +5,20 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4PAIonisation.cc,v 1.8 2000/05/02 15:12:45 grichine Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4PAIonisation.cc,v 1.13 2000/09/22 14:46:38 grichine Exp $
|
||||
// GEANT4 tag $Name: geant4-03-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
|
||||
// ---------- G4PAIonisation physics process -----------
|
||||
// modified by V.Grichine 27.11.97
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW IONISATION PROCESS.
|
||||
// It calculates the ionisation of charged hadrons.
|
||||
// **************************************************************
|
||||
//
|
||||
// 12.07.00, V.Grichine - modifications in BuildPAIonisationTable
|
||||
// 11.07.00, V.Grichine - GetRandomEnergyTransfer, and PostStepDoIt
|
||||
// modifications
|
||||
// 03.07.00, V.Grichine - modifications in AlongStepDoIt
|
||||
// 08-04-98: remove 'traking cut' of the ionizing particle, MMa
|
||||
// 30-11-97: V. Grichine
|
||||
//
|
||||
|
||||
//
|
||||
// **************************************************************
|
||||
|
||||
#include "G4PAIonisation.hh"
|
||||
#include "G4PAIxSection.hh"
|
||||
@@ -73,10 +65,10 @@ G4PAIonisation::G4PAIonisation( const G4String& materialName,
|
||||
G4Exception("Invalid material name in G4PAIonisation constructor") ;
|
||||
}
|
||||
ComputeSandiaPhotoAbsCof() ;
|
||||
BuildPAIonisationTable() ;
|
||||
|
||||
|
||||
// G4cout<<"G4PAIonisation constructor is called"<<G4endl ;
|
||||
// BuildPAIonisationTable() ;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -95,7 +87,13 @@ G4PAIonisation::~G4PAIonisation()
|
||||
fPAItransferBank->clearAndDestroy() ;
|
||||
delete fPAItransferBank ;
|
||||
}
|
||||
for(G4int i=0;i<fSandiaIntervalNumber;i++)
|
||||
{
|
||||
delete[] fSandiaPhotoAbsCof[i] ;
|
||||
}
|
||||
delete[] fSandiaPhotoAbsCof ;
|
||||
|
||||
// if(fProtonEnergyVector) delete fProtonEnergyVector ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
@@ -167,7 +165,7 @@ G4PAIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
G4double Chargesquare = Charge*Charge ;
|
||||
CutInRange = aParticleType.GetLengthCuts();
|
||||
|
||||
BuildLossTable(aParticleType) ;
|
||||
// BuildLossTable(aParticleType) ;
|
||||
|
||||
if(Charge>0.)
|
||||
{
|
||||
@@ -193,47 +191,18 @@ G4PAIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
// the tables are built for MATERIALS
|
||||
// *********
|
||||
|
||||
void
|
||||
G4PAIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
//G4PAIonisation::BuildPAIonisationTable()
|
||||
void
|
||||
G4PAIonisation::BuildPAIonisationTable()
|
||||
{
|
||||
G4double Charge = aParticleType.GetPDGCharge() ;
|
||||
|
||||
G4double LowEdgeEnergy , ionloss ;
|
||||
G4double RateMass ;
|
||||
G4bool isOutRange ;
|
||||
static const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
const G4double SmallIonLoss = DBL_MIN ;
|
||||
const G4double twoln10 = 2.*log(10.) ;
|
||||
const G4double Factor = twopi_mc2_rcl2 ;
|
||||
const G4double bg2lim = 0.0169 , taulim = 8.4146e-3 ;
|
||||
|
||||
// cuts for p/pbar and electron
|
||||
|
||||
// /* *********************************************
|
||||
if(Charge>0.)
|
||||
{
|
||||
ParticleCutInKineticEnergy = theProton->GetCutsInEnergy() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParticleCutInKineticEnergy = theAntiProton->GetCutsInEnergy() ;
|
||||
}
|
||||
DeltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
|
||||
// ************************************************** */
|
||||
|
||||
ParticleMass = proton_mass_c2;
|
||||
RateMass = electron_mass_c2/ParticleMass ;
|
||||
G4int numOfMaterials = theMaterialTable->length(); // create table
|
||||
G4double massRatio, tau, Tmax, gamma, bg2 ;
|
||||
|
||||
if ( theLossTable)
|
||||
{
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
theLossTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
// theLossTable = new G4PhysicsTable(1);
|
||||
theLossTable = new G4PhysicsTable();
|
||||
|
||||
if( fPAItransferBank )
|
||||
{
|
||||
@@ -241,118 +210,72 @@ G4PAIonisation::BuildLossTable(const G4ParticleDefinition& aParticleType)
|
||||
delete fPAItransferBank ;
|
||||
}
|
||||
fPAItransferBank = new G4PhysicsTable(TotBin) ;
|
||||
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++) // loop for materials
|
||||
{
|
||||
if( J != fMatIndex ) continue ; // skip another material
|
||||
|
||||
//create physics vector then fill it ....
|
||||
//create physics vector then fill it ....
|
||||
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector( LowestKineticEnergy,
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector( LowestKineticEnergy,
|
||||
HighestKineticEnergy,
|
||||
TotBin ) ;
|
||||
|
||||
// get material parameters needed for the energy loss calculation
|
||||
// From gas detector experience
|
||||
|
||||
G4double ElectronDensity, Eexc, Eexc2, Cden, Mden, Aden, X0den, X1den, taul ;
|
||||
G4double* ShellCorrectionVector ;
|
||||
|
||||
const G4Material* material= (*theMaterialTable)[J];
|
||||
DeltaCutInKineticEnergyNow = 100*keV ;
|
||||
|
||||
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();
|
||||
for (G4int i = 0 ; i < TotBin ; i++) //The loop for the kinetic energy
|
||||
{
|
||||
LowEdgeEnergy = fProtonEnergyVector->GetLowEdgeEnergy(i) ;
|
||||
|
||||
tau = LowEdgeEnergy/proton_mass_c2 ;
|
||||
|
||||
// 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] ;
|
||||
|
||||
// From gas detector experience
|
||||
|
||||
DeltaCutInKineticEnergyNow = 100*keV ;
|
||||
|
||||
// some local variables
|
||||
|
||||
G4double tau,tau0,Tmax,gamma,bg2,beta2,rcut,delta,x,sh ;
|
||||
|
||||
// G4cout<<"Material no. = "<<J<<"\t"<<"TotBin = "<<TotBin<<G4endl ;
|
||||
|
||||
for (G4int i = 0 ; i < TotBin ; i++) //The loop for the kinetic energy
|
||||
if(tau < 0.01) // was 0.11, 0.05
|
||||
{
|
||||
G4PhysicsFreeVector* transferVector ;
|
||||
LowEdgeEnergy = fProtonEnergyVector->GetLowEdgeEnergy(i) ;
|
||||
tau = LowEdgeEnergy/ParticleMass ;
|
||||
|
||||
|
||||
|
||||
// high energy part , <dE/dx> according PAI cross section
|
||||
{
|
||||
if(tau < 0.01) // was 0.11, 0.05
|
||||
{
|
||||
tau = 0.01 ;
|
||||
}
|
||||
gamma = tau +1. ;
|
||||
}
|
||||
gamma = tau +1. ;
|
||||
|
||||
// G4cout<<"gamma = "<<gamma<<endl ;
|
||||
// G4cout<<"gamma = "<<gamma<<endl ;
|
||||
|
||||
bg2 = tau*(tau+2.) ;
|
||||
beta2 = bg2/(gamma*gamma) ;
|
||||
Tmax = 2.*electron_mass_c2*bg2
|
||||
/(1.+2.*gamma*RateMass+RateMass*RateMass) ;
|
||||
bg2 = tau*(tau + 2. ) ;
|
||||
massRatio = electron_mass_c2/proton_mass_c2 ;
|
||||
|
||||
if ( DeltaCutInKineticEnergyNow > Tmax) // was <
|
||||
{
|
||||
DeltaCutInKineticEnergyNow = Tmax ;
|
||||
}
|
||||
G4PAIxSection protonPAI(J,DeltaCutInKineticEnergyNow,bg2,
|
||||
fSandiaPhotoAbsCof,fSandiaIntervalNumber) ;
|
||||
Tmax = 2.*electron_mass_c2*bg2/(1.+2.*gamma*massRatio+massRatio*massRatio) ;
|
||||
|
||||
if ( DeltaCutInKineticEnergyNow > Tmax) // was <
|
||||
{
|
||||
DeltaCutInKineticEnergyNow = Tmax ;
|
||||
}
|
||||
G4PAIxSection protonPAI( fMatIndex,
|
||||
DeltaCutInKineticEnergyNow,
|
||||
bg2,
|
||||
fSandiaPhotoAbsCof,
|
||||
fSandiaIntervalNumber ) ;
|
||||
|
||||
ionloss = protonPAI.GetMeanEnergyLoss() ; // total <dE/dx>
|
||||
ionloss = protonPAI.GetMeanEnergyLoss() ; // total <dE/dx>
|
||||
|
||||
// G4cout<<"ionloss = "<<ionloss*cm/keV<<" keV/cm"<<endl ;
|
||||
// G4cout<<"n1 = "<<protonPAI.GetIntegralPAIxSection(1)*cm<<" 1/cm"<<endl ;
|
||||
// G4cout<<"protonPAI.GetSplineSize() = "<<
|
||||
// protonPAI.GetSplineSize()<<G4endl ;
|
||||
|
||||
transferVector = new
|
||||
G4PhysicsFreeVector* transferVector = new
|
||||
G4PhysicsFreeVector(protonPAI.GetSplineSize()) ;
|
||||
|
||||
for(G4int k=0;k<protonPAI.GetSplineSize();k++)
|
||||
{
|
||||
transferVector->PutValue( k ,
|
||||
for(G4int k=0;k<protonPAI.GetSplineSize();k++)
|
||||
{
|
||||
transferVector->PutValue( k ,
|
||||
protonPAI.GetSplineEnergy(k+1),
|
||||
protonPAI.GetIntegralPAIxSection(k+1) ) ;
|
||||
}
|
||||
}
|
||||
if ( ionloss <= 0.)
|
||||
{
|
||||
ionloss = SmallIonLoss ;
|
||||
}
|
||||
aVector->PutValue(i,ionloss) ;
|
||||
}
|
||||
if ( ionloss <= 0.) ionloss = DBL_MIN ;
|
||||
|
||||
fPAItransferBank->insertAt(i,transferVector) ;
|
||||
aVector->PutValue(i,ionloss) ;
|
||||
|
||||
fPAItransferBank->insertAt(i,transferVector) ;
|
||||
|
||||
// delete[] transferVector ;
|
||||
} // end of Tkin loop
|
||||
theLossTable->insert(aVector);
|
||||
} // end of material loop
|
||||
} // end of Tkin loop
|
||||
theLossTable->insert(aVector);
|
||||
// end of material loop
|
||||
// G4cout<<"G4PAIonisation::BuildPAIonisationTable() have been called"<<G4endl ;
|
||||
// G4cout<<"G4PAIonisation::BuildLossTable() have been called"<<G4endl ;
|
||||
}
|
||||
@@ -492,144 +415,38 @@ G4VParticleChange*
|
||||
G4PAIonisation::PostStepDoIt( const G4Track& trackData,
|
||||
const G4Step& stepData )
|
||||
{
|
||||
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 ;
|
||||
|
||||
G4double Charge;
|
||||
|
||||
G4double kinE, massRatio, scaledTkin, energyTransfer, finalTkin ;
|
||||
|
||||
aParticleChange.Initialize(trackData) ;
|
||||
aMaterial = trackData.GetMaterial() ;
|
||||
aParticle = trackData.GetDynamicParticle() ;
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle() ;
|
||||
|
||||
Charge=aParticle->GetDefinition()->GetPDGCharge();
|
||||
KineticEnergy=aParticle->GetKineticEnergy();
|
||||
ParticleMass=aParticle->GetDefinition()->GetPDGMass();
|
||||
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()];
|
||||
|
||||
betasquare=Psquare/Esquare ; // kinematics
|
||||
|
||||
MaxKineticEnergyTransfer = 2.*electron_mass_c2*Psquare
|
||||
/(summass*summass+2.*electron_mass_c2*KineticEnergy);
|
||||
|
||||
// sampling kinetic energy of the delta ray
|
||||
|
||||
if( MaxKineticEnergyTransfer <= DeltaCutInKineticEnergyNow ) // no change at all
|
||||
if( trackData.GetMaterial()->GetIndex() != fMatIndex )
|
||||
{
|
||||
//return &aParticleChange;
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
else // normal case
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
kinE = aParticle->GetKineticEnergy() ;
|
||||
massRatio = proton_mass_c2/aParticle->GetDefinition()->GetPDGMass() ;
|
||||
scaledTkin = kinE*massRatio ;
|
||||
energyTransfer = GetRandomEnergyTransfer(scaledTkin) ;
|
||||
finalTkin = kinE - energyTransfer ;
|
||||
|
||||
// kill the particle if the kinetic energy <= 0
|
||||
|
||||
if (finalTkin <= 0. )
|
||||
{
|
||||
xc=DeltaCutInKineticEnergyNow/MaxKineticEnergyTransfer ;
|
||||
rate=MaxKineticEnergyTransfer/TotalEnergy ;
|
||||
|
||||
if(aParticle->GetDefinition()->GetPDGSpin() == 1)
|
||||
{
|
||||
te2 = 0.5*rate*rate ;
|
||||
}
|
||||
else
|
||||
{
|
||||
te2 = 0.0 ;
|
||||
}
|
||||
grejc=1.-betasquare*xc+te2*xc*xc ; // sampling follows ...
|
||||
|
||||
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) ;
|
||||
|
||||
|
||||
|
||||
if ( costheta < -1. ) // protection against costheta > 1 or < -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 ;
|
||||
|
||||
if (finalKineticEnergy > 0.)
|
||||
{
|
||||
// changed energy and momentum of the actual particle
|
||||
finalMomentum=sqrt(finalKineticEnergy*
|
||||
(finalKineticEnergy+2.*ParticleMass)) ;
|
||||
|
||||
finalPx = (TotalMomentum*ParticleDirection.x()
|
||||
-DeltaTotalMomentum*DeltaDirection.x())/finalMomentum ;
|
||||
finalPy = (TotalMomentum*ParticleDirection.y()
|
||||
-DeltaTotalMomentum*DeltaDirection.y())/finalMomentum ;
|
||||
finalPz = (TotalMomentum*ParticleDirection.z()
|
||||
-DeltaTotalMomentum*DeltaDirection.z())/finalMomentum ;
|
||||
|
||||
aParticleChange.SetMomentumChange( finalPx,finalPy,finalPz );
|
||||
}
|
||||
else
|
||||
{
|
||||
finalKineticEnergy = 0. ;
|
||||
if (aParticle->GetDefinition()->GetParticleName() == "proton")
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
}
|
||||
aParticleChange.SetEnergyChange( finalKineticEnergy );
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary( theDeltaRay );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
finalTkin = 0.;
|
||||
if (aParticle->GetDefinition()->GetParticleName() == "proton")
|
||||
{
|
||||
aParticleChange.SetStatusChange( fStopAndKill ) ;
|
||||
}
|
||||
else aParticleChange.SetStatusChange( fStopButAlive ) ;
|
||||
}
|
||||
aParticleChange.SetNumberOfSecondaries(0) ;
|
||||
aParticleChange.SetEnergyChange( finalTkin ) ;
|
||||
aParticleChange.SetLocalEnergyDeposit (energyTransfer) ;
|
||||
|
||||
// ResetNumberOfInteractionLengthLeft;
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
// return &aParticleChange ;
|
||||
}
|
||||
|
||||
|
||||
@@ -695,7 +512,7 @@ G4VParticleChange* G4PAIonisation::AlongStepDoIt( const G4Track& trackData,
|
||||
|
||||
// now the loss with fluctuation
|
||||
|
||||
finalT = E-GetLossWithFluct(Step,aParticle,aMaterial)*Chargesquare ;
|
||||
finalT = E-GetLossWithFluct(Step,aParticle,aMaterial) ;
|
||||
|
||||
if (finalT<0.) finalT = 0. ;
|
||||
|
||||
@@ -722,7 +539,7 @@ G4VParticleChange* G4PAIonisation::AlongStepDoIt( const G4Track& trackData,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// Returns random energy loss from step
|
||||
|
||||
G4double
|
||||
G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
@@ -736,19 +553,17 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
|
||||
// G4cout<<"G4VPAIenergyLoss::GetLossWithFluct"<<G4endl ;
|
||||
|
||||
G4double loss = 0.0 ;
|
||||
G4double loss = 0.0, charge2 ;
|
||||
G4double transfer, position, E1, E2, W1, W2, W, firstMu, secondMu ;
|
||||
G4double Tkin = aParticle->GetKineticEnergy() ;
|
||||
G4double MassRatio = proton_mass_c2/aParticle->GetDefinition()->GetPDGMass() ;
|
||||
G4double charge = aParticle->GetDefinition()->GetPDGCharge() ;
|
||||
charge2 = charge*charge ;
|
||||
G4double TkinScaled = Tkin*MassRatio ;
|
||||
G4PhysicsLogVector*
|
||||
aLogVector = new G4PhysicsLogVector( G4PAIonisation::GetMinKineticEnergy(),
|
||||
G4PAIonisation::GetMaxKineticEnergy(),
|
||||
G4PAIonisation::GetBinNumber() ) ;
|
||||
|
||||
for(iTkin=0;iTkin<G4PAIonisation::GetBinNumber();iTkin++)
|
||||
{
|
||||
if(TkinScaled < aLogVector->GetLowEdgeEnergy(iTkin)) // <= ?
|
||||
if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) // <= ?
|
||||
{
|
||||
break ;
|
||||
}
|
||||
@@ -757,13 +572,11 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
|
||||
// G4cout<<"iPlace = "<<iPlace<<endl ;
|
||||
|
||||
G4PhysicsVector* firstVector = (*fPAItransferBank)(iPlace) ;
|
||||
G4PhysicsVector* secondVector = (*fPAItransferBank)(iPlace + 1) ;
|
||||
|
||||
if(iTkin == G4PAIonisation::GetBinNumber()) // Fermi plato, try from left
|
||||
{
|
||||
numOfCollisions = RandPoisson::shoot((*(*fPAItransferBank)(iPlace))(0)*Step) ;
|
||||
|
||||
numOfCollisions = RandPoisson::
|
||||
shoot((*(*fPAItransferBank)(iPlace))(0)*Step*charge2) ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
@@ -774,7 +587,8 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace))(iTransfer)) break ;
|
||||
}
|
||||
loss += (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
// loss += (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
loss += GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
@@ -783,7 +597,7 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
if(iTkin == 0) // Tkin is too small, trying from right only
|
||||
{
|
||||
numOfCollisions = RandPoisson::
|
||||
shoot((*(*fPAItransferBank)(iPlace+1))(0)*Step) ;
|
||||
shoot((*(*fPAItransferBank)(iPlace+1))(0)*Step*charge2) ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
@@ -795,14 +609,15 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace+1))(iTransfer)) break ;
|
||||
}
|
||||
loss += (*fPAItransferBank)(iPlace+1)->GetLowEdgeEnergy(iTransfer) ;
|
||||
// loss += (*fPAItransferBank)(iPlace+1)->GetLowEdgeEnergy(iTransfer) ;
|
||||
loss += GetEnergyTransfer(iPlace+1,position,iTransfer);
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
else // general case: Tkin between two vectors of the material
|
||||
{
|
||||
E1 = aLogVector->GetLowEdgeEnergy(iTkin - 1) ;
|
||||
E2 = aLogVector->GetLowEdgeEnergy(iTkin) ;
|
||||
E1 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin - 1) ;
|
||||
E2 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin) ;
|
||||
W = 1.0/(E2 - E1) ;
|
||||
W1 = (E2 - TkinScaled)*W ;
|
||||
W2 = (TkinScaled - E1)*W ;
|
||||
@@ -814,8 +629,7 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
|
||||
numOfCollisions = RandPoisson::shoot(
|
||||
( (*(*fPAItransferBank)(iPlace))(0)*W1 +
|
||||
(*(*fPAItransferBank)(iPlace+1))(0)*W2 )*Step) ;
|
||||
|
||||
(*(*fPAItransferBank)(iPlace+1))(0)*W2 )*Step*charge2) ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<endl ;
|
||||
|
||||
@@ -835,7 +649,8 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
break ;
|
||||
}
|
||||
}
|
||||
loss += (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
// loss += (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
loss += GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
@@ -845,7 +660,125 @@ G4PAIonisation::GetLossWithFluct( G4double Step,
|
||||
return loss ;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns random PAI energy transfer according to passed scaled kinetic
|
||||
// energy of particle
|
||||
|
||||
G4double
|
||||
G4PAIonisation::GetRandomEnergyTransfer( G4double scaledTkin )
|
||||
{
|
||||
// G4cout<<"G4VPAIenergyLoss::GetRandomEnergyTransfer"<<G4endl ;
|
||||
|
||||
G4int iTkin, iTransfer, iPlace ;
|
||||
G4double transfer = 0.0, position, E1, E2, W1, W2, W ;
|
||||
|
||||
for(iTkin=0;iTkin<G4PAIonisation::GetBinNumber();iTkin++)
|
||||
{
|
||||
if(scaledTkin < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
|
||||
}
|
||||
iPlace = iTkin - 1 ;
|
||||
|
||||
// G4cout<<"iPlace = "<<iPlace<<endl ;
|
||||
|
||||
if(iTkin == G4PAIonisation::GetBinNumber()) // Fermi plato, try from left
|
||||
{
|
||||
position = (*(*fPAItransferBank)(iPlace))(0)*G4UniformRand() ;
|
||||
|
||||
for(iTransfer=0;;iTransfer++)
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace))(iTransfer)) break ;
|
||||
}
|
||||
// transfer = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
transfer = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(iTkin == 0) // Tkin is too small, trying from right only
|
||||
{
|
||||
position = (*(*fPAItransferBank)(iPlace+1))(0)*G4UniformRand() ;
|
||||
|
||||
for(iTransfer=0;;iTransfer++)
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace+1))(iTransfer)) break ;
|
||||
}
|
||||
// transfer = (*fPAItransferBank)(iPlace+1)->GetLowEdgeEnergy(iTransfer) ;
|
||||
transfer = GetEnergyTransfer(iPlace+1,position,iTransfer);
|
||||
}
|
||||
else // general case: Tkin between two vectors of the material
|
||||
{
|
||||
E1 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin - 1) ;
|
||||
E2 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin) ;
|
||||
W = 1.0/(E2 - E1) ;
|
||||
W1 = (E2 - scaledTkin)*W ;
|
||||
W2 = (scaledTkin - E1)*W ;
|
||||
|
||||
position =( (*(*fPAItransferBank)(iPlace))(0)*W1 +
|
||||
(*(*fPAItransferBank)(iPlace+1))(0)*W2 )*G4UniformRand() ;
|
||||
|
||||
// G4cout<<position<<"\t" ;
|
||||
|
||||
for(iTransfer=0;;iTransfer++)
|
||||
{
|
||||
if( position >=
|
||||
( (*(*fPAItransferBank)(iPlace))(iTransfer)*W1 +
|
||||
(*(*fPAItransferBank)(iPlace+1))(iTransfer)*W2) ) break ;
|
||||
}
|
||||
// transfer = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
transfer = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
}
|
||||
}
|
||||
// G4cout<<"PAI transfer = "<<transfer/keV<<" keV"<<endl ;
|
||||
if(transfer < 0.0 ) transfer = 0.0 ;
|
||||
return transfer ;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns random PAI energy transfer according to passed scaled kinetic
|
||||
// energy of particle
|
||||
|
||||
G4double
|
||||
G4PAIonisation::GetEnergyTransfer( G4int iPlace, G4double position, G4int iTransfer )
|
||||
{
|
||||
G4double x1, x2, y1, y2, result ;
|
||||
|
||||
if(iTransfer == 0)
|
||||
{
|
||||
result = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1 = (*(*fPAItransferBank)(iPlace))(iTransfer-1) ;
|
||||
y2 = (*(*fPAItransferBank)(iPlace))(iTransfer) ;
|
||||
|
||||
x1 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
|
||||
x2 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
|
||||
if ( x1 == x2 ) result = x2 ;
|
||||
else
|
||||
{
|
||||
if ( y1 == y2 ) result = x1 + (x2 - x1)*G4UniformRand() ;
|
||||
else
|
||||
{
|
||||
result = x1 + (position - y1)*(x2 - x1)/(y2 - y1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4PAIxSection.cc,v 1.4 1999/12/15 14:51:51 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// GEANT4 tag $Name: geant4-03-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.9 1999/12/15 14:51:52 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4PhotoElectricEffect.cc,v 1.11 2000/06/22 08:57:11 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -33,6 +33,8 @@
|
||||
// 06-01-99, use Sandia crossSection below 50 keV, V.Grichine mma
|
||||
// 20-05-99, protection against very low energy photons ,L.Urban
|
||||
// 08-06-99, removed this above protection from the DoIt. mma
|
||||
// 21-06-00, in DoIt, killing photon: aParticleChange.SetEnergyChange(0.); mma
|
||||
// 22-06-00, in DoIt, absorbe very low energy photon (back to 20-05-99); mma
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4PhotoElectricEffect.hh"
|
||||
@@ -242,9 +244,10 @@ G4VParticleChange* G4PhotoElectricEffect::PostStepDoIt(const G4Track& aTrack,
|
||||
G4int NbOfShells = anElement->GetNbOfAtomicShells();
|
||||
G4int i=0;
|
||||
while ((i<NbOfShells)&&(PhotonEnergy<anElement->GetAtomicShell(i))) i++;
|
||||
if (i==NbOfShells) return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
|
||||
|
||||
G4double ElecKineEnergy = PhotonEnergy - anElement->GetAtomicShell(i);
|
||||
G4double BindingEnergy = 0.;
|
||||
if (i<NbOfShells) BindingEnergy = anElement->GetAtomicShell(i);
|
||||
|
||||
G4double ElecKineEnergy = PhotonEnergy - BindingEnergy;
|
||||
if ((G4EnergyLossTables::GetRange(G4Electron::Electron(),
|
||||
ElecKineEnergy,aMaterial)>aStep.GetPostStepPoint()->GetSafety())
|
||||
||
|
||||
@@ -266,7 +269,8 @@ G4VParticleChange* G4PhotoElectricEffect::PostStepDoIt(const G4Track& aTrack,
|
||||
//
|
||||
// Kill the incident photon
|
||||
//
|
||||
aParticleChange.SetLocalEnergyDeposit(PhotonEnergy-ElecKineEnergy);
|
||||
aParticleChange.SetLocalEnergyDeposit(PhotonEnergy-ElecKineEnergy);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
|
||||
@@ -5,19 +5,17 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4PolarizedComptonScattering.cc,v 1.2 1999/12/15 14:51:52 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4PolarizedComptonScattering.cc,v 1.4 2000/11/17 15:03:18 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
//
|
||||
//---------- G4PolarizedComptonScattering physics process -------
|
||||
// by Vicente Lara, March 1998
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
// CERN Geneva Switzerland
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, IT Division, ASD group
|
||||
//
|
||||
// ---------- G4PolarizedComptonScattering physics process --------
|
||||
// by Vicente Lara, March 1998
|
||||
// **************************************************************
|
||||
// Corrections by Rui Curado da Silva (Nov. 2000)
|
||||
// - Sampling of Phi
|
||||
// - Depolarization probability
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -50,6 +48,7 @@ G4VParticleChange* G4PolarizedComptonScattering::PostStepDoIt(const G4Track& aTr
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
|
||||
G4ThreeVector GammaPolarization0 = aDynamicGamma->GetPolarization();
|
||||
|
||||
if (abs(GammaPolarization0.mag() - 1.e0) > 1.e-14)
|
||||
G4ComptonScattering::PostStepDoIt(aTrack,aStep);
|
||||
|
||||
@@ -81,14 +80,49 @@ G4VParticleChange* G4PolarizedComptonScattering::PostStepDoIt(const G4Track& aTr
|
||||
greject = 1. - epsilon*sint2/(1.+ epsilonsq);
|
||||
} while (greject < G4UniformRand());
|
||||
|
||||
|
||||
|
||||
// ****************************************************
|
||||
// Phi determination
|
||||
// ****************************************************
|
||||
|
||||
|
||||
G4double middle;
|
||||
G4double maximum, minimum;
|
||||
G4double resolution;
|
||||
|
||||
G4double Rand = G4UniformRand();
|
||||
|
||||
minimum = 0.;
|
||||
middle = 0.;
|
||||
maximum = twopi;
|
||||
resolution = 0.001;
|
||||
|
||||
|
||||
int j = 0;
|
||||
while ((j < 100) && (abs(SetPhi(epsilon,sint2,middle,Rand)) > resolution))
|
||||
{
|
||||
middle = (maximum + minimum)/2;
|
||||
if (SetPhi(epsilon,sint2,middle,Rand)*SetPhi(epsilon,sint2,minimum,Rand)<0) {
|
||||
maximum = middle;
|
||||
} else {
|
||||
minimum = middle;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// scattered gamma angles. ( Z - axis along the parent gamma)
|
||||
//
|
||||
|
||||
G4double cosTeta = 1. - onecost , sinTeta = sqrt (sint2);
|
||||
G4double Phi = twopi * G4UniformRand() ;
|
||||
G4double Phi = middle;
|
||||
G4double dirx = sinTeta*cos(Phi) , diry = sinTeta*sin(Phi) , dirz = cosTeta ;
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
//
|
||||
@@ -103,6 +137,8 @@ G4VParticleChange* G4PolarizedComptonScattering::PostStepDoIt(const G4Track& aTr
|
||||
// Set new direction
|
||||
G4ThreeVector GammaDirection1 ( dirx,diry,dirz );
|
||||
|
||||
|
||||
|
||||
// Change reference frame.
|
||||
SystemOfRefChange(GammaDirection0,GammaDirection1,
|
||||
GammaPolarization0,GammaPolarization1);
|
||||
@@ -151,6 +187,20 @@ G4VParticleChange* G4PolarizedComptonScattering::PostStepDoIt(const G4Track& aTr
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4PolarizedComptonScattering::SetPhi(G4double EnergyRate,
|
||||
G4double sinsqrth,
|
||||
G4double phi,
|
||||
G4double rand)
|
||||
{
|
||||
G4double cosphi = cos(phi), sinphi = sin(phi);
|
||||
|
||||
G4double PhiDetermination = ((twopi*rand - phi)*(EnergyRate + 1./EnergyRate - sinsqrth)) + (sinsqrth*sinphi*cosphi);
|
||||
|
||||
return PhiDetermination;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4ThreeVector G4PolarizedComptonScattering::SetNewPolarization(G4double EnergyRate,
|
||||
@@ -160,19 +210,21 @@ G4ThreeVector G4PolarizedComptonScattering::SetNewPolarization(G4double EnergyRa
|
||||
G4ThreeVector& GammaPolarization0)
|
||||
{
|
||||
G4double cosphi = cos(phi), sinphi = sin(phi);
|
||||
G4double ParallelIntensityPolar = EnergyRate + 1./EnergyRate + 2. - 4.*sinsqrth*cosphi*cosphi;
|
||||
// G4double ParallelIntensityPolar = EnergyRate + 1./EnergyRate + 2. - 4.*sinsqrth*cosphi*cosphi;
|
||||
G4double ParallelIntensityPolar = EnergyRate + 1./EnergyRate - 2.*sinsqrth*cosphi*cosphi;
|
||||
G4double PerpendiIntensityPolar = EnergyRate + 1./EnergyRate - 2.;
|
||||
G4double PolarizationDegree = sqrt(sinsqrth*sinphi*sinphi + costheta*costheta);
|
||||
G4double sintheta = sqrt(sinsqrth);
|
||||
|
||||
G4ThreeVector GammaPolarization1;
|
||||
// depolarization probability (1-P)
|
||||
if ( G4UniformRand() > 0.5*(PerpendiIntensityPolar/ParallelIntensityPolar) )
|
||||
if ( G4UniformRand() > (PerpendiIntensityPolar/ParallelIntensityPolar) )
|
||||
{
|
||||
// Parallel to initial polarization
|
||||
GammaPolarization1.setX(PolarizationDegree);
|
||||
GammaPolarization1.setY(-sinsqrth*sinphi*cosphi/PolarizationDegree);
|
||||
GammaPolarization1.setZ(-sintheta*costheta*cosphi/PolarizationDegree);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -180,6 +232,7 @@ G4ThreeVector G4PolarizedComptonScattering::SetNewPolarization(G4double EnergyRa
|
||||
GammaPolarization1.setX(0.);
|
||||
GammaPolarization1.setY(costheta/PolarizationDegree);
|
||||
GammaPolarization1.setZ(-sintheta*sinphi/PolarizationDegree);
|
||||
|
||||
};
|
||||
|
||||
return GammaPolarization1;
|
||||
@@ -196,6 +249,8 @@ void G4PolarizedComptonScattering::SystemOfRefChange(G4ThreeVector& Direction0,
|
||||
G4double cosTeta0 = Direction0.cosTheta(), sinTeta0 = sin(Direction0.theta());
|
||||
G4double cosPhi0 = cos(Direction0.phi()), sinPhi0 = sin(Direction0.phi());
|
||||
|
||||
|
||||
|
||||
G4double cosPsi, sinPsi;
|
||||
|
||||
if (sinTeta0 != 0. ) {
|
||||
@@ -218,7 +273,6 @@ void G4PolarizedComptonScattering::SystemOfRefChange(G4ThreeVector& Direction0,
|
||||
Direction1.rotateUz(Direction0);
|
||||
aParticleChange.SetMomentumChange( Direction1 ) ;
|
||||
|
||||
|
||||
// 3 Euler angles rotation for scattered photon polarization
|
||||
Polarization1.rotateZ(Psi);
|
||||
Polarization1.rotateUz(Direction0);
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4SynchrotronRadiation.cc,v 1.2 1999/12/15 14:51:52 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4SynchrotronRadiation.cc,v 1.3 2000/11/01 15:30:46 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -87,7 +87,7 @@ G4SynchrotronRadiation::PostStepDoIt(const G4Track& trackData,
|
||||
|
||||
G4bool FieldExists = globalFieldMgr->DoesFieldExist() ;
|
||||
G4ThreeVector FieldValue;
|
||||
G4Field* pField = 0 ;
|
||||
const G4Field* pField = 0 ;
|
||||
if (FieldExists)
|
||||
{
|
||||
pField = globalFieldMgr->GetDetectorField() ;
|
||||
@@ -218,7 +218,7 @@ G4SynchrotronRadiation::GetPhotonEnergy( const G4Track& trackData,
|
||||
|
||||
G4bool FieldExists = globalFieldMgr->DoesFieldExist() ;
|
||||
G4ThreeVector FieldValue;
|
||||
G4Field* pField = 0 ;
|
||||
const G4Field* pField = 0 ;
|
||||
if (FieldExists)
|
||||
{
|
||||
pField = globalFieldMgr->GetDetectorField() ;
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4VIeEnergyLoss.cc,v 1.1 2000/04/25 14:33:09 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4VIeEnergyLoss.cc,v 1.3 2000/08/15 09:42:45 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
// $Id:
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, IT Division, ASD group
|
||||
// GEANT4 Collaboration
|
||||
// History: based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ---------- G4VIeEnergyLoss physics process -----------
|
||||
@@ -1017,7 +1017,7 @@ G4VParticleChange* G4VIeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
if ((EnlossFlucFlag) && (finalT > 0.) && (finalT < E)&&(E > LowestKineticEnergy))
|
||||
|
||||
{
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,MeanLoss);
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,1.,MeanLoss,Step);
|
||||
if (finalT < 0.) finalT = E-MeanLoss;
|
||||
}
|
||||
}
|
||||
@@ -1041,141 +1041,224 @@ G4VParticleChange* G4VIeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
|
||||
G4double G4VIeEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial,
|
||||
G4double MeanLoss)
|
||||
// calculate actual loss from the mean loss
|
||||
// The model used to get the fluctuation is the same as in Glandz in Geant3.
|
||||
G4double ChargeSquare,
|
||||
G4double MeanLoss,
|
||||
G4double step )
|
||||
{
|
||||
static const G4double Tlow=10.*keV ;
|
||||
// calculate actual loss from the mean loss
|
||||
// The model used to get the fluctuation is essentially the same as in Glandz in Geant3.
|
||||
|
||||
static const G4double minLoss = 1.*eV ;
|
||||
static const G4double probLim = 0.01 ;
|
||||
static const G4double sumaLim = -log(probLim) ;
|
||||
static const G4double alim=10.;
|
||||
static const G4double kappa = 10. ;
|
||||
static const G4double factor = twopi_mc2_rcl2 ;
|
||||
|
||||
|
||||
// check if the material has changed ( cache mechanism)
|
||||
|
||||
if (aMaterial != lastMaterial)
|
||||
{
|
||||
lastMaterial = aMaterial;
|
||||
imat = aMaterial->GetIndex();
|
||||
f1Fluct = aMaterial->GetIonisation()->GetF1fluct();
|
||||
f2Fluct = aMaterial->GetIonisation()->GetF2fluct();
|
||||
e1Fluct = aMaterial->GetIonisation()->GetEnergy1fluct();
|
||||
e2Fluct = aMaterial->GetIonisation()->GetEnergy2fluct();
|
||||
e1LogFluct = aMaterial->GetIonisation()->GetLogEnergy1fluct();
|
||||
e2LogFluct = aMaterial->GetIonisation()->GetLogEnergy2fluct();
|
||||
rateFluct = aMaterial->GetIonisation()->GetRateionexcfluct();
|
||||
ipotFluct = aMaterial->GetIonisation()->GetMeanExcitationEnergy();
|
||||
ipotLogFluct = aMaterial->GetIonisation()->GetLogMeanExcEnergy();
|
||||
imat = aMaterial->GetIndex();
|
||||
f1Fluct = aMaterial->GetIonisation()->GetF1fluct();
|
||||
f2Fluct = aMaterial->GetIonisation()->GetF2fluct();
|
||||
e1Fluct = aMaterial->GetIonisation()->GetEnergy1fluct();
|
||||
e2Fluct = aMaterial->GetIonisation()->GetEnergy2fluct();
|
||||
e1LogFluct = aMaterial->GetIonisation()->GetLogEnergy1fluct();
|
||||
e2LogFluct = aMaterial->GetIonisation()->GetLogEnergy2fluct();
|
||||
rateFluct = aMaterial->GetIonisation()->GetRateionexcfluct();
|
||||
ipotFluct = aMaterial->GetIonisation()->GetMeanExcitationEnergy();
|
||||
ipotLogFluct = aMaterial->GetIonisation()->GetLogMeanExcEnergy();
|
||||
}
|
||||
|
||||
G4double threshold,w1,w2,w3,lnw3,C,prob,
|
||||
beta2,suma,e0,Em,loss,lossc ,w;
|
||||
G4double threshold,w1,w2,C,
|
||||
beta2,suma,e0,loss,lossc ,w,electronDensity;
|
||||
G4double a1,a2,a3;
|
||||
G4long p1,p2,p3;
|
||||
G4int p1,p2,p3;
|
||||
G4int nb;
|
||||
G4double Corrfac, na,alfa,rfac,namean,sa,alfa1,ea,sea;
|
||||
G4double dp1,dnmaxDirectFluct,dp3,dnmaxCont2;
|
||||
G4double dp1,dp3;
|
||||
G4double siga ;
|
||||
|
||||
// shortcut for very very small loss
|
||||
if(MeanLoss < minLoss) return MeanLoss ;
|
||||
|
||||
// get particle data
|
||||
G4double Tkin = aParticle->GetKineticEnergy();
|
||||
G4double charge = aParticle->GetDefinition()->GetPDGCharge();
|
||||
if (charge<0.) threshold =((*G4Electron::Electron()).GetCutsInEnergy())[imat];
|
||||
else threshold =((*G4Positron::Positron()).GetCutsInEnergy())[imat];
|
||||
G4double Tkin = aParticle->GetKineticEnergy();
|
||||
ParticleMass = aParticle->GetMass() ;
|
||||
|
||||
threshold =((*G4Electron::Electron()).GetCutsInEnergy())[imat];
|
||||
G4double rmass = electron_mass_c2/ParticleMass;
|
||||
G4double tau = Tkin/ParticleMass, tau1 = tau+1., tau2 = tau*(tau+2.);
|
||||
G4double Tm = 2.*electron_mass_c2*tau2/(1.+2.*tau1*rmass+rmass*rmass)
|
||||
-ipotFluct;
|
||||
if (Tm < 0.) Tm = 0.;
|
||||
else if (Tm > threshold) Tm = threshold;
|
||||
G4double tau = Tkin/ParticleMass, tau1 = tau+1., tau2 = tau*(tau+2.);
|
||||
G4double Tm = 2.*electron_mass_c2*tau2/(1.+2.*tau1*rmass+rmass*rmass);
|
||||
|
||||
w1 = Tm+ipotFluct;
|
||||
w2 = w1/ipotFluct;
|
||||
w3 = 2.*electron_mass_c2*tau2;
|
||||
lnw3 = log(w3);
|
||||
if (Tm <= ipotFluct) Tm = ipotFluct ;
|
||||
|
||||
if(Tm > threshold) Tm = threshold;
|
||||
beta2 = tau2/(tau1*tau1);
|
||||
|
||||
C = (1.-rateFluct)*MeanLoss/(lnw3-ipotLogFluct-beta2);
|
||||
// Gaussian fluctuation ?
|
||||
if(MeanLoss >= kappa*Tm)
|
||||
{
|
||||
electronDensity = aMaterial->GetElectronDensity() ;
|
||||
siga = sqrt(MeanLoss*Tm*(0.5-0.25*beta2)*step*
|
||||
factor*electronDensity*ChargeSquare/beta2) ;
|
||||
loss = G4RandGauss::shoot(MeanLoss,siga) ;
|
||||
if(loss < 0.) loss = 0. ;
|
||||
return loss ;
|
||||
}
|
||||
|
||||
w1 = Tm/ipotFluct;
|
||||
w2 = log(2.*electron_mass_c2*tau2);
|
||||
|
||||
C = MeanLoss*(1.-rateFluct)/(w2-ipotLogFluct-beta2);
|
||||
|
||||
a1 = C*f1Fluct*(w2-e1LogFluct-beta2)/e1Fluct;
|
||||
a2 = C*f2Fluct*(w2-e2LogFluct-beta2)/e2Fluct;
|
||||
if(Tm > ipotFluct)
|
||||
a3 = rateFluct*MeanLoss*(Tm-ipotFluct)/(ipotFluct*Tm*log(w1));
|
||||
else
|
||||
{
|
||||
a1 /= 1.-rateFluct ;
|
||||
a2 /= 1.-rateFluct ;
|
||||
a3 = 0. ;
|
||||
}
|
||||
|
||||
a1 = C*f1Fluct*(lnw3-e1LogFluct-beta2)/e1Fluct;
|
||||
a2 = C*f2Fluct*(lnw3-e2LogFluct-beta2)/e2Fluct;
|
||||
if (Tm > 0.) a3 = rateFluct*MeanLoss*Tm/(ipotFluct*w1*log(w2));
|
||||
else { a1 /= rateFluct; a2 /= rateFluct; a3 = 0.;}
|
||||
suma = a1+a2+a3;
|
||||
|
||||
//no fluctuation if the loss is too big
|
||||
if (suma > MaxExcitationNumber) return MeanLoss;
|
||||
|
||||
suma<50.? prob = exp(-suma) : prob = 0.;
|
||||
loss = 0. ;
|
||||
|
||||
if (prob > probLimFluct) // very small Step
|
||||
if(suma < sumaLim) // very small Step
|
||||
{
|
||||
e0 = aMaterial->GetIonisation()->GetEnergy0fluct();
|
||||
if (Tm <= 0.)
|
||||
{
|
||||
a1 = MeanLoss/e0;
|
||||
p1 = G4Poisson(a1);
|
||||
loss = p1*e0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
Em = Tm+e0;
|
||||
a1 = MeanLoss*(Em-e0)/(Em*e0*log(Em/e0));
|
||||
p1 = G4Poisson(a1);
|
||||
w = (Em-e0)/Em;
|
||||
// just to save time
|
||||
if (p1 > nmaxDirectFluct)
|
||||
{
|
||||
dp1 = p1;
|
||||
dnmaxDirectFluct=nmaxDirectFluct;
|
||||
Corrfac = dp1/dnmaxDirectFluct;
|
||||
p1 = nmaxDirectFluct;
|
||||
}
|
||||
else Corrfac = 1.;
|
||||
e0 = aMaterial->GetIonisation()->GetEnergy0fluct();
|
||||
|
||||
loss = 0.;
|
||||
for (long i=0; i<p1; i++) loss += 1./(1.-w*G4UniformRand());
|
||||
loss *= (e0*Corrfac);
|
||||
if(Tm == ipotFluct)
|
||||
{
|
||||
a3 = MeanLoss/e0;
|
||||
|
||||
}
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = G4std::max(0,int(G4RandGauss::shoot(a3,siga)+0.5));
|
||||
}
|
||||
p3 = G4Poisson(a3);
|
||||
|
||||
loss = p3*e0 ;
|
||||
|
||||
if(p3 > 0)
|
||||
loss += (1.-2.*G4UniformRand())*e0 ;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Tm = Tm-ipotFluct+e0 ;
|
||||
a3 = MeanLoss*(Tm-e0)/(Tm*e0*log(Tm/e0));
|
||||
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = G4std::max(0,int(G4RandGauss::shoot(a3,siga)+0.5));
|
||||
}
|
||||
else
|
||||
p3 = G4Poisson(a3);
|
||||
|
||||
if(p3 > 0)
|
||||
{
|
||||
w = (Tm-e0)/Tm ;
|
||||
if(p3 > nmaxCont2)
|
||||
{
|
||||
dp3 = G4float(p3) ;
|
||||
Corrfac = dp3/G4float(nmaxCont2) ;
|
||||
p3 = nmaxCont2 ;
|
||||
}
|
||||
else
|
||||
Corrfac = 1. ;
|
||||
|
||||
for(G4int i=0; i<p3; i++) loss += 1./(1.-w*G4UniformRand()) ;
|
||||
loss *= e0*Corrfac ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else // not so small Step
|
||||
|
||||
else // not so small Step
|
||||
{
|
||||
p1 = G4Poisson(a1);
|
||||
p2 = G4Poisson(a2);
|
||||
loss = p1*e1Fluct+p2*e2Fluct;
|
||||
if (loss>0.) loss += (1.-2.*G4UniformRand())*e1Fluct;
|
||||
p3 = G4Poisson(a3);
|
||||
// excitation type 1
|
||||
if(a1>alim)
|
||||
{
|
||||
siga=sqrt(a1) ;
|
||||
p1 = G4std::max(0,int(G4RandGauss::shoot(a1,siga)+0.5));
|
||||
}
|
||||
else
|
||||
p1 = G4Poisson(a1);
|
||||
|
||||
lossc = 0.; na = 0.; alfa = 1.;
|
||||
if (p3 > nmaxCont2)
|
||||
{
|
||||
dp3 = p3;
|
||||
dnmaxCont2 = nmaxCont2;
|
||||
rfac = dp3/(dnmaxCont2+dp3);
|
||||
namean = p3*rfac;
|
||||
sa = nmaxCont1*rfac;
|
||||
na = RandGauss::shoot(namean,sa);
|
||||
// excitation type 2
|
||||
if(a2>alim)
|
||||
{
|
||||
siga=sqrt(a2) ;
|
||||
p2 = G4std::max(0,int(G4RandGauss::shoot(a2,siga)+0.5));
|
||||
}
|
||||
else
|
||||
p2 = G4Poisson(a2);
|
||||
|
||||
loss = p1*e1Fluct+p2*e2Fluct;
|
||||
|
||||
// smearing to avoid unphysical peaks
|
||||
if(p2 > 0)
|
||||
loss += (1.-2.*G4UniformRand())*e2Fluct;
|
||||
else if (loss>0.)
|
||||
loss += (1.-2.*G4UniformRand())*e1Fluct;
|
||||
|
||||
// ionisation .......................................
|
||||
if(a3 > 0.)
|
||||
{
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = G4std::max(0,int(G4RandGauss::shoot(a3,siga)+0.5));
|
||||
}
|
||||
else
|
||||
p3 = G4Poisson(a3);
|
||||
|
||||
lossc = 0.;
|
||||
if(p3 > 0)
|
||||
{
|
||||
na = 0.;
|
||||
alfa = 1.;
|
||||
if (p3 > nmaxCont2)
|
||||
{
|
||||
dp3 = G4float(p3);
|
||||
rfac = dp3/(G4float(nmaxCont2)+dp3);
|
||||
namean = G4float(p3)*rfac;
|
||||
sa = G4float(nmaxCont1)*rfac;
|
||||
na = G4RandGauss::shoot(namean,sa);
|
||||
if (na > 0.)
|
||||
{
|
||||
alfa = w2*(nmaxCont2+p3)/(w2*nmaxCont2+p3);
|
||||
alfa1 = alfa*log(alfa)/(alfa-1.);
|
||||
ea = na*ipotFluct*alfa1;
|
||||
sea = ipotFluct*sqrt(na*(alfa-alfa1*alfa1));
|
||||
lossc += RandGauss::shoot(ea,sea);
|
||||
}
|
||||
{
|
||||
alfa = w1*G4float(nmaxCont2+p3)/(w1*G4float(nmaxCont2)+G4float(p3));
|
||||
alfa1 = alfa*log(alfa)/(alfa-1.);
|
||||
ea = na*ipotFluct*alfa1;
|
||||
sea = ipotFluct*sqrt(na*(alfa-alfa1*alfa1));
|
||||
lossc += G4RandGauss::shoot(ea,sea);
|
||||
}
|
||||
}
|
||||
|
||||
nb = G4int(p3-na);
|
||||
if (nb > 0)
|
||||
{
|
||||
nb = G4int(G4float(p3)-na);
|
||||
if (nb > 0)
|
||||
{
|
||||
w2 = alfa*ipotFluct;
|
||||
w = (w1-w2)/w1;
|
||||
for (G4int k=0; k<nb; k++) lossc += w2/(1.-w*G4UniformRand());
|
||||
}
|
||||
|
||||
loss += lossc;
|
||||
}
|
||||
w = (Tm-w2)/Tm;
|
||||
for (G4int k=0; k<nb; k++) lossc += w2/(1.-w*G4UniformRand());
|
||||
|
||||
}
|
||||
}
|
||||
loss += lossc;
|
||||
}
|
||||
}
|
||||
|
||||
return loss ;
|
||||
}
|
||||
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4VIhEnergyLoss.cc,v 1.1 2000/04/25 14:33:10 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4VIhEnergyLoss.cc,v 1.3 2000/08/15 09:42:45 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
// $Id:
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// For information related to this code contact:
|
||||
// CERN, IT Division, ASD group
|
||||
// GEANT4 Collaboration
|
||||
// History: based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ---------- G4VIhEnergyLoss physics process -----------
|
||||
@@ -1147,7 +1147,7 @@ G4VParticleChange* G4VIhEnergyLoss::AlongStepDoIt(
|
||||
if ((EnlossFlucFlag) && (finalT > 0.) && (finalT < E)&&(E > LowestKineticEnergy))
|
||||
{
|
||||
MeanLoss /= ChargeSquare ;
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,MeanLoss)*ChargeSquare ;
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,ChargeSquare,MeanLoss,Step)*ChargeSquare ;
|
||||
if (finalT < 0.) finalT = 0. ;
|
||||
}
|
||||
|
||||
@@ -1168,141 +1168,236 @@ G4VParticleChange* G4VIhEnergyLoss::AlongStepDoIt(
|
||||
return &aParticleChange ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VIhEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial,
|
||||
G4double MeanLoss)
|
||||
// calculate actual loss from the mean loss
|
||||
// The model used to get the fluctuation is the same as in Glandz in Geant3.
|
||||
G4Material* aMaterial,
|
||||
G4double ChargeSquare,
|
||||
G4double MeanLoss,
|
||||
G4double step )
|
||||
{
|
||||
static const G4double Tlow=10.*keV ;
|
||||
// calculate actual loss from the mean loss
|
||||
// The model used to get the fluctuation is essentially the same as in Glandz in Geant3.
|
||||
|
||||
static const G4double minLoss = 1.*eV ;
|
||||
static const G4double probLim = 0.01 ;
|
||||
static const G4double sumaLim = -log(probLim) ;
|
||||
static const G4double alim=10.;
|
||||
static const G4double kappa = 10. ;
|
||||
static const G4double factor = twopi_mc2_rcl2 ;
|
||||
|
||||
|
||||
// check if the material has changed ( cache mechanism)
|
||||
|
||||
if (aMaterial != lastMaterial)
|
||||
{
|
||||
lastMaterial = aMaterial;
|
||||
imat = aMaterial->GetIndex();
|
||||
f1Fluct = aMaterial->GetIonisation()->GetF1fluct();
|
||||
f2Fluct = aMaterial->GetIonisation()->GetF2fluct();
|
||||
e1Fluct = aMaterial->GetIonisation()->GetEnergy1fluct();
|
||||
e2Fluct = aMaterial->GetIonisation()->GetEnergy2fluct();
|
||||
e1LogFluct = aMaterial->GetIonisation()->GetLogEnergy1fluct();
|
||||
e2LogFluct = aMaterial->GetIonisation()->GetLogEnergy2fluct();
|
||||
rateFluct = aMaterial->GetIonisation()->GetRateionexcfluct();
|
||||
ipotFluct = aMaterial->GetIonisation()->GetMeanExcitationEnergy();
|
||||
ipotLogFluct = aMaterial->GetIonisation()->GetLogMeanExcEnergy();
|
||||
imat = aMaterial->GetIndex();
|
||||
f1Fluct = aMaterial->GetIonisation()->GetF1fluct();
|
||||
f2Fluct = aMaterial->GetIonisation()->GetF2fluct();
|
||||
e1Fluct = aMaterial->GetIonisation()->GetEnergy1fluct();
|
||||
e2Fluct = aMaterial->GetIonisation()->GetEnergy2fluct();
|
||||
e1LogFluct = aMaterial->GetIonisation()->GetLogEnergy1fluct();
|
||||
e2LogFluct = aMaterial->GetIonisation()->GetLogEnergy2fluct();
|
||||
rateFluct = aMaterial->GetIonisation()->GetRateionexcfluct();
|
||||
ipotFluct = aMaterial->GetIonisation()->GetMeanExcitationEnergy();
|
||||
ipotLogFluct = aMaterial->GetIonisation()->GetLogMeanExcEnergy();
|
||||
}
|
||||
|
||||
G4double threshold,w1,w2,w3,lnw3,C,prob,
|
||||
beta2,suma,e0,Em,loss,lossc ,w;
|
||||
G4double threshold,w1,w2,C,
|
||||
beta2,suma,e0,loss,lossc ,w,electronDensity;
|
||||
G4double a1,a2,a3;
|
||||
G4long p1,p2,p3;
|
||||
G4int p1,p2,p3;
|
||||
G4int nb;
|
||||
G4double Corrfac, na,alfa,rfac,namean,sa,alfa1,ea,sea;
|
||||
G4double dp1,dnmaxDirectFluct,dp3,dnmaxCont2;
|
||||
G4double dp1,dp3;
|
||||
G4double siga ;
|
||||
|
||||
// shortcut for very very small loss
|
||||
if(MeanLoss < minLoss) return MeanLoss ;
|
||||
|
||||
// get particle data
|
||||
G4double Tkin = aParticle->GetKineticEnergy();
|
||||
G4double charge = aParticle->GetDefinition()->GetPDGCharge();
|
||||
G4double Tkin = aParticle->GetKineticEnergy();
|
||||
ParticleMass = aParticle->GetMass() ;
|
||||
|
||||
threshold =((*G4Electron::Electron()).GetCutsInEnergy())[imat];
|
||||
|
||||
G4double rmass = electron_mass_c2/ParticleMass;
|
||||
G4double tau = Tkin/ParticleMass, tau1 = tau+1., tau2 = tau*(tau+2.);
|
||||
G4double Tm = 2.*electron_mass_c2*tau2/(1.+2.*tau1*rmass+rmass*rmass)
|
||||
-ipotFluct;
|
||||
if (Tm < 0.) Tm = 0.;
|
||||
else if (Tm > threshold) Tm = threshold;
|
||||
G4double tau = Tkin/ParticleMass, tau1 = tau+1., tau2 = tau*(tau+2.);
|
||||
G4double Tm = 2.*electron_mass_c2*tau2/(1.+2.*tau1*rmass+rmass*rmass);
|
||||
|
||||
w1 = Tm+ipotFluct;
|
||||
w2 = w1/ipotFluct;
|
||||
w3 = 2.*electron_mass_c2*tau2;
|
||||
lnw3 = log(w3);
|
||||
if (Tm <= ipotFluct) Tm = ipotFluct ;
|
||||
|
||||
if(Tm > threshold) Tm = threshold;
|
||||
beta2 = tau2/(tau1*tau1);
|
||||
|
||||
C = (1.-rateFluct)*MeanLoss/(lnw3-ipotLogFluct-beta2);
|
||||
// Gaussian fluctuation ?
|
||||
if(MeanLoss >= kappa*Tm)
|
||||
{
|
||||
electronDensity = aMaterial->GetElectronDensity() ;
|
||||
siga = sqrt(MeanLoss*Tm*(0.5-0.25*beta2)*step*
|
||||
factor*electronDensity*ChargeSquare/beta2) ;
|
||||
loss = G4RandGauss::shoot(MeanLoss,siga) ;
|
||||
if(loss < 0.) loss = 0. ;
|
||||
return loss ;
|
||||
}
|
||||
|
||||
w1 = Tm/ipotFluct;
|
||||
w2 = log(2.*electron_mass_c2*tau2);
|
||||
|
||||
C = MeanLoss*(1.-rateFluct)/(w2-ipotLogFluct-beta2);
|
||||
|
||||
a1 = C*f1Fluct*(w2-e1LogFluct-beta2)/e1Fluct;
|
||||
a2 = C*f2Fluct*(w2-e2LogFluct-beta2)/e2Fluct;
|
||||
if(Tm > ipotFluct)
|
||||
a3 = rateFluct*MeanLoss*(Tm-ipotFluct)/(ipotFluct*Tm*log(w1));
|
||||
else
|
||||
{
|
||||
a1 /= 1.-rateFluct ;
|
||||
a2 /= 1.-rateFluct ;
|
||||
a3 = 0. ;
|
||||
}
|
||||
|
||||
a1 = C*f1Fluct*(lnw3-e1LogFluct-beta2)/e1Fluct;
|
||||
a2 = C*f2Fluct*(lnw3-e2LogFluct-beta2)/e2Fluct;
|
||||
if (Tm > 0.) a3 = rateFluct*MeanLoss*Tm/(ipotFluct*w1*log(w2));
|
||||
else { a1 /= rateFluct; a2 /= rateFluct; a3 = 0.;}
|
||||
suma = a1+a2+a3;
|
||||
|
||||
//no fluctuation if the loss is too big
|
||||
if (suma > MaxExcitationNumber) return MeanLoss;
|
||||
|
||||
suma<50.? prob = exp(-suma) : prob = 0.;
|
||||
loss = 0. ;
|
||||
|
||||
if (prob > probLimFluct) // very small Step
|
||||
if(suma < sumaLim) // very small Step
|
||||
{
|
||||
e0 = aMaterial->GetIonisation()->GetEnergy0fluct();
|
||||
if (Tm <= 0.)
|
||||
{
|
||||
a1 = MeanLoss/e0;
|
||||
p1 = G4Poisson(a1);
|
||||
loss = p1*e0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
Em = Tm+e0;
|
||||
a1 = MeanLoss*(Em-e0)/(Em*e0*log(Em/e0));
|
||||
p1 = G4Poisson(a1);
|
||||
w = (Em-e0)/Em;
|
||||
// just to save time
|
||||
if (p1 > nmaxDirectFluct)
|
||||
{
|
||||
dp1 = p1;
|
||||
dnmaxDirectFluct=nmaxDirectFluct;
|
||||
Corrfac = dp1/dnmaxDirectFluct;
|
||||
p1 = nmaxDirectFluct;
|
||||
}
|
||||
else Corrfac = 1.;
|
||||
e0 = aMaterial->GetIonisation()->GetEnergy0fluct();
|
||||
|
||||
loss = 0.;
|
||||
for (long i=0; i<p1; i++) loss += 1./(1.-w*G4UniformRand());
|
||||
loss *= (e0*Corrfac);
|
||||
if(Tm == ipotFluct)
|
||||
{
|
||||
a3 = MeanLoss/e0;
|
||||
|
||||
}
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = G4std::max(0,int(G4RandGauss::shoot(a3,siga)+0.5));
|
||||
}
|
||||
p3 = G4Poisson(a3);
|
||||
|
||||
loss = p3*e0 ;
|
||||
|
||||
if(p3 > 0)
|
||||
loss += (1.-2.*G4UniformRand())*e0 ;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Tm = Tm-ipotFluct+e0 ;
|
||||
a3 = MeanLoss*(Tm-e0)/(Tm*e0*log(Tm/e0));
|
||||
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = G4std::max(0,int(G4RandGauss::shoot(a3,siga)+0.5));
|
||||
}
|
||||
else
|
||||
p3 = G4Poisson(a3);
|
||||
|
||||
if(p3 > 0)
|
||||
{
|
||||
w = (Tm-e0)/Tm ;
|
||||
if(p3 > nmaxCont2)
|
||||
{
|
||||
dp3 = G4float(p3) ;
|
||||
Corrfac = dp3/G4float(nmaxCont2) ;
|
||||
p3 = nmaxCont2 ;
|
||||
}
|
||||
else
|
||||
Corrfac = 1. ;
|
||||
|
||||
for(G4int i=0; i<p3; i++) loss += 1./(1.-w*G4UniformRand()) ;
|
||||
loss *= e0*Corrfac ;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else // not so small Step
|
||||
else // not so small Step
|
||||
{
|
||||
p1 = G4Poisson(a1);
|
||||
p2 = G4Poisson(a2);
|
||||
loss = p1*e1Fluct+p2*e2Fluct;
|
||||
if (loss>0.) loss += (1.-2.*G4UniformRand())*e1Fluct;
|
||||
p3 = G4Poisson(a3);
|
||||
// excitation type 1
|
||||
if(a1>alim)
|
||||
{
|
||||
siga=sqrt(a1) ;
|
||||
p1 = G4std::max(0,int(G4RandGauss::shoot(a1,siga)+0.5));
|
||||
}
|
||||
else
|
||||
p1 = G4Poisson(a1);
|
||||
|
||||
lossc = 0.; na = 0.; alfa = 1.;
|
||||
if (p3 > nmaxCont2)
|
||||
{
|
||||
dp3 = p3;
|
||||
dnmaxCont2 = nmaxCont2;
|
||||
rfac = dp3/(dnmaxCont2+dp3);
|
||||
namean = p3*rfac;
|
||||
sa = nmaxCont1*rfac;
|
||||
na = RandGauss::shoot(namean,sa);
|
||||
// excitation type 2
|
||||
if(a2>alim)
|
||||
{
|
||||
siga=sqrt(a2) ;
|
||||
p2 = G4std::max(0,int(G4RandGauss::shoot(a2,siga)+0.5));
|
||||
}
|
||||
else
|
||||
p2 = G4Poisson(a2);
|
||||
|
||||
loss = p1*e1Fluct+p2*e2Fluct;
|
||||
|
||||
// smearing to avoid unphysical peaks
|
||||
if(p2 > 0)
|
||||
|
||||
loss += (1.-2.*G4UniformRand())*e2Fluct;
|
||||
else if (loss>0.)
|
||||
loss += (1.-2.*G4UniformRand())*e1Fluct;
|
||||
|
||||
// ionisation .......................................
|
||||
if(a3 > 0.)
|
||||
{
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = G4std::max(0,int(G4RandGauss::shoot(a3,siga)+0.5));
|
||||
}
|
||||
else
|
||||
p3 = G4Poisson(a3);
|
||||
|
||||
lossc = 0.;
|
||||
if(p3 > 0)
|
||||
{
|
||||
na = 0.;
|
||||
alfa = 1.;
|
||||
if (p3 > nmaxCont2)
|
||||
{
|
||||
dp3 = G4float(p3);
|
||||
rfac = dp3/(G4float(nmaxCont2)+dp3);
|
||||
namean = G4float(p3)*rfac;
|
||||
sa = G4float(nmaxCont1)*rfac;
|
||||
na = G4RandGauss::shoot(namean,sa);
|
||||
if (na > 0.)
|
||||
{
|
||||
alfa = w2*(nmaxCont2+p3)/(w2*nmaxCont2+p3);
|
||||
alfa1 = alfa*log(alfa)/(alfa-1.);
|
||||
ea = na*ipotFluct*alfa1;
|
||||
sea = ipotFluct*sqrt(na*(alfa-alfa1*alfa1));
|
||||
lossc += RandGauss::shoot(ea,sea);
|
||||
}
|
||||
|
||||
{
|
||||
alfa = w1*G4float(nmaxCont2+p3)/(w1*G4float(nmaxCont2)+G4float(p3));
|
||||
alfa1 = alfa*log(alfa)/(alfa-1.);
|
||||
ea = na*ipotFluct*alfa1;
|
||||
sea = ipotFluct*sqrt(na*(alfa-alfa1*alfa1));
|
||||
lossc += G4RandGauss::shoot(ea,sea);
|
||||
}
|
||||
}
|
||||
|
||||
nb = G4int(p3-na);
|
||||
if (nb > 0)
|
||||
{
|
||||
nb = G4int(G4float(p3)-na);
|
||||
if (nb > 0)
|
||||
{
|
||||
w2 = alfa*ipotFluct;
|
||||
w = (w1-w2)/w1;
|
||||
for (G4int k=0; k<nb; k++) lossc += w2/(1.-w*G4UniformRand());
|
||||
}
|
||||
w = (Tm-w2)/Tm;
|
||||
for (G4int k=0; k<nb; k++) lossc += w2/(1.-w*G4UniformRand());
|
||||
|
||||
loss += lossc;
|
||||
}
|
||||
}
|
||||
loss += lossc;
|
||||
}
|
||||
}
|
||||
|
||||
return loss ;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4VPAIenergyLoss.cc,v 1.1 2000/04/25 14:33:10 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
|
||||
@@ -5,21 +5,10 @@
|
||||
// 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 $
|
||||
// $Id: G4VeEnergyLoss.cc,v 1.8 2000/10/30 07:01:09 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-03-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:
|
||||
@@ -28,14 +17,13 @@
|
||||
// 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
|
||||
@@ -49,10 +37,6 @@ G4PhysicsTable** G4VeEnergyLoss::RecorderOfElectronProcess =
|
||||
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;
|
||||
@@ -76,8 +60,6 @@ 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
|
||||
@@ -92,11 +74,7 @@ G4VeEnergyLoss::G4VeEnergyLoss(const G4String& processName)
|
||||
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....
|
||||
|
||||
@@ -106,7 +84,6 @@ G4VeEnergyLoss::~G4VeEnergyLoss()
|
||||
{
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable; theLossTable = NULL;
|
||||
/// if(MinDeltaEnergy) delete MinDeltaEnergy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +278,7 @@ void G4VeEnergyLoss::BuildDEDXTable(
|
||||
if(!setMinDeltaCutInRange )
|
||||
MinDeltaCutInRange = G4Electron::Electron()->GetCuts()/10. ;
|
||||
|
||||
if(&aParticleType==G4Electron::Electron())
|
||||
if((subSecFlag) && (&aParticleType==G4Electron::Electron()))
|
||||
{
|
||||
G4cout << G4endl;
|
||||
G4cout.precision(5) ;
|
||||
@@ -314,8 +291,12 @@ void G4VeEnergyLoss::BuildDEDXTable(
|
||||
|
||||
if(MinDeltaEnergy) delete MinDeltaEnergy ;
|
||||
MinDeltaEnergy = new G4double [numOfMaterials] ;
|
||||
if(LowerLimitForced) delete LowerLimitForced ;
|
||||
LowerLimitForced = new G4bool [numOfMaterials] ;
|
||||
for(G4int mat=0; mat<numOfMaterials; mat++)
|
||||
{
|
||||
LowerLimitForced[mat] = false ;
|
||||
|
||||
MinDeltaEnergy[mat] = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4Electron::Electron(),MinDeltaCutInRange,
|
||||
(*theMaterialTable)(mat)) ;
|
||||
@@ -326,10 +307,14 @@ void G4VeEnergyLoss::BuildDEDXTable(
|
||||
if(MinDeltaEnergy[mat]>G4Electron::Electron()->GetCutsInEnergy()[mat])
|
||||
MinDeltaEnergy[mat]=G4Electron::Electron()->GetCutsInEnergy()[mat] ;
|
||||
|
||||
if(&aParticleType==G4Electron::Electron())
|
||||
if((subSecFlag) && (&aParticleType==G4Electron::Electron()))
|
||||
{
|
||||
G4cout << G4std::setw(20) << (*theMaterialTable)(mat)->GetName()
|
||||
<< G4std::setw(15) << MinDeltaEnergy[mat]/keV << G4endl;
|
||||
<< G4std::setw(15) << MinDeltaEnergy[mat]/keV ;
|
||||
if(LowerLimitForced[mat])
|
||||
G4cout << " lower limit forced." << G4endl;
|
||||
else
|
||||
G4cout << G4endl ;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -436,7 +421,9 @@ G4VParticleChange* G4VeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
G4Electron::Electron(),safety,aMaterial) ;
|
||||
|
||||
// absolute lower limit for T0
|
||||
if(T0<MinDeltaEnergyNow) T0=MinDeltaEnergyNow ;
|
||||
// if(T0<MinDeltaEnergyNow) T0=MinDeltaEnergyNow ;
|
||||
if((T0<MinDeltaEnergyNow)||(LowerLimitForced[aMaterial->GetIndex()]))
|
||||
T0=MinDeltaEnergyNow ;
|
||||
// ..................................................................
|
||||
|
||||
x1=stepData.GetPreStepPoint()->GetPosition().x();
|
||||
@@ -597,7 +584,7 @@ G4VParticleChange* G4VeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
//now the loss with fluctuation
|
||||
if ((EnlossFlucFlag) && (finalT > 0.) && (finalT < E)&&(E > LowerBoundEloss))
|
||||
{
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,MeanLoss);
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,1.,MeanLoss,Step);
|
||||
if (finalT < 0.) finalT = 0. ;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,24 +5,11 @@
|
||||
// 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 $
|
||||
// $Id: G4VhEnergyLoss.cc,v 1.13 2000/10/30 07:01:09 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-03-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
|
||||
@@ -30,16 +17,24 @@
|
||||
// 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
|
||||
// 18/07/00 : bug fix in AlongStepDoIt V.Ivanchenko
|
||||
// 10/08/00 : V.Ivanchenko change AlongStepDoIt and
|
||||
// add EnergyLossFluctuation in order to simulate
|
||||
// energy losses of ions
|
||||
// 17/08/00 : V.Ivanchenko change EnergyLossFluctuation
|
||||
// 18/08/00 : V.Ivanchenko bug fixed in GetConstrained
|
||||
// --------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4VhEnergyLoss.hh"
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
// Initialisation of static members ******************************************
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4int G4VhEnergyLoss::NbOfProcesses = 1 ;
|
||||
|
||||
G4int G4VhEnergyLoss::CounterOfProcess = 0 ;
|
||||
@@ -80,10 +75,6 @@ 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 ;
|
||||
@@ -97,28 +88,26 @@ 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
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
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();
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
}
|
||||
G4VhEnergyLoss::~G4VhEnergyLoss()
|
||||
{
|
||||
if(theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable; theLossTable = NULL;
|
||||
}
|
||||
/// if(MinDeltaEnergy) delete MinDeltaEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VhEnergyLoss::BuildDEDXTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
@@ -305,6 +294,7 @@ void G4VhEnergyLoss::BuildDEDXTable(
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// make the energy loss and the range table available
|
||||
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
@@ -325,7 +315,7 @@ void G4VhEnergyLoss::BuildDEDXTable(
|
||||
if(!setMinDeltaCutInRange)
|
||||
MinDeltaCutInRange = G4Electron::Electron()->GetCuts()/10.;
|
||||
|
||||
if(aParticleType.GetParticleName()=="proton")
|
||||
if((subSecFlag) && (aParticleType.GetParticleName()=="proton"))
|
||||
{
|
||||
G4cout << G4endl;
|
||||
G4cout.precision(5) ;
|
||||
@@ -338,9 +328,13 @@ void G4VhEnergyLoss::BuildDEDXTable(
|
||||
|
||||
if(MinDeltaEnergy) delete MinDeltaEnergy ;
|
||||
MinDeltaEnergy = new G4double [numOfMaterials] ;
|
||||
if(LowerLimitForced) delete LowerLimitForced ;
|
||||
LowerLimitForced = new G4bool [numOfMaterials] ;
|
||||
G4double Tlowerlimit = 1.*keV ;
|
||||
for(G4int mat=0; mat<numOfMaterials; mat++)
|
||||
{
|
||||
LowerLimitForced[mat] = false ;
|
||||
|
||||
MinDeltaEnergy[mat] = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4Electron::Electron(),MinDeltaCutInRange,
|
||||
(*theMaterialTable)(mat)) ;
|
||||
@@ -349,12 +343,19 @@ void G4VhEnergyLoss::BuildDEDXTable(
|
||||
if(MinDeltaEnergy[mat]>G4Electron::Electron()->GetCutsInEnergy()[mat])
|
||||
MinDeltaEnergy[mat]=G4Electron::Electron()->GetCutsInEnergy()[mat] ;
|
||||
|
||||
if(aParticleType.GetParticleName()=="proton")
|
||||
if((subSecFlag) && (aParticleType.GetParticleName()=="proton"))
|
||||
{
|
||||
G4cout << G4std::setw(20) << (*theMaterialTable)(mat)->GetName()
|
||||
<< G4std::setw(15) << MinDeltaEnergy[mat]/keV << G4endl;
|
||||
<< G4std::setw(15) << MinDeltaEnergy[mat]/keV ;
|
||||
if(LowerLimitForced[mat])
|
||||
G4cout << " lower limit forced." << G4endl;
|
||||
else
|
||||
G4cout << G4endl ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VhEnergyLoss::GetConstraints(const G4DynamicParticle *aParticle,
|
||||
G4Material *aMaterial)
|
||||
@@ -408,6 +409,8 @@ G4double G4VhEnergyLoss::GetConstraints(const G4DynamicParticle *aParticle,
|
||||
return StepLimit ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
const G4Track& trackData,const G4Step& stepData)
|
||||
// compute the energy loss after a step
|
||||
@@ -464,7 +467,7 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
theAntiProton,
|
||||
rscaled-sscaled,aMaterial) ;
|
||||
}
|
||||
MeanLoss /= (massratio*ChargeSquare) ;
|
||||
MeanLoss /= massratio ;
|
||||
}
|
||||
else MeanLoss = Step*fdEdx ;
|
||||
}
|
||||
@@ -557,7 +560,9 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
aMaterial) ;
|
||||
|
||||
// absolute lower limit for T0
|
||||
if(T0<MinDeltaEnergyNow) T0=MinDeltaEnergyNow ;
|
||||
// if(T0<MinDeltaEnergyNow) T0=MinDeltaEnergyNow ;
|
||||
if((T0<MinDeltaEnergyNow)||(LowerLimitForced[aMaterial->GetIndex()]))
|
||||
T0=MinDeltaEnergyNow ;
|
||||
|
||||
// compute nb of delta rays to be generated
|
||||
G4int N=int(fragment*(c0N/(E*T0)+c1N/T0-(c2N+c3N*T0)/Tc)*
|
||||
@@ -677,8 +682,8 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
// now the loss with fluctuation
|
||||
if((EnlossFlucFlag) && (finalT > 0.) && (finalT < E)&&(E > LowerBoundEloss))
|
||||
{
|
||||
MeanLoss /= ChargeSquare ;
|
||||
finalT = E-GetLossWithFluct(aParticle,aMaterial,MeanLoss)*ChargeSquare ;
|
||||
finalT = E -
|
||||
EnergyLossFluctuation(aParticle,aMaterial,ChargeSquare,MeanLoss,Step) ;
|
||||
if (finalT < 0.) finalT = 0. ;
|
||||
}
|
||||
|
||||
@@ -699,4 +704,18 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
return &aParticleChange ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VhEnergyLoss::EnergyLossFluctuation(
|
||||
const G4DynamicParticle *aParticle,
|
||||
G4Material *aMaterial,
|
||||
G4double ChargeSquare,
|
||||
G4double MeanLoss,
|
||||
G4double Step)
|
||||
{
|
||||
G4double loss = GetLossWithFluct(aParticle,aMaterial,
|
||||
ChargeSquare,MeanLoss,Step) ;
|
||||
return loss ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4eBremsstrahlung.cc,v 1.11 2000/05/23 15:44:29 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4eBremsstrahlung.cc,v 1.13 2000/09/21 09:34:29 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
@@ -30,6 +30,8 @@
|
||||
// 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
|
||||
// 07/08/00 new cross section/en.loss parametrisation, LPM flag , L.Urban
|
||||
// 21/09/00 : corrections in the LPM implementation, L.Urban
|
||||
// --------------------------------------------------------------
|
||||
|
||||
#include "G4eBremsstrahlung.hh"
|
||||
@@ -40,6 +42,8 @@
|
||||
G4double G4eBremsstrahlung::LowerBoundLambda = 1.*keV ;
|
||||
G4double G4eBremsstrahlung::UpperBoundLambda = 100.*TeV ;
|
||||
G4int G4eBremsstrahlung::NbinLambda = 100 ;
|
||||
G4double G4eBremsstrahlung::probsup = 1.00 ;
|
||||
G4bool G4eBremsstrahlung::LPMflag = true;
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -49,7 +53,8 @@ G4int G4eBremsstrahlung::NbinLambda = 100 ;
|
||||
G4eBremsstrahlung::G4eBremsstrahlung(const G4String& processName)
|
||||
: G4VeEnergyLoss(processName), // initialization
|
||||
theMeanFreePathTable(NULL)
|
||||
{MinThreshold = 10*keV; }
|
||||
{ // MinThreshold = 10*keV;
|
||||
MinThreshold = 1*keV; }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -148,7 +153,6 @@ void G4eBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType
|
||||
{
|
||||
KineticEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
TotalEnergy = KineticEnergy+ParticleMass ;
|
||||
|
||||
Cut = GammaCutInKineticEnergy[J] ;
|
||||
if (Cut < MinThreshold) Cut = MinThreshold;
|
||||
if (Cut > KineticEnergy) Cut = KineticEnergy;
|
||||
@@ -200,60 +204,40 @@ void G4eBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType
|
||||
|
||||
}
|
||||
|
||||
// now compute the correction due to the LPM effect
|
||||
const G4double MigdalConstant = classic_electr_radius*
|
||||
electron_Compton_length*
|
||||
electron_Compton_length/pi ;
|
||||
static const G4double MigdalConstant = classic_electr_radius
|
||||
*electron_Compton_length
|
||||
*electron_Compton_length/pi;
|
||||
G4double TotalEnergy = KineticEnergy+electron_mass_c2 ;
|
||||
G4double kp2 = MigdalConstant*TotalEnergy*TotalEnergy*
|
||||
(material->GetElectronDensity()) ;
|
||||
|
||||
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 ;
|
||||
// now compute the correction due to the supression(s)
|
||||
G4double kmin = 1.*eV ;
|
||||
G4double kmax = Cut ;
|
||||
|
||||
G4double LPMEnergy = LPMconstant*(material->GetRadlen()) ;
|
||||
G4double TotalEnergysquare = TotalEnergy*TotalEnergy ;
|
||||
G4double LPMGammaEnergyLimit = TotalEnergysquare/LPMEnergy ;
|
||||
|
||||
if(LPMGammaEnergyLimit > klim)
|
||||
if(kmax > kmin)
|
||||
{
|
||||
G4double kmax = G4std::min(Cut,LPMGammaEnergyLimit) ;
|
||||
|
||||
G4double floss = 0. ;
|
||||
G4int nmax = 1000 ;
|
||||
G4int nmax = 100 ;
|
||||
G4int nn ;
|
||||
G4double vmin=log(kmin);
|
||||
G4double vmax=log(Cut) ;
|
||||
G4double vmax=log(kmax) ;
|
||||
nn = int(nmax*(vmax-vmin)/(log(HighestKineticEnergy)-vmin)) ;
|
||||
G4double u,uu,s2lpm,sp,fac,c,v,dv,w ;
|
||||
G4double u,fac,c,v,dv ;
|
||||
dv = (vmax-vmin)/nn ;
|
||||
v = vmin-dv ;
|
||||
if(nn > 0)
|
||||
{
|
||||
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 = u*SupressionFunction(material,KineticEnergy,u) ;
|
||||
|
||||
fac *= uu*u ;
|
||||
probsup = 1. ;
|
||||
fac *= probsup*(u*u/(u*u+kp2))+1.-probsup ;
|
||||
|
||||
if((n==0)||(n==nn))
|
||||
c=0.5;
|
||||
@@ -264,13 +248,18 @@ void G4eBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType
|
||||
floss += fac ;
|
||||
}
|
||||
|
||||
floss *=dv*3./(Cut*Cut*Cut-kmin*kmin*kmin) ;
|
||||
floss *=dv/(kmax-kmin) ;
|
||||
|
||||
}
|
||||
else
|
||||
floss = 1. ;
|
||||
|
||||
if(floss > 1.) floss = 1. ;
|
||||
|
||||
// correct the loss
|
||||
bremloss *= floss ;
|
||||
}
|
||||
|
||||
|
||||
if(bremloss < 0.) bremloss = 0. ;
|
||||
aVector->PutValue(i,bremloss);
|
||||
}
|
||||
@@ -314,72 +303,96 @@ G4double G4eBremsstrahlung::ComputeBremLoss(G4double Z,G4double natom,
|
||||
G4double T,G4double Cut,G4double x)
|
||||
|
||||
// compute loss due to soft brems
|
||||
// 'Migdal' version , this is the default in GEANT3
|
||||
{
|
||||
const G4double beta=0.99,ksi=2.51,ve=0.00004 ;
|
||||
const G4double corrfac = classic_electr_radius*electron_Compton_length*electron_Compton_length/pi ;
|
||||
static const G4double beta=1.00,ksi=2.00 ;
|
||||
static const G4double clossh = 0.254 , closslow = 1./3. , alosslow = 1. ;
|
||||
static const G4double Tlim= 10.*MeV ;
|
||||
|
||||
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 xlim = 1.2 ;
|
||||
static const G4int NZ = 8 ;
|
||||
static const G4int Nloss = 11 ;
|
||||
static const G4double ZZ[NZ] =
|
||||
{2.,4.,6.,14.,26.,50.,82.,92.};
|
||||
static const G4double coefloss[NZ][Nloss] = {
|
||||
// Z=2
|
||||
0.98916, 0.47564, -0.2505, -0.45186, 0.14462,
|
||||
0.21307, -0.013738, -0.045689, -0.0042914, 0.0034429,
|
||||
0.00064189,
|
||||
|
||||
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};
|
||||
// Z=4
|
||||
1.0626, 0.37662, -0.23646, -0.45188, 0.14295,
|
||||
0.22906, -0.011041, -0.051398, -0.0055123, 0.0039919,
|
||||
0.00078003,
|
||||
// Z=6
|
||||
1.0954, 0.315, -0.24011, -0.43849, 0.15017,
|
||||
0.23001, -0.012846, -0.052555, -0.0055114, 0.0041283,
|
||||
0.00080318,
|
||||
|
||||
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};
|
||||
// Z=14
|
||||
1.1649, 0.18976, -0.24972, -0.30124, 0.1555,
|
||||
0.13565, -0.024765, -0.027047, -0.00059821, 0.0019373,
|
||||
0.00027647,
|
||||
|
||||
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};
|
||||
// Z=26
|
||||
1.2261, 0.14272, -0.25672, -0.28407, 0.13874,
|
||||
0.13586, -0.020562, -0.026722, -0.00089557, 0.0018665,
|
||||
0.00026981,
|
||||
|
||||
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;
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
// Z=50
|
||||
1.3147, 0.020049, -0.35543, -0.13927, 0.17666,
|
||||
0.073746, -0.036076, -0.013407, 0.0025727, 0.00084005,
|
||||
-1.4082e-05,
|
||||
|
||||
G4double TotalEnergy = T + electron_mass_c2;
|
||||
G4double y=log(Cut/(ve*TotalEnergy));
|
||||
// Z=82
|
||||
1.3986, -0.10586, -0.49187, -0.0048846, 0.23621,
|
||||
0.031652, -0.052938, -0.0076639, 0.0048181, 0.00056486,
|
||||
-0.00011995,
|
||||
|
||||
// Z=92
|
||||
1.4217, -0.116, -0.55497, -0.044075, 0.27506,
|
||||
0.081364, -0.058143, -0.023402, 0.0031322, 0.0020201,
|
||||
0.00017519
|
||||
|
||||
} ;
|
||||
|
||||
G4int iz = 0 ;
|
||||
G4double delz = 1.e6 ;
|
||||
for (G4int ii=0; ii<NZ; ii++)
|
||||
{
|
||||
if(abs(Z-ZZ[ii]) < delz)
|
||||
{
|
||||
iz = ii ;
|
||||
delz = abs(Z-ZZ[ii]) ;
|
||||
}
|
||||
}
|
||||
|
||||
G4double xx = log10(T) ;
|
||||
G4double fl = 1. ;
|
||||
|
||||
if(xx <= xlim)
|
||||
{
|
||||
fl = coefloss[iz][Nloss-1] ;
|
||||
for (G4int j=Nloss-2; j>=0; j--)
|
||||
{
|
||||
fl = fl*xx+coefloss[iz][j] ;
|
||||
}
|
||||
if(fl < 0.) fl = 0. ;
|
||||
}
|
||||
|
||||
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 E = T+electron_mass_c2 ;
|
||||
|
||||
G4double rate = TotalEnergy/Cut ;
|
||||
G4double corr = 1./(1.+corrfac*natom*rate*rate) ;
|
||||
loss = Z*(Z+ksi)*E*E/(T+E)*exp(beta*log(Cut/T))*(2.-clossh*exp(log(Z)/4.)) ;
|
||||
|
||||
G4double factor = pow(Cut*corr/T,beta);
|
||||
factor *= Z*(Z+ksi)*TotalEnergy*TotalEnergy/(TotalEnergy+electron_mass_c2) ;
|
||||
if(T <= Tlim)
|
||||
loss /= exp(closslow*log(Tlim/T)) ;
|
||||
|
||||
loss *= factor ;
|
||||
if(T <= Cut)
|
||||
loss *= exp(alosslow*log(T/Cut)) ;
|
||||
|
||||
loss *= fl ;
|
||||
|
||||
loss /= Avogadro ;
|
||||
|
||||
return loss ;
|
||||
}
|
||||
@@ -472,6 +485,66 @@ G4double G4eBremsstrahlung::ComputeMeanFreePath(
|
||||
(*theElementVector)(i)->GetZ(),
|
||||
GammaEnergyCut );
|
||||
}
|
||||
// now compute the correction due to the supression(s)
|
||||
|
||||
G4double kmax = KineticEnergy ;
|
||||
G4double kmin = GammaEnergyCut ;
|
||||
|
||||
static const G4double MigdalConstant = classic_electr_radius
|
||||
*electron_Compton_length
|
||||
*electron_Compton_length/pi;
|
||||
G4double TotalEnergy = KineticEnergy+electron_mass_c2 ;
|
||||
G4double kp2 = MigdalConstant*TotalEnergy*TotalEnergy*
|
||||
(aMaterial->GetElectronDensity()) ;
|
||||
|
||||
if(kmax > kmin)
|
||||
{
|
||||
|
||||
G4double fsig = 0. ;
|
||||
G4int nmax = 100 ;
|
||||
G4int nn ;
|
||||
G4double vmin=log(kmin);
|
||||
G4double vmax=log(kmax) ;
|
||||
nn = int(nmax*(vmax-vmin)/(log(HighestKineticEnergy)-vmin)) ;
|
||||
G4double u,fac,c,v,dv,y ;
|
||||
dv = (vmax-vmin)/nn ;
|
||||
v = vmin-dv ;
|
||||
if(nn > 0)
|
||||
{
|
||||
for(G4int n=0; n<=nn; n++)
|
||||
{
|
||||
v += dv ;
|
||||
u = exp(v) ;
|
||||
|
||||
fac = SupressionFunction(aMaterial,KineticEnergy,u) ;
|
||||
|
||||
y = u/kmax ;
|
||||
|
||||
fac *= (4.-4.*y+3.*y*y)/3. ;
|
||||
|
||||
fac *= probsup*(u*u/(u*u+kp2))+1.-probsup ;
|
||||
|
||||
if((n==0)||(n==nn))
|
||||
c=0.5;
|
||||
else
|
||||
c=1.;
|
||||
|
||||
fac *= c ;
|
||||
fsig += fac ;
|
||||
}
|
||||
y = kmin/kmax ;
|
||||
fsig *=dv/(-4.*log(y)/3.-4.*(1.-y)/3.+0.5*(1.-y*y)) ;
|
||||
|
||||
}
|
||||
else
|
||||
fsig = 1. ;
|
||||
|
||||
if(fsig > 1.) fsig = 1. ;
|
||||
|
||||
// correct the cross section
|
||||
SIGMA *= fsig ;
|
||||
}
|
||||
|
||||
|
||||
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
}
|
||||
@@ -484,165 +557,103 @@ G4double G4eBremsstrahlung::ComputeMicroscopicCrossSection(
|
||||
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;
|
||||
static const G4double ksi=2.0, alfa=1.00;
|
||||
static const G4double csigh = 0.127, csiglow = 0.25, asiglow = 0.020*MeV ;
|
||||
static const G4double Tlim = 10.*MeV ;
|
||||
|
||||
const G4double KinLimitScale = 100.*GeV, CutLimitScale = 50.*GeV;
|
||||
static const G4double xlim = 1.2 ;
|
||||
static const G4int NZ = 8 ;
|
||||
static const G4int Nsig = 11 ;
|
||||
static const G4double ZZ[NZ] =
|
||||
{2.,4.,6.,14.,26.,50.,82.,92.} ;
|
||||
static const G4double coefsig[NZ][Nsig] = {
|
||||
// Z=2
|
||||
0.4638, 0.37748, 0.32249, -0.060362, -0.065004,
|
||||
-0.033457, -0.004583, 0.011954, 0.0030404, -0.0010077,
|
||||
-0.00028131,
|
||||
|
||||
// Z=4
|
||||
0.50008, 0.33483, 0.34364, -0.086262, -0.055361,
|
||||
-0.028168, -0.0056172, 0.011129, 0.0027528, -0.00092265,
|
||||
-0.00024348,
|
||||
|
||||
const G4double Tlim = 1.*MeV;
|
||||
if (KineticEnergy < Tlim) LocalKineticEnergy = Tlim;
|
||||
// Z=6
|
||||
0.51587, 0.31095, 0.34996, -0.11623, -0.056167,
|
||||
-0.0087154, 0.00053943, 0.0054092, 0.00077685, -0.00039635,
|
||||
-6.7818e-05,
|
||||
|
||||
if (KineticEnergy > KinLimitScale)
|
||||
{ LocalKineticEnergy = KinLimitScale;
|
||||
if (GammaEnergyCut > KinLimitScale) LocalGammaEnergyCut = CutLimitScale;
|
||||
}
|
||||
// Z=14
|
||||
0.55058, 0.25629, 0.35854, -0.080656, -0.054308,
|
||||
-0.049933, -0.00064246, 0.016597, 0.0021789, -0.001327,
|
||||
-0.00025983,
|
||||
|
||||
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;
|
||||
// Z=26
|
||||
0.5791, 0.26152, 0.38953, -0.17104, -0.099172,
|
||||
0.024596, 0.023718, -0.0039205, -0.0036658, 0.00041749,
|
||||
0.00023408,
|
||||
|
||||
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;
|
||||
// Z=50
|
||||
0.62085, 0.27045, 0.39073, -0.37916, -0.18878,
|
||||
0.23905, 0.095028, -0.068744, -0.023809, 0.0062408,
|
||||
0.0020407,
|
||||
|
||||
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;
|
||||
// Z=82
|
||||
0.66053, 0.24513, 0.35404, -0.47275, -0.22837,
|
||||
0.35647, 0.13203, -0.1049, -0.034851, 0.0095046,
|
||||
0.0030535,
|
||||
|
||||
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;
|
||||
// Z=92
|
||||
0.67143, 0.23079, 0.32256, -0.46248, -0.20013,
|
||||
0.3506, 0.11779, -0.1024, -0.032013, 0.0092279,
|
||||
0.0028592
|
||||
|
||||
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;
|
||||
G4int iz = 0 ;
|
||||
G4double delz = 1.e6 ;
|
||||
for (G4int ii=0; ii<NZ; ii++)
|
||||
{
|
||||
if(abs(AtomicNumber-ZZ[ii]) < delz)
|
||||
{
|
||||
iz = ii ;
|
||||
delz = abs(AtomicNumber-ZZ[ii]) ;
|
||||
}
|
||||
}
|
||||
|
||||
G4double F0 = ay0 + ay1*Y + ay2*Y2 + ay3*Y3 + ay4*Y4 + ay5*Y5,
|
||||
F1 = by0 + by1*Y + by2*Y2 + by3*Y3 + by4*Y4;
|
||||
G4double xx = log10(KineticEnergy) ;
|
||||
G4double fs = 1. ;
|
||||
|
||||
if(xx <= xlim)
|
||||
{
|
||||
fs = coefsig[iz][Nsig-1] ;
|
||||
for (G4int j=Nsig-2; j>=0; j--)
|
||||
{
|
||||
fs = fs*xx+coefsig[iz][j] ;
|
||||
}
|
||||
if(fs < 0.) fs = 0. ;
|
||||
}
|
||||
|
||||
CrossSection = AtomicNumber*(AtomicNumber+ksi)*TotalEnergy*TotalEnergy
|
||||
* pow(log(LocalKineticEnergy/LocalGammaEnergyCut),alfa)
|
||||
* (F0 + F1*AtomicNumber)
|
||||
/ (LocalKineticEnergy*(LocalKineticEnergy+2*electron_mass_c2));
|
||||
|
||||
CrossSection = AtomicNumber*(AtomicNumber+ksi)*
|
||||
(1.-csigh*exp(log(AtomicNumber)/4.))*
|
||||
pow(log(KineticEnergy/GammaEnergyCut),alfa) ;
|
||||
|
||||
if(KineticEnergy <= Tlim)
|
||||
CrossSection *= exp(csiglow*log(Tlim/KineticEnergy))*
|
||||
(1.+asiglow/(sqrt(AtomicNumber)*KineticEnergy)) ;
|
||||
|
||||
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.);
|
||||
}
|
||||
CrossSection *= ComputePositronCorrFactorSigma(AtomicNumber, KineticEnergy,
|
||||
GammaEnergyCut);
|
||||
CrossSection *= fs ;
|
||||
CrossSection /= Avogadro ;
|
||||
|
||||
if (CrossSection < 0.) CrossSection = 0.;
|
||||
return CrossSection;
|
||||
@@ -742,6 +753,8 @@ G4VParticleChange* G4eBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
*electron_Compton_length/pi;
|
||||
const G4double LPMconstant = fine_structure_const*electron_mass_c2*
|
||||
electron_mass_c2/(8.*pi*hbarc) ;
|
||||
G4double GammaEnergy ;
|
||||
G4bool LPMOK = false ;
|
||||
|
||||
aParticleChange.Initialize(trackData);
|
||||
G4Material* aMaterial=trackData.GetMaterial() ;
|
||||
@@ -780,12 +793,12 @@ G4VParticleChange* G4eBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
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
|
||||
G4double
|
||||
MigdalFactor = (aMaterial->GetElectronDensity())*MigdalConstant
|
||||
/(epsilmax*epsilmax);
|
||||
|
||||
//
|
||||
@@ -796,6 +809,7 @@ G4VParticleChange* G4eBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
// sample the energy rate of the emitted gamma for electron kinetic energy > 1 MeV
|
||||
//
|
||||
|
||||
do {
|
||||
if (KineticEnergy > 1.*MeV)
|
||||
{
|
||||
// parameters
|
||||
@@ -823,6 +837,7 @@ G4VParticleChange* G4eBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
// sample the energy rate of the emitted Gamma
|
||||
G4double screenvar;
|
||||
|
||||
|
||||
do {
|
||||
|
||||
x = pow(xmin, G4UniformRand());
|
||||
@@ -865,21 +880,19 @@ G4VParticleChange* G4eBremsstrahlung::PostStepDoIt(const G4Track& trackData,
|
||||
} while( greject < G4UniformRand()*grejmax );
|
||||
}
|
||||
|
||||
G4double GammaEnergy = x*KineticEnergy;
|
||||
GammaEnergy = x*KineticEnergy;
|
||||
|
||||
// now comes the supression due to the LPM effect
|
||||
if(GammaEnergy < LPMGammaEnergyLimit)
|
||||
if(LPMflag)
|
||||
{
|
||||
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. ;
|
||||
// take into account the supression due to the LPM effect
|
||||
if (G4UniformRand() <= SupressionFunction(aMaterial,KineticEnergy,GammaEnergy))
|
||||
LPMOK = true ;
|
||||
}
|
||||
else
|
||||
LPMOK = true ;
|
||||
|
||||
} while (!LPMOK) ;
|
||||
|
||||
|
||||
//protection: DO NOT PRODUCE a gamma with energy 0. !
|
||||
if (GammaEnergy <= 0.)
|
||||
@@ -953,10 +966,68 @@ G4Element* G4eBremsstrahlung::SelectRandomAtom(G4Material* aMaterial) const
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4double G4eBremsstrahlung::SupressionFunction(const G4Material* aMaterial,
|
||||
G4double KineticEnergy,G4double GammaEnergy)
|
||||
{
|
||||
// supression due to the LPM effect+polarisation of the medium/
|
||||
// supression due to the polarisation alone
|
||||
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) ;
|
||||
G4double TotalEnergy,TotalEnergySquare,LPMEnergy,LPMGammaEnergyLimit,
|
||||
LPMGammaEnergyLimit2,GammaEnergySquare,sp,s2lpm,supr,w,splim,Cnorm ;
|
||||
|
||||
TotalEnergy = KineticEnergy+electron_mass_c2 ;
|
||||
TotalEnergySquare = TotalEnergy*TotalEnergy ;
|
||||
|
||||
LPMEnergy = LPMconstant*(aMaterial->GetRadlen()) ;
|
||||
LPMGammaEnergyLimit = TotalEnergySquare/LPMEnergy ;
|
||||
GammaEnergySquare = GammaEnergy*GammaEnergy ;
|
||||
|
||||
LPMGammaEnergyLimit2 = LPMGammaEnergyLimit*LPMGammaEnergyLimit ;
|
||||
splim = LPMGammaEnergyLimit2/(LPMGammaEnergyLimit2+MigdalConstant*TotalEnergySquare*
|
||||
(aMaterial->GetElectronDensity())) ;
|
||||
w = 1.+1./splim ;
|
||||
Cnorm = 2./(sqrt(w*w+4.)-w) ;
|
||||
|
||||
sp = GammaEnergySquare/(GammaEnergySquare+MigdalConstant*TotalEnergySquare*
|
||||
(aMaterial->GetElectronDensity())) ;
|
||||
if(LPMflag)
|
||||
{
|
||||
s2lpm = LPMEnergy*GammaEnergy/TotalEnergySquare ;
|
||||
|
||||
if(s2lpm < 1.)
|
||||
{
|
||||
if((1.-sp) < 1.e-6)
|
||||
w = s2lpm*(3.-sp) ;
|
||||
else
|
||||
w = s2lpm*(1.+1./sp) ;
|
||||
supr = Cnorm*(sqrt(w*w+4.*s2lpm)-w)/2. ;
|
||||
}
|
||||
else
|
||||
{
|
||||
supr = sp ;
|
||||
}
|
||||
}
|
||||
else
|
||||
supr = sp ;
|
||||
|
||||
supr /= sp ;
|
||||
|
||||
return supr ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlung::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "Total cross sections from a parametrisation. ";
|
||||
comments += "Good description from 10 KeV to 100 GeV.\n";
|
||||
G4String comments = "Total cross sections from a NEW parametrisation based on the EEDL data library. ";
|
||||
// comments += "Good description from 10 KeV to 100 GeV.\n";
|
||||
comments += "\n 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.";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4eIonisation.cc,v 1.10 2000/05/23 14:42:21 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4eplusAnnihilation.cc,v 1.2 1999/12/15 14:51:53 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// based on the Program) you indicate your acceptance of this statement,
|
||||
// and all its terms.
|
||||
//
|
||||
// $Id: G4hIonisation.cc,v 1.11 2000/05/23 14:42:22 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-02-00 $
|
||||
// $Id: G4hIonisation.cc,v 1.12 2000/08/10 22:13:01 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-03-00 $
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -28,6 +28,10 @@
|
||||
// 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
|
||||
// 10/08/00 : V.Ivanchenko change BuildLambdaTable, in order to
|
||||
// simulate energy losses of ions; correction to
|
||||
// cross section for particles with spin 1 is inserted
|
||||
// as well
|
||||
// --------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -71,7 +75,7 @@ void G4hIonisation::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
Charge = aParticleType.GetPDGCharge();
|
||||
Charge = (aParticleType.GetPDGCharge())/eplus;
|
||||
|
||||
G4double ElectronCutInRange = G4Electron::Electron()->GetCuts();
|
||||
|
||||
@@ -289,6 +293,7 @@ void G4hIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
// Build mean free path tables for the delta ray production process
|
||||
// tables are built for MATERIALS
|
||||
|
||||
G4double chargeSquare = Charge*Charge ;
|
||||
G4double LowEdgeEnergy , Value ,sigma ;
|
||||
G4bool isOutRange ;
|
||||
const G4MaterialTable* theMaterialTable=
|
||||
@@ -345,10 +350,10 @@ void G4hIonisation::BuildLambdaTable(const G4ParticleDefinition& aParticleType)
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ )
|
||||
{
|
||||
sigma += theAtomicNumDensityVector[iel]*
|
||||
ComputeMicroscopicCrossSection(aParticleType,
|
||||
LowEdgeEnergy,
|
||||
(*theElementVector)(iel)->GetZ() ) ;
|
||||
sigma += theAtomicNumDensityVector[iel]*
|
||||
chargeSquare*
|
||||
ComputeMicroscopicCrossSection(aParticleType,
|
||||
LowEdgeEnergy,(*theElementVector)(iel)->GetZ() ) ;
|
||||
}
|
||||
|
||||
// mean free path = 1./macroscopic cross section
|
||||
@@ -401,16 +406,26 @@ G4double G4hIonisation::ComputeMicroscopicCrossSection(
|
||||
TotalCrossSection = (1.-tempvar*(1.-betasquare*log(tempvar)))
|
||||
/DeltaCutInKineticEnergyNow;
|
||||
|
||||
G4double spin = aParticleType.GetPDGSpin() ;
|
||||
|
||||
// +term for spin=1/2 particle
|
||||
if(aParticleType.GetPDGSpin() == 0.5)
|
||||
{
|
||||
TotalCrossSection += 0.5
|
||||
if(0.5 == spin)
|
||||
{
|
||||
TotalCrossSection += 0.5
|
||||
*(MaxKineticEnergyTransfer-DeltaCutInKineticEnergyNow)
|
||||
/(TotalEnergy*TotalEnergy);
|
||||
G4double Section = 0.5
|
||||
*(MaxKineticEnergyTransfer-DeltaCutInKineticEnergyNow)
|
||||
/(TotalEnergy*TotalEnergy);
|
||||
}
|
||||
|
||||
// +term for spin=1 particle
|
||||
} else if( 0.9 < spin )
|
||||
{
|
||||
TotalCrossSection +=
|
||||
-log(tempvar)/(3.0*DeltaCutInKineticEnergyNow) +
|
||||
(MaxKineticEnergyTransfer - DeltaCutInKineticEnergyNow) *
|
||||
( (5.0+ 1.0/tempvar)*0.25 / (TotalEnergy*TotalEnergy) -
|
||||
betasquare /
|
||||
(MaxKineticEnergyTransfer * DeltaCutInKineticEnergyNow)
|
||||
) / 3.0 ;
|
||||
}
|
||||
TotalCrossSection = twopi_mc2_rcl2 * AtomicNumber
|
||||
*TotalCrossSection/betasquare;
|
||||
}
|
||||
|
||||
@@ -1,459 +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: G4ionIonisation.cc,v 1.4 1999/12/15 14:51:54 gunter 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
|
||||
// ---------- G4ionIonisation physics process -----------
|
||||
// by Laszlo Urban, 08 Dec 1998
|
||||
// **************************************************************
|
||||
// It is the first implementation of the ionisation for IONS
|
||||
// --------------------------------------------------------------
|
||||
|
||||
|
||||
#include "G4ionIonisation.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4ionIonisation::G4ionIonisation(const G4String& processName)
|
||||
: G4VContinuousDiscreteProcess(processName),
|
||||
ParticleMass(proton_mass_c2),Charge(eplus),
|
||||
dEdx(1.*MeV/mm),MinKineticEnergy(1.*keV)
|
||||
{ PrintInfoDefinition() ; }
|
||||
|
||||
|
||||
G4ionIonisation::~G4ionIonisation()
|
||||
{ }
|
||||
|
||||
G4double G4ionIonisation::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....
|
||||
const G4double minstep=0.01*mm ;
|
||||
|
||||
G4double KineticEnergy,StepLimit;
|
||||
|
||||
Charge = aParticle->GetDefinition()->GetPDGCharge()/eplus ;
|
||||
|
||||
KineticEnergy = aParticle->GetKineticEnergy();
|
||||
|
||||
G4double massratio=proton_mass_c2/
|
||||
aParticle->GetDefinition()->GetPDGMass() ;
|
||||
|
||||
G4double Tscaled= KineticEnergy*massratio ;
|
||||
G4double ChargeSquare = Charge*Charge ;
|
||||
|
||||
dEdx=ComputedEdx(aParticle,aMaterial) ;
|
||||
StepLimit = 0.2*KineticEnergy/dEdx ;
|
||||
if(StepLimit < minstep)
|
||||
StepLimit = minstep ;
|
||||
|
||||
return StepLimit ;
|
||||
}
|
||||
|
||||
G4VParticleChange* G4ionIonisation::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() ;
|
||||
G4double massratio=proton_mass_c2/
|
||||
aParticle->GetDefinition()->GetPDGMass() ;
|
||||
ChargeSquare = Charge*Charge ;
|
||||
|
||||
G4int index = aMaterial->GetIndex() ;
|
||||
E = aParticle->GetKineticEnergy() ;
|
||||
|
||||
if(E < MinKineticEnergy) MeanLoss = E ;
|
||||
else
|
||||
{
|
||||
MeanLoss = Step*dEdx ;
|
||||
MeanLoss /= (massratio*ChargeSquare) ;
|
||||
}
|
||||
finalT = E - MeanLoss ;
|
||||
|
||||
if(finalT < MinKineticEnergy) finalT = 0. ;
|
||||
|
||||
// kill the particle if the kinetic energy <= 0
|
||||
if (finalT <= 0. )
|
||||
{
|
||||
finalT = 0.;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange( finalT ) ;
|
||||
aParticleChange.SetLocalEnergyDeposit(E-finalT) ;
|
||||
|
||||
return &aParticleChange ;
|
||||
}
|
||||
|
||||
|
||||
G4double G4ionIonisation::GetMeanFreePath(
|
||||
const G4Track& trackData,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition)
|
||||
{
|
||||
const G4DynamicParticle* aParticle ;
|
||||
G4Material* aMaterial ;
|
||||
G4double MeanFreePath;
|
||||
|
||||
*condition = NotForced ;
|
||||
|
||||
aParticle = trackData.GetDynamicParticle() ;
|
||||
aMaterial = trackData.GetMaterial() ;
|
||||
|
||||
G4double KineticEnergy = aParticle->GetKineticEnergy() ;
|
||||
Charge=(aParticle->GetDefinition()->GetPDGCharge())/eplus;
|
||||
G4double ChargeSquare=Charge*Charge ;
|
||||
|
||||
// compute the (macroscopic) cross section first
|
||||
|
||||
const G4ElementVector* theElementVector=
|
||||
aMaterial->GetElementVector() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
aMaterial->GetAtomicNumDensityVector();
|
||||
const G4int NumberOfElements=
|
||||
aMaterial->GetNumberOfElements() ;
|
||||
G4int index = aMaterial->GetIndex() ;
|
||||
|
||||
DeltaCutInKineticEnergy = G4Electron::Electron()->GetCutsInEnergy();
|
||||
DeltaCutInKineticEnergyNow = DeltaCutInKineticEnergy[index] ;
|
||||
|
||||
G4double sigma = 0. ;
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++ )
|
||||
{
|
||||
sigma += theAtomicNumDensityVector[iel]*
|
||||
ComputeMicroscopicCrossSection(aParticle,
|
||||
KineticEnergy,
|
||||
(*theElementVector)(iel)->GetZ() ) ;
|
||||
}
|
||||
|
||||
sigma *= twopi_mc2_rcl2 * ChargeSquare ;
|
||||
|
||||
// mean free path = 1./macroscopic cross section
|
||||
MeanFreePath = sigma<=0 ? DBL_MAX : 1./sigma ;
|
||||
|
||||
return MeanFreePath ;
|
||||
}
|
||||
|
||||
G4double G4ionIonisation::ComputeMicroscopicCrossSection(
|
||||
const G4DynamicParticle* aParticle,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber)
|
||||
{
|
||||
G4double TotalEnergy,
|
||||
betasquare,
|
||||
MaxKineticEnergyTransfer,TotalCrossSection,tempvar;
|
||||
|
||||
// get particle data ...................................
|
||||
ParticleMass = aParticle->GetDefinition()->GetPDGMass() ;
|
||||
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;
|
||||
|
||||
TotalCrossSection *= AtomicNumber/betasquare;
|
||||
}
|
||||
else
|
||||
TotalCrossSection= 0. ;
|
||||
|
||||
return TotalCrossSection ;
|
||||
}
|
||||
|
||||
G4double G4ionIonisation::ComputedEdx(const G4DynamicParticle* aParticle,
|
||||
G4Material* material)
|
||||
{
|
||||
// cuts for electron ....................
|
||||
DeltaCutInKineticEnergy = G4Electron::Electron()->GetCutsInEnergy() ;
|
||||
|
||||
G4double KineticEnergy , ionloss ;
|
||||
G4double RateMass ;
|
||||
G4bool isOutRange ;
|
||||
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 ;
|
||||
|
||||
// get material parameters needed for the energy loss calculation
|
||||
|
||||
G4double ElectronDensity,Eexc,Eexc2,Cden,Mden,Aden,X0den,X1den,taul ;
|
||||
G4double* ShellCorrectionVector;
|
||||
|
||||
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[material->GetIndex()] ;
|
||||
|
||||
// some local variables -------------------
|
||||
G4double tau,tau0,Tmax,gamma,bg2,beta2,rcut,delta,x,sh ;
|
||||
|
||||
KineticEnergy=aParticle->GetKineticEnergy();
|
||||
|
||||
|
||||
tau = KineticEnergy/proton_mass_c2 ;
|
||||
|
||||
if ( tau < taul )
|
||||
// low energy part , parametrized energy loss formulae
|
||||
{
|
||||
ionloss = 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) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
// high energy part , Bethe-Bloch formula
|
||||
{
|
||||
gamma = tau +1. ;
|
||||
bg2 = tau*(tau+2.) ;
|
||||
beta2 = bg2/(gamma*gamma) ;
|
||||
Tmax = 2.*electron_mass_c2*bg2
|
||||
/(1.+2.*gamma*RateMass+RateMass*RateMass) ;
|
||||
|
||||
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. ;
|
||||
|
||||
dEdx = ionloss ;
|
||||
return dEdx ;
|
||||
}
|
||||
|
||||
|
||||
G4VParticleChange* G4ionIonisation::PostStepDoIt(
|
||||
const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
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,grej,Psquare,Esquare,summass,rate,grejc,finalMomentum ;
|
||||
|
||||
aParticleChange.Initialize(trackData) ;
|
||||
aMaterial = trackData.GetMaterial() ;
|
||||
|
||||
aParticle = trackData.GetDynamicParticle() ;
|
||||
|
||||
KineticEnergy=aParticle->GetKineticEnergy();
|
||||
TotalEnergy=KineticEnergy + ParticleMass ;
|
||||
Psquare=KineticEnergy*(TotalEnergy+ParticleMass) ;
|
||||
Esquare=TotalEnergy*TotalEnergy ;
|
||||
summass = ParticleMass + electron_mass_c2 ;
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection() ;
|
||||
|
||||
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 )
|
||||
{
|
||||
// there is no change at all).....
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal case ......................................
|
||||
xc=DeltaCutInKineticEnergyNow/MaxKineticEnergyTransfer ;
|
||||
rate=MaxKineticEnergyTransfer/TotalEnergy ;
|
||||
|
||||
// sampling follows ...
|
||||
grejc=1.-betasquare*xc ;
|
||||
|
||||
do {
|
||||
x=xc/(1.-(1.-xc)*G4UniformRand());
|
||||
grej=(1.-x*betasquare)/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 ;
|
||||
if (finalKineticEnergy > 0.)
|
||||
{
|
||||
// changed energy and momentum of the actual particle
|
||||
finalMomentum=sqrt(finalKineticEnergy*
|
||||
(finalKineticEnergy+2.*ParticleMass)) ;
|
||||
|
||||
finalPx = (TotalMomentum*ParticleDirection.x()
|
||||
-DeltaTotalMomentum*DeltaDirection.x())/finalMomentum ;
|
||||
finalPy = (TotalMomentum*ParticleDirection.y()
|
||||
-DeltaTotalMomentum*DeltaDirection.y())/finalMomentum ;
|
||||
finalPz = (TotalMomentum*ParticleDirection.z()
|
||||
-DeltaTotalMomentum*DeltaDirection.z())/finalMomentum ;
|
||||
|
||||
aParticleChange.SetMomentumChange( finalPx,finalPy,finalPz );
|
||||
}
|
||||
else
|
||||
{
|
||||
finalKineticEnergy = 0. ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange( finalKineticEnergy );
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary( theDeltaRay );
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
void G4ionIonisation::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = " Knock-on electron cross sections . ";
|
||||
comments += "\n MeanFreePath is computed at tracking time.\n";
|
||||
comments += " delta ray energy sampled from differential Xsection.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments << G4endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user