Import Geant4 7.0.0 source tree
This commit is contained in:
@@ -1,250 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4AnnihiToMuPair.cc,v 1.3 2004/03/10 16:48:45 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-01 $
|
||||
//
|
||||
// ------------ G4AnnihiToMuPair physics process ------
|
||||
// by H.Burkhardt, S. Kelner and R. Kokoulin, November 2002
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......//
|
||||
//
|
||||
// 04.02.03 : cosmetic simplifications (mma)
|
||||
// 27.01.03 : first implementation (hbu)
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4AnnihiToMuPair.hh"
|
||||
|
||||
#include "G4ios.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
#include "G4Positron.hh"
|
||||
#include "G4MuonPlus.hh"
|
||||
#include "G4MuonMinus.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Step.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// constructor
|
||||
|
||||
G4AnnihiToMuPair::G4AnnihiToMuPair(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type)
|
||||
{
|
||||
//e+ Energy threshold
|
||||
const G4double Mu_massc2 = G4MuonPlus::MuonPlus()->GetPDGMass();
|
||||
LowestEnergyLimit = 2*Mu_massc2*Mu_massc2/electron_mass_c2 - electron_mass_c2;
|
||||
|
||||
//modele ok up to 1000 TeV due to neglected Z-interference
|
||||
HighestEnergyLimit = 1000*TeV;
|
||||
|
||||
CrossSecFactor = 1.;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4AnnihiToMuPair::~G4AnnihiToMuPair() // (empty) destructor
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4AnnihiToMuPair::IsApplicable(const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Positron::Positron() );
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4AnnihiToMuPair::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// Build cross section and mean free path tables
|
||||
//here no tables, just calling PrintInfoDefinition
|
||||
{
|
||||
PrintInfoDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4AnnihiToMuPair::SetCrossSecFactor(G4double fac)
|
||||
// Set the factor to artificially increase the cross section
|
||||
{
|
||||
CrossSecFactor = fac;
|
||||
G4cout << "The cross section for AnnihiToMuPair is artificially "
|
||||
<< "increased by the CrossSecFactor=" << CrossSecFactor << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4AnnihiToMuPair::ComputeCrossSectionPerAtom(G4double Epos, G4double Z)
|
||||
// Calculates the microscopic cross section in GEANT4 internal units.
|
||||
// It gives a good description from threshold to 1000 GeV
|
||||
{
|
||||
static const G4double Mmuon = G4MuonPlus::MuonPlus()->GetPDGMass();
|
||||
static const G4double Rmuon = elm_coupling/Mmuon; //classical particle radius
|
||||
static const G4double Sig0 = pi*Rmuon*Rmuon/3.; //constant in crossSection
|
||||
|
||||
G4double CrossSection = 0.;
|
||||
if (Epos < LowestEnergyLimit) return CrossSection;
|
||||
|
||||
G4double xi = LowestEnergyLimit/Epos;
|
||||
G4double SigmaEl = Sig0*xi*(1.+xi/2.)*sqrt(1.-xi); // per electron
|
||||
CrossSection = SigmaEl*Z; // number of electrons per atom
|
||||
CrossSection *= CrossSecFactor; //increase the CrossSection by (default 1)
|
||||
return CrossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4AnnihiToMuPair::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double, G4ForceCondition*)
|
||||
|
||||
// returns the positron mean free path in GEANT4 internal units
|
||||
|
||||
{
|
||||
const G4DynamicParticle* aDynamicPositron = aTrack.GetDynamicParticle();
|
||||
G4double PositronEnergy = aDynamicPositron->GetKineticEnergy()
|
||||
+electron_mass_c2;
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double SIGMA = 0 ;
|
||||
|
||||
for ( size_t i=0 ; i < aMaterial->GetNumberOfElements() ; i++ )
|
||||
{
|
||||
G4double AtomicZ = (*theElementVector)[i]->GetZ();
|
||||
SIGMA += NbOfAtomsPerVolume[i] *
|
||||
ComputeCrossSectionPerAtom(PositronEnergy,AtomicZ);
|
||||
}
|
||||
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VParticleChange* G4AnnihiToMuPair::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
//
|
||||
// generation of e+e- -> mu+mu-
|
||||
//
|
||||
{
|
||||
|
||||
aParticleChange.Initialize(aTrack);
|
||||
static const G4double Mele=electron_mass_c2;
|
||||
static const G4double Mmuon=G4MuonPlus::MuonPlus()->GetPDGMass();
|
||||
|
||||
// current Positron energy and direction, return if energy too low
|
||||
const G4DynamicParticle *aDynamicPositron = aTrack.GetDynamicParticle();
|
||||
G4double Epos = aDynamicPositron->GetKineticEnergy()+Mele;
|
||||
|
||||
if (Epos < LowestEnergyLimit)
|
||||
{ G4cout
|
||||
<< "error in G4AnnihiToMuPair::PostStepDoIt called with energy below"
|
||||
" threshold Epos= "
|
||||
<< Epos << G4endl; // shoud never happen
|
||||
G4Exception(10);
|
||||
}
|
||||
|
||||
if (Epos < LowestEnergyLimit)
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
|
||||
G4ParticleMomentum PositronDirection =
|
||||
aDynamicPositron->GetMomentumDirection();
|
||||
G4double xi = LowestEnergyLimit/Epos; // xi is always less than 1,
|
||||
// goes to 0 at high Epos
|
||||
|
||||
// generate cost
|
||||
//
|
||||
G4double cost;
|
||||
do cost = 2.*G4UniformRand()-1.;
|
||||
while (2.*G4UniformRand() > 1.+xi+cost*cost*(1.-xi) );
|
||||
//1+cost**2 at high Epos
|
||||
G4double sint = sqrt(1.-cost*cost);
|
||||
|
||||
// generate phi
|
||||
//
|
||||
G4double phi=2.*pi*G4UniformRand();
|
||||
|
||||
G4double Ecm = sqrt(0.5*Mele*(Epos+Mele));
|
||||
G4double Pcm = sqrt(Ecm*Ecm-Mmuon*Mmuon);
|
||||
G4double beta = sqrt((Epos-Mele)/(Epos+Mele));
|
||||
G4double gamma = Ecm/Mele; // =sqrt((Epos+Mele)/(2.*Mele));
|
||||
G4double Pt = Pcm*sint;
|
||||
|
||||
// energy and momentum of the muons in the Lab
|
||||
//
|
||||
G4double EmuPlus = gamma*( Ecm+cost*beta*Pcm);
|
||||
G4double EmuMinus = gamma*( Ecm-cost*beta*Pcm);
|
||||
G4double PmuPlusZ = gamma*(beta*Ecm+cost* Pcm);
|
||||
G4double PmuMinusZ = gamma*(beta*Ecm-cost* Pcm);
|
||||
G4double PmuPlusX = Pt*cos(phi);
|
||||
G4double PmuPlusY = Pt*sin(phi);
|
||||
G4double PmuMinusX =-Pt*cos(phi);
|
||||
G4double PmuMinusY =-Pt*sin(phi);
|
||||
// absolute momenta
|
||||
G4double PmuPlus = sqrt(Pt*Pt+PmuPlusZ *PmuPlusZ );
|
||||
G4double PmuMinus = sqrt(Pt*Pt+PmuMinusZ*PmuMinusZ);
|
||||
|
||||
// mu+ mu- directions for Positron in z-direction
|
||||
//
|
||||
G4ThreeVector
|
||||
MuPlusDirection ( PmuPlusX/PmuPlus, PmuPlusY/PmuPlus, PmuPlusZ/PmuPlus );
|
||||
G4ThreeVector
|
||||
MuMinusDirection(PmuMinusX/PmuMinus,PmuMinusY/PmuMinus,PmuMinusZ/PmuMinus);
|
||||
|
||||
// rotate to actual Positron direction
|
||||
//
|
||||
MuPlusDirection.rotateUz(PositronDirection);
|
||||
MuMinusDirection.rotateUz(PositronDirection);
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(2);
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1= new G4DynamicParticle(
|
||||
G4MuonPlus::MuonPlus(),MuPlusDirection,EmuPlus-Mmuon);
|
||||
aParticleChange.AddSecondary(aParticle1);
|
||||
// create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* aParticle2= new G4DynamicParticle(
|
||||
G4MuonMinus::MuonMinus(),MuMinusDirection,EmuMinus-Mmuon);
|
||||
aParticleChange.AddSecondary(aParticle2);
|
||||
|
||||
// Kill the incident positron
|
||||
//
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. );
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4AnnihiToMuPair::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments ="e+e->mu+mu- annihilation, atomic e- at rest.\n";
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< " threshold at " << LowestEnergyLimit/GeV << " GeV"
|
||||
<< " good description up to "
|
||||
<< HighestEnergyLimit/TeV << " TeV for all Z." << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -0,0 +1,306 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4BetheBlochModel.cc,v 1.2 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class header file
|
||||
//
|
||||
//
|
||||
// File name: G4BetheBlochModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko on base of Laszlo Urban code
|
||||
//
|
||||
// Creation date: 03.01.2002
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 04-12-02 Fix problem of G4DynamicParticle constructor (V.Ivanchenko)
|
||||
// 23-12-02 Change interface in order to move to cut per region (V.Ivanchenko)
|
||||
// 27-01-03 Make models region aware (V.Ivanchenko)
|
||||
// 13-02-03 Add name (V.Ivanchenko)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4BetheBlochModel.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4BetheBlochModel::G4BetheBlochModel(const G4ParticleDefinition* p, const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
particle(0),
|
||||
highKinEnergy(100.*TeV),
|
||||
lowKinEnergy(2.0*MeV),
|
||||
twoln10(2.0*log(10.0)),
|
||||
bg2lim(0.0169),
|
||||
taulim(8.4146e-3),
|
||||
isIon(false)
|
||||
{
|
||||
if(p) SetParticle(p);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BetheBlochModel::~G4BetheBlochModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BetheBlochModel::SetParticle(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(particle != p) {
|
||||
particle = p;
|
||||
mass = particle->GetPDGMass();
|
||||
spin = particle->GetPDGSpin();
|
||||
G4double q = particle->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
ratio = electron_mass_c2/mass;
|
||||
if(particle->GetParticleName() == "GenericIon") isIon = true;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BetheBlochModel::HighEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return highKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BetheBlochModel::LowEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return lowKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BetheBlochModel::MinEnergyCut(const G4ParticleDefinition*,
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BetheBlochModel::IsInCharge(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return (p->GetPDGCharge() != 0.0 && p->GetPDGMass() > 10.*MeV);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BetheBlochModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BetheBlochModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cut)
|
||||
{
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
G4double cutEnergy = min(cut,tmax);
|
||||
|
||||
G4double tau = kineticEnergy/mass;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double beta2 = bg2/(gam*gam);
|
||||
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
G4double eexc2 = eexc*eexc;
|
||||
G4double taul = material->GetIonisation()->GetTaul();
|
||||
G4double cden = material->GetIonisation()->GetCdensity();
|
||||
G4double mden = material->GetIonisation()->GetMdensity();
|
||||
G4double aden = material->GetIonisation()->GetAdensity();
|
||||
G4double x0den = material->GetIonisation()->GetX0density();
|
||||
G4double x1den = material->GetIonisation()->GetX1density();
|
||||
G4double* shellCorrectionVector =
|
||||
material->GetIonisation()->GetShellCorrectionVector();
|
||||
G4double eDensity = material->GetElectronDensity();
|
||||
|
||||
G4double dedx = log(2.0*electron_mass_c2*bg2*cutEnergy/eexc2)-(1.0 + cutEnergy/tmax)*beta2;
|
||||
|
||||
if(0.5 == spin) {
|
||||
G4double del = 0.5*cutEnergy/(kineticEnergy + mass);
|
||||
dedx += del*del;
|
||||
}
|
||||
|
||||
// density correction
|
||||
G4double x = log(bg2)/twoln10;
|
||||
if ( x >= x0den ) {
|
||||
dedx -= twoln10*x - cden ;
|
||||
if ( x < x1den ) dedx -= aden*pow((x1den-x),mden) ;
|
||||
}
|
||||
|
||||
// shell correction
|
||||
G4double sh = 0.0;
|
||||
x = 1.0;
|
||||
|
||||
if ( bg2 > bg2lim ) {
|
||||
for (G4int k=0; k<3; k++) {
|
||||
x *= bg2 ;
|
||||
sh += shellCorrectionVector[k]/x;
|
||||
}
|
||||
|
||||
} else {
|
||||
for (G4int k=0; k<3; k++) {
|
||||
x *= bg2lim ;
|
||||
sh += shellCorrectionVector[k]/x;
|
||||
}
|
||||
sh *= log(tau/taul)/log(taulim/taul);
|
||||
}
|
||||
dedx -= sh;
|
||||
|
||||
// now compute the total ionization loss
|
||||
|
||||
if (dedx < 0.0) dedx = 0.0 ;
|
||||
|
||||
dedx *= twopi_mc2_rcl2*chargeSquare*eDensity/beta2;
|
||||
|
||||
return dedx;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BetheBlochModel::CrossSection(const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy,
|
||||
G4double maxKinEnergy)
|
||||
{
|
||||
G4double cross = 0.0;
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
G4double maxEnergy = min(tmax,maxKinEnergy);
|
||||
if(cutEnergy < maxEnergy) {
|
||||
|
||||
G4double totEnergy = kineticEnergy + mass;
|
||||
G4double energy2 = totEnergy*totEnergy;
|
||||
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
|
||||
|
||||
cross = 1.0/cutEnergy - 1.0/maxEnergy - beta2*log(maxEnergy/cutEnergy)/tmax;
|
||||
|
||||
// +term for spin=1/2 particle
|
||||
if( 0.5 == spin ) cross += 0.5*(maxEnergy - cutEnergy)/energy2;
|
||||
|
||||
cross *= twopi_mc2_rcl2*chargeSquare*
|
||||
(couple->GetMaterial()->GetElectronDensity())/beta2;
|
||||
}
|
||||
// G4cout << "BB: e= " << kineticEnergy << " tmin= " << cutEnergy << " tmax= " << tmax
|
||||
// << " cross= " << cross << G4endl;
|
||||
return cross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DynamicParticle* G4BetheBlochModel::SampleSecondary(
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double minEnergy,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4double tmax = MaxSecondaryEnergy(dp);
|
||||
G4double maxKinEnergy = min(maxEnergy,tmax);
|
||||
G4double minKinEnergy = min(minEnergy,maxKinEnergy);
|
||||
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
G4double totEnergy = kineticEnergy + mass;
|
||||
G4double etot2 = totEnergy*totEnergy;
|
||||
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/etot2;
|
||||
|
||||
G4double deltaKinEnergy, f;
|
||||
|
||||
// sampling follows ...
|
||||
do {
|
||||
G4double q = G4UniformRand();
|
||||
deltaKinEnergy = minKinEnergy*maxKinEnergy/(minKinEnergy*(1.0 - q) + maxKinEnergy*q);
|
||||
|
||||
|
||||
f = 1.0 - beta2*deltaKinEnergy/tmax;
|
||||
if( 0.5 == spin ) f += 0.5*deltaKinEnergy*deltaKinEnergy/etot2;
|
||||
|
||||
if(f > 1.0) {
|
||||
G4cout << "G4BetheBlochModel::SampleSecondary Warning! "
|
||||
<< "Majorant 1.0 < "
|
||||
<< f << " for Edelta= " << deltaKinEnergy
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
} while( G4UniformRand() > f );
|
||||
|
||||
G4double totMomentum = totEnergy*sqrt(beta2);
|
||||
G4double deltaMomentum =
|
||||
sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
|
||||
G4double cost = deltaKinEnergy * (totEnergy + electron_mass_c2) /
|
||||
(deltaMomentum * totMomentum);
|
||||
G4double sint = sqrt(1.0 - cost*cost);
|
||||
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
|
||||
|
||||
G4ThreeVector deltaDirection(sint*cos(phi),sint*sin(phi), cost) ;
|
||||
G4ThreeVector direction = dp->GetMomentumDirection();
|
||||
deltaDirection.rotateUz(direction);
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
G4DynamicParticle* delta = new G4DynamicParticle(G4Electron::Electron(),
|
||||
deltaDirection,deltaKinEnergy);
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
vector<G4DynamicParticle*>* G4BetheBlochModel::SampleSecondaries(
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
vector<G4DynamicParticle*>* vdp = new vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
|
||||
return vdp;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4BohrFluctuations.cc,v 1.2 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4BohrFluctuations
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 02.04.2003
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 23-05-03 Add control on parthalogical cases (V.Ivanchenko)
|
||||
// 16-10-03 Changed interface to Initialisation (V.Ivanchenko)
|
||||
//
|
||||
// Class Description: Sampling of Gaussion fluctuations
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4BohrFluctuations.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4BohrFluctuations::G4BohrFluctuations(const G4String& nam)
|
||||
:G4VEmFluctuationModel(nam),
|
||||
particle(0),
|
||||
minNumberInteractionsBohr(10.0),
|
||||
minFraction(0.2),
|
||||
xmin(0.2),
|
||||
minLoss(0.001*eV)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BohrFluctuations::~G4BohrFluctuations()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BohrFluctuations::InitialiseMe(const G4ParticleDefinition* part)
|
||||
{
|
||||
particle = part;
|
||||
particleMass = part->GetPDGMass();
|
||||
G4double q = part->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BohrFluctuations::SampleFluctuations(const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length,
|
||||
G4double& meanLoss)
|
||||
{
|
||||
if(meanLoss <= minLoss) return meanLoss;
|
||||
G4double siga = Dispersion(material,dp,tmax,length);
|
||||
G4double loss = meanLoss;
|
||||
|
||||
G4double navr = minNumberInteractionsBohr;
|
||||
|
||||
// Gaussian fluctuation
|
||||
G4bool gauss = true;
|
||||
if (meanLoss < minNumberInteractionsBohr*tmax) {
|
||||
navr = meanLoss*meanLoss/siga;
|
||||
if (navr < minNumberInteractionsBohr) gauss = false;
|
||||
}
|
||||
// G4cout << "### meanLoss= " << meanLoss << " navr= " << navr << " sig= " << sqrt(siga) << G4endl;
|
||||
|
||||
if(gauss) {
|
||||
// Increase fluctuations for big fractional energy loss
|
||||
|
||||
if ( meanLoss > minFraction*kineticEnergy ) {
|
||||
G4double gam = (kineticEnergy - meanLoss)/particleMass + 1.0;
|
||||
G4double b2 = 1.0 - 1.0/(gam*gam);
|
||||
if(b2 < xmin*beta2) b2 = xmin*beta2;
|
||||
G4double x = b2/beta2;
|
||||
G4double x3 = 1.0/(x*x*x);
|
||||
siga *= 0.25*(1.0 + x)*(x3 + (1.0/b2 - 0.5)/(1.0/beta2 - 0.5) );
|
||||
}
|
||||
siga = sqrt(siga);
|
||||
|
||||
G4double twomeanLoss = meanLoss + meanLoss;
|
||||
|
||||
if(twomeanLoss < siga) {
|
||||
G4double x;
|
||||
do {
|
||||
loss = twomeanLoss*G4UniformRand();
|
||||
x = (loss - meanLoss)/siga;
|
||||
} while (1.0 - 0.5*x*x < G4UniformRand());
|
||||
} else {
|
||||
do {
|
||||
loss = G4RandGauss::shoot(meanLoss,siga);
|
||||
} while (0.0 > loss || loss > twomeanLoss);
|
||||
}
|
||||
|
||||
// Poisson fluctuations
|
||||
} else {
|
||||
G4double n = (G4double)(G4Poisson(navr));
|
||||
loss = meanLoss*n/navr;
|
||||
}
|
||||
|
||||
return loss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -0,0 +1,591 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4BraggIonModel.cc,v 1.2 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4BraggIonModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 13.10.2004
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of energy loss and delta-electron production by
|
||||
// slow charged heavy particles
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4BraggIonModel.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4BraggIonModel::G4BraggIonModel(const G4ParticleDefinition* p, const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
particle(0),
|
||||
HeMassAMU(4.0026),
|
||||
rateMass(HeMassAMU/1.007276),
|
||||
iMolecula(0),
|
||||
isIon(false)
|
||||
{
|
||||
if(p) SetParticle(p);
|
||||
highKinEnergy = 2.0*MeV;
|
||||
lowKinEnergy = 0.0*MeV;
|
||||
lowestKinEnergy = 1.0*keV;
|
||||
theZieglerFactor = eV*cm2*1.0e-15;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BraggIonModel::~G4BraggIonModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BraggIonModel::SetParticle(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(particle != p) {
|
||||
particle = p;
|
||||
mass = particle->GetPDGMass();
|
||||
spin = particle->GetPDGSpin();
|
||||
G4double q = particle->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
massRate = mass/proton_mass_c2;
|
||||
ratio = electron_mass_c2/mass;
|
||||
if(particle->GetParticleName() == "GenericIon") isIon = true;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::HighEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return highKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::LowEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return lowKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::MinEnergyCut(const G4ParticleDefinition*,
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BraggIonModel::IsInCharge(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return (p->GetPDGCharge() != 0.0 && p->GetPDGMass() > 10.*MeV);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BraggIonModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy)
|
||||
{
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
G4double tkin = kineticEnergy/massRate;
|
||||
G4double dedx = 0.0;
|
||||
if(tkin > lowestKinEnergy) dedx = DEDX(material, tkin);
|
||||
else dedx = DEDX(material, lowestKinEnergy)*sqrt(tkin/lowestKinEnergy);
|
||||
|
||||
if (cutEnergy < tmax) {
|
||||
|
||||
G4double tau = kineticEnergy/mass;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double beta2 = bg2/(gam*gam);
|
||||
G4double x = cutEnergy/tmax;
|
||||
|
||||
dedx += (log(x) + (1.0 - x)*beta2) * twopi_mc2_rcl2
|
||||
* (material->GetElectronDensity())/beta2;
|
||||
}
|
||||
|
||||
// now compute the total ionization loss
|
||||
|
||||
if (dedx < 0.0) dedx = 0.0 ;
|
||||
|
||||
dedx *= chargeSquare;
|
||||
|
||||
return dedx;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::CrossSection(const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy,
|
||||
G4double maxKinEnergy)
|
||||
{
|
||||
|
||||
G4double cross = 0.0;
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
G4double maxEnergy = min(tmax,maxKinEnergy);
|
||||
if(cutEnergy < tmax) {
|
||||
|
||||
G4double energy = kineticEnergy + mass;
|
||||
G4double energy2 = energy*energy;
|
||||
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
|
||||
cross = 1.0/cutEnergy - 1.0/maxEnergy - beta2*log(maxEnergy/cutEnergy)/tmax;
|
||||
|
||||
cross *= twopi_mc2_rcl2*chargeSquare*
|
||||
(couple->GetMaterial()->GetElectronDensity())/beta2;
|
||||
}
|
||||
// G4cout << "BR: e= " << kineticEnergy << " tmin= " << cutEnergy << " tmax= " << tmax
|
||||
// << " cross= " << cross << G4endl;
|
||||
return cross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DynamicParticle* G4BraggIonModel::SampleSecondary(
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4double tmax = MaxSecondaryEnergy(dp);
|
||||
G4double xmax = min(tmax, maxEnergy);
|
||||
G4double xmin = min(xmax,tmin);
|
||||
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
G4double energy = kineticEnergy + mass;
|
||||
G4double energy2 = energy*energy;
|
||||
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
|
||||
G4double grej = 1.0;
|
||||
G4double deltaKinEnergy, f;
|
||||
|
||||
G4ThreeVector momentum = dp->GetMomentumDirection();
|
||||
|
||||
// sampling follows ...
|
||||
do {
|
||||
G4double q = G4UniformRand();
|
||||
deltaKinEnergy = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
|
||||
|
||||
f = 1.0 - beta2*deltaKinEnergy/tmax;
|
||||
|
||||
if(f > grej) {
|
||||
G4cout << "G4BraggIonModel::SampleSecondary Warning! "
|
||||
<< "Majorant " << grej << " < "
|
||||
<< f << " for e= " << deltaKinEnergy
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
} while( grej*G4UniformRand() >= f );
|
||||
|
||||
G4double deltaMomentum =
|
||||
sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
|
||||
G4double totMomentum = sqrt(energy2 - mass*mass);
|
||||
G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
|
||||
(deltaMomentum * totMomentum);
|
||||
G4double sint = sqrt(1.0 - cost*cost);
|
||||
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
|
||||
G4ThreeVector deltaDirection(sint*cos(phi),sint*sin(phi), cost) ;
|
||||
deltaDirection.rotateUz(momentum);
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
G4DynamicParticle* delta = new G4DynamicParticle(G4Electron::Electron(),
|
||||
deltaDirection,deltaKinEnergy);
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
vector<G4DynamicParticle*>* G4BraggIonModel::SampleSecondaries(
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
vector<G4DynamicParticle*>* vdp = new vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
|
||||
return vdp;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BraggIonModel::HasMaterial(const G4Material* material)
|
||||
{
|
||||
G4String chFormula = material->GetChemicalFormula() ;
|
||||
|
||||
// ICRU Report N49, 1993. Power's model for He.
|
||||
const size_t numberOfMolecula = 30 ;
|
||||
SetMoleculaNumber(numberOfMolecula) ;
|
||||
static G4String name[numberOfMolecula] = {
|
||||
"H_2", "Be-Solid", "C-Solid", "Graphite", "N_2",
|
||||
"O_2", "Al-Solid", "Si-Solid", "Ar-Solid", "Cu-Solid",
|
||||
"Ge", "W-Solid", "Au-Solid", "Pb-Solid", "C_2H_2",
|
||||
"CO_2", "Cellulose-Nitrat", "C_2H_4", "LiF",
|
||||
"CH_4", "Nylon", "Polycarbonate", "(CH_2)_N-Polyetilene", "PMMA",
|
||||
"(C_8H_8)_N", "SiO_2", "CsI", "H_2O", "H_2O-Gas"} ;
|
||||
|
||||
// Special treatment for water in gas state
|
||||
|
||||
const G4State theState = material->GetState() ;
|
||||
if( theState == kStateGas && "H_2O" == chFormula)
|
||||
chFormula = G4String("H_2O-Gas");
|
||||
|
||||
// Search for the material in the table
|
||||
for (size_t i=0; i<numberOfMolecula; i++) {
|
||||
if (chFormula == name[i]) {
|
||||
SetMoleculaNumber(i) ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::StoppingPower(const G4Material* material,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
G4double ionloss = 0.0 ;
|
||||
|
||||
if (iMolecula < 30) {
|
||||
|
||||
// The data and the fit from:
|
||||
// ICRU Report N49, 1993. Ziegler's model for protons.
|
||||
// Proton kinetic energy for parametrisation (keV/amu)
|
||||
|
||||
G4double T = kineticEnergy*rateMass/MeV ;
|
||||
|
||||
static G4double c[30][7] = {
|
||||
{8.0080, 3.6287, 23.0700, 14.9900, 0.8507, 0.60, 2.0
|
||||
},{ 13.3100, 3.7432, 39.4130, 12.1990, 1.0950, 0.38, 1.4
|
||||
},{ 22.7240, 3.6040, 47.1810, 17.5490, 0.9040, 0.40, 1.4
|
||||
},{ 24.4040, 2.4032, 48.9440, 27.9730, 1.2933, 0.40, 1.6
|
||||
},{ 58.4719, 1.5115, 77.6421, 102.490, 1.5811, 0.50, 2.0
|
||||
},{ 60.5408, 1.6297, 91.7601, 94.1260, 1.3662, 0.50, 2.0
|
||||
},{ 48.4480, 6.4323, 59.2890, 18.3810, 0.4937, 0.48, 1.6
|
||||
},{ 59.0346, 5.1305, 47.0866, 30.0857, 0.3500, 0.60, 2.0
|
||||
},{ 71.8691, 2.8250, 51.1658, 57.1235, 0.4477, 0.60, 2.0
|
||||
},{ 78.3520, 4.0961, 136.731, 28.4470, 1.0621, 0.52, 1.2
|
||||
},{ 120.553, 1.5374, 49.8740, 82.2980, 0.8733, 0.45, 1.6
|
||||
},{ 249.896, 0.6996, -37.274, 248.592, 1.1052, 0.50, 1.5
|
||||
},{ 246.698, 0.6219, -58.391, 292.921, 0.8186, 0.56, 1.8
|
||||
},{ 248.563, 0.6235, -36.8968, 306.960, 1.3214, 0.50, 2.0
|
||||
},{ 25.5860, 1.7125, 154.723, 118.620, 2.2580, 0.50, 2.0
|
||||
},{ 138.294, 25.6413, 231.873, 17.3780, 0.3218, 0.58, 1.3
|
||||
},{ 83.2091, 1.1294, 135.7457, 190.865, 2.3461, 0.50, 2.0
|
||||
},{ 263.542, 1.4754, 1541.446, 781.898, 1.9209, 0.40, 2.0
|
||||
},{ 59.5545, 1.5354, 132.1523, 153.3537, 2.0262, 0.50, 2.0
|
||||
},{ 31.7380, 19.820, 125.2100, 6.8910, 0.7242, 0.50, 1.1
|
||||
},{ 31.7549, 1.5682, 97.4777, 106.0774, 2.3204, 0.50, 2.0
|
||||
},{ 230.465, 4.8967, 1845.320, 358.641, 1.0774, 0.46, 1.2
|
||||
},{ 423.444, 5.3761, 1189.114, 319.030, 0.7652, 0.48, 1.5
|
||||
},{ 86.3410, 3.3322, 91.0433, 73.1091, 0.4650, 0.50, 2.0
|
||||
},{ 146.105, 9.4344, 515.1500, 82.8860, 0.6239, 0.55, 1.5
|
||||
},{ 238.050, 5.6901, 372.3575, 146.1835, 0.3992, 0.50, 2.0
|
||||
},{ 124.2338, 2.6730, 133.8175, 99.4109, 0.7776, 0.50, 2.0
|
||||
},{ 221.723, 1.5415, 87.7315, 192.5266, 1.0742, 0.50, 2.0
|
||||
},{ 26.7537, 1.3717, 90.8007, 77.1587, 2.3264, 0.50, 2.0
|
||||
},{ 37.6121, 1.8052, 73.0250, 66.2070, 1.4038, 0.50, 2.0} };
|
||||
|
||||
G4double a1,a2 ;
|
||||
// Free electron gas model
|
||||
if ( T < 0.001 ) {
|
||||
G4double T0 = 0.001 ;
|
||||
a1 = 1.0 - exp(-c[iMolecula][1]*pow(T0,-2.0+c[iMolecula][5])) ;
|
||||
a2 = (c[iMolecula][0]*log(T0)/T0 + c[iMolecula][2]/T0) *
|
||||
exp(-c[iMolecula][4]*pow(T0,-c[iMolecula][6])) +
|
||||
c[iMolecula][3]/(T0*T0) ;
|
||||
|
||||
ionloss *= sqrt(T/T0) ;
|
||||
|
||||
// Main parametrisation
|
||||
} else {
|
||||
a1 = 1.0 - exp(-c[iMolecula][1]*pow(T,-2.0+c[iMolecula][5])) ;
|
||||
a2 = (c[iMolecula][0]*log(T)/T + c[iMolecula][2]/T) *
|
||||
exp(-c[iMolecula][4]*pow(T,-c[iMolecula][6])) +
|
||||
c[iMolecula][3]/(T*T) ;
|
||||
}
|
||||
|
||||
// He effective charge
|
||||
G4double z = (material->GetTotNbOfElectPerVolume()) /
|
||||
(material->GetTotNbOfAtomsPerVolume()) ;
|
||||
|
||||
ionloss = a1*a2 / HeEffChargeSquare(z, T*keV) ;
|
||||
|
||||
if ( ionloss < 0.0) ionloss = 0.0 ;
|
||||
}
|
||||
|
||||
return ionloss ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::ElectronicStoppingPower(G4double z,
|
||||
G4double kineticEnergy) const
|
||||
{
|
||||
G4double ionloss ;
|
||||
G4int i = G4int(z)-1 ; // index of atom
|
||||
if(i < 0) i = 0 ;
|
||||
if(i > 91) i = 91 ;
|
||||
|
||||
// The data and the fit from:
|
||||
// ICRU Report 49, 1993. Ziegler's type of parametrisations.
|
||||
// Proton kinetic energy for parametrisation (keV/amu)
|
||||
|
||||
// He energy in internal units of parametrisation formula (MeV)
|
||||
G4double T = kineticEnergy*rateMass/MeV ;
|
||||
|
||||
static G4double a[92][5] = {
|
||||
{0.35485, 0.6456, 6.01525, 20.8933, 4.3515
|
||||
},{ 0.58, 0.59, 6.3, 130.0, 44.07
|
||||
},{ 1.42, 0.49, 12.25, 32.0, 9.161
|
||||
},{ 2.1895, 0.47183,7.2362, 134.30, 197.96
|
||||
},{ 3.691, 0.4128, 18.48, 50.72, 9.0
|
||||
},{ 3.83523, 0.42993,12.6125, 227.41, 188.97
|
||||
},{ 1.9259, 0.5550, 27.15125, 26.0665, 6.2768
|
||||
},{ 2.81015, 0.4759, 50.0253, 10.556, 1.0382
|
||||
},{ 1.533, 0.531, 40.44, 18.41, 2.718
|
||||
},{ 2.303, 0.4861, 37.01, 37.96, 5.092
|
||||
},{ 9.894, 0.3081, 23.65, 0.384, 92.93
|
||||
},{ 4.3, 0.47, 34.3, 3.3, 12.74
|
||||
},{ 2.5, 0.625, 45.7, 0.1, 4.359
|
||||
},{ 2.1, 0.65, 49.34, 1.788, 4.133
|
||||
},{ 1.729, 0.6562, 53.41, 2.405, 3.845
|
||||
},{ 1.402, 0.6791, 58.98, 3.528, 3.211
|
||||
},{ 1.117, 0.7044, 69.69, 3.705, 2.156
|
||||
},{ 2.291, 0.6284, 73.88, 4.478, 2.066
|
||||
},{ 8.554, 0.3817, 83.61, 11.84, 1.875
|
||||
},{ 6.297, 0.4622, 65.39, 10.14, 5.036
|
||||
},{ 5.307, 0.4918, 61.74, 12.4, 6.665
|
||||
},{ 4.71, 0.5087, 65.28, 8.806, 5.948
|
||||
},{ 6.151, 0.4524, 83.0, 18.31, 2.71
|
||||
},{ 6.57, 0.4322, 84.76, 15.53, 2.779
|
||||
},{ 5.738, 0.4492, 84.6, 14.18, 3.101
|
||||
},{ 5.013, 0.4707, 85.8, 16.55, 3.211
|
||||
},{ 4.32, 0.4947, 76.14, 10.85, 5.441
|
||||
},{ 4.652, 0.4571, 80.73, 22.0, 4.952
|
||||
},{ 3.114, 0.5236, 76.67, 7.62, 6.385
|
||||
},{ 3.114, 0.5236, 76.67, 7.62, 7.502
|
||||
},{ 3.114, 0.5236, 76.67, 7.62, 8.514
|
||||
},{ 5.746, 0.4662, 79.24, 1.185, 7.993
|
||||
},{ 2.792, 0.6346, 106.1, 0.2986, 2.331
|
||||
},{ 4.667, 0.5095, 124.3, 2.102, 1.667
|
||||
},{ 2.44, 0.6346, 105.0, 0.83, 2.851
|
||||
},{ 1.413, 0.7377, 147.9, 1.466, 1.016
|
||||
},{ 11.72, 0.3826, 102.8, 9.231, 4.371
|
||||
},{ 7.126, 0.4804, 119.3, 5.784, 2.454
|
||||
},{ 11.61, 0.3955, 146.7, 7.031, 1.423
|
||||
},{ 10.99, 0.41, 163.9, 7.1, 1.052
|
||||
},{ 9.241, 0.4275, 163.1, 7.954, 1.102
|
||||
},{ 9.276, 0.418, 157.1, 8.038, 1.29
|
||||
},{ 3.999, 0.6152, 97.6, 1.297, 5.792
|
||||
},{ 4.306, 0.5658, 97.99, 5.514, 5.754
|
||||
},{ 3.615, 0.6197, 86.26, 0.333, 8.689
|
||||
},{ 5.8, 0.49, 147.2, 6.903, 1.289
|
||||
},{ 5.6, 0.49, 130.0, 10.0, 2.844
|
||||
},{ 3.55, 0.6068, 124.7, 1.112, 3.119
|
||||
},{ 3.6, 0.62, 105.8, 0.1692, 6.026
|
||||
},{ 5.4, 0.53, 103.1, 3.931, 7.767
|
||||
},{ 3.97, 0.6459, 131.8, 0.2233, 2.723
|
||||
},{ 3.65, 0.64, 126.8, 0.6834, 3.411
|
||||
},{ 3.118, 0.6519, 164.9, 1.208, 1.51
|
||||
},{ 3.949, 0.6209, 200.5, 1.878, 0.9126
|
||||
},{ 14.4, 0.3923, 152.5, 8.354, 2.597
|
||||
},{ 10.99, 0.4599, 138.4, 4.811, 3.726
|
||||
},{ 16.6, 0.3773, 224.1, 6.28, 0.9121
|
||||
},{ 10.54, 0.4533, 159.3, 4.832, 2.529
|
||||
},{ 10.33, 0.4502, 162.0, 5.132, 2.444
|
||||
},{ 10.15, 0.4471, 165.6, 5.378, 2.328
|
||||
},{ 9.976, 0.4439, 168.0, 5.721, 2.258
|
||||
},{ 9.804, 0.4408, 176.2, 5.675, 1.997
|
||||
},{ 14.22, 0.363, 228.4, 7.024, 1.016
|
||||
},{ 9.952, 0.4318, 233.5, 5.065, 0.9244
|
||||
},{ 9.272, 0.4345, 210.0, 4.911, 1.258
|
||||
},{ 10.13, 0.4146, 225.7, 5.525, 1.055
|
||||
},{ 8.949, 0.4304, 213.3, 5.071, 1.221
|
||||
},{ 11.94, 0.3783, 247.2, 6.655, 0.849
|
||||
},{ 8.472, 0.4405, 195.5, 4.051, 1.604
|
||||
},{ 8.301, 0.4399, 203.7, 3.667, 1.459
|
||||
},{ 6.567, 0.4858, 193.0, 2.65, 1.66
|
||||
},{ 5.951, 0.5016, 196.1, 2.662, 1.589
|
||||
},{ 7.495, 0.4523, 251.4, 3.433, 0.8619
|
||||
},{ 6.335, 0.4825, 255.1, 2.834, 0.8228
|
||||
},{ 4.314, 0.5558, 214.8, 2.354, 1.263
|
||||
},{ 4.02, 0.5681, 219.9, 2.402, 1.191
|
||||
},{ 3.836, 0.5765, 210.2, 2.742, 1.305
|
||||
},{ 4.68, 0.5247, 244.7, 2.749, 0.8962
|
||||
},{ 3.223, 0.5883, 232.7, 2.954, 1.05
|
||||
},{ 2.892, 0.6204, 208.6, 2.415, 1.416
|
||||
},{ 4.728, 0.5522, 217.0, 3.091, 1.386
|
||||
},{ 6.18, 0.52, 170.0, 4.0, 3.224
|
||||
},{ 9.0, 0.47, 198.0, 3.8, 2.032
|
||||
},{ 2.324, 0.6997, 216.0, 1.599, 1.399
|
||||
},{ 1.961, 0.7286, 223.0, 1.621, 1.296
|
||||
},{ 1.75, 0.7427, 350.1, 0.9789, 0.5507
|
||||
},{ 10.31, 0.4613, 261.2, 4.738, 0.9899
|
||||
},{ 7.962, 0.519, 235.7, 4.347, 1.313
|
||||
},{ 6.227, 0.5645, 231.9, 3.961, 1.379
|
||||
},{ 5.246, 0.5947, 228.6, 4.027, 1.432
|
||||
},{ 5.408, 0.5811, 235.7, 3.961, 1.358
|
||||
},{ 5.218, 0.5828, 245.0, 3.838, 1.25}
|
||||
};
|
||||
|
||||
// Free electron gas model
|
||||
if ( T < 0.001 ) {
|
||||
G4double slow = a[i][0] ;
|
||||
G4double shigh = log( 1.0 + a[i][3]*1000.0 + a[i][4]*0.001 )
|
||||
* a[i][2]*1000.0 ;
|
||||
ionloss = slow*shigh / (slow + shigh) ;
|
||||
ionloss *= sqrt(T*1000.0) ;
|
||||
|
||||
// Main parametrisation
|
||||
} else {
|
||||
G4double slow = a[i][0] * pow((T*1000.0), a[i][1]) ;
|
||||
G4double shigh = log( 1.0 + a[i][3]/T + a[i][4]*T ) * a[i][2]/T ;
|
||||
ionloss = slow*shigh / (slow + shigh) ;
|
||||
|
||||
}
|
||||
if ( ionloss < 0.0) ionloss = 0.0 ;
|
||||
|
||||
// He effective charge
|
||||
ionloss /= HeEffChargeSquare(z, T*MeV);
|
||||
|
||||
return ionloss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::DEDX(const G4Material* material,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
G4double eloss = 0.0;
|
||||
const G4int numberOfElements = material->GetNumberOfElements();
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector();
|
||||
|
||||
// compaund material with parametrisation
|
||||
if( HasMaterial(material) ) {
|
||||
|
||||
eloss = StoppingPower(material, kineticEnergy)
|
||||
* (material->GetTotNbOfAtomsPerVolume());
|
||||
eloss *= material->GetTotNbOfAtomsPerVolume();
|
||||
if(1 < numberOfElements) {
|
||||
G4int nAtoms = 0;
|
||||
|
||||
const G4int* theAtomsVector = material->GetAtomsVector();
|
||||
for (G4int iel=0; iel<numberOfElements; iel++) {
|
||||
nAtoms += theAtomsVector[iel];
|
||||
}
|
||||
eloss /= nAtoms;
|
||||
}
|
||||
// pure material
|
||||
} else if(1 == numberOfElements) {
|
||||
|
||||
G4double z = material->GetZ();
|
||||
eloss = ElectronicStoppingPower(z, kineticEnergy)
|
||||
* (material->GetTotNbOfAtomsPerVolume());
|
||||
|
||||
// Brugg's rule calculation
|
||||
} else {
|
||||
const G4ElementVector* theElementVector =
|
||||
material->GetElementVector() ;
|
||||
|
||||
// loop for the elements in the material
|
||||
for (G4int i=0; i<numberOfElements; i++)
|
||||
{
|
||||
const G4Element* element = (*theElementVector)[i] ;
|
||||
eloss += ElectronicStoppingPower(element->GetZ(), kineticEnergy)
|
||||
* theAtomicNumDensityVector[i];
|
||||
}
|
||||
}
|
||||
return eloss*theZieglerFactor;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggIonModel::HeEffChargeSquare(G4double z, G4double kinEnergyHe) const
|
||||
{
|
||||
// The aproximation of He effective charge from:
|
||||
// J.F.Ziegler, J.P. Biersack, U. Littmark
|
||||
// The Stopping and Range of Ions in Matter,
|
||||
// Vol.1, Pergamon Press, 1985
|
||||
|
||||
static G4double c[6] = {0.2865, 0.1266, -0.001429,
|
||||
0.02402,-0.01135, 0.001475} ;
|
||||
|
||||
G4double e = log( max( 1.0, kinEnergyHe/(keV*HeMassAMU))) ;
|
||||
G4double x = c[0] ;
|
||||
G4double y = 1.0 ;
|
||||
for (G4int i=1; i<6; i++) {
|
||||
y *= e ;
|
||||
x += y * c[i] ;
|
||||
}
|
||||
|
||||
G4double w = 7.6 - e ;
|
||||
w = 1.0 + (0.007 + 0.00005*z) * exp( -w*w ) ;
|
||||
w = 4.0 * (1.0 - exp(-x)) * w * w ;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -0,0 +1,693 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4BraggModel.cc,v 1.2 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4BraggModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 03.01.2002
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 04-12-02 Fix problem of G4DynamicParticle constructor (V.Ivanchenko)
|
||||
// 23-12-02 Change interface in order to move to cut per region (V.Ivanchenko)
|
||||
// 27-01-03 Make models region aware (V.Ivanchenko)
|
||||
// 13-02-03 Add name (V.Ivanchenko)
|
||||
// 04-06-03 Fix compilation warnings (V.Ivanchenko)
|
||||
// 12-09-04 Add lowestKinEnergy and change order of if in DEDX method (V.Ivanchenko)
|
||||
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of energy loss and delta-electron production by
|
||||
// slow charged heavy particles
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4BraggModel.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4BraggModel::G4BraggModel(const G4ParticleDefinition* p, const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
particle(0),
|
||||
protonMassAMU(1.007276),
|
||||
iMolecula(0),
|
||||
isIon(false)
|
||||
{
|
||||
if(p) SetParticle(p);
|
||||
highKinEnergy = 2.0*MeV;
|
||||
lowKinEnergy = 0.0*MeV;
|
||||
lowestKinEnergy = 1.0*keV;
|
||||
theZieglerFactor = eV*cm2*1.0e-15;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BraggModel::~G4BraggModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BraggModel::SetParticle(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(particle != p) {
|
||||
particle = p;
|
||||
mass = particle->GetPDGMass();
|
||||
spin = particle->GetPDGSpin();
|
||||
G4double q = particle->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
massRate = mass/proton_mass_c2;
|
||||
ratio = electron_mass_c2/mass;
|
||||
if(particle->GetParticleName() == "GenericIon") isIon = true;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::HighEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return highKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::LowEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return lowKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::MinEnergyCut(const G4ParticleDefinition*,
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BraggModel::IsInCharge(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return (p->GetPDGCharge() != 0.0 && p->GetPDGMass() > 10.*MeV);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BraggModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy)
|
||||
{
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
G4double tkin = kineticEnergy/massRate;
|
||||
G4double dedx = 0.0;
|
||||
if(tkin > lowestKinEnergy) dedx = DEDX(material, tkin);
|
||||
else dedx = DEDX(material, lowestKinEnergy)*sqrt(tkin/lowestKinEnergy);
|
||||
|
||||
if (cutEnergy < tmax) {
|
||||
|
||||
G4double tau = kineticEnergy/mass;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double beta2 = bg2/(gam*gam);
|
||||
G4double x = cutEnergy/tmax;
|
||||
|
||||
dedx += (log(x) + (1.0 - x)*beta2) * twopi_mc2_rcl2
|
||||
* (material->GetElectronDensity())/beta2;
|
||||
}
|
||||
|
||||
// now compute the total ionization loss
|
||||
|
||||
if (dedx < 0.0) dedx = 0.0 ;
|
||||
|
||||
dedx *= chargeSquare;
|
||||
|
||||
return dedx;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::CrossSection(const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy,
|
||||
G4double maxKinEnergy)
|
||||
{
|
||||
|
||||
G4double cross = 0.0;
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
G4double maxEnergy = min(tmax,maxKinEnergy);
|
||||
if(cutEnergy < tmax) {
|
||||
|
||||
G4double energy = kineticEnergy + mass;
|
||||
G4double energy2 = energy*energy;
|
||||
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
|
||||
cross = 1.0/cutEnergy - 1.0/maxEnergy - beta2*log(maxEnergy/cutEnergy)/tmax;
|
||||
|
||||
cross *= twopi_mc2_rcl2*chargeSquare*
|
||||
(couple->GetMaterial()->GetElectronDensity())/beta2;
|
||||
}
|
||||
// G4cout << "BR: e= " << kineticEnergy << " tmin= " << cutEnergy << " tmax= " << tmax
|
||||
// << " cross= " << cross << G4endl;
|
||||
return cross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DynamicParticle* G4BraggModel::SampleSecondary(
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4double tmax = MaxSecondaryEnergy(dp);
|
||||
G4double xmax = min(tmax, maxEnergy);
|
||||
G4double xmin = min(xmax,tmin);
|
||||
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
G4double energy = kineticEnergy + mass;
|
||||
G4double energy2 = energy*energy;
|
||||
G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*mass)/energy2;
|
||||
G4double grej = 1.0;
|
||||
G4double deltaKinEnergy, f;
|
||||
|
||||
G4ThreeVector momentum = dp->GetMomentumDirection();
|
||||
|
||||
// sampling follows ...
|
||||
do {
|
||||
G4double q = G4UniformRand();
|
||||
deltaKinEnergy = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
|
||||
|
||||
f = 1.0 - beta2*deltaKinEnergy/tmax;
|
||||
|
||||
if(f > grej) {
|
||||
G4cout << "G4BraggModel::SampleSecondary Warning! "
|
||||
<< "Majorant " << grej << " < "
|
||||
<< f << " for e= " << deltaKinEnergy
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
} while( grej*G4UniformRand() >= f );
|
||||
|
||||
G4double deltaMomentum =
|
||||
sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
|
||||
G4double totMomentum = sqrt(energy2 - mass*mass);
|
||||
G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
|
||||
(deltaMomentum * totMomentum);
|
||||
G4double sint = sqrt(1.0 - cost*cost);
|
||||
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
|
||||
G4ThreeVector deltaDirection(sint*cos(phi),sint*sin(phi), cost) ;
|
||||
deltaDirection.rotateUz(momentum);
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
G4DynamicParticle* delta = new G4DynamicParticle(G4Electron::Electron(),
|
||||
deltaDirection,deltaKinEnergy);
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
vector<G4DynamicParticle*>* G4BraggModel::SampleSecondaries(
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
vector<G4DynamicParticle*>* vdp = new vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
|
||||
return vdp;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BraggModel::HasMaterial(const G4Material* material)
|
||||
{
|
||||
const size_t numberOfMolecula = 11 ;
|
||||
SetMoleculaNumber(numberOfMolecula) ;
|
||||
G4String chFormula = material->GetChemicalFormula() ;
|
||||
|
||||
// ICRU Report N49, 1993. Power's model for He.
|
||||
static G4String molName[numberOfMolecula] = {
|
||||
"Al_2O_3", "CO_2", "CH_4",
|
||||
"(C_2H_4)_N-Polyethylene", "(C_2H_4)_N-Polypropylene", "(C_8H_8)_N",
|
||||
"C_3H_8", "SiO_2", "H_2O",
|
||||
"H_2O-Gas", "Graphite" } ;
|
||||
|
||||
// Special treatment for water in gas state
|
||||
const G4State theState = material->GetState() ;
|
||||
|
||||
if( theState == kStateGas && "H_2O" == chFormula) {
|
||||
chFormula = G4String("H_2O-Gas");
|
||||
}
|
||||
|
||||
// Search for the material in the table
|
||||
for (size_t i=0; i<numberOfMolecula; i++) {
|
||||
if (chFormula == molName[i]) {
|
||||
SetMoleculaNumber(i) ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::StoppingPower(const G4Material* material,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
G4double ionloss = 0.0 ;
|
||||
|
||||
if (iMolecula < 11) {
|
||||
|
||||
// The data and the fit from:
|
||||
// ICRU Report N49, 1993. Ziegler's model for protons.
|
||||
// Proton kinetic energy for parametrisation (keV/amu)
|
||||
|
||||
G4double T = kineticEnergy/(keV*protonMassAMU) ;
|
||||
|
||||
static G4double a[11][5] = {
|
||||
{1.187E+1, 1.343E+1, 1.069E+4, 7.723E+2, 2.153E-2},
|
||||
{7.802E+0, 8.814E+0, 8.303E+3, 7.446E+2, 7.966E-3},
|
||||
{7.294E+0, 8.284E+0, 5.010E+3, 4.544E+2, 8.153E-3},
|
||||
{8.646E+0, 9.800E+0, 7.066E+3, 4.581E+2, 9.383E-3},
|
||||
{1.286E+1, 1.462E+1, 5.625E+3, 2.621E+3, 3.512E-2},
|
||||
{3.229E+1, 3.696E+1, 8.918E+3, 3.244E+3, 1.273E-1},
|
||||
{1.604E+1, 1.825E+1, 6.967E+3, 2.307E+3, 3.775E-2},
|
||||
{8.049E+0, 9.099E+0, 9.257E+3, 3.846E+2, 1.007E-2},
|
||||
{4.015E+0, 4.542E+0, 3.955E+3, 4.847E+2, 7.904E-3},
|
||||
{4.571E+0, 5.173E+0, 4.346E+3, 4.779E+2, 8.572E-3},
|
||||
{2.631E+0, 2.601E+0, 1.701E+3, 1.279E+3, 1.638E-2} };
|
||||
|
||||
|
||||
if ( T < 10.0 ) {
|
||||
ionloss = a[iMolecula][0] * sqrt(T) ;
|
||||
|
||||
} else if ( T < 10000.0 ) {
|
||||
G4double slow = a[iMolecula][1] * pow(T, 0.45) ;
|
||||
G4double shigh = log( 1.0 + a[iMolecula][3]/T
|
||||
+ a[iMolecula][4]*T ) * a[iMolecula][2]/T ;
|
||||
ionloss = slow*shigh / (slow + shigh) ;
|
||||
}
|
||||
|
||||
if ( ionloss < 0.0) ionloss = 0.0 ;
|
||||
if ( 10 == iMolecula ) {
|
||||
if (T < 100.0) {
|
||||
ionloss *= (1.0+0.023+0.0066*log10(T));
|
||||
}
|
||||
else if (T < 700.0) {
|
||||
ionloss *=(1.0+0.089-0.0248*log10(T-99.));
|
||||
}
|
||||
else if (T < 10000.0) {
|
||||
ionloss *=(1.0+0.089-0.0248*log10(700.-99.));
|
||||
}
|
||||
}
|
||||
|
||||
// pure material (normally not the case for this function)
|
||||
} else if(1 == (material->GetNumberOfElements())) {
|
||||
G4double z = material->GetZ() ;
|
||||
ionloss = ElectronicStoppingPower( z, kineticEnergy ) ;
|
||||
}
|
||||
|
||||
return ionloss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::ElectronicStoppingPower(G4double z,
|
||||
G4double kineticEnergy) const
|
||||
{
|
||||
G4double ionloss ;
|
||||
G4int i = G4int(z)-1 ; // index of atom
|
||||
if(i < 0) i = 0 ;
|
||||
if(i > 91) i = 91 ;
|
||||
|
||||
// The data and the fit from:
|
||||
// ICRU Report 49, 1993. Ziegler's type of parametrisations.
|
||||
// Proton kinetic energy for parametrisation (keV/amu)
|
||||
|
||||
G4double T = kineticEnergy/(keV*protonMassAMU) ;
|
||||
|
||||
static G4double a[92][5] = {
|
||||
{1.254E+0, 1.440E+0, 2.426E+2, 1.200E+4, 1.159E-1},
|
||||
{1.229E+0, 1.397E+0, 4.845E+2, 5.873E+3, 5.225E-2},
|
||||
{1.411E+0, 1.600E+0, 7.256E+2, 3.013E+3, 4.578E-2},
|
||||
{2.248E+0, 2.590E+0, 9.660E+2, 1.538E+2, 3.475E-2},
|
||||
{2.474E+0, 2.815E+0, 1.206E+3, 1.060E+3, 2.855E-2},
|
||||
{2.631E+0, 2.601E+0, 1.701E+3, 1.279E+3, 1.638E-2},
|
||||
{2.954E+0, 3.350E+0, 1.683E+3, 1.900E+3, 2.513E-2},
|
||||
{2.652E+0, 3.000E+0, 1.920E+3, 2.000E+3, 2.230E-2},
|
||||
{2.085E+0, 2.352E+0, 2.157E+3, 2.634E+3, 1.816E-2},
|
||||
{1.951E+0, 2.199E+0, 2.393E+3, 2.699E+3, 1.568E-2},
|
||||
{2.542E+0, 2.869E+0, 2.628E+3, 1.854E+3, 1.472E-2},
|
||||
{3.791E+0, 4.293E+0, 2.862E+3, 1.009E+3, 1.397E-2},
|
||||
{4.154E+0, 4.739E+0, 2.766E+3, 1.645E+2, 2.023E-2},
|
||||
{4.914E+0, 5.598E+0, 3.193E+3, 2.327E+2, 1.419E-2},
|
||||
{3.232E+0, 3.647E+0, 3.561E+3, 1.560E+3, 1.267E-2},
|
||||
{3.447E+0, 3.891E+0, 3.792E+3, 1.219E+3, 1.211E-2},
|
||||
{5.301E+0, 6.008E+0, 3.969E+3, 6.451E+2, 1.183E-2},
|
||||
{5.731E+0, 6.500E+0, 4.253E+3, 5.300E+2, 1.123E-2},
|
||||
{5.152E+0, 5.833E+0, 4.482E+3, 5.457E+2, 1.129E-2},
|
||||
{5.521E+0, 6.252E+0, 4.710E+3, 5.533E+2, 1.112E-2},
|
||||
{5.201E+0, 5.884E+0, 4.938E+3, 5.609E+2, 9.995E-3},
|
||||
{4.858E+0, 5.489E+0, 5.260E+3, 6.511E+2, 8.930E-3},
|
||||
{4.479E+0, 5.055E+0, 5.391E+3, 9.523E+2, 9.117E-3},
|
||||
{3.983E+0, 4.489E+0, 5.616E+3, 1.336E+3, 8.413E-3},
|
||||
{3.469E+0, 3.907E+0, 5.725E+3, 1.461E+3, 8.829E-3},
|
||||
{3.519E+0, 3.963E+0, 6.065E+3, 1.243E+3, 7.782E-3},
|
||||
{3.140E+0, 3.535E+0, 6.288E+3, 1.372E+3, 7.361E-3},
|
||||
{3.553E+0, 4.004E+0, 6.205E+3, 5.551E+2, 8.763E-3},
|
||||
{3.696E+0, 4.194E+0, 4.649E+3, 8.113E+1, 2.242E-2},
|
||||
{4.210E+0, 4.750E+0, 6.953E+3, 2.952E+2, 6.809E-3},
|
||||
{5.041E+0, 5.697E+0, 7.173E+3, 2.026E+2, 6.725E-3},
|
||||
{5.554E+0, 6.300E+0, 6.496E+3, 1.100E+2, 9.689E-3},
|
||||
{5.323E+0, 6.012E+0, 7.611E+3, 2.925E+2, 6.447E-3},
|
||||
{5.874E+0, 6.656E+0, 7.395E+3, 1.175E+2, 7.684E-3},
|
||||
{6.658E+0, 7.536E+0, 7.694E+3, 2.223E+2, 6.509E-3},
|
||||
{6.413E+0, 7.240E+0, 1.185E+4, 1.537E+2, 2.880E-3},
|
||||
{5.694E+0, 6.429E+0, 8.478E+3, 2.929E+2, 6.087E-3},
|
||||
{6.339E+0, 7.159E+0, 8.693E+3, 3.303E+2, 6.003E-3},
|
||||
{6.407E+0, 7.234E+0, 8.907E+3, 3.678E+2, 5.889E-3},
|
||||
{6.734E+0, 7.603E+0, 9.120E+3, 4.052E+2, 5.765E-3},
|
||||
{6.901E+0, 7.791E+0, 9.333E+3, 4.427E+2, 5.587E-3},
|
||||
{6.424E+0, 7.248E+0, 9.545E+3, 4.802E+2, 5.376E-3},
|
||||
{6.799E+0, 7.671E+0, 9.756E+3, 5.176E+2, 5.315E-3},
|
||||
{6.109E+0, 6.887E+0, 9.966E+3, 5.551E+2, 5.151E-3},
|
||||
{5.924E+0, 6.677E+0, 1.018E+4, 5.925E+2, 4.919E-3},
|
||||
{5.238E+0, 5.900E+0, 1.038E+4, 6.300E+2, 4.758E-3},
|
||||
{5.345E+0, 6.038E+0, 6.790E+3, 3.978E+2, 1.676E-2},
|
||||
{5.814E+0, 6.554E+0, 1.080E+4, 3.555E+2, 4.626E-3},
|
||||
{6.229E+0, 7.024E+0, 1.101E+4, 3.709E+2, 4.540E-3},
|
||||
{6.409E+0, 7.227E+0, 1.121E+4, 3.864E+2, 4.474E-3},
|
||||
{7.500E+0, 8.480E+0, 8.608E+3, 3.480E+2, 9.074E-3},
|
||||
{6.979E+0, 7.871E+0, 1.162E+4, 3.924E+2, 4.402E-3},
|
||||
{7.725E+0, 8.716E+0, 1.183E+4, 3.948E+2, 4.376E-3},
|
||||
{8.337E+0, 9.425E+0, 1.051E+4, 2.696E+2, 6.206E-3},
|
||||
{7.287E+0, 8.218E+0, 1.223E+4, 3.997E+2, 4.447E-3},
|
||||
{7.899E+0, 8.911E+0, 1.243E+4, 4.021E+2, 4.511E-3},
|
||||
{8.041E+0, 9.071E+0, 1.263E+4, 4.045E+2, 4.540E-3},
|
||||
{7.488E+0, 8.444E+0, 1.283E+4, 4.069E+2, 4.420E-3},
|
||||
{7.291E+0, 8.219E+0, 1.303E+4, 4.093E+2, 4.298E-3},
|
||||
{7.098E+0, 8.000E+0, 1.323E+4, 4.118E+2, 4.182E-3},
|
||||
{6.909E+0, 7.786E+0, 1.343E+4, 4.142E+2, 4.058E-3},
|
||||
{6.728E+0, 7.580E+0, 1.362E+4, 4.166E+2, 3.976E-3},
|
||||
{6.551E+0, 7.380E+0, 1.382E+4, 4.190E+2, 3.877E-3},
|
||||
{6.739E+0, 7.592E+0, 1.402E+4, 4.214E+2, 3.863E-3},
|
||||
{6.212E+0, 6.996E+0, 1.421E+4, 4.239E+2, 3.725E-3},
|
||||
{5.517E+0, 6.210E+0, 1.440E+4, 4.263E+2, 3.632E-3},
|
||||
{5.220E+0, 5.874E+0, 1.460E+4, 4.287E+2, 3.498E-3},
|
||||
{5.071E+0, 5.706E+0, 1.479E+4, 4.330E+2, 3.405E-3},
|
||||
{4.926E+0, 5.542E+0, 1.498E+4, 4.335E+2, 3.342E-3},
|
||||
{4.788E+0, 5.386E+0, 1.517E+4, 4.359E+2, 3.292E-3},
|
||||
{4.893E+0, 5.505E+0, 1.536E+4, 4.384E+2, 3.243E-3},
|
||||
{5.028E+0, 5.657E+0, 1.555E+4, 4.408E+2, 3.195E-3},
|
||||
{4.738E+0, 5.329E+0, 1.574E+4, 4.432E+2, 3.186E-3},
|
||||
{4.587E+0, 5.160E+0, 1.541E+4, 4.153E+2, 3.406E-3},
|
||||
{5.201E+0, 5.851E+0, 1.612E+4, 4.416E+2, 3.122E-3},
|
||||
{5.071E+0, 5.704E+0, 1.630E+4, 4.409E+2, 3.082E-3},
|
||||
{4.946E+0, 5.563E+0, 1.649E+4, 4.401E+2, 2.965E-3},
|
||||
{4.477E+0, 5.034E+0, 1.667E+4, 4.393E+2, 2.871E-3},
|
||||
{4.844E+0, 5.458E+0, 7.852E+3, 9.758E+2, 2.077E-2},
|
||||
{4.307E+0, 4.843E+0, 1.704E+4, 4.878E+2, 2.882E-3},
|
||||
{4.723E+0, 5.311E+0, 1.722E+4, 5.370E+2, 2.913E-3},
|
||||
{5.319E+0, 5.982E+0, 1.740E+4, 5.863E+2, 2.871E-3},
|
||||
{5.956E+0, 6.700E+0, 1.780E+4, 6.770E+2, 2.660E-3},
|
||||
{6.158E+0, 6.928E+0, 1.777E+4, 5.863E+2, 2.812E-3},
|
||||
{6.203E+0, 6.979E+0, 1.795E+4, 5.863E+2, 2.776E-3},
|
||||
{6.181E+0, 6.954E+0, 1.812E+4, 5.863E+2, 2.748E-3},
|
||||
{6.949E+0, 7.820E+0, 1.830E+4, 5.863E+2, 2.737E-3},
|
||||
{7.506E+0, 8.448E+0, 1.848E+4, 5.863E+2, 2.727E-3},
|
||||
{7.648E+0, 8.609E+0, 1.866E+4, 5.863E+2, 2.697E-3},
|
||||
{7.711E+0, 8.679E+0, 1.883E+4, 5.863E+2, 2.641E-3},
|
||||
{7.407E+0, 8.336E+0, 1.901E+4, 5.863E+2, 2.603E-3},
|
||||
{7.290E+0, 8.204E+0, 1.918E+4, 5.863E+2, 2.673E-3}
|
||||
};
|
||||
|
||||
G4double fac = 1.0 ;
|
||||
|
||||
// Carbon specific case for E < 40 keV
|
||||
if ( T < 40.0 && 5 == i) {
|
||||
fac = sqrt(T/40.0) ;
|
||||
T = 40.0 ;
|
||||
|
||||
// Free electron gas model
|
||||
} else if ( T < 10.0 ) {
|
||||
fac = sqrt(T*0.1) ;
|
||||
T =10.0 ;
|
||||
}
|
||||
|
||||
// Main parametrisation
|
||||
G4double slow = a[i][1] * pow(T, 0.45) ;
|
||||
G4double shigh = log( 1.0 + a[i][3]/T + a[i][4]*T ) * a[i][2]/T ;
|
||||
ionloss = slow*shigh*fac / (slow + shigh) ;
|
||||
|
||||
if ( ionloss < 0.0) ionloss = 0.0 ;
|
||||
|
||||
return ionloss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::DEDX(const G4Material* material,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
G4double eloss = 0.0;
|
||||
const G4int numberOfElements = material->GetNumberOfElements();
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector();
|
||||
|
||||
// compaund material with parametrisation
|
||||
if( HasMaterial(material) ) {
|
||||
|
||||
eloss = StoppingPower(material, kineticEnergy)
|
||||
* (material->GetTotNbOfAtomsPerVolume());
|
||||
eloss *= material->GetTotNbOfAtomsPerVolume();
|
||||
if(1 < numberOfElements) {
|
||||
G4int nAtoms = 0;
|
||||
|
||||
const G4int* theAtomsVector = material->GetAtomsVector();
|
||||
for (G4int iel=0; iel<numberOfElements; iel++) {
|
||||
nAtoms += theAtomsVector[iel];
|
||||
}
|
||||
eloss /= nAtoms;
|
||||
}
|
||||
// pure material
|
||||
} else if(1 == numberOfElements) {
|
||||
|
||||
G4double z = material->GetZ();
|
||||
eloss = ElectronicStoppingPower(z, kineticEnergy)
|
||||
* (material->GetTotNbOfAtomsPerVolume());
|
||||
|
||||
|
||||
// Experimental data exist only for kinetic energy 125 keV
|
||||
} else if( MolecIsInZiegler1988(material) ) {
|
||||
|
||||
// Cycle over elements - calculation based on Bragg's rule
|
||||
G4double eloss125 = 0.0 ;
|
||||
const G4ElementVector* theElementVector =
|
||||
material->GetElementVector();
|
||||
|
||||
// loop for the elements in the material
|
||||
for (G4int i=0; i<numberOfElements; i++) {
|
||||
const G4Element* element = (*theElementVector)[i] ;
|
||||
G4double z = element->GetZ() ;
|
||||
eloss += ElectronicStoppingPower(z,kineticEnergy)
|
||||
* theAtomicNumDensityVector[i] ;
|
||||
eloss125 += ElectronicStoppingPower(z,125.0*keV)
|
||||
* theAtomicNumDensityVector[i] ;
|
||||
}
|
||||
|
||||
// Chemical factor is taken into account
|
||||
eloss *= ChemicalFactor(kineticEnergy, eloss125) ;
|
||||
|
||||
// Brugg's rule calculation
|
||||
} else {
|
||||
const G4ElementVector* theElementVector =
|
||||
material->GetElementVector() ;
|
||||
|
||||
// loop for the elements in the material
|
||||
for (G4int i=0; i<numberOfElements; i++)
|
||||
{
|
||||
const G4Element* element = (*theElementVector)[i] ;
|
||||
eloss += ElectronicStoppingPower(element->GetZ(), kineticEnergy)
|
||||
* theAtomicNumDensityVector[i];
|
||||
}
|
||||
}
|
||||
return eloss*theZieglerFactor;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BraggModel::MolecIsInZiegler1988(const G4Material* material)
|
||||
{
|
||||
// The list of molecules from
|
||||
// J.F.Ziegler and J.M.Manoyan, The stopping of ions in compaunds,
|
||||
// Nucl. Inst. & Meth. in Phys. Res. B35 (1988) 215-228.
|
||||
|
||||
G4String myFormula = G4String(" ") ;
|
||||
const G4String chFormula = material->GetChemicalFormula() ;
|
||||
if (myFormula == chFormula ) return false ;
|
||||
|
||||
// There are no evidence for difference of stopping power depended on
|
||||
// phase of the compound except for water. The stopping power of the
|
||||
// water in gas phase can be predicted using Bragg's rule.
|
||||
//
|
||||
// No chemical factor for water-gas
|
||||
|
||||
myFormula = G4String("H_2O") ;
|
||||
const G4State theState = material->GetState() ;
|
||||
if( theState == kStateGas && myFormula == chFormula) return false ;
|
||||
|
||||
const size_t numberOfMolecula = 53 ;
|
||||
|
||||
// The coffecient from Table.4 of Ziegler & Manoyan
|
||||
const G4double HeEff = 2.8735 ;
|
||||
|
||||
static G4String nameOfMol[numberOfMolecula] = {
|
||||
"H_2O", "C_2H_4O", "C_3H_6O", "C_2H_2", "C_H_3OH",
|
||||
"C_2H_5OH", "C_3H_7OH", "C_3H_4", "NH_3", "C_14H_10",
|
||||
"C_6H_6", "C_4H_10", "C_4H_6", "C_4H_8O", "CCl_4",
|
||||
"CF_4", "C_6H_8", "C_6H_12", "C_6H_10O", "C_6H_10",
|
||||
"C_8H_16", "C_5H_10", "C_5H_8", "C_3H_6-Cyclopropane","C_2H_4F_2",
|
||||
"C_2H_2F_2", "C_4H_8O_2", "C_2H_6", "C_2F_6", "C_2H_6O",
|
||||
"C_3H_6O", "C_4H_10O", "C_2H_4", "C_2H_4O", "C_2H_4S",
|
||||
"SH_2", "CH_4", "CCLF_3", "CCl_2F_2", "CHCl_2F",
|
||||
"(CH_3)_2S", "N_2O", "C_5H_10O", "C_8H_6", "(CH_2)_N",
|
||||
"(C_3H_6)_N","(C_8H_8)_N", "C_3H_8", "C_3H_6-Propylene", "C_3H_6O",
|
||||
"C_3H_6S", "C_4H_4S", "C_7H_8"
|
||||
} ;
|
||||
|
||||
static G4double expStopping[numberOfMolecula] = {
|
||||
66.1, 190.4, 258.7, 42.2, 141.5,
|
||||
210.9, 279.6, 198.8, 31.0, 267.5,
|
||||
122.8, 311.4, 260.3, 328.9, 391.3,
|
||||
206.6, 374.0, 422.0, 432.0, 398.0,
|
||||
554.0, 353.0, 326.0, 74.6, 220.5,
|
||||
197.4, 362.0, 170.0, 330.5, 211.3,
|
||||
262.3, 349.6, 51.3, 187.0, 236.9,
|
||||
121.9, 35.8, 247.0, 292.6, 268.0,
|
||||
262.3, 49.0, 398.9, 444.0, 22.91,
|
||||
68.0, 155.0, 84.0, 74.2, 254.7,
|
||||
306.8, 324.4, 420.0
|
||||
} ;
|
||||
|
||||
static G4double expCharge[numberOfMolecula] = {
|
||||
HeEff, HeEff, HeEff, 1.0, HeEff,
|
||||
HeEff, HeEff, HeEff, 1.0, 1.0,
|
||||
1.0, HeEff, HeEff, HeEff, HeEff,
|
||||
HeEff, HeEff, HeEff, HeEff, HeEff,
|
||||
HeEff, HeEff, HeEff, 1.0, HeEff,
|
||||
HeEff, HeEff, HeEff, HeEff, HeEff,
|
||||
HeEff, HeEff, 1.0, HeEff, HeEff,
|
||||
HeEff, 1.0, HeEff, HeEff, HeEff,
|
||||
HeEff, 1.0, HeEff, HeEff, 1.0,
|
||||
1.0, 1.0, 1.0, 1.0, HeEff,
|
||||
HeEff, HeEff, HeEff
|
||||
} ;
|
||||
|
||||
static G4double numberOfAtomsPerMolecula[numberOfMolecula] = {
|
||||
3.0, 7.0, 10.0, 4.0, 6.0,
|
||||
9.0, 12.0, 7.0, 4.0, 24.0,
|
||||
12.0, 14.0, 10.0, 13.0, 5.0,
|
||||
5.0, 14.0, 18.0, 17.0, 17.0,
|
||||
24.0, 15.0, 13.0, 9.0, 8.0,
|
||||
6.0, 14.0, 8.0, 8.0, 9.0,
|
||||
10.0, 15.0, 6.0, 7.0, 7.0,
|
||||
3.0, 5.0, 5.0, 5.0, 5.0,
|
||||
9.0, 3.0, 16.0, 14.0, 3.0,
|
||||
9.0, 16.0, 11.0, 9.0, 10.0,
|
||||
10.0, 9.0, 15.0
|
||||
} ;
|
||||
|
||||
// Search for the compaund in the table
|
||||
for (size_t i=0; i<numberOfMolecula; i++)
|
||||
{
|
||||
if(chFormula == nameOfMol[i]) {
|
||||
G4double exp125 = expStopping[i] *
|
||||
(material->GetTotNbOfAtomsPerVolume()) /
|
||||
(expCharge[i] * numberOfAtomsPerMolecula[i]) ;
|
||||
SetExpStopPower125(exp125);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::ChemicalFactor(G4double kineticEnergy,
|
||||
G4double eloss125) const
|
||||
{
|
||||
// Approximation of Chemical Factor according to
|
||||
// J.F.Ziegler and J.M.Manoyan, The stopping of ions in compaunds,
|
||||
// Nucl. Inst. & Meth. in Phys. Res. B35 (1988) 215-228.
|
||||
|
||||
G4double gamma = 1.0 + kineticEnergy/proton_mass_c2 ;
|
||||
G4double gamma25 = 1.0 + 25.0*keV /proton_mass_c2 ;
|
||||
G4double gamma125 = 1.0 + 125.0*keV/proton_mass_c2 ;
|
||||
G4double beta = sqrt(1.0 - 1.0/(gamma*gamma)) ;
|
||||
G4double beta25 = sqrt(1.0 - 1.0/(gamma25*gamma25)) ;
|
||||
G4double beta125 = sqrt(1.0 - 1.0/(gamma125*gamma125)) ;
|
||||
|
||||
G4double factor = 1.0 + (expStopPower125/eloss125 - 1.0) *
|
||||
(1.0 + exp( 1.48 * ( beta125/beta25 - 7.0 ) ) ) /
|
||||
(1.0 + exp( 1.48 * ( beta/beta25 - 7.0 ) ) ) ;
|
||||
|
||||
return factor ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ComptonScattering.cc,v 1.18 2004/03/10 16:48:45 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-01 $
|
||||
// $Id: G4ComptonScattering.cc,v 1.23 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//
|
||||
//------------ G4ComptonScattering physics process -----------------------------
|
||||
@@ -48,20 +47,24 @@
|
||||
// 20-09-01, DoIt: fminimalEnergy = 1*eV (mma)
|
||||
// 01-10-01, come back to BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// 17-04-02, LowestEnergyLimit = 1*keV
|
||||
// 26-05-04, cross section parametrization improved for low energy :
|
||||
// Egamma <~ 15 keV (Laszlo)
|
||||
// 08-11-04, Remove Store/Retrieve tables (V.Ivantchenko)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "G4ComptonScattering.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4PhysicsTableHelper.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// constructor
|
||||
|
||||
G4ComptonScattering::G4ComptonScattering(const G4String& processName,
|
||||
using namespace std;
|
||||
|
||||
G4ComptonScattering::G4ComptonScattering(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type),
|
||||
theCrossSectionTable(NULL),
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestEnergyLimit ( 1*keV),
|
||||
theMeanFreePathTable(NULL),
|
||||
LowestEnergyLimit ( 1*keV),
|
||||
HighestEnergyLimit(100*GeV),
|
||||
NumbBinTable(80),
|
||||
fminimalEnergy(1*eV)
|
||||
@@ -86,6 +89,13 @@ G4ComptonScattering::~G4ComptonScattering()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4ComptonScattering::IsApplicable( const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4ComptonScattering::SetPhysicsTableBining(
|
||||
G4double lowE, G4double highE, G4int nBins)
|
||||
{
|
||||
@@ -110,17 +120,17 @@ void G4ComptonScattering::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
G4double AtomicNumber;
|
||||
size_t J;
|
||||
|
||||
for ( J=0 ; J < G4Element::GetNumberOfElements(); J++ )
|
||||
{
|
||||
for ( J=0 ; J < G4Element::GetNumberOfElements(); J++ )
|
||||
{
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(LowestEnergyLimit,HighestEnergyLimit,
|
||||
NumbBinTable );
|
||||
AtomicNumber = (*theElementTable)[J]->GetZ();
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
|
||||
Value = ComputeCrossSectionPerAtom(LowEdgeEnergy, AtomicNumber);
|
||||
Value = ComputeCrossSectionPerAtom(LowEdgeEnergy, AtomicNumber);
|
||||
ptrVector->PutValue(i,Value);
|
||||
}
|
||||
|
||||
@@ -143,7 +153,7 @@ void G4ComptonScattering::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
ptrVector = new G4PhysicsLogVector(LowestEnergyLimit,HighestEnergyLimit,
|
||||
NumbBinTable ) ;
|
||||
material = (*theMaterialTable)[J];
|
||||
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
|
||||
@@ -155,7 +165,7 @@ void G4ComptonScattering::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
}
|
||||
|
||||
PrintInfoDefinition();
|
||||
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -167,6 +177,7 @@ G4double G4ComptonScattering::ComputeCrossSectionPerAtom
|
||||
// A parametrized formula from L. Urban is used to estimate
|
||||
// the total cross section.
|
||||
// It gives a good description of the data from 10 keV to 100/Z GeV.
|
||||
// lower limit 1 keV now with a correction for low energy
|
||||
|
||||
{
|
||||
G4double CrossSection = 0.0 ;
|
||||
@@ -184,16 +195,99 @@ G4double G4ComptonScattering::ComputeCrossSectionPerAtom
|
||||
G4double p1Z = Z*(d1 + e1*Z + f1*Z*Z), p2Z = Z*(d2 + e2*Z + f2*Z*Z),
|
||||
p3Z = Z*(d3 + e3*Z + f3*Z*Z), p4Z = Z*(d4 + e4*Z + f4*Z*Z);
|
||||
|
||||
G4double X = GammaEnergy / electron_mass_c2 ;
|
||||
G4double T0 = 15*keV; if (Z == 1.) T0 = 40*keV;
|
||||
|
||||
return CrossSection = p1Z*log(1.+2*X)/X
|
||||
+ (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
|
||||
}
|
||||
G4double X = max(GammaEnergy, T0) / electron_mass_c2;
|
||||
CrossSection = p1Z*log(1.+2*X)/X
|
||||
+ (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
|
||||
|
||||
// modification for low energy. (special case for Hydrogen)
|
||||
if (GammaEnergy < T0) {
|
||||
G4double dT0 = 1.*keV;
|
||||
X = (T0+dT0) / electron_mass_c2 ;
|
||||
G4double sigma = p1Z*log(1.+2*X)/X
|
||||
+ (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
|
||||
G4double c1 = -T0*(sigma-CrossSection)/(CrossSection*dT0);
|
||||
G4double c2 = 0.150; if (Z > 1.) c2 = 0.375-0.0556*log(Z);
|
||||
G4double y = log(GammaEnergy/T0);
|
||||
CrossSection *= exp(-y*(c1+c2*y));
|
||||
}
|
||||
|
||||
return CrossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4ComptonScattering::ComputeMeanFreePath(G4double GammaEnergy,
|
||||
G4Material* aMaterial)
|
||||
|
||||
// returns the gamma mean free path in GEANT4 internal units
|
||||
|
||||
{
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector() ;
|
||||
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double SIGMA = 0.;
|
||||
|
||||
for ( size_t elm=0 ; elm < aMaterial->GetNumberOfElements() ; elm++ )
|
||||
{
|
||||
SIGMA += NbOfAtomsPerVolume[elm] *
|
||||
ComputeCrossSectionPerAtom(GammaEnergy,
|
||||
(*theElementVector)[elm]->GetZ());
|
||||
}
|
||||
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4ComptonScattering::GetCrossSectionPerAtom(
|
||||
G4DynamicParticle* aDynamicGamma,
|
||||
G4Element* anElement)
|
||||
|
||||
// gives the microscopic total cross section in GEANT4 internal units
|
||||
|
||||
{
|
||||
G4double crossSection;
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4bool isOutRange ;
|
||||
if (GammaEnergy < LowestEnergyLimit || GammaEnergy > HighestEnergyLimit)
|
||||
crossSection = 0.;
|
||||
else
|
||||
crossSection = (*theCrossSectionTable)(anElement->GetIndex())->
|
||||
GetValue(GammaEnergy, isOutRange);
|
||||
|
||||
return crossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
G4double G4ComptonScattering::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double,
|
||||
G4ForceCondition*)
|
||||
|
||||
// returns the gamma mean free path in GEANT4 internal units
|
||||
|
||||
{
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
G4double MeanFreePath;
|
||||
G4bool isOutRange;
|
||||
|
||||
if (GammaEnergy > HighestEnergyLimit || GammaEnergy < LowestEnergyLimit)
|
||||
MeanFreePath = DBL_MAX;
|
||||
else
|
||||
MeanFreePath = (*theMeanFreePathTable)(aMaterial->GetIndex())->
|
||||
GetValue(GammaEnergy, isOutRange);
|
||||
return MeanFreePath;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
const G4Step& aStep)
|
||||
//
|
||||
// The scattered gamma energy is sampled according to Klein - Nishina formula.
|
||||
// The random number techniques of Butcher & Messel are used
|
||||
@@ -214,7 +308,7 @@ G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
//
|
||||
// sample the energy rate of the scattered gamma
|
||||
//
|
||||
|
||||
|
||||
G4double epsilon, epsilonsq, onecost, sint2, greject ;
|
||||
|
||||
G4double epsilon0 = 1./(1. + 2*E0_m) , epsilon0sq = epsilon0*epsilon0;
|
||||
@@ -242,24 +336,24 @@ G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double dirx = sinTeta*cos(Phi), diry = sinTeta*sin(Phi), dirz = cosTeta;
|
||||
|
||||
//
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
// update G4VParticleChange for the scattered gamma
|
||||
//
|
||||
|
||||
G4ThreeVector GammaDirection1 ( dirx,diry,dirz );
|
||||
GammaDirection1.rotateUz(GammaDirection0);
|
||||
aParticleChange.SetMomentumChange( GammaDirection1 );
|
||||
aParticleChange.ProposeMomentumDirection( GammaDirection1 );
|
||||
G4double GammaEnergy1 = epsilon*GammaEnergy0;
|
||||
G4double localEnergyDeposit = 0.;
|
||||
|
||||
if (GammaEnergy1 > fminimalEnergy)
|
||||
{
|
||||
aParticleChange.SetEnergyChange( GammaEnergy1 );
|
||||
aParticleChange.ProposeEnergy( GammaEnergy1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
localEnergyDeposit += GammaEnergy1;
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.ProposeEnergy(0.) ;
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -275,8 +369,8 @@ G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
G4ThreeVector ElecDirection (
|
||||
(GammaEnergy0*GammaDirection0 - GammaEnergy1*GammaDirection1)
|
||||
*(1./ElecMomentum) );
|
||||
|
||||
// create G4DynamicParticle object for the electron.
|
||||
|
||||
// create G4DynamicParticle object for the electron.
|
||||
G4DynamicParticle* aElectron= new G4DynamicParticle(
|
||||
G4Electron::Electron(),ElecDirection,ElecKineEnergy);
|
||||
|
||||
@@ -287,18 +381,18 @@ G4VParticleChange* G4ComptonScattering::PostStepDoIt(const G4Track& aTrack,
|
||||
{
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
localEnergyDeposit += ElecKineEnergy;
|
||||
}
|
||||
aParticleChange.SetLocalEnergyDeposit (localEnergyDeposit);
|
||||
|
||||
}
|
||||
aParticleChange.ProposeLocalEnergyDeposit (localEnergyDeposit);
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4ComptonScattering::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
G4bool G4ComptonScattering::StorePhysicsTable(const G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4String filename;
|
||||
|
||||
@@ -317,17 +411,17 @@ G4bool G4ComptonScattering::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4ComptonScattering::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
/*
|
||||
G4bool G4ComptonScattering::RetrievePhysicsTable(const G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
// delete theCrossSectionTable and theMeanFreePathTable
|
||||
@@ -345,27 +439,27 @@ G4bool G4ComptonScattering::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
// retreive cross section table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"CrossSection",ascii);
|
||||
theCrossSectionTable = new G4PhysicsTable(G4Element::GetNumberOfElements());
|
||||
if ( !theCrossSectionTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
if ( !G4PhysicsTableHelper::RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theCrossSectionTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// retreive mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
theMeanFreePathTable = new G4PhysicsTable(G4Material::GetNumberOfMaterials());
|
||||
if ( !theMeanFreePathTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
if ( !G4PhysicsTableHelper::RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to retrieve the PhysicsTables from "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
*/
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4ComptonScattering::PrintInfoDefinition()
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4GammaConversion.cc,v 1.19 2004/03/10 16:48:45 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-01 $
|
||||
// $Id: G4GammaConversion.cc,v 1.23 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//------------------ G4GammaConversion physics process -------------------------
|
||||
// by Michel Maire, 24 May 1996
|
||||
//
|
||||
//
|
||||
// 11-06-96 Added SelectRandomAtom() method, M.Maire
|
||||
// 21-06-96 SetCuts implementation, M.Maire
|
||||
// 24-06-96 simplification in ComputeCrossSectionPerAtom, M.Maire
|
||||
@@ -54,7 +54,8 @@
|
||||
// 20-09-01 DoIt: fminimalEnergy = 1*eV (mma)
|
||||
// 01-10-01 come back to BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// 11-01-02 ComputeCrossSection: correction of extrapolation below EnergyLimit
|
||||
// 21-03-02 DoIt: correction of the e+e- angular distribution (bug 363) mma
|
||||
// 21-03-02 DoIt: correction of the e+e- angular distribution (bug 363) mma
|
||||
// 08-11-04 Remove of Store/Retrieve tables (V.Ivantchenko)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "G4GammaConversion.hh"
|
||||
@@ -62,7 +63,7 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// constructor
|
||||
using namespace std;
|
||||
|
||||
G4GammaConversion::G4GammaConversion(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type),
|
||||
@@ -90,6 +91,13 @@ G4GammaConversion::~G4GammaConversion()
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4GammaConversion::IsApplicable( const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -146,16 +154,16 @@ void G4GammaConversion::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
G4Material* material;
|
||||
|
||||
for ( J=0 ; J < G4Material::GetNumberOfMaterials(); J++ )
|
||||
{
|
||||
{
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(LowestEnergyLimit,HighestEnergyLimit,
|
||||
NumbBinTable);
|
||||
material = (*theMaterialTable)[J];
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
|
||||
|
||||
for ( G4int i = 0 ; i < NumbBinTable ; i++ )
|
||||
{
|
||||
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
|
||||
Value = ComputeMeanFreePath( LowEdgeEnergy, material);
|
||||
Value = ComputeMeanFreePath( LowEdgeEnergy, material);
|
||||
ptrVector->PutValue( i , Value ) ;
|
||||
}
|
||||
|
||||
@@ -170,7 +178,7 @@ void G4GammaConversion::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
|
||||
G4double G4GammaConversion::ComputeCrossSectionPerAtom
|
||||
(G4double GammaEnergy, G4double AtomicNumber)
|
||||
|
||||
|
||||
// Calculates the microscopic cross section in GEANT4 internal units.
|
||||
// A parametrized formula from L. Urban is used to estimate
|
||||
// the total cross section.
|
||||
@@ -183,7 +191,7 @@ G4double G4GammaConversion::ComputeCrossSectionPerAtom
|
||||
G4double CrossSection = 0.0 ;
|
||||
if ( AtomicNumber < 1. ) return CrossSection;
|
||||
if ( GammaEnergy < 2*electron_mass_c2 ) return CrossSection;
|
||||
|
||||
|
||||
static const G4double
|
||||
a0= 8.7842e+2*microbarn, a1=-1.9625e+3*microbarn, a2= 1.2949e+3*microbarn,
|
||||
a3=-2.0028e+2*microbarn, a4= 1.2575e+1*microbarn, a5=-2.8333e-1*microbarn;
|
||||
@@ -219,6 +227,79 @@ G4double G4GammaConversion::ComputeCrossSectionPerAtom
|
||||
|
||||
return CrossSection;
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4GammaConversion::ComputeMeanFreePath(G4double GammaEnergy,
|
||||
G4Material* aMaterial)
|
||||
|
||||
// computes and returns the photon mean free path in GEANT4 internal units
|
||||
|
||||
{
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double SIGMA = 0 ;
|
||||
|
||||
for ( size_t i=0 ; i < aMaterial->GetNumberOfElements() ; i++ )
|
||||
{
|
||||
SIGMA += NbOfAtomsPerVolume[i] *
|
||||
ComputeCrossSectionPerAtom(GammaEnergy,
|
||||
(*theElementVector)[i]->GetZ());
|
||||
}
|
||||
|
||||
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4GammaConversion::GetCrossSectionPerAtom(
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4Element* anElement)
|
||||
|
||||
// gives the total cross section per atom in GEANT4 internal units
|
||||
|
||||
{
|
||||
G4double crossSection;
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4bool isOutRange ;
|
||||
|
||||
if (GammaEnergy < LowestEnergyLimit)
|
||||
crossSection = 0. ;
|
||||
else {
|
||||
if (GammaEnergy > HighestEnergyLimit) GammaEnergy=0.99*HighestEnergyLimit;
|
||||
crossSection = (*theCrossSectionTable)(anElement->GetIndex())->
|
||||
GetValue( GammaEnergy, isOutRange );
|
||||
}
|
||||
|
||||
return crossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4GammaConversion::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double,
|
||||
G4ForceCondition*)
|
||||
|
||||
// returns the photon mean free path in GEANT4 internal units
|
||||
// (MeanFreePath is a private member of the class)
|
||||
|
||||
{
|
||||
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
G4bool isOutRange;
|
||||
|
||||
if (GammaEnergy < LowestEnergyLimit)
|
||||
MeanFreePath = DBL_MAX;
|
||||
else {
|
||||
if (GammaEnergy > HighestEnergyLimit) GammaEnergy=0.99*HighestEnergyLimit;
|
||||
MeanFreePath = (*theMeanFreePathTable)(aMaterial->GetIndex())->
|
||||
GetValue( GammaEnergy, isOutRange );
|
||||
}
|
||||
|
||||
return MeanFreePath;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -237,7 +318,7 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
// Note 2 : The differential cross section implicitly takes account of
|
||||
// pair creation in both nuclear and atomic electron fields.
|
||||
// However triplet prodution is not generated.
|
||||
|
||||
|
||||
{
|
||||
aParticleChange.Initialize(aTrack);
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
@@ -251,7 +332,7 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double epsil0 = electron_mass_c2/GammaEnergy ;
|
||||
|
||||
// do it fast if GammaEnergy < 2. MeV
|
||||
const G4double Egsmall=2.*MeV;
|
||||
const G4double Egsmall=2.*MeV;
|
||||
if (GammaEnergy<Egsmall) { epsil = epsil0 + (0.5-epsil0)*G4UniformRand(); }
|
||||
|
||||
else
|
||||
@@ -267,11 +348,11 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
// limits of the screening variable
|
||||
G4double screenfac = 136.*epsil0/(anElement->GetIonisation()->GetZ3());
|
||||
G4double screenmax = exp ((42.24 - FZ)/8.368) - 0.952 ;
|
||||
G4double screenmin = std::min(4.*screenfac,screenmax);
|
||||
G4double screenmin = min(4.*screenfac,screenmax);
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double epsil1 = 0.5 - 0.5*sqrt(1. - screenmin/screenmax) ;
|
||||
G4double epsilmin = std::max(epsil0,epsil1) , epsilrange = 0.5 - epsilmin;
|
||||
G4double epsilmin = max(epsil0,epsil1) , epsilrange = 0.5 - epsilmin;
|
||||
|
||||
//
|
||||
// sample the energy rate of the created electron (or positron)
|
||||
@@ -281,8 +362,8 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
|
||||
G4double F10 = ScreenFunction1(screenmin) - FZ;
|
||||
G4double F20 = ScreenFunction2(screenmin) - FZ;
|
||||
G4double NormF1 = std::max(F10*epsilrange*epsilrange,0.);
|
||||
G4double NormF2 = std::max(1.5*F20,0.);
|
||||
G4double NormF1 = max(F10*epsilrange*epsilrange,0.);
|
||||
G4double NormF2 = max(1.5*F20,0.);
|
||||
|
||||
do {
|
||||
if ( NormF1/(NormF1+NormF2) > G4UniformRand() )
|
||||
@@ -342,14 +423,14 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
|
||||
aParticleChange.SetNumberOfSecondaries(2);
|
||||
|
||||
G4double ElectKineEnergy = std::max(0.,ElectTotEnergy - electron_mass_c2);
|
||||
G4double ElectKineEnergy = max(0.,ElectTotEnergy - electron_mass_c2);
|
||||
G4double localEnergyDeposit = 0.;
|
||||
|
||||
if (ElectKineEnergy > fminimalEnergy)
|
||||
{
|
||||
G4ThreeVector ElectDirection (dxEl, dyEl, dzEl);
|
||||
ElectDirection.rotateUz(GammaDirection);
|
||||
|
||||
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1= new G4DynamicParticle(
|
||||
G4Electron::Electron(),ElectDirection,ElectKineEnergy);
|
||||
@@ -360,27 +441,26 @@ G4VParticleChange* G4GammaConversion::PostStepDoIt(const G4Track& aTrack,
|
||||
|
||||
// the e+ is always created (even with Ekine=0) for further annihilation.
|
||||
|
||||
G4double PositKineEnergy = std::max(0.,PositTotEnergy - electron_mass_c2);
|
||||
G4double PositKineEnergy = max(0.,PositTotEnergy - electron_mass_c2);
|
||||
if (PositKineEnergy < fminimalEnergy)
|
||||
{ localEnergyDeposit += PositKineEnergy; PositKineEnergy = 0.;}
|
||||
|
||||
G4ThreeVector PositDirection (dxPo, dyPo, dzPo);
|
||||
PositDirection.rotateUz(GammaDirection);
|
||||
|
||||
|
||||
// create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* aParticle2= new G4DynamicParticle(
|
||||
G4Positron::Positron(),PositDirection,PositKineEnergy);
|
||||
aParticleChange.AddSecondary(aParticle2);
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(localEnergyDeposit);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(localEnergyDeposit);
|
||||
|
||||
//
|
||||
// Kill the incident photon
|
||||
//
|
||||
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. );
|
||||
aParticleChange.SetEnergyChange( 0. );
|
||||
aParticleChange.SetStatusChange( fStopAndKill );
|
||||
aParticleChange.ProposeEnergy( 0. );
|
||||
aParticleChange.ProposeTrackStatus( fStopAndKill );
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
|
||||
@@ -392,7 +472,7 @@ G4Element* G4GammaConversion::SelectRandomAtom(
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4Material* aMaterial)
|
||||
{
|
||||
// select randomly 1 element within the material
|
||||
// select randomly 1 element within the material
|
||||
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
@@ -402,7 +482,7 @@ G4Element* G4GammaConversion::SelectRandomAtom(
|
||||
|
||||
G4double PartialSumSigma = 0. ;
|
||||
G4double rval = G4UniformRand()/MeanFreePath;
|
||||
|
||||
|
||||
for ( G4int i=0 ; i < NumberOfElements ; i++ )
|
||||
{ PartialSumSigma += NbOfAtomsPerVolume[i] *
|
||||
GetCrossSectionPerAtom(aDynamicGamma, (*theElementVector)[i]);
|
||||
@@ -415,9 +495,9 @@ G4Element* G4GammaConversion::SelectRandomAtom(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4GammaConversion::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
G4bool G4GammaConversion::StorePhysicsTable(const G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4String filename;
|
||||
|
||||
@@ -436,18 +516,18 @@ G4bool G4GammaConversion::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4GammaConversion::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
/*
|
||||
G4bool G4GammaConversion::RetrievePhysicsTable(const G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
// delete theCrossSectionTable and theMeanFreePathTable
|
||||
if (theCrossSectionTable != 0) {
|
||||
@@ -464,27 +544,27 @@ G4bool G4GammaConversion::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
// retreive cross section table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"CrossSection",ascii);
|
||||
theCrossSectionTable = new G4PhysicsTable(G4Element::GetNumberOfElements());
|
||||
if ( !theCrossSectionTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
if ( !G4PhysicsTableHelper::RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theCrossSectionTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// retreive mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
theMeanFreePathTable = new G4PhysicsTable(G4Material::GetNumberOfMaterials());
|
||||
if ( !theMeanFreePathTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
if ( !G4PhysicsTableHelper::RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to retrieve the PhysicsTables from "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
*/
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4GammaConversion::PrintInfoDefinition()
|
||||
@@ -492,11 +572,11 @@ void G4GammaConversion::PrintInfoDefinition()
|
||||
G4String comments = "Total cross sections from a parametrisation. ";
|
||||
comments += "Good description from 1.5 MeV to 100 GeV for all Z. \n";
|
||||
comments += " e+e- energies according Bethe-Heitler";
|
||||
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from "
|
||||
<< "\n PhysicsTables from "
|
||||
<< G4BestUnit(LowestEnergyLimit, "Energy")
|
||||
<< " to " << G4BestUnit(HighestEnergyLimit,"Energy")
|
||||
<< " to " << G4BestUnit(HighestEnergyLimit,"Energy")
|
||||
<< " in " << NumbBinTable << " bins. \n";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,324 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4GammaConversionToMuons.cc,v 1.5 2004/03/10 16:48:45 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-01 $
|
||||
//
|
||||
// ------------ G4GammaConversionToMuons physics process ------
|
||||
// by H.Burkhardt, S. Kelner and R. Kokoulin, April 2002
|
||||
//
|
||||
//
|
||||
// 07-08-02: missprint in OR condition in DoIt : f1<0 || f1>f1_max ..etc ...
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include "G4GammaConversionToMuons.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4MuonPlus.hh"
|
||||
#include "G4MuonMinus.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
// constructor
|
||||
|
||||
G4GammaConversionToMuons::G4GammaConversionToMuons(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type),
|
||||
LowestEnergyLimit (4*G4MuonPlus::MuonPlus()->GetPDGMass()), // 4*Mmuon
|
||||
HighestEnergyLimit(1e21*eV), // ok to 1e21eV=1e12GeV, then LPM suppression
|
||||
CrossSecFactor(1.)
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
// destructor
|
||||
|
||||
G4GammaConversionToMuons::~G4GammaConversionToMuons() // (empty) destructor
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4GammaConversionToMuons::BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
// Build cross section and mean free path tables
|
||||
{ //here no tables, just calling PrintInfoDefinition
|
||||
PrintInfoDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4GammaConversionToMuons::SetCrossSecFactor(G4double fac)
|
||||
// Set the factor to artificially increase the cross section
|
||||
{ CrossSecFactor=fac;
|
||||
G4cout << "The cross section for GammaConversionToMuons is artificially "
|
||||
<< "increased by the CrossSecFactor=" << CrossSecFactor << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4double G4GammaConversionToMuons::ComputeCrossSectionPerAtom(
|
||||
G4double Egam, G4double Z, G4double A)
|
||||
// Calculates the microscopic cross section in GEANT4 internal units.
|
||||
// Total cross section parametrisation from H.Burkhardt
|
||||
// It gives a good description at any energy (from 0 to 10**21 eV)
|
||||
{ static const G4double Mmuon=G4MuonPlus::MuonPlus()->GetPDGMass();
|
||||
static const G4double Mele=electron_mass_c2;
|
||||
static const G4double Rc=elm_coupling/Mmuon; // classical particle radius
|
||||
static const G4double sqrte=sqrt(exp(1.));
|
||||
static const G4double PowSat=-0.88;
|
||||
|
||||
static G4double CrossSection = 0.0 ;
|
||||
|
||||
if ( A < 1. ) return 0;
|
||||
if ( Egam < 4*Mmuon ) return 0 ; // below threshold return 0
|
||||
|
||||
static G4double EgamLast=0,Zlast=0,PowThres,Ecor,B,Dn,Zthird,Winfty,WMedAppr,
|
||||
Wsatur,sigfac;
|
||||
|
||||
if(Zlast==Z && Egam==EgamLast) return CrossSection; // already calculated
|
||||
EgamLast=Egam;
|
||||
|
||||
if(Zlast!=Z) // new element
|
||||
{ Zlast=Z;
|
||||
if(Z==1) // special case of Hydrogen
|
||||
{ B=202.4;
|
||||
Dn=1.49;
|
||||
}
|
||||
else
|
||||
{ B=183.;
|
||||
Dn=1.54*pow(A,0.27);
|
||||
}
|
||||
Zthird=pow(Z,-1./3.); // Z**(-1/3)
|
||||
Winfty=B*Zthird*Mmuon/(Dn*Mele);
|
||||
WMedAppr=1./(4.*Dn*sqrte*Mmuon);
|
||||
Wsatur=Winfty/WMedAppr;
|
||||
sigfac=4.*fine_structure_const*Z*Z*Rc*Rc;
|
||||
PowThres=1.479+0.00799*Dn;
|
||||
Ecor=-18.+4347./(B*Zthird);
|
||||
}
|
||||
G4double CorFuc=1.+.04*log(1.+Ecor/Egam);
|
||||
G4double Eg=pow(1.-4.*Mmuon/Egam,PowThres)*pow( pow(Wsatur,PowSat)+
|
||||
pow(Egam,PowSat),1./PowSat); // threshold and saturation
|
||||
CrossSection=7./9.*sigfac*log(1.+WMedAppr*CorFuc*Eg);
|
||||
CrossSection*=CrossSecFactor; // increase the CrossSection by (by default 1)
|
||||
return CrossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4VParticleChange* G4GammaConversionToMuons::PostStepDoIt(
|
||||
const G4Track& aTrack,
|
||||
const G4Step& aStep)
|
||||
//
|
||||
// generation of gamma->mu+mu-
|
||||
//
|
||||
{
|
||||
aParticleChange.Initialize(aTrack);
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
static const G4double Mmuon=G4MuonPlus::MuonPlus()->GetPDGMass();
|
||||
static const G4double Mele=electron_mass_c2;
|
||||
static const G4double sqrte=sqrt(exp(1.));
|
||||
|
||||
// current Gamma energy and direction, return if energy too low
|
||||
const G4DynamicParticle *aDynamicGamma = aTrack.GetDynamicParticle();
|
||||
G4double Egam = aDynamicGamma->GetKineticEnergy();
|
||||
if (Egam < 4*Mmuon) return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
|
||||
G4ParticleMomentum GammaDirection = aDynamicGamma->GetMomentumDirection();
|
||||
|
||||
// select randomly one element constituting the material
|
||||
const G4Element& anElement = *SelectRandomAtom(aDynamicGamma, aMaterial);
|
||||
G4double Z = anElement.GetZ();
|
||||
G4double A = anElement.GetA()/(g/mole);
|
||||
|
||||
static G4double Zlast=0,B,Dn,Zthird,Winfty,A027,C1Num2,C2Term2;
|
||||
if(Zlast!=Z) // the element has changed
|
||||
{ Zlast=Z;
|
||||
if(Z==1) // special case of Hydrogen
|
||||
{ B=202.4;
|
||||
Dn=1.49;
|
||||
}
|
||||
else
|
||||
{ B=183.;
|
||||
Dn=1.54*pow(A,0.27);
|
||||
}
|
||||
Zthird=pow(Z,-1./3.); // Z**(-1/3)
|
||||
Winfty=B*Zthird*Mmuon/(Dn*Mele);
|
||||
A027=pow(A,0.27);
|
||||
G4double C1Num=0.35*A027;
|
||||
C1Num2=C1Num*C1Num;
|
||||
C2Term2=Mele/(183.*Zthird*Mmuon);
|
||||
}
|
||||
|
||||
G4double GammaMuonInv=Mmuon/Egam;
|
||||
G4double sqrtx=sqrt(.25-GammaMuonInv);
|
||||
G4double xmax=.5+sqrtx;
|
||||
G4double xmin=.5-sqrtx;
|
||||
|
||||
// generate xPlus according to the differential cross section by rejection
|
||||
G4double Ds2=(Dn*sqrte-2.);
|
||||
G4double sBZ=sqrte*B*Zthird/Mele;
|
||||
G4double LogWmaxInv=1./log(Winfty*(1.+2.*Ds2*GammaMuonInv)
|
||||
/(1.+2.*sBZ*Mmuon*GammaMuonInv));
|
||||
G4double xPlus,xMinus,xPM,result,W;
|
||||
do
|
||||
{ xPlus=xmin+G4UniformRand()*(xmax-xmin);
|
||||
xMinus=1.-xPlus;
|
||||
xPM=xPlus*xMinus;
|
||||
G4double del=Mmuon*Mmuon/(2.*Egam*xPM);
|
||||
W=Winfty*(1.+Ds2*del/Mmuon)/(1.+sBZ*del);
|
||||
if(W<1.) W=1.; // to avoid negative cross section at xmin
|
||||
G4double xxp=1.-4./3.*xPM; // the main xPlus dependence
|
||||
result=xxp*log(W)*LogWmaxInv;
|
||||
if(result>1.)
|
||||
{ G4cout << "error in dSigxPlusGen, result=" << result << " is >1" << '\n';
|
||||
exit(10);
|
||||
}
|
||||
}
|
||||
while (G4UniformRand() > result);
|
||||
|
||||
// now generate the angular variables via the auxilary variables t,psi,rho
|
||||
G4double t;
|
||||
G4double psi;
|
||||
G4double rho;
|
||||
|
||||
G4double thetaPlus,thetaMinus,phiHalf; // final angular variables
|
||||
|
||||
do // t, psi, rho generation start (while angle < pi)
|
||||
{
|
||||
//generate t by the rejection method
|
||||
G4double C1=C1Num2* GammaMuonInv/xPM;
|
||||
G4double f1_max=(1.-xPM) / (1.+C1);
|
||||
G4double f1; // the probability density
|
||||
do
|
||||
{ t=G4UniformRand();
|
||||
f1=(1.-2.*xPM+4.*xPM*t*(1.-t)) / (1.+C1/(t*t));
|
||||
if(f1<0 || f1> f1_max) // should never happend
|
||||
{ G4cout << "outside allowed range f1=" << f1 << G4endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
while ( G4UniformRand()*f1_max > f1);
|
||||
// generate psi by the rejection method
|
||||
G4double f2_max=1.-2.*xPM*(1.-4.*t*(1.-t));
|
||||
|
||||
// long version
|
||||
G4double f2;
|
||||
do
|
||||
{ psi=2.*pi*G4UniformRand();
|
||||
f2=1.-2.*xPM+4.*xPM*t*(1.-t)*(1.+cos(2.*psi));
|
||||
if(f2<0 || f2> f2_max) // should never happend
|
||||
{ G4cout << "outside allowed range f2=" << f2 << G4endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
while ( G4UniformRand()*f2_max > f2);
|
||||
|
||||
// generate rho by direct transformation
|
||||
G4double C2Term1=GammaMuonInv/(2.*xPM*t);
|
||||
G4double C2=4./sqrt(xPM)*pow(C2Term1*C2Term1+C2Term2*C2Term2,2);
|
||||
G4double rhomax=1.9/A027*(1./t-1.);
|
||||
G4double beta=log( (C2+pow(rhomax,4))/C2 );
|
||||
rho=pow(C2 *( exp(beta*G4UniformRand())-1. ) ,0.25);
|
||||
|
||||
//now get from t and psi the kinematical variables
|
||||
G4double u=sqrt(1./t-1.);
|
||||
G4double xiHalf=0.5*rho*cos(psi);
|
||||
phiHalf=0.5*rho/u*sin(psi);
|
||||
|
||||
thetaPlus =GammaMuonInv*(u+xiHalf)/xPlus;
|
||||
thetaMinus=GammaMuonInv*(u-xiHalf)/xMinus;
|
||||
|
||||
} while ( abs(thetaPlus)>pi || abs(thetaMinus) >pi);
|
||||
|
||||
// now construct the vectors
|
||||
// azimuthal symmetry, take phi0 at random between 0 and 2 pi
|
||||
G4double phi0=2.*pi*G4UniformRand();
|
||||
G4double EPlus=xPlus*Egam;
|
||||
G4double EMinus=xMinus*Egam;
|
||||
|
||||
// mu+ mu- directions for gamma in z-direction
|
||||
G4ThreeVector MuPlusDirection ( sin(thetaPlus) *cos(phi0+phiHalf),
|
||||
sin(thetaPlus) *sin(phi0+phiHalf), cos(thetaPlus) );
|
||||
G4ThreeVector MuMinusDirection (-sin(thetaMinus)*cos(phi0-phiHalf),
|
||||
-sin(thetaMinus) *sin(phi0-phiHalf), cos(thetaMinus) );
|
||||
// rotate to actual gamma direction
|
||||
MuPlusDirection.rotateUz(GammaDirection);
|
||||
MuMinusDirection.rotateUz(GammaDirection);
|
||||
aParticleChange.SetNumberOfSecondaries(2);
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1= new G4DynamicParticle(
|
||||
G4MuonPlus::MuonPlus(),MuPlusDirection,EPlus-Mmuon);
|
||||
aParticleChange.AddSecondary(aParticle1);
|
||||
// create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* aParticle2= new G4DynamicParticle(
|
||||
G4MuonMinus::MuonMinus(),MuMinusDirection,EMinus-Mmuon);
|
||||
aParticleChange.AddSecondary(aParticle2);
|
||||
//
|
||||
// Kill the incident photon
|
||||
//
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. ) ;
|
||||
aParticleChange.SetEnergyChange( 0. ) ;
|
||||
aParticleChange.SetStatusChange( fStopAndKill ) ;
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4Element* G4GammaConversionToMuons::SelectRandomAtom(
|
||||
const G4DynamicParticle* aDynamicGamma,
|
||||
G4Material* aMaterial)
|
||||
{
|
||||
// select randomly 1 element within the material, invoked by PostStepDoIt
|
||||
|
||||
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
if (NumberOfElements == 1) return (*theElementVector)[0];
|
||||
|
||||
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double PartialSumSigma = 0. ;
|
||||
G4double rval = G4UniformRand()/MeanFreePath;
|
||||
|
||||
|
||||
for ( G4int i=0 ; i < NumberOfElements ; i++ )
|
||||
{ PartialSumSigma += NbOfAtomsPerVolume[i] *
|
||||
GetCrossSectionPerAtom(aDynamicGamma, (*theElementVector)[i]);
|
||||
if (rval <= PartialSumSigma) return ((*theElementVector)[i]);
|
||||
}
|
||||
G4cout << " WARNING !!! - The Material '"<< aMaterial->GetName()
|
||||
<< "' has no elements, NULL pointer returned." << G4endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4GammaConversionToMuons::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments ="gamma->mu+mu- Bethe Heitler process.\n";
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< " good cross section parametrization from "
|
||||
<< G4BestUnit(LowestEnergyLimit,"Energy")
|
||||
<< " to " << HighestEnergyLimit/GeV << " GeV for all Z." << G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,388 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4IonFluctuations.cc,v 1.2 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4IonFluctuation
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 03.01.2002
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 28-12-02 add method Dispersion (V.Ivanchenko)
|
||||
// 07-02-03 change signature (V.Ivanchenko)
|
||||
// 13-02-03 Add name (V.Ivanchenko)
|
||||
// 23-05-03 Add control on parthalogical cases (V.Ivanchenko)
|
||||
// 16-10-03 Changed interface to Initialisation (V.Ivanchenko)
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4IonFluctuations.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4IonFluctuations::G4IonFluctuations(const G4String& nam)
|
||||
:G4VEmFluctuationModel(nam),
|
||||
particle(0),
|
||||
minNumberInteractionsBohr(10.0),
|
||||
theBohrBeta2(50.0*keV/proton_mass_c2),
|
||||
minFraction(0.2),
|
||||
xmin(0.2),
|
||||
minLoss(0.001*eV)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4IonFluctuations::~G4IonFluctuations()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IonFluctuations::InitialiseMe(const G4ParticleDefinition* part)
|
||||
{
|
||||
particle = part;
|
||||
particleMass = part->GetPDGMass();
|
||||
charge = part->GetPDGCharge()/eplus;
|
||||
chargeSquare = charge*charge;
|
||||
chargeSqRatio = 1.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IonFluctuations::SampleFluctuations(const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length,
|
||||
G4double& meanLoss)
|
||||
{
|
||||
if(meanLoss <= minLoss) return meanLoss;
|
||||
|
||||
if(dp->GetDefinition() != particle) {
|
||||
particle = dp->GetDefinition();
|
||||
charge = particle->GetPDGCharge()/eplus;
|
||||
}
|
||||
|
||||
G4double siga = Dispersion(material,dp,tmax,length);
|
||||
G4double loss = meanLoss;
|
||||
|
||||
|
||||
G4double navr = minNumberInteractionsBohr;
|
||||
|
||||
// Gaussian fluctuation
|
||||
G4bool gauss = true;
|
||||
if (meanLoss >= minNumberInteractionsBohr*tmax) {
|
||||
navr = meanLoss*meanLoss/siga;
|
||||
if (navr < minNumberInteractionsBohr) gauss = false;
|
||||
}
|
||||
|
||||
if(gauss) {
|
||||
// Increase fluctuations for big fractional energy loss
|
||||
|
||||
//G4cout << "siga= " << siga << G4endl;
|
||||
if ( meanLoss > minFraction*kineticEnergy ) {
|
||||
G4double gam = (kineticEnergy - meanLoss)/particleMass + 1.0;
|
||||
G4double b2 = 1.0 - 1.0/(gam*gam);
|
||||
if(b2 < xmin*beta2) b2 = xmin*beta2;
|
||||
G4double x = b2/beta2;
|
||||
G4double x3 = 1.0/(x*x*x);
|
||||
siga *= 0.25*(1.0 + x)*(x3 + (1.0/b2 - 0.5)/(1.0/beta2 - 0.5) );
|
||||
}
|
||||
// G4cout << "siga= " << siga << G4endl;
|
||||
siga = sqrt(siga);
|
||||
|
||||
G4double lossmax = meanLoss+meanLoss;
|
||||
do {
|
||||
loss = G4RandGauss::shoot(meanLoss,siga);
|
||||
} while (0.0 > loss || loss > lossmax);
|
||||
|
||||
// Poisson fluctuations
|
||||
} else {
|
||||
|
||||
G4double n = (G4double)(G4Poisson(navr));
|
||||
loss = meanLoss*n/navr;
|
||||
}
|
||||
|
||||
// G4cout << "meanLoss= " << meanLoss << " loss= " << loss << G4endl;
|
||||
return loss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IonFluctuations::Dispersion(
|
||||
const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length)
|
||||
{
|
||||
particleMass = dp->GetMass();
|
||||
G4double q = dp->GetCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
chargeSqRatio = chargeSquare/(charge*charge);
|
||||
|
||||
G4double electronDensity = material->GetElectronDensity();
|
||||
kineticEnergy = dp->GetKineticEnergy();
|
||||
// G4cout << "e= " << kineticEnergy << " m= " << particleMass
|
||||
// << " tmax= " << tmax << " l= " << length << " q^2= " << chargeSquare << G4endl;
|
||||
G4double gam = kineticEnergy/particleMass + 1.0;
|
||||
beta2 = 1.0 - 1.0/(gam*gam);
|
||||
G4double siga = (1.0/beta2 - 0.5)*tmax*length*electronDensity*twopi_mc2_rcl2*chargeSquare;
|
||||
// G4cout << "siga= " << siga << G4endl;
|
||||
|
||||
// Low velocity - additional ion charge fluctuations according to
|
||||
// Q.Yang et al., NIM B61(1991)149-155.
|
||||
G4double zeff = electronDensity/(material->GetTotNbOfAtomsPerVolume());
|
||||
//G4cout << "siga= " << siga << " zeff= " << zeff << G4endl;
|
||||
|
||||
if ( beta2 < 3.0*theBohrBeta2*zeff ) {
|
||||
|
||||
G4double a = CoeffitientA (zeff);
|
||||
G4double b = CoeffitientB (material, zeff);
|
||||
// G4cout << "a= " << a << " b= " << b << G4endl;
|
||||
siga *= (a*chargeSqRatio + b);
|
||||
} else {
|
||||
|
||||
// H.Geissel et al. NIM B, 195 (2002) 3.
|
||||
siga *= RelativisticFactor(material, zeff);
|
||||
}
|
||||
|
||||
return siga;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IonFluctuations::CoeffitientA(G4double& zeff)
|
||||
{
|
||||
// The aproximation of energy loss fluctuations
|
||||
// Q.Yang et al., NIM B61(1991)149-155.
|
||||
|
||||
// Reduced energy in MeV/AMU
|
||||
G4double energy = kineticEnergy * amu_c2/(particleMass*MeV) ;
|
||||
static G4double a[96][4] = {
|
||||
{-0.3291, -0.8312, 0.2460, -1.0220},
|
||||
{-0.5615, -0.5898, 0.5205, -0.7258},
|
||||
{-0.5280, -0.4981, 0.5519, -0.5865},
|
||||
{-0.5125, -0.4625, 0.5660, -0.5190},
|
||||
{-0.5127, -0.8595, 0.5626, -0.8721},
|
||||
{-0.5174, -1.1930, 0.5565, -1.1980},
|
||||
{-0.5179, -1.1850, 0.5560, -1.2070},
|
||||
{-0.5209, -0.9355, 0.5590, -1.0250},
|
||||
{-0.5255, -0.7766, 0.5720, -0.9412},
|
||||
|
||||
{-0.5776, -0.6665, 0.6598, -0.8484},
|
||||
{-0.6013, -0.6045, 0.7321, -0.7671},
|
||||
{-0.5781, -0.5518, 0.7605, -0.6919},
|
||||
{-0.5587, -0.4981, 0.7835, -0.6195},
|
||||
{-0.5466, -0.4656, 0.7978, -0.5771},
|
||||
{-0.5406, -0.4690, 0.8031, -0.5718},
|
||||
{-0.5391, -0.5061, 0.8024, -0.5974},
|
||||
{-0.5380, -0.6483, 0.7962, -0.6970},
|
||||
{-0.5355, -0.7722, 0.7962, -0.7839},
|
||||
{-0.5329, -0.7720, 0.7988, -0.7846},
|
||||
|
||||
{-0.5335, -0.7671, 0.7984, -0.7933},
|
||||
{-0.5324, -0.7612, 0.7998, -0.8031},
|
||||
{-0.5305, -0.7300, 0.8031, -0.7990},
|
||||
{-0.5307, -0.7178, 0.8049, -0.8216},
|
||||
{-0.5248, -0.6621, 0.8165, -0.7919},
|
||||
{-0.5180, -0.6502, 0.8266, -0.7986},
|
||||
{-0.5084, -0.6408, 0.8396, -0.8048},
|
||||
{-0.4967, -0.6331, 0.8549, -0.8093},
|
||||
{-0.4861, -0.6508, 0.8712, -0.8432},
|
||||
{-0.4700, -0.6186, 0.8961, -0.8132},
|
||||
|
||||
{-0.4545, -0.5720, 0.9227, -0.7710},
|
||||
{-0.4404, -0.5226, 0.9481, -0.7254},
|
||||
{-0.4288, -0.4778, 0.9701, -0.6850},
|
||||
{-0.4199, -0.4425, 0.9874, -0.6539},
|
||||
{-0.4131, -0.4188, 0.9998, -0.6332},
|
||||
{-0.4089, -0.4057, 1.0070, -0.6218},
|
||||
{-0.4039, -0.3913, 1.0150, -0.6107},
|
||||
{-0.3987, -0.3698, 1.0240, -0.5938},
|
||||
{-0.3977, -0.3608, 1.0260, -0.5852},
|
||||
{-0.3972, -0.3600, 1.0260, -0.5842},
|
||||
|
||||
{-0.3985, -0.3803, 1.0200, -0.6013},
|
||||
{-0.3985, -0.3979, 1.0150, -0.6168},
|
||||
{-0.3968, -0.3990, 1.0160, -0.6195},
|
||||
{-0.3971, -0.4432, 1.0050, -0.6591},
|
||||
{-0.3944, -0.4665, 1.0010, -0.6825},
|
||||
{-0.3924, -0.5109, 0.9921, -0.7235},
|
||||
{-0.3882, -0.5158, 0.9947, -0.7343},
|
||||
{-0.3838, -0.5125, 0.9999, -0.7370},
|
||||
{-0.3786, -0.4976, 1.0090, -0.7310},
|
||||
{-0.3741, -0.4738, 1.0200, -0.7155},
|
||||
|
||||
{-0.3969, -0.4496, 1.0320, -0.6982},
|
||||
{-0.3663, -0.4297, 1.0430, -0.6828},
|
||||
{-0.3630, -0.4120, 1.0530, -0.6689},
|
||||
{-0.3597, -0.3964, 1.0620, -0.6564},
|
||||
{-0.3555, -0.3809, 1.0720, -0.6454},
|
||||
{-0.3525, -0.3607, 1.0820, -0.6289},
|
||||
{-0.3505, -0.3465, 1.0900, -0.6171},
|
||||
{-0.3397, -0.3570, 1.1020, -0.6384},
|
||||
{-0.3314, -0.3552, 1.1130, -0.6441},
|
||||
{-0.3235, -0.3531, 1.1230, -0.6498},
|
||||
|
||||
{-0.3150, -0.3483, 1.1360, -0.6539},
|
||||
{-0.3060, -0.3441, 1.1490, -0.6593},
|
||||
{-0.2968, -0.3396, 1.1630, -0.6649},
|
||||
{-0.2935, -0.3225, 1.1760, -0.6527},
|
||||
{-0.2797, -0.3262, 1.1940, -0.6722},
|
||||
{-0.2704, -0.3202, 1.2100, -0.6770},
|
||||
{-0.2815, -0.3227, 1.2480, -0.6775},
|
||||
{-0.2880, -0.3245, 1.2810, -0.6801},
|
||||
{-0.3034, -0.3263, 1.3270, -0.6778},
|
||||
{-0.2936, -0.3215, 1.3430, -0.6835},
|
||||
|
||||
{-0.3282, -0.3200, 1.3980, -0.6650},
|
||||
{-0.3260, -0.3070, 1.4090, -0.6552},
|
||||
{-0.3511, -0.3074, 1.4470, -0.6442},
|
||||
{-0.3501, -0.3064, 1.4500, -0.6442},
|
||||
{-0.3490, -0.3027, 1.4550, -0.6418},
|
||||
{-0.3487, -0.3048, 1.4570, -0.6447},
|
||||
{-0.3478, -0.3074, 1.4600, -0.6483},
|
||||
{-0.3501, -0.3283, 1.4540, -0.6669},
|
||||
{-0.3494, -0.3373, 1.4550, -0.6765},
|
||||
{-0.3485, -0.3373, 1.4570, -0.6774},
|
||||
|
||||
{-0.3462, -0.3300, 1.4630, -0.6728},
|
||||
{-0.3462, -0.3225, 1.4690, -0.6662},
|
||||
{-0.3453, -0.3094, 1.4790, -0.6553},
|
||||
{-0.3844, -0.3134, 1.5240, -0.6412},
|
||||
{-0.3848, -0.3018, 1.5310, -0.6303},
|
||||
{-0.3862, -0.2955, 1.5360, -0.6237},
|
||||
{-0.4262, -0.2991, 1.5860, -0.6115},
|
||||
{-0.4278, -0.2910, 1.5900, -0.6029},
|
||||
{-0.4303, -0.2817, 1.5940, -0.5927},
|
||||
{-0.4315, -0.2719, 1.6010, -0.5829},
|
||||
|
||||
{-0.4359, -0.2914, 1.6050, -0.6010},
|
||||
{-0.4365, -0.2982, 1.6080, -0.6080},
|
||||
{-0.4253, -0.3037, 1.6120, -0.6150},
|
||||
{-0.4335, -0.3245, 1.6160, -0.6377},
|
||||
{-0.4307, -0.3292, 1.6210, -0.6447},
|
||||
{-0.4284, -0.3204, 1.6290, -0.6380},
|
||||
{-0.4227, -0.3217, 1.6360, -0.6438}
|
||||
} ;
|
||||
|
||||
G4int iz = (G4int)zeff - 2 ;
|
||||
if( 0 > iz ) iz = 0 ;
|
||||
if(95 < iz ) iz = 95 ;
|
||||
|
||||
G4double q = 1.0 / (1.0 + a[iz][0]*pow(energy,a[iz][1])+
|
||||
+ a[iz][2]*pow(energy,a[iz][3])) ;
|
||||
|
||||
return q ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IonFluctuations::CoeffitientB(const G4Material* material, G4double& zeff)
|
||||
{
|
||||
// The aproximation of energy loss fluctuations
|
||||
// Q.Yang et al., NIM B61(1991)149-155.
|
||||
|
||||
// Reduced energy in MeV/AMU
|
||||
G4double energy = kineticEnergy *amu_c2/(particleMass*MeV) ;
|
||||
|
||||
G4int i = 0 ;
|
||||
G4double factor = 1.0 ;
|
||||
|
||||
// The index of set of parameters i = 0 for protons(hadrons) in gases
|
||||
// 1 for protons(hadrons) in solids
|
||||
// 2 for ions in atomic gases
|
||||
// 3 for ions in molecular gases
|
||||
// 4 for ions in solids
|
||||
static G4double b[5][4] = {
|
||||
{0.1014, 0.3700, 0.9642, 3.987},
|
||||
{0.1955, 0.6941, 2.522, 1.040},
|
||||
{0.05058, 0.08975, 0.1419, 10.80},
|
||||
{0.05009, 0.08660, 0.2751, 3.787},
|
||||
{0.01273, 0.03458, 0.3951, 3.812}
|
||||
} ;
|
||||
|
||||
// protons (hadrons)
|
||||
if(1.5 > charge) {
|
||||
if( kStateGas != material->GetState() ) i = 1 ;
|
||||
|
||||
// ions
|
||||
} else {
|
||||
factor = charge * pow(charge/zeff, 0.3333) ;
|
||||
|
||||
if( kStateGas == material->GetState() ) {
|
||||
energy /= (charge * sqrt(charge)) ;
|
||||
|
||||
if(1 == (material->GetNumberOfElements())) {
|
||||
i = 2 ;
|
||||
} else {
|
||||
i = 3 ;
|
||||
}
|
||||
|
||||
} else {
|
||||
energy /= (charge * sqrt(charge*zeff)) ;
|
||||
i = 4 ;
|
||||
}
|
||||
}
|
||||
|
||||
G4double x = b[i][2] * (1.0 - exp( - energy * b[i][3] )) ;
|
||||
|
||||
G4double q = factor * x * b[i][0] /
|
||||
((energy - b[i][1])*(energy - b[i][1]) + x*x) ;
|
||||
|
||||
return q ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IonFluctuations::RelativisticFactor(const G4Material*, G4double& zeff)
|
||||
{
|
||||
// H.Geissel et al. NIM B, 195 (2002) 3.
|
||||
G4double factor = 1.0 + 0.667*theBohrBeta2*(1.0 - beta2)
|
||||
* log(2.0*electron_mass_c2/(5.0*charge*eV))
|
||||
/ ((1.0 - 0.5*beta2)*beta2*zeff) ;
|
||||
factor *= (1.0 + 1.415e-4*chargeSquare/beta2);
|
||||
// G4cout << "factor= " << factor << G4endl;
|
||||
return factor;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -1,288 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Implementation of class for selecting ionisation model depending on
|
||||
// logical volume
|
||||
//
|
||||
//
|
||||
|
||||
#include "G4IonisationByLogicalVolume.hh"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4IonisationByLogicalVolume::
|
||||
G4IonisationByLogicalVolume( const G4String& particleName,
|
||||
G4LogicalVolume* volumeForPAImodel,
|
||||
const G4String& processName ) :
|
||||
G4VContinuousDiscreteProcess(processName),
|
||||
fPAIonisation(NULL),feIonisation(NULL),fMuIonisation(NULL),fhIonisation(NULL)
|
||||
{
|
||||
fParticleName = particleName ;
|
||||
fVolumeForPAImodel = volumeForPAImodel ;
|
||||
fMaterialNameForPAI = volumeForPAImodel->GetMaterial()->GetName() ;
|
||||
|
||||
// fPAIonisation = new G4PAIonisation(fMaterialNameForPAI);
|
||||
fPAIonisation = new G4PAIonisation(volumeForPAImodel);
|
||||
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
feIonisation = new G4eIonisation52(particleName) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
fMuIonisation = new G4MuIonisation52(particleName) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fhIonisation = new G4hIonisation52(particleName) ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4IonisationByLogicalVolume::~G4IonisationByLogicalVolume()
|
||||
{
|
||||
if(fPAIonisation) delete fPAIonisation ;
|
||||
if(feIonisation) delete feIonisation ;
|
||||
if(fMuIonisation) delete fMuIonisation ;
|
||||
if(fhIonisation) delete fhIonisation ;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Methods
|
||||
|
||||
G4bool G4IonisationByLogicalVolume::
|
||||
IsApplicable( const G4ParticleDefinition& particle )
|
||||
{
|
||||
return( particle.GetPDGCharge() != 0.) ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
/* ***********************************************
|
||||
|
||||
G4double G4IonisationByLogicalVolume::
|
||||
GetConstraints(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial )
|
||||
{
|
||||
if ( aMaterial->GetName() == fMaterialNameForPAI )
|
||||
{
|
||||
return fPAIonisation->GetConstraints(aParticle,aMaterial) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
return feIonisation->GetConstraints(aParticle,aMaterial) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
return fMuIonisation->GetConstraints(aParticle,aMaterial) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fhIonisation->GetConstraints(aParticle,aMaterial) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
************************************** */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4VParticleChange*
|
||||
G4IonisationByLogicalVolume::PostStepDoIt( const G4Track& track,
|
||||
const G4Step& step )
|
||||
{
|
||||
if ( track.GetVolume()->GetLogicalVolume() == fVolumeForPAImodel )
|
||||
{
|
||||
pParticleChange = fPAIonisation->PostStepDoIt(track,step) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
pParticleChange = feIonisation->PostStepDoIt(track,step) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
pParticleChange = fMuIonisation->PostStepDoIt(track,step) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
pParticleChange = fhIonisation->PostStepDoIt(track,step) ;
|
||||
}
|
||||
}
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(track,step);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
void G4IonisationByLogicalVolume::
|
||||
BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
fPAIonisation->BuildPhysicsTable(aParticleType) ;
|
||||
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
feIonisation->BuildPhysicsTable(aParticleType) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
fMuIonisation->BuildPhysicsTable(aParticleType) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
fhIonisation->BuildPhysicsTable(aParticleType) ;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4IonisationByLogicalVolume::
|
||||
GetContinuousStepLimit( const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4double currentMinimumStep,
|
||||
G4double& currentSafety )
|
||||
{
|
||||
G4double x = 0.0;
|
||||
|
||||
if ( track.GetVolume()->GetLogicalVolume() == fVolumeForPAImodel )
|
||||
{
|
||||
x = fPAIonisation->GetContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimumStep,currentSafety) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
x = feIonisation->GetContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimumStep,currentSafety) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
x = fMuIonisation->GetContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimumStep,currentSafety) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = fhIonisation->GetContinuousStepLimit(track,previousStepSize,
|
||||
currentMinimumStep,currentSafety) ;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4double G4IonisationByLogicalVolume::
|
||||
GetMeanFreePath( const G4Track& track,
|
||||
G4double previousStepSize,
|
||||
G4ForceCondition* condition )
|
||||
{
|
||||
G4double x = 0.0;
|
||||
if ( track.GetVolume()->GetLogicalVolume() == fVolumeForPAImodel )
|
||||
{
|
||||
x = fPAIonisation->GetMeanFreePath(track,previousStepSize,condition) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
x = feIonisation->GetMeanFreePath(track,previousStepSize,condition) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
x = fMuIonisation->GetMeanFreePath(track,previousStepSize,condition) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = fhIonisation->GetMeanFreePath(track,previousStepSize,condition) ;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
G4VParticleChange*
|
||||
G4IonisationByLogicalVolume::AlongStepDoIt( const G4Track& track ,
|
||||
const G4Step& step )
|
||||
{
|
||||
if ( track.GetVolume()->GetLogicalVolume() == fVolumeForPAImodel )
|
||||
{
|
||||
return fPAIonisation->AlongStepDoIt(track,step) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fParticleName == "e+" || fParticleName == "e-" )
|
||||
{
|
||||
return feIonisation->AlongStepDoIt(track,step) ;
|
||||
}
|
||||
else if ( fParticleName == "mu+" || fParticleName == "mu-" )
|
||||
{
|
||||
return fMuIonisation->AlongStepDoIt(track,step) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return fhIonisation->AlongStepDoIt(track,step) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
void G4IonisationByLogicalVolume::
|
||||
SetVolumeForPAImodel( G4LogicalVolume* volumeForPAImodel )
|
||||
{
|
||||
fVolumeForPAImodel = volumeForPAImodel ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4MollerBhabhaModel.cc,v 1.14 2003/11/19 19:38:46 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-01 $
|
||||
// $Id: G4MollerBhabhaModel.cc,v 1.15 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -59,6 +59,8 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4MollerBhabhaModel::G4MollerBhabhaModel(const G4ParticleDefinition* p,
|
||||
const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
@@ -152,7 +154,7 @@ G4double G4MollerBhabhaModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
|
||||
eexc /= electron_mass_c2;
|
||||
G4double eexc2 = eexc*eexc;
|
||||
|
||||
G4double d = std::min(cutEnergy, MaxSecondaryEnergy(p, tkin))/electron_mass_c2;
|
||||
G4double d = min(cutEnergy, MaxSecondaryEnergy(p, tkin))/electron_mass_c2;
|
||||
G4double dedx;
|
||||
|
||||
// electron
|
||||
@@ -214,7 +216,7 @@ G4double G4MollerBhabhaModel::CrossSection(const G4MaterialCutsCouple* couple,
|
||||
|
||||
G4double cross = 0.0;
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
tmax = std::min(maxEnergy, tmax);
|
||||
tmax = min(maxEnergy, tmax);
|
||||
|
||||
if(cutEnergy < tmax) {
|
||||
|
||||
@@ -263,7 +265,7 @@ G4DynamicParticle* G4MollerBhabhaModel::SampleSecondary(
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4double tmax = std::min(maxEnergy, MaxSecondaryEnergy(dp));
|
||||
G4double tmax = min(maxEnergy, MaxSecondaryEnergy(dp));
|
||||
if(tmin > tmax) tmin = tmax;
|
||||
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
@@ -364,13 +366,13 @@ G4DynamicParticle* G4MollerBhabhaModel::SampleSecondary(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
std::vector<G4DynamicParticle*>* G4MollerBhabhaModel::SampleSecondaries(
|
||||
vector<G4DynamicParticle*>* G4MollerBhabhaModel::SampleSecondaries(
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
std::vector<G4DynamicParticle*>* vdp = new std::vector<G4DynamicParticle*>;
|
||||
vector<G4DynamicParticle*>* vdp = new vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
|
||||
|
||||
@@ -0,0 +1,689 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4MscModel.cc,v 1.2 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4MscModel
|
||||
//
|
||||
// Author: Laszlo Urban
|
||||
//
|
||||
// Creation date: 03.03.2001
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 27-03-03 Move model part from G4MultipleScattering (V.Ivanchenko)
|
||||
// 23-05-03 important change in angle distribution for muons/hadrons
|
||||
// the central part now is similar to the Highland parametrization +
|
||||
// minor correction in angle sampling algorithm (for all particles)
|
||||
// (L.Urban)
|
||||
// 30-05-03 misprint in SampleCosineTheta corrected(L.Urban)
|
||||
// 27-03-03 Rename (V.Ivanchenko)
|
||||
// 05-08-03 angle distribution has been modified (L.Urban)
|
||||
// 06-11-03 precision problems solved for high energy (PeV) particles
|
||||
// change in the tail of the angular distribution
|
||||
// highKinEnergy is set to 100 PeV (L.Urban)
|
||||
//
|
||||
// 10-11-03 highKinEnergy is set back to 100 TeV, some tail tuning +
|
||||
// cleaning (L.Urban)
|
||||
// 26-11-03 correction in TrueStepLength :
|
||||
// trueLength <= currentRange (L.Urban)
|
||||
// 01-03-04 signature changed in SampleCosineTheta,
|
||||
// energy dependence calculations has been simplified,
|
||||
// 11-03-04 corrections in GeomPathLength,TrueStepLength,
|
||||
// SampleCosineTheta
|
||||
// 23-04-04 true -> geom and geom -> true transformation has been
|
||||
// rewritten, changes in the angular distribution (L.Urban)
|
||||
// 19-07-04 correction in SampleCosineTheta in order to avoid
|
||||
// num. precision problems at high energy/small step(L.Urban)
|
||||
// 17-08-04 changes in the angle distribution (slightly modified
|
||||
// Highland formula for the width of the central part,
|
||||
// changes in the numerical values of some other parameters)
|
||||
// ---> approximately step independent distribution (L.Urban)
|
||||
// 21-09-04 change in the tail of the angular distribution (L.Urban)
|
||||
//
|
||||
// 03-11-04 precision problem for very high energy ions and small stepsize
|
||||
// solved in SampleCosineTheta (L.Urban).
|
||||
//
|
||||
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of the model of multiple scattering based on
|
||||
// H.W.Lewis Phys Rev 78 (1950) 526 and others
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4MscModel.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4MscModel::G4MscModel(G4double& m_dtrl, G4double& m_NuclCorrPar,
|
||||
G4double& m_FactPar, G4double& m_factail,
|
||||
G4bool& m_samplez, const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
taubig(8.0),
|
||||
tausmall(1.e-20),
|
||||
taulim(1.e-6),
|
||||
dtrl(m_dtrl),
|
||||
NuclCorrPar (m_NuclCorrPar),
|
||||
FactPar(m_FactPar),
|
||||
factail(m_factail),
|
||||
samplez(m_samplez)
|
||||
{
|
||||
highKinEnergy = 100.0*TeV;
|
||||
lowKinEnergy = 0.1*keV;
|
||||
stepmin = 1.e-6*mm;
|
||||
currentRange = 0. ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4MscModel::~G4MscModel()
|
||||
{}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4MscModel::IsInCharge(const G4ParticleDefinition* p)
|
||||
{
|
||||
return (p->GetPDGCharge() != 0.0);
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4MscModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector&)
|
||||
{
|
||||
// set values of some data members
|
||||
sigmafactor = twopi*classic_electr_radius*classic_electr_radius;
|
||||
particle = p;
|
||||
mass = particle->GetPDGMass();
|
||||
charge = particle->GetPDGCharge()/eplus;
|
||||
b = 1. ;
|
||||
xsi = 3.00 ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4MscModel::CrossSection(const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* NbOfAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
|
||||
G4int NumberOfElements = material->GetNumberOfElements();
|
||||
|
||||
// loop for element in the material
|
||||
G4double sigma = 0.0;
|
||||
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++)
|
||||
{
|
||||
G4double atomicNumber = (*theElementVector)[iel]->GetZ();
|
||||
G4double atomicWeight = (*theElementVector)[iel]->GetA();
|
||||
sigma += NbOfAtomsPerVolume[iel]*ComputeTransportCrossSection(p,
|
||||
kineticEnergy,atomicNumber,atomicWeight);
|
||||
}
|
||||
sigma *= sigmafactor;
|
||||
// Calculate lambda
|
||||
if ( sigma > 0.0) sigma = 1.0/sigma;
|
||||
else sigma = DBL_MAX;
|
||||
|
||||
return sigma;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4MscModel::ComputeTransportCrossSection(
|
||||
const G4ParticleDefinition* part,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber,
|
||||
G4double AtomicWeight)
|
||||
{
|
||||
const G4double epsfactor = 2.*electron_mass_c2*electron_mass_c2*
|
||||
Bohr_radius*Bohr_radius/(hbarc*hbarc);
|
||||
const G4double epsmin = 1.e-4 , epsmax = 1.e10;
|
||||
|
||||
const G4double Zdat[15] = { 4., 6.,13.,20.,26.,29.,32.,38.,47.,
|
||||
50.,56.,64.,74.,79.,82. };
|
||||
|
||||
const G4double Tdat[23] = {0.0001*MeV,0.0002*MeV,0.0004*MeV,0.0007*MeV,
|
||||
0.001*MeV,0.002*MeV,0.004*MeV,0.007*MeV,
|
||||
0.01*MeV,0.02*MeV,0.04*MeV,0.07*MeV,
|
||||
0.1*MeV,0.2*MeV,0.4*MeV,0.7*MeV,
|
||||
1.*MeV,2.*MeV,4.*MeV,7.*MeV,10.*MeV,20.*MeV,
|
||||
10000.0*MeV};
|
||||
|
||||
// corr. factors for e-/e+ lambda
|
||||
G4double celectron[15][23] =
|
||||
{{1.125,1.072,1.051,1.047,1.047,1.050,1.052,1.054,
|
||||
1.054,1.057,1.062,1.069,1.075,1.090,1.105,1.111,
|
||||
1.112,1.108,1.100,1.093,1.089,1.087,0.7235 },
|
||||
{1.408,1.246,1.143,1.096,1.077,1.059,1.053,1.051,
|
||||
1.052,1.053,1.058,1.065,1.072,1.087,1.101,1.108,
|
||||
1.109,1.105,1.097,1.090,1.086,1.082,0.7925 },
|
||||
{2.833,2.268,1.861,1.612,1.486,1.309,1.204,1.156,
|
||||
1.136,1.114,1.106,1.106,1.109,1.119,1.129,1.132,
|
||||
1.131,1.124,1.113,1.104,1.099,1.098,0.9147 },
|
||||
{3.879,3.016,2.380,2.007,1.818,1.535,1.340,1.236,
|
||||
1.190,1.133,1.107,1.099,1.098,1.103,1.110,1.113,
|
||||
1.112,1.105,1.096,1.089,1.085,1.098,0.9700 },
|
||||
{6.937,4.330,2.886,2.256,1.987,1.628,1.395,1.265,
|
||||
1.203,1.122,1.080,1.065,1.061,1.063,1.070,1.073,
|
||||
1.073,1.070,1.064,1.059,1.056,1.056,1.0022 },
|
||||
{9.616,5.708,3.424,2.551,2.204,1.762,1.485,1.330,
|
||||
1.256,1.155,1.099,1.077,1.070,1.068,1.072,1.074,
|
||||
1.074,1.070,1.063,1.059,1.056,1.052,1.0158 },
|
||||
{11.72,6.364,3.811,2.806,2.401,1.884,1.564,1.386,
|
||||
1.300,1.180,1.112,1.082,1.073,1.066,1.068,1.069,
|
||||
1.068,1.064,1.059,1.054,1.051,1.050,1.0284 },
|
||||
{18.08,8.601,4.569,3.183,2.662,2.025,1.646,1.439,
|
||||
1.339,1.195,1.108,1.068,1.053,1.040,1.039,1.039,
|
||||
1.039,1.037,1.034,1.031,1.030,1.036,1.0515 },
|
||||
{18.22,10.48,5.333,3.713,3.115,2.367,1.898,1.631,
|
||||
1.498,1.301,1.171,1.105,1.077,1.048,1.036,1.033,
|
||||
1.031,1.028,1.024,1.022,1.021,1.024,1.0834 },
|
||||
{14.14,10.65,5.710,3.929,3.266,2.453,1.951,1.669,
|
||||
1.528,1.319,1.178,1.106,1.075,1.040,1.027,1.022,
|
||||
1.020,1.017,1.015,1.013,1.013,1.020,1.0937 },
|
||||
{14.11,11.73,6.312,4.240,3.478,2.566,2.022,1.720,
|
||||
1.569,1.342,1.186,1.102,1.065,1.022,1.003,0.997,
|
||||
0.995,0.993,0.993,0.993,0.993,1.011,1.1140 },
|
||||
{22.76,20.01,8.835,5.287,4.144,2.901,2.219,1.855,
|
||||
1.677,1.410,1.224,1.121,1.073,1.014,0.986,0.976,
|
||||
0.974,0.972,0.973,0.974,0.975,0.987,1.1410 },
|
||||
{50.77,40.85,14.13,7.184,5.284,3.435,2.520,2.059,
|
||||
1.837,1.512,1.283,1.153,1.091,1.010,0.969,0.954,
|
||||
0.950,0.947,0.949,0.952,0.954,0.963,1.1750 },
|
||||
{65.87,59.06,15.87,7.570,5.567,3.650,2.682,2.182,
|
||||
1.939,1.579,1.325,1.178,1.108,1.014,0.965,0.947,
|
||||
0.941,0.938,0.940,0.944,0.946,0.954,1.1922 },
|
||||
{55.60,47.34,15.92,7.810,5.755,3.767,2.760,2.239,
|
||||
1.985,1.609,1.343,1.188,1.113,1.013,0.960,0.939,
|
||||
0.933,0.930,0.933,0.936,0.939,0.949,1.2026 }};
|
||||
G4double cpositron[15][23] = {
|
||||
{2.589,2.044,1.658,1.446,1.347,1.217,1.144,1.110,
|
||||
1.097,1.083,1.080,1.086,1.092,1.108,1.123,1.131,
|
||||
1.131,1.126,1.117,1.108,1.103,1.100,0.7235 },
|
||||
{3.904,2.794,2.079,1.710,1.543,1.325,1.202,1.145,
|
||||
1.122,1.096,1.089,1.092,1.098,1.114,1.130,1.137,
|
||||
1.138,1.132,1.122,1.113,1.108,1.102,0.7925 },
|
||||
{7.970,6.080,4.442,3.398,2.872,2.127,1.672,1.451,
|
||||
1.357,1.246,1.194,1.179,1.178,1.188,1.201,1.205,
|
||||
1.203,1.190,1.173,1.159,1.151,1.145,0.9147 },
|
||||
{9.714,7.607,5.747,4.493,3.815,2.777,2.079,1.715,
|
||||
1.553,1.353,1.253,1.219,1.211,1.214,1.225,1.228,
|
||||
1.225,1.210,1.191,1.175,1.166,1.174,0.9700 },
|
||||
{17.97,12.95,8.628,6.065,4.849,3.222,2.275,1.820,
|
||||
1.624,1.382,1.259,1.214,1.202,1.202,1.214,1.219,
|
||||
1.217,1.203,1.184,1.169,1.160,1.151,1.0022 },
|
||||
{24.83,17.06,10.84,7.355,5.767,3.707,2.546,1.996,
|
||||
1.759,1.465,1.311,1.252,1.234,1.228,1.238,1.241,
|
||||
1.237,1.222,1.201,1.184,1.174,1.159,1.0158 },
|
||||
{23.26,17.15,11.52,8.049,6.375,4.114,2.792,2.155,
|
||||
1.880,1.535,1.353,1.281,1.258,1.247,1.254,1.256,
|
||||
1.252,1.234,1.212,1.194,1.183,1.170,1.0284 },
|
||||
{22.33,18.01,12.86,9.212,7.336,4.702,3.117,2.348,
|
||||
2.015,1.602,1.385,1.297,1.268,1.251,1.256,1.258,
|
||||
1.254,1.237,1.214,1.195,1.185,1.179,1.0515 },
|
||||
{33.91,24.13,15.71,10.80,8.507,5.467,3.692,2.808,
|
||||
2.407,1.873,1.564,1.425,1.374,1.330,1.324,1.320,
|
||||
1.312,1.288,1.258,1.235,1.221,1.205,1.0834 },
|
||||
{32.14,24.11,16.30,11.40,9.015,5.782,3.868,2.917,
|
||||
2.490,1.925,1.596,1.447,1.391,1.342,1.332,1.327,
|
||||
1.320,1.294,1.264,1.240,1.226,1.214,1.0937 },
|
||||
{29.51,24.07,17.19,12.28,9.766,6.238,4.112,3.066,
|
||||
2.602,1.995,1.641,1.477,1.414,1.356,1.342,1.336,
|
||||
1.328,1.302,1.270,1.245,1.231,1.233,1.1140 },
|
||||
{38.19,30.85,21.76,15.35,12.07,7.521,4.812,3.498,
|
||||
2.926,2.188,1.763,1.563,1.484,1.405,1.382,1.371,
|
||||
1.361,1.330,1.294,1.267,1.251,1.239,1.1410 },
|
||||
{49.71,39.80,27.96,19.63,15.36,9.407,5.863,4.155,
|
||||
3.417,2.478,1.944,1.692,1.589,1.480,1.441,1.423,
|
||||
1.409,1.372,1.330,1.298,1.280,1.258,1.1750 },
|
||||
{59.25,45.08,30.36,20.83,16.15,9.834,6.166,4.407,
|
||||
3.641,2.648,2.064,1.779,1.661,1.531,1.482,1.459,
|
||||
1.442,1.400,1.354,1.319,1.299,1.272,1.1922 },
|
||||
{56.38,44.29,30.50,21.18,16.51,10.11,6.354,4.542,
|
||||
3.752,2.724,2.116,1.817,1.692,1.554,1.499,1.474,
|
||||
1.456,1.412,1.364,1.328,1.307,1.282,1.2026 }};
|
||||
|
||||
G4double sigma;
|
||||
if (part != particle ) {
|
||||
particle = part;
|
||||
mass = particle->GetPDGMass();
|
||||
charge = particle->GetPDGCharge()/eplus;
|
||||
}
|
||||
|
||||
G4double Z23 = 2.*log(AtomicNumber)/3.; Z23 = exp(Z23);
|
||||
|
||||
// correction if particle .ne. e-/e+
|
||||
// compute equivalent kinetic energy
|
||||
// lambda depends on p*beta ....
|
||||
|
||||
G4double eKineticEnergy = KineticEnergy;
|
||||
|
||||
if((particle->GetParticleName() != "e-") &&
|
||||
(particle->GetParticleName() != "e+") )
|
||||
{
|
||||
G4double TAU = KineticEnergy/mass ;
|
||||
G4double c = mass*TAU*(TAU+2.)/(electron_mass_c2*(TAU+1.)) ;
|
||||
G4double w = c-2. ;
|
||||
G4double tau = 0.5*(w+sqrt(w*w+4.*c)) ;
|
||||
eKineticEnergy = electron_mass_c2*tau ;
|
||||
}
|
||||
|
||||
G4double ChargeSquare = charge*charge;
|
||||
|
||||
G4double eTotalEnergy = eKineticEnergy + electron_mass_c2 ;
|
||||
G4double beta2 = eKineticEnergy*(eTotalEnergy+electron_mass_c2)
|
||||
/(eTotalEnergy*eTotalEnergy);
|
||||
G4double bg2 = eKineticEnergy*(eTotalEnergy+electron_mass_c2)
|
||||
/(electron_mass_c2*electron_mass_c2);
|
||||
|
||||
G4double eps = epsfactor*bg2/Z23;
|
||||
|
||||
if (eps<epsmin) sigma = 2.*eps*eps;
|
||||
else if(eps<epsmax) sigma = log(1.+2.*eps)-2.*eps/(1.+2.*eps);
|
||||
else sigma = log(2.*eps)-1.+1./eps;
|
||||
|
||||
sigma *= ChargeSquare*AtomicNumber*AtomicNumber/(beta2*bg2);
|
||||
|
||||
// nuclear size effect correction for high energy
|
||||
// ( a simple approximation at present)
|
||||
G4double corrnuclsize,a,w1,w2,w;
|
||||
|
||||
G4double x0 = 1. - NuclCorrPar*mass/(KineticEnergy*
|
||||
exp(log(AtomicWeight/(g/mole))/3.));
|
||||
if ( x0 < -1. || eKineticEnergy <= 10.*MeV)
|
||||
{
|
||||
x0 = -1.;
|
||||
corrnuclsize = 1.;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = 1.+1./eps;
|
||||
if (eps > epsmax) w1=log(2.*eps)+1./eps-3./(8.*eps*eps);
|
||||
else w1=log((a+1.)/(a-1.))-2./(a+1.);
|
||||
w = 1./((1.-x0)*eps);
|
||||
if (w < epsmin) w2=-log(w)-1.+2.*w-1.5*w*w;
|
||||
else w2 = log((a-x0)/(a-1.))-(1.-x0)/(a-x0);
|
||||
corrnuclsize = w1/w2;
|
||||
corrnuclsize = exp(-FactPar*mass/KineticEnergy)*
|
||||
(corrnuclsize-1.)+1.;
|
||||
}
|
||||
|
||||
// interpolate in AtomicNumber and beta2
|
||||
// get bin number in Z
|
||||
G4int iZ = 14;
|
||||
while ((iZ>=0)&&(Zdat[iZ]>=AtomicNumber)) iZ -= 1;
|
||||
if (iZ==14) iZ = 13;
|
||||
if (iZ==-1) iZ = 0 ;
|
||||
|
||||
G4double Z1 = Zdat[iZ];
|
||||
G4double Z2 = Zdat[iZ+1];
|
||||
G4double ratZ = (AtomicNumber-Z1)/(Z2-Z1);
|
||||
|
||||
// get bin number in T (beta2)
|
||||
G4int iT = 22;
|
||||
while ((iT>=0)&&(Tdat[iT]>=eKineticEnergy)) iT -= 1;
|
||||
if(iT==22) iT = 21;
|
||||
if(iT==-1) iT = 0 ;
|
||||
|
||||
// calculate betasquare values
|
||||
G4double T = Tdat[iT], E = T + electron_mass_c2;
|
||||
G4double b2small = T*(E+electron_mass_c2)/(E*E);
|
||||
T = Tdat[iT+1]; E = T + electron_mass_c2;
|
||||
G4double b2big = T*(E+electron_mass_c2)/(E*E);
|
||||
G4double ratb2 = (beta2-b2small)/(b2big-b2small);
|
||||
G4double c1,c2,cc1,cc2,corr;
|
||||
if (charge < 0.)
|
||||
{
|
||||
c1 = celectron[iZ][iT];
|
||||
c2 = celectron[iZ+1][iT];
|
||||
cc1 = c1+ratZ*(c2-c1);
|
||||
|
||||
c1 = celectron[iZ][iT+1];
|
||||
c2 = celectron[iZ+1][iT+1];
|
||||
cc2 = c1+ratZ*(c2-c1);
|
||||
|
||||
corr = cc1+ratb2*(cc2-cc1);
|
||||
sigma /= corr;
|
||||
}
|
||||
|
||||
if (charge > 0.)
|
||||
{
|
||||
c1 = cpositron[iZ][iT];
|
||||
c2 = cpositron[iZ+1][iT];
|
||||
cc1 = c1+ratZ*(c2-c1);
|
||||
|
||||
c1 = cpositron[iZ][iT+1];
|
||||
c2 = cpositron[iZ+1][iT+1];
|
||||
cc2 = c1+ratZ*(c2-c1);
|
||||
|
||||
corr = cc1+ratb2*(cc2-cc1);
|
||||
sigma /= corr;
|
||||
}
|
||||
|
||||
// nucl. size correction for particles other than e+/e- only at present !!!!
|
||||
if((particle->GetParticleName() != "e-") &&
|
||||
(particle->GetParticleName() != "e+") )
|
||||
sigma /= corrnuclsize;
|
||||
|
||||
return sigma;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4MscModel::GeomPathLength(
|
||||
G4PhysicsTable* theLambdaTable,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* theParticle,
|
||||
G4double& T0,
|
||||
G4double lambda,
|
||||
G4double range,
|
||||
G4double truePathLength)
|
||||
{
|
||||
// do the true -> geom transformation
|
||||
const G4double ztmax = 101./103. ;
|
||||
if (theParticle != particle ) {
|
||||
particle = theParticle;
|
||||
mass = particle->GetPDGMass();
|
||||
charge = particle->GetPDGCharge()/eplus;
|
||||
}
|
||||
currentKinEnergy = T0;
|
||||
currentRange = range ;
|
||||
currentRadLength = couple->GetMaterial()->GetRadlen();
|
||||
|
||||
lambda0 = lambda;
|
||||
par1 = -1. ;
|
||||
par2 = par3 = 0. ;
|
||||
tPathLength = truePathLength;
|
||||
|
||||
// this correction needed to run MSC with eIoni and eBrem inactivated
|
||||
// and makes no harm for a normal run
|
||||
if(tPathLength > range)
|
||||
tPathLength = range ;
|
||||
|
||||
G4double tau = tPathLength/lambda0 ;
|
||||
|
||||
if (tau <= tausmall) return tPathLength;
|
||||
|
||||
G4double zmean = tPathLength;
|
||||
if (tPathLength < range*dtrl) {
|
||||
zmean = lambda0*(1.-exp(-tau));
|
||||
if(tau < taulim) zmean = tPathLength*(1.-0.5*tPathLength/lambda0) ;
|
||||
} else if(T0 < mass) {
|
||||
par1 = 1./range ;
|
||||
par2 = 1./(par1*lambda0) ;
|
||||
par3 = 1.+par2 ;
|
||||
zmean = (1.-exp(par3*log(1.-tPathLength/range)))/(par1*par3) ;
|
||||
} else {
|
||||
G4LossTableManager* theManager = G4LossTableManager::Instance();
|
||||
G4double T1 = theManager->GetEnergy(particle,range-tPathLength,couple);
|
||||
G4double lambda1 ;
|
||||
if (theLambdaTable) {
|
||||
G4bool bb;
|
||||
lambda1 = ((*theLambdaTable)[couple->GetIndex()])->GetValue(T1,bb);
|
||||
} else {
|
||||
lambda1 = CrossSection(couple,particle,T1,0.0,1.0);
|
||||
}
|
||||
par1 = (lambda0-lambda1)/(lambda0*tPathLength) ;
|
||||
par2 = 1./(par1*lambda0) ;
|
||||
par3 = 1.+par2 ;
|
||||
zmean = (1.-exp(par3*log(lambda1/lambda0)))/(par1*par3) ;
|
||||
}
|
||||
|
||||
// sample z
|
||||
G4double zPathLength = zmean ;
|
||||
G4double zt = zmean/tPathLength ;
|
||||
if (tPathLength >= stepmin && samplez && zt > 0.5 && zt < ztmax)
|
||||
{
|
||||
G4double cz = 0.5*(3.*zt-1.)/(1.-zt) ;
|
||||
G4double cz1 = 1.+cz ;
|
||||
G4double u0 = cz/cz1 ;
|
||||
G4double u,grej ;
|
||||
do {
|
||||
u = exp(log(G4UniformRand())/cz1) ;
|
||||
grej = exp(cz*log(u/u0))*(1.-u)/(1.-u0) ;
|
||||
} while (grej < G4UniformRand()) ;
|
||||
zPathLength = tPathLength*u ;
|
||||
}
|
||||
|
||||
return zPathLength ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4MscModel::TrueStepLength(G4double geomStepLength)
|
||||
{
|
||||
G4double trueLength = geomStepLength;
|
||||
trueLength = geomStepLength;
|
||||
if(geomStepLength > lambda0*tausmall)
|
||||
{
|
||||
if(par1 < 0.)
|
||||
trueLength = -lambda0*log(1.-geomStepLength/lambda0) ;
|
||||
else
|
||||
{
|
||||
if(par1*par3*geomStepLength < 1.)
|
||||
trueLength = (1.-exp(log(1.-par1*par3*geomStepLength)/par3))/par1 ;
|
||||
else
|
||||
trueLength = currentRange ;
|
||||
}
|
||||
}
|
||||
|
||||
if(trueLength > tPathLength) trueLength = tPathLength;
|
||||
if(trueLength > currentRange) trueLength = currentRange ;
|
||||
if(trueLength < geomStepLength) trueLength = geomStepLength;
|
||||
|
||||
return trueLength;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4MscModel::SampleCosineTheta(G4double trueStepLength, G4double KineticEnergy)
|
||||
{
|
||||
G4double cth = 1. ;
|
||||
G4double tau = trueStepLength/lambda0 ;
|
||||
|
||||
if(trueStepLength >= currentRange*dtrl)
|
||||
if(par1*trueStepLength < 1.)
|
||||
tau = -par2*log(1.-par1*trueStepLength) ;
|
||||
else
|
||||
tau = taubig ;
|
||||
|
||||
currentTau = tau ;
|
||||
|
||||
if(trueStepLength < stepmin)
|
||||
cth = exp(-tau) ;
|
||||
else
|
||||
{
|
||||
if (tau >= taubig) cth = -1.+2.*G4UniformRand();
|
||||
else if (tau >= tausmall)
|
||||
{
|
||||
G4double a ;
|
||||
|
||||
// for all particles take the width of the central part
|
||||
// from a parametrization similar to the Highland formula
|
||||
// ( Highland formula: Particle Physics Booklet, July 2002, eq. 26.10)
|
||||
// here : theta0 = 13.6*MeV*Q*(t/X0)**0.555/(beta*cp)
|
||||
const G4double c_highland = 13.6*MeV, corr_highland=0.555 ;
|
||||
G4double Q = fabs(charge) ;
|
||||
G4double xx0 = trueStepLength/currentRadLength;
|
||||
G4double betacp = sqrt(currentKinEnergy*(currentKinEnergy+2.*mass)*
|
||||
KineticEnergy*(KineticEnergy+2.*mass)/
|
||||
((currentKinEnergy+mass)*(KineticEnergy+mass))) ;
|
||||
G4double theta0 = c_highland*Q*exp(corr_highland*log(xx0))/betacp ;
|
||||
|
||||
if(theta0 > taulim) a = 0.5/(1.-cos(theta0)) ;
|
||||
else a = 1.0/(theta0*theta0) ;
|
||||
|
||||
G4double xmeanth = exp(-tau);
|
||||
G4double xmeanth1 = 1.-xmeanth ;
|
||||
if(currentTau < taulim) xmeanth1 = tau ;
|
||||
|
||||
const G4double x1fac1 = exp(-xsi) ;
|
||||
const G4double x1fac2 = (1.-(1.+xsi)*x1fac1)/(1.-x1fac1) ;
|
||||
const G4double x1fac3 = 1.3 ;
|
||||
|
||||
G4double ea,eaa,xmean1 ;
|
||||
G4double c = 2.,b1 = 2., bx = 2.,
|
||||
eb1 = b1, ebx = b1, xmean2 = 0. ;
|
||||
G4double prob = 1., qprob ;
|
||||
G4double x0 = 1.-xsi/a;
|
||||
G4double oneminusx0=xsi/a ;
|
||||
G4double oneplusx0=2.+xsi/a ;
|
||||
|
||||
G4double f1x0=1., f2x0=1. ;
|
||||
const G4double tau0 = 0.10 ;
|
||||
if(tau > tau0)
|
||||
{
|
||||
// 1 model function
|
||||
a = 1./xmeanth1 ;
|
||||
ea = exp(-2.*a) ;
|
||||
eaa= 1.-ea ;
|
||||
xmean1 = 1.-1./a+2.*ea/eaa ;
|
||||
prob = 1. ;
|
||||
qprob = 1. ;
|
||||
}
|
||||
else if (x0 <= -1.)
|
||||
{
|
||||
// 2 model fuctions only
|
||||
// in order to have xmean1 > xmeanth -> qprob < 1
|
||||
x0 = -1.;
|
||||
|
||||
if( a < 1./xmeanth1)
|
||||
a = 1./xmeanth1 ;
|
||||
|
||||
oneminusx0 = 1.-x0 ;
|
||||
oneplusx0 = 1.+x0 ;
|
||||
ea = exp(-a*oneminusx0);
|
||||
eaa = 1.-ea ;
|
||||
xmean1 = 1.-1./a+oneminusx0*ea/eaa ;
|
||||
qprob = xmeanth/xmean1 ;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// 3 model fuctions
|
||||
// in order to have xmean1 > xmeanth
|
||||
if((1.-x1fac2/a) < xmeanth)
|
||||
{
|
||||
a = x1fac3*x1fac2/xmeanth1 ;
|
||||
x0 = 1.-xsi/a ;
|
||||
oneminusx0=xsi/a ;
|
||||
oneplusx0=2.-xsi/a ;
|
||||
}
|
||||
|
||||
ea = x1fac1 ;
|
||||
eaa = 1.-ea ;
|
||||
xmean1 = 1.-x1fac2/a ;
|
||||
|
||||
const G4double fctail = factail*1.0 ;
|
||||
c = 2.+fctail*tau ;
|
||||
G4double c1 = c-1. ;
|
||||
G4double c2 = c-2. ;
|
||||
if(c2 == 0.) c2 = fctail*tausmall ;
|
||||
|
||||
b = 1.+(c-xsi)/a ;
|
||||
|
||||
b1 = b+1. ;
|
||||
bx = c/a ;
|
||||
eb1=exp((c1)*log(b1)) ;
|
||||
ebx=exp((c1)*log(bx)) ;
|
||||
xmean2 = (x0*eb1+ebx-(eb1*bx-b1*ebx)/c2)/(eb1-ebx) ;
|
||||
|
||||
f1x0 = a*ea/eaa ;
|
||||
f2x0 = c1*eb1*ebx/(eb1-ebx)/
|
||||
exp(c*log(bx)) ;
|
||||
// from continuity at x=x0
|
||||
prob = f2x0/(f1x0+f2x0) ;
|
||||
// from xmean = xmeanth
|
||||
qprob = (f1x0+f2x0)*xmeanth/(f2x0*xmean1+f1x0*xmean2) ;
|
||||
|
||||
}
|
||||
|
||||
// sampling of costheta
|
||||
if (G4UniformRand() < qprob)
|
||||
{
|
||||
if (G4UniformRand() < prob)
|
||||
cth = 1.+log(ea+G4UniformRand()*eaa)/a ;
|
||||
else
|
||||
cth = b-b1*bx/exp(log(ebx-G4UniformRand()*(ebx-eb1))/(c-1.)) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
cth = -1.+2.*G4UniformRand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cth ;
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4MscModel::SampleDisplacement()
|
||||
{
|
||||
const G4double kappa = 2.5;
|
||||
const G4double kappapl1 = kappa+1.;
|
||||
const G4double kappami1 = kappa-1.;
|
||||
G4double rmean = 0.0;
|
||||
if (currentTau >= tausmall) {
|
||||
if (currentTau < taulim) {
|
||||
rmean = kappa*currentTau*currentTau*currentTau*(1.-kappapl1*currentTau*0.25)/6. ;
|
||||
|
||||
} else {
|
||||
G4double etau = 0.0;
|
||||
if (currentTau<taubig) etau = exp(-currentTau);
|
||||
rmean = -kappa*currentTau;
|
||||
rmean = -exp(rmean)/(kappa*kappami1);
|
||||
rmean += currentTau-kappapl1/kappa+kappa*etau/kappami1;
|
||||
}
|
||||
if (rmean>0.) rmean = 2.*lambda0*sqrt(rmean/3.0);
|
||||
else rmean = 0.;
|
||||
}
|
||||
return rmean;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4MultipleScattering.cc,v 1.23 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// 16/05/01 value of cparm changed , L.Urban
|
||||
// 18/05/01 V.Ivanchenko Clean up against Linux ANSI compilation
|
||||
// 07/08/01 new methods Store/Retrieve PhysicsTable (mma)
|
||||
// 23-08-01 new angle and z distribution,energy dependence reduced,
|
||||
// Store,Retrieve methods commented out temporarily, L.Urban
|
||||
// 27-08-01 in BuildPhysicsTable:aParticleType.GetParticleName()=="mu+" (mma)
|
||||
// 28-08-01 GetContinuousStepLimit and AlongStepDoIt moved from .icc file (mma)
|
||||
// 03-09-01 value of data member factlim changed, L.Urban
|
||||
// 10-09-01 small change in GetContinuousStepLimit, L.Urban
|
||||
// 11-09-01 G4MultipleScatteringx put as default G4MultipleScattering
|
||||
// store/retrieve physics table reactivated (mma)
|
||||
// 13-09-01 corr. in ComputeTransportCrossSection, L.Urban
|
||||
// 14-09-01 protection in GetContinuousStepLimit, L.Urban
|
||||
// 17-09-01 migration of Materials to pure STL (mma)
|
||||
// 27-09-01 value of data member factlim changed, L.Urban
|
||||
// 31-10-01 big fixed in PostStepDoIt,L.Urban
|
||||
// 17-04-02 NEW angle distribution + boundary algorithm modified, L.Urban
|
||||
// 22-04-02 boundary algorithm modified -> important improvement in timing (L.Urban)
|
||||
// 24-04-02 some minor changes in boundary algorithm, L.Urban
|
||||
// 06-05-02 bug fixed in GetContinuousStepLimit, L.Urban
|
||||
// 24-05-02 changes in angle distribution and boundary algorithm, L.Urban
|
||||
// 11-06-02 bug fixed in ComputeTransportCrossSection, L.Urban
|
||||
// 12-08-02 bug fixed in PostStepDoIt (lateral displacement), L.Urban
|
||||
// 15-08-02 new angle distribution, L.Urban
|
||||
// 26-09-02 angle distribution + boundary algorithm modified, L.Urban
|
||||
// 15-10-02 temporary fix for proton scattering
|
||||
// 30-10-02 modified angle distribution,mods in boundary algorithm,
|
||||
// changes in data members, L.Urban
|
||||
// 11-12-02 precision problem in ComputeTransportCrossSection
|
||||
// for small Tkin/for heavy particles cured from L.Urban
|
||||
// 20-01-03 Migrade to cut per region (V.Ivanchenko)
|
||||
// 05-02-03 changes in data members, new sampling for geom.
|
||||
// path length, step dependence reduced with new
|
||||
// method
|
||||
// 28-03-03 Move to model design (V.Ivanchenko)
|
||||
// 08-08-03 STD substitute standard (V.Ivanchenko)
|
||||
// 23-04-04 value of data member dtrl changed from 0.15 to 0.05 (L.Urban)
|
||||
// 17-08-04 name of facxsi changed to factail (L.Urban)
|
||||
// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4MultipleScattering.hh"
|
||||
#include "G4MscModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4MultipleScattering::G4MultipleScattering(const G4String& processName)
|
||||
: G4VMultipleScattering(processName),
|
||||
totBins(120),
|
||||
facrange(0.199),
|
||||
dtrl(0.05),
|
||||
NuclCorrPar (0.0615),
|
||||
FactPar(0.40),
|
||||
factail(1.0),
|
||||
cf(1.001),
|
||||
stepnolastmsc(-1000000),
|
||||
nsmallstep(5)
|
||||
{
|
||||
lowKineticEnergy = 0.1*keV;
|
||||
highKineticEnergy= 100.*TeV;
|
||||
|
||||
tlimit = 1.e10*mm;
|
||||
tlimitmin = 1.e-7*mm;
|
||||
|
||||
SetBinning(totBins);
|
||||
SetMinKinEnergy(lowKineticEnergy);
|
||||
SetMaxKinEnergy(highKineticEnergy);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4MultipleScattering::~G4MultipleScattering()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4MultipleScattering::InitialiseProcess(const G4ParticleDefinition* particle)
|
||||
{
|
||||
if (particle->GetParticleType() == "nucleus") {
|
||||
SetBoundary(false);
|
||||
SetLateralDisplasmentFlag(false);
|
||||
SetBuildLambdaTable(false);
|
||||
Setsamplez(false) ;
|
||||
} else {
|
||||
SetBoundary(true);
|
||||
SetLateralDisplasmentFlag(true);
|
||||
SetBuildLambdaTable(true);
|
||||
Setsamplez(true) ;
|
||||
}
|
||||
G4MscModel* em = new G4MscModel(dtrl,NuclCorrPar,FactPar,factail,samplez);
|
||||
em->SetLowEnergyLimit(lowKineticEnergy);
|
||||
em->SetHighEnergyLimit(highKineticEnergy);
|
||||
AddEmModel(1, em);
|
||||
boundary = BoundaryAlgorithmFlag();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4MultipleScattering::TruePathLengthLimit(const G4Track& track,
|
||||
G4double& lambda,
|
||||
G4double currentMinimalStep)
|
||||
{
|
||||
|
||||
G4double tPathLength = currentMinimalStep;
|
||||
|
||||
// special treatment near boundaries ?
|
||||
if (boundary) {
|
||||
|
||||
G4int stepno = track.GetCurrentStepNumber() ;
|
||||
// first step
|
||||
if (stepno == 1) {
|
||||
stepnolastmsc = -1000000 ;
|
||||
tlimit = 1.e10;
|
||||
} else if (stepno > 1) {
|
||||
|
||||
if (track.GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary) {
|
||||
|
||||
stepnolastmsc = stepno;
|
||||
// if : diff.treatment for small/not small Z
|
||||
G4double range = CurrentRange();
|
||||
if (range > lambda) tlimit = facrange*range;
|
||||
else tlimit = facrange*lambda;
|
||||
|
||||
if(tlimit < tlimitmin) tlimit = tlimitmin;
|
||||
if(tPathLength > tlimit) tPathLength = tlimit;
|
||||
|
||||
} else if (stepno > stepnolastmsc && stepno - stepnolastmsc < nsmallstep
|
||||
&& tPathLength > tlimit) {
|
||||
tlimit *= cf;
|
||||
tPathLength = tlimit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tPathLength;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4MultipleScattering::PrintInfoDefinition()
|
||||
{
|
||||
G4VMultipleScattering::PrintInfoDefinition();
|
||||
if(boundary) {
|
||||
G4cout << " Boundary algorithm is active with facrange= "
|
||||
<< facrange
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,950 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4MultipleScattering52.cc,v 1.2 2004/12/01 19:37:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// 16/05/01 value of cparm changed , L.Urban
|
||||
// 18/05/01 V.Ivanchenko Clean up against Linux ANSI compilation
|
||||
// 07/08/01 new methods Store/Retrieve PhysicsTable (mma)
|
||||
// 23-08-01 new angle and z distribution,energy dependence reduced,
|
||||
// Store,Retrieve methods commented out temporarily, L.Urban
|
||||
// 27-08-01 in BuildPhysicsTable:aParticleType.GetParticleName()=="mu+" (mma)
|
||||
// 28-08-01 GetContinuousStepLimit and AlongStepDoIt moved from .icc file (mma)
|
||||
// 03-09-01 value of data member factlim changed, L.Urban
|
||||
// 10-09-01 small change in GetContinuousStepLimit, L.Urban
|
||||
// 11-09-01 G4MultipleScatteringx put as default G4MultipleScattering
|
||||
// store/retrieve physics table reactivated (mma)
|
||||
// 13-09-01 corr. in ComputeTransportCrossSection, L.Urban
|
||||
// 14-09-01 protection in GetContinuousStepLimit, L.Urban
|
||||
// 17-09-01 migration of Materials to pure STL (mma)
|
||||
// 27-09-01 value of data member factlim changed, L.Urban
|
||||
// 31-10-01 big fixed in PostStepDoIt,L.Urban
|
||||
// 24-04-02 some minor changes in boundary algorithm, L.Urban
|
||||
// 06-05-02 bug fixed in GetContinuousStepLimit, L.Urban
|
||||
// 24-05-02 changes in angle distribution and boundary algorithm, L.Urban
|
||||
// 11-06-02 bug fixed in ComputeTransportCrossSection, L.Urban
|
||||
// 12-08-02 bug fixed in PostStepDoIt (lateral displacement), L.Urban
|
||||
// 15-08-02 new angle distribution, L.Urban
|
||||
// 26-09-02 angle distribution + boundary algorithm modified, L.Urban
|
||||
// 15-10-02 temporary fix for proton scattering
|
||||
// 30-10-02 modified angle distribution,mods in boundary algorithm,
|
||||
// changes in data members, L.Urban
|
||||
// 30-10-02 rename variable cm - Ecm, V.Ivanchenko
|
||||
// 11-12-02 precision problem in ComputeTransportCrossSection
|
||||
// for small Tkin/for heavy particles cured, L.Urban
|
||||
// 05-02-03 changes in data members, new sampling for geom.
|
||||
// path length, step dependence reduced with new
|
||||
// method
|
||||
// 17-03-03 cut per region, V.Ivanchenko
|
||||
// 13-04-03 add initialisation in GetContinuesStepLimit
|
||||
// + change table size (V.Ivanchenko)
|
||||
// 26-04-03 fix problems of retrieve tables (M.Asai)
|
||||
// 23-05-03 important change in angle distribution for muons/hadrons
|
||||
// the central part now is similar to the Highland parametrization +
|
||||
// minor correction in angle sampling algorithm (for all particles)
|
||||
// (L.Urban)
|
||||
// 24-05-03 bug in nuclear size corr.computation fixed thanks to Vladimir(L.Urban)
|
||||
// 30-05-03 misprint in PostStepDoIt corrected(L.Urban)
|
||||
// 08-08-03 This class is frozen at the release 5.2 (V.Ivanchenko)
|
||||
// 08-11-04 Remove Store/Retrieve tables (V.Ivantchenko)
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
#include "G4MultipleScattering52.hh"
|
||||
#include "G4StepStatus.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4MultipleScattering52::G4MultipleScattering52(const G4String& processName)
|
||||
: G4VContinuousDiscreteProcess(processName),
|
||||
theTransportMeanFreePathTable(0),
|
||||
taubig(8.0),tausmall(1.e-14),taulim(1.e-5),
|
||||
LowestKineticEnergy(0.1*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
TotBin(100),
|
||||
materialIndex(0),
|
||||
tLast (0.0),
|
||||
zLast (0.0),
|
||||
boundary(true),
|
||||
facrange(0.199),tlimit(1.e10*mm),tlimitmin(1.e-7*mm),
|
||||
cf(1.001),
|
||||
stepno(0),stepnolastmsc(-1000000),nsmallstep(5),
|
||||
laststep(0.),
|
||||
valueGPILSelectionMSC(NotCandidateForSelection),
|
||||
zmean(0.),samplez(true),
|
||||
range(1.),T0(1.),T1(1.),lambda0(1.),lambda1(-1.),
|
||||
Tlow(0.),alam(1.),blam(1.),dtrl(0.15),
|
||||
lambdam(-1.),clam(1.),zm(1.),cthm(1.),
|
||||
fLatDisplFlag(true),
|
||||
NuclCorrPar (0.0615),
|
||||
FactPar(0.40),
|
||||
facxsi(1.)
|
||||
{ }
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4MultipleScattering52::~G4MultipleScattering52()
|
||||
{
|
||||
if(theTransportMeanFreePathTable)
|
||||
{
|
||||
theTransportMeanFreePathTable->clearAndDestroy();
|
||||
delete theTransportMeanFreePathTable;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4MultipleScattering52::BuildPhysicsTable(
|
||||
const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
// set values of some data members
|
||||
if((aParticleType.GetParticleName() == "e-") ||
|
||||
(aParticleType.GetParticleName() == "e+"))
|
||||
{
|
||||
// parameters for e+/e-
|
||||
alfa1 = 1.45 ;
|
||||
alfa2 = 0.60 ;
|
||||
alfa3 = 0.30 ;
|
||||
b = 1. ;
|
||||
xsi = facxsi*2.22 ;
|
||||
c0 = 2.30 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// parameters for heavy particles
|
||||
alfa1 = 1.10 ;
|
||||
alfa2 = 0.14 ;
|
||||
alfa3 = 0.07 ;
|
||||
b = 1. ;
|
||||
xsi = facxsi*2.70 ;
|
||||
c0 = 1.40 ;
|
||||
}
|
||||
|
||||
// ..............................
|
||||
Tlow = aParticleType.GetPDGMass();
|
||||
|
||||
// tables are built for MATERIALS
|
||||
const G4double sigmafactor = twopi*classic_electr_radius*
|
||||
classic_electr_radius;
|
||||
G4double KineticEnergy,AtomicNumber,AtomicWeight,sigma,lambda;
|
||||
G4double density;
|
||||
|
||||
// destroy old tables if any
|
||||
if (theTransportMeanFreePathTable)
|
||||
{
|
||||
theTransportMeanFreePathTable->clearAndDestroy();
|
||||
delete theTransportMeanFreePathTable;
|
||||
}
|
||||
|
||||
// create table
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
theTransportMeanFreePathTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
// loop for materials
|
||||
for (size_t i=0; i<numOfCouples; i++)
|
||||
{
|
||||
|
||||
// create physics vector and fill it
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowestKineticEnergy,HighestKineticEnergy,TotBin);
|
||||
|
||||
// get elements in the material
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->
|
||||
GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
const G4ElementVector* theElementVector = material->GetElementVector();
|
||||
const G4double* NbOfAtomsPerVolume =
|
||||
material->GetVecNbOfAtomsPerVolume();
|
||||
const G4int NumberOfElements = material->GetNumberOfElements();
|
||||
density = material->GetDensity();
|
||||
|
||||
// loop for kinetic energy values
|
||||
for (G4int i=0; i<TotBin; i++)
|
||||
{
|
||||
KineticEnergy = aVector->GetLowEdgeEnergy(i);
|
||||
sigma = 0.;
|
||||
|
||||
// loop for element in the material
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++)
|
||||
{
|
||||
AtomicNumber = (*theElementVector)[iel]->GetZ();
|
||||
AtomicWeight = (*theElementVector)[iel]->GetA();
|
||||
sigma += NbOfAtomsPerVolume[iel]*
|
||||
ComputeTransportCrossSection(aParticleType,KineticEnergy,
|
||||
AtomicNumber,AtomicWeight);
|
||||
}
|
||||
sigma *= sigmafactor;
|
||||
lambda = 1./sigma;
|
||||
aVector->PutValue(i,lambda);
|
||||
}
|
||||
|
||||
theTransportMeanFreePathTable->insert(aVector);
|
||||
|
||||
}
|
||||
|
||||
if((aParticleType.GetParticleName() == "e-" ) ||
|
||||
(aParticleType.GetParticleName() == "mu+" ) ||
|
||||
(aParticleType.GetParticleName() == "proton") ) PrintInfoDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4MultipleScattering52::ComputeTransportCrossSection(
|
||||
const G4ParticleDefinition& aParticleType,
|
||||
G4double KineticEnergy,
|
||||
G4double AtomicNumber,G4double AtomicWeight)
|
||||
{
|
||||
const G4double epsfactor = 2.*electron_mass_c2*electron_mass_c2*
|
||||
Bohr_radius*Bohr_radius/(hbarc*hbarc);
|
||||
const G4double epsmin = 1.e-4 , epsmax = 1.e10;
|
||||
|
||||
const G4double Zdat[15] = { 4., 6.,13.,20.,26.,29.,32.,38.,47.,
|
||||
50.,56.,64.,74.,79.,82. };
|
||||
|
||||
const G4double Tdat[23] = {0.0001*MeV,0.0002*MeV,0.0004*MeV,0.0007*MeV,
|
||||
0.001*MeV,0.002*MeV,0.004*MeV,0.007*MeV,
|
||||
0.01*MeV,0.02*MeV,0.04*MeV,0.07*MeV,
|
||||
0.1*MeV,0.2*MeV,0.4*MeV,0.7*MeV,
|
||||
1.*MeV,2.*MeV,4.*MeV,7.*MeV,10.*MeV,20.*MeV,
|
||||
10000.0*MeV};
|
||||
|
||||
// corr. factors for e-/e+ lambda
|
||||
G4double celectron[15][23] =
|
||||
{{1.125,1.072,1.051,1.047,1.047,1.050,1.052,1.054,
|
||||
1.054,1.057,1.062,1.069,1.075,1.090,1.105,1.111,
|
||||
1.112,1.108,1.100,1.093,1.089,1.087,0.7235 },
|
||||
{1.408,1.246,1.143,1.096,1.077,1.059,1.053,1.051,
|
||||
1.052,1.053,1.058,1.065,1.072,1.087,1.101,1.108,
|
||||
1.109,1.105,1.097,1.090,1.086,1.082,0.7925 },
|
||||
{2.833,2.268,1.861,1.612,1.486,1.309,1.204,1.156,
|
||||
1.136,1.114,1.106,1.106,1.109,1.119,1.129,1.132,
|
||||
1.131,1.124,1.113,1.104,1.099,1.098,0.9147 },
|
||||
{3.879,3.016,2.380,2.007,1.818,1.535,1.340,1.236,
|
||||
1.190,1.133,1.107,1.099,1.098,1.103,1.110,1.113,
|
||||
1.112,1.105,1.096,1.089,1.085,1.098,0.9700 },
|
||||
{6.937,4.330,2.886,2.256,1.987,1.628,1.395,1.265,
|
||||
1.203,1.122,1.080,1.065,1.061,1.063,1.070,1.073,
|
||||
1.073,1.070,1.064,1.059,1.056,1.056,1.0022 },
|
||||
{9.616,5.708,3.424,2.551,2.204,1.762,1.485,1.330,
|
||||
1.256,1.155,1.099,1.077,1.070,1.068,1.072,1.074,
|
||||
1.074,1.070,1.063,1.059,1.056,1.052,1.0158 },
|
||||
{11.72,6.364,3.811,2.806,2.401,1.884,1.564,1.386,
|
||||
1.300,1.180,1.112,1.082,1.073,1.066,1.068,1.069,
|
||||
1.068,1.064,1.059,1.054,1.051,1.050,1.0284 },
|
||||
{18.08,8.601,4.569,3.183,2.662,2.025,1.646,1.439,
|
||||
1.339,1.195,1.108,1.068,1.053,1.040,1.039,1.039,
|
||||
1.039,1.037,1.034,1.031,1.030,1.036,1.0515 },
|
||||
{18.22,10.48,5.333,3.713,3.115,2.367,1.898,1.631,
|
||||
1.498,1.301,1.171,1.105,1.077,1.048,1.036,1.033,
|
||||
1.031,1.028,1.024,1.022,1.021,1.024,1.0834 },
|
||||
{14.14,10.65,5.710,3.929,3.266,2.453,1.951,1.669,
|
||||
1.528,1.319,1.178,1.106,1.075,1.040,1.027,1.022,
|
||||
1.020,1.017,1.015,1.013,1.013,1.020,1.0937 },
|
||||
{14.11,11.73,6.312,4.240,3.478,2.566,2.022,1.720,
|
||||
1.569,1.342,1.186,1.102,1.065,1.022,1.003,0.997,
|
||||
0.995,0.993,0.993,0.993,0.993,1.011,1.1140 },
|
||||
{22.76,20.01,8.835,5.287,4.144,2.901,2.219,1.855,
|
||||
1.677,1.410,1.224,1.121,1.073,1.014,0.986,0.976,
|
||||
0.974,0.972,0.973,0.974,0.975,0.987,1.1410 },
|
||||
{50.77,40.85,14.13,7.184,5.284,3.435,2.520,2.059,
|
||||
1.837,1.512,1.283,1.153,1.091,1.010,0.969,0.954,
|
||||
0.950,0.947,0.949,0.952,0.954,0.963,1.1750 },
|
||||
{65.87,59.06,15.87,7.570,5.567,3.650,2.682,2.182,
|
||||
1.939,1.579,1.325,1.178,1.108,1.014,0.965,0.947,
|
||||
0.941,0.938,0.940,0.944,0.946,0.954,1.1922 },
|
||||
// {45.60,47.34,15.92,7.810,5.755,3.767,2.760,2.239, // paper.....
|
||||
{55.60,47.34,15.92,7.810,5.755,3.767,2.760,2.239,
|
||||
1.985,1.609,1.343,1.188,1.113,1.013,0.960,0.939,
|
||||
0.933,0.930,0.933,0.936,0.939,0.949,1.2026 }};
|
||||
G4double cpositron[15][23] = {
|
||||
{2.589,2.044,1.658,1.446,1.347,1.217,1.144,1.110,
|
||||
1.097,1.083,1.080,1.086,1.092,1.108,1.123,1.131,
|
||||
1.131,1.126,1.117,1.108,1.103,1.100,0.7235 },
|
||||
{3.904,2.794,2.079,1.710,1.543,1.325,1.202,1.145,
|
||||
1.122,1.096,1.089,1.092,1.098,1.114,1.130,1.137,
|
||||
1.138,1.132,1.122,1.113,1.108,1.102,0.7925 },
|
||||
{7.970,6.080,4.442,3.398,2.872,2.127,1.672,1.451,
|
||||
1.357,1.246,1.194,1.179,1.178,1.188,1.201,1.205,
|
||||
1.203,1.190,1.173,1.159,1.151,1.145,0.9147 },
|
||||
{9.714,7.607,5.747,4.493,3.815,2.777,2.079,1.715,
|
||||
1.553,1.353,1.253,1.219,1.211,1.214,1.225,1.228,
|
||||
1.225,1.210,1.191,1.175,1.166,1.174,0.9700 },
|
||||
{17.97,12.95,8.628,6.065,4.849,3.222,2.275,1.820,
|
||||
1.624,1.382,1.259,1.214,1.202,1.202,1.214,1.219,
|
||||
1.217,1.203,1.184,1.169,1.160,1.151,1.0022 },
|
||||
{24.83,17.06,10.84,7.355,5.767,3.707,2.546,1.996,
|
||||
1.759,1.465,1.311,1.252,1.234,1.228,1.238,1.241,
|
||||
1.237,1.222,1.201,1.184,1.174,1.159,1.0158 },
|
||||
{23.26,17.15,11.52,8.049,6.375,4.114,2.792,2.155,
|
||||
1.880,1.535,1.353,1.281,1.258,1.247,1.254,1.256,
|
||||
1.252,1.234,1.212,1.194,1.183,1.170,1.0284 },
|
||||
{22.33,18.01,12.86,9.212,7.336,4.702,3.117,2.348,
|
||||
2.015,1.602,1.385,1.297,1.268,1.251,1.256,1.258,
|
||||
1.254,1.237,1.214,1.195,1.185,1.179,1.0515 },
|
||||
{33.91,24.13,15.71,10.80,8.507,5.467,3.692,2.808,
|
||||
2.407,1.873,1.564,1.425,1.374,1.330,1.324,1.320,
|
||||
1.312,1.288,1.258,1.235,1.221,1.205,1.0834 },
|
||||
{32.14,24.11,16.30,11.40,9.015,5.782,3.868,2.917,
|
||||
2.490,1.925,1.596,1.447,1.391,1.342,1.332,1.327,
|
||||
1.320,1.294,1.264,1.240,1.226,1.214,1.0937 },
|
||||
{29.51,24.07,17.19,12.28,9.766,6.238,4.112,3.066,
|
||||
2.602,1.995,1.641,1.477,1.414,1.356,1.342,1.336,
|
||||
1.328,1.302,1.270,1.245,1.231,1.233,1.1140 },
|
||||
{38.19,30.85,21.76,15.35,12.07,7.521,4.812,3.498,
|
||||
2.926,2.188,1.763,1.563,1.484,1.405,1.382,1.371,
|
||||
1.361,1.330,1.294,1.267,1.251,1.239,1.1410 },
|
||||
{49.71,39.80,27.96,19.63,15.36,9.407,5.863,4.155,
|
||||
3.417,2.478,1.944,1.692,1.589,1.480,1.441,1.423,
|
||||
1.409,1.372,1.330,1.298,1.280,1.258,1.1750 },
|
||||
{59.25,45.08,30.36,20.83,16.15,9.834,6.166,4.407,
|
||||
3.641,2.648,2.064,1.779,1.661,1.531,1.482,1.459,
|
||||
1.442,1.400,1.354,1.319,1.299,1.272,1.1922 },
|
||||
{56.38,44.29,30.50,21.18,16.51,10.11,6.354,4.542,
|
||||
3.752,2.724,2.116,1.817,1.692,1.554,1.499,1.474,
|
||||
1.456,1.412,1.364,1.328,1.307,1.282,1.2026 }};
|
||||
|
||||
G4double sigma;
|
||||
G4double Z23 = 2.*log(AtomicNumber)/3.; Z23 = exp(Z23);
|
||||
|
||||
G4double ParticleMass = aParticleType.GetPDGMass();
|
||||
G4double ParticleKineticEnergy = KineticEnergy ;
|
||||
|
||||
// correction if particle .ne. e-/e+
|
||||
// compute equivalent kinetic energy
|
||||
// lambda depends on p*beta ....
|
||||
G4double Mass = ParticleMass ;
|
||||
if((aParticleType.GetParticleName() != "e-") &&
|
||||
(aParticleType.GetParticleName() != "e+") )
|
||||
{
|
||||
G4double TAU = KineticEnergy/Mass ;
|
||||
G4double c = Mass*TAU*(TAU+2.)/(electron_mass_c2*(TAU+1.)) ;
|
||||
G4double w = c-2. ;
|
||||
G4double tau = 0.5*(w+sqrt(w*w+4.*c)) ;
|
||||
KineticEnergy = electron_mass_c2*tau ;
|
||||
Mass = electron_mass_c2 ;
|
||||
}
|
||||
|
||||
G4double Charge = aParticleType.GetPDGCharge();
|
||||
G4double ChargeSquare = Charge*Charge/(eplus*eplus);
|
||||
|
||||
G4double TotalEnergy = KineticEnergy + Mass ;
|
||||
G4double beta2 = KineticEnergy*(TotalEnergy+Mass)
|
||||
/(TotalEnergy*TotalEnergy);
|
||||
G4double bg2 = KineticEnergy*(TotalEnergy+Mass)
|
||||
/(Mass*Mass);
|
||||
|
||||
G4double eps = epsfactor*bg2/Z23;
|
||||
|
||||
if (eps<epsmin) sigma = 2.*eps*eps;
|
||||
else if(eps<epsmax) sigma = log(1.+2.*eps)-2.*eps/(1.+2.*eps);
|
||||
else sigma = log(2.*eps)-1.+1./eps;
|
||||
|
||||
sigma *= ChargeSquare*AtomicNumber*AtomicNumber/(beta2*bg2);
|
||||
|
||||
// nuclear size effect correction for high energy
|
||||
// ( a simple approximation at present)
|
||||
G4double corrnuclsize,a,x0,w1,w2,w;
|
||||
|
||||
x0 = 1. - NuclCorrPar*ParticleMass/(ParticleKineticEnergy*
|
||||
exp(log(AtomicWeight/(g/mole))/3.));
|
||||
if ( (x0 < -1.) || (ParticleKineticEnergy <= 10.*MeV))
|
||||
{ x0 = -1.; corrnuclsize = 1.;}
|
||||
else
|
||||
{ a = 1.+1./eps;
|
||||
if (eps > epsmax) w1=log(2.*eps)+1./eps-3./(8.*eps*eps);
|
||||
else w1=log((a+1.)/(a-1.))-2./(a+1.);
|
||||
w = 1./((1.-x0)*eps);
|
||||
if (w < epsmin) w2=-log(w)-1.+2.*w-1.5*w*w;
|
||||
else w2 = log((a-x0)/(a-1.))-(1.-x0)/(a-x0);
|
||||
corrnuclsize = w1/w2;
|
||||
corrnuclsize = exp(-FactPar*ParticleMass/ParticleKineticEnergy)*
|
||||
(corrnuclsize-1.)+1.;
|
||||
}
|
||||
|
||||
// interpolate in AtomicNumber and beta2
|
||||
// get bin number in Z
|
||||
G4int iZ = 14;
|
||||
while ((iZ>=0)&&(Zdat[iZ]>=AtomicNumber)) iZ -= 1;
|
||||
if (iZ==14) iZ = 13;
|
||||
if (iZ==-1) iZ = 0 ;
|
||||
|
||||
G4double Z1 = Zdat[iZ];
|
||||
G4double Z2 = Zdat[iZ+1];
|
||||
G4double ratZ = (AtomicNumber-Z1)/(Z2-Z1);
|
||||
|
||||
// get bin number in T (beta2)
|
||||
G4int iT = 22;
|
||||
while ((iT>=0)&&(Tdat[iT]>=KineticEnergy)) iT -= 1;
|
||||
if(iT==22) iT = 21;
|
||||
if(iT==-1) iT = 0 ;
|
||||
|
||||
// calculate betasquare values
|
||||
G4double T = Tdat[iT], E = T + electron_mass_c2;
|
||||
G4double b2small = T*(E+electron_mass_c2)/(E*E);
|
||||
T = Tdat[iT+1]; E = T + electron_mass_c2;
|
||||
G4double b2big = T*(E+electron_mass_c2)/(E*E);
|
||||
G4double ratb2 = (beta2-b2small)/(b2big-b2small);
|
||||
|
||||
G4double c1,c2,cc1,cc2,corr;
|
||||
|
||||
if (Charge < 0.)
|
||||
{
|
||||
c1 = celectron[iZ][iT];
|
||||
c2 = celectron[iZ+1][iT];
|
||||
cc1 = c1+ratZ*(c2-c1);
|
||||
|
||||
c1 = celectron[iZ][iT+1];
|
||||
c2 = celectron[iZ+1][iT+1];
|
||||
cc2 = c1+ratZ*(c2-c1);
|
||||
|
||||
corr = cc1+ratb2*(cc2-cc1);
|
||||
sigma /= corr;
|
||||
}
|
||||
|
||||
if (Charge > 0.)
|
||||
{
|
||||
c1 = cpositron[iZ][iT];
|
||||
c2 = cpositron[iZ+1][iT];
|
||||
cc1 = c1+ratZ*(c2-c1);
|
||||
|
||||
c1 = cpositron[iZ][iT+1];
|
||||
c2 = cpositron[iZ+1][iT+1];
|
||||
cc2 = c1+ratZ*(c2-c1);
|
||||
|
||||
corr = cc1+ratb2*(cc2-cc1);
|
||||
sigma /= corr;
|
||||
}
|
||||
|
||||
// nucl. size correction for particles other than e+/e- only at present !!!!
|
||||
if((aParticleType.GetParticleName() != "e-") &&
|
||||
(aParticleType.GetParticleName() != "e+") )
|
||||
sigma /= corrnuclsize;
|
||||
|
||||
return sigma;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4MultipleScattering52::GetContinuousStepLimit(
|
||||
const G4Track& track,
|
||||
G4double,
|
||||
G4double currentMinimumStep,
|
||||
G4double&)
|
||||
{
|
||||
G4double zPathLength,tPathLength;
|
||||
const G4DynamicParticle* aParticle;
|
||||
G4double tau,zt,cz,cz1,grej,grej0;
|
||||
const G4double expmax = 100., ztmax = (2.*expmax+1.)/(2.*expmax+3.) ;
|
||||
const G4double tmax = 1.e20*mm ;
|
||||
|
||||
G4bool isOut;
|
||||
|
||||
// this process is not a candidate for selection by default
|
||||
valueGPILSelectionMSC = NotCandidateForSelection;
|
||||
|
||||
tPathLength = currentMinimumStep;
|
||||
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
materialIndex = couple->GetIndex();
|
||||
|
||||
aParticle = track.GetDynamicParticle();
|
||||
T0 = aParticle->GetKineticEnergy();
|
||||
|
||||
lambda0 = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(T0,isOut);
|
||||
|
||||
|
||||
range = G4EnergyLossTables::GetRange(aParticle->GetDefinition(),
|
||||
T0,couple);
|
||||
//VI Initialisation at the beginning of the step
|
||||
cthm = 1.;
|
||||
lambda1 = -1.;
|
||||
lambdam = -1.;
|
||||
alam = range;
|
||||
blam = 1.+alam/lambda0 ;
|
||||
zm = 1.;
|
||||
|
||||
// special treatment near boundaries ?
|
||||
if (boundary && range >= currentMinimumStep)
|
||||
{
|
||||
// step limitation at boundary ?
|
||||
stepno = track.GetCurrentStepNumber() ;
|
||||
if(stepno == 1)
|
||||
{
|
||||
stepnolastmsc = -1000000 ;
|
||||
tlimit = 1.e10 ;
|
||||
}
|
||||
|
||||
if(stepno > 1)
|
||||
{
|
||||
if(track.GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary)
|
||||
{
|
||||
stepnolastmsc = stepno ;
|
||||
// if : diff.treatment for small/not small Z
|
||||
if(range > lambda0)
|
||||
tlimit = facrange*range ;
|
||||
else
|
||||
tlimit = facrange*lambda0 ;
|
||||
if(tlimit < tlimitmin) tlimit = tlimitmin ;
|
||||
laststep = tlimit ;
|
||||
if(tPathLength > tlimit)
|
||||
{
|
||||
tPathLength = tlimit ;
|
||||
valueGPILSelectionMSC = CandidateForSelection;
|
||||
}
|
||||
}
|
||||
else if(stepno > stepnolastmsc)
|
||||
{
|
||||
if((stepno - stepnolastmsc) < nsmallstep)
|
||||
{
|
||||
if(tPathLength > tlimit)
|
||||
{
|
||||
laststep *= cf ;
|
||||
tPathLength = laststep ;
|
||||
valueGPILSelectionMSC = CandidateForSelection;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do the true -> geom transformation
|
||||
zmean = tPathLength;
|
||||
|
||||
tau = tPathLength/lambda0 ;
|
||||
|
||||
if (tau < tausmall || range < currentMinimumStep) zPathLength = tPathLength;
|
||||
else
|
||||
{
|
||||
if(tPathLength/range < dtrl) zmean = lambda0*(1.-exp(-tau));
|
||||
else
|
||||
{
|
||||
T1 = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
aParticle->GetDefinition(),range-tPathLength,couple);
|
||||
lambda1 = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(T1,isOut);
|
||||
if(T0 < Tlow)
|
||||
alam = range ;
|
||||
else
|
||||
alam = lambda0*tPathLength/(lambda0-lambda1) ;
|
||||
blam = 1.+alam/lambda0 ;
|
||||
if(tPathLength/range < 2.*dtrl)
|
||||
{
|
||||
zmean = alam*(1.-exp(blam*log(1.-tPathLength/alam)))/blam ;
|
||||
lambdam = -1. ;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double w = 1.-0.5*tPathLength/alam ;
|
||||
lambdam = lambda0*w ;
|
||||
clam = 1.+alam/lambdam ;
|
||||
cthm = exp(alam*log(w)/lambda0) ;
|
||||
zm = alam*(1.-exp(blam*log(w)))/blam ;
|
||||
zmean = zm + alam*(1.-exp(clam*log(w)))*cthm/clam ;
|
||||
}
|
||||
}
|
||||
|
||||
// sample z
|
||||
zt = zmean/tPathLength ;
|
||||
if (samplez && (zt < ztmax) && (zt > 0.5))
|
||||
{
|
||||
cz = 0.5*(3.*zt-1.)/(1.-zt) ;
|
||||
if(tPathLength < exp(log(tmax)/(2.*cz)))
|
||||
{
|
||||
cz1 = 1.+cz ;
|
||||
grej0 = exp(cz1*log(cz*tPathLength/cz1))/cz ;
|
||||
do
|
||||
{
|
||||
zPathLength = tPathLength*exp(log(G4UniformRand())/cz1) ;
|
||||
grej = exp(cz*log(zPathLength))*(tPathLength-zPathLength)/grej0 ;
|
||||
} while (grej < G4UniformRand()) ;
|
||||
}
|
||||
else zPathLength = zmean;
|
||||
}
|
||||
else zPathLength = zmean;
|
||||
}
|
||||
// protection against z > lambda
|
||||
if(zPathLength > lambda0)
|
||||
zPathLength = lambda0 ;
|
||||
|
||||
tLast = tPathLength;
|
||||
zLast = zPathLength;
|
||||
|
||||
return zPathLength;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VParticleChange* G4MultipleScattering52::AlongStepDoIt(
|
||||
const G4Track& track,const G4Step& step)
|
||||
{
|
||||
// only a geom path->true path transformation is performed
|
||||
|
||||
fParticleChange.Initialize(track);
|
||||
|
||||
G4double geomPathLength = step.GetStepLength();
|
||||
|
||||
G4double truePathLength = 0. ;
|
||||
|
||||
//VI change order of if operators
|
||||
if(geomPathLength == zLast) truePathLength = tLast;
|
||||
else if(geomPathLength/lambda0 < tausmall) truePathLength = geomPathLength;
|
||||
else
|
||||
{
|
||||
if(lambda1 < 0.) truePathLength = -lambda0*log(1.-geomPathLength/lambda0) ;
|
||||
else if(lambdam < 0.)
|
||||
{
|
||||
if(blam*geomPathLength/alam < 1.)
|
||||
truePathLength = alam*(1.-exp(log(1.-blam*geomPathLength/alam)/
|
||||
blam)) ;
|
||||
else
|
||||
truePathLength = tLast;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(geomPathLength <= zm)
|
||||
{
|
||||
if(blam*geomPathLength/alam < 1.)
|
||||
truePathLength = alam*(1.-exp(log(1.-blam*geomPathLength/alam)/
|
||||
blam)) ;
|
||||
else
|
||||
truePathLength = 0.5*tLast;
|
||||
|
||||
lambdam = -1. ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(clam*(geomPathLength-zm)/(alam*cthm) < 1.)
|
||||
truePathLength = 0.5*tLast + alam*(1.-
|
||||
exp(log(1.-clam*(geomPathLength-zm)/(alam*cthm)))/clam) ;
|
||||
else
|
||||
truePathLength = tLast ;
|
||||
}
|
||||
}
|
||||
// protection ....
|
||||
if(truePathLength > tLast)
|
||||
truePathLength = tLast ;
|
||||
}
|
||||
|
||||
//VI truePath length cannot be smaller than geomPathLength
|
||||
if (truePathLength < geomPathLength) truePathLength = geomPathLength;
|
||||
fParticleChange.ProposeTrueStepLength(truePathLength);
|
||||
|
||||
return &fParticleChange;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VParticleChange* G4MultipleScattering52::PostStepDoIt(
|
||||
const G4Track& trackData,
|
||||
const G4Step& stepData)
|
||||
{
|
||||
// angle distribution parameters
|
||||
const G4double kappa = 2.5, kappapl1 = kappa+1., kappami1 = kappa-1. ;
|
||||
|
||||
fParticleChange.Initialize(trackData);
|
||||
G4double truestep = stepData.GetStepLength();
|
||||
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
|
||||
G4double KineticEnergy = aParticle->GetKineticEnergy();
|
||||
G4double Mass = aParticle->GetDefinition()->GetPDGMass() ;
|
||||
|
||||
// do nothing for stopped particles !
|
||||
if(KineticEnergy > 0.)
|
||||
{
|
||||
// change direction first ( scattering )
|
||||
G4double cth = 1.0 ;
|
||||
G4double tau = truestep/lambda0 ;
|
||||
|
||||
if (tau < tausmall) cth = 1.;
|
||||
else if(tau > taubig) cth = -1.+2.*G4UniformRand();
|
||||
else
|
||||
{
|
||||
if(lambda1 > 0.)
|
||||
{
|
||||
if(lambdam < 0.)
|
||||
tau = -alam*log(1.-truestep/alam)/lambda0 ;
|
||||
else
|
||||
tau = -log(cthm)-alam*log(1.-(truestep-0.5*tLast)/alam)/lambdam ;
|
||||
}
|
||||
|
||||
if(tau > taubig) cth = -1.+2.*G4UniformRand();
|
||||
else
|
||||
{
|
||||
const G4double amax=25. ;
|
||||
const G4double tau0 = 0.02 ;
|
||||
const G4double c_highland = 13.6*MeV, corr_highland=0.038 ;
|
||||
|
||||
const G4double x1fac1 = exp(-xsi) ;
|
||||
const G4double x1fac2 = (1.-(1.+xsi)*x1fac1)/(1.-x1fac1) ;
|
||||
const G4double x1fac3 = 1.3 ; // x1fac3 >= 1. !!!!!!!!!
|
||||
|
||||
G4double a,x0,c,xmean1,xmean2,
|
||||
xmeanth,prob,qprob ;
|
||||
G4double ea,eaa,b1,bx,eb1,ebx,cnorm1,cnorm2,f1x0,f2x0,w ;
|
||||
|
||||
// for heavy particles take the width of the cetral part
|
||||
// from the Highland formula
|
||||
// (Particle Physics Booklet, July 2002, eq. 26.10)
|
||||
if(Mass > electron_mass_c2) // + other conditions (beta, x/X0,...?)
|
||||
{
|
||||
G4double Q = fabs(aParticle->GetDefinition()->GetPDGCharge()) ;
|
||||
G4double X0 = trackData.GetMaterialCutsCouple()->
|
||||
GetMaterial()->GetRadlen() ;
|
||||
G4double xx0 = truestep/X0 ;
|
||||
G4double betacp = KineticEnergy*(KineticEnergy+2.*Mass)/
|
||||
(KineticEnergy+Mass) ;
|
||||
G4double theta0=c_highland*Q*sqrt(xx0)*
|
||||
(1.+corr_highland*log(xx0))/betacp ;
|
||||
if(theta0 > tausmall)
|
||||
a = 0.5/(1.-cos(theta0)) ;
|
||||
else
|
||||
a = 1./(theta0*theta0) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = log(tau/tau0) ;
|
||||
if(tau < tau0)
|
||||
a = (alfa1-alfa2*w)/tau ;
|
||||
else
|
||||
a = (alfa1+alfa3*w)/tau ;
|
||||
}
|
||||
|
||||
xmeanth = exp(-tau) ;
|
||||
|
||||
x0 = 1.-xsi/a ;
|
||||
if(x0 < -1.) x0 = -1. ;
|
||||
|
||||
if(x0 == -1.)
|
||||
{
|
||||
// 1 model fuction only
|
||||
// in order to have xmean1 > xmeanth -> qprob < 1
|
||||
if((1.-1./a) < xmeanth)
|
||||
a = 1./(1.-xmeanth) ;
|
||||
|
||||
if(a*(1.-x0) < amax)
|
||||
ea = exp(-a*(1.-x0)) ;
|
||||
else
|
||||
ea = 0. ;
|
||||
eaa = 1.-ea ;
|
||||
xmean1 = 1.-1./a+(1.-x0)*ea/eaa ;
|
||||
|
||||
c = 2. ;
|
||||
b1 = b+1. ;
|
||||
bx = b1 ;
|
||||
eb1 = b1 ;
|
||||
ebx = b1 ;
|
||||
xmean2 = 0. ;
|
||||
|
||||
prob = 1. ;
|
||||
qprob = xmeanth/xmean1 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2 model fuctions
|
||||
// in order to have xmean1 > xmeanth
|
||||
if((1.-x1fac2/a) < xmeanth)
|
||||
{
|
||||
a = x1fac3*x1fac2/(1.-xmeanth) ;
|
||||
if(a*(1.-x0) < amax)
|
||||
ea = exp(-a*(1.-x0)) ;
|
||||
else
|
||||
ea = 0. ;
|
||||
eaa = 1.-ea ;
|
||||
xmean1 = 1.-1./a+(1.-x0)*ea/eaa ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ea = x1fac1 ;
|
||||
eaa = 1.-x1fac1 ;
|
||||
xmean1 = 1.-x1fac2/a ;
|
||||
}
|
||||
|
||||
// from continuity of the 1st derivatives
|
||||
c = a*(b-x0) ;
|
||||
if(a*tau < c0)
|
||||
c = c0*(b-x0)/tau ;
|
||||
|
||||
if(c == 1.) c=1.000001 ;
|
||||
if(c == 2.) c=2.000001 ;
|
||||
if(c == 3.) c=3.000001 ;
|
||||
|
||||
b1 = b+1. ;
|
||||
bx=b-x0 ;
|
||||
eb1=exp((c-1.)*log(b1)) ;
|
||||
ebx=exp((c-1.)*log(bx)) ;
|
||||
xmean2 = (x0*eb1+ebx+(eb1*bx-b1*ebx)/(2.-c))/(eb1-ebx) ;
|
||||
|
||||
cnorm1 = a/eaa ;
|
||||
f1x0 = cnorm1*exp(-a*(1.-x0)) ;
|
||||
cnorm2 = (c-1.)*eb1*ebx/(eb1-ebx) ;
|
||||
f2x0 = cnorm2/exp(c*log(b-x0)) ;
|
||||
|
||||
// from continuity at x=x0
|
||||
prob = f2x0/(f1x0+f2x0) ;
|
||||
// from xmean = xmeanth
|
||||
qprob = (f1x0+f2x0)*xmeanth/(f2x0*xmean1+f1x0*xmean2) ;
|
||||
}
|
||||
|
||||
// protection against prob or qprob > 1 and
|
||||
// prob or qprob < 0
|
||||
// ***************************************************************
|
||||
if((qprob > 1.) || (qprob < 0.) || (prob > 1.) || (prob < 0.))
|
||||
{
|
||||
// this print possibility has been left intentionally
|
||||
// for debugging purposes ..........................
|
||||
G4bool pr = false ;
|
||||
// pr = true ;
|
||||
if(pr)
|
||||
{
|
||||
const G4double prlim = 0.10 ;
|
||||
if((fabs((xmeanth-xmean2)/(xmean1-xmean2)-prob)/prob > prlim) ||
|
||||
((xmeanth-xmean2)/(xmean1-xmean2) > 1.) ||
|
||||
((xmeanth-xmean2)/(xmean1-xmean2) < 0.) )
|
||||
{
|
||||
G4cout.precision(5) ;
|
||||
G4cout << "\nparticle=" << aParticle->GetDefinition()->
|
||||
GetParticleName() << " in material "
|
||||
<< trackData.GetMaterialCutsCouple()->
|
||||
GetMaterial()->GetName() << " with kinetic energy "
|
||||
<< KineticEnergy << " MeV," << G4endl ;
|
||||
G4cout << " step length="
|
||||
<< truestep << " mm" << G4endl ;
|
||||
G4cout << "p=" << prob << " q=" << qprob << " -----> "
|
||||
<< "p=" << (xmeanth-xmean2)/(xmean1-xmean2)
|
||||
<< " q=" << 1. << G4endl ;
|
||||
}
|
||||
}
|
||||
qprob = 1. ;
|
||||
prob = (xmeanth-xmean2)/(xmean1-xmean2) ;
|
||||
}
|
||||
// **************************************************************
|
||||
|
||||
// sampling of costheta
|
||||
if(G4UniformRand() < qprob)
|
||||
{
|
||||
if(G4UniformRand() < prob)
|
||||
cth = 1.+log(ea+G4UniformRand()*eaa)/a ;
|
||||
else
|
||||
cth = b-b1*bx/exp(log(ebx-G4UniformRand()*(ebx-eb1))/(c-1.)) ;
|
||||
}
|
||||
else
|
||||
cth = -1.+2.*G4UniformRand() ;
|
||||
}
|
||||
}
|
||||
|
||||
G4double sth = sqrt(1.-cth*cth);
|
||||
G4double phi = twopi*G4UniformRand();
|
||||
G4double dirx = sth*cos(phi), diry = sth*sin(phi), dirz = cth;
|
||||
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection();
|
||||
|
||||
G4ThreeVector newDirection(dirx,diry,dirz);
|
||||
newDirection.rotateUz(ParticleDirection);
|
||||
fParticleChange.ProposeMomentumDirection(newDirection.x(),
|
||||
newDirection.y(),
|
||||
newDirection.z());
|
||||
|
||||
if (fLatDisplFlag)
|
||||
{
|
||||
// compute mean lateral displacement, only for safety > tolerance !
|
||||
G4double safetyminustolerance = stepData.GetPostStepPoint()->GetSafety();
|
||||
G4double rmean, etau;
|
||||
|
||||
if (safetyminustolerance > 0.)
|
||||
{
|
||||
if (tau < tausmall) rmean = 0.;
|
||||
else if(tau < taulim) rmean = kappa*tau*tau*tau*(1.-kappapl1*tau/4.)/6.;
|
||||
else
|
||||
{
|
||||
if(tau<taubig) etau = exp(-tau);
|
||||
else etau = 0.;
|
||||
rmean = -kappa*tau;
|
||||
rmean = -exp(rmean)/(kappa*kappami1);
|
||||
rmean += tau-kappapl1/kappa+kappa*etau/kappami1;
|
||||
}
|
||||
|
||||
if (rmean>0.) rmean = 2.*lambda0*sqrt(rmean/3.);
|
||||
else rmean = 0.;
|
||||
|
||||
// for rmean > 0) only
|
||||
if (rmean > 0.)
|
||||
{
|
||||
if (rmean>safetyminustolerance) rmean = safetyminustolerance;
|
||||
|
||||
// sample direction of lateral displacement
|
||||
phi = twopi*G4UniformRand();
|
||||
dirx = cos(phi); diry = sin(phi); dirz = 0.;
|
||||
|
||||
G4ThreeVector latDirection(dirx,diry,dirz);
|
||||
latDirection.rotateUz(ParticleDirection);
|
||||
|
||||
// compute new endpoint of the Step
|
||||
G4ThreeVector newPosition = stepData.GetPostStepPoint()->GetPosition()
|
||||
+ rmean*latDirection;
|
||||
|
||||
G4Navigator* navigator =
|
||||
G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
navigator->LocateGlobalPointWithinVolume(newPosition);
|
||||
|
||||
fParticleChange.ProposePosition(newPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4MultipleScattering52::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = " Tables of transport mean free paths.";
|
||||
comments += "\n New model of MSC , computes the lateral \n";
|
||||
comments += " displacement of the particle , too.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from "
|
||||
<< G4BestUnit(LowestKineticEnergy ,"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -28,6 +28,9 @@
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 17.08.04 V.Grichine, bug fixed for Tkin<=0 in SampleSecondary
|
||||
// 16.08.04 V.Grichine, bug fixed in massRatio for DEDX, CrossSection, SampleSecondary
|
||||
//
|
||||
|
||||
#include "G4Region.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
@@ -48,9 +51,10 @@
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4PAIModel::G4PAIModel(const G4ParticleDefinition* p, const G4String& nam)
|
||||
: G4VEmModel(nam),G4VEmFluctuationModel(nam),
|
||||
fLowestKineticEnergy(10.0*keV),
|
||||
@@ -68,7 +72,7 @@ G4PAIModel::G4PAIModel(const G4ParticleDefinition* p, const G4String& nam)
|
||||
fProtonEnergyVector = new G4PhysicsLogVector(fLowestKineticEnergy,
|
||||
fHighestKineticEnergy,
|
||||
fTotBin);
|
||||
fPAItransferBank = 0;
|
||||
fPAItransferTable = 0;
|
||||
fPAIdEdxTable = 0;
|
||||
fSandiaPhotoAbsCof = 0;
|
||||
fdEdxVector = 0;
|
||||
@@ -84,10 +88,11 @@ G4PAIModel::~G4PAIModel()
|
||||
if(fdEdxVector) delete fdEdxVector ;
|
||||
if ( fLambdaVector) delete fLambdaVector;
|
||||
if ( fdNdxCutVector) delete fdNdxCutVector;
|
||||
if( fPAItransferBank )
|
||||
|
||||
if( fPAItransferTable )
|
||||
{
|
||||
fPAItransferBank->clearAndDestroy();
|
||||
delete fPAItransferBank ;
|
||||
fPAItransferTable->clearAndDestroy();
|
||||
delete fPAItransferTable ;
|
||||
}
|
||||
if(fSandiaPhotoAbsCof)
|
||||
{
|
||||
@@ -132,9 +137,9 @@ G4double G4PAIModel::LowEnergyLimit( const G4ParticleDefinition* p )
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4PAIModel::MinEnergyCut( const G4ParticleDefinition*,
|
||||
const G4MaterialCutsCouple* couple )
|
||||
const G4MaterialCutsCouple*)
|
||||
{
|
||||
return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
|
||||
return 0.*eV; // any positive cut
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -161,7 +166,7 @@ void G4PAIModel::Initialise(const G4ParticleDefinition* p,
|
||||
|
||||
// (*fPAIRegionVector[iRegion])
|
||||
|
||||
std::vector<G4Material*>::const_iterator matIter = curReg->GetMaterialIterator();
|
||||
vector<G4Material*>::const_iterator matIter = curReg->GetMaterialIterator();
|
||||
size_t jMat;
|
||||
size_t numOfMat = curReg->GetNumberOfMaterials();
|
||||
|
||||
@@ -184,7 +189,8 @@ void G4PAIModel::Initialise(const G4ParticleDefinition* p,
|
||||
|
||||
ComputeSandiaPhotoAbsCof();
|
||||
BuildPAIonisationTable();
|
||||
fPAIxscBank.push_back(fPAItransferBank);
|
||||
|
||||
fPAIxscBank.push_back(fPAItransferTable);
|
||||
fPAIdEdxBank.push_back(fPAIdEdxTable);
|
||||
fdEdxTable.push_back(fdEdxVector);
|
||||
|
||||
@@ -253,13 +259,13 @@ G4PAIModel::BuildPAIonisationTable()
|
||||
G4double LowEdgeEnergy , ionloss ;
|
||||
G4double massRatio, tau, Tmax, Tmin, Tkin, deltaLow, gamma, bg2 ;
|
||||
/*
|
||||
if( fPAItransferBank )
|
||||
if( fPAItransferTable )
|
||||
{
|
||||
fPAItransferBank->clearAndDestroy() ;
|
||||
delete fPAItransferBank ;
|
||||
fPAItransferTable->clearAndDestroy() ;
|
||||
delete fPAItransferTable ;
|
||||
}
|
||||
*/
|
||||
fPAItransferBank = new G4PhysicsTable(fTotBin);
|
||||
fPAItransferTable = new G4PhysicsTable(fTotBin);
|
||||
/*
|
||||
if( fPAIdEdxTable )
|
||||
{
|
||||
@@ -328,7 +334,7 @@ G4PAIModel::BuildPAIonisationTable()
|
||||
if ( ionloss <= 0.) ionloss = DBL_MIN ;
|
||||
fdEdxVector->PutValue(i,ionloss) ;
|
||||
|
||||
fPAItransferBank->insertAt(i,transferVector) ;
|
||||
fPAItransferTable->insertAt(i,transferVector) ;
|
||||
fPAIdEdxTable->insertAt(i,dEdxVector) ;
|
||||
|
||||
// delete[] transferVector ;
|
||||
@@ -363,7 +369,7 @@ G4PAIModel::BuildLambdaVector(const G4MaterialCutsCouple* matCutsCouple)
|
||||
}
|
||||
if( jMatCC == numOfCouples && jMatCC > 0 ) jMatCC--;
|
||||
|
||||
const std::vector<G4double>* deltaCutInKineticEnergy = theCoupleTable->
|
||||
const vector<G4double>* deltaCutInKineticEnergy = theCoupleTable->
|
||||
GetEnergyCutsVector(idxG4ElectronCut);
|
||||
|
||||
if (fLambdaVector) delete fLambdaVector;
|
||||
@@ -402,33 +408,33 @@ G4PAIModel::GetdNdxCut( G4int iPlace, G4double transferCut)
|
||||
G4int iTransfer;
|
||||
G4double x1, x2, y1, y2, dNdxCut;
|
||||
// G4cout<<"iPlace = "<<iPlace<<"; "<<"transferCut = "<<transferCut<<G4endl;
|
||||
// G4cout<<"size = "<<G4int((*fPAItransferBank)(iPlace)->GetVectorLength())
|
||||
// G4cout<<"size = "<<G4int((*fPAItransferTable)(iPlace)->GetVectorLength())
|
||||
// <<G4endl;
|
||||
for( iTransfer = 0 ;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()) ;
|
||||
iTransfer < G4int((*fPAItransferTable)(iPlace)->GetVectorLength()) ;
|
||||
iTransfer++)
|
||||
{
|
||||
if(transferCut <= (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer))
|
||||
if(transferCut <= (*fPAItransferTable)(iPlace)->GetLowEdgeEnergy(iTransfer))
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( iTransfer >= G4int((*fPAItransferBank)(iPlace)->GetVectorLength()) )
|
||||
if ( iTransfer >= G4int((*fPAItransferTable)(iPlace)->GetVectorLength()) )
|
||||
{
|
||||
iTransfer = (*fPAItransferBank)(iPlace)->GetVectorLength() - 1 ;
|
||||
iTransfer = (*fPAItransferTable)(iPlace)->GetVectorLength() - 1 ;
|
||||
}
|
||||
y1 = (*(*fPAItransferBank)(iPlace))(iTransfer-1) ;
|
||||
y2 = (*(*fPAItransferBank)(iPlace))(iTransfer) ;
|
||||
y1 = (*(*fPAItransferTable)(iPlace))(iTransfer-1) ;
|
||||
y2 = (*(*fPAItransferTable)(iPlace))(iTransfer) ;
|
||||
// G4cout<<"y1 = "<<y1<<"; "<<"y2 = "<<y2<<G4endl;
|
||||
x1 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
|
||||
x2 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
x1 = (*fPAItransferTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
|
||||
x2 = (*fPAItransferTable)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
// G4cout<<"x1 = "<<x1<<"; "<<"x2 = "<<x2<<G4endl;
|
||||
|
||||
if ( y1 == y2 ) dNdxCut = y2 ;
|
||||
else
|
||||
{
|
||||
// if ( x1 == x2 ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( abs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( fabs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
else dNdxCut = y1 + (transferCut - x1)*(y2 - y1)/(x2 - x1) ;
|
||||
}
|
||||
// G4cout<<""<<dNdxCut<<G4endl;
|
||||
@@ -470,7 +476,7 @@ G4PAIModel::GetdEdxCut( G4int iPlace, G4double transferCut)
|
||||
else
|
||||
{
|
||||
// if ( x1 == x2 ) dEdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( abs(x1-x2) <= eV ) dEdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( fabs(x1-x2) <= eV ) dEdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
else dEdxCut = y1 + (transferCut - x1)*(y2 - y1)/(x2 - x1) ;
|
||||
}
|
||||
// G4cout<<""<<dEdxCut<<G4endl;
|
||||
@@ -486,7 +492,8 @@ G4double G4PAIModel::ComputeDEDX(const G4MaterialCutsCouple* matCC,
|
||||
{
|
||||
G4int iTkin,iPlace;
|
||||
size_t jMat;
|
||||
G4double scaledTkin = kineticEnergy*p->GetPDGMass()/proton_mass_c2;
|
||||
G4double massRatio = proton_mass_c2/p->GetPDGMass();
|
||||
G4double scaledTkin = kineticEnergy*massRatio;
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double charge2 = charge*charge, dEdx;
|
||||
|
||||
@@ -520,8 +527,9 @@ G4double G4PAIModel::CrossSection( const G4MaterialCutsCouple* matCC,
|
||||
{
|
||||
G4int iTkin,iPlace;
|
||||
size_t jMat;
|
||||
G4double tmax = std::min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
|
||||
G4double scaledTkin = kineticEnergy*p->GetPDGMass()/proton_mass_c2;
|
||||
G4double tmax = min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
|
||||
G4double massRatio = proton_mass_c2/p->GetPDGMass();
|
||||
G4double scaledTkin = kineticEnergy*massRatio;
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double charge2 = charge*charge, cross, cross1, cross2;
|
||||
|
||||
@@ -531,7 +539,7 @@ G4double G4PAIModel::CrossSection( const G4MaterialCutsCouple* matCC,
|
||||
}
|
||||
if(jMat == fMaterialCutsCoupleVector.size() && jMat > 0) jMat--;
|
||||
|
||||
fPAItransferBank = fPAIxscBank[jMat];
|
||||
fPAItransferTable = fPAIxscBank[jMat];
|
||||
|
||||
for(iTkin = 0 ; iTkin < fTotBin ; iTkin++)
|
||||
{
|
||||
@@ -540,10 +548,18 @@ G4double G4PAIModel::CrossSection( const G4MaterialCutsCouple* matCC,
|
||||
iPlace = iTkin - 1;
|
||||
if(iPlace < 0) iPlace = 0;
|
||||
|
||||
cross1 = GetdNdxCut(iPlace,tmax) ;
|
||||
// G4cout<<"iPlace = "<<iPlace<<"; tmax = "
|
||||
// <<tmax<<"; cutEnergy = "<<cutEnergy<<G4endl;
|
||||
cross1 = GetdNdxCut(iPlace,tmax) ;
|
||||
// G4cout<<"cross1 = "<<cross1<<G4endl;
|
||||
cross2 = GetdNdxCut(iPlace,cutEnergy) ;
|
||||
// G4cout<<"cross2 = "<<cross2<<G4endl;
|
||||
cross = (cross2-cross1)*charge2;
|
||||
if( cross < 0.) cross = 0.;
|
||||
// G4cout<<"cross = "<<cross<<G4endl;
|
||||
if( cross < DBL_MIN) cross = DBL_MIN;
|
||||
// if( cross2 < DBL_MIN) cross2 = DBL_MIN;
|
||||
|
||||
// return cross2;
|
||||
return cross;
|
||||
}
|
||||
|
||||
@@ -565,20 +581,33 @@ G4PAIModel::SampleSecondary( const G4MaterialCutsCouple* matCC,
|
||||
}
|
||||
if(jMat == fMaterialCutsCoupleVector.size() && jMat > 0) jMat--;
|
||||
|
||||
fPAItransferBank = fPAIxscBank[jMat];
|
||||
fdNdxCutVector = fdNdxCutTable[jMat];
|
||||
fPAItransferTable = fPAIxscBank[jMat];
|
||||
fdNdxCutVector = fdNdxCutTable[jMat];
|
||||
|
||||
G4double tmax = std::min(MaxSecondaryEnergy(dp), maxEnergy);
|
||||
if( tmin >= tmax ) return 0;
|
||||
G4double tmax = min(MaxSecondaryEnergy(dp), maxEnergy);
|
||||
if( tmin >= tmax )
|
||||
{
|
||||
G4cout<<"G4PAIModel::SampleSecondary: tmin >= tmax "<<G4endl;
|
||||
}
|
||||
G4ThreeVector momentum = dp->GetMomentumDirection();
|
||||
G4double particleMass = dp->GetMass();
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
G4double scaledTkin = kineticEnergy*particleMass/proton_mass_c2;
|
||||
|
||||
G4double massRatio = proton_mass_c2/particleMass;
|
||||
G4double scaledTkin = kineticEnergy*massRatio;
|
||||
G4double totalEnergy = kineticEnergy + particleMass;
|
||||
G4double pSquare = kineticEnergy*(totalEnergy+particleMass);
|
||||
|
||||
G4double deltaTkin = GetPostStepTransfer(scaledTkin);
|
||||
if( deltaTkin <= 0. ) return 0;
|
||||
if( deltaTkin <= 0. )
|
||||
{
|
||||
G4cout<<"Tkin of secondary e- <= 0."<<G4endl;
|
||||
G4cout<<"G4PAIModel::SampleSecondary::deltaTkin = "<<deltaTkin<<G4endl;
|
||||
deltaTkin = 10*eV;
|
||||
G4cout<<"Set G4PAIModel::SampleSecondary::deltaTkin = "<<deltaTkin<<G4endl;
|
||||
}
|
||||
if(deltaTkin > kineticEnergy) deltaTkin = kineticEnergy;
|
||||
|
||||
G4double deltaTotalMomentum = sqrt(deltaTkin*(deltaTkin + 2. * electron_mass_c2 ));
|
||||
G4double totalMomentum = sqrt(pSquare);
|
||||
G4double costheta = deltaTkin*(totalEnergy + electron_mass_c2)
|
||||
@@ -586,7 +615,7 @@ G4PAIModel::SampleSecondary( const G4MaterialCutsCouple* matCC,
|
||||
if (costheta < 0.) costheta = 0.;
|
||||
if (costheta > +1.) costheta = +1.;
|
||||
|
||||
// direction of the delta electron
|
||||
// direction of the delta electron
|
||||
|
||||
G4double phi = twopi*G4UniformRand();
|
||||
G4double sintheta = sqrt((1.+costheta)*(1.-costheta));
|
||||
@@ -595,11 +624,11 @@ G4PAIModel::SampleSecondary( const G4MaterialCutsCouple* matCC,
|
||||
G4ThreeVector deltaDirection(dirx,diry,dirz);
|
||||
deltaDirection.rotateUz(momentum);
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
// create G4DynamicParticle object for e- delta ray
|
||||
|
||||
G4DynamicParticle* deltaRay = new G4DynamicParticle;
|
||||
deltaRay->SetDefinition(G4Electron::Electron());
|
||||
deltaRay->SetKineticEnergy( deltaTkin );
|
||||
deltaRay->SetKineticEnergy( deltaTkin ); // !!! trick for last steps /2.0 ???
|
||||
deltaRay->SetMomentumDirection(deltaDirection);
|
||||
|
||||
return deltaRay;
|
||||
@@ -624,33 +653,35 @@ G4PAIModel::GetPostStepTransfer( G4double scaledTkin )
|
||||
if(scaledTkin < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
|
||||
}
|
||||
iPlace = iTkin - 1 ;
|
||||
// G4cout<<"from search, iPlace = "<<iPlace<<G4endl ;
|
||||
if(iPlace < 0) iPlace = 0;
|
||||
dNdxCut1 = (*fdNdxCutVector)(iPlace) ;
|
||||
// G4cout<<"dNdxCut1 = "<<dNdxCut1<<G4endl ;
|
||||
|
||||
// G4cout<<"iPlace = "<<iPlace<<endl ;
|
||||
|
||||
if(iTkin == fTotBin) // Fermi plato, try from left
|
||||
{
|
||||
position = dNdxCut1*G4UniformRand() ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
iTransfer < G4int((*fPAItransferTable)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace))(iTransfer)) break ;
|
||||
if(position >= (*(*fPAItransferTable)(iPlace))(iTransfer)) break ;
|
||||
}
|
||||
transfer = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
dNdxCut2 = (*fdNdxCutVector)(iPlace+1) ;
|
||||
// G4cout<<"dNdxCut2 = "<<dNdxCut2<<G4endl ;
|
||||
if(iTkin == 0) // Tkin is too small, trying from right only
|
||||
{
|
||||
position = dNdxCut2*G4UniformRand() ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace+1)->GetVectorLength()); iTransfer++ )
|
||||
iTransfer < G4int((*fPAItransferTable)(iPlace+1)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace+1))(iTransfer)) break ;
|
||||
if(position >= (*(*fPAItransferTable)(iPlace+1))(iTransfer)) break ;
|
||||
}
|
||||
transfer = GetEnergyTransfer(iPlace+1,position,iTransfer);
|
||||
}
|
||||
@@ -667,16 +698,16 @@ G4PAIModel::GetPostStepTransfer( G4double scaledTkin )
|
||||
// G4cout<<position<<"\t" ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
iTransfer < G4int((*fPAItransferTable)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if( position >=
|
||||
( (*(*fPAItransferBank)(iPlace))(iTransfer)*W1 +
|
||||
(*(*fPAItransferBank)(iPlace+1))(iTransfer)*W2) ) break ;
|
||||
( (*(*fPAItransferTable)(iPlace))(iTransfer)*W1 +
|
||||
(*(*fPAItransferTable)(iPlace+1))(iTransfer)*W2) ) break ;
|
||||
}
|
||||
transfer = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
}
|
||||
}
|
||||
// G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"<<endl ;
|
||||
// G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"<<G4endl ;
|
||||
if(transfer < 0.0 ) transfer = 0.0 ;
|
||||
return transfer ;
|
||||
}
|
||||
@@ -693,19 +724,19 @@ G4PAIModel::GetEnergyTransfer( G4int iPlace, G4double position, G4int iTransfer
|
||||
|
||||
if(iTransfer == 0)
|
||||
{
|
||||
energyTransfer = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
energyTransfer = (*fPAItransferTable)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( iTransfer >= G4int((*fPAItransferBank)(iPlace)->GetVectorLength()) )
|
||||
if ( iTransfer >= G4int((*fPAItransferTable)(iPlace)->GetVectorLength()) )
|
||||
{
|
||||
iTransfer = (*fPAItransferBank)(iPlace)->GetVectorLength() - 1 ;
|
||||
iTransfer = (*fPAItransferTable)(iPlace)->GetVectorLength() - 1 ;
|
||||
}
|
||||
y1 = (*(*fPAItransferBank)(iPlace))(iTransfer-1) ;
|
||||
y2 = (*(*fPAItransferBank)(iPlace))(iTransfer) ;
|
||||
y1 = (*(*fPAItransferTable)(iPlace))(iTransfer-1) ;
|
||||
y2 = (*(*fPAItransferTable)(iPlace))(iTransfer) ;
|
||||
|
||||
x1 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
|
||||
x2 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
x1 = (*fPAItransferTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
|
||||
x2 = (*fPAItransferTable)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
|
||||
if ( x1 == x2 ) energyTransfer = x2 ;
|
||||
else
|
||||
@@ -723,15 +754,16 @@ G4PAIModel::GetEnergyTransfer( G4int iPlace, G4double position, G4int iTransfer
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<G4DynamicParticle*>*
|
||||
G4PAIModel::SampleSecondaries( const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
vector<G4DynamicParticle*>*
|
||||
G4PAIModel::SampleSecondaries( const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
std::vector<G4DynamicParticle*>* vdp = new std::vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
vector<G4DynamicParticle*>* vdp = 0;
|
||||
// vector<G4DynamicParticle*>* vdp = new vector<G4DynamicParticle*>;
|
||||
// G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
// vdp->push_back(delta);
|
||||
return vdp;
|
||||
}
|
||||
|
||||
@@ -750,18 +782,19 @@ G4double G4PAIModel::SampleFluctuations( const G4Material* material,
|
||||
}
|
||||
if(jMat == fMaterialCutsCoupleVector.size() && jMat > 0) jMat--;
|
||||
|
||||
fPAItransferBank = fPAIxscBank[jMat];
|
||||
fPAItransferTable = fPAIxscBank[jMat];
|
||||
fdNdxCutVector = fdNdxCutTable[jMat];
|
||||
|
||||
G4int iTkin, iTransfer, iPlace ;
|
||||
G4long numOfCollisions;
|
||||
G4long numOfCollisions=0;
|
||||
|
||||
// G4cout<<"G4PAIModel::SampleFluctuations"<<G4endl ;
|
||||
// G4cout<<"in: "<<fMaterialCutsCoupleVector[jMat]->GetMaterial()->GetName()<<G4endl ;
|
||||
|
||||
G4double loss = 0.0, charge2 ;
|
||||
|
||||
G4double stepSum = 0., stepDelta, lambda, omega;
|
||||
G4double position, E1, E2, W1, W2, W, dNdxCut1, dNdxCut2, meanNumber;
|
||||
|
||||
G4bool numb = true;
|
||||
G4double Tkin = aParticle->GetKineticEnergy() ;
|
||||
G4double MassRatio = proton_mass_c2/aParticle->GetDefinition()->GetPDGMass() ;
|
||||
G4double charge = aParticle->GetDefinition()->GetPDGCharge() ;
|
||||
@@ -773,55 +806,80 @@ G4double G4PAIModel::SampleFluctuations( const G4Material* material,
|
||||
if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
|
||||
}
|
||||
iPlace = iTkin - 1 ;
|
||||
// G4cout<<"from search, iPlace = "<<iPlace<<G4endl ;
|
||||
dNdxCut1 = (*fdNdxCutVector)(iPlace) ;
|
||||
// G4cout<<"dNdxCut1 = "<<dNdxCut1<<G4endl ;
|
||||
|
||||
// G4cout<<"iPlace = "<<iPlace<<endl ;
|
||||
|
||||
if(iTkin == fTotBin) // Fermi plato, try from left
|
||||
{
|
||||
meanNumber =((*(*fPAItransferBank)(iPlace))(0)-dNdxCut1)*step*charge2;
|
||||
meanNumber =((*(*fPAItransferTable)(iPlace))(0)-dNdxCut1)*step*charge2;
|
||||
if(meanNumber < 0.) meanNumber = 0. ;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
|
||||
// numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
// numOfCollisions = G4Poisson(meanNumber) ;
|
||||
if( meanNumber > 0.) lambda = step/meanNumber;
|
||||
else lambda = DBL_MAX;
|
||||
while(numb)
|
||||
{
|
||||
stepDelta = RandExponential::shoot(lambda);
|
||||
stepSum += stepDelta;
|
||||
if(stepSum >= step) break;
|
||||
numOfCollisions++;
|
||||
}
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position = dNdxCut1+
|
||||
((*(*fPAItransferBank)(iPlace))(0)-dNdxCut1)*G4UniformRand() ;
|
||||
((*(*fPAItransferTable)(iPlace))(0)-dNdxCut1)*G4UniformRand() ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
iTransfer < G4int((*fPAItransferTable)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace))(iTransfer)) break ;
|
||||
if(position >= (*(*fPAItransferTable)(iPlace))(iTransfer)) break ;
|
||||
}
|
||||
loss += GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
omega = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
// G4cout<<omega/keV<<"\t";
|
||||
loss += omega;
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dNdxCut2 = (*fdNdxCutVector)(iPlace+1) ;
|
||||
// G4cout<<"dNdxCut2 = "<<dNdxCut2<<G4endl ;
|
||||
|
||||
if(iTkin == 0) // Tkin is too small, trying from right only
|
||||
{
|
||||
meanNumber =((*(*fPAItransferBank)(iPlace+1))(0)-dNdxCut2)*step*charge2;
|
||||
meanNumber =((*(*fPAItransferTable)(iPlace+1))(0)-dNdxCut2)*step*charge2;
|
||||
if( meanNumber < 0. ) meanNumber = 0. ;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
// numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
// numOfCollisions = G4Poisson(meanNumber) ;
|
||||
if( meanNumber > 0.) lambda = step/meanNumber;
|
||||
else lambda = DBL_MAX;
|
||||
while(numb)
|
||||
{
|
||||
stepDelta = RandExponential::shoot(lambda);
|
||||
stepSum += stepDelta;
|
||||
if(stepSum >= step) break;
|
||||
numOfCollisions++;
|
||||
}
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position = dNdxCut2+
|
||||
((*(*fPAItransferBank)(iPlace+1))(0)-dNdxCut2)*G4UniformRand();
|
||||
((*(*fPAItransferTable)(iPlace+1))(0)-dNdxCut2)*G4UniformRand();
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace+1)->GetVectorLength()); iTransfer++ )
|
||||
iTransfer < G4int((*fPAItransferTable)(iPlace+1)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace+1))(iTransfer)) break ;
|
||||
if(position >= (*(*fPAItransferTable)(iPlace+1))(iTransfer)) break ;
|
||||
}
|
||||
loss += GetEnergyTransfer(iPlace+1,position,iTransfer);
|
||||
omega = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
// G4cout<<omega/keV<<"\t";
|
||||
loss += omega;
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
@@ -833,45 +891,56 @@ G4double G4PAIModel::SampleFluctuations( const G4Material* material,
|
||||
W1 = (E2 - TkinScaled)*W ;
|
||||
W2 = (TkinScaled - E1)*W ;
|
||||
|
||||
// G4cout<<"(*(*fPAItransferBank)(iPlace))(0) = "<<
|
||||
// (*(*fPAItransferBank)(iPlace))(0)<<G4endl ;
|
||||
// G4cout<<"(*(*fPAItransferBank)(iPlace+1))(0) = "<<
|
||||
// (*(*fPAItransferBank)(iPlace+1))(0)<<G4endl ;
|
||||
// G4cout<<"(*(*fPAItransferTable)(iPlace))(0) = "<<
|
||||
// (*(*fPAItransferTable)(iPlace))(0)<<G4endl ;
|
||||
// G4cout<<"(*(*fPAItransferTable)(iPlace+1))(0) = "<<
|
||||
// (*(*fPAItransferTable)(iPlace+1))(0)<<G4endl ;
|
||||
|
||||
meanNumber=( ((*(*fPAItransferBank)(iPlace))(0)-dNdxCut1)*W1 +
|
||||
((*(*fPAItransferBank)(iPlace+1))(0)-dNdxCut2)*W2 )*step*charge2;
|
||||
meanNumber=( ((*(*fPAItransferTable)(iPlace))(0)-dNdxCut1)*W1 +
|
||||
((*(*fPAItransferTable)(iPlace+1))(0)-dNdxCut2)*W2 )*step*charge2;
|
||||
if(meanNumber<0.0) meanNumber = 0.0;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
// numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
// numOfCollisions = G4Poisson(meanNumber) ;
|
||||
if( meanNumber > 0.) lambda = step/meanNumber;
|
||||
else lambda = DBL_MAX;
|
||||
while(numb)
|
||||
{
|
||||
stepDelta = RandExponential::shoot(lambda);
|
||||
stepSum += stepDelta;
|
||||
if(stepSum >= step) break;
|
||||
numOfCollisions++;
|
||||
}
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position =( (dNdxCut1+
|
||||
((*(*fPAItransferBank)(iPlace ))(0)-dNdxCut1))*W1 +
|
||||
(dNdxCut2+
|
||||
((*(*fPAItransferBank)(iPlace+1))(0)-dNdxCut2))*W2 )*G4UniformRand();
|
||||
position = dNdxCut1*W1 + dNdxCut2*W2 +
|
||||
( ( (*(*fPAItransferTable)(iPlace))(0)-dNdxCut1 )*W1 +
|
||||
dNdxCut2+
|
||||
( (*(*fPAItransferTable)(iPlace+1))(0)-dNdxCut2 )*W2 )*G4UniformRand();
|
||||
|
||||
// G4cout<<position<<"\t" ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
iTransfer < G4int((*fPAItransferTable)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if( position >=
|
||||
( (*(*fPAItransferBank)(iPlace))(iTransfer)*W1 +
|
||||
(*(*fPAItransferBank)(iPlace+1))(iTransfer)*W2) )
|
||||
( (*(*fPAItransferTable)(iPlace))(iTransfer)*W1 +
|
||||
(*(*fPAItransferTable)(iPlace+1))(iTransfer)*W2) )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
// loss += (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
loss += GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
omega = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
// G4cout<<omega/keV<<"\t";
|
||||
loss += omega;
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// G4cout<<"PAIModel AlongStepLoss = "<<loss/keV<<" keV"<<endl ;
|
||||
|
||||
// G4cout<<"PAIModel AlongStepLoss = "<<loss/keV<<" keV"<<G4endl ;
|
||||
if(loss > Tkin) loss=Tkin;
|
||||
return loss ;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,12 +22,15 @@
|
||||
//
|
||||
// File name: G4PAIPhotonModel.cc
|
||||
//
|
||||
// Author: Vladimir.Grichine@cern.ch on base of Vladimir Ivanchenko code
|
||||
// Author: Vladimir.Grichine@cern.ch based on G4PAIModel class
|
||||
//
|
||||
// Creation date: 05.10.2003
|
||||
// Creation date: 20.05.2004
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 17.08.04 V.Grichine, bug fixed for Tkin<=0 in SampleSecondary
|
||||
// 16.08.04 V.Grichine, bug fixed in massRatio for DEDX, CrossSection, SampleSecondary
|
||||
//
|
||||
|
||||
#include "G4Region.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
@@ -49,9 +52,10 @@
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4PAIPhotonModel::G4PAIPhotonModel(const G4ParticleDefinition* p, const G4String& nam)
|
||||
: G4VEmModel(nam),G4VEmFluctuationModel(nam),
|
||||
fLowestKineticEnergy(10.0*keV),
|
||||
@@ -180,7 +184,7 @@ void G4PAIPhotonModel::Initialise(const G4ParticleDefinition* p,
|
||||
|
||||
// (*fPAIRegionVector[iRegion])
|
||||
|
||||
std::vector<G4Material*>::const_iterator matIter = curReg->GetMaterialIterator();
|
||||
vector<G4Material*>::const_iterator matIter = curReg->GetMaterialIterator();
|
||||
size_t jMat;
|
||||
size_t numOfMat = curReg->GetNumberOfMaterials();
|
||||
|
||||
@@ -409,9 +413,9 @@ G4PAIPhotonModel::BuildLambdaVector(const G4MaterialCutsCouple* matCutsCouple)
|
||||
}
|
||||
if( jMatCC == numOfCouples && jMatCC > 0 ) jMatCC--;
|
||||
|
||||
const std::vector<G4double>* deltaCutInKineticEnergy = theCoupleTable->
|
||||
const vector<G4double>* deltaCutInKineticEnergy = theCoupleTable->
|
||||
GetEnergyCutsVector(idxG4ElectronCut);
|
||||
const std::vector<G4double>* photonCutInKineticEnergy = theCoupleTable->
|
||||
const vector<G4double>* photonCutInKineticEnergy = theCoupleTable->
|
||||
GetEnergyCutsVector(idxG4GammaCut);
|
||||
|
||||
if (fLambdaVector) delete fLambdaVector;
|
||||
@@ -494,7 +498,7 @@ G4PAIPhotonModel::GetdNdxCut( G4int iPlace, G4double transferCut)
|
||||
else
|
||||
{
|
||||
// if ( x1 == x2 ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( abs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( fabs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
else dNdxCut = y1 + (transferCut - x1)*(y2 - y1)/(x2 - x1) ;
|
||||
}
|
||||
// G4cout<<""<<dNdxCut<<G4endl;
|
||||
@@ -537,7 +541,7 @@ G4PAIPhotonModel::GetdNdxPhotonCut( G4int iPlace, G4double transferCut)
|
||||
else
|
||||
{
|
||||
// if ( x1 == x2 ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( abs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( fabs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
else dNdxCut = y1 + (transferCut - x1)*(y2 - y1)/(x2 - x1) ;
|
||||
}
|
||||
// G4cout<<""<<dNdxPhotonCut<<G4endl;
|
||||
@@ -581,7 +585,7 @@ G4PAIPhotonModel::GetdNdxPlasmonCut( G4int iPlace, G4double transferCut)
|
||||
else
|
||||
{
|
||||
// if ( x1 == x2 ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( abs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( fabs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
else dNdxCut = y1 + (transferCut - x1)*(y2 - y1)/(x2 - x1) ;
|
||||
}
|
||||
// G4cout<<""<<dNdxPlasmonCut<<G4endl;
|
||||
@@ -624,7 +628,7 @@ G4PAIPhotonModel::GetdEdxCut( G4int iPlace, G4double transferCut)
|
||||
else
|
||||
{
|
||||
// if ( x1 == x2 ) dEdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( abs(x1-x2) <= eV ) dEdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( fabs(x1-x2) <= eV ) dEdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
else dEdxCut = y1 + (transferCut - x1)*(y2 - y1)/(x2 - x1) ;
|
||||
}
|
||||
// G4cout<<""<<dEdxCut<<G4endl;
|
||||
@@ -640,9 +644,10 @@ G4double G4PAIPhotonModel::ComputeDEDX(const G4MaterialCutsCouple* matCC,
|
||||
{
|
||||
G4int iTkin,iPlace;
|
||||
size_t jMat;
|
||||
G4double scaledTkin = kineticEnergy*p->GetPDGMass()/proton_mass_c2;
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double charge2 = charge*charge, dEdx;
|
||||
G4double particleMass = p->GetPDGMass();
|
||||
G4double scaledTkin = kineticEnergy*proton_mass_c2/particleMass;
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double charge2 = charge*charge, dEdx;
|
||||
|
||||
for( jMat = 0 ;jMat < fMaterialCutsCoupleVector.size() ; ++jMat )
|
||||
{
|
||||
@@ -674,10 +679,11 @@ G4double G4PAIPhotonModel::CrossSection( const G4MaterialCutsCouple* matCC,
|
||||
{
|
||||
G4int iTkin,iPlace;
|
||||
size_t jMat, jMatCC;
|
||||
G4double tmax = std::min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
|
||||
G4double scaledTkin = kineticEnergy*p->GetPDGMass()/proton_mass_c2;
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double charge2 = charge*charge, cross, cross1, cross2;
|
||||
G4double tmax = min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
|
||||
G4double particleMass = p->GetPDGMass();
|
||||
G4double scaledTkin = kineticEnergy*proton_mass_c2/particleMass;
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double charge2 = charge*charge, cross, cross1, cross2;
|
||||
G4double photon1, photon2, plasmon1, plasmon2;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
@@ -691,7 +697,7 @@ G4double G4PAIPhotonModel::CrossSection( const G4MaterialCutsCouple* matCC,
|
||||
}
|
||||
if( jMatCC == numOfCouples && jMatCC > 0 ) jMatCC--;
|
||||
|
||||
const std::vector<G4double>* photonCutInKineticEnergy = theCoupleTable->
|
||||
const vector<G4double>* photonCutInKineticEnergy = theCoupleTable->
|
||||
GetEnergyCutsVector(idxG4GammaCut);
|
||||
|
||||
G4double photonCut = (*photonCutInKineticEnergy)[jMatCC] ;
|
||||
@@ -713,6 +719,8 @@ G4double G4PAIPhotonModel::CrossSection( const G4MaterialCutsCouple* matCC,
|
||||
iPlace = iTkin - 1;
|
||||
if(iPlace < 0) iPlace = 0;
|
||||
|
||||
// G4cout<<"iPlace = "<<iPlace<<"; tmax = "
|
||||
// <<tmax<<"; cutEnergy = "<<cutEnergy<<G4endl;
|
||||
photon1 = GetdNdxPhotonCut(iPlace,tmax);
|
||||
photon2 = GetdNdxPhotonCut(iPlace,photonCut);
|
||||
|
||||
@@ -720,8 +728,11 @@ G4double G4PAIPhotonModel::CrossSection( const G4MaterialCutsCouple* matCC,
|
||||
plasmon2 = GetdNdxPlasmonCut(iPlace,cutEnergy);
|
||||
|
||||
cross1 = photon1 + plasmon1;
|
||||
// G4cout<<"cross1 = "<<cross1<<G4endl;
|
||||
cross2 = photon2 + plasmon2;
|
||||
// G4cout<<"cross2 = "<<cross2<<G4endl;
|
||||
cross = (cross2 - cross1)*charge2;
|
||||
// G4cout<<"cross = "<<cross<<G4endl;
|
||||
|
||||
if( cross < 0. ) cross = 0.;
|
||||
return cross;
|
||||
@@ -754,13 +765,16 @@ G4PAIPhotonModel::SampleSecondary( const G4MaterialCutsCouple* matCC,
|
||||
fdNdxCutPhotonVector = fdNdxCutPhotonTable[jMat];
|
||||
fdNdxCutPlasmonVector = fdNdxCutPlasmonTable[jMat];
|
||||
|
||||
G4double tmax = std::min(MaxSecondaryEnergy(dp), maxEnergy);
|
||||
if( tmin >= tmax ) return 0;
|
||||
G4double tmax = min(MaxSecondaryEnergy(dp), maxEnergy);
|
||||
if( tmin >= tmax )
|
||||
{
|
||||
G4cout<<"G4PAIPhotonModel::SampleSecondary: tmin >= tmax "<<G4endl;
|
||||
}
|
||||
|
||||
G4ThreeVector momentum = dp->GetMomentumDirection();
|
||||
G4double particleMass = dp->GetMass();
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
G4double scaledTkin = kineticEnergy*particleMass/proton_mass_c2;
|
||||
G4double scaledTkin = kineticEnergy*proton_mass_c2/particleMass;
|
||||
G4double totalEnergy = kineticEnergy + particleMass;
|
||||
G4double pSquare = kineticEnergy*(totalEnergy+particleMass);
|
||||
|
||||
@@ -785,9 +799,15 @@ G4PAIPhotonModel::SampleSecondary( const G4MaterialCutsCouple* matCC,
|
||||
G4double deltaTkin = GetPostStepTransfer(fPAIplasmonTable, fdNdxCutPlasmonVector,
|
||||
iPlace, scaledTkin);
|
||||
|
||||
//G4cout<<"PAIPhotonModel PlasmonPostStepTransfer = "<<deltaTkin/keV<<" keV"<<G4endl ;
|
||||
|
||||
if( deltaTkin <= 0. ) return 0;
|
||||
// G4cout<<"PAIPhotonModel PlasmonPostStepTransfer = "<<deltaTkin/keV<<" keV"<<G4endl ;
|
||||
|
||||
if( deltaTkin <= 0. )
|
||||
{
|
||||
G4cout<<"Tkin of secondary e- <= 0."<<G4endl;
|
||||
G4cout<<"G4PAIPhotonModel::SampleSecondary::deltaTkin = "<<deltaTkin<<G4endl;
|
||||
deltaTkin = 10*eV;
|
||||
G4cout<<"Set G4PAIPhotonModel::SampleSecondary::deltaTkin = "<<deltaTkin<<G4endl;
|
||||
}
|
||||
|
||||
G4double deltaTotalMomentum = sqrt(deltaTkin*(deltaTkin + 2. * electron_mass_c2 ));
|
||||
G4double totalMomentum = sqrt(pSquare);
|
||||
@@ -819,17 +839,24 @@ G4PAIPhotonModel::SampleSecondary( const G4MaterialCutsCouple* matCC,
|
||||
G4double deltaTkin = GetPostStepTransfer(fPAIphotonTable, fdNdxCutPhotonVector,
|
||||
iPlace,scaledTkin);
|
||||
|
||||
//G4cout<<"PAIPhotonModel PhotonPostStepTransfer = "<<deltaTkin/keV<<" keV"<<G4endl ;
|
||||
// G4cout<<"PAIPhotonModel PhotonPostStepTransfer = "<<deltaTkin/keV<<" keV"<<G4endl ;
|
||||
|
||||
if( deltaTkin <= 0. ) return 0;
|
||||
if( deltaTkin <= 0. )
|
||||
{
|
||||
G4cout<<"Tkin of secondary photon <= 0."<<G4endl;
|
||||
G4cout<<"G4PAIPhotonModel::SampleSecondary::deltaTkin = "<<deltaTkin<<G4endl;
|
||||
deltaTkin = 10*eV;
|
||||
G4cout<<"Set G4PAIPhotonModel::SampleSecondary::deltaTkin = "<<deltaTkin<<G4endl;
|
||||
}
|
||||
|
||||
// G4double deltaTotalMomentum = sqrt(deltaTkin*(deltaTkin + 2. * electron_mass_c2 ));
|
||||
// G4double totalMomentum = sqrt(pSquare);
|
||||
// deltaTkin*(totalEnergy + electron_mass_c2)
|
||||
// /(deltaTotalMomentum * totalMomentum);
|
||||
|
||||
G4double costheta = G4UniformRand();
|
||||
if (costheta < 0.) costheta = 0.;
|
||||
G4double costheta = 0.; // G4UniformRand(); // VG: ??? for start only
|
||||
|
||||
if (costheta < 0.) costheta = 0.;
|
||||
if (costheta > 1.) costheta = 1.;
|
||||
|
||||
// direction of the 'Cherenkov' photon
|
||||
@@ -844,7 +871,7 @@ G4PAIPhotonModel::SampleSecondary( const G4MaterialCutsCouple* matCC,
|
||||
// create G4DynamicParticle object for photon ray
|
||||
|
||||
G4DynamicParticle* photonRay = new G4DynamicParticle;
|
||||
photonRay->SetDefinition(G4Gamma::Gamma());
|
||||
photonRay->SetDefinition( G4Gamma::Gamma() );
|
||||
photonRay->SetKineticEnergy( deltaTkin );
|
||||
photonRay->SetMomentumDirection(deltaDirection);
|
||||
|
||||
@@ -967,13 +994,13 @@ G4PAIPhotonModel::GetEnergyTransfer( G4PhysicsTable* pTable, G4int iPlace,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<G4DynamicParticle*>*
|
||||
vector<G4DynamicParticle*>*
|
||||
G4PAIPhotonModel::SampleSecondaries( const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
std::vector<G4DynamicParticle*>* vdp = new std::vector<G4DynamicParticle*>;
|
||||
vector<G4DynamicParticle*>* vdp = new vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
return vdp;
|
||||
@@ -1028,11 +1055,13 @@ G4double G4PAIPhotonModel::SampleFluctuations( const G4Material* material,
|
||||
iPlace = iTkin - 1 ;
|
||||
if( iPlace < 0 ) iPlace = 0;
|
||||
|
||||
photonLoss = GetAlongStepTransfer(fPAIphotonTable,fdNdxCutPhotonVector,iPlace,scaledTkin,cof);
|
||||
photonLoss = GetAlongStepTransfer(fPAIphotonTable,fdNdxCutPhotonVector,
|
||||
iPlace,scaledTkin,step,cof);
|
||||
|
||||
// G4cout<<"PAIPhotonModel AlongStepPhotonLoss = "<<photonLoss/keV<<" keV"<<G4endl ;
|
||||
|
||||
plasmonLoss = GetAlongStepTransfer(fPAIplasmonTable,fdNdxCutPlasmonVector,iPlace,scaledTkin,cof);
|
||||
plasmonLoss = GetAlongStepTransfer(fPAIplasmonTable,fdNdxCutPlasmonVector,
|
||||
iPlace,scaledTkin,step,cof);
|
||||
|
||||
// G4cout<<"PAIPhotonModel AlongStepPlasmonLoss = "<<plasmonLoss/keV<<" keV"<<G4endl ;
|
||||
|
||||
@@ -1051,12 +1080,14 @@ G4double G4PAIPhotonModel::SampleFluctuations( const G4Material* material,
|
||||
G4double
|
||||
G4PAIPhotonModel::GetAlongStepTransfer( G4PhysicsTable* pTable,
|
||||
G4PhysicsLogVector* pVector,
|
||||
G4int iPlace, G4double scaledTkin,
|
||||
G4int iPlace, G4double scaledTkin,G4double step,
|
||||
G4double cof )
|
||||
{
|
||||
G4int iTkin = iPlace + 1, iTransfer;
|
||||
G4double loss = 0., position, E1, E2, W1, W2, W, dNdxCut1, dNdxCut2, meanNumber;
|
||||
G4long numOfCollisions;
|
||||
G4double lambda, stepDelta, stepSum=0. ;
|
||||
G4long numOfCollisions=0;
|
||||
G4bool numb = true;
|
||||
|
||||
dNdxCut1 = (*pVector)(iPlace) ;
|
||||
|
||||
@@ -1066,7 +1097,16 @@ G4PAIPhotonModel::GetAlongStepTransfer( G4PhysicsTable* pTable,
|
||||
{
|
||||
meanNumber = ((*(*pTable)(iPlace))(0) - dNdxCut1)*cof;
|
||||
if(meanNumber < 0.) meanNumber = 0. ;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
// numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
if( meanNumber > 0.) lambda = step/meanNumber;
|
||||
else lambda = DBL_MAX;
|
||||
while(numb)
|
||||
{
|
||||
stepDelta = RandExponential::shoot(lambda);
|
||||
stepSum += stepDelta;
|
||||
if(stepSum >= step) break;
|
||||
numOfCollisions++;
|
||||
}
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
@@ -1092,7 +1132,16 @@ G4PAIPhotonModel::GetAlongStepTransfer( G4PhysicsTable* pTable,
|
||||
{
|
||||
meanNumber = ((*(*pTable)(iPlace+1))(0) - dNdxCut2)*cof;
|
||||
if( meanNumber < 0. ) meanNumber = 0. ;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
// numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
if( meanNumber > 0.) lambda = step/meanNumber;
|
||||
else lambda = DBL_MAX;
|
||||
while(numb)
|
||||
{
|
||||
stepDelta = RandExponential::shoot(lambda);
|
||||
stepSum += stepDelta;
|
||||
if(stepSum >= step) break;
|
||||
numOfCollisions++;
|
||||
}
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
@@ -1126,16 +1175,25 @@ G4PAIPhotonModel::GetAlongStepTransfer( G4PhysicsTable* pTable,
|
||||
meanNumber=( ((*(*pTable)(iPlace))(0)-dNdxCut1)*W1 +
|
||||
((*(*pTable)(iPlace+1))(0)-dNdxCut2)*W2 )*cof;
|
||||
if(meanNumber<0.0) meanNumber = 0.0;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
// numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
if( meanNumber > 0.) lambda = step/meanNumber;
|
||||
else lambda = DBL_MAX;
|
||||
while(numb)
|
||||
{
|
||||
stepDelta = RandExponential::shoot(lambda);
|
||||
stepSum += stepDelta;
|
||||
if(stepSum >= step) break;
|
||||
numOfCollisions++;
|
||||
}
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position =( (dNdxCut1+
|
||||
((*(*pTable)(iPlace ))(0)-dNdxCut1))*W1 +
|
||||
(dNdxCut2+
|
||||
((*(*pTable)(iPlace+1))(0)-dNdxCut2))*W2 )*G4UniformRand();
|
||||
position = dNdxCut1*W1 + dNdxCut2*W2 +
|
||||
( ( (*(*pTable)(iPlace ))(0) - dNdxCut1)*W1 +
|
||||
|
||||
( (*(*pTable)(iPlace+1))(0) - dNdxCut2)*W2 )*G4UniformRand();
|
||||
|
||||
// G4cout<<position<<"\t" ;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,848 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// File name: G4PAIwithPhotons.cc
|
||||
//
|
||||
// Author: Vladimir.Grichine@cern.ch on base of Vladimir Ivanchenko code
|
||||
//
|
||||
// Creation date: 05.10.2003
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
|
||||
#include "G4Region.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4PhysicsFreeVector.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4SandiaTable.hh"
|
||||
#include "G4PAIxSection.hh"
|
||||
|
||||
#include "G4PAIwithPhotons.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4Timer.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4PAIwithPhotons::G4PAIwithPhotons(const G4ParticleDefinition* p, const G4String& nam)
|
||||
: G4VEmModel(nam),G4VEmFluctuationModel(nam),
|
||||
fLowestKineticEnergy(10.0*keV),
|
||||
fHighestKineticEnergy(100.*TeV),
|
||||
fTotBin(200),
|
||||
fMeanNumber(20),
|
||||
fParticle(0),
|
||||
fHighKinEnergy(100.*TeV),
|
||||
fLowKinEnergy(2.0*MeV),
|
||||
fTwoln10(2.0*log(10.0)),
|
||||
fBg2lim(0.0169),
|
||||
fTaulim(8.4146e-3)
|
||||
{
|
||||
if(p) SetParticle(p);
|
||||
fProtonEnergyVector = new G4PhysicsLogVector(fLowestKineticEnergy,
|
||||
fHighestKineticEnergy,
|
||||
fTotBin);
|
||||
fInitXscPAI = 0;
|
||||
fPAItransferBank = 0;
|
||||
fPAIdEdxTable = 0;
|
||||
fdEdxVector = 0;
|
||||
fLambdaVector = 0;
|
||||
fdNdxCutVector = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4PAIwithPhotons::~G4PAIwithPhotons()
|
||||
{
|
||||
if(fProtonEnergyVector) delete fProtonEnergyVector;
|
||||
if(fInitXscPAI) delete fInitXscPAI;
|
||||
if(fdEdxVector) delete fdEdxVector ;
|
||||
if ( fLambdaVector) delete fLambdaVector;
|
||||
if ( fdNdxCutVector) delete fdNdxCutVector;
|
||||
if( fPAItransferBank )
|
||||
{
|
||||
fPAItransferBank->clearAndDestroy();
|
||||
delete fPAItransferBank ;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void G4PAIwithPhotons::SetParticle(const G4ParticleDefinition* p)
|
||||
{
|
||||
fParticle = p;
|
||||
fMass = fParticle->GetPDGMass();
|
||||
fSpin = fParticle->GetPDGSpin();
|
||||
G4double q = fParticle->GetPDGCharge()/eplus;
|
||||
fChargeSquare = q*q;
|
||||
fLowKinEnergy *= fMass/proton_mass_c2;
|
||||
fRatio = electron_mass_c2/fMass;
|
||||
fQc = fMass/fRatio;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4PAIwithPhotons::HighEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!fParticle) SetParticle(p);
|
||||
return fHighKinEnergy;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4PAIwithPhotons::LowEnergyLimit( const G4ParticleDefinition* p )
|
||||
{
|
||||
if(!fParticle) SetParticle(p);
|
||||
return fLowKinEnergy;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4PAIwithPhotons::MinEnergyCut( const G4ParticleDefinition*,
|
||||
const G4MaterialCutsCouple* couple )
|
||||
{
|
||||
return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4bool G4PAIwithPhotons::IsInCharge( const G4ParticleDefinition* p )
|
||||
{
|
||||
if(!fParticle) SetParticle(p);
|
||||
return (p->GetPDGCharge() != 0.0 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void G4PAIwithPhotons::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector&)
|
||||
{
|
||||
if(!fParticle) SetParticle(p);
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable =
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
G4Timer timer;
|
||||
for(size_t iReg = 0; iReg < fPAIRegionVector.size();++iReg) // region loop
|
||||
{
|
||||
const G4Region* curReg = fPAIRegionVector[iReg];
|
||||
|
||||
// (*fPAIRegionVector[iRegion])
|
||||
|
||||
vector<G4Material*>::const_iterator matIter = curReg->GetMaterialIterator();
|
||||
size_t jMat;
|
||||
size_t numOfMat = curReg->GetNumberOfMaterials();
|
||||
|
||||
|
||||
for(jMat = 0 ; jMat < numOfMat; ++jMat) // region material loop
|
||||
{
|
||||
const G4MaterialCutsCouple* matCouple = theCoupleTable->
|
||||
GetMaterialCutsCouple( *matIter, curReg->GetProductionCuts() );
|
||||
fMaterialCutsCoupleVector.push_back(matCouple);
|
||||
|
||||
fInitXscPAI = new G4InitXscPAI(matCouple);
|
||||
|
||||
timer.Start();
|
||||
|
||||
BuildPAIonisationTable();
|
||||
fPAIxscBank.push_back(fPAItransferBank);
|
||||
fPAIdEdxBank.push_back(fPAIdEdxTable);
|
||||
fdEdxTable.push_back(fdEdxVector);
|
||||
|
||||
BuildLambdaVector(matCouple);
|
||||
fdNdxCutTable.push_back(fdNdxCutVector);
|
||||
fLambdaTable.push_back(fLambdaVector);
|
||||
|
||||
timer.Stop();
|
||||
|
||||
G4cout<<"Initialisation for "<<matCouple->GetMaterial()->GetName()<<" = "
|
||||
<<timer.GetUserElapsed()<<" s " <<"("<<fParticle->GetParticleName()<<")"<<G4endl;
|
||||
matIter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Build tables for the ionization energy loss
|
||||
// the tables are built for MATERIALS
|
||||
// *********
|
||||
|
||||
void
|
||||
G4PAIwithPhotons::BuildPAIonisationTable()
|
||||
{
|
||||
G4double LowEdgeEnergy , ionloss ;
|
||||
G4double massRatio, tau, Tmax, Tmin, Tkin, deltaLow, gamma, bg2 ;
|
||||
/*
|
||||
if( fPAItransferBank )
|
||||
{
|
||||
fPAItransferBank->clearAndDestroy() ;
|
||||
delete fPAItransferBank ;
|
||||
}
|
||||
*/
|
||||
fPAItransferBank = new G4PhysicsTable(fTotBin);
|
||||
/*
|
||||
if( fPAIdEdxTable )
|
||||
{
|
||||
fPAIdEdxTable->clearAndDestroy() ;
|
||||
delete fPAIdEdxTable ;
|
||||
}
|
||||
*/
|
||||
fPAIdEdxTable = new G4PhysicsTable(fTotBin);
|
||||
|
||||
// if(fdEdxVector) delete fdEdxVector ;
|
||||
fdEdxVector = new G4PhysicsLogVector( fLowestKineticEnergy,
|
||||
fHighestKineticEnergy,
|
||||
fTotBin ) ;
|
||||
Tmin = fInitXscPAI->GetMatSandiaMatrix(0,0) ; // low energy Sandia interval
|
||||
deltaLow = 0.5*eV ;
|
||||
|
||||
for (G4int i = 0 ; i < fTotBin ; i++) //The loop for the kinetic energy
|
||||
{
|
||||
LowEdgeEnergy = fProtonEnergyVector->GetLowEdgeEnergy(i) ;
|
||||
tau = LowEdgeEnergy/proton_mass_c2 ;
|
||||
// if(tau < 0.01) tau = 0.01 ;
|
||||
gamma = tau +1. ;
|
||||
// G4cout<<"gamma = "<<gamma<<endl ;
|
||||
bg2 = tau*(tau + 2. ) ;
|
||||
massRatio = electron_mass_c2/proton_mass_c2 ;
|
||||
Tmax = 2.*electron_mass_c2*bg2/(1.+2.*gamma*massRatio+massRatio*massRatio) ;
|
||||
// G4cout<<"proton Tkin = "<<LowEdgeEnergy/MeV<<" MeV"
|
||||
// <<" Tmax = "<<Tmax/MeV<<" MeV"<<G4endl;
|
||||
// Tkin = DeltaCutInKineticEnergyNow ;
|
||||
|
||||
// if ( DeltaCutInKineticEnergyNow > Tmax) // was <
|
||||
{
|
||||
Tkin = Tmax ;
|
||||
}
|
||||
if ( Tkin < Tmin + deltaLow ) // low energy safety
|
||||
{
|
||||
Tkin = Tmin + deltaLow ;
|
||||
}
|
||||
fInitXscPAI->IntegralPAIxSection(bg2,Tkin);
|
||||
fInitXscPAI->IntegralPAIdEdx(bg2,Tkin);
|
||||
fInitXscPAI->IntegralCherenkov(bg2,Tkin);
|
||||
|
||||
|
||||
// G4cout<<"ionloss = "<<ionloss*cm/keV<<" keV/cm"<<endl ;
|
||||
// G4cout<<"n1 = "<<protonPAI.GetIntegralPAIxSection(1)*cm<<" 1/cm"<<endl ;
|
||||
// G4cout<<"protonPAI.GetSplineSize() = "<<
|
||||
// protonPAI.GetSplineSize()<<G4endl<<G4endl ;
|
||||
|
||||
G4PhysicsLogVector* transferVector = fInitXscPAI->GetPAIxscVector();
|
||||
G4PhysicsLogVector* dEdxVector = fInitXscPAI->GetPAIdEdxVector();
|
||||
|
||||
ionloss = (*dEdxVector)(0); // total <dE/dx>
|
||||
if ( ionloss <= 0.) ionloss = DBL_MIN;
|
||||
|
||||
fdEdxVector->PutValue(i,ionloss) ;
|
||||
|
||||
fPAItransferBank->insertAt(i,transferVector) ;
|
||||
fPAIdEdxTable->insertAt(i,dEdxVector) ;
|
||||
|
||||
// delete[] transferVector ;
|
||||
} // end of Tkin loop
|
||||
// theLossTable->insert(fdEdxVector);
|
||||
// end of material loop
|
||||
// G4cout<<"G4PAIonisation::BuildPAIonisationTable() have been called"<<G4endl ;
|
||||
// G4cout<<"G4PAIonisation::BuildLossTable() have been called"<<G4endl ;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Build mean free path tables for the delta ray production process
|
||||
// tables are built for MATERIALS
|
||||
//
|
||||
|
||||
void
|
||||
G4PAIwithPhotons::BuildLambdaVector(const G4MaterialCutsCouple* matCutsCouple)
|
||||
{
|
||||
G4int i ;
|
||||
G4double dNdxCut, lambda;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
size_t jMatCC;
|
||||
|
||||
for (jMatCC = 0 ; jMatCC < numOfCouples ; jMatCC++ )
|
||||
{
|
||||
if( matCutsCouple == theCoupleTable->GetMaterialCutsCouple(jMatCC) ) break;
|
||||
}
|
||||
if( jMatCC == numOfCouples && jMatCC > 0 ) jMatCC--;
|
||||
|
||||
const vector<G4double>* deltaCutInKineticEnergy = theCoupleTable->
|
||||
GetEnergyCutsVector(idxG4ElectronCut);
|
||||
|
||||
if (fLambdaVector) delete fLambdaVector;
|
||||
if (fdNdxCutVector) delete fdNdxCutVector;
|
||||
|
||||
fLambdaVector = new G4PhysicsLogVector( fLowestKineticEnergy,
|
||||
fHighestKineticEnergy,
|
||||
fTotBin ) ;
|
||||
fdNdxCutVector = new G4PhysicsLogVector( fLowestKineticEnergy,
|
||||
fHighestKineticEnergy,
|
||||
fTotBin ) ;
|
||||
G4double deltaCutInKineticEnergyNow = (*deltaCutInKineticEnergy)[jMatCC] ;
|
||||
|
||||
G4cout<<"PAIwithPhotons DeltaCutInKineticEnergyNow = "
|
||||
<<deltaCutInKineticEnergyNow/keV<<" keV"<<G4endl;
|
||||
|
||||
for ( i = 0 ; i < fTotBin ; i++ )
|
||||
{
|
||||
dNdxCut = GetdNdxCut(i,deltaCutInKineticEnergyNow) ;
|
||||
lambda = dNdxCut <= DBL_MIN ? DBL_MAX: 1.0/dNdxCut ;
|
||||
|
||||
if (lambda <= 1000*kCarTolerance) lambda = 1000*kCarTolerance ; // Mmm ???
|
||||
|
||||
fLambdaVector->PutValue(i, lambda) ;
|
||||
fdNdxCutVector->PutValue(i, dNdxCut) ;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns integral PAI cross section for energy transfers >= transferCut
|
||||
|
||||
G4double
|
||||
G4PAIwithPhotons::GetdNdxCut( G4int iPlace, G4double transferCut)
|
||||
{
|
||||
G4int iTransfer;
|
||||
G4double x1, x2, y1, y2, dNdxCut;
|
||||
// G4cout<<"iPlace = "<<iPlace<<"; "<<"transferCut = "<<transferCut<<G4endl;
|
||||
// G4cout<<"size = "<<G4int((*fPAItransferBank)(iPlace)->GetVectorLength())
|
||||
// <<G4endl;
|
||||
for( iTransfer = 0 ;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()) ;
|
||||
iTransfer++)
|
||||
{
|
||||
if(transferCut <= (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer))
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( iTransfer >= G4int((*fPAItransferBank)(iPlace)->GetVectorLength()) )
|
||||
{
|
||||
iTransfer = (*fPAItransferBank)(iPlace)->GetVectorLength() - 1 ;
|
||||
}
|
||||
y1 = (*(*fPAItransferBank)(iPlace))(iTransfer-1) ;
|
||||
y2 = (*(*fPAItransferBank)(iPlace))(iTransfer) ;
|
||||
// G4cout<<"y1 = "<<y1<<"; "<<"y2 = "<<y2<<G4endl;
|
||||
x1 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
|
||||
x2 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
// G4cout<<"x1 = "<<x1<<"; "<<"x2 = "<<x2<<G4endl;
|
||||
|
||||
if ( y1 == y2 ) dNdxCut = y2 ;
|
||||
else
|
||||
{
|
||||
// if ( x1 == x2 ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( fabs(x1-x2) <= eV ) dNdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
else dNdxCut = y1 + (transferCut - x1)*(y2 - y1)/(x2 - x1) ;
|
||||
}
|
||||
// G4cout<<""<<dNdxCut<<G4endl;
|
||||
return dNdxCut ;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns integral dEdx for energy transfers >= transferCut
|
||||
|
||||
G4double
|
||||
G4PAIwithPhotons::GetdEdxCut( G4int iPlace, G4double transferCut)
|
||||
{
|
||||
G4int iTransfer;
|
||||
G4double x1, x2, y1, y2, dEdxCut;
|
||||
// G4cout<<"iPlace = "<<iPlace<<"; "<<"transferCut = "<<transferCut<<G4endl;
|
||||
// G4cout<<"size = "<<G4int((*fPAIdEdxTable)(iPlace)->GetVectorLength())
|
||||
// <<G4endl;
|
||||
for( iTransfer = 0 ;
|
||||
iTransfer < G4int((*fPAIdEdxTable)(iPlace)->GetVectorLength()) ;
|
||||
iTransfer++)
|
||||
{
|
||||
if(transferCut <= (*fPAIdEdxTable)(iPlace)->GetLowEdgeEnergy(iTransfer))
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( iTransfer >= G4int((*fPAIdEdxTable)(iPlace)->GetVectorLength()) )
|
||||
{
|
||||
iTransfer = (*fPAIdEdxTable)(iPlace)->GetVectorLength() - 1 ;
|
||||
}
|
||||
y1 = (*(*fPAIdEdxTable)(iPlace))(iTransfer-1) ;
|
||||
y2 = (*(*fPAIdEdxTable)(iPlace))(iTransfer) ;
|
||||
// G4cout<<"y1 = "<<y1<<"; "<<"y2 = "<<y2<<G4endl;
|
||||
x1 = (*fPAIdEdxTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
|
||||
x2 = (*fPAIdEdxTable)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
// G4cout<<"x1 = "<<x1<<"; "<<"x2 = "<<x2<<G4endl;
|
||||
|
||||
if ( y1 == y2 ) dEdxCut = y2 ;
|
||||
else
|
||||
{
|
||||
// if ( x1 == x2 ) dEdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
if ( fabs(x1-x2) <= eV ) dEdxCut = y1 + (y2 - y1)*G4UniformRand() ;
|
||||
else dEdxCut = y1 + (transferCut - x1)*(y2 - y1)/(x2 - x1) ;
|
||||
}
|
||||
// G4cout<<""<<dEdxCut<<G4endl;
|
||||
return dEdxCut ;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4PAIwithPhotons::ComputeDEDX(const G4MaterialCutsCouple* matCC,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy)
|
||||
{
|
||||
G4int iTkin,iPlace;
|
||||
size_t jMat;
|
||||
G4double scaledTkin = kineticEnergy*p->GetPDGMass()/proton_mass_c2;
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double charge2 = charge*charge, dEdx;
|
||||
|
||||
for( jMat = 0 ;jMat < fMaterialCutsCoupleVector.size() ; ++jMat )
|
||||
{
|
||||
if( matCC == fMaterialCutsCoupleVector[jMat] ) break;
|
||||
}
|
||||
if(jMat == fMaterialCutsCoupleVector.size() && jMat > 0) jMat--;
|
||||
|
||||
fPAIdEdxTable = fPAIdEdxBank[jMat];
|
||||
fdEdxVector = fdEdxTable[jMat];
|
||||
for(iTkin = 0 ; iTkin < fTotBin ; iTkin++)
|
||||
{
|
||||
if(scaledTkin < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
|
||||
}
|
||||
iPlace = iTkin - 1;
|
||||
if(iPlace < 0) iPlace = 0;
|
||||
dEdx = charge2*( (*fdEdxVector)(iPlace) - GetdEdxCut(iPlace,cutEnergy) ) ;
|
||||
|
||||
if( dEdx < 0.) dEdx = 0.;
|
||||
return dEdx;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4PAIwithPhotons::CrossSection( const G4MaterialCutsCouple* matCC,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy )
|
||||
{
|
||||
G4int iTkin,iPlace;
|
||||
size_t jMat;
|
||||
G4double tmax = min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
|
||||
G4double scaledTkin = kineticEnergy*p->GetPDGMass()/proton_mass_c2;
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double charge2 = charge*charge, cross, cross1, cross2;
|
||||
|
||||
for( jMat = 0 ;jMat < fMaterialCutsCoupleVector.size() ; ++jMat )
|
||||
{
|
||||
if( matCC == fMaterialCutsCoupleVector[jMat] ) break;
|
||||
}
|
||||
if(jMat == fMaterialCutsCoupleVector.size() && jMat > 0) jMat--;
|
||||
|
||||
fPAItransferBank = fPAIxscBank[jMat];
|
||||
|
||||
for(iTkin = 0 ; iTkin < fTotBin ; iTkin++)
|
||||
{
|
||||
if(scaledTkin < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
|
||||
}
|
||||
iPlace = iTkin - 1;
|
||||
if(iPlace < 0) iPlace = 0;
|
||||
|
||||
cross1 = GetdNdxCut(iPlace,tmax) ;
|
||||
cross2 = GetdNdxCut(iPlace,cutEnergy) ;
|
||||
cross = (cross2-cross1)*charge2;
|
||||
if( cross < 0.) cross = 0.;
|
||||
return cross;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// It is analog of PostStepDoIt in terms of secondary electron.
|
||||
//
|
||||
|
||||
G4DynamicParticle*
|
||||
G4PAIwithPhotons::SampleSecondary( const G4MaterialCutsCouple* matCC,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
size_t jMat;
|
||||
for( jMat = 0 ;jMat < fMaterialCutsCoupleVector.size() ; ++jMat )
|
||||
{
|
||||
if( matCC == fMaterialCutsCoupleVector[jMat] ) break;
|
||||
}
|
||||
if(jMat == fMaterialCutsCoupleVector.size() && jMat > 0) jMat--;
|
||||
|
||||
fPAItransferBank = fPAIxscBank[jMat];
|
||||
fdNdxCutVector = fdNdxCutTable[jMat];
|
||||
|
||||
G4double tmax = min(MaxSecondaryEnergy(dp), maxEnergy);
|
||||
if( tmin >= tmax ) return 0;
|
||||
G4ThreeVector momentum = dp->GetMomentumDirection();
|
||||
G4double particleMass = dp->GetMass();
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
G4double scaledTkin = kineticEnergy*particleMass/proton_mass_c2;
|
||||
G4double totalEnergy = kineticEnergy + particleMass;
|
||||
G4double pSquare = kineticEnergy*(totalEnergy+particleMass);
|
||||
|
||||
G4double deltaTkin = GetPostStepTransfer(scaledTkin);
|
||||
if( deltaTkin <= 0. ) return 0;
|
||||
G4double deltaTotalMomentum = sqrt(deltaTkin*(deltaTkin + 2. * electron_mass_c2 ));
|
||||
G4double totalMomentum = sqrt(pSquare);
|
||||
G4double costheta = deltaTkin*(totalEnergy + electron_mass_c2)
|
||||
/(deltaTotalMomentum * totalMomentum);
|
||||
if (costheta < 0.) costheta = 0.;
|
||||
if (costheta > +1.) costheta = +1.;
|
||||
|
||||
// direction of the delta electron
|
||||
|
||||
G4double phi = twopi*G4UniformRand();
|
||||
G4double sintheta = sqrt((1.+costheta)*(1.-costheta));
|
||||
G4double dirx = sintheta*cos(phi), diry = sintheta*sin(phi), dirz = costheta;
|
||||
|
||||
G4ThreeVector deltaDirection(dirx,diry,dirz);
|
||||
deltaDirection.rotateUz(momentum);
|
||||
|
||||
// create G4DynamicParticle object for delta ray
|
||||
|
||||
G4DynamicParticle* deltaRay = new G4DynamicParticle;
|
||||
deltaRay->SetDefinition(G4Electron::Electron());
|
||||
deltaRay->SetKineticEnergy( deltaTkin );
|
||||
deltaRay->SetMomentumDirection(deltaDirection);
|
||||
|
||||
return deltaRay;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns post step PAI energy transfer > cut electron energy according to passed
|
||||
// scaled kinetic energy of particle
|
||||
|
||||
G4double
|
||||
G4PAIwithPhotons::GetPostStepTransfer( G4double scaledTkin )
|
||||
{
|
||||
// G4cout<<"G4PAIwithPhotons::GetPostStepTransfer"<<G4endl ;
|
||||
|
||||
G4int iTkin, iTransfer, iPlace ;
|
||||
G4double transfer = 0.0, position, dNdxCut1, dNdxCut2, E1, E2, W1, W2, W ;
|
||||
|
||||
for(iTkin=0;iTkin<fTotBin;iTkin++)
|
||||
{
|
||||
if(scaledTkin < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
|
||||
}
|
||||
iPlace = iTkin - 1 ;
|
||||
if(iPlace < 0) iPlace = 0;
|
||||
dNdxCut1 = (*fdNdxCutVector)(iPlace) ;
|
||||
|
||||
// G4cout<<"iPlace = "<<iPlace<<endl ;
|
||||
|
||||
if(iTkin == fTotBin) // Fermi plato, try from left
|
||||
{
|
||||
position = dNdxCut1*G4UniformRand() ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace))(iTransfer)) break ;
|
||||
}
|
||||
transfer = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
dNdxCut2 = (*fdNdxCutVector)(iPlace+1) ;
|
||||
if(iTkin == 0) // Tkin is too small, trying from right only
|
||||
{
|
||||
position = dNdxCut2*G4UniformRand() ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace+1)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace+1))(iTransfer)) break ;
|
||||
}
|
||||
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 = ( dNdxCut1*W1 + dNdxCut2*W2 )*G4UniformRand() ;
|
||||
|
||||
// G4cout<<position<<"\t" ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if( position >=
|
||||
( (*(*fPAItransferBank)(iPlace))(iTransfer)*W1 +
|
||||
(*(*fPAItransferBank)(iPlace+1))(iTransfer)*W2) ) break ;
|
||||
}
|
||||
transfer = GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
}
|
||||
}
|
||||
// G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"<<endl ;
|
||||
if(transfer < 0.0 ) transfer = 0.0 ;
|
||||
return transfer ;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns random PAI energy transfer according to passed
|
||||
// indexes of particle kinetic
|
||||
|
||||
G4double
|
||||
G4PAIwithPhotons::GetEnergyTransfer( G4int iPlace, G4double position, G4int iTransfer )
|
||||
{
|
||||
G4double x1, x2, y1, y2, energyTransfer ;
|
||||
|
||||
if(iTransfer == 0)
|
||||
{
|
||||
energyTransfer = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( iTransfer >= G4int((*fPAItransferBank)(iPlace)->GetVectorLength()) )
|
||||
{
|
||||
iTransfer = (*fPAItransferBank)(iPlace)->GetVectorLength() - 1 ;
|
||||
}
|
||||
y1 = (*(*fPAItransferBank)(iPlace))(iTransfer-1) ;
|
||||
y2 = (*(*fPAItransferBank)(iPlace))(iTransfer) ;
|
||||
|
||||
x1 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
|
||||
x2 = (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
|
||||
if ( x1 == x2 ) energyTransfer = x2 ;
|
||||
else
|
||||
{
|
||||
if ( y1 == y2 ) energyTransfer = x1 + (x2 - x1)*G4UniformRand() ;
|
||||
else
|
||||
{
|
||||
energyTransfer = x1 + (position - y1)*(x2 - x1)/(y2 - y1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return energyTransfer ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
vector<G4DynamicParticle*>*
|
||||
G4PAIwithPhotons::SampleSecondaries( const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
vector<G4DynamicParticle*>* vdp = new vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
return vdp;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
G4double G4PAIwithPhotons::SampleFluctuations( const G4Material* material,
|
||||
const G4DynamicParticle* aParticle,
|
||||
G4double&,
|
||||
G4double& step,
|
||||
G4double&)
|
||||
{
|
||||
size_t jMat;
|
||||
for( jMat = 0 ;jMat < fMaterialCutsCoupleVector.size() ; ++jMat )
|
||||
{
|
||||
if( material == fMaterialCutsCoupleVector[jMat]->GetMaterial() ) break;
|
||||
}
|
||||
if(jMat == fMaterialCutsCoupleVector.size() && jMat > 0) jMat--;
|
||||
|
||||
fPAItransferBank = fPAIxscBank[jMat];
|
||||
fdNdxCutVector = fdNdxCutTable[jMat];
|
||||
|
||||
G4int iTkin, iTransfer, iPlace ;
|
||||
G4long numOfCollisions;
|
||||
|
||||
// G4cout<<"G4PAIwithPhotons::SampleFluctuations"<<G4endl ;
|
||||
|
||||
G4double loss = 0.0, charge2 ;
|
||||
|
||||
G4double position, E1, E2, W1, W2, W, dNdxCut1, dNdxCut2, meanNumber;
|
||||
|
||||
G4double Tkin = aParticle->GetKineticEnergy() ;
|
||||
G4double MassRatio = proton_mass_c2/aParticle->GetDefinition()->GetPDGMass() ;
|
||||
G4double charge = aParticle->GetDefinition()->GetPDGCharge() ;
|
||||
charge2 = charge*charge ;
|
||||
G4double TkinScaled = Tkin*MassRatio ;
|
||||
|
||||
for(iTkin=0;iTkin<fTotBin;iTkin++)
|
||||
{
|
||||
if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
|
||||
}
|
||||
iPlace = iTkin - 1 ;
|
||||
dNdxCut1 = (*fdNdxCutVector)(iPlace) ;
|
||||
|
||||
// G4cout<<"iPlace = "<<iPlace<<endl ;
|
||||
|
||||
if(iTkin == fTotBin) // Fermi plato, try from left
|
||||
{
|
||||
meanNumber =((*(*fPAItransferBank)(iPlace))(0)-dNdxCut1)*step*charge2;
|
||||
if(meanNumber < 0.) meanNumber = 0. ;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position = dNdxCut1+
|
||||
((*(*fPAItransferBank)(iPlace))(0)-dNdxCut1)*G4UniformRand() ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace))(iTransfer)) break ;
|
||||
}
|
||||
loss += GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dNdxCut2 = (*fdNdxCutVector)(iPlace+1) ;
|
||||
|
||||
if(iTkin == 0) // Tkin is too small, trying from right only
|
||||
{
|
||||
meanNumber =((*(*fPAItransferBank)(iPlace+1))(0)-dNdxCut2)*step*charge2;
|
||||
if( meanNumber < 0. ) meanNumber = 0. ;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position = dNdxCut2+
|
||||
((*(*fPAItransferBank)(iPlace+1))(0)-dNdxCut2)*G4UniformRand();
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace+1)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if(position >= (*(*fPAItransferBank)(iPlace+1))(iTransfer)) break ;
|
||||
}
|
||||
loss += GetEnergyTransfer(iPlace+1,position,iTransfer);
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
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 - TkinScaled)*W ;
|
||||
W2 = (TkinScaled - E1)*W ;
|
||||
|
||||
// G4cout<<"(*(*fPAItransferBank)(iPlace))(0) = "<<
|
||||
// (*(*fPAItransferBank)(iPlace))(0)<<G4endl ;
|
||||
// G4cout<<"(*(*fPAItransferBank)(iPlace+1))(0) = "<<
|
||||
// (*(*fPAItransferBank)(iPlace+1))(0)<<G4endl ;
|
||||
|
||||
meanNumber=( ((*(*fPAItransferBank)(iPlace))(0)-dNdxCut1)*W1 +
|
||||
((*(*fPAItransferBank)(iPlace+1))(0)-dNdxCut2)*W2 )*step*charge2;
|
||||
if(meanNumber<0.0) meanNumber = 0.0;
|
||||
numOfCollisions = RandPoisson::shoot(meanNumber) ;
|
||||
|
||||
// G4cout<<"numOfCollisions = "<<numOfCollisions<<endl ;
|
||||
|
||||
while(numOfCollisions)
|
||||
{
|
||||
position =( (dNdxCut1+
|
||||
((*(*fPAItransferBank)(iPlace ))(0)-dNdxCut1))*W1 +
|
||||
(dNdxCut2+
|
||||
((*(*fPAItransferBank)(iPlace+1))(0)-dNdxCut2))*W2 )*G4UniformRand();
|
||||
|
||||
// G4cout<<position<<"\t" ;
|
||||
|
||||
for( iTransfer = 0;
|
||||
iTransfer < G4int((*fPAItransferBank)(iPlace)->GetVectorLength()); iTransfer++ )
|
||||
{
|
||||
if( position >=
|
||||
( (*(*fPAItransferBank)(iPlace))(iTransfer)*W1 +
|
||||
(*(*fPAItransferBank)(iPlace+1))(iTransfer)*W2) )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
// loss += (*fPAItransferBank)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
|
||||
loss += GetEnergyTransfer(iPlace,position,iTransfer);
|
||||
numOfCollisions-- ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// G4cout<<"PAIwithPhotons AlongStepLoss = "<<loss/keV<<" keV"<<endl ;
|
||||
|
||||
return loss ;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Returns the statistical estimation of the energy loss distribution variance
|
||||
//
|
||||
|
||||
|
||||
G4double G4PAIwithPhotons::Dispersion( const G4Material* material,
|
||||
const G4DynamicParticle* aParticle,
|
||||
G4double& tmax,
|
||||
G4double& step )
|
||||
{
|
||||
G4double loss, sumLoss=0., sumLoss2=0., sigma2, meanLoss=0.;
|
||||
for(G4int i = 0 ; i < fMeanNumber; i++)
|
||||
{
|
||||
loss = SampleFluctuations(material,aParticle,tmax,step,meanLoss);
|
||||
sumLoss += loss;
|
||||
sumLoss2 += loss*loss;
|
||||
}
|
||||
meanLoss = sumLoss/fMeanNumber;
|
||||
sigma2 = meanLoss*meanLoss + (sumLoss2-2*sumLoss*meanLoss)/fMeanNumber;
|
||||
return sigma2;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4PAIxSection.cc,v 1.19 2004/06/07 07:33:21 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-06-02 $
|
||||
// $Id: G4PAIxSection.cc,v 1.20 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//
|
||||
// G4PAIxSection.cc -- class implementation file
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4SandiaTable.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* ******************************************************************
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4PhotoElectricEffect.cc,v 1.30 2004/03/10 16:48:46 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-01 $
|
||||
// $Id: G4PhotoElectricEffect.cc,v 1.33 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// constructor
|
||||
using namespace std;
|
||||
|
||||
G4PhotoElectricEffect::G4PhotoElectricEffect(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type),
|
||||
@@ -83,6 +83,14 @@ G4PhotoElectricEffect::~G4PhotoElectricEffect()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline G4bool G4PhotoElectricEffect::IsApplicable(const G4ParticleDefinition&
|
||||
particle)
|
||||
{
|
||||
return ( &particle == G4Gamma::Gamma() );
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4PhotoElectricEffect::ComputeCrossSectionPerAtom(G4double GammaEnergy,
|
||||
G4double AtomicNumber)
|
||||
|
||||
@@ -119,6 +127,29 @@ G4double G4PhotoElectricEffect::ComputeMeanFreePath(G4double GammaEnergy,
|
||||
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
inline G4double G4PhotoElectricEffect::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double,
|
||||
G4ForceCondition*)
|
||||
|
||||
// returns the gamma mean free path in GEANT4 internal units
|
||||
{
|
||||
G4double GammaEnergy = aTrack.GetDynamicParticle()->GetKineticEnergy();
|
||||
G4double* SandiaCof = aTrack.GetMaterial()->GetSandiaTable()
|
||||
->GetSandiaCofForMaterial(GammaEnergy);
|
||||
|
||||
G4double energy2 = GammaEnergy*GammaEnergy, energy3 = GammaEnergy*energy2,
|
||||
energy4 = energy2*energy2;
|
||||
|
||||
|
||||
G4double SIGMA = SandiaCof[0]/GammaEnergy + SandiaCof[1]/energy2 +
|
||||
SandiaCof[2]/energy3 + SandiaCof[3]/energy4;
|
||||
|
||||
MeanFreePath = SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
return MeanFreePath;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VParticleChange* G4PhotoElectricEffect::PostStepDoIt(const G4Track& aTrack,
|
||||
@@ -177,9 +208,9 @@ G4VParticleChange* G4PhotoElectricEffect::PostStepDoIt(const G4Track& aTrack,
|
||||
//
|
||||
// Kill the incident photon
|
||||
//
|
||||
aParticleChange.SetLocalEnergyDeposit(PhotonEnergy-ElecKineEnergy);
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(PhotonEnergy-ElecKineEnergy);
|
||||
aParticleChange.ProposeEnergy(0.);
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4PolarizedComptonScattering.cc,v 1.10 2003/05/26 16:13:14 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-02-patch-01 $
|
||||
// $Id: G4PolarizedComptonScattering.cc,v 1.12 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//
|
||||
//---------- G4PolarizedComptonScattering physics process ----------------------
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// constructor
|
||||
using namespace std;
|
||||
|
||||
G4PolarizedComptonScattering::G4PolarizedComptonScattering(
|
||||
const G4String& processName)
|
||||
@@ -69,7 +69,7 @@ G4VParticleChange* G4PolarizedComptonScattering::PostStepDoIt(
|
||||
|
||||
G4ThreeVector GammaPolarization0 = aDynamicGamma->GetPolarization();
|
||||
|
||||
if (abs(GammaPolarization0.mag() - 1.e0) > 1.e-14)
|
||||
if (fabs(GammaPolarization0.mag() - 1.e0) > 1.e-14)
|
||||
G4ComptonScattering::PostStepDoIt(aTrack,aStep);
|
||||
|
||||
G4double GammaEnergy0 = aDynamicGamma->GetKineticEnergy();
|
||||
@@ -106,7 +106,7 @@ G4VParticleChange* G4PolarizedComptonScattering::PostStepDoIt(
|
||||
G4double Rand = G4UniformRand();
|
||||
|
||||
int j = 0;
|
||||
while ((j < 100) && (abs(SetPhi(epsilon,sint2,middle,Rand)) > resolution))
|
||||
while ((j < 100) && (fabs(SetPhi(epsilon,sint2,middle,Rand)) > resolution))
|
||||
{
|
||||
middle = (maximum + minimum)/2;
|
||||
if (SetPhi(epsilon,sint2,middle,Rand)*
|
||||
@@ -143,13 +143,13 @@ G4VParticleChange* G4PolarizedComptonScattering::PostStepDoIt(
|
||||
|
||||
if (GammaEnergy1 > fminimalEnergy)
|
||||
{
|
||||
aParticleChange.SetEnergyChange(GammaEnergy1);
|
||||
aParticleChange.ProposeEnergy(GammaEnergy1);
|
||||
}
|
||||
else
|
||||
{
|
||||
localEnergyDeposit += GammaEnergy1;
|
||||
aParticleChange.SetEnergyChange(0.) ;
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.ProposeEnergy(0.) ;
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -177,7 +177,7 @@ G4VParticleChange* G4PolarizedComptonScattering::PostStepDoIt(
|
||||
localEnergyDeposit += ElecKineEnergy;
|
||||
}
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit (localEnergyDeposit);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(localEnergyDeposit);
|
||||
|
||||
// Reset NbOfInteractionLengthLeft and return aParticleChange
|
||||
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
|
||||
@@ -271,12 +271,12 @@ void G4PolarizedComptonScattering::SystemOfRefChange(G4ThreeVector& Direction0,
|
||||
Direction1.rotateZ(Psi);
|
||||
//
|
||||
Direction1.rotateUz(Direction0);
|
||||
aParticleChange.SetMomentumChange(Direction1);
|
||||
aParticleChange.ProposeMomentumDirection(Direction1);
|
||||
|
||||
// 3 Euler angles rotation for scattered photon polarization
|
||||
Polarization1.rotateZ(Psi);
|
||||
Polarization1.rotateUz(Direction0);
|
||||
aParticleChange.SetPolarizationChange(Polarization1);
|
||||
aParticleChange.ProposePolarization(Polarization1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4SCProcessorStand.cc,v 1.2 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4SCProcessorStand
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 10.05.2002
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 09-12-02 remove warning (V.Ivanchenko)
|
||||
// 23-12-02 change interface in order to move to cut per region (V.Ivanchenko)
|
||||
// 26-12-02 Secondary production moved to derived classes (V.Ivanchenko)
|
||||
// 27-01-03 Make models region aware (V.Ivanchenko)
|
||||
// 13-02-03 Add name (V.Ivanchenko)
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4SCProcessorStand.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4EmModelManager.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Step.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4SCProcessorStand::G4SCProcessorStand(const G4String& nam)
|
||||
: G4VSubCutoffProcessor(nam),
|
||||
theLambdaSubTable(0),
|
||||
thePositron(G4Positron::Positron())
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4SCProcessorStand::~G4SCProcessorStand()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4SCProcessorStand::Initialise(const G4ParticleDefinition* p,
|
||||
const G4ParticleDefinition* sp,
|
||||
const G4DataVector* vCuts,
|
||||
const G4DataVector* vSubCuts)
|
||||
{
|
||||
particle = p;
|
||||
secondaryParticle = sp;
|
||||
navigator = (G4TransportationManager::GetTransportationManager())
|
||||
->GetNavigatorForTracking();
|
||||
theCuts = vCuts;
|
||||
theSubCuts = vSubCuts;
|
||||
initialMass= particle->GetPDGMass();
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
vector<G4Track*>* G4SCProcessorStand::SampleSecondaries(
|
||||
const G4Step& step,
|
||||
G4double& tmax,
|
||||
G4double& meanLoss,
|
||||
G4VEmModel* currentModel)
|
||||
{
|
||||
G4bool b;
|
||||
const G4Track* track = step.GetTrack();
|
||||
const G4MaterialCutsCouple* couple = track->GetMaterialCutsCouple();
|
||||
|
||||
size_t index = couple->GetIndex();
|
||||
G4double subcut = (*theSubCuts)[index];
|
||||
|
||||
if(subcut >= tmax) return 0;
|
||||
|
||||
G4double cut = (*theCuts)[index];
|
||||
G4double rcut = couple->GetProductionCuts()->GetProductionCut(1);
|
||||
|
||||
|
||||
const G4DynamicParticle* dp = track->GetDynamicParticle();
|
||||
G4double ekin = dp->GetKineticEnergy();
|
||||
G4double effChargeFactor = 1.0;
|
||||
G4double massRatio = 1.0;
|
||||
G4double mass = initialMass;
|
||||
|
||||
if(dp->GetDefinition() != particle) {
|
||||
mass = dp->GetMass();
|
||||
massRatio = initialMass/mass;
|
||||
G4double q = particle->GetPDGCharge()/dp->GetCharge();
|
||||
effChargeFactor = q*q;
|
||||
}
|
||||
|
||||
G4double cross = (*theLambdaSubTable)[index]->GetValue(ekin*massRatio, b);
|
||||
|
||||
if(0.0 >= cross) return 0;
|
||||
|
||||
G4StepPoint* pre = step.GetPreStepPoint();
|
||||
G4double presafety = pre->GetSafety();
|
||||
G4ThreeVector postpoint = step.GetPostStepPoint()->GetPosition();
|
||||
G4double postsafety = navigator->ComputeSafety(postpoint);
|
||||
G4double safety = min(presafety,postsafety);
|
||||
if(safety >= rcut) return 0;
|
||||
|
||||
|
||||
G4ThreeVector prepoint = pre->GetPosition();
|
||||
G4ThreeVector dr = postpoint - prepoint;
|
||||
G4double pretime = step.GetPreStepPoint()->GetGlobalTime();
|
||||
G4double fragment = 0.0;
|
||||
G4double dt = 0.0;
|
||||
G4double length = step.GetStepLength();
|
||||
G4double inv_v = (ekin + mass)/(c_light*dp->GetTotalMomentum());
|
||||
|
||||
vector<G4Track*>* vtr = new vector<G4Track*>;
|
||||
|
||||
do {
|
||||
|
||||
G4double del = G4UniformRand()*effChargeFactor / cross;
|
||||
fragment += del/length;
|
||||
if (fragment > 1.0) break;
|
||||
|
||||
dt += del * inv_v;
|
||||
vector<G4DynamicParticle*>* newp =
|
||||
currentModel->SampleSecondaries(couple, dp, subcut, cut);
|
||||
if (newp) {
|
||||
|
||||
G4DynamicParticle* p;
|
||||
G4int nNew = newp->size();
|
||||
for (G4int i=0; i<nNew; i++) {
|
||||
|
||||
p = (*newp)[i];
|
||||
G4double e = p->GetKineticEnergy();
|
||||
if (p->GetDefinition() == thePositron) e += electron_mass_c2;
|
||||
|
||||
if (e <= meanLoss) {
|
||||
meanLoss -= e;
|
||||
G4Track* t = new G4Track(p, pretime + dt, prepoint + fragment*dr);
|
||||
vtr->push_back(t);
|
||||
|
||||
} else {
|
||||
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (fragment < 1.0);
|
||||
|
||||
return vtr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4SynchrotronRadiation.cc,v 1.10 2004/06/07 13:49:52 gcosmo Exp $
|
||||
// GEANT4 tag $Name: geant4-06-02 $
|
||||
// $Id: G4SynchrotronRadiation.cc,v 1.12 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
@@ -44,6 +44,8 @@
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4SynchrotronRadiation::G4SynchrotronRadiation(const G4String& processName,
|
||||
G4ProcessType type):G4VDiscreteProcess (processName, type),
|
||||
@@ -256,22 +258,22 @@ G4SynchrotronRadiation::PostStepDoIt(const G4Track& trackData,
|
||||
|
||||
if (newKinEnergy > 0.)
|
||||
{
|
||||
aParticleChange.SetMomentumChange( particleDirection );
|
||||
aParticleChange.SetEnergyChange( newKinEnergy );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
aParticleChange.ProposeMomentumDirection( particleDirection );
|
||||
aParticleChange.ProposeEnergy( newKinEnergy );
|
||||
aParticleChange.ProposeLocalEnergyDeposit (0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetEnergyChange( 0. );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
aParticleChange.ProposeEnergy( 0. );
|
||||
aParticleChange.ProposeLocalEnergyDeposit (0.);
|
||||
G4double charge = aDynamicParticle->GetDefinition()->GetPDGCharge();
|
||||
if (charge<0.)
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopAndKill) ;
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetStatusChange(fStopButAlive) ;
|
||||
aParticleChange.ProposeTrackStatus(fStopButAlive) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4UniversalFluctuation.cc,v 1.2 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4UniversalFluctuation
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 03.01.2002
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 28-12-02 add method Dispersion (V.Ivanchenko)
|
||||
// 07-02-03 change signature (V.Ivanchenko)
|
||||
// 13-02-03 Add name (V.Ivanchenko)
|
||||
// 16-10-03 Changed interface to Initialisation (V.Ivanchenko)
|
||||
// 07-11-03 Fix problem of rounding of double in G4UniversalFluctuations
|
||||
// 06-02-04 Add control on big sigma > 2*meanLoss (V.Ivanchenko)
|
||||
// 26-04-04 Comment out the case of very small step (V.Ivanchenko)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4UniversalFluctuation.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Poisson.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4DynamicParticle.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4UniversalFluctuation::G4UniversalFluctuation(const G4String& nam)
|
||||
:G4VEmFluctuationModel(nam),
|
||||
particle(0),
|
||||
minNumberInteractionsBohr(10.0),
|
||||
theBohrBeta2(50.0*keV/proton_mass_c2),
|
||||
minLoss(0.001*eV),
|
||||
sumalim(0.01),
|
||||
alim(10.),
|
||||
nmaxCont1(4.),
|
||||
nmaxCont2(16.)
|
||||
{
|
||||
lastMaterial = 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4UniversalFluctuation::~G4UniversalFluctuation()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4UniversalFluctuation::InitialiseMe(const G4ParticleDefinition* part)
|
||||
{
|
||||
particle = part;
|
||||
particleMass = part->GetPDGMass();
|
||||
G4double q = part->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length,
|
||||
G4double& meanLoss)
|
||||
{
|
||||
// calculate actual loss from the mean loss
|
||||
// The model used to get the fluctuation is essentially the same
|
||||
// as in Glandz in Geant3.
|
||||
// G4cout << "### Mean loss= " << meanLoss << G4endl;
|
||||
|
||||
// shortcut for very very small loss
|
||||
if(meanLoss < minLoss) return meanLoss;
|
||||
|
||||
if(!particle) InitialiseMe(dp->GetDefinition());
|
||||
|
||||
ipotFluct = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
|
||||
G4double tau = dp->GetKineticEnergy()/particleMass;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gam2 = gam*gam;
|
||||
G4double beta2 = tau*(tau + 2.0)/gam2;
|
||||
|
||||
// Validity range for delta electron cross section
|
||||
G4double loss, siga;
|
||||
// G4cout << "tmax= " << tmax << " kappa= " << minNumberInteractionsBohr << " l= " << length << G4endl;
|
||||
// Gaussian fluctuation
|
||||
// if(meanLoss >= minNumberInteractionsBohr*tmax || tmax <= ipotFluct*minNumberInteractionsBohr)
|
||||
if(meanLoss >= minNumberInteractionsBohr*tmax)
|
||||
{
|
||||
electronDensity = material->GetElectronDensity();
|
||||
siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
|
||||
* electronDensity * chargeSquare ;
|
||||
siga = sqrt(siga);
|
||||
G4double twomeanLoss = meanLoss + meanLoss;
|
||||
if(twomeanLoss < siga) {
|
||||
G4double x;
|
||||
do {
|
||||
loss = twomeanLoss*G4UniformRand();
|
||||
x = (loss - meanLoss)/siga;
|
||||
} while (1.0 - 0.5*x*x < G4UniformRand());
|
||||
} else {
|
||||
do {
|
||||
loss = G4RandGauss::shoot(meanLoss,siga);
|
||||
} while (loss < 0. || loss > twomeanLoss);
|
||||
}
|
||||
//G4cout << "### meanLoss= " << meanLoss << " fluc= " << loss-meanLoss << " sig= " << siga << G4endl;
|
||||
|
||||
return loss;
|
||||
}
|
||||
|
||||
// Non Gaussian fluctuation
|
||||
|
||||
if(material != lastMaterial) {
|
||||
f1Fluct = material->GetIonisation()->GetF1fluct();
|
||||
f2Fluct = material->GetIonisation()->GetF2fluct();
|
||||
e1Fluct = material->GetIonisation()->GetEnergy1fluct();
|
||||
e2Fluct = material->GetIonisation()->GetEnergy2fluct();
|
||||
e1LogFluct = material->GetIonisation()->GetLogEnergy1fluct();
|
||||
e2LogFluct = material->GetIonisation()->GetLogEnergy2fluct();
|
||||
rateFluct = material->GetIonisation()->GetRateionexcfluct();
|
||||
ipotLogFluct = material->GetIonisation()->GetLogMeanExcEnergy();
|
||||
lastMaterial = material;
|
||||
}
|
||||
|
||||
G4double p1,p2,p3;
|
||||
|
||||
G4double w1 = tmax/ipotFluct;
|
||||
G4double w2 = log(2.*electron_mass_c2*beta2*gam2);
|
||||
|
||||
G4double C = meanLoss*(1.-rateFluct)/(w2-ipotLogFluct-beta2);
|
||||
|
||||
G4double a1 = C*f1Fluct*(w2-e1LogFluct-beta2)/e1Fluct;
|
||||
G4double a2 = C*f2Fluct*(w2-e2LogFluct-beta2)/e2Fluct;
|
||||
G4double a3 = rateFluct*meanLoss*(tmax-ipotFluct)/(ipotFluct*tmax*log(w1));
|
||||
if(a1 < 0.) a1 = 0.;
|
||||
if(a2 < 0.) a2 = 0.;
|
||||
if(a3 < 0.) a3 = 0.;
|
||||
|
||||
G4double suma = a1+a2+a3;
|
||||
loss = 0. ;
|
||||
|
||||
if(suma < sumalim) // very small Step
|
||||
{
|
||||
//G4cout << "A very small step" << G4endl;
|
||||
G4double e0 = material->GetIonisation()->GetEnergy0fluct();
|
||||
|
||||
if(tmax == ipotFluct)
|
||||
{
|
||||
a3 = meanLoss/e0;
|
||||
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = max(0.,G4RandGauss::shoot(a3,siga)+0.5);
|
||||
} else {
|
||||
p3 = G4double(G4Poisson(a3));
|
||||
}
|
||||
loss = p3*e0 ;
|
||||
|
||||
if(p3 > 0.) loss += (1.-2.*G4UniformRand())*e0 ;
|
||||
|
||||
} else {
|
||||
tmax = tmax-ipotFluct+e0 ;
|
||||
a3 = meanLoss*(tmax-e0)/(tmax*e0*log(tmax/e0));
|
||||
|
||||
if(a3>alim)
|
||||
{
|
||||
siga=sqrt(a3) ;
|
||||
p3 = max(0.,G4RandGauss::shoot(a3,siga)+0.5);
|
||||
} else {
|
||||
p3 = G4double(G4Poisson(a3));
|
||||
}
|
||||
if(p3 > 0.) {
|
||||
G4double w = (tmax-e0)/tmax ;
|
||||
G4double corrfac = 1. ;
|
||||
if(p3 > nmaxCont2) {
|
||||
corrfac = p3/nmaxCont2 ;
|
||||
p3 = nmaxCont2 ;
|
||||
}
|
||||
G4int ip3 = (G4int)p3;
|
||||
for(G4int i=0; i<ip3; i++) {
|
||||
loss += 1./(1.-w*G4UniformRand()) ;
|
||||
}
|
||||
loss *= e0*corrfac ;
|
||||
}
|
||||
}
|
||||
// Not so small Step
|
||||
} else {
|
||||
//G4cout << "Excitation alim= " << alim << " a1= " << a1 << " a2= " << a2 << G4endl;
|
||||
// excitation type 1
|
||||
if(a1>alim) {
|
||||
siga=sqrt(a1) ;
|
||||
p1 = max(0.,G4RandGauss::shoot(a1,siga)+0.5);
|
||||
} else {
|
||||
p1 = G4double(G4Poisson(a1));
|
||||
}
|
||||
// excitation type 2
|
||||
if(a2>alim) {
|
||||
siga=sqrt(a2) ;
|
||||
p2 = max(0.,G4RandGauss::shoot(a2,siga)+0.5);
|
||||
} else {
|
||||
p2 = G4double(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;
|
||||
if(loss < 0.) loss = 0.0;
|
||||
|
||||
// ionisation
|
||||
if(a3 > 0.) {
|
||||
if(a3>alim) {
|
||||
siga=sqrt(a3) ;
|
||||
p3 = max(0.,G4RandGauss::shoot(a3,siga)+0.5);
|
||||
} else {
|
||||
p3 = G4double(G4Poisson(a3));
|
||||
}
|
||||
G4double lossc = 0.;
|
||||
if(p3 > 0) {
|
||||
G4double na = 0.;
|
||||
G4double alfa = 1.;
|
||||
if (p3 > nmaxCont2) {
|
||||
G4double rfac = p3/(nmaxCont2+p3);
|
||||
G4double namean = p3*rfac;
|
||||
G4double sa = nmaxCont1*rfac;
|
||||
na = G4RandGauss::shoot(namean,sa);
|
||||
if (na > 0.) {
|
||||
alfa = w1*(nmaxCont2+p3)/(w1*nmaxCont2+p3);
|
||||
G4double alfa1 = alfa*log(alfa)/(alfa-1.);
|
||||
G4double ea = na*ipotFluct*alfa1;
|
||||
G4double sea = ipotFluct*sqrt(na*(alfa-alfa1*alfa1));
|
||||
lossc += G4RandGauss::shoot(ea,sea);
|
||||
}
|
||||
}
|
||||
|
||||
if (p3 > na) {
|
||||
w2 = alfa*ipotFluct;
|
||||
G4double w = (tmax-w2)/tmax;
|
||||
G4int nb = G4int(p3-na);
|
||||
for (G4int k=0; k<nb; k++) {
|
||||
lossc += w2/(1.-w*G4UniformRand());
|
||||
}
|
||||
}
|
||||
}
|
||||
loss += lossc;
|
||||
}
|
||||
}
|
||||
//G4cout << "### Final loss= " << loss << G4endl;
|
||||
return loss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4double G4UniversalFluctuation::Dispersion(
|
||||
const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length)
|
||||
{
|
||||
if(!particle) InitialiseMe(dp->GetDefinition());
|
||||
|
||||
electronDensity = material->GetElectronDensity();
|
||||
|
||||
G4double gam = (dp->GetKineticEnergy())/particleMass + 1.0;
|
||||
G4double beta2 = 1.0 - 1.0/(gam*gam);
|
||||
|
||||
G4double siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
|
||||
* electronDensity * chargeSquare;
|
||||
|
||||
return siga;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -1,391 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * This code implementation is the intellectual property of the *
|
||||
// * GEANT4 collaboration. *
|
||||
// * By copying, distributing or modifying the Program (or any work *
|
||||
// * based on the Program) you indicate your acceptance of this *
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VPAIenergyLoss.cc,v 1.7 2003/03/10 12:22:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-02-patch-01 $
|
||||
//
|
||||
// -----------------------------------------------------------
|
||||
// GEANT 4 class implementation file
|
||||
//
|
||||
// History: based on object model of
|
||||
// 2nd December 1995, G.Cosmo
|
||||
// ---------- G4VPAIenergyLoss physics process -----------
|
||||
// by V. Grichine, 30 Nov 1997
|
||||
// **************************************************************
|
||||
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
|
||||
// It calculates the energy loss of charged hadrons.
|
||||
// **************************************************************
|
||||
//
|
||||
// corrected by V. Grichine on 24/11/97
|
||||
// corrected by L. Urban on 27/05/98 ( other corrections come soon!)
|
||||
// 10/02/00 modifications , new e.m. structure, L.Urban
|
||||
// 02/03/00 initialisation of theDEDXTable
|
||||
// 17-09-01, migration of Materials to pure STL (mma)
|
||||
// 10-03-03 remove tails of old cuts (V.Ivanchenko)
|
||||
//
|
||||
|
||||
|
||||
#include "G4VPAIenergyLoss.hh"
|
||||
#include "G4PAIonisation.hh"
|
||||
#include "G4EnergyLossTables.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialisation of static members
|
||||
|
||||
G4int G4VPAIenergyLoss::NbOfProcesses = 1 ;
|
||||
G4PhysicsTable** G4VPAIenergyLoss::RecorderOfpProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
G4int G4VPAIenergyLoss::CounterOfpProcess = 0 ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theDEDXpTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theRangepTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theInverseRangepTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theLabTimepTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theProperTimepTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepRangeCoeffCTable = NULL ;
|
||||
|
||||
G4PhysicsTable** G4VPAIenergyLoss::RecorderOfpbarProcess =
|
||||
new G4PhysicsTable*[10] ;
|
||||
G4int G4VPAIenergyLoss::CounterOfpbarProcess = 0 ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theDEDXpbarTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theInverseRangepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theLabTimepbarTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theProperTimepbarTable = NULL ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepbarRangeCoeffATable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepbarRangeCoeffBTable = NULL ;
|
||||
G4PhysicsTable* G4VPAIenergyLoss::thepbarRangeCoeffCTable = NULL ;
|
||||
|
||||
// G4PhysicsTable* G4VPAIenergyLoss::fPAItransferBank = NULL ;
|
||||
|
||||
G4PhysicsTable* G4VPAIenergyLoss::theDEDXTable = NULL ;
|
||||
|
||||
G4double G4VPAIenergyLoss::LowerBoundEloss= 1.00*keV ;
|
||||
G4double G4VPAIenergyLoss::UpperBoundEloss= 100.*TeV ;
|
||||
G4int G4VPAIenergyLoss::NbinEloss =100 ;
|
||||
G4double G4VPAIenergyLoss::RTable,G4VPAIenergyLoss::LOGRTable;
|
||||
|
||||
|
||||
// constructor and destructor
|
||||
|
||||
G4VPAIenergyLoss::G4VPAIenergyLoss(const G4String& processName)
|
||||
: G4VEnergyLoss (processName),
|
||||
dToverTini(0.20), // max.relative range loss in one Step = 20%
|
||||
theElectron ( G4Electron::Electron() ),
|
||||
theProton ( G4Proton::Proton() ),
|
||||
theAntiProton ( G4AntiProton::AntiProton() )
|
||||
{
|
||||
theLossTable = NULL ;
|
||||
|
||||
// calculate data members LOGRTable,RTable first
|
||||
G4double lrate ;
|
||||
lrate = log(UpperBoundEloss/LowerBoundEloss) ;
|
||||
LOGRTable=lrate/NbinEloss;
|
||||
RTable =exp(LOGRTable);
|
||||
|
||||
}
|
||||
|
||||
G4VPAIenergyLoss::~G4VPAIenergyLoss()
|
||||
{
|
||||
if(theLossTable) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
G4double G4VPAIenergyLoss::GetMaxKineticEnergy() {return UpperBoundEloss;}
|
||||
G4double G4VPAIenergyLoss::GetMinKineticEnergy() {return LowerBoundEloss;}
|
||||
G4int G4VPAIenergyLoss::GetBinNumber() {return NbinEloss;}
|
||||
|
||||
void G4VPAIenergyLoss::SetNbOfProcesses(G4int nb) {NbOfProcesses=nb;}
|
||||
void G4VPAIenergyLoss::PlusNbOfProcesses() {NbOfProcesses++ ;}
|
||||
void G4VPAIenergyLoss::MinusNbOfProcesses() {NbOfProcesses-- ;}
|
||||
G4int G4VPAIenergyLoss::GetNbOfProcesses() {return NbOfProcesses;}
|
||||
|
||||
void G4VPAIenergyLoss::SetLowerBoundEloss(G4double val) {LowerBoundEloss=val;}
|
||||
void G4VPAIenergyLoss::SetUpperBoundEloss(G4double val) {UpperBoundEloss=val;}
|
||||
void G4VPAIenergyLoss::SetNbinEloss(G4int nb) {NbinEloss=nb;}
|
||||
|
||||
G4double G4VPAIenergyLoss::GetLowerBoundEloss() {return LowerBoundEloss;}
|
||||
G4double G4VPAIenergyLoss::GetUpperBoundEloss() {return UpperBoundEloss;}
|
||||
G4int G4VPAIenergyLoss::GetNbinEloss() {return NbinEloss;}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
void G4VPAIenergyLoss::BuildDEDXTable(const G4ParticleDefinition& aParticleType)
|
||||
{
|
||||
|
||||
G4bool MakeTable = false ;
|
||||
|
||||
// Create tables only if there is a new cut value !
|
||||
|
||||
// create/fill proton or antiproton tables depending on the charge of the particle
|
||||
G4double Charge = aParticleType.GetPDGCharge();
|
||||
|
||||
if (Charge>0.)
|
||||
{
|
||||
theDEDXTable= theDEDXpTable;
|
||||
}
|
||||
else
|
||||
{
|
||||
theDEDXTable= theDEDXpbarTable;
|
||||
}
|
||||
|
||||
if ( CutsWhereModified() || (theDEDXTable==NULL))
|
||||
{
|
||||
MakeTable = true ;
|
||||
}
|
||||
|
||||
if( MakeTable )
|
||||
{
|
||||
|
||||
// Build energy loss table as a sum of the energy loss due to the
|
||||
// different processes.
|
||||
//
|
||||
// different processes.
|
||||
|
||||
// create table for the total energy loss
|
||||
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
G4PhysicsTable** RecorderOfProcess;
|
||||
int CounterOfProcess;
|
||||
|
||||
if( Charge >0.)
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpProcess;
|
||||
CounterOfProcess=CounterOfpProcess;
|
||||
|
||||
if(CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
// create tables
|
||||
if(theDEDXpTable)
|
||||
{ theDEDXpTable->clearAndDestroy();
|
||||
delete theDEDXpTable; }
|
||||
theDEDXpTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXTable = theDEDXpTable;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RecorderOfProcess=RecorderOfpbarProcess;
|
||||
CounterOfProcess=CounterOfpbarProcess;
|
||||
|
||||
if(CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
// create tables
|
||||
if(theDEDXpbarTable)
|
||||
{ theDEDXpbarTable->clearAndDestroy();
|
||||
delete theDEDXpbarTable; }
|
||||
theDEDXpbarTable = new G4PhysicsTable(numOfMaterials);
|
||||
theDEDXTable = theDEDXpbarTable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(CounterOfProcess == NbOfProcesses)
|
||||
{
|
||||
// fill the tables
|
||||
|
||||
// loop for materials
|
||||
G4double LowEdgeEnergy , Value ;
|
||||
G4bool isOutRange ;
|
||||
|
||||
G4PhysicsTable* pointer ;
|
||||
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
// create physics vector and fill it
|
||||
|
||||
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(
|
||||
LowerBoundEloss, UpperBoundEloss, NbinEloss);
|
||||
|
||||
// loop for the kinetic energy
|
||||
|
||||
for (G4int i=0; i<NbinEloss; i++)
|
||||
|
||||
{
|
||||
LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
|
||||
// here comes the sum of the different tables created by the
|
||||
// processes (ionisation,etc...)
|
||||
|
||||
Value = 0. ;
|
||||
|
||||
for (G4int process=0; process < NbOfProcesses; process++)
|
||||
{
|
||||
pointer= RecorderOfProcess[process];
|
||||
Value += (*pointer)[J]->
|
||||
GetValue(LowEdgeEnergy,isOutRange) ;
|
||||
}
|
||||
|
||||
aVector->PutValue(i,Value) ;
|
||||
|
||||
}
|
||||
|
||||
theDEDXTable->insert(aVector) ;
|
||||
}
|
||||
|
||||
// reset counter to zero
|
||||
|
||||
if( Charge >0.) CounterOfpProcess=0 ;
|
||||
else CounterOfpbarProcess=0 ;
|
||||
|
||||
ParticleMass = aParticleType.GetPDGMass() ;
|
||||
|
||||
if(Charge > 0.)
|
||||
{
|
||||
// Build range table
|
||||
theRangepTable = BuildRangeTable(theDEDXpTable,
|
||||
theRangepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
// Build lab/proper time tables
|
||||
theLabTimepTable = BuildLabTimeTable(theDEDXpTable,
|
||||
theLabTimepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
theProperTimepTable = BuildProperTimeTable(theDEDXpTable,
|
||||
theProperTimepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// Build coeff tables for the energy loss calculation
|
||||
thepRangeCoeffATable = BuildRangeCoeffATable(theRangepTable,
|
||||
thepRangeCoeffATable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepRangeCoeffBTable = BuildRangeCoeffBTable(theRangepTable,
|
||||
thepRangeCoeffBTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepRangeCoeffCTable = BuildRangeCoeffCTable(theRangepTable,
|
||||
thepRangeCoeffCTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// invert the range table
|
||||
theInverseRangepTable = BuildInverseRangeTable(theRangepTable,
|
||||
thepRangeCoeffATable,
|
||||
thepRangeCoeffBTable,
|
||||
thepRangeCoeffCTable,
|
||||
theInverseRangepTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build range table
|
||||
theRangepbarTable = BuildRangeTable(theDEDXpbarTable,
|
||||
theRangepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
// Build lab/proper time tables
|
||||
theLabTimepbarTable = BuildLabTimeTable(theDEDXpbarTable,
|
||||
theLabTimepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
theProperTimepbarTable = BuildProperTimeTable(theDEDXpbarTable,
|
||||
theProperTimepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// Build coeff tables for the energy loss calculation
|
||||
thepbarRangeCoeffATable = BuildRangeCoeffATable(theRangepbarTable,
|
||||
thepbarRangeCoeffATable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepbarRangeCoeffBTable = BuildRangeCoeffBTable(theRangepbarTable,
|
||||
thepbarRangeCoeffBTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
thepbarRangeCoeffCTable = BuildRangeCoeffCTable(theRangepbarTable,
|
||||
thepbarRangeCoeffCTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
// invert the range table
|
||||
theInverseRangepbarTable = BuildInverseRangeTable(theRangepbarTable,
|
||||
thepbarRangeCoeffATable,
|
||||
thepbarRangeCoeffBTable,
|
||||
thepbarRangeCoeffCTable,
|
||||
theInverseRangepbarTable,
|
||||
LowerBoundEloss,UpperBoundEloss,NbinEloss);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// make the energy loss and the range table available
|
||||
|
||||
|
||||
G4EnergyLossTables::Register(&aParticleType,
|
||||
(Charge>0)?
|
||||
theDEDXpTable: theDEDXpbarTable,
|
||||
(Charge>0)?
|
||||
theRangepTable: theRangepbarTable,
|
||||
(Charge>0)?
|
||||
theInverseRangepTable: theInverseRangepbarTable,
|
||||
(Charge>0)?
|
||||
theLabTimepTable: theLabTimepbarTable,
|
||||
(Charge>0)?
|
||||
theProperTimepTable: theProperTimepbarTable,
|
||||
LowerBoundEloss, UpperBoundEloss,
|
||||
proton_mass_c2/aParticleType.GetPDGMass(),NbinEloss);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VeEnergyLoss.cc,v 1.32 2003/06/16 17:02:12 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-05-02-patch-01 $
|
||||
// $Id: G4VeEnergyLoss.cc,v 1.34 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -95,7 +95,7 @@ G4double G4VeEnergyLoss::RTable,G4VeEnergyLoss::LOGRTable;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// constructor and destructor
|
||||
using namespace std;
|
||||
|
||||
G4VeEnergyLoss::G4VeEnergyLoss(const G4String& processName)
|
||||
: G4VEnergyLoss (processName),
|
||||
@@ -520,7 +520,7 @@ G4VParticleChange* G4VeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
postsafety =
|
||||
navigator->ComputeSafety(stepData.GetPostStepPoint()->GetPosition());
|
||||
|
||||
safety=std::min(presafety,postsafety);
|
||||
safety=min(presafety,postsafety);
|
||||
|
||||
if(safety<rcut)
|
||||
{
|
||||
@@ -676,7 +676,7 @@ G4VParticleChange* G4VeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
|
||||
// update the particle direction and kinetic energy
|
||||
if(subdelta > 0)
|
||||
aParticleChange.SetMomentumChange(Px,Py,Pz) ;
|
||||
aParticleChange.ProposeMomentumDirection(Px,Py,Pz) ;
|
||||
E = Tkin ;
|
||||
|
||||
}
|
||||
@@ -704,12 +704,12 @@ G4VParticleChange* G4VeEnergyLoss::AlongStepDoIt( const G4Track& trackData,
|
||||
if (finalT <= 0. )
|
||||
{
|
||||
finalT = 0.;
|
||||
if (Charge < 0.) aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
if (Charge < 0.) aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
else aParticleChange.ProposeTrackStatus(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange(finalT);
|
||||
aParticleChange.SetLocalEnergyDeposit(E-finalT);
|
||||
aParticleChange.ProposeEnergy(finalT);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(E-finalT);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VhEnergyLoss.cc,v 1.46 2003/06/16 17:02:13 gunter Exp $
|
||||
// GEANT4 tag $Name: geant4-05-02-patch-01 $
|
||||
// $Id: G4VhEnergyLoss.cc,v 1.48 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -115,6 +115,8 @@ G4int G4VhEnergyLoss::Ndeltamax = 100;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4VhEnergyLoss::G4VhEnergyLoss(const G4String& processName)
|
||||
: G4VEnergyLoss (processName),
|
||||
theLossTable (NULL),
|
||||
@@ -411,7 +413,7 @@ G4double G4VhEnergyLoss::GetConstraints(const G4DynamicParticle *aParticle,
|
||||
|
||||
// compute the (random) Step limit
|
||||
//
|
||||
G4double r = std::min(finalRange, couple->GetProductionCuts()
|
||||
G4double r = min(finalRange, couple->GetProductionCuts()
|
||||
->GetProductionCut(idxG4ElectronCut));
|
||||
G4double StepLimit;
|
||||
if (fRangeNow > r)
|
||||
@@ -526,7 +528,7 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
->GetNavigatorForTracking();
|
||||
G4double postsafety =
|
||||
navigator->ComputeSafety(stepData.GetPostStepPoint()->GetPosition());
|
||||
G4double safety = std::min(presafety,postsafety);
|
||||
G4double safety = min(presafety,postsafety);
|
||||
|
||||
if (safety < rcut)
|
||||
{
|
||||
@@ -565,7 +567,7 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
{
|
||||
G4double T0=G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4Electron::Electron(),
|
||||
std::min(presafety,postsafety),
|
||||
min(presafety,postsafety),
|
||||
couple);
|
||||
// absolute lower limit for T0
|
||||
if((T0<MinDeltaEnergyNow)||(LowerLimitForced[index]))
|
||||
@@ -667,7 +669,7 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
} while (subdelta<N);
|
||||
|
||||
// update the particle direction and kinetic energy
|
||||
if(subdelta > 0) aParticleChange.SetMomentumChange(Px,Py,Pz);
|
||||
if(subdelta > 0) aParticleChange.ProposeMomentumDirection(Px,Py,Pz);
|
||||
E = Tkin;
|
||||
}
|
||||
}
|
||||
@@ -693,12 +695,12 @@ G4VParticleChange* G4VhEnergyLoss::AlongStepDoIt(
|
||||
{
|
||||
finalT = 0.;
|
||||
if(!aParticle->GetDefinition()->GetProcessManager()->GetAtRestProcessVector()->size())
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
else aParticleChange.ProposeTrackStatus(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange(finalT);
|
||||
aParticleChange.SetLocalEnergyDeposit(E-finalT);
|
||||
aParticleChange.ProposeEnergy(finalT);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(E-finalT);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eBremsstrahlung.cc,v 1.37 2003/11/12 16:23:42 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-00-patch-01 $
|
||||
// $Id: G4eBremsstrahlung.cc,v 1.40 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -60,6 +60,8 @@
|
||||
// 23-05-03 Define default integral + BohrFluctuations (V.Ivanchenko)
|
||||
// 08-08-03 STD substitute standard (V.Ivanchenko)
|
||||
// 12-11-03 G4EnergyLossSTD -> G4EnergyLossProcess (V.Ivanchenko)
|
||||
// 04-11-04 add gamma threshold (V.Ivanchenko)
|
||||
// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -77,10 +79,18 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4eBremsstrahlung::G4eBremsstrahlung(const G4String& name)
|
||||
: G4VEnergyLossProcess(name)
|
||||
using namespace std;
|
||||
|
||||
G4eBremsstrahlung::G4eBremsstrahlung(const G4String& name, G4double thresh):
|
||||
G4VEnergyLossProcess(name),
|
||||
gammaThreshold(thresh),
|
||||
isInitialised(false)
|
||||
{
|
||||
InitialiseProcess();
|
||||
SetDEDXBinning(120);
|
||||
SetLambdaBinning(120);
|
||||
SetMinKinEnergy(0.1*keV);
|
||||
SetMaxKinEnergy(100.0*TeV);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -90,27 +100,27 @@ G4eBremsstrahlung::~G4eBremsstrahlung()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlung::InitialiseProcess()
|
||||
void G4eBremsstrahlung::InitialiseEnergyLossProcess(const G4ParticleDefinition*,
|
||||
const G4ParticleDefinition*)
|
||||
{
|
||||
SetSecondaryParticle(G4Gamma::Gamma());
|
||||
if(!isInitialised) {
|
||||
isInitialised = true;
|
||||
SetSecondaryParticle(G4Gamma::Gamma());
|
||||
SetIonisation(false);
|
||||
|
||||
SetDEDXBinning(120);
|
||||
SetLambdaBinning(120);
|
||||
SetMinKinEnergy(0.1*keV);
|
||||
SetMaxKinEnergy(100.0*TeV);
|
||||
//G4VEmFluctuationModel* fm = 0;
|
||||
G4VEmFluctuationModel* fm = new G4UniversalFluctuation();
|
||||
|
||||
//G4VEmFluctuationModel* fm = 0;
|
||||
G4VEmFluctuationModel* fm = new G4UniversalFluctuation();
|
||||
|
||||
G4VEmModel* em = new G4eBremsstrahlungModel();
|
||||
em->SetLowEnergyLimit(0.1*keV);
|
||||
em->SetHighEnergyLimit(100.0*TeV);
|
||||
AddEmModel(1, em, fm);
|
||||
G4VEmModel* em = new G4eBremsstrahlungModel();
|
||||
em->SetLowEnergyLimit(0.1*keV);
|
||||
em->SetHighEnergyLimit(100.0*TeV);
|
||||
AddEmModel(1, em, fm);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eBremsstrahlung::PrintInfoDefinition()
|
||||
void G4eBremsstrahlung::PrintInfoDefinition()
|
||||
{
|
||||
G4VEnergyLossProcess::PrintInfoDefinition();
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eBremsstrahlung52.cc,v 1.1 2003/08/08 11:30:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-00-patch-01 $
|
||||
// $Id: G4eBremsstrahlung52.cc,v 1.4 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//
|
||||
// ------------ G4eBremsstrahlung52 physics process --------
|
||||
@@ -50,6 +50,7 @@
|
||||
// 16-01-03 Migrade to cut per region (V.Ivanchenko)
|
||||
// 26-04-03 fix problems of retrieve tables (V.Ivanchenko)
|
||||
// 08-08-03 This class is frozen at the release 5.2 (V.Ivanchenko)
|
||||
// 08-11-04 Remove of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
// --------------------------------------------------------------
|
||||
|
||||
@@ -69,8 +70,8 @@ G4double G4eBremsstrahlung52::probsup = 1.00;
|
||||
G4bool G4eBremsstrahlung52::LPMflag = true;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
// constructor
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4eBremsstrahlung52::G4eBremsstrahlung52(const G4String& processName)
|
||||
: G4VeEnergyLoss(processName), // initialization
|
||||
@@ -376,7 +377,7 @@ G4double G4eBremsstrahlung52::ComputeBremLoss(G4double Z,G4double,
|
||||
G4double delz = 1.e6;
|
||||
for (G4int ii=0; ii<NZ; ii++)
|
||||
{
|
||||
if(abs(Z-ZZ[ii]) < delz) { iz = ii; delz = abs(Z-ZZ[ii]);}
|
||||
if(fabs(Z-ZZ[ii]) < delz) { iz = ii; delz = fabs(Z-ZZ[ii]);}
|
||||
}
|
||||
|
||||
G4double xx = log10(T);
|
||||
@@ -617,10 +618,10 @@ G4double G4eBremsstrahlung52::ComputeCrossSectionPerAtom(
|
||||
G4double delz = 1.e6 ;
|
||||
for (G4int ii=0; ii<NZ; ii++)
|
||||
{
|
||||
if(abs(AtomicNumber-ZZ[ii]) < delz)
|
||||
if(fabs(AtomicNumber-ZZ[ii]) < delz)
|
||||
{
|
||||
iz = ii ;
|
||||
delz = abs(AtomicNumber-ZZ[ii]) ;
|
||||
delz = fabs(AtomicNumber-ZZ[ii]) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -774,9 +775,9 @@ G4VParticleChange* G4eBremsstrahlung52::PostStepDoIt(const G4Track& trackData,
|
||||
// check against insufficient energy
|
||||
if (KineticEnergy < GammaEnergyCut)
|
||||
{
|
||||
aParticleChange.SetMomentumChange( ParticleDirection );
|
||||
aParticleChange.SetEnergyChange( KineticEnergy );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
aParticleChange.ProposeMomentumDirection( ParticleDirection );
|
||||
aParticleChange.ProposeEnergy( KineticEnergy );
|
||||
aParticleChange.ProposeLocalEnergyDeposit (0.);
|
||||
aParticleChange.SetNumberOfSecondaries(0);
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
@@ -829,8 +830,8 @@ G4VParticleChange* G4eBremsstrahlung52::PostStepDoIt(const G4Track& trackData,
|
||||
G4double screenmin = screenfac*epsilmin/(1.-epsilmin);
|
||||
|
||||
// Compute the maximum of the rejection function
|
||||
G4double F1 = std::max(ScreenFunction1(screenmin) - FZ ,0.);
|
||||
G4double F2 = std::max(ScreenFunction2(screenmin) - FZ ,0.);
|
||||
G4double F1 = max(ScreenFunction1(screenmin) - FZ ,0.);
|
||||
G4double F2 = max(ScreenFunction2(screenmin) - FZ ,0.);
|
||||
grejmax = (F1 - epsilmin* (F1*ah - bh*epsilmin*F2))/(42.392 - FZ);
|
||||
|
||||
// sample the energy rate of the emitted Gamma
|
||||
@@ -842,8 +843,8 @@ G4VParticleChange* G4eBremsstrahlung52::PostStepDoIt(const G4Track& trackData,
|
||||
x = pow(xmin, G4UniformRand());
|
||||
epsil = x*KineticEnergy/TotalEnergy;
|
||||
screenvar = screenfac*epsil/(1-epsil);
|
||||
F1 = std::max(ScreenFunction1(screenvar) - FZ ,0.);
|
||||
F2 = std::max(ScreenFunction2(screenvar) - FZ ,0.);
|
||||
F1 = max(ScreenFunction1(screenvar) - FZ ,0.);
|
||||
F2 = max(ScreenFunction2(screenvar) - FZ ,0.);
|
||||
migdal = (1. + MigdalFactor)/(1. + MigdalFactor/(x*x));
|
||||
greject = migdal*(F1 - epsil* (ah*F1 - bh*epsil*F2))/(42.392 - FZ);
|
||||
} while( greject < G4UniformRand()*grejmax );
|
||||
@@ -867,9 +868,9 @@ G4VParticleChange* G4eBremsstrahlung52::PostStepDoIt(const G4Track& trackData,
|
||||
G4double bl = bl0 + bl1*U + bl2*U2;
|
||||
|
||||
// Compute the maximum of the rejection function
|
||||
grejmax = std::max(1. + xmin* (al + bl*xmin), 1.+al+bl);
|
||||
grejmax = max(1. + xmin* (al + bl*xmin), 1.+al+bl);
|
||||
G4double xm = -al/(2.*bl);
|
||||
if ((xmin < xm)&&(xm < 1.)) grejmax = std::max(grejmax, 1.+ xm* (al + bl*xm));
|
||||
if ((xmin < xm)&&(xm < 1.)) grejmax = max(grejmax, 1.+ xm* (al + bl*xm));
|
||||
|
||||
// sample the energy rate of the emitted Gamma
|
||||
|
||||
@@ -930,16 +931,16 @@ G4VParticleChange* G4eBremsstrahlung52::PostStepDoIt(const G4Track& trackData,
|
||||
G4double NewKinEnergy = KineticEnergy - GammaEnergy;
|
||||
if (NewKinEnergy > 0.)
|
||||
{
|
||||
aParticleChange.SetMomentumChange( ParticleDirection );
|
||||
aParticleChange.SetEnergyChange( NewKinEnergy );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
aParticleChange.ProposeMomentumDirection( ParticleDirection );
|
||||
aParticleChange.ProposeEnergy( NewKinEnergy );
|
||||
aParticleChange.ProposeLocalEnergyDeposit (0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
aParticleChange.SetEnergyChange( 0. );
|
||||
aParticleChange.SetLocalEnergyDeposit (0.);
|
||||
if (charge<0.) aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
aParticleChange.ProposeEnergy( 0. );
|
||||
aParticleChange.ProposeLocalEnergyDeposit (0.);
|
||||
if (charge<0.) aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
else aParticleChange.ProposeTrackStatus(fStopButAlive);
|
||||
}
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
@@ -1018,122 +1019,6 @@ G4double G4eBremsstrahlung52::SupressionFunction(const G4Material* aMaterial,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4eBremsstrahlung52::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4String filename;
|
||||
|
||||
// store stopping power table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"StoppingPower",ascii);
|
||||
if ( !theLossTable->StorePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theLossTable->StorePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// store mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
if ( !theMeanFreePathTable->StorePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->StorePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// store PartialSumSigma table (G4OrderedTable)
|
||||
filename = GetPhysicsTableFileName(particle,directory,"PartSumSigma",ascii);
|
||||
if ( !PartialSumSigma.Store(filename, ascii) ){
|
||||
G4cout << " FAIL PartialSumSigma.store in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4eBremsstrahlung52::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
// delete theLossTable and theMeanFreePathTable
|
||||
if (theLossTable != 0) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
if (theMeanFreePathTable != 0) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
|
||||
// get bining from EnergyLoss
|
||||
LowestKineticEnergy = GetLowerBoundEloss();
|
||||
HighestKineticEnergy = GetUpperBoundEloss();
|
||||
TotBin = GetNbinEloss();
|
||||
|
||||
G4String filename;
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
secondaryEnergyCuts = theCoupleTable->GetEnergyCutsVector(0);
|
||||
|
||||
// retreive stopping power table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"StoppingPower",ascii);
|
||||
theLossTable = new G4PhysicsTable(numOfCouples);
|
||||
if ( !theLossTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theLossTable0->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// retreive mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
theMeanFreePathTable = new G4PhysicsTable(numOfCouples);
|
||||
if ( !theMeanFreePathTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// retrieve PartialSumSigma table (G4OrderedTable)
|
||||
PartialSumSigma.clearAndDestroy();
|
||||
PartialSumSigma.reserve(numOfCouples);
|
||||
filename = GetPhysicsTableFileName(particle,directory,"PartSumSigma",ascii);
|
||||
if ( !PartialSumSigma.Retrieve(filename, ascii) ){
|
||||
G4cout << " FAIL PartialSumSigma.retrieve in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to retrieve the PhysicsTables from "
|
||||
<< directory << G4endl;
|
||||
|
||||
if (particle==G4Electron::Electron())
|
||||
{
|
||||
RecorderOfElectronProcess[CounterOfElectronProcess] = (*this).theLossTable;
|
||||
CounterOfElectronProcess++;
|
||||
}
|
||||
else
|
||||
{
|
||||
RecorderOfPositronProcess[CounterOfPositronProcess] = (*this).theLossTable;
|
||||
CounterOfPositronProcess++;
|
||||
}
|
||||
|
||||
BuildDEDXTable (*particle);
|
||||
|
||||
if (particle==G4Electron::Electron()) PrintInfoDefinition();
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4eBremsstrahlung52::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "Total cross sections from a NEW parametrisation"
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eBremsstrahlungModel.cc,v 1.16 2004/05/20 19:46:14 urban Exp $
|
||||
// GEANT4 tag $Name: geant4-06-02 $
|
||||
// $Id: G4eBremsstrahlungModel.cc,v 1.18 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -66,6 +66,8 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4eBremsstrahlungModel::G4eBremsstrahlungModel(const G4ParticleDefinition* p,
|
||||
const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
@@ -80,6 +82,7 @@ G4eBremsstrahlungModel::G4eBremsstrahlungModel(const G4ParticleDefinition* p,
|
||||
theLPMflag(true)
|
||||
{
|
||||
if(p) SetParticle(p);
|
||||
theGamma = G4Gamma::Gamma();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -151,7 +154,7 @@ void G4eBremsstrahlungModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4DataVector* dv = ComputePartialSumSigma(material, 0.5*highKinEnergy,
|
||||
std::min(cuts[i], 0.25*highKinEnergy));
|
||||
min(cuts[i], 0.25*highKinEnergy));
|
||||
partialSumSigma.push_back(dv);
|
||||
}
|
||||
|
||||
@@ -169,7 +172,7 @@ G4double G4eBremsstrahlungModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
|
||||
|
||||
const G4double thigh = 100.*GeV;
|
||||
|
||||
G4double cut = std::min(cutEnergy, kineticEnergy);
|
||||
G4double cut = min(cutEnergy, kineticEnergy);
|
||||
|
||||
G4double rate, loss;
|
||||
const G4double factorHigh = 36./(1450.*GeV);
|
||||
@@ -334,7 +337,7 @@ G4double G4eBremsstrahlungModel::ComputeBremLoss(G4double Z, G4double T,
|
||||
G4double delz = 1.e6;
|
||||
for (G4int ii=0; ii<NZ; ii++)
|
||||
{
|
||||
G4double dz = abs(Z-ZZ[ii]);
|
||||
G4double dz = fabs(Z-ZZ[ii]);
|
||||
if(dz < delz) {
|
||||
iz = ii;
|
||||
delz = dz;
|
||||
@@ -402,8 +405,8 @@ G4double G4eBremsstrahlungModel::CrossSection(const G4MaterialCutsCouple* couple
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
G4double cross = 0.0;
|
||||
G4double tmax = std::min(maxEnergy, kineticEnergy);
|
||||
G4double cut = std::max(cutEnergy, minThreshold);
|
||||
G4double tmax = min(maxEnergy, kineticEnergy);
|
||||
G4double cut = max(cutEnergy, minThreshold);
|
||||
if(cut >= tmax) return cross;
|
||||
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
@@ -536,10 +539,10 @@ G4double G4eBremsstrahlungModel::CrossSectionPerAtom(G4double kineticEnergy,
|
||||
G4double delz = 1.e6 ;
|
||||
for (G4int ii=0; ii<NZ; ii++)
|
||||
{
|
||||
if(abs(Z-ZZ[ii]) < delz)
|
||||
if(fabs(Z-ZZ[ii]) < delz)
|
||||
{
|
||||
iz = ii ;
|
||||
delz = abs(Z-ZZ[ii]);
|
||||
delz = fabs(Z-ZZ[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,7 +642,7 @@ G4DynamicParticle* G4eBremsstrahlungModel::SampleSecondary(
|
||||
// (Nuc Phys 20(1960),15).
|
||||
{
|
||||
G4double kineticEnergy = dp->GetKineticEnergy();
|
||||
G4double tmax = std::min(maxEnergy, kineticEnergy);
|
||||
G4double tmax = min(maxEnergy, kineticEnergy);
|
||||
if(tmin > tmax) tmin = tmax;
|
||||
|
||||
//
|
||||
@@ -721,8 +724,8 @@ G4DynamicParticle* G4eBremsstrahlungModel::SampleSecondary(
|
||||
G4double screenmin = screenfac*epsilmin/(1.-epsilmin);
|
||||
|
||||
// Compute the maximum of the rejection function
|
||||
G4double F1 = std::max(ScreenFunction1(screenmin) - FZ ,0.);
|
||||
G4double F2 = std::max(ScreenFunction2(screenmin) - FZ ,0.);
|
||||
G4double F1 = max(ScreenFunction1(screenmin) - FZ ,0.);
|
||||
G4double F2 = max(ScreenFunction2(screenmin) - FZ ,0.);
|
||||
grejmax = (F1 - epsilmin* (F1*ah - bh*epsilmin*F2))/(42.392 - FZ);
|
||||
|
||||
} else {
|
||||
@@ -739,9 +742,9 @@ G4DynamicParticle* G4eBremsstrahlungModel::SampleSecondary(
|
||||
bh = bl0 + bl1*U + bl2*U2;
|
||||
|
||||
// Compute the maximum of the rejection function
|
||||
grejmax = std::max(1. + xmin* (ah + bh*xmin), 1.+ah+bh);
|
||||
grejmax = max(1. + xmin* (ah + bh*xmin), 1.+ah+bh);
|
||||
G4double xm = -ah/(2.*bh);
|
||||
if ( xmin < xm && xm < xmax) grejmax = std::max(grejmax, 1.+ xm* (ah + bh*xm));
|
||||
if ( xmin < xm && xm < xmax) grejmax = max(grejmax, 1.+ xm* (ah + bh*xm));
|
||||
}
|
||||
|
||||
//
|
||||
@@ -755,8 +758,8 @@ G4DynamicParticle* G4eBremsstrahlungModel::SampleSecondary(
|
||||
x = pow(xmin, q + kappa*(1.0 - q));
|
||||
epsil = x*kineticEnergy/totalEnergy;
|
||||
G4double screenvar = screenfac*epsil/(1.0-epsil);
|
||||
G4double F1 = std::max(ScreenFunction1(screenvar) - FZ ,0.);
|
||||
G4double F2 = std::max(ScreenFunction2(screenvar) - FZ ,0.);
|
||||
G4double F1 = max(ScreenFunction1(screenvar) - FZ ,0.);
|
||||
G4double F2 = max(ScreenFunction2(screenvar) - FZ ,0.);
|
||||
migdal = (1. + MigdalFactor)/(1. + MigdalFactor/(x*x));
|
||||
greject = migdal*(F1 - epsil* (ah*F1 - bh*epsil*F2))/(42.392 - FZ);
|
||||
/*
|
||||
@@ -823,14 +826,14 @@ G4DynamicParticle* G4eBremsstrahlungModel::SampleSecondary(
|
||||
gammaDirection.rotateUz(direction);
|
||||
|
||||
// create G4DynamicParticle object for the Gamma
|
||||
G4DynamicParticle* g = new G4DynamicParticle(G4Gamma::Gamma(),gammaDirection,gammaEnergy);
|
||||
G4DynamicParticle* g = new G4DynamicParticle(theGamma,gammaDirection,gammaEnergy);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
std::vector<G4DynamicParticle*>* G4eBremsstrahlungModel::SampleSecondaries(
|
||||
vector<G4DynamicParticle*>* G4eBremsstrahlungModel::SampleSecondaries(
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double,
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eIonisation.cc,v 1.37 2003/11/12 16:23:42 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-00-patch-01 $
|
||||
// $Id: G4eIonisation.cc,v 1.39 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -57,6 +57,7 @@
|
||||
// 03-06-03 Fix initialisation problem for STD ionisation (V.Ivanchenko)
|
||||
// 08-08-03 STD substitute standard (V.Ivanchenko)
|
||||
// 12-11-03 G4EnergyLossSTD -> G4EnergyLossProcess (V.Ivanchenko)
|
||||
// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -67,11 +68,12 @@
|
||||
#include "G4Electron.hh"
|
||||
#include "G4MollerBhabhaModel.hh"
|
||||
#include "G4UniversalFluctuation.hh"
|
||||
//#include "G4BohrFluctuations.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4eIonisation::G4eIonisation(const G4String& name)
|
||||
: G4VEnergyLossProcess(name),
|
||||
theElectron(G4Electron::Electron()),
|
||||
@@ -92,33 +94,21 @@ G4eIonisation::~G4eIonisation()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eIonisation::InitialiseProcess()
|
||||
void G4eIonisation::InitialiseEnergyLossProcess(const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition*)
|
||||
{
|
||||
SetSecondaryParticle(theElectron);
|
||||
if(!isInitialised) {
|
||||
if(part == G4Positron::Positron()) isElectron = false;
|
||||
SetSecondaryParticle(theElectron);
|
||||
|
||||
if(IsIntegral()) {
|
||||
// flucModel = new G4BohrFluctuations();
|
||||
flucModel = new G4UniversalFluctuation();
|
||||
|
||||
} else {
|
||||
flucModel = new G4UniversalFluctuation();
|
||||
G4VEmModel* em = new G4MollerBhabhaModel();
|
||||
em->SetLowEnergyLimit(0.1*keV);
|
||||
em->SetHighEnergyLimit(100.0*TeV);
|
||||
AddEmModel(1, em, flucModel);
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
G4VEmModel* em = new G4MollerBhabhaModel();
|
||||
em->SetLowEnergyLimit(0.1*keV);
|
||||
em->SetHighEnergyLimit(100.0*TeV);
|
||||
AddEmModel(1, em, flucModel);
|
||||
isInitialised = true;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4ParticleDefinition* G4eIonisation::DefineBaseParticle(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(p == G4Positron::Positron()) isElectron = false;
|
||||
if(!isInitialised) InitialiseProcess();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eIonisation52.cc,v 1.1 2003/08/08 11:30:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-00-patch-01 $
|
||||
// $Id: G4eIonisation52.cc,v 1.4 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//--------------- G4eIonisation52 physics process --------------------------------
|
||||
// by Laszlo Urban, 20 March 1997
|
||||
@@ -45,6 +45,7 @@
|
||||
// 08-04-03 finalRange is region aware (V.Ivanchenko)
|
||||
// 26-04-03 fix problems of retrieve tables (V.Ivanchenko)
|
||||
// 08-08-03 This class is frozen at the release 5.2 (V.Ivanchenko)
|
||||
// 08-11-04 Remove of Store/Retrieve tables (V.Ivantchenko)
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -62,6 +63,8 @@ G4int G4eIonisation52::NbinLambda = 100;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4eIonisation52::G4eIonisation52(const G4String& processName)
|
||||
: G4VeEnergyLoss(processName),
|
||||
theMeanFreePathTable(NULL)
|
||||
@@ -284,7 +287,7 @@ G4double G4eIonisation52::ComputeRestrictedMeandEdx (
|
||||
if (&aParticleType==G4Electron::Electron())
|
||||
{
|
||||
Tmax = KineticEnergy/2.;
|
||||
d = std::min(DeltaThreshold, Tmax)/particleMass;
|
||||
d = min(DeltaThreshold, Tmax)/particleMass;
|
||||
dEdx = log(2.*(tau+2.)/Eexcm2)-1.-beta2
|
||||
+ log((tau-d)*d)+tau/(tau-d)
|
||||
+ (0.5*d*d+(2.*tau+1.)*log(1.-d/tau))/gamma2;
|
||||
@@ -293,7 +296,7 @@ G4double G4eIonisation52::ComputeRestrictedMeandEdx (
|
||||
else //positron
|
||||
{
|
||||
Tmax = KineticEnergy;
|
||||
d = std::min(DeltaThreshold, Tmax)/particleMass;
|
||||
d = min(DeltaThreshold, Tmax)/particleMass;
|
||||
G4double d2=d*d/2., d3=d*d*d/3., d4=d*d*d*d/4.;
|
||||
G4double y=1./(1.+gamma);
|
||||
dEdx = log(2.*(tau+2.)/Eexcm2)+log(tau*d)
|
||||
@@ -491,128 +494,32 @@ G4VParticleChange* G4eIonisation52::PostStepDoIt( const G4Track& trackData,
|
||||
finalPy /= finalMomentum;
|
||||
finalPz /= finalMomentum;
|
||||
|
||||
aParticleChange.SetMomentumChange(finalPx, finalPy, finalPz);
|
||||
aParticleChange.ProposeMomentumDirection(finalPx, finalPy, finalPz);
|
||||
}
|
||||
else
|
||||
{
|
||||
Edep = finalKineticEnergy;
|
||||
finalKineticEnergy = 0.;
|
||||
if (Charge < 0.) aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
if (Charge < 0.) aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
else aParticleChange.ProposeTrackStatus(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange(finalKineticEnergy);
|
||||
aParticleChange.ProposeEnergy(finalKineticEnergy);
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(theDeltaRay);
|
||||
aParticleChange.SetLocalEnergyDeposit(Edep);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(Edep);
|
||||
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4eIonisation52::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4String filename;
|
||||
|
||||
// store stopping power table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"StoppingPower",ascii);
|
||||
if ( !theLossTable->StorePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theLossTable->StorePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
// store mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
if ( !theMeanFreePathTable->StorePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->StorePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4eIonisation52::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
// delete theLossTable and theMeanFreePathTable
|
||||
if (theLossTable != 0) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
if (theMeanFreePathTable != 0) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
// get bining from EnergyLoss
|
||||
LowestKineticEnergy = GetLowerBoundEloss();
|
||||
HighestKineticEnergy = GetUpperBoundEloss();
|
||||
TotBin = GetNbinEloss();
|
||||
|
||||
G4String filename;
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
secondaryEnergyCuts = theCoupleTable->GetEnergyCutsVector(1);
|
||||
|
||||
// retreive stopping power table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"StoppingPower",ascii);
|
||||
theLossTable = new G4PhysicsTable(numOfCouples);
|
||||
if ( !theLossTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theLossTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// retreive mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
theMeanFreePathTable = new G4PhysicsTable(numOfCouples);
|
||||
if ( !theMeanFreePathTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to retrieve the PhysicsTables from "
|
||||
<< directory << G4endl;
|
||||
|
||||
if (particle==G4Electron::Electron())
|
||||
{
|
||||
RecorderOfElectronProcess[CounterOfElectronProcess] = (*this).theLossTable;
|
||||
CounterOfElectronProcess++;
|
||||
}
|
||||
else
|
||||
{
|
||||
RecorderOfPositronProcess[CounterOfPositronProcess] = (*this).theLossTable;
|
||||
CounterOfPositronProcess++;
|
||||
}
|
||||
|
||||
BuildDEDXTable(*particle);
|
||||
if (particle==G4Electron::Electron()) PrintInfoDefinition();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4eIonisation52::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = "delta cross sections from Moller+Bhabha. "
|
||||
"Good description from 1 KeV to 100 GeV.\n"
|
||||
" delta ray energy sampled from differential Xsection.";
|
||||
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from "
|
||||
<< G4BestUnit(LowerBoundLambda,"Energy")
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4eeToTwoGammaModel.cc,v 1.4 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4eeToTwoGammaModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko on base of Michel Maire code
|
||||
//
|
||||
// Creation date: 02.08.2004
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of e+ annihilation into 2 gamma
|
||||
//
|
||||
// The secondaries Gamma energies are sampled using the Heitler cross section.
|
||||
//
|
||||
// A modified version of the random number techniques of Butcher & Messel
|
||||
// is used (Nuc Phys 20(1960),15).
|
||||
//
|
||||
// GEANT4 internal units.
|
||||
//
|
||||
// Note 1: The initial electron is assumed free and at rest.
|
||||
//
|
||||
// Note 2: The annihilation processes producing one or more than two photons are
|
||||
// ignored, as negligible compared to the two photons process.
|
||||
|
||||
|
||||
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4eeToTwoGammaModel.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "Randomize.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4eeToTwoGammaModel::G4eeToTwoGammaModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
highKinEnergy(10.*TeV),
|
||||
lowKinEnergy(0.1*keV),
|
||||
pi_rcl2(pi*classic_electr_radius*classic_electr_radius)
|
||||
{
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4eeToTwoGammaModel::~G4eeToTwoGammaModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eeToTwoGammaModel::HighEnergyLimit(const G4ParticleDefinition*)
|
||||
{
|
||||
return highKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eeToTwoGammaModel::LowEnergyLimit(const G4ParticleDefinition*)
|
||||
{
|
||||
return lowKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eeToTwoGammaModel::MinEnergyCut(const G4ParticleDefinition*,
|
||||
const G4MaterialCutsCouple*)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4eeToTwoGammaModel::IsInCharge(const G4ParticleDefinition* p)
|
||||
{
|
||||
return (p == G4Positron::Positron());
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eeToTwoGammaModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eeToTwoGammaModel::ComputeDEDX(const G4MaterialCutsCouple*,
|
||||
const G4ParticleDefinition*,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4eeToTwoGammaModel::CrossSection(const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition*,
|
||||
G4double kineticEnergy,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
// Calculates the cross section per atom of annihilation into two photons
|
||||
// from the Heilter formula.
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
G4double eDensity = material->GetElectronDensity();
|
||||
|
||||
G4double tau = kineticEnergy/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gamma2= gam*gam;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double bg = sqrt(bg2);
|
||||
|
||||
G4double cross = pi_rcl2*eDensity*((gamma2+4*gam+1.)*log(gam+bg) - (gam+3.)*bg)
|
||||
/ (bg2*(gam+1.));
|
||||
return cross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4DynamicParticle* G4eeToTwoGammaModel::SampleSecondary(
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle*,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
vector<G4DynamicParticle*>* G4eeToTwoGammaModel::SampleSecondaries(
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
G4double PositKinEnergy = dp->GetKineticEnergy();
|
||||
G4ThreeVector PositDirection = dp->GetMomentumDirection();
|
||||
|
||||
G4double tau = PositKinEnergy/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double tau2 = tau + 2.0;
|
||||
G4double sqgrate = sqrt(tau/tau2)*0.5;
|
||||
G4double sqg2m1 = sqrt(tau*tau2);
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double epsilmin = 0.5 - sqgrate;
|
||||
G4double epsilmax = 0.5 + sqgrate;
|
||||
G4double epsilqot = epsilmax/epsilmin;
|
||||
|
||||
//
|
||||
// sample the energy rate of the created gammas
|
||||
//
|
||||
G4double epsil, greject;
|
||||
|
||||
do {
|
||||
epsil = epsilmin*pow(epsilqot,G4UniformRand());
|
||||
greject = 1. - epsil + (2.*gam*epsil-1.)/(epsil*tau2*tau2);
|
||||
} while( greject < G4UniformRand() );
|
||||
|
||||
//
|
||||
// scattered Gamma angles. ( Z - axis along the parent positron)
|
||||
//
|
||||
|
||||
G4double cost = (epsil*tau2-1.)/(epsil*sqg2m1);
|
||||
G4double sint = sqrt((1.+cost)*(1.-cost));
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
|
||||
G4double dirx = sint*cos(phi) , diry = sint*sin(phi) , dirz = cost;
|
||||
|
||||
//
|
||||
// kinematic of the created pair
|
||||
//
|
||||
|
||||
G4double TotalAvailableEnergy = PositKinEnergy + 2.0*electron_mass_c2;
|
||||
G4double Phot1Energy = epsil*TotalAvailableEnergy;
|
||||
|
||||
vector<G4DynamicParticle*>* vdp = new vector<G4DynamicParticle*>;
|
||||
|
||||
G4ThreeVector Phot1Direction (dirx, diry, dirz);
|
||||
Phot1Direction.rotateUz(PositDirection);
|
||||
G4DynamicParticle* aParticle1 = new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
Phot1Direction, Phot1Energy);
|
||||
vdp->push_back(aParticle1);
|
||||
|
||||
G4double Phot2Energy =(1.-epsil)*TotalAvailableEnergy;
|
||||
G4double Eratio= Phot1Energy/Phot2Energy;
|
||||
G4double PositP= sqrt(PositKinEnergy*(PositKinEnergy+2.*electron_mass_c2));
|
||||
G4ThreeVector Phot2Direction (-dirx*Eratio, -diry*Eratio,
|
||||
(PositP-dirz*Phot1Energy)/Phot2Energy);
|
||||
Phot2Direction.unit();
|
||||
Phot2Direction.rotateUz(PositDirection);
|
||||
// create G4DynamicParticle object for the particle2
|
||||
G4DynamicParticle* aParticle2= new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
Phot2Direction, Phot2Energy);
|
||||
vdp->push_back(aParticle2);
|
||||
return vdp;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4eplusAnnihilation.cc,v 1.16 2004/03/10 16:48:46 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-01 $
|
||||
// $Id: G4eplusAnnihilation.cc,v 1.20 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
// 17-09-01, migration of Materials to pure STL (mma)
|
||||
// 20-09-01, DoIt: fminimalEnergy = 1*eV (mma)
|
||||
// 01-10-01, come back to BuildPhysicsTable(const G4ParticleDefinition&)
|
||||
//
|
||||
// 08-11-04, Remove of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -47,7 +48,7 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// constructor
|
||||
using namespace std;
|
||||
|
||||
G4eplusAnnihilation::G4eplusAnnihilation(const G4String& processName,
|
||||
G4ProcessType type):G4VRestDiscreteProcess (processName, type),
|
||||
@@ -75,6 +76,12 @@ G4eplusAnnihilation::~G4eplusAnnihilation()
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
}
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4eplusAnnihilation::IsApplicable( const G4ParticleDefinition& particle)
|
||||
{
|
||||
return ( &particle == G4Positron::Positron() );
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -104,7 +111,7 @@ void G4eplusAnnihilation::BuildPhysicsTable(const G4ParticleDefinition& )
|
||||
G4double AtomicNumber;
|
||||
size_t J;
|
||||
|
||||
for ( J=0 ; J < G4Element::GetNumberOfElements(); J++ )
|
||||
for ( J=0 ; J < G4Element::GetNumberOfElements(); J++ )
|
||||
{
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(LowestEnergyLimit, HighestEnergyLimit,
|
||||
@@ -132,7 +139,7 @@ void G4eplusAnnihilation::BuildPhysicsTable(const G4ParticleDefinition& )
|
||||
G4Material* material;
|
||||
|
||||
for ( J=0 ; J < G4Material::GetNumberOfMaterials(); J++ )
|
||||
{
|
||||
{
|
||||
//create physics vector then fill it ....
|
||||
ptrVector = new G4PhysicsLogVector(LowestEnergyLimit, HighestEnergyLimit,
|
||||
NumbBinTable );
|
||||
@@ -149,7 +156,7 @@ void G4eplusAnnihilation::BuildPhysicsTable(const G4ParticleDefinition& )
|
||||
|
||||
}
|
||||
|
||||
PrintInfoDefinition();
|
||||
PrintInfoDefinition();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -173,6 +180,92 @@ G4double G4eplusAnnihilation::ComputeCrossSectionPerAtom
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4eplusAnnihilation::ComputeMeanFreePath( G4double PositKinEnergy,
|
||||
G4Material* aMaterial)
|
||||
|
||||
// returns the positron mean free path in GEANT4 internal units
|
||||
|
||||
{
|
||||
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
|
||||
const G4double* NbOfAtomsPerVolume = aMaterial->GetVecNbOfAtomsPerVolume();
|
||||
|
||||
G4double SIGMA = 0 ;
|
||||
|
||||
for (size_t elm=0 ; elm < aMaterial->GetNumberOfElements() ; elm++ )
|
||||
{
|
||||
SIGMA += NbOfAtomsPerVolume[elm] *
|
||||
ComputeCrossSectionPerAtom(PositKinEnergy,
|
||||
(*theElementVector)[elm]->GetZ());
|
||||
}
|
||||
|
||||
return SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4eplusAnnihilation::GetCrossSectionPerAtom(
|
||||
G4DynamicParticle* aDynamicPositron,
|
||||
G4Element* anElement)
|
||||
|
||||
// return the total cross section per atom in GEANT4 internal units
|
||||
|
||||
{
|
||||
G4double crossSection;
|
||||
G4double PositronEnergy = aDynamicPositron->GetKineticEnergy();
|
||||
G4bool isOutRange ;
|
||||
|
||||
if (PositronEnergy > HighestEnergyLimit)
|
||||
crossSection = 0. ;
|
||||
else {
|
||||
if (PositronEnergy < LowestEnergyLimit) PositronEnergy = 1.01*LowestEnergyLimit;
|
||||
crossSection = (*theCrossSectionTable)(anElement->GetIndex())->
|
||||
GetValue( PositronEnergy, isOutRange );
|
||||
}
|
||||
|
||||
return crossSection;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4eplusAnnihilation::GetMeanFreePath(const G4Track& aTrack,
|
||||
G4double,
|
||||
G4ForceCondition*)
|
||||
|
||||
// returns the positron mean free path in GEANT4 internal units
|
||||
|
||||
{
|
||||
const G4DynamicParticle* aDynamicPositron = aTrack.GetDynamicParticle();
|
||||
G4double PositronEnergy = aDynamicPositron->GetKineticEnergy();
|
||||
G4Material* aMaterial = aTrack.GetMaterial();
|
||||
|
||||
G4double MeanFreePath;
|
||||
G4bool isOutRange ;
|
||||
|
||||
if (PositronEnergy > HighestEnergyLimit) MeanFreePath = DBL_MAX;
|
||||
else
|
||||
{
|
||||
if (PositronEnergy < LowestEnergyLimit)
|
||||
PositronEnergy = 1.01*LowestEnergyLimit;
|
||||
MeanFreePath = (*theMeanFreePathTable)(aMaterial->GetIndex())->
|
||||
GetValue( PositronEnergy, isOutRange );
|
||||
}
|
||||
|
||||
return MeanFreePath;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4eplusAnnihilation::GetMeanLifeTime(const G4Track&,
|
||||
G4ForceCondition*)
|
||||
|
||||
// returns the annihilation mean life time in GEANT4 internal units
|
||||
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
G4VParticleChange* G4eplusAnnihilation::PostStepDoIt(const G4Track& aTrack,
|
||||
@@ -186,7 +279,7 @@ G4VParticleChange* G4eplusAnnihilation::PostStepDoIt(const G4Track& aTrack,
|
||||
// GEANT4 internal units.
|
||||
//
|
||||
// Note 1: The initial electron is assumed free and at rest.
|
||||
//
|
||||
//
|
||||
// Note 2: The annihilation processes producing one or more than two photons are
|
||||
// ignored, as negligible compared to the two photons process.
|
||||
|
||||
@@ -242,7 +335,7 @@ G4VParticleChange* G4eplusAnnihilation::PostStepDoIt(const G4Track& aTrack,
|
||||
G4double Phot1Energy = epsil*TotalAvailableEnergy;
|
||||
if (Phot1Energy > fminimalEnergy) {
|
||||
G4ThreeVector Phot1Direction (dirx, diry, dirz);
|
||||
Phot1Direction.rotateUz(PositDirection);
|
||||
Phot1Direction.rotateUz(PositDirection);
|
||||
// create G4DynamicParticle object for the particle1
|
||||
G4DynamicParticle* aParticle1= new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
Phot1Direction, Phot1Energy);
|
||||
@@ -264,15 +357,14 @@ G4VParticleChange* G4eplusAnnihilation::PostStepDoIt(const G4Track& aTrack,
|
||||
}
|
||||
else localEnergyDeposit += Phot2Energy;
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(localEnergyDeposit);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(localEnergyDeposit);
|
||||
|
||||
//
|
||||
// Kill the incident positron
|
||||
//
|
||||
|
||||
aParticleChange.SetMomentumChange( 0., 0., 0. );
|
||||
aParticleChange.SetEnergyChange(0.);
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.ProposeEnergy(0.);
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
@@ -288,7 +380,7 @@ G4VParticleChange* G4eplusAnnihilation::AtRestDoIt(const G4Track& aTrack,
|
||||
// GEANT4 internal units
|
||||
//
|
||||
// Note : Effects due to binding of atomic electrons are negliged.
|
||||
|
||||
|
||||
{
|
||||
aParticleChange.Initialize(aTrack);
|
||||
|
||||
@@ -303,19 +395,19 @@ G4VParticleChange* G4eplusAnnihilation::AtRestDoIt(const G4Track& aTrack,
|
||||
aParticleChange.AddSecondary( new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
-Direction, electron_mass_c2) );
|
||||
|
||||
aParticleChange.SetLocalEnergyDeposit(0.);
|
||||
aParticleChange.ProposeLocalEnergyDeposit(0.);
|
||||
|
||||
// Kill the incident positron
|
||||
//
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
|
||||
return &aParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4eplusAnnihilation::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool G4eplusAnnihilation::StorePhysicsTable(const G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4String filename;
|
||||
@@ -335,17 +427,17 @@ G4bool G4eplusAnnihilation::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4eplusAnnihilation::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
/*
|
||||
G4bool G4eplusAnnihilation::RetrievePhysicsTable(const G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
// delete theCrossSectionTable and theMeanFreePathTable
|
||||
@@ -365,7 +457,7 @@ G4bool G4eplusAnnihilation::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
theCrossSectionTable = new G4PhysicsTable(G4Element::GetNumberOfElements());
|
||||
if ( !theCrossSectionTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theCrossSectionTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -374,16 +466,16 @@ G4bool G4eplusAnnihilation::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
theMeanFreePathTable = new G4PhysicsTable(G4Material::GetNumberOfMaterials());
|
||||
if ( !theMeanFreePathTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to retrieve the PhysicsTables from "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
*/
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4eplusAnnihilation::PrintInfoDefinition()
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * DISCLAIMER *
|
||||
// * *
|
||||
// * The following disclaimer summarizes all the specific disclaimers *
|
||||
// * of contributors to this software. The specific disclaimers,which *
|
||||
// * govern, are listed with their locations in: *
|
||||
// * http://cern.ch/geant4/license *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. *
|
||||
// * *
|
||||
// * 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: G4eplusAnnihilation70.cc,v 1.3 2004/12/01 19:37:15 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4eplusAnnihilation70
|
||||
//
|
||||
// Author: Vladimir Ivanchenko on base of Michel Maire code
|
||||
//
|
||||
// Creation date: 02.08.2004
|
||||
//
|
||||
// Modifications:
|
||||
// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4eplusAnnihilation70.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4eeToTwoGammaModel.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4eplusAnnihilation70::G4eplusAnnihilation70(const G4String& name)
|
||||
: G4VEmProcess(name), isInitialised(false)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4eplusAnnihilation70::~G4eplusAnnihilation70()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eplusAnnihilation70::InitialiseProcess(const G4ParticleDefinition*)
|
||||
{
|
||||
if(!isInitialised) {
|
||||
isInitialised = true;
|
||||
SetSecondaryParticle(G4Gamma::Gamma());
|
||||
G4double emin = 0.1*keV;
|
||||
G4double emax = 100.*TeV;
|
||||
SetLambdaBinning(120);
|
||||
SetMinKinEnergy(emin);
|
||||
SetMaxKinEnergy(emax);
|
||||
G4VEmModel* em = new G4eeToTwoGammaModel();
|
||||
em->SetLowEnergyLimit(emin);
|
||||
em->SetHighEnergyLimit(emax);
|
||||
AddEmModel(1, em);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4eplusAnnihilation70::PrintInfoDefinition()
|
||||
{
|
||||
G4VEmProcess::PrintInfoDefinition();
|
||||
|
||||
G4cout << " Heilter model of formula of annihilation into 2 photons"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4PhysicsVector* G4eplusAnnihilation70::LambdaPhysicsVector(const G4MaterialCutsCouple*)
|
||||
{
|
||||
G4PhysicsVector* v = new G4PhysicsLogVector(MinKinEnergy(), MaxKinEnergy(),
|
||||
LambdaBinning());
|
||||
return v;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4eplusAnnihilation70::AtRestDoIt(const G4Track& aTrack,
|
||||
const G4Step& )
|
||||
//
|
||||
// Performs the e+ e- annihilation when both particles are assumed at rest.
|
||||
// It generates two back to back photons with energy = electron_mass.
|
||||
// The angular distribution is isotropic.
|
||||
// GEANT4 internal units
|
||||
//
|
||||
// Note : Effects due to binding of atomic electrons are negliged.
|
||||
{
|
||||
fParticleChange.InitializeForPostStep(aTrack);
|
||||
|
||||
// Below gamma production threshold
|
||||
if(electron_mass_c2 < GetGammaEnergyCut()) {
|
||||
fParticleChange.ProposeLocalEnergyDeposit(2.0*electron_mass_c2);
|
||||
|
||||
// Real gamma production
|
||||
} else {
|
||||
fParticleChange.SetNumberOfSecondaries(2);
|
||||
|
||||
G4double cosTeta = 2.*G4UniformRand()-1. , sinTeta = sqrt(1.-cosTeta*cosTeta);
|
||||
G4double phi = twopi * G4UniformRand();
|
||||
G4ThreeVector direction (sinTeta*cos(phi), sinTeta*sin(phi), cosTeta);
|
||||
fParticleChange.AddSecondary( new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
direction, electron_mass_c2) );
|
||||
fParticleChange.AddSecondary( new G4DynamicParticle (G4Gamma::Gamma(),
|
||||
-direction, electron_mass_c2) );
|
||||
}
|
||||
// Kill the incident positron
|
||||
//
|
||||
fParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4hIonisation.cc,v 1.51 2004/05/27 17:23:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-02 $
|
||||
// $Id: G4hIonisation.cc,v 1.54 2004/12/01 19:37:16 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -67,6 +67,7 @@
|
||||
// 08-08-03 STD substitute standard (V.Ivanchenko)
|
||||
// 12-11-03 G4EnergyLossSTD -> G4EnergyLossProcess (V.Ivanchenko)
|
||||
// 27-05-04 Set integral to be a default regime (V.Ivanchenko)
|
||||
// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -85,6 +86,8 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4hIonisation::G4hIonisation(const G4String& name)
|
||||
: G4VEnergyLossProcess(name),
|
||||
theParticle(0),
|
||||
@@ -108,9 +111,18 @@ G4hIonisation::~G4hIonisation()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hIonisation::InitialiseProcess()
|
||||
void G4hIonisation::InitialiseEnergyLossProcess(const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition* bpart)
|
||||
{
|
||||
if(isInitialised) return;
|
||||
|
||||
theParticle = part;
|
||||
|
||||
if(part == bpart || part == G4Proton::Proton()) theBaseParticle = 0;
|
||||
else if(bpart == 0) theBaseParticle = G4Proton::Proton();
|
||||
else theBaseParticle = bpart;
|
||||
|
||||
SetBaseParticle(theBaseParticle);
|
||||
SetSecondaryParticle(G4Electron::Electron());
|
||||
mass = theParticle->GetPDGMass();
|
||||
ratio = electron_mass_c2/mass;
|
||||
@@ -135,18 +147,6 @@ void G4hIonisation::InitialiseProcess()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4ParticleDefinition* G4hIonisation::DefineBaseParticle(
|
||||
const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!theParticle) theParticle = p;
|
||||
if(p != BaseParticle() && p != G4Proton::Proton()) theBaseParticle = G4Proton::Proton();
|
||||
if(!isInitialised) InitialiseProcess();
|
||||
|
||||
return theBaseParticle;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4hIonisation::PrintInfoDefinition()
|
||||
{
|
||||
G4VEnergyLossProcess::PrintInfoDefinition();
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4hIonisation52.cc,v 1.1 2003/08/08 11:30:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-00-patch-01 $
|
||||
// $Id: G4hIonisation52.cc,v 1.4 2004/12/01 19:37:16 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
//---------------- G4hIonisation52 physics process -------------------------------
|
||||
// by Laszlo Urban, 30 May 1997
|
||||
@@ -56,6 +56,7 @@
|
||||
// 17-04-03 fix problem of hadron tests (V.Ivanchenko)
|
||||
// 26-04-03 fix problems of retrieve tables (V.Ivanchenko)
|
||||
// 08-08-03 This class is frozen at the release 5.2 (V.Ivanchenko)
|
||||
// 08-11-04 Remove of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -76,6 +77,8 @@ G4int G4hIonisation52::NbinLambda = 100;
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4hIonisation52::G4hIonisation52(const G4String& processName)
|
||||
: G4VhEnergyLoss(processName),
|
||||
theMeanFreePathTable(0),
|
||||
@@ -357,7 +360,7 @@ G4double G4hIonisation52::ComputeRestrictedMeandEdx (
|
||||
//
|
||||
if (tau > taul)
|
||||
{
|
||||
G4double rcut = std::min(DeltaThreshold/Tmax, 1.);
|
||||
G4double rcut = min(DeltaThreshold/Tmax, 1.);
|
||||
dEdx = log(2.*electron_mass_c2*bg2*Tmax/Eexc2)
|
||||
+log(rcut)-(1.+rcut)*beta2;
|
||||
|
||||
@@ -574,21 +577,21 @@ G4VParticleChange* G4hIonisation52::PostStepDoIt(const G4Track& trackData,
|
||||
finalPy /= finalMomentum;
|
||||
finalPz /= finalMomentum;
|
||||
|
||||
aParticleChange.SetMomentumChange( finalPx,finalPy,finalPz );
|
||||
aParticleChange.ProposeMomentumDirection( finalPx,finalPy,finalPz );
|
||||
}
|
||||
else
|
||||
{
|
||||
Edep = finalKineticEnergy;
|
||||
finalKineticEnergy = 0.;
|
||||
if (!aParticle->GetDefinition()->GetProcessManager()->GetAtRestProcessVector()->size())
|
||||
aParticleChange.SetStatusChange(fStopAndKill);
|
||||
else aParticleChange.SetStatusChange(fStopButAlive);
|
||||
aParticleChange.ProposeTrackStatus(fStopAndKill);
|
||||
else aParticleChange.ProposeTrackStatus(fStopButAlive);
|
||||
}
|
||||
|
||||
aParticleChange.SetEnergyChange( finalKineticEnergy );
|
||||
aParticleChange.ProposeEnergy( finalKineticEnergy );
|
||||
aParticleChange.SetNumberOfSecondaries(1);
|
||||
aParticleChange.AddSecondary(theDeltaRay);
|
||||
aParticleChange.SetLocalEnergyDeposit (Edep);
|
||||
aParticleChange.ProposeLocalEnergyDeposit (Edep);
|
||||
|
||||
//ResetNumberOfInteractionLengthLeft();
|
||||
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
|
||||
@@ -596,122 +599,6 @@ G4VParticleChange* G4hIonisation52::PostStepDoIt(const G4Track& trackData,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4hIonisation52::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4String particleName = particle->GetParticleName();
|
||||
G4String filename;
|
||||
|
||||
// store stopping power table
|
||||
if ((particleName == "proton")||(particleName == "anti_proton")) {
|
||||
filename = GetPhysicsTableFileName(particle,directory,"StoppingPower",ascii);
|
||||
if ( !theLossTable->StorePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theLossTable->StorePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// store mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
if ( !theMeanFreePathTable->StorePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->StorePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
G4cout << GetProcessName() << " for " << particleName
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4hIonisation52::RetrievePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
|
||||
G4String particleName = particle->GetParticleName();
|
||||
if(particle->GetParticleType() == "nucleus" &&
|
||||
particleName != "GenericIon" &&
|
||||
particle->GetParticleSubType() == "generic")
|
||||
{
|
||||
|
||||
G4EnergyLossTables::Register(particle,
|
||||
theDEDXpTable,
|
||||
theRangepTable,
|
||||
theInverseRangepTable,
|
||||
theLabTimepTable,
|
||||
theProperTimepTable,
|
||||
LowestKineticEnergy, HighestKineticEnergy,
|
||||
proton_mass_c2/particle->GetPDGMass(),
|
||||
TotBin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// delete theLossTable and theMeanFreePathTable
|
||||
if (theLossTable != 0) {
|
||||
theLossTable->clearAndDestroy();
|
||||
delete theLossTable;
|
||||
}
|
||||
if (theMeanFreePathTable != 0) {
|
||||
theMeanFreePathTable->clearAndDestroy();
|
||||
delete theMeanFreePathTable;
|
||||
}
|
||||
|
||||
// get bining from EnergyLoss
|
||||
LowestKineticEnergy = GetLowerBoundEloss();
|
||||
HighestKineticEnergy = GetUpperBoundEloss();
|
||||
TotBin = GetNbinEloss();
|
||||
|
||||
G4String filename;
|
||||
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
secondaryEnergyCuts = theCoupleTable->GetEnergyCutsVector(1);
|
||||
|
||||
G4double charge = particle->GetPDGCharge()/eplus;
|
||||
G4ParticleDefinition* basep = G4Proton::Proton();
|
||||
if(charge < 0.0) basep = G4AntiProton::AntiProton();
|
||||
filename = GetPhysicsTableFileName(basep,directory,"StoppingPower",ascii);
|
||||
|
||||
theLossTable = new G4PhysicsTable(numOfCouples);
|
||||
if ( !theLossTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theLossTable0->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
BuildPhysicsTable(*particle);
|
||||
return true;
|
||||
}
|
||||
RecorderOfpProcess[0] = (*this).theLossTable;
|
||||
|
||||
// retreive mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
theMeanFreePathTable = new G4PhysicsTable(numOfCouples);
|
||||
if ( !theMeanFreePathTable->RetrievePhysicsTable(filename, ascii) ){
|
||||
G4cout << " FAIL theMeanFreePathTable->RetrievePhysicsTable in " << filename
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
initialMass = particle->GetPDGMass();
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particleName
|
||||
<< ": Success to retrieve the PhysicsTables from "
|
||||
<< directory << G4endl;
|
||||
|
||||
BuildDEDXTable(*particle);
|
||||
if (particle == G4Proton::Proton()) PrintInfoDefinition();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4hIonisation52::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = " Knock-on electron cross sections . "
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4ionIonisation.cc,v 1.23 2004/05/27 17:22:56 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-06-02 $
|
||||
// $Id: G4ionIonisation.cc,v 1.31 2004/12/01 19:37:16 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-07-00-cand-03 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -42,7 +42,8 @@
|
||||
// 18-04-03 Use IonFluctuations (V.Ivanchenko)
|
||||
// 03-08-03 Add effective charge (V.Ivanchenko)
|
||||
// 12-11-03 G4EnergyLossSTD -> G4EnergyLossProcess (V.Ivanchenko)
|
||||
// 27-05-04 Set integral to be a default regime (V.Ivanchenko)
|
||||
// 27-05-04 Set integral to be a default regime (V.Ivanchenko)
|
||||
// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko)
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
@@ -53,20 +54,30 @@
|
||||
#include "G4ionIonisation.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4Proton.hh"
|
||||
#include "G4AntiProton.hh"
|
||||
#include "G4GenericIon.hh"
|
||||
#include "G4BraggModel.hh"
|
||||
#include "G4BraggIonModel.hh"
|
||||
#include "G4BetheBlochModel.hh"
|
||||
#include "G4IonFluctuations.hh"
|
||||
#include "G4UniversalFluctuation.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
using namespace std;
|
||||
|
||||
G4ionIonisation::G4ionIonisation(const G4String& name)
|
||||
: G4VEnergyLossProcess(name),
|
||||
theParticle(0),
|
||||
theBaseParticle(0),
|
||||
isInitialised(false),
|
||||
subCutoff(false)
|
||||
{
|
||||
InitialiseProcess();
|
||||
SetDEDXBinning(120);
|
||||
SetLambdaBinning(120);
|
||||
SetMinKinEnergy(0.1*keV);
|
||||
SetMaxKinEnergy(100.0*TeV);
|
||||
SetVerboseLevel(0);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -76,18 +87,23 @@ G4ionIonisation::~G4ionIonisation()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4ionIonisation::InitialiseProcess()
|
||||
void G4ionIonisation::InitialiseEnergyLossProcess(const G4ParticleDefinition* part,
|
||||
const G4ParticleDefinition* bpart)
|
||||
{
|
||||
SetSecondaryParticle(G4Electron::Electron());
|
||||
if(isInitialised) return;
|
||||
|
||||
SetDEDXBinning(120);
|
||||
SetLambdaBinning(120);
|
||||
SetMinKinEnergy(0.1*keV);
|
||||
SetMaxKinEnergy(100.0*TeV);
|
||||
theParticle = part;
|
||||
|
||||
if(part == bpart || part == G4GenericIon::GenericIon()) theBaseParticle = 0;
|
||||
else if(bpart == 0) theBaseParticle = G4GenericIon::GenericIon();
|
||||
else theBaseParticle = bpart;
|
||||
|
||||
SetBaseParticle(theBaseParticle);
|
||||
SetSecondaryParticle(G4Electron::Electron());
|
||||
|
||||
flucModel = new G4IonFluctuations();
|
||||
|
||||
G4VEmModel* em = new G4BraggModel();
|
||||
G4VEmModel* em = new G4BraggIonModel();
|
||||
em->SetLowEnergyLimit(0.1*keV);
|
||||
em->SetHighEnergyLimit(2.0*MeV);
|
||||
AddEmModel(1, em, flucModel);
|
||||
@@ -96,20 +112,10 @@ void G4ionIonisation::InitialiseProcess()
|
||||
em1->SetHighEnergyLimit(100.0*TeV);
|
||||
AddEmModel(2, em1, flucModel);
|
||||
|
||||
chargeLowLimit = 0.1;
|
||||
energyLowLimit = 25.*MeV;
|
||||
SetLinearLossLimit(0.15);
|
||||
SetStepLimits(0.1, 0.1*mm);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4ParticleDefinition* G4ionIonisation::DefineBaseParticle(
|
||||
const G4ParticleDefinition* p)
|
||||
{
|
||||
if(p) theParticle = p;
|
||||
theBaseParticle = G4Proton::Proton();
|
||||
return theBaseParticle;
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -134,141 +140,4 @@ void G4ionIonisation::SetSubCutoff(G4bool val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4ionIonisation::EffectiveCharge(const G4ParticleDefinition* p,
|
||||
const G4Material* material,
|
||||
G4double kineticEnergy)
|
||||
{
|
||||
G4double mass = p->GetPDGMass();
|
||||
G4double charge = p->GetPDGCharge();
|
||||
G4double Zi = charge/eplus;
|
||||
|
||||
chargeCorrection = 1.0;
|
||||
|
||||
// The aproximation of ion effective charge from:
|
||||
// J.F.Ziegler, J.P. Biersack, U. Littmark
|
||||
// The Stopping and Range of Ions in Matter,
|
||||
// Vol.1, Pergamon Press, 1985
|
||||
// Fast ions or hadrons
|
||||
G4double reducedEnergy = kineticEnergy * proton_mass_c2/mass ;
|
||||
if( reducedEnergy > energyLowLimit || Zi < 1.5 ) return charge ;
|
||||
|
||||
static G4double vFermi[92] = {
|
||||
1.0309, 0.15976, 0.59782, 1.0781, 1.0486, 1.0, 1.058, 0.93942, 0.74562, 0.3424,
|
||||
0.45259, 0.71074, 0.90519, 0.97411, 0.97184, 0.89852, 0.70827, 0.39816, 0.36552, 0.62712,
|
||||
0.81707, 0.9943, 1.1423, 1.2381, 1.1222, 0.92705, 1.0047, 1.2, 1.0661, 0.97411,
|
||||
0.84912, 0.95, 1.0903, 1.0429, 0.49715, 0.37755, 0.35211, 0.57801, 0.77773, 1.0207,
|
||||
1.029, 1.2542, 1.122, 1.1241, 1.0882, 1.2709, 1.2542, 0.90094, 0.74093, 0.86054,
|
||||
0.93155, 1.0047, 0.55379, 0.43289, 0.32636, 0.5131, 0.695, 0.72591, 0.71202, 0.67413,
|
||||
0.71418, 0.71453, 0.5911, 0.70263, 0.68049, 0.68203, 0.68121, 0.68532, 0.68715, 0.61884,
|
||||
0.71801, 0.83048, 1.1222, 1.2381, 1.045, 1.0733, 1.0953, 1.2381, 1.2879, 0.78654,
|
||||
0.66401, 0.84912, 0.88433, 0.80746, 0.43357, 0.41923, 0.43638, 0.51464, 0.73087, 0.81065,
|
||||
1.9578, 1.0257} ;
|
||||
|
||||
static G4double lFactor[92] = {
|
||||
1.0, 1.0, 1.1, 1.06, 1.01, 1.03, 1.04, 0.99, 0.95, 0.9,
|
||||
0.82, 0.81, 0.83, 0.88, 1.0, 0.95, 0.97, 0.99, 0.98, 0.97,
|
||||
0.98, 0.97, 0.96, 0.93, 0.91, 0.9, 0.88, 0.9, 0.9, 0.9,
|
||||
0.9, 0.85, 0.9, 0.9, 0.91, 0.92, 0.9, 0.9, 0.9, 0.9,
|
||||
0.9, 0.88, 0.9, 0.88, 0.88, 0.9, 0.9, 0.88, 0.9, 0.9,
|
||||
0.9, 0.9, 0.96, 1.2, 0.9, 0.88, 0.88, 0.85, 0.9, 0.9,
|
||||
0.92, 0.95, 0.99, 1.03, 1.05, 1.07, 1.08, 1.1, 1.08, 1.08,
|
||||
1.08, 1.08, 1.09, 1.09, 1.1, 1.11, 1.12, 1.13, 1.14, 1.15,
|
||||
1.17, 1.2, 1.18, 1.17, 1.17, 1.16, 1.16, 1.16, 1.16, 1.16,
|
||||
1.16, 1.16} ;
|
||||
|
||||
static G4double c[6] = {0.2865, 0.1266, -0.001429,
|
||||
0.02402,-0.01135, 0.001475} ;
|
||||
|
||||
// get elements in the actual material,
|
||||
const G4ElementVector* theElementVector = material->GetElementVector() ;
|
||||
const G4double* theAtomicNumDensityVector =
|
||||
material->GetAtomicNumDensityVector() ;
|
||||
const G4int NumberOfElements = material->GetNumberOfElements() ;
|
||||
|
||||
// loop for the elements in the material
|
||||
// to find out average values Z, vF, lF
|
||||
G4double z = 0.0, vF = 0.0, lF = 0.0, norm = 0.0 ;
|
||||
|
||||
if( 1 == NumberOfElements ) {
|
||||
z = material->GetZ() ;
|
||||
G4int iz = G4int(z) - 1 ;
|
||||
if(iz < 0) iz = 0 ;
|
||||
else if(iz > 91) iz = 91 ;
|
||||
vF = vFermi[iz] ;
|
||||
lF = lFactor[iz] ;
|
||||
|
||||
} else {
|
||||
for (G4int iel=0; iel<NumberOfElements; iel++)
|
||||
{
|
||||
const G4Element* element = (*theElementVector)[iel] ;
|
||||
G4double z2 = element->GetZ() ;
|
||||
const G4double weight = theAtomicNumDensityVector[iel] ;
|
||||
norm += weight ;
|
||||
z += z2 * weight ;
|
||||
G4int iz = G4int(z2) - 1 ;
|
||||
if(iz < 0) iz = 0 ;
|
||||
else if(iz > 91) iz =91 ;
|
||||
vF += vFermi[iz] * weight ;
|
||||
lF += lFactor[iz] * weight ;
|
||||
}
|
||||
z /= norm ;
|
||||
vF /= norm ;
|
||||
lF /= norm ;
|
||||
}
|
||||
|
||||
G4double q;
|
||||
// Helium ion case
|
||||
if( Zi < 2.5 ) {
|
||||
|
||||
// Normalise to He4 mass
|
||||
G4double e = log(std::max(1.0, kineticEnergy / (keV*4.0026) ) );
|
||||
G4double x = c[0] ;
|
||||
G4double y = 1.0 ;
|
||||
for (G4int i=1; i<6; i++) {
|
||||
y *= e ;
|
||||
x += y * c[i] ;
|
||||
}
|
||||
q = 7.6 - e ;
|
||||
q = 1.0 + ( 0.007 + 0.00005 * z ) * exp( -q*q ) * sqrt(1.0 - exp(-x)) ;
|
||||
if( q < chargeLowLimit ) q = chargeLowLimit ;
|
||||
|
||||
// Heavy ion case
|
||||
} else {
|
||||
// v1 is ion velocity in vF unit
|
||||
G4double v1 = sqrt( reducedEnergy / (25.0 * keV) )/ vF ;
|
||||
G4double y ;
|
||||
G4double z13 = pow(Zi, 0.3333) ;
|
||||
|
||||
// Faster than Fermi velocity
|
||||
if ( v1 > 1.0 ) {
|
||||
y = vF * v1 * ( 1.0 + 0.2 / (v1*v1) ) / (z13*z13) ;
|
||||
|
||||
// Slower than Fermi velocity
|
||||
} else {
|
||||
y = 0.6923 * vF * (1.0 + 2.0*v1*v1/3.0 + v1*v1*v1*v1/15.0) / (z13*z13) ;
|
||||
}
|
||||
|
||||
G4double y3 = pow(y, 0.3) ;
|
||||
// G4cout << "y= " << y << " y3= " << y3 << " v1= " << v1 << " vF= " << vF << G4endl;
|
||||
q = 1.0 - exp( 0.803*y3 - 1.3167*y3*y3 - 0.38157*y - 0.008983*y*y ) ;
|
||||
|
||||
if( q < chargeLowLimit ) q = chargeLowLimit ;
|
||||
|
||||
G4double s = 7.6 - log(std::max(1.0, reducedEnergy/keV)) ;
|
||||
s = 1.0 + ( 0.18 + 0.0015 * z ) * exp( -s*s )/ (Zi*Zi) ;
|
||||
|
||||
// Screen length according to
|
||||
// J.F.Ziegler and J.M.Manoyan, The stopping of ions in compaunds,
|
||||
// Nucl. Inst. & Meth. in Phys. Res. B35 (1988) 215-228.
|
||||
|
||||
G4double lambda = 10.0 * vF * pow(1.0-q, 0.6667) / (z13 * (6.0 + q)) ;
|
||||
chargeCorrection = s * (1.0 + 0.5*(1.0/q - 1.0)*log(1.0 + lambda*lambda)/(vF*vF) );
|
||||
}
|
||||
// G4cout << "G4ionIonisation: charge= " << charge << " q= " << q
|
||||
// << " chargeCor= " << chargeCorrection << G4endl;
|
||||
return charge*q;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user