Import Geant4 5.1.0 source tree
This commit is contained in:
@@ -29,10 +29,15 @@
|
||||
// File name: G4BetheBlochModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko on base of Laszlo Urban code
|
||||
//
|
||||
//
|
||||
// Creation date: 03.01.2002
|
||||
//
|
||||
// Modifications: 04.12.2002 VI Fix problem of G4DynamicParticle constructor
|
||||
// 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)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -47,13 +52,13 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BetheBlochModel::G4BetheBlochModel(const G4ParticleDefinition* p)
|
||||
: G4VEmModel(),
|
||||
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),
|
||||
bg2lim(0.0169),
|
||||
taulim(8.4146e-3)
|
||||
{
|
||||
if(p) SetParticle(p);
|
||||
@@ -61,12 +66,12 @@ G4BetheBlochModel::G4BetheBlochModel(const G4ParticleDefinition* p)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BetheBlochModel::~G4BetheBlochModel()
|
||||
G4BetheBlochModel::~G4BetheBlochModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BetheBlochModel::SetParticle(const G4ParticleDefinition* p)
|
||||
void G4BetheBlochModel::SetParticle(const G4ParticleDefinition* p)
|
||||
{
|
||||
particle = p;
|
||||
mass = particle->GetPDGMass();
|
||||
@@ -80,17 +85,15 @@ void G4BetheBlochModel::SetParticle(const G4ParticleDefinition* p)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BetheBlochModel::HighEnergyLimit(const G4ParticleDefinition* p,
|
||||
const G4Material*)
|
||||
G4double G4BetheBlochModel::HighEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return highKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BetheBlochModel::LowEnergyLimit(const G4ParticleDefinition* p,
|
||||
const G4Material*)
|
||||
G4double G4BetheBlochModel::LowEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return lowKinEnergy;
|
||||
@@ -99,32 +102,39 @@ G4double G4BetheBlochModel::LowEnergyLimit(const G4ParticleDefinition* p,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BetheBlochModel::MinEnergyCut(const G4ParticleDefinition* p,
|
||||
const G4Material* material)
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
return material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BetheBlochModel::IsInCharge(const G4ParticleDefinition* p,
|
||||
const G4Material*)
|
||||
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 G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy)
|
||||
G4double cutEnergy)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
G4double tau = kineticEnergy/mass;
|
||||
G4double x = 1.0;
|
||||
if(cutEnergy < tmax) x = cutEnergy/tmax;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double beta2 = 1. - 1./(gam*gam);
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
|
||||
@@ -190,24 +200,23 @@ G4double G4BetheBlochModel::CrossSection(const G4Material* material,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
G4double cross = 0.0;
|
||||
G4double tmax = G4std::min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
|
||||
if(cutEnergy < tmax) {
|
||||
|
||||
|
||||
G4double x = cutEnergy/tmax;
|
||||
G4double energy = kineticEnergy + mass;
|
||||
G4double gam = energy/mass;
|
||||
G4double beta2 = 1. - 1./(gam*gam);
|
||||
cross = (1.0 - x*(1.0 - beta2*log(x)))/cutEnergy;
|
||||
|
||||
|
||||
// +term for spin=1/2 particle
|
||||
if( 0.5 == spin ) {
|
||||
cross += 0.5 * (tmax - cutEnergy) / (energy*energy);
|
||||
|
||||
|
||||
// +term for spin=1 particle
|
||||
} else if( 0.9 < spin ) {
|
||||
|
||||
|
||||
cross += -log(x)/(3.0*qc) +
|
||||
(tmax - cutEnergy) * ((1.0+ 0.25*tmax*(1.0 + x)/qc)/(energy*energy)
|
||||
- beta2 / (tmax * qc) )/3.0;
|
||||
@@ -222,11 +231,11 @@ G4double G4BetheBlochModel::CrossSection(const G4Material* material,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* G4BetheBlochModel::SampleSecondary(
|
||||
const G4Material* material,
|
||||
G4DynamicParticle* G4BetheBlochModel::SampleSecondary(
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4double tmax = MaxSecondaryEnergy(dp);
|
||||
G4double xmin = tmin/tmax;
|
||||
@@ -253,7 +262,7 @@ G4std::vector<G4DynamicParticle*>* G4BetheBlochModel::SampleSecondary(
|
||||
}
|
||||
G4double z, f;
|
||||
|
||||
// sampling follows ...
|
||||
// sampling follows ...
|
||||
do {
|
||||
G4double q = G4UniformRand();
|
||||
z = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
|
||||
@@ -267,34 +276,48 @@ G4std::vector<G4DynamicParticle*>* G4BetheBlochModel::SampleSecondary(
|
||||
G4cout << "G4BetheBlochModel::SampleSecondary Warning! "
|
||||
<< "Majorant " << grej << " < "
|
||||
<< f << " for x= " << z
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
} while( grej*G4UniformRand() > f );
|
||||
|
||||
|
||||
G4double deltaKinEnergy = z * tmax;
|
||||
|
||||
G4double deltaMomentum =
|
||||
|
||||
G4double deltaMomentum =
|
||||
sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
|
||||
G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
|
||||
(deltaMomentum * totMomentum);
|
||||
G4double sint = sqrt(1.0 - cost*cost);
|
||||
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
|
||||
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();
|
||||
delta->SetDefinition(G4Electron::Electron());
|
||||
delta->SetKineticEnergy(deltaKinEnergy);
|
||||
delta->SetMomentumDirection(deltaDirection);
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* G4BetheBlochModel::SampleSecondaries(
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4std::vector<G4DynamicParticle*>* vdp = new G4std::vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
|
||||
return vdp;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4BohrFluctuations
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 02.04.2003
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
//
|
||||
// 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....
|
||||
|
||||
G4BohrFluctuations::G4BohrFluctuations(const G4String& nam)
|
||||
:G4VEmFluctuationModel(nam),
|
||||
minNumberInteractionsBohr(10.0),
|
||||
minFraction(0.2)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BohrFluctuations::~G4BohrFluctuations()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BohrFluctuations::Initialise(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)
|
||||
{
|
||||
G4double siga = Dispersion(material,dp,tmax,length);
|
||||
G4double loss = meanLoss;
|
||||
|
||||
// Gaussian fluctuation
|
||||
if (meanLoss >= minNumberInteractionsBohr*tmax) {
|
||||
|
||||
// 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);
|
||||
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);
|
||||
do {
|
||||
loss = G4RandGauss::shoot(meanLoss,siga);
|
||||
} while (loss < 0. || loss > 2.*meanLoss);
|
||||
|
||||
// Poisson fluctuations
|
||||
} else {
|
||||
G4double navr = meanLoss*meanLoss/siga;
|
||||
G4double n = (G4double)G4Poisson(navr);
|
||||
loss = meanLoss*n/navr;
|
||||
}
|
||||
|
||||
return loss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
@@ -32,12 +32,17 @@
|
||||
//
|
||||
// Creation date: 03.01.2002
|
||||
//
|
||||
// Modifications: 04.12.2002 VI Fix problem of G4DynamicParticle constructor
|
||||
// Modifications:
|
||||
//
|
||||
// Class Description:
|
||||
// 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)
|
||||
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of energy loss and delta-electron production by
|
||||
// slow charged heavy particles
|
||||
// Implementation of energy loss and delta-electron production by
|
||||
// slow charged heavy particles
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -52,8 +57,8 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BraggModel::G4BraggModel(const G4ParticleDefinition* p)
|
||||
: G4VEmModel(),
|
||||
G4BraggModel::G4BraggModel(const G4ParticleDefinition* p, const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
particle(0),
|
||||
highKinEnergy(2.0*MeV),
|
||||
lowKinEnergy(0.0*MeV),
|
||||
@@ -66,12 +71,12 @@ G4BraggModel::G4BraggModel(const G4ParticleDefinition* p)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4BraggModel::~G4BraggModel()
|
||||
G4BraggModel::~G4BraggModel()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4BraggModel::SetParticle(const G4ParticleDefinition* p)
|
||||
void G4BraggModel::SetParticle(const G4ParticleDefinition* p)
|
||||
{
|
||||
particle = p;
|
||||
mass = particle->GetPDGMass();
|
||||
@@ -85,17 +90,15 @@ void G4BraggModel::SetParticle(const G4ParticleDefinition* p)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::HighEnergyLimit(const G4ParticleDefinition* p,
|
||||
const G4Material*)
|
||||
G4double G4BraggModel::HighEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return highKinEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::LowEnergyLimit(const G4ParticleDefinition* p,
|
||||
const G4Material*)
|
||||
G4double G4BraggModel::LowEnergyLimit(const G4ParticleDefinition* p)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
return lowKinEnergy;
|
||||
@@ -104,27 +107,34 @@ G4double G4BraggModel::LowEnergyLimit(const G4ParticleDefinition* p,
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4BraggModel::MinEnergyCut(const G4ParticleDefinition* p,
|
||||
const G4Material* material)
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
return material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BraggModel::IsInCharge(const G4ParticleDefinition* p,
|
||||
const G4Material*)
|
||||
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 G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy)
|
||||
G4double cutEnergy)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
|
||||
G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
|
||||
G4double dedx = DEDX(material, kineticEnergy/massRate);
|
||||
@@ -133,20 +143,20 @@ G4double G4BraggModel::ComputeDEDX(const G4Material* material,
|
||||
|
||||
G4double x = cutEnergy/tmax;
|
||||
G4double tau = kineticEnergy/mass;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double beta2 = 1. - 1./(gam*gam);
|
||||
// G4double bg2 = tau * (tau+2.0);
|
||||
dedx += (log(x) + (1.0 - x)*beta2) * twopi_mc2_rcl2
|
||||
// G4double bg2 = tau * (tau+2.0);
|
||||
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;
|
||||
|
||||
return dedx;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -155,9 +165,9 @@ G4double G4BraggModel::CrossSection(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double cutEnergy,
|
||||
G4double maxEnergy)
|
||||
G4double maxEnergy)
|
||||
{
|
||||
if(!particle) SetParticle(p);
|
||||
|
||||
G4double cross = 0.0;
|
||||
G4double tmax = G4std::min(MaxSecondaryEnergy(p, kineticEnergy), maxEnergy);
|
||||
if(cutEnergy < tmax) {
|
||||
@@ -177,11 +187,11 @@ G4double G4BraggModel::CrossSection(const G4Material* material,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* G4BraggModel::SampleSecondary(
|
||||
const G4Material* material,
|
||||
G4DynamicParticle* G4BraggModel::SampleSecondary(
|
||||
const G4MaterialCutsCouple*,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4double tmax = MaxSecondaryEnergy(dp);
|
||||
G4double xmin = tmin/tmax;
|
||||
@@ -193,10 +203,10 @@ G4std::vector<G4DynamicParticle*>* G4BraggModel::SampleSecondary(
|
||||
G4double beta2 = 1. - mass*mass/(energy*energy);
|
||||
G4double grej = 1.0 - beta2*xmin;
|
||||
G4double z, f;
|
||||
|
||||
|
||||
G4ThreeVector momentum = dp->GetMomentumDirection();
|
||||
|
||||
// sampling follows ...
|
||||
// sampling follows ...
|
||||
do {
|
||||
G4double q = G4UniformRand();
|
||||
z = xmin*xmax/(xmin*(1.0 - q) + xmax*q);
|
||||
@@ -207,21 +217,21 @@ G4std::vector<G4DynamicParticle*>* G4BraggModel::SampleSecondary(
|
||||
G4cout << "G4BraggModel::SampleSecondary Warning! "
|
||||
<< "Majorant " << grej << " < "
|
||||
<< f << " for x= " << z
|
||||
<< G4endl;
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
} while( grej*G4UniformRand() >= f );
|
||||
|
||||
|
||||
G4double deltaKinEnergy = z * tmax;
|
||||
|
||||
G4double deltaMomentum =
|
||||
|
||||
G4double deltaMomentum =
|
||||
sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
|
||||
G4double totMomentum = sqrt(energy*energy - mass*mass);
|
||||
G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
|
||||
(deltaMomentum * totMomentum);
|
||||
G4double sint = sqrt(1.0 - cost*cost);
|
||||
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
|
||||
G4double phi = twopi * G4UniformRand() ;
|
||||
|
||||
G4ThreeVector deltaDirection(sint*cos(phi),sint*sin(phi), cost) ;
|
||||
deltaDirection.rotateUz(momentum);
|
||||
@@ -232,7 +242,19 @@ G4std::vector<G4DynamicParticle*>* G4BraggModel::SampleSecondary(
|
||||
delta->SetKineticEnergy(deltaKinEnergy);
|
||||
delta->SetMomentumDirection(deltaDirection);
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4std::vector<G4DynamicParticle*>* G4BraggModel::SampleSecondaries(
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double tmin,
|
||||
G4double maxEnergy)
|
||||
{
|
||||
G4std::vector<G4DynamicParticle*>* vdp = new G4std::vector<G4DynamicParticle*>;
|
||||
G4DynamicParticle* delta = SampleSecondary(couple, dp, tmin, maxEnergy);
|
||||
vdp->push_back(delta);
|
||||
|
||||
return vdp;
|
||||
@@ -240,7 +262,7 @@ G4std::vector<G4DynamicParticle*>* G4BraggModel::SampleSecondary(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4BraggModel::HasMaterial(const G4Material* material)
|
||||
G4bool G4BraggModel::HasMaterial(const G4Material* material)
|
||||
{
|
||||
G4String chFormula = material->GetChemicalFormula() ;
|
||||
G4String myFormula = G4String(" ") ;
|
||||
@@ -251,10 +273,10 @@ G4bool G4BraggModel::HasMaterial(const G4Material* material)
|
||||
}
|
||||
|
||||
// ICRU Report N49, 1993. Power's model for He.
|
||||
const size_t numberOfMolecula = 11 ;
|
||||
const size_t numberOfMolecula = 11 ;
|
||||
static G4String name[numberOfMolecula] = {
|
||||
"Al_2O_3", "CO_2", "CH_4",
|
||||
"(C_2H_4)_N-Polyethylene", "(C_2H_4)_N-Polypropylene", "(C_8H_8)_N",
|
||||
"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" } ;
|
||||
|
||||
@@ -335,7 +357,7 @@ G4double G4BraggModel::StoppingPower(const G4Material* material,
|
||||
}
|
||||
|
||||
return ionloss;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -655,7 +677,7 @@ G4double G4BraggModel::ChemicalFactor(G4double kineticEnergy,
|
||||
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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,15 +28,23 @@
|
||||
//
|
||||
// File name: G4EmModelManager
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 07.05.2002
|
||||
//
|
||||
// Modifications:
|
||||
// Modifications:
|
||||
//
|
||||
// Class Description:
|
||||
// 23-12-02 V.Ivanchenko change interface in order to move
|
||||
// to cut per region
|
||||
// 20-01-03 Migrade to cut per region (V.Ivanchenko)
|
||||
// 24-01-03 Make models region aware (V.Ivanchenko)
|
||||
// 13-02-03 The set of models is defined for region (V.Ivanchenko)
|
||||
// 06-03-03 Fix in energy intervals for models (V.Ivanchenko)
|
||||
// 13-04-03 Add startFromNull (V.Ivanchenko)
|
||||
//
|
||||
// It is the unified energy loss process it calculates the continuous
|
||||
// Class Description:
|
||||
//
|
||||
// It is the unified energy loss process it calculates the continuous
|
||||
// energy loss for charged particles using a set of Energy Loss
|
||||
// models valid for different energy regions. There are a possibility
|
||||
// to create and access to dE/dx and range tables, or to calculate
|
||||
@@ -45,41 +53,88 @@
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
#include "G4EmModelManager.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4RegionModels::G4RegionModels(G4int nMod, G4std::vector<G4int>& list, G4DataVector& lowE)
|
||||
{
|
||||
nModelsForRegion = nMod;
|
||||
theListOfModelIndexes = new G4int [nModelsForRegion];
|
||||
lowKineticEnergy = new G4double [nModelsForRegion];
|
||||
for (G4int i=0; i<nModelsForRegion; i++) {
|
||||
theListOfModelIndexes[i] = list[i];
|
||||
lowKineticEnergy[i] = lowE[i];
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4RegionModels::~G4RegionModels()
|
||||
{
|
||||
delete [] theListOfModelIndexes;
|
||||
delete [] lowKineticEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmModelManager::G4EmModelManager():
|
||||
nEmModels(0),
|
||||
nmax(4),
|
||||
orderIsChanged(false),
|
||||
nRegions(0),
|
||||
nCouples(0),
|
||||
minSubRange(0.1),
|
||||
particle(0)
|
||||
particle(0),
|
||||
verboseLevel(0)
|
||||
{
|
||||
verboseLevel = 0;
|
||||
for(G4int i = 0; i<nmax; i++) {
|
||||
emModels[i] = 0;
|
||||
order[i] = 0;
|
||||
upperEkin[i] = 0.0;
|
||||
}
|
||||
models.clear();
|
||||
flucModels.clear();
|
||||
regions.clear();
|
||||
orderOfModels.clear();
|
||||
upperEkin.clear();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmModelManager::~G4EmModelManager()
|
||||
{
|
||||
G4int i,j;
|
||||
Clear();
|
||||
for(G4int i = 0; i<nmax; i++) {
|
||||
if(emModels[i]) delete emModels[i];
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
orderOfModels[i] = 1;
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
if (orderOfModels[i]) {
|
||||
orderOfModels[i] = 0;
|
||||
for(j = i+1; j<nEmModels; j++) {
|
||||
if(models[i] == models[j]) orderOfModels[j] = 0;
|
||||
}
|
||||
delete models[i];
|
||||
}
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
orderOfModels[i] = 1;
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
if (orderOfModels[i]) {
|
||||
orderOfModels[i] = 0;
|
||||
for(j = i+1; j<nEmModels; j++) {
|
||||
if(flucModels[i] == flucModels[j]) orderOfModels[j] = 0;
|
||||
}
|
||||
delete flucModels[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,18 +148,52 @@ void G4EmModelManager::Clear()
|
||||
|
||||
theCuts.clear();
|
||||
theSubCuts.clear();
|
||||
upperEkin.clear();
|
||||
idxOfRegionModels.clear();
|
||||
setOfRegionModels.clear();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
void G4EmModelManager::AddEmModel(G4int num, G4VEmModel* p,
|
||||
G4VEmFluctuationModel* fm, const G4Region* r)
|
||||
{
|
||||
if(!p) {
|
||||
G4cout << "G4EmModelManager::AddEmModel WARNING: no model defined." << G4endl;
|
||||
return;
|
||||
}
|
||||
models.push_back(p);
|
||||
flucModels.push_back(fm);
|
||||
regions.push_back(r);
|
||||
orderOfModels.push_back(num);
|
||||
if (nEmModels) {
|
||||
G4int idx = nEmModels;
|
||||
do {idx--;} while (idx && num < orderOfModels[idx]);
|
||||
if (num >= orderOfModels[idx] && num <= orderOfModels[idx+1]) idx++;
|
||||
if (idx < nEmModels) {
|
||||
models[nEmModels] = models[idx];
|
||||
flucModels[nEmModels] = flucModels[idx];
|
||||
regions[nEmModels] = regions[idx];
|
||||
orderOfModels[nEmModels] = orderOfModels[idx];
|
||||
models[idx] = p;
|
||||
flucModels[idx] = fm;
|
||||
regions[idx] = r;
|
||||
orderOfModels[idx] = num;
|
||||
}
|
||||
}
|
||||
nEmModels++;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
const G4ParticleDefinition* sp,
|
||||
G4double theMinSubRange,
|
||||
G4int val)
|
||||
{
|
||||
// Are models defined?
|
||||
if(!nEmModels) {
|
||||
G4Exception("G4EmModelManager::Initialise without any model defined");
|
||||
G4Exception("G4EmModelManager::Initialise without any model defined");
|
||||
}
|
||||
particle = p;
|
||||
secondaryParticle = sp;
|
||||
@@ -112,188 +201,161 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
verboseLevel = val;
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::Initialise() for "
|
||||
<< p->GetParticleName()
|
||||
G4cout << "### G4EmModelManager::Initialise() for "
|
||||
<< p->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
Clear();
|
||||
|
||||
// Ordering
|
||||
if(orderIsChanged) {
|
||||
G4int oldOrder[5];
|
||||
G4VEmModel* oldEmModels[5];
|
||||
for(G4int k = 0; k<nmax; k++) {
|
||||
oldEmModels[k] = emModels[k];
|
||||
oldOrder[k] = order[k];
|
||||
}
|
||||
G4RegionStore* regionStore = G4RegionStore::GetInstance();
|
||||
const G4Region* world = regionStore->GetRegion("DefaultRegionForTheWorld", false);
|
||||
|
||||
// Identify the list of regions with different set of models
|
||||
nRegions = 1;
|
||||
G4std::vector<const G4Region*> set;
|
||||
set.push_back(world);
|
||||
|
||||
for(G4int ik=0; ik<nEmModels; ik++) {
|
||||
|
||||
G4int low = INT_MAX;
|
||||
G4int index = 0;
|
||||
for(G4int kk=0; kk<nEmModels; kk++) {
|
||||
if(oldEmModels[kk]) {
|
||||
if(oldOrder[kk] < low) {
|
||||
low = oldOrder[kk];
|
||||
index = kk;
|
||||
}
|
||||
}
|
||||
for (G4int ii=0; ii<nEmModels; ii++) {
|
||||
const G4Region* r = regions[ii];
|
||||
if ( r && r != world) {
|
||||
G4bool newRegion = true;
|
||||
if (nRegions>1) {
|
||||
for (G4int j=1; j<nRegions; j++) {
|
||||
if ( r == set[j] ) newRegion = false;
|
||||
}
|
||||
}
|
||||
if (newRegion) {
|
||||
set.push_back(r);
|
||||
nRegions++;
|
||||
}
|
||||
emModels[ik] = oldEmModels[index];
|
||||
order[ik] = ik;
|
||||
oldEmModels[index] = 0;
|
||||
}
|
||||
orderIsChanged = false;
|
||||
}
|
||||
|
||||
G4DataVector eLow;
|
||||
eLow.clear();
|
||||
setOfRegionModels.clear();
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
idxOfRegionModels.resize(numOfCouples);
|
||||
upperEkin.resize(nEmModels);
|
||||
|
||||
G4int n = 0;
|
||||
// Order models for regions
|
||||
for (G4int reg=0; reg<nRegions; reg++) {
|
||||
|
||||
for(G4int j=0; j<nEmModels; j++) {
|
||||
const G4Region* region = set[reg];
|
||||
|
||||
G4double ep = 0.0;
|
||||
if(0 < n) ep = upperEkin[n-1];
|
||||
G4VEmModel* model = emModels[j];
|
||||
G4bool accepted = false;
|
||||
G4int n = 0;
|
||||
|
||||
if(model->IsInCharge(particle, 0)) {
|
||||
G4std::vector<G4int> modelAtRegion;
|
||||
G4DataVector eLow;
|
||||
G4DataVector eHigh;
|
||||
modelAtRegion.clear();
|
||||
eLow.clear();
|
||||
eHigh.clear();
|
||||
|
||||
G4double tmin = model->LowEnergyLimit(particle, 0);
|
||||
G4double tmax = model->HighEnergyLimit(particle, 0);
|
||||
for (G4int ii=0; ii<nEmModels; ii++) {
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "New model for tmin(MeV)= " << tmin/MeV
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< "; tlast(MeV)= " << ep/MeV
|
||||
G4VEmModel* model = models[ii];
|
||||
if ( (model->IsInCharge(particle)) &&
|
||||
(0 == regions[ii] || region == regions[ii]) )
|
||||
{
|
||||
|
||||
G4double tmin = model->LowEnergyLimit(particle);
|
||||
G4double tmax = model->HighEnergyLimit(particle);
|
||||
if (n) tmin = G4std::max(tmin, eHigh[n-1]);
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Model # " << ii << " for region <"
|
||||
<< region->GetName() << "> "
|
||||
<< " tmin(MeV)= " << tmin/MeV
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(tmax > tmin) {
|
||||
|
||||
if(n == 0 || tmax > upperEkin[n-1]) {
|
||||
|
||||
// First model or next model for more high energy range;
|
||||
upperEkin[n] = (tmax);
|
||||
if(0 < n) tmin = G4std::max(tmin, upperEkin[n-1]);
|
||||
eLow.push_back(tmin);
|
||||
n++;
|
||||
accepted = true;
|
||||
|
||||
} else {
|
||||
|
||||
G4cout << "The model number #" << j
|
||||
<< " has no active range "
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< "; tlast(MeV)= " << ep/MeV
|
||||
<< G4endl;
|
||||
if (tmin < tmax) {
|
||||
modelAtRegion.push_back(ii);
|
||||
eLow.push_back(tmin);
|
||||
eHigh.push_back(tmax);
|
||||
upperEkin[ii] = tmax;
|
||||
n++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
G4cout << "The model number #" << j
|
||||
<< " has no active range "
|
||||
<< "; tmin(MeV)= " << tmin/MeV
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
if(!accepted) {
|
||||
upperEkin[n] = ep;
|
||||
eLow.push_back(ep);
|
||||
n++;
|
||||
eLow[0] = 0.0;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "New G4RegionModels set with " << n << " models for region <"
|
||||
<< region->GetName() << "> " << G4endl;
|
||||
}
|
||||
G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow);
|
||||
setOfRegionModels.push_back(rm);
|
||||
}
|
||||
|
||||
// Access to materials and build cuts
|
||||
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
size_t nMaterials = G4Material::GetNumberOfMaterials();
|
||||
for(size_t i=0; i<numOfCouples; i++) {
|
||||
|
||||
for(size_t i=0; i<nMaterials; i++) {
|
||||
|
||||
const G4Material* material = (*theMaterialTable)[i];
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
const G4ProductionCuts* pcuts = couple->GetProductionCuts();
|
||||
G4int reg = nRegions;
|
||||
do {reg--;} while (reg>0 && pcuts != (set[reg]->GetProductionCuts()));
|
||||
idxOfRegionModels[i] = reg;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::Initialise() for "
|
||||
G4cout << "G4EmModelManager::Initialise() for "
|
||||
<< material->GetName() << G4endl;
|
||||
}
|
||||
|
||||
G4double cut = 0.0;
|
||||
G4double subcut = 0.0;
|
||||
if(secondaryParticle) {
|
||||
cut = secondaryParticle->GetEnergyThreshold(material);
|
||||
size_t idx = 1;
|
||||
if( secondaryParticle == G4Gamma::Gamma() ) idx = 0;
|
||||
cut = (*theCoupleTable->GetEnergyCutsVector(idx))[i];
|
||||
subcut = minSubRange*cut;
|
||||
}
|
||||
|
||||
for(G4int j=0; j<nEmModels; j++) {
|
||||
G4int nm = setOfRegionModels[reg]->NumberOfModels();
|
||||
for(G4int j=0; j<nm; j++) {
|
||||
|
||||
G4VEmModel* model = emModels[j];
|
||||
if(upperEkin[j] > eLow[j]) {
|
||||
G4VEmModel* model = models[setOfRegionModels[reg]->ModelIndex(j)];
|
||||
|
||||
G4double tcutmin = model->MinEnergyCut(particle, material);
|
||||
G4double tcutmin = model->MinEnergyCut(particle, couple);
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "The model # " << j
|
||||
<< "; tcutmin(MeV)= " << tcutmin/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
cut = G4std::max(cut, tcutmin);
|
||||
subcut = G4std::max(subcut, tcutmin);
|
||||
cut = G4std::max(cut, tcutmin);
|
||||
G4double x = G4std::max(cut*minSubRange, tcutmin);
|
||||
subcut = G4std::max(subcut, x);
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "The model # " << j
|
||||
<< "; tcutmin(MeV)= " << tcutmin/MeV
|
||||
<< "; tcut(MeV)= " << cut/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
theCuts.push_back(cut);
|
||||
theSubCuts.push_back(subcut);
|
||||
}
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager is initialised "
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
return &theCuts;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::AddEmModel(G4VEmModel* p, G4int num)
|
||||
{
|
||||
if(nEmModels) {
|
||||
for(G4int i=0; i<nEmModels; i++) {
|
||||
if(num < order[i]) orderIsChanged = true;
|
||||
}
|
||||
for(G4int jj=0; jj<nEmModels; jj++) {
|
||||
models[jj]->Initialise(particle, theCuts);
|
||||
if(flucModels[jj]) flucModels[jj]->Initialise(particle);
|
||||
}
|
||||
|
||||
if(nEmModels == nmax) {
|
||||
|
||||
G4cout << "G4EmModelManager::AddEmModel WARNING: cannot accept model #"
|
||||
<< nEmModels << " - the list is closed"
|
||||
<< G4endl;
|
||||
|
||||
} else {
|
||||
|
||||
emModels[nEmModels] = p;
|
||||
order[nEmModels] = num;
|
||||
currentModel = p;
|
||||
nEmModels++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
const G4Material* material)
|
||||
{
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::FillDEDXVector() for "
|
||||
<< material->GetName()
|
||||
G4cout << "G4EmModelManager is initialised "
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
return &theCuts;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
|
||||
// vectors to provide continues dE/dx
|
||||
G4DataVector factor;
|
||||
G4DataVector dedxLow;
|
||||
@@ -301,42 +363,59 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
|
||||
G4double e;
|
||||
|
||||
G4int i = material->GetIndex();
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
size_t i = couple->GetIndex();
|
||||
G4double cut = theCuts[i];
|
||||
factor.resize(nEmModels);
|
||||
dedxLow.resize(nEmModels);
|
||||
dedxHigh.resize(nEmModels);
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "There are " << nEmModels << " models for "
|
||||
<< material->GetName() << G4endl;
|
||||
G4cout << "G4EmModelManager::FillDEDXVector() for "
|
||||
<< material->GetName()
|
||||
<< " Ecut(MeV)= " << cut/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4int reg = idxOfRegionModels[i];
|
||||
const G4RegionModels* regModels = setOfRegionModels[reg];
|
||||
G4int nmod = regModels->NumberOfModels();
|
||||
factor.resize(nmod);
|
||||
dedxLow.resize(nmod);
|
||||
dedxHigh.resize(nmod);
|
||||
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "There are " << nmod << " models for "
|
||||
<< material->GetName()
|
||||
<< " at the region #" << reg
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
// calculate factors to provide continuity of energy loss
|
||||
factor[0] = 1.0;
|
||||
G4int j;
|
||||
|
||||
G4int totBinsLoss = aVector->GetVectorLength();
|
||||
|
||||
dedxLow[0] = 0.0;
|
||||
|
||||
e = upperEkin[0];
|
||||
dedxHigh[0] = emModels[0]->ComputeDEDX(material,particle,e,cut);
|
||||
e = upperEkin[regModels->ModelIndex(0)];
|
||||
dedxHigh[0] = models[regModels->ModelIndex(0)]->ComputeDEDX(material,particle,e,cut);
|
||||
|
||||
if(nEmModels > 1) {
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(nmod > 1) {
|
||||
for(j=1; j<nmod; j++) {
|
||||
|
||||
e = upperEkin[j-1];
|
||||
dedxLow[j] = emModels[j]->ComputeDEDX(material,particle,e,cut);
|
||||
e = upperEkin[j];
|
||||
dedxHigh[j] = emModels[j]->ComputeDEDX(material,particle,e,cut);
|
||||
e = upperEkin[regModels->ModelIndex(j-1)];
|
||||
dedxLow[j] = models[regModels->ModelIndex(j)]->ComputeDEDX(material,particle,e,cut);
|
||||
e = upperEkin[regModels->ModelIndex(j)];
|
||||
dedxHigh[j] = models[regModels->ModelIndex(j)]->ComputeDEDX(material,particle,e,cut);
|
||||
}
|
||||
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(dedxLow[j] > 0.0) factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0);
|
||||
for(j=1; j<nmod; j++) {
|
||||
if(dedxLow[j] > 0.0) factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0);
|
||||
else factor[j] = 0.0;
|
||||
}
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Loop over " << totBinsLoss << " bins start " << G4endl;
|
||||
}
|
||||
}
|
||||
@@ -349,22 +428,21 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
|
||||
// Choose a model of energy losses
|
||||
G4int k = 0;
|
||||
if(nEmModels > 1) {
|
||||
if (e >= upperEkin[0]) {
|
||||
for(k=1; k<nEmModels; k++) {
|
||||
fac *= (1.0 + factor[k]*upperEkin[k-1]/e);
|
||||
if(e <= upperEkin[k]) break;
|
||||
}
|
||||
}
|
||||
if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
|
||||
do {
|
||||
k++;
|
||||
fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
|
||||
} while (k<nmod-1 && e < upperEkin[regModels->ModelIndex(k)] );
|
||||
}
|
||||
|
||||
G4double dedx = emModels[k]->ComputeDEDX(material,particle,e,cut)*fac;
|
||||
G4double dedx = models[regModels->ModelIndex(k)]->ComputeDEDX(material,particle,e,cut)*fac;
|
||||
|
||||
if(dedx < 0.0) dedx = 0.0;
|
||||
if(0 < verboseLevel) {
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Material= " << material->GetName()
|
||||
<< " E(MeV)= " << e/MeV
|
||||
<< " dEdx(MeV/mm)= " << dedx*mm/MeV
|
||||
<< " E(MeV)= " << e/MeV
|
||||
<< " dEdx(MeV/mm)= " << dedx*mm/MeV
|
||||
<< " fac= " << fac
|
||||
<< G4endl;
|
||||
}
|
||||
aVector->PutValue(j, dedx);
|
||||
@@ -374,16 +452,11 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
const G4Material* material)
|
||||
void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4bool startFromNull)
|
||||
{
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::FillLambdaVector() for particle "
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
|
||||
// vectors to provide continues dE/dx
|
||||
G4DataVector factor;
|
||||
G4DataVector sigmaLow;
|
||||
@@ -391,14 +464,28 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
G4double e;
|
||||
|
||||
G4int i = material->GetIndex();
|
||||
G4double cut = theCuts[i];
|
||||
factor.resize(nEmModels);
|
||||
sigmaLow.resize(nEmModels);
|
||||
sigmaHigh.resize(nEmModels);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "There are " << nEmModels << " models for "
|
||||
G4cout << "G4EmModelManager::FillLambdaVector() for particle "
|
||||
<< particle->GetParticleName()
|
||||
<< " in " << material->GetName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
size_t i = couple->GetIndex();
|
||||
G4double cut = theCuts[i];
|
||||
|
||||
G4int reg = idxOfRegionModels[i];
|
||||
const G4RegionModels* regModels = setOfRegionModels[reg];
|
||||
G4int nmod = regModels->NumberOfModels();
|
||||
factor.resize(nmod);
|
||||
sigmaLow.resize(nmod);
|
||||
sigmaHigh.resize(nmod);
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "There are " << nmod << " models for "
|
||||
<< material->GetName() << G4endl;
|
||||
}
|
||||
|
||||
@@ -409,31 +496,31 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
sigmaLow[0] = 0.0;
|
||||
|
||||
e = upperEkin[0];
|
||||
e = upperEkin[regModels->ModelIndex(0)];
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### For material " << material->GetName()
|
||||
<< " " << nEmModels
|
||||
<< " " << nmod
|
||||
<< " models"
|
||||
<< " Ecut(MeV)= " << cut/MeV
|
||||
<< " Emax(MeV)= " << e/MeV
|
||||
<< " nbins= " << totBinsLambda
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
sigmaHigh[0] = emModels[0]->CrossSection(material,particle,e,cut,e);
|
||||
|
||||
if(nEmModels > 1) {
|
||||
sigmaHigh[0] = models[regModels->ModelIndex(0)]->CrossSection(material,particle,e,cut,e);
|
||||
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(nmod > 1) {
|
||||
|
||||
e = upperEkin[j-1];
|
||||
sigmaLow[j] = emModels[j]->CrossSection(material,particle,e,cut,e);
|
||||
e = upperEkin[j];
|
||||
sigmaHigh[j] = emModels[j]->CrossSection(material,particle,e,cut,e);
|
||||
for(j=1; j<nmod; j++) {
|
||||
|
||||
e = upperEkin[regModels->ModelIndex(j-1)];
|
||||
sigmaLow[j] = models[regModels->ModelIndex(j)]->CrossSection(material,particle,e,cut,e);
|
||||
e = upperEkin[regModels->ModelIndex(j)];
|
||||
sigmaHigh[j] = models[regModels->ModelIndex(j)]->CrossSection(material,particle,e,cut,e);
|
||||
}
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
for(j=1; j<nmod; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
else factor[j] = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -446,30 +533,23 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
// Choose a model of energy losses
|
||||
G4int k = 0;
|
||||
G4double fac = 1.0;
|
||||
if(nEmModels > 1) {
|
||||
if(e >= upperEkin[0]) {
|
||||
for(k=1; k<nEmModels; k++) {
|
||||
fac *= (1.0 + factor[k]*upperEkin[k-1]/e);
|
||||
if(e <= upperEkin[k]) break;
|
||||
}
|
||||
}
|
||||
if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
|
||||
do {
|
||||
k++;
|
||||
fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
|
||||
} while (k<nmod-1 && e < upperEkin[regModels->ModelIndex(k)] );
|
||||
}
|
||||
|
||||
// Cross section interpolation should start from zero
|
||||
G4double cross = 0.0;
|
||||
if(j > 0) {
|
||||
cross = emModels[k]->CrossSection(material,particle,e,cut,e)*fac;
|
||||
}
|
||||
G4double cross = models[regModels->ModelIndex(k)]->CrossSection(material,particle,e,cut,e)*fac;
|
||||
if(j==0 && startFromNull) cross = 0.0;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "BuildLambdaTable: e(MeV)= " << e/MeV
|
||||
<< " cross(1/mm)= " << cross*mm
|
||||
G4cout << "FillLambdaVector: " << j << ". e(MeV)= " << e/MeV
|
||||
<< " cross(1/mm)= " << cross*mm
|
||||
<< " fac= " << fac
|
||||
<< G4endl;
|
||||
}
|
||||
if(cross <= 0.0) cross = 0.0;
|
||||
// if(cross <= 0.0) cross = DBL_MAX;
|
||||
// else cross = 1.0/cross;
|
||||
if(cross < 0.0) cross = 0.0;
|
||||
|
||||
aVector->PutValue(j, cross);
|
||||
}
|
||||
@@ -477,11 +557,12 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
const G4Material* material)
|
||||
void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4bool startFromNull)
|
||||
{
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::BuildLambdaSubTable() for particle "
|
||||
G4cout << "G4EmModelManager::BuildLambdaSubTable() for particle "
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
@@ -493,15 +574,20 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
G4double e;
|
||||
|
||||
G4int i = material->GetIndex();
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
size_t i = couple->GetIndex();
|
||||
G4double cut = theCuts[i];
|
||||
G4double subcut = theSubCuts[i];
|
||||
factor.resize(nEmModels);
|
||||
sigmaLow.resize(nEmModels);
|
||||
sigmaHigh.resize(nEmModels);
|
||||
|
||||
G4int reg = idxOfRegionModels[i];
|
||||
const G4RegionModels* regModels = setOfRegionModels[reg];
|
||||
G4int nmod = regModels->NumberOfModels();
|
||||
factor.resize(nmod);
|
||||
sigmaLow.resize(nmod);
|
||||
sigmaHigh.resize(nmod);
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "There are " << nEmModels << " models for "
|
||||
G4cout << "There are " << nmod << " models for "
|
||||
<< material->GetName() << G4endl;
|
||||
}
|
||||
|
||||
@@ -512,31 +598,31 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
sigmaLow[0] = 0.0;
|
||||
|
||||
e = upperEkin[0];
|
||||
e = upperEkin[regModels->ModelIndex(0)];
|
||||
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### For material " << material->GetName()
|
||||
<< " are available " << nEmModels
|
||||
<< " are available " << nmod
|
||||
<< " models"
|
||||
<< " Ecut(MeV)= " << cut/MeV
|
||||
<< " nbins= " << totBinsLambda
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
sigmaHigh[0] = emModels[0]->CrossSection(material,particle,e,subcut,cut);
|
||||
|
||||
if(nEmModels > 1) {
|
||||
sigmaHigh[0] = models[regModels->ModelIndex(0)]->CrossSection(material,particle,e,subcut,cut);
|
||||
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(nmod > 1) {
|
||||
|
||||
e = upperEkin[j-1];
|
||||
sigmaLow[j] = emModels[j]->CrossSection(material,particle,e,subcut,cut);
|
||||
e = upperEkin[j];
|
||||
sigmaHigh[j] = emModels[j]->CrossSection(material,particle,e,subcut,cut);
|
||||
for(j=1; j<nmod; j++) {
|
||||
|
||||
e = upperEkin[regModels->ModelIndex(j-1)];
|
||||
sigmaLow[j] = models[regModels->ModelIndex(j)]->CrossSection(material,particle,e,subcut,cut);
|
||||
e = upperEkin[regModels->ModelIndex(j)];
|
||||
sigmaHigh[j] = models[regModels->ModelIndex(j)]->CrossSection(material,particle,e,subcut,cut);
|
||||
}
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
for(j=1; j<nmod; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
else factor[j] = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -549,37 +635,26 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
// Choose a model of energy losses
|
||||
G4int k = 0;
|
||||
G4double fac = 1.0;
|
||||
if(nEmModels > 1) {
|
||||
if(e >= upperEkin[0]) {
|
||||
for(k=1; k<nEmModels; k++) {
|
||||
fac *= (1.0 + factor[k]*upperEkin[k-1]/e);
|
||||
if(e <= upperEkin[k]) break;
|
||||
}
|
||||
}
|
||||
if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
|
||||
do {
|
||||
k++;
|
||||
fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
|
||||
} while (k<nmod-1 && e < upperEkin[regModels->ModelIndex(k)] );
|
||||
}
|
||||
|
||||
G4double cross = 0.0;
|
||||
|
||||
// Cross section interpolation should start from zero
|
||||
if (j > 0) {
|
||||
cross = emModels[k]->CrossSection(material,particle,e,subcut,cut)*fac;
|
||||
}
|
||||
G4double cross=models[regModels->ModelIndex(k)]->CrossSection(material,particle,e,subcut,cut)*fac;
|
||||
if(j==0 && startFromNull) cross = 0.0;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "BuildLambdaTable: e(MeV)= " << e/MeV
|
||||
<< " cross(1/mm)= " << cross*mm
|
||||
G4cout << "BuildLambdaTable: e(MeV)= " << e/MeV
|
||||
<< " cross(1/mm)= " << cross*mm
|
||||
<< " fac= " << fac
|
||||
<< G4endl;
|
||||
}
|
||||
if(cross <= 0.0) cross = 0.0;
|
||||
if(cross < 0.0) cross = 0.0;
|
||||
|
||||
aVector->PutValue(j, cross);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4EnergyLossMessenger.cc,v 1.5 2002/12/04 21:07:43 asaim Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4EnergyLossMessenger.cc,v 1.7 2003/04/04 14:33:34 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
|
||||
#include "G4VEnergyLoss.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
@@ -52,24 +53,24 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
|
||||
RndmStepCmd->SetGuidance("Randomize the proposed step by eLoss.");
|
||||
RndmStepCmd->SetParameterName("choice",true);
|
||||
RndmStepCmd->SetDefaultValue(false);
|
||||
RndmStepCmd->AvailableForStates(G4State_Idle);
|
||||
RndmStepCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
EnlossFlucCmd = new G4UIcmdWithABool("/process/eLoss/fluct",this);
|
||||
EnlossFlucCmd->SetGuidance("Switch true/false the energy loss fluctuations.");
|
||||
EnlossFlucCmd->SetParameterName("choice",true);
|
||||
EnlossFlucCmd->SetDefaultValue(true);
|
||||
EnlossFlucCmd->AvailableForStates(G4State_Idle);
|
||||
EnlossFlucCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
SubSecCmd = new G4UIcmdWithABool("/process/eLoss/subsec",this);
|
||||
SubSecCmd->SetGuidance("Switch true/false the subcutoff generation.");
|
||||
SubSecCmd->SetParameterName("choice",true);
|
||||
SubSecCmd->SetDefaultValue(true);
|
||||
SubSecCmd->AvailableForStates(G4State_Idle);
|
||||
SubSecCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
MinSubSecCmd = new G4UIcmdWithADoubleAndUnit("/process/eLoss/minsubsec",this);
|
||||
MinSubSecCmd->SetGuidance("Set the min. cut for subcutoff delta in range.");
|
||||
MinSubSecCmd->SetParameterName("rcmin",true);
|
||||
MinSubSecCmd->AvailableForStates(G4State_Idle);
|
||||
MinSubSecCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
StepFuncCmd = new G4UIcommand("/process/eLoss/StepFunction",this);
|
||||
StepFuncCmd->SetGuidance("Set the energy loss step limitation parameters.");
|
||||
@@ -93,7 +94,25 @@ G4EnergyLossMessenger::G4EnergyLossMessenger()
|
||||
unitPrm->SetParameterCandidates(unitCandidates);
|
||||
|
||||
StepFuncCmd->SetParameter(unitPrm);
|
||||
StepFuncCmd->AvailableForStates(G4State_Idle);
|
||||
StepFuncCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
MinEnCmd = new G4UIcmdWithADoubleAndUnit("/process/eLoss/minKinEnergy",this);
|
||||
MinEnCmd->SetGuidance("Set the min kinetic energy");
|
||||
MinEnCmd->SetParameterName("emin",true);
|
||||
MinEnCmd->SetUnitCategory("Energy");
|
||||
MinEnCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
MaxEnCmd = new G4UIcmdWithADoubleAndUnit("/process/eLoss/maxKinEnergy",this);
|
||||
MaxEnCmd->SetGuidance("Set the max kinetic energy");
|
||||
MaxEnCmd->SetParameterName("emax",true);
|
||||
MaxEnCmd->SetUnitCategory("Energy");
|
||||
MaxEnCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
IntegCmd = new G4UIcmdWithABool("/process/eLoss/integral",this);
|
||||
IntegCmd->SetGuidance("Switch true/false the integration of cross section over step.");
|
||||
IntegCmd->SetParameterName("integ",true);
|
||||
IntegCmd->SetDefaultValue(true);
|
||||
IntegCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -106,22 +125,29 @@ G4EnergyLossMessenger::~G4EnergyLossMessenger()
|
||||
delete MinSubSecCmd;
|
||||
delete StepFuncCmd;
|
||||
delete eLossDirectory;
|
||||
delete MinEnCmd;
|
||||
delete MaxEnCmd;
|
||||
delete IntegCmd;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
{
|
||||
G4LossTableManager* lossTables = G4LossTableManager::Instance();
|
||||
if (command == RndmStepCmd)
|
||||
{ G4VEnergyLoss::SetRndmStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
lossTables->SetRandomStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == EnlossFlucCmd)
|
||||
{ G4VEnergyLoss::SetEnlossFluc(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
lossTables->SetLossFluctuations(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == SubSecCmd)
|
||||
{ G4VEnergyLoss::SetSubSec(SubSecCmd->GetNewBoolValue(newValue));
|
||||
lossTables->SetSubCutoff(SubSecCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == MinSubSecCmd)
|
||||
@@ -138,7 +164,20 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
G4String unt = unts;
|
||||
v2 *= G4UIcommand::ValueOf(unt);
|
||||
G4VEnergyLoss::SetStepFunction(v1,v2);
|
||||
lossTables->SetStepLimits(v1,v2);
|
||||
}
|
||||
|
||||
if (command == MinEnCmd) {
|
||||
lossTables->SetMinEnergy(MinEnCmd->GetNewDoubleValue(newValue));
|
||||
}
|
||||
|
||||
if (command == MaxEnCmd) {
|
||||
lossTables->SetMaxEnergy(MaxEnCmd->GetNewDoubleValue(newValue));
|
||||
}
|
||||
if (command == IntegCmd) {
|
||||
lossTables->SetIntegral(IntegCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -1,190 +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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4EnergyLossMessengerSTD
|
||||
//
|
||||
// Author:
|
||||
//
|
||||
// Creation date:
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 03.01.2002 V.Ivanchenko update to new design
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4EnergyLossMessengerSTD.hh"
|
||||
|
||||
#include "G4LossTableManager.hh"
|
||||
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UIcommand.hh"
|
||||
#include "G4UIparameter.hh"
|
||||
#include "G4UIcmdWithABool.hh"
|
||||
#include "G4UIcmdWithADoubleAndUnit.hh"
|
||||
|
||||
#include "g4std/strstream"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EnergyLossMessengerSTD::G4EnergyLossMessengerSTD()
|
||||
{
|
||||
eLossDirectory = new G4UIdirectory("/process/eLoss/");
|
||||
eLossDirectory->SetGuidance("Commands for G4VEnergyLoss.");
|
||||
|
||||
RndmStepCmd = new G4UIcmdWithABool("/process/eLoss/rndmStep",this);
|
||||
RndmStepCmd->SetGuidance("Randomize the proposed step by eLoss.");
|
||||
RndmStepCmd->SetParameterName("rndmStep",true);
|
||||
RndmStepCmd->SetDefaultValue(false);
|
||||
RndmStepCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
EnlossFlucCmd = new G4UIcmdWithABool("/process/eLoss/fluct",this);
|
||||
EnlossFlucCmd->SetGuidance("Switch true/false the energy loss fluctuations.");
|
||||
EnlossFlucCmd->SetParameterName("fluct",true);
|
||||
EnlossFlucCmd->SetDefaultValue(true);
|
||||
EnlossFlucCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
SubSecCmd = new G4UIcmdWithABool("/process/eLoss/subsec",this);
|
||||
SubSecCmd->SetGuidance("Switch true/false the subcutoff generation.");
|
||||
SubSecCmd->SetParameterName("subsec",true);
|
||||
SubSecCmd->SetDefaultValue(true);
|
||||
SubSecCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
IntegCmd = new G4UIcmdWithABool("/process/eLoss/integral",this);
|
||||
IntegCmd->SetGuidance("Switch true/false the integration of cross section over step.");
|
||||
IntegCmd->SetParameterName("integ",true);
|
||||
IntegCmd->SetDefaultValue(true);
|
||||
IntegCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
MinSubSecCmd = new G4UIcmdWithADoubleAndUnit("/process/eLoss/minsubsec",this);
|
||||
MinSubSecCmd->SetGuidance("Set the min. cut for subcutoff delta in range.");
|
||||
MinSubSecCmd->SetParameterName("minsubsec",true);
|
||||
MinSubSecCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
MinEnCmd = new G4UIcmdWithADoubleAndUnit("/process/eLoss/minKinEnergy",this);
|
||||
MinEnCmd->SetGuidance("Set the min kinetic energy");
|
||||
MinEnCmd->SetParameterName("emin",true);
|
||||
MinEnCmd->SetUnitCategory("Energy");
|
||||
MinEnCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
MaxEnCmd = new G4UIcmdWithADoubleAndUnit("/process/eLoss/maxKinEnergy",this);
|
||||
MaxEnCmd->SetGuidance("Set the max kinetic energy");
|
||||
MaxEnCmd->SetParameterName("emax",true);
|
||||
MaxEnCmd->SetUnitCategory("Energy");
|
||||
MaxEnCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
|
||||
StepFuncCmd = new G4UIcommand("/process/eLoss/StepFunction",this);
|
||||
StepFuncCmd->SetGuidance("Set the energy loss step limitation parameters.");
|
||||
StepFuncCmd->SetGuidance(" dRoverR : max Range variation per step");
|
||||
StepFuncCmd->SetGuidance(" finalRange: range for final step");
|
||||
|
||||
G4UIparameter* dRoverRPrm = new G4UIparameter("dRoverR",'d',false);
|
||||
dRoverRPrm->SetGuidance("max Range variation per step (fractional number)");
|
||||
dRoverRPrm->SetParameterRange("dRoverR>0. && dRoverR<=1.");
|
||||
StepFuncCmd->SetParameter(dRoverRPrm);
|
||||
|
||||
G4UIparameter* finalRangePrm = new G4UIparameter("finalRange",'d',false);
|
||||
finalRangePrm->SetGuidance("range for final step");
|
||||
finalRangePrm->SetParameterRange("finalRange>0.");
|
||||
StepFuncCmd->SetParameter(finalRangePrm);
|
||||
|
||||
G4UIparameter* unitPrm = new G4UIparameter("unit",'s',true);
|
||||
unitPrm->SetGuidance("unit of finalRange");
|
||||
unitPrm->SetDefaultValue("mm");
|
||||
G4String unitCandidates = G4UIcommand::UnitsList(G4UIcommand::CategoryOf("mm"));
|
||||
unitPrm->SetParameterCandidates(unitCandidates);
|
||||
|
||||
StepFuncCmd->SetParameter(unitPrm);
|
||||
StepFuncCmd->AvailableForStates(G4State_PreInit,G4State_Idle);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EnergyLossMessengerSTD::~G4EnergyLossMessengerSTD()
|
||||
{
|
||||
delete RndmStepCmd;
|
||||
delete EnlossFlucCmd;
|
||||
delete SubSecCmd;
|
||||
delete MinSubSecCmd;
|
||||
delete MinEnCmd;
|
||||
delete MaxEnCmd;
|
||||
delete StepFuncCmd;
|
||||
delete IntegCmd;
|
||||
delete eLossDirectory;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EnergyLossMessengerSTD::SetNewValue(G4UIcommand* command,G4String newValue)
|
||||
{
|
||||
G4LossTableManager* lossTables = G4LossTableManager::Instance();
|
||||
|
||||
if (command == RndmStepCmd) {
|
||||
lossTables->SetRandomStep(RndmStepCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == IntegCmd) {
|
||||
lossTables->SetIntegral(IntegCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == EnlossFlucCmd) {
|
||||
lossTables->SetLossFluctuations(EnlossFlucCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == SubSecCmd) {
|
||||
lossTables->SetSubCutoff(SubSecCmd->GetNewBoolValue(newValue));
|
||||
}
|
||||
|
||||
if (command == MinEnCmd) {
|
||||
lossTables->SetMinEnergy(MinEnCmd->GetNewDoubleValue(newValue));
|
||||
}
|
||||
|
||||
if (command == MaxEnCmd) {
|
||||
lossTables->SetMaxEnergy(MaxEnCmd->GetNewDoubleValue(newValue));
|
||||
}
|
||||
|
||||
if (command == StepFuncCmd) {
|
||||
G4double v1,v2;
|
||||
char unts[30];
|
||||
const char* t = newValue;
|
||||
G4std::istrstream is((char*)t);
|
||||
is >> v1 >> v2 >> unts;
|
||||
G4String unt = unts;
|
||||
v2 *= G4UIcommand::ValueOf(unt);
|
||||
lossTables->SetStepLimits(v1,v2);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -21,10 +21,10 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4EnergyLossTables.cc,v 1.17 2001/10/29 09:40:52 maire Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4EnergyLossTables.cc,v 1.27 2003/04/18 17:49:26 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------
|
||||
// first version created by P.Urban , 06/04/1998
|
||||
// modifications + "precise" functions added by L.Urban , 27/05/98
|
||||
// modifications , TOF functions , 26/10/98, L.Urban
|
||||
@@ -33,20 +33,32 @@
|
||||
// 10.11.99: moved from RWT hash dictionary to STL map, G.Barrand, M.Maire
|
||||
// 27.09.01 L.Urban , bug fixed (negative energy deposit)
|
||||
// 26.10.01 all static functions moved from .icc files (mma)
|
||||
// 15.01.03 Add interfaces required for "cut per region" (V.Ivanchenko)
|
||||
// 12.03.03 Add warnings to obsolete interfaces (V.Ivanchenko)
|
||||
// 10.04.03 Add call to G4LossTableManager is particle is not registered (V.Ivanchenko)
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#include "G4EnergyLossTables.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4EnergyLossTablesHelper G4EnergyLossTables::t ;
|
||||
const G4ParticleDefinition* G4EnergyLossTables::lastParticle = 0;
|
||||
G4EnergyLossTablesHelper G4EnergyLossTables::null_loss ;
|
||||
const G4ParticleDefinition* G4EnergyLossTables::lastParticle = 0;
|
||||
G4double G4EnergyLossTables::QQPositron = eplus*eplus ;
|
||||
G4double G4EnergyLossTables::Chargesquare ;
|
||||
G4int G4EnergyLossTables::oldIndex = -1 ;
|
||||
G4double G4EnergyLossTables::rmin = 0. ;
|
||||
G4double G4EnergyLossTables::rmax = 0. ;
|
||||
G4double G4EnergyLossTables::Thigh = 0. ;
|
||||
G4int G4EnergyLossTables::let_counter = 0;
|
||||
G4int G4EnergyLossTables::let_max_num_warnings = 2;
|
||||
G4bool G4EnergyLossTables::first_loss = true;
|
||||
|
||||
G4EnergyLossTables::helper_map G4EnergyLossTables::dict;
|
||||
|
||||
@@ -95,11 +107,15 @@ void G4EnergyLossTables::Register(
|
||||
dict[p]= G4EnergyLossTablesHelper(tDEDX, tRange,tInverseRange,
|
||||
tLabTime,tProperTime,lowestKineticEnergy,
|
||||
highestKineticEnergy, massRatio,NumberOfBins);
|
||||
|
||||
|
||||
t = GetTables(p) ; // important for cache !!!!!
|
||||
lastParticle = p ;
|
||||
Chargesquare = (p->GetPDGCharge())*(p->GetPDGCharge())/
|
||||
QQPositron ;
|
||||
if (first_loss ) {
|
||||
null_loss = G4EnergyLossTablesHelper(0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0);
|
||||
first_loss = false;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -109,7 +125,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetDEDXTable(
|
||||
{
|
||||
helper_map::iterator it;
|
||||
if((it=dict.find(p))==dict.end()) return 0;
|
||||
return (*it).second.theDEDXTable;
|
||||
return (*it).second.theDEDXTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -119,7 +135,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetRangeTable(
|
||||
{
|
||||
helper_map::iterator it;
|
||||
if((it=dict.find(p))==dict.end()) return 0;
|
||||
return (*it).second.theRangeTable;
|
||||
return (*it).second.theRangeTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -129,7 +145,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetInverseRangeTable(
|
||||
{
|
||||
helper_map::iterator it;
|
||||
if((it=dict.find(p))==dict.end()) return 0;
|
||||
return (*it).second.theInverseRangeTable;
|
||||
return (*it).second.theInverseRangeTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -139,7 +155,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetLabTimeTable(
|
||||
{
|
||||
helper_map::iterator it;
|
||||
if((it=dict.find(p))==dict.end()) return 0;
|
||||
return (*it).second.theLabTimeTable;
|
||||
return (*it).second.theLabTimeTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -149,7 +165,7 @@ const G4PhysicsTable* G4EnergyLossTables::GetProperTimeTable(
|
||||
{
|
||||
helper_map::iterator it;
|
||||
if((it=dict.find(p))==dict.end()) return 0;
|
||||
return (*it).second.theProperTimeTable;
|
||||
return (*it).second.theProperTimeTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -158,9 +174,11 @@ G4EnergyLossTablesHelper G4EnergyLossTables::GetTables(
|
||||
const G4ParticleDefinition* p)
|
||||
{
|
||||
helper_map::iterator it;
|
||||
if((it=dict.find(p))==dict.end()) {
|
||||
G4Exception("G4EnergyLossTables::GetTables: table not found!");
|
||||
exit(1);
|
||||
if ((it=dict.find(p))==dict.end()) {
|
||||
// G4cout << "Table is not found out for " << p->GetParticleName() << G4endl;
|
||||
// G4Exception("G4EnergyLossTables::GetTables: table not found!");
|
||||
// exit(1);
|
||||
return null_loss;
|
||||
}
|
||||
return (*it).second;
|
||||
}
|
||||
@@ -172,6 +190,7 @@ G4double G4EnergyLossTables::GetDEDX(
|
||||
G4double KineticEnergy,
|
||||
const G4Material *aMaterial)
|
||||
{
|
||||
CPRWarning();
|
||||
if(aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -182,6 +201,7 @@ G4double G4EnergyLossTables::GetDEDX(
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
if (!dEdxTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
G4int materialIndex = aMaterial->GetIndex();
|
||||
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
|
||||
@@ -200,7 +220,7 @@ G4double G4EnergyLossTables::GetDEDX(
|
||||
t.theHighestKineticEnergy,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
dEdx = (*dEdxTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut);
|
||||
|
||||
@@ -216,6 +236,7 @@ G4double G4EnergyLossTables::GetLabTime(
|
||||
G4double KineticEnergy,
|
||||
const G4Material *aMaterial)
|
||||
{
|
||||
CPRWarning();
|
||||
if(aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -223,8 +244,9 @@ G4double G4EnergyLossTables::GetLabTime(
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* labtimeTable= t.theLabTimeTable;
|
||||
if (!labtimeTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
const G4double parlowen=0.4 , ppar=0.5-parlowen ;
|
||||
const G4double parlowen=0.4 , ppar=0.5-parlowen ;
|
||||
G4int materialIndex = aMaterial->GetIndex();
|
||||
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
|
||||
G4double time;
|
||||
@@ -243,7 +265,7 @@ G4double G4EnergyLossTables::GetLabTime(
|
||||
t.theHighestKineticEnergy,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
time = (*labtimeTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut);
|
||||
|
||||
@@ -260,6 +282,7 @@ G4double G4EnergyLossTables::GetDeltaLabTime(
|
||||
G4double KineticEnergyEnd,
|
||||
const G4Material *aMaterial)
|
||||
{
|
||||
CPRWarning();
|
||||
if(aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -267,9 +290,10 @@ G4double G4EnergyLossTables::GetDeltaLabTime(
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* labtimeTable= t.theLabTimeTable;
|
||||
if (!labtimeTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
const G4double parlowen=0.4 , ppar=0.5-parlowen ;
|
||||
const G4double dToverT = 0.05 , facT = 1. -dToverT ;
|
||||
const G4double dToverT = 0.05 , facT = 1. -dToverT ;
|
||||
G4double timestart,timeend,deltatime,dTT;
|
||||
G4bool isOut;
|
||||
|
||||
@@ -296,12 +320,12 @@ G4double G4EnergyLossTables::GetDeltaLabTime(
|
||||
}
|
||||
|
||||
dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
|
||||
|
||||
|
||||
if( dTT < dToverT )
|
||||
scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio;
|
||||
else
|
||||
scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio;
|
||||
|
||||
|
||||
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
|
||||
|
||||
timeend = exp(ppar*log(scaledKineticEnergy/t.theLowestKineticEnergy))*
|
||||
@@ -336,6 +360,7 @@ G4double G4EnergyLossTables::GetProperTime(
|
||||
G4double KineticEnergy,
|
||||
const G4Material *aMaterial)
|
||||
{
|
||||
CPRWarning();
|
||||
if(aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -343,6 +368,7 @@ G4double G4EnergyLossTables::GetProperTime(
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* propertimeTable= t.theProperTimeTable;
|
||||
if (!propertimeTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
const G4double parlowen=0.4 , ppar=0.5-parlowen ;
|
||||
G4int materialIndex = aMaterial->GetIndex();
|
||||
@@ -380,6 +406,7 @@ G4double G4EnergyLossTables::GetDeltaProperTime(
|
||||
G4double KineticEnergyEnd,
|
||||
const G4Material *aMaterial)
|
||||
{
|
||||
CPRWarning();
|
||||
if(aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -387,9 +414,10 @@ G4double G4EnergyLossTables::GetDeltaProperTime(
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* propertimeTable= t.theProperTimeTable;
|
||||
if (!propertimeTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
const G4double parlowen=0.4 , ppar=0.5-parlowen ;
|
||||
const G4double dToverT = 0.05 , facT = 1. -dToverT ;
|
||||
const G4double dToverT = 0.05 , facT = 1. -dToverT ;
|
||||
G4double timestart,timeend,deltatime,dTT;
|
||||
G4bool isOut;
|
||||
|
||||
@@ -416,12 +444,12 @@ G4double G4EnergyLossTables::GetDeltaProperTime(
|
||||
}
|
||||
|
||||
dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
|
||||
|
||||
|
||||
if( dTT < dToverT )
|
||||
scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio;
|
||||
else
|
||||
scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio;
|
||||
|
||||
|
||||
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
|
||||
|
||||
timeend = exp(ppar*log(scaledKineticEnergy/t.theLowestKineticEnergy))*
|
||||
@@ -456,6 +484,7 @@ G4double G4EnergyLossTables::GetRange(
|
||||
G4double KineticEnergy,
|
||||
const G4Material *aMaterial)
|
||||
{
|
||||
CPRWarning();
|
||||
if(aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -467,6 +496,7 @@ G4double G4EnergyLossTables::GetRange(
|
||||
}
|
||||
const G4PhysicsTable* rangeTable= t.theRangeTable;
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
if (!dEdxTable || !rangeTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
G4int materialIndex = aMaterial->GetIndex();
|
||||
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
|
||||
@@ -488,7 +518,7 @@ G4double G4EnergyLossTables::GetRange(
|
||||
t.theHighestKineticEnergy,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
Range = (*rangeTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut);
|
||||
|
||||
@@ -505,6 +535,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
const G4Material *aMaterial)
|
||||
// it returns the value of the kinetic energy for a given range
|
||||
{
|
||||
CPRWarning();
|
||||
if( aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -516,6 +547,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
}
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
const G4PhysicsTable* inverseRangeTable= t.theInverseRangeTable;
|
||||
if (!dEdxTable || !inverseRangeTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
G4double scaledrange,scaledKineticEnergy ;
|
||||
G4bool isOut ;
|
||||
@@ -566,7 +598,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4double KineticEnergy,
|
||||
const G4Material *aMaterial)
|
||||
{
|
||||
|
||||
CPRWarning();
|
||||
if( aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -577,6 +609,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
if (!dEdxTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
G4int materialIndex = aMaterial->GetIndex();
|
||||
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
|
||||
@@ -595,7 +628,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
t.theHighestKineticEnergy,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
dEdx = (*dEdxTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut) ;
|
||||
|
||||
@@ -611,6 +644,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
G4double KineticEnergy,
|
||||
const G4Material *aMaterial)
|
||||
{
|
||||
CPRWarning();
|
||||
if( aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
@@ -622,6 +656,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
}
|
||||
const G4PhysicsTable* rangeTable= t.theRangeTable;
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
if (!dEdxTable || !rangeTable) ParticleHaveNoLoss(aParticle);
|
||||
|
||||
G4int materialIndex = aMaterial->GetIndex();
|
||||
|
||||
@@ -648,7 +683,7 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
Thighr,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
Range = (*rangeTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut) ;
|
||||
|
||||
@@ -659,6 +694,299 @@ G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4EnergyLossTables::GetDEDX(
|
||||
const G4ParticleDefinition *aParticle,
|
||||
G4double KineticEnergy,
|
||||
const G4MaterialCutsCouple *couple)
|
||||
{
|
||||
if(aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
lastParticle = aParticle ;
|
||||
Chargesquare = (aParticle->GetPDGCharge())*
|
||||
(aParticle->GetPDGCharge())/
|
||||
QQPositron ;
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
if ( !dEdxTable )
|
||||
return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
|
||||
|
||||
G4int materialIndex = couple->GetIndex();
|
||||
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
|
||||
G4double dEdx;
|
||||
G4bool isOut;
|
||||
|
||||
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
|
||||
|
||||
dEdx =(*dEdxTable)(materialIndex)->GetValue(
|
||||
t.theLowestKineticEnergy,isOut)
|
||||
*sqrt(scaledKineticEnergy/t.theLowestKineticEnergy);
|
||||
|
||||
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
|
||||
|
||||
dEdx = (*dEdxTable)(materialIndex)->GetValue(
|
||||
t.theHighestKineticEnergy,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
dEdx = (*dEdxTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut);
|
||||
|
||||
}
|
||||
|
||||
return dEdx*Chargesquare;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4EnergyLossTables::GetRange(
|
||||
const G4ParticleDefinition *aParticle,
|
||||
G4double KineticEnergy,
|
||||
const G4MaterialCutsCouple *couple)
|
||||
{
|
||||
if(aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
lastParticle = aParticle ;
|
||||
Chargesquare = (aParticle->GetPDGCharge())*
|
||||
(aParticle->GetPDGCharge())/
|
||||
QQPositron ;
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* rangeTable= t.theRangeTable;
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
if ( !rangeTable || !dEdxTable)
|
||||
return G4LossTableManager::Instance()->GetRange(aParticle,KineticEnergy,couple);
|
||||
|
||||
|
||||
G4int materialIndex = couple->GetIndex();
|
||||
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
|
||||
G4double Range;
|
||||
G4bool isOut;
|
||||
|
||||
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
|
||||
|
||||
Range = sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
|
||||
(*rangeTable)(materialIndex)->GetValue(
|
||||
t.theLowestKineticEnergy,isOut);
|
||||
|
||||
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
|
||||
|
||||
Range = (*rangeTable)(materialIndex)->GetValue(
|
||||
t.theHighestKineticEnergy,isOut)+
|
||||
(scaledKineticEnergy-t.theHighestKineticEnergy)/
|
||||
(*dEdxTable)(materialIndex)->GetValue(
|
||||
t.theHighestKineticEnergy,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
Range = (*rangeTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut);
|
||||
|
||||
}
|
||||
|
||||
return Range/(Chargesquare*t.theMassRatio);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
const G4ParticleDefinition *aParticle,
|
||||
G4double range,
|
||||
const G4MaterialCutsCouple *couple)
|
||||
// it returns the value of the kinetic energy for a given range
|
||||
{
|
||||
if( aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
lastParticle = aParticle;
|
||||
Chargesquare = (aParticle->GetPDGCharge())*
|
||||
(aParticle->GetPDGCharge())/
|
||||
QQPositron ;
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
const G4PhysicsTable* inverseRangeTable= t.theInverseRangeTable;
|
||||
if ( !dEdxTable || !inverseRangeTable)
|
||||
return G4LossTableManager::Instance()->GetEnergy(aParticle,range,couple);
|
||||
|
||||
G4double scaledrange,scaledKineticEnergy ;
|
||||
G4bool isOut ;
|
||||
|
||||
G4int materialIndex = couple->GetIndex() ;
|
||||
|
||||
if(materialIndex != oldIndex)
|
||||
{
|
||||
oldIndex = materialIndex ;
|
||||
rmin = (*inverseRangeTable)(materialIndex)->
|
||||
GetLowEdgeEnergy(0) ;
|
||||
rmax = (*inverseRangeTable)(materialIndex)->
|
||||
GetLowEdgeEnergy(t.theNumberOfBins-2) ;
|
||||
Thigh = (*inverseRangeTable)(materialIndex)->
|
||||
GetValue(rmax,isOut) ;
|
||||
}
|
||||
|
||||
scaledrange = range*Chargesquare*t.theMassRatio ;
|
||||
|
||||
if(scaledrange < rmin)
|
||||
{
|
||||
scaledKineticEnergy = t.theLowestKineticEnergy*
|
||||
scaledrange*scaledrange/(rmin*rmin) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(scaledrange < rmax)
|
||||
{
|
||||
scaledKineticEnergy = (*inverseRangeTable)(materialIndex)->
|
||||
GetValue( scaledrange,isOut) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
scaledKineticEnergy = Thigh +
|
||||
(scaledrange-rmax)*
|
||||
(*dEdxTable)(materialIndex)->
|
||||
GetValue(Thigh,isOut) ;
|
||||
}
|
||||
}
|
||||
|
||||
return scaledKineticEnergy/t.theMassRatio ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4EnergyLossTables::GetPreciseDEDX(
|
||||
const G4ParticleDefinition *aParticle,
|
||||
G4double KineticEnergy,
|
||||
const G4MaterialCutsCouple *couple)
|
||||
{
|
||||
|
||||
if( aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
lastParticle = aParticle;
|
||||
Chargesquare = (aParticle->GetPDGCharge())*
|
||||
(aParticle->GetPDGCharge())/
|
||||
QQPositron ;
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
if ( !dEdxTable )
|
||||
return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
|
||||
|
||||
G4int materialIndex = couple->GetIndex();
|
||||
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
|
||||
G4double dEdx;
|
||||
G4bool isOut;
|
||||
|
||||
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
|
||||
|
||||
dEdx = sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)
|
||||
*(*dEdxTable)(materialIndex)->GetValue(
|
||||
t.theLowestKineticEnergy,isOut);
|
||||
|
||||
} else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
|
||||
|
||||
dEdx = (*dEdxTable)(materialIndex)->GetValue(
|
||||
t.theHighestKineticEnergy,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
dEdx = (*dEdxTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut) ;
|
||||
|
||||
}
|
||||
|
||||
return dEdx*Chargesquare;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4EnergyLossTables::GetPreciseRangeFromEnergy(
|
||||
const G4ParticleDefinition *aParticle,
|
||||
G4double KineticEnergy,
|
||||
const G4MaterialCutsCouple *couple)
|
||||
{
|
||||
if( aParticle != lastParticle)
|
||||
{
|
||||
t= GetTables(aParticle);
|
||||
lastParticle = aParticle;
|
||||
Chargesquare = (aParticle->GetPDGCharge())*
|
||||
(aParticle->GetPDGCharge())/
|
||||
QQPositron ;
|
||||
oldIndex = -1 ;
|
||||
}
|
||||
const G4PhysicsTable* rangeTable= t.theRangeTable;
|
||||
const G4PhysicsTable* dEdxTable= t.theDEDXTable;
|
||||
if ( !dEdxTable || !rangeTable)
|
||||
return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
|
||||
|
||||
G4int materialIndex = couple->GetIndex();
|
||||
|
||||
G4double Thighr = t.theHighestKineticEnergy*t.theLowestKineticEnergy/
|
||||
(*rangeTable)(materialIndex)->
|
||||
GetLowEdgeEnergy(1) ;
|
||||
|
||||
G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
|
||||
G4double Range;
|
||||
G4bool isOut;
|
||||
|
||||
if (scaledKineticEnergy<t.theLowestKineticEnergy) {
|
||||
|
||||
Range = sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
|
||||
(*rangeTable)(materialIndex)->GetValue(
|
||||
t.theLowestKineticEnergy,isOut);
|
||||
|
||||
} else if (scaledKineticEnergy>Thighr) {
|
||||
|
||||
Range = (*rangeTable)(materialIndex)->GetValue(
|
||||
Thighr,isOut)+
|
||||
(scaledKineticEnergy-Thighr)/
|
||||
(*dEdxTable)(materialIndex)->GetValue(
|
||||
Thighr,isOut);
|
||||
|
||||
} else {
|
||||
|
||||
Range = (*rangeTable)(materialIndex)->GetValue(
|
||||
scaledKineticEnergy,isOut) ;
|
||||
|
||||
}
|
||||
|
||||
return Range/(Chargesquare*t.theMassRatio);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EnergyLossTables::CPRWarning()
|
||||
{
|
||||
// if (let_counter < let_max_num_warnings) {
|
||||
|
||||
// G4cout << G4endl;
|
||||
// G4cout << "##### G4EnergyLossTable WARNING: The obsolete interface is used" << G4endl;
|
||||
// G4cout << "##### Please, substitute G4Material by G4MaterialCutsCouple" << G4endl;
|
||||
// G4cout << "##### Obsolete interface will be removed soon" << G4endl;
|
||||
// G4cout << G4endl;
|
||||
// let_counter++;
|
||||
if ((G4RegionStore::GetInstance())->size() > 1) {
|
||||
G4Exception("G4EnergyLossTables:: More than 1 region - table can't be accessed with obsolete interface");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// } else if (let_counter == let_max_num_warnings) {
|
||||
|
||||
// G4cout << "##### G4EnergyLossTable WARNING closed" << G4endl;
|
||||
// let_counter++;
|
||||
// }
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle)
|
||||
{
|
||||
G4String s = "G4EnergyLossTables:: dE/dx table not found for "
|
||||
+ aParticle->GetParticleName() + "!";
|
||||
G4Exception(s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// 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....
|
||||
|
||||
G4IonFluctuations::G4IonFluctuations(const G4String& nam)
|
||||
:G4VEmFluctuationModel(nam),
|
||||
minNumberInteractionsBohr(10.0),
|
||||
theBohrBeta2(50.0*keV/proton_mass_c2),
|
||||
minFraction(0.2)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4IonFluctuations::~G4IonFluctuations()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4IonFluctuations::Initialise(const G4ParticleDefinition* part)
|
||||
{
|
||||
particle = part;
|
||||
particleMass = part->GetPDGMass();
|
||||
G4double q = part->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IonFluctuations::SampleFluctuations(const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length,
|
||||
G4double& meanLoss)
|
||||
{
|
||||
|
||||
if(dp->GetDefinition() != particle) {
|
||||
particle = dp->GetDefinition();
|
||||
particleMass = dp->GetMass();
|
||||
charge = dp->GetCharge();
|
||||
chargeSquare = charge*charge;
|
||||
}
|
||||
|
||||
G4double siga = Dispersion(material,dp,tmax,length);
|
||||
G4double loss = meanLoss;
|
||||
|
||||
// Gaussian fluctuation
|
||||
if (meanLoss >= minNumberInteractionsBohr*tmax) {
|
||||
|
||||
// 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);
|
||||
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);
|
||||
do {
|
||||
loss = G4RandGauss::shoot(meanLoss,siga);
|
||||
} while (loss < 0. || loss > 2.*meanLoss);
|
||||
|
||||
// Poisson fluctuations
|
||||
} else {
|
||||
G4double navr = meanLoss*meanLoss/siga;
|
||||
G4double n = (G4double)G4Poisson(navr);
|
||||
loss = meanLoss*n/navr;
|
||||
}
|
||||
|
||||
return loss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4IonFluctuations::Dispersion(
|
||||
const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length)
|
||||
{
|
||||
G4double electronDensity = material->GetElectronDensity();
|
||||
kineticEnergy = dp->GetKineticEnergy();
|
||||
G4double gam = kineticEnergy/particleMass + 1.0;
|
||||
beta2 = 1.0 - 1.0/(gam*gam);
|
||||
G4double siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
|
||||
* electronDensity * chargeSquare;
|
||||
|
||||
// Low velocity - additional ion charge fluctuations according to
|
||||
// Q.Yang et al., NIM B61(1991)149-155.
|
||||
G4double zeff = electronDensity/(material->GetTotNbOfAtomsPerVolume());
|
||||
|
||||
if ( beta2 < 3.0*theBohrBeta2*zeff ) {
|
||||
|
||||
G4double a = CoeffitientA (zeff);
|
||||
G4double b = CoeffitientB (material, zeff);
|
||||
siga *= (chargeSquare * a + b);
|
||||
}
|
||||
|
||||
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....
|
||||
@@ -0,0 +1,643 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4LewisModel
|
||||
//
|
||||
// Author: Laszlo Urban
|
||||
//
|
||||
// Creation date: 03.03.2001
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 27-03-03 Move model part from G4MultipleScattering (V.Ivanchenko)
|
||||
//
|
||||
|
||||
// Class Description:
|
||||
//
|
||||
// Implementation of Lewis model of multiple scattering
|
||||
// H.W.Lewis Phys Rev 78 (1950) 526
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4LewisModel.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LewisModel::G4LewisModel(G4double& m_dtrl, G4double& m_NuclCorrPar,
|
||||
G4double& m_FactPar, G4double& m_facxsi,
|
||||
G4bool& m_samplez, const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
highKinEnergy(10.0*TeV),
|
||||
lowKinEnergy(0.1*keV),
|
||||
taubig(8.0),
|
||||
tausmall(1.e-14),
|
||||
taulim(1.e-5),
|
||||
dtrl(m_dtrl),
|
||||
NuclCorrPar (m_NuclCorrPar),
|
||||
FactPar(m_FactPar),
|
||||
facxsi(m_facxsi),
|
||||
samplez(m_samplez),
|
||||
stepmin(1.e-6*mm)
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4LewisModel::~G4LewisModel()
|
||||
{}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4LewisModel::IsInCharge(const G4ParticleDefinition* p)
|
||||
{
|
||||
return (p->GetPDGCharge() != 0.0);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4LewisModel::Initialise(const G4ParticleDefinition* p,
|
||||
const G4DataVector&)
|
||||
{
|
||||
// set values of some data members
|
||||
if((p->GetParticleName() == "e-") || (p->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 ;
|
||||
}
|
||||
sigmafactor = twopi*classic_electr_radius*classic_electr_radius;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LewisModel::CrossSection(const G4Material* material,
|
||||
const G4ParticleDefinition* p,
|
||||
G4double kineticEnergy,
|
||||
G4double,
|
||||
G4double)
|
||||
{
|
||||
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 G4LewisModel::ComputeTransportCrossSection(
|
||||
const G4ParticleDefinition* particle,
|
||||
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 = particle->GetPDGMass();
|
||||
|
||||
// correction if particle .ne. e-/e+
|
||||
// compute equivalent kinetic energy
|
||||
// lambda depends on p*beta ....
|
||||
|
||||
if((particle->GetParticleName() != "e-") &&
|
||||
(particle->GetParticleName() != "e+") )
|
||||
{
|
||||
G4double TAU = KineticEnergy/ParticleMass ;
|
||||
G4double c = ParticleMass*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 ;
|
||||
}
|
||||
|
||||
G4double Charge = particle->GetPDGCharge();
|
||||
G4double ChargeSquare = Charge*Charge/(eplus*eplus);
|
||||
|
||||
G4double TotalEnergy = KineticEnergy + electron_mass_c2 ;
|
||||
G4double beta2 = KineticEnergy*(TotalEnergy+electron_mass_c2)
|
||||
/(TotalEnergy*TotalEnergy);
|
||||
G4double bg2 = KineticEnergy*(TotalEnergy+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*ParticleMass/(KineticEnergy*
|
||||
exp(log(AtomicWeight/(g/mole))/3.));
|
||||
if ( x0 < -1. || KineticEnergy <= 10.*MeV)
|
||||
{
|
||||
x0 = -1.;
|
||||
corrnuclsize = 1.;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = 1.+1./eps;
|
||||
if (eps > epsmax) w1=log(2.*eps)+1./eps-3./(8.*eps*eps);
|
||||
else w1=log((a+1.)/(a-1.))-2./(a+1.);
|
||||
w = 1./((1.-x0)*eps);
|
||||
if (w < epsmin) w2=-log(w)-1.+2.*w-1.5*w*w;
|
||||
else w2 = log((a-x0)/(a-1.))-(1.-x0)/(a-x0);
|
||||
corrnuclsize = w1/w2;
|
||||
corrnuclsize = exp(-FactPar*ParticleMass/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]>=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((particle->GetParticleName() != "e-") &&
|
||||
(particle->GetParticleName() != "e+") )
|
||||
sigma /= corrnuclsize;
|
||||
|
||||
return sigma;
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LewisModel::GeomPathLength(
|
||||
G4PhysicsTable* theLambdaTable,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
const G4ParticleDefinition* particle,
|
||||
G4double& T0,
|
||||
G4double lambda,
|
||||
G4double range,
|
||||
G4double truePathLength)
|
||||
{
|
||||
// do the true -> geom transformation
|
||||
const G4double ztmin = 1./3., ztmax = 0.98 ;
|
||||
|
||||
lambda0 = lambda;
|
||||
lambda1 = -1.;
|
||||
lambdam = -1.;
|
||||
alam = range;
|
||||
zm = 1.;
|
||||
cthm = 1.;
|
||||
tPathLength = truePathLength;
|
||||
G4double tau = tPathLength/lambda0 ;
|
||||
|
||||
if (tau <= tausmall) return tPathLength;
|
||||
|
||||
G4double zmean = tPathLength;
|
||||
|
||||
if (tPathLength < range*dtrl) {
|
||||
zmean = lambda0*(1.-exp(-tau));
|
||||
|
||||
} else {
|
||||
G4LossTableManager* theManager = G4LossTableManager::Instance();
|
||||
G4double T1 = theManager->GetEnergy(particle,range-tPathLength,couple);
|
||||
|
||||
if (theLambdaTable) {
|
||||
G4bool b;
|
||||
lambda1 = ((*theLambdaTable)[couple->GetIndex()])->GetValue(T1,b);
|
||||
} else {
|
||||
lambda1 = CrossSection(couple->GetMaterial(),particle,T1,0.0,1.0);
|
||||
}
|
||||
if (T0 > particle->GetPDGMass()) alam = lambda0*tPathLength/(lambda0-lambda1) ;
|
||||
G4double blam = 1.+alam/lambda0 ;
|
||||
if (tPathLength < 2.*dtrl*range) {
|
||||
zmean = alam*(1.-exp(blam*log(1.-tPathLength/alam)))/blam ;
|
||||
|
||||
} else {
|
||||
G4double w = 1.-0.5*tPathLength/alam ;
|
||||
lambdam = lambda0*w ;
|
||||
G4double 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
|
||||
G4double zPathLength = zmean ;
|
||||
G4double zt = zmean/tPathLength ;
|
||||
if (tPathLength >= stepmin && samplez && zt > ztmin && zt < ztmax) {
|
||||
G4double cz = 0.5*(3.*zt-1.)/(1.-zt) ;
|
||||
G4double cz1 = 1.+cz ;
|
||||
G4double u0 = cz/cz1 ;
|
||||
G4double u,grej ;
|
||||
G4double grej0 = exp(cz*log(u0))*(1.-u0) ;
|
||||
do {
|
||||
u = exp(log(G4UniformRand())/cz1) ;
|
||||
grej = exp(cz*log(u))*(1.-u) ;
|
||||
if (grej > grej0)
|
||||
G4cout << "G4LewisModel: Warning! majorant "
|
||||
<< grej0 << " < " << grej << G4endl;
|
||||
} while (grej < grej0*G4UniformRand()) ;
|
||||
zPathLength = tPathLength*u ;
|
||||
}
|
||||
|
||||
return zPathLength ;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LewisModel::TrueStepLength(G4double geomStepLength)
|
||||
{
|
||||
G4double trueLength = geomStepLength;
|
||||
if (geomStepLength > lambda0*tausmall) {
|
||||
G4double blam = 1.+alam/lambda0;
|
||||
// G4cout << "alam= " << alam << " blam= " << blam << " lambda1= " << lambda1 << G4endl;
|
||||
if (lambda1 < 0.) {
|
||||
trueLength = -lambda0*log(1.-geomStepLength/lambda0) ;
|
||||
|
||||
} else if (lambdam < 0.) {
|
||||
if (blam*geomStepLength < alam)
|
||||
trueLength = alam*(1.-exp(log(1.-blam*geomStepLength/alam)/blam));
|
||||
else
|
||||
trueLength = tPathLength;
|
||||
|
||||
} else {
|
||||
if (geomStepLength <= zm) {
|
||||
|
||||
// ??? here is a problems - redefine variable
|
||||
lambdam = -1.;
|
||||
|
||||
if(blam*geomStepLength < alam )
|
||||
trueLength = alam*(1.-exp(log(1.-blam*geomStepLength/alam)/blam));
|
||||
else
|
||||
trueLength = 0.5*tPathLength;
|
||||
|
||||
} else {
|
||||
G4double clam = 1.+alam/lambdam;
|
||||
// G4cout << "clam= " << clam << " zm= " << zm << " cthm= " << cthm << G4endl;
|
||||
if(clam*(geomStepLength-zm)/(alam*cthm) < 1.)
|
||||
trueLength = 0.5*tPathLength + alam*(1.-
|
||||
exp(log(1.-clam*(geomStepLength-zm)/(alam*cthm)))/clam) ;
|
||||
else
|
||||
trueLength = tPathLength;
|
||||
}
|
||||
}
|
||||
// G4cout << "tLenth= " << trueLength << " tpl= " << tPathLength << G4endl;
|
||||
if(trueLength > tPathLength) trueLength = tPathLength;
|
||||
if(trueLength < geomStepLength) trueLength = geomStepLength;
|
||||
}
|
||||
|
||||
return trueLength;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LewisModel::SampleCosineTheta(G4double trueStepLength)
|
||||
{
|
||||
G4double cth = 1.;
|
||||
currentTau = trueStepLength/lambda0;
|
||||
if(trueStepLength < stepmin)
|
||||
cth = exp(-currentTau) ;
|
||||
else
|
||||
{
|
||||
// G4cout << "tau= " << currentTau << " lambda1= " << lambda1 << " lambdam= " << lambdam << G4endl;
|
||||
if (currentTau > taubig) cth = -1.+2.*G4UniformRand();
|
||||
else if (currentTau >= tausmall)
|
||||
{
|
||||
if(lambda1 > 0.)
|
||||
{
|
||||
if (lambdam < 0.)
|
||||
currentTau = -alam*log(1.-trueStepLength/alam)/lambda0 ;
|
||||
else
|
||||
currentTau = -log(cthm)-alam*
|
||||
log(1.-(trueStepLength-0.5*tPathLength)/alam)/lambdam ;
|
||||
}
|
||||
if(currentTau > taubig) cth = -1.+2.*G4UniformRand();
|
||||
else
|
||||
{
|
||||
const G4double amax = 25. ;
|
||||
const G4double tau0 = 0.02 ;
|
||||
|
||||
G4double a;
|
||||
|
||||
G4double w = log(currentTau/tau0) ;
|
||||
if (currentTau < tau0) a = (alfa1-alfa2*w)/currentTau ;
|
||||
else a = (alfa1+alfa3*w)/currentTau ;
|
||||
|
||||
G4double x0 = 1.-xsi/a ;
|
||||
if(x0 < 0.) x0 = 0. ;
|
||||
|
||||
// from continuity of the 1st derivatives
|
||||
G4double c = a*(b-x0) ;
|
||||
if(a*currentTau < c0) c = c0*(b-x0)/currentTau ;
|
||||
|
||||
if(c == 1.) c=1.000001 ;
|
||||
if(c == 2.) c=2.000001 ;
|
||||
if(c == 3.) c=3.000001 ;
|
||||
|
||||
G4double ea = 0.0;
|
||||
if (a*(1.-x0) < amax) ea = exp(-a*(1.-x0)) ;
|
||||
|
||||
G4double eaa = 1.-ea ;
|
||||
G4double xmean1 = 1.-1./a+(1.-x0)*ea/eaa ;
|
||||
|
||||
G4double b1 = b+1. ;
|
||||
G4double bx = b-x0 ;
|
||||
G4double eb1= exp((c-1.)*log(b1)) ;
|
||||
G4double ebx= exp((c-1.)*log(bx)) ;
|
||||
|
||||
G4double xmean2 = (x0*eb1+ebx+(eb1*bx-b1*ebx)/(2.-c))/(eb1-ebx) ;
|
||||
G4double xmeanth = exp(-currentTau) ;
|
||||
|
||||
G4double cnorm1 = a/eaa ;
|
||||
G4double cnorm2 = (c-1.)*eb1*ebx/(eb1-ebx) ;
|
||||
G4double f1x0 = cnorm1*exp(-a*(1.-x0)) ;
|
||||
G4double f2x0 = cnorm2/exp(c*log(b-x0)) ;
|
||||
|
||||
// from continuity at x=x0
|
||||
G4double prob = f2x0/(f1x0+f2x0) ;
|
||||
// from xmean = xmeanth
|
||||
G4double qprob = (f1x0+f2x0)*xmeanth/(f2x0*xmean1+f1x0*xmean2) ;
|
||||
|
||||
// protection against qprob > 1
|
||||
if(qprob > 1.)
|
||||
{
|
||||
qprob = 1. ;
|
||||
prob = (xmeanth-xmean2)/(xmean1-xmean2) ;
|
||||
}
|
||||
/*
|
||||
G4cout << "tau= " << currentTau << " prob= " << prob << " qprob= " << qprob << G4endl;
|
||||
G4cout << "ea= " << ea << " eaa= " << eaa << " a= " << a
|
||||
<< " b= " << b << " b1= " << b1 << " bx= " << bx
|
||||
<< " ebx= " << ebx << " eb1= " << eb1 << " c= " << c
|
||||
<< G4endl;
|
||||
*/
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// G4cout << "cth= " << cth << G4endl;
|
||||
return cth;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4LewisModel::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;
|
||||
// G4cout << "tau= " << currentTau << " lambda0= " << lambda0 << " etau= " << etau << " kappa= " << kappa << G4endl;
|
||||
}
|
||||
if (rmean>0.) rmean = 2.*lambda0*sqrt(rmean/3.0);
|
||||
else rmean = 0.;
|
||||
// G4cout << "rmean= " << rmean << G4endl;
|
||||
}
|
||||
return rmean;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -29,10 +29,12 @@
|
||||
// File name: G4LossTableBuilder
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
//
|
||||
// Creation date: 03.01.2002
|
||||
//
|
||||
// Modifications:
|
||||
// Modifications:
|
||||
//
|
||||
// 23.01.2003 V.Ivanchenko Cut per region
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
@@ -59,16 +61,16 @@ G4PhysicsTable* G4LossTableBuilder::BuildDEDXTable(
|
||||
|
||||
if(!n_vectors) return 0;
|
||||
|
||||
G4PhysicsVector* pv = (*(list[0]))[0];
|
||||
size_t nbins = pv->GetVectorLength();
|
||||
|
||||
G4double elow = pv->GetLowEdgeEnergy(0);
|
||||
G4double ehigh = pv->GetLowEdgeEnergy(nbins);
|
||||
G4PhysicsTable* theTable = new G4PhysicsTable();
|
||||
G4bool b;
|
||||
|
||||
for (size_t i=0; i<n_vectors; i++) {
|
||||
|
||||
G4PhysicsVector* pv = (*(list[0]))[i];
|
||||
size_t nbins = pv->GetVectorLength();
|
||||
|
||||
G4double elow = pv->GetLowEdgeEnergy(0);
|
||||
G4double ehigh = pv->GetLowEdgeEnergy(nbins);
|
||||
G4PhysicsLogVector* v = new G4PhysicsLogVector(elow, ehigh, nbins);
|
||||
|
||||
for (size_t j=0; j<nbins; j++) {
|
||||
@@ -80,15 +82,15 @@ G4PhysicsTable* G4LossTableBuilder::BuildDEDXTable(
|
||||
dedx += ((*(list[k]))[i])->GetValue(energy, b);
|
||||
|
||||
}
|
||||
v->PutValue(j, dedx);
|
||||
v->PutValue(j, dedx);
|
||||
}
|
||||
theTable->insert(v);
|
||||
theTable->insert(v);
|
||||
}
|
||||
return theTable;
|
||||
}
|
||||
return theTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4PhysicsTable* G4LossTableBuilder::BuildRangeTable(
|
||||
const G4PhysicsTable* dedxTable)
|
||||
// Build range table from the energy loss table
|
||||
@@ -99,17 +101,16 @@ G4PhysicsTable* G4LossTableBuilder::BuildRangeTable(
|
||||
G4bool b;
|
||||
size_t n = 100;
|
||||
G4double del = 1.0/(G4double)n;
|
||||
G4PhysicsVector* pv = (*dedxTable)[0];
|
||||
size_t nbins = pv->GetVectorLength();
|
||||
G4double elow = pv->GetLowEdgeEnergy(0);
|
||||
G4double ehigh = pv->GetLowEdgeEnergy(nbins);
|
||||
G4PhysicsTable* theTable = new G4PhysicsTable();
|
||||
|
||||
for (size_t i=0; i<n_vectors; i++) {
|
||||
|
||||
G4PhysicsVector* pv = (*dedxTable)[i];
|
||||
size_t nbins = pv->GetVectorLength();
|
||||
G4double elow = pv->GetLowEdgeEnergy(0);
|
||||
G4double ehigh = pv->GetLowEdgeEnergy(nbins);
|
||||
G4PhysicsLogVector* v = new G4PhysicsLogVector(elow, ehigh, nbins);
|
||||
|
||||
pv = (*dedxTable)[i];
|
||||
G4double dedx1 = pv->GetValue(elow, b);
|
||||
G4double range = 0.5*elow/dedx1;
|
||||
v->PutValue(0,range);
|
||||
@@ -135,11 +136,11 @@ G4PhysicsTable* G4LossTableBuilder::BuildRangeTable(
|
||||
theTable->insert(v);
|
||||
}
|
||||
|
||||
return theTable;
|
||||
}
|
||||
return theTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4PhysicsTable* G4LossTableBuilder::BuildInverseRangeTable(
|
||||
const G4PhysicsTable* dedxTable,
|
||||
const G4PhysicsTable* rangeTable)
|
||||
@@ -178,11 +179,11 @@ G4PhysicsTable* G4LossTableBuilder::BuildInverseRangeTable(
|
||||
|
||||
for (ihigh=ilow+1; ihigh<nbins; ihigh++) {
|
||||
energy2 = pv->GetLowEdgeEnergy(ihigh);
|
||||
range2 = pv->GetValue(energy2, b);
|
||||
range2 = pv->GetValue(energy2, b);
|
||||
if(range2 >= range || ihigh == nbins-1) {
|
||||
ilow = ihigh - 1;
|
||||
energy1 = pv->GetLowEdgeEnergy(ilow);
|
||||
range1 = pv->GetValue(energy1, b);
|
||||
range1 = pv->GetValue(energy1, b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -194,7 +195,7 @@ G4PhysicsTable* G4LossTableBuilder::BuildInverseRangeTable(
|
||||
theTable->insert(v);
|
||||
}
|
||||
|
||||
return theTable;
|
||||
}
|
||||
return theTable;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -28,13 +28,21 @@
|
||||
//
|
||||
// File name: G4LossTableManager
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 03.01.2002
|
||||
//
|
||||
// Modifications:
|
||||
// Modifications:
|
||||
//
|
||||
// Class Description:
|
||||
// 20-01-03 Migrade to cut per region (V.Ivanchenko)
|
||||
// 15-02-03 Lambda table can be scaled (V.Ivanchenko)
|
||||
// 17-02-03 Fix problem of store/restore tables (V.Ivanchenko)
|
||||
// 10-03-03 Add Ion registration (V.Ivanchenko)
|
||||
// 25-03-03 Add deregistration (V.Ivanchenko)
|
||||
// 02-04-03 Change messenger (V.Ivanchenko)
|
||||
// 26-04-03 Fix retrieve tables (V.Ivanchenko)
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -42,12 +50,13 @@
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4EnergyLossMessengerSTD.hh"
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4Electron.hh"
|
||||
#include "G4VMultipleScattering.hh"
|
||||
|
||||
G4LossTableManager* G4LossTableManager::theInstance = 0;
|
||||
|
||||
@@ -65,6 +74,13 @@ G4LossTableManager* G4LossTableManager::Instance()
|
||||
|
||||
G4LossTableManager::~G4LossTableManager()
|
||||
{
|
||||
for (G4int i=0; i<n_loss; i++) {
|
||||
if( loss_vector[i] ) delete loss_vector[i];
|
||||
}
|
||||
size_t msc = msc_vector.size();
|
||||
for (size_t j=0; j<msc; j++) {
|
||||
if(msc_vector[j] ) delete msc_vector[j];
|
||||
} Clear();
|
||||
delete theMessenger;
|
||||
delete tableBuilder;
|
||||
}
|
||||
@@ -72,10 +88,11 @@ G4LossTableManager::~G4LossTableManager()
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4LossTableManager::G4LossTableManager()
|
||||
{
|
||||
{
|
||||
n_loss = 0;
|
||||
first_entry = true;
|
||||
all_tables_are_built = false;
|
||||
all_particles_are_mapped = false;
|
||||
all_tables_are_stored = false;
|
||||
electron_table_are_built = false;
|
||||
currentLoss = 0;
|
||||
currentParticle = 0;
|
||||
@@ -88,7 +105,7 @@ G4LossTableManager::G4LossTableManager()
|
||||
eIonisation = 0;
|
||||
minKinEnergy = 0.1*eV;
|
||||
maxKinEnergy = 100.0*GeV;
|
||||
theMessenger = new G4EnergyLossMessengerSTD();
|
||||
theMessenger = new G4EnergyLossMessenger();
|
||||
theElectron = G4Electron::Electron();
|
||||
tableBuilder = new G4LossTableBuilder();
|
||||
integral = true;
|
||||
@@ -98,22 +115,14 @@ G4LossTableManager::G4LossTableManager()
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::Clear()
|
||||
{
|
||||
{
|
||||
all_tables_are_built = false;
|
||||
all_particles_are_mapped = false;
|
||||
electron_table_are_built = false;
|
||||
eIonisation = 0;
|
||||
currentLoss = 0;
|
||||
currentParticle = 0;
|
||||
if(n_loss)
|
||||
if(n_loss)
|
||||
{
|
||||
for(G4int i=0; i<n_loss; i++)
|
||||
{
|
||||
if(dedx_vector[i]) dedx_vector[i]->clearAndDestroy();
|
||||
if(range_vector[i]) range_vector[i]->clearAndDestroy();
|
||||
if(inv_range_vector[i]) inv_range_vector[i]->clearAndDestroy();
|
||||
}
|
||||
|
||||
dedx_vector.clear();
|
||||
range_vector.clear();
|
||||
inv_range_vector.clear();
|
||||
@@ -138,44 +147,95 @@ void G4LossTableManager::Register(G4VEnergyLossSTD* p)
|
||||
range_vector.push_back(0);
|
||||
inv_range_vector.push_back(0);
|
||||
tables_are_built.push_back(false);
|
||||
all_particles_are_mapped = false;
|
||||
all_tables_are_built = false;
|
||||
/*
|
||||
p->SetLossFluctuations(lossFluctuationFlag);
|
||||
p->SetSubCutoff(subCutoffFlag);
|
||||
p->SetRandomStep(rndmStepFlag);
|
||||
p->SetMinSubRange(minSubRange);
|
||||
p->SetMinKinEnergy(minKinEnergy);
|
||||
p->SetMaxKinEnergy(maxKinEnergy);
|
||||
p->SetStepLimits(maxRangeVariation, maxFinalStep);
|
||||
p->SetIntegral(integral);
|
||||
*/
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::DeRegister(G4VEnergyLossSTD* p)
|
||||
{
|
||||
for (G4int i=0; i<n_loss; i++) {
|
||||
if(loss_vector[i] == p) loss_vector[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::Register(G4VMultipleScattering* p)
|
||||
{
|
||||
msc_vector.push_back(p);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::DeRegister(G4VMultipleScattering* p)
|
||||
{
|
||||
size_t msc = msc_vector.size();
|
||||
for (size_t i=0; i<msc; i++) {
|
||||
if(msc_vector[i] == p) msc_vector[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::RegisterIon(const G4ParticleDefinition* ion, G4VEnergyLossSTD* p)
|
||||
{
|
||||
loss_map[ion] = p;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
G4EnergyLossMessenger* G4LossTableManager::GetMessenger()
|
||||
{
|
||||
return theMessenger;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
|
||||
|
||||
void G4LossTableManager::ParticleHaveNoLoss(const G4ParticleDefinition* aParticle)
|
||||
{
|
||||
G4String s = "G4LossTableManager:: dE/dx table not found for "
|
||||
+ aParticle->GetParticleName() + "!";
|
||||
G4Exception(s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::Initialise()
|
||||
void G4LossTableManager::Initialise(const G4ParticleDefinition* aParticle)
|
||||
{
|
||||
all_tables_are_built = true;
|
||||
if (first_entry) {
|
||||
first_entry = false;
|
||||
firstParticle = aParticle;
|
||||
}
|
||||
|
||||
for(G4int j=0; j<n_loss; j++) {
|
||||
|
||||
const G4ParticleDefinition* pd = loss_vector[j]->Particle();
|
||||
if (!pd) {
|
||||
pd = loss_vector[j]->GetProcessManager()->GetParticleType();
|
||||
loss_vector[j]->SetParticle(pd);
|
||||
}
|
||||
if(!tables_are_built[j]) all_tables_are_built = false;
|
||||
if(pd != part_vector[j]) {
|
||||
part_vector[j] = pd;
|
||||
base_part_vector[j] = loss_vector[j]->BaseParticle();
|
||||
}
|
||||
if(1 < verbose) {
|
||||
G4String nm = "unknown";
|
||||
const G4ParticleDefinition* pd = loss_vector[j]->Particle();
|
||||
if(pd) nm = pd->GetParticleName();
|
||||
G4cout << "For " << loss_vector[j]->GetProcessName()
|
||||
<< " for " << nm
|
||||
<< " tables_are_built= " << tables_are_built[j]
|
||||
<< " procFlag= " << loss_vector[j]->TablesAreBuilt()
|
||||
<< " all_tables_are_built= " << all_tables_are_built
|
||||
<< G4endl;
|
||||
}
|
||||
if(!loss_vector[j]->TablesAreBuilt()) {
|
||||
all_tables_are_built = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// All tables have to be rebuilt
|
||||
if(all_particles_are_mapped && all_tables_are_built) {
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
if (all_tables_are_built && firstParticle == aParticle) {
|
||||
for (G4int i=0; i<n_loss; i++) {
|
||||
tables_are_built[i] = false;
|
||||
}
|
||||
all_tables_are_built = false;
|
||||
@@ -183,29 +243,9 @@ void G4LossTableManager::Initialise()
|
||||
loss_map.clear();
|
||||
}
|
||||
|
||||
// map all particles
|
||||
if(!all_particles_are_mapped) {
|
||||
|
||||
const G4ParticleDefinition* pd;
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
if(!part_vector[i]) {
|
||||
pd = loss_vector[i]->Particle();
|
||||
if(!pd) {
|
||||
pd = loss_vector[i]->GetProcessManager()->GetParticleType();
|
||||
loss_vector[i]->SetParticle(pd);
|
||||
}
|
||||
if(pd == theElectron) eIonisation = loss_vector[i];
|
||||
part_vector[i] = pd;
|
||||
pd = loss_vector[i]->BaseParticle();
|
||||
base_part_vector[i] = pd;
|
||||
}
|
||||
}
|
||||
all_particles_are_mapped = true;
|
||||
}
|
||||
if(1 < verbose) {
|
||||
G4cout << "electron_table_are_built= " << electron_table_are_built
|
||||
<< " all_tables_are_built= " << all_tables_are_built
|
||||
<< " all_particles_are_mapped= " << all_particles_are_mapped
|
||||
<< " all_tables_are_built= " << all_tables_are_built
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
@@ -213,79 +253,77 @@ void G4LossTableManager::Initialise()
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::BuildDEDXTable(const G4ParticleDefinition* aParticle)
|
||||
void G4LossTableManager::BuildPhysicsTable(const G4ParticleDefinition* aParticle)
|
||||
{
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildDEDXTable() for "
|
||||
<< aParticle->GetParticleName()
|
||||
if(0 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildDEDXTable() for "
|
||||
<< aParticle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
Initialise();
|
||||
Initialise(aParticle);
|
||||
|
||||
// identify all particles and built electron table
|
||||
if(!electron_table_are_built) {
|
||||
eIonisation = BuildTables(theElectron);
|
||||
currentLoss = eIonisation;
|
||||
currentParticle = theElectron;
|
||||
electron_table_are_built = true;
|
||||
}
|
||||
|
||||
// If particle is not an electron
|
||||
// If particle is not an electron
|
||||
if(aParticle != theElectron) {
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
|
||||
if(1 < verbose) {
|
||||
G4String nm = "0";
|
||||
G4String nm1= "0";
|
||||
G4String nm2= "0";
|
||||
const G4ParticleDefinition* pd = loss_vector[i]->Particle();
|
||||
const G4ParticleDefinition* bpd = loss_vector[i]->BaseParticle();
|
||||
if(pd) nm = pd->GetParticleName();
|
||||
if(bpd) nm2 = bpd->GetParticleName();
|
||||
if(part_vector[i]) nm1 = part_vector[i]->GetParticleName();
|
||||
G4cout << "For " << loss_vector[i]->GetProcessName()
|
||||
<< " for " << nm
|
||||
<< " (" << nm1 << ") "
|
||||
<< " base_part= " << nm2
|
||||
<< " tables_are_built= " << tables_are_built[i]
|
||||
<< G4endl;
|
||||
}
|
||||
if(aParticle == part_vector[i]) {
|
||||
if(tables_are_built[i]) break;
|
||||
base_part_vector[i] = loss_vector[i]->BaseParticle();
|
||||
if(!base_part_vector[i]) {
|
||||
G4VEnergyLossSTD* hIonisation = BuildTables(aParticle);
|
||||
for(G4int j=0; j<i; j++) {
|
||||
if(aParticle == base_part_vector[j]) {
|
||||
if (aParticle == base_part_vector[j]) {
|
||||
tables_are_built[j] = true;
|
||||
G4VEnergyLossSTD* em = loss_vector[j];
|
||||
G4VEnergyLossSTD* em = loss_vector[j];
|
||||
em->Initialise();
|
||||
em->SetDEDXTable(hIonisation->DEDXTable());
|
||||
em->SetRangeTable(hIonisation->RangeTable());
|
||||
em->SetInverseRangeTable(hIonisation->InverseRangeTable());
|
||||
loss_map[part_vector[j]] = hIonisation;
|
||||
if(em->SecondaryParticle() == theElectron) {
|
||||
em->SetLambdaTable(hIonisation->LambdaTable());
|
||||
em->SetSubLambdaTable(hIonisation->SubLambdaTable());
|
||||
loss_map[part_vector[j]] = em;
|
||||
if (em->SecondaryParticle() == theElectron) {
|
||||
em->SetSecondaryRangeTable(eIonisation->RangeTable());
|
||||
}
|
||||
if (0 < verbose) {
|
||||
G4cout << "For " << loss_vector[j]->GetProcessName()
|
||||
<< " for " << part_vector[j]->GetParticleName()
|
||||
<< " base_part= " << base_part_vector[j]->GetParticleName()
|
||||
<< " tables_are_built= " << G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
G4VEnergyLossSTD* em = loss_vector[i];
|
||||
for(G4int j=0; j<n_loss; j++) {
|
||||
if(part_vector[j] == base_part_vector[i]) {
|
||||
G4VEnergyLossSTD* hIonisation = loss_vector[j];
|
||||
if(tables_are_built[j] && hIonisation->DEDXTable()) {
|
||||
tables_are_built[i] = true;
|
||||
em->Initialise();
|
||||
em->SetDEDXTable(hIonisation->DEDXTable());
|
||||
em->SetRangeTable(hIonisation->RangeTable());
|
||||
em->SetInverseRangeTable(hIonisation->InverseRangeTable());
|
||||
loss_map[part_vector[i]] = hIonisation;
|
||||
if(em->SecondaryParticle() == theElectron) {
|
||||
if (tables_are_built[j] && part_vector[j] == base_part_vector[i]) {
|
||||
G4VEnergyLossSTD* hIonisation = loss_vector[j];
|
||||
tables_are_built[i] = true;
|
||||
em->Initialise();
|
||||
em->SetDEDXTable(hIonisation->DEDXTable());
|
||||
em->SetRangeTable(hIonisation->RangeTable());
|
||||
em->SetInverseRangeTable(hIonisation->InverseRangeTable());
|
||||
em->SetLambdaTable(hIonisation->LambdaTable());
|
||||
em->SetSubLambdaTable(hIonisation->SubLambdaTable());
|
||||
loss_map[part_vector[i]] = em;
|
||||
if (em->SecondaryParticle() == theElectron)
|
||||
em->SetSecondaryRangeTable(eIonisation->RangeTable());
|
||||
}
|
||||
break;
|
||||
if (0 < verbose) {
|
||||
G4cout << "For " << em->GetProcessName()
|
||||
<< " for " << part_vector[i]->GetParticleName()
|
||||
<< " base_part= " << base_part_vector[i]->GetParticleName()
|
||||
<< " tables_are_built= " << G4endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,60 +331,105 @@ void G4LossTableManager::BuildDEDXTable(const G4ParticleDefinition* aParticle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
all_tables_are_built = true;
|
||||
for (G4int ii=0; ii<n_loss; ii++) {
|
||||
if ( !tables_are_built[ii] ) {
|
||||
all_tables_are_built = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildDEDXTable: end; "
|
||||
<< "all_tables_are_built= " << all_tables_are_built
|
||||
G4cout << "G4LossTableManager::BuildDEDXTable: end; "
|
||||
<< "all_tables_are_built= " << all_tables_are_built
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::RetrieveDEDXTable(const G4ParticleDefinition* aParticle,
|
||||
G4VEnergyLossSTD* theModel)
|
||||
void G4LossTableManager::RetrievePhysicsTables(const G4ParticleDefinition* aParticle,
|
||||
G4VEnergyLossSTD* theLoss)
|
||||
{
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
if(theModel == loss_vector[i]) {
|
||||
if(0 < verbose) {
|
||||
G4cout << "G4LossTableManager::RetrievePhysicsTable() for "
|
||||
<< aParticle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
if (first_entry) Initialise(aParticle);
|
||||
if (all_tables_are_built) return;
|
||||
|
||||
G4bool hasRange = false;
|
||||
for (G4int i=0; i<n_loss; i++) {
|
||||
if ( theLoss == loss_vector[i] ) {
|
||||
tables_are_built[i] = true;
|
||||
if(theModel->DEDXTable()) {
|
||||
for(G4int j=0; j<n_loss; j++) {
|
||||
if(j != i && tables_are_built[j]) {
|
||||
if(aParticle == base_part_vector[j]) {
|
||||
G4VEnergyLossSTD* em = loss_vector[j];
|
||||
em->SetDEDXTable(theModel->DEDXTable());
|
||||
em->SetRangeTable(theModel->RangeTable());
|
||||
em->SetInverseRangeTable(theModel->InverseRangeTable());
|
||||
loss_map[part_vector[j]] = theModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const G4ParticleDefinition* bp = theModel->BaseParticle();
|
||||
for(G4int j=0; j<n_loss; j++) {
|
||||
if(j != i && tables_are_built[j]) {
|
||||
if(bp == part_vector[j] && loss_vector[j]->DEDXTable()) {
|
||||
G4VEnergyLossSTD* hIonisation = loss_vector[j];
|
||||
theModel->SetDEDXTable(hIonisation->DEDXTable());
|
||||
theModel->SetRangeTable(hIonisation->RangeTable());
|
||||
theModel->SetInverseRangeTable(hIonisation->InverseRangeTable());
|
||||
loss_map[part_vector[j]] = hIonisation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (theLoss->RangeTable()) {
|
||||
if (part_vector[i] == theElectron) {
|
||||
eIonisation = theLoss;
|
||||
currentLoss = theLoss;
|
||||
currentParticle = theElectron;
|
||||
electron_table_are_built = true;
|
||||
}
|
||||
loss_map[part_vector[i]] = theLoss;
|
||||
hasRange = true;
|
||||
if (0 < verbose) {
|
||||
G4cout << "dEdx and Range tables are defined for "
|
||||
<< aParticle->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (electron_table_are_built && theLoss->SecondaryParticle() == theElectron)
|
||||
theLoss->SetSecondaryRangeTable(eIonisation->RangeTable());
|
||||
}
|
||||
|
||||
if ( hasRange ) {
|
||||
for (G4int j=0; j<n_loss; j++) {
|
||||
if ( base_part_vector[j] == aParticle && !tables_are_built[j] ) {
|
||||
G4VEnergyLossSTD* em = loss_vector[j];
|
||||
tables_are_built[j] = true;
|
||||
em->Initialise();
|
||||
em->SetDEDXTable(theLoss->DEDXTable());
|
||||
em->SetRangeTable(theLoss->RangeTable());
|
||||
em->SetInverseRangeTable(theLoss->InverseRangeTable());
|
||||
em->SetLambdaTable(theLoss->LambdaTable());
|
||||
em->SetSubLambdaTable(theLoss->SubLambdaTable());
|
||||
if (electron_table_are_built && em->SecondaryParticle() == theElectron)
|
||||
em->SetSecondaryRangeTable(eIonisation->RangeTable());
|
||||
loss_map[part_vector[j]] = em;
|
||||
if (1 < verbose) {
|
||||
G4String nm = "0";
|
||||
G4String nm1= "0";
|
||||
G4String nm2= "0";
|
||||
const G4ParticleDefinition* pd = part_vector[j];
|
||||
const G4ParticleDefinition* bpd = base_part_vector[j];
|
||||
if (pd) nm = pd->GetParticleName();
|
||||
if (bpd) nm2 = bpd->GetParticleName();
|
||||
if (part_vector[j]) nm1 = part_vector[j]->GetParticleName();
|
||||
G4cout << "For " << loss_vector[j]->GetProcessName()
|
||||
<< " for " << nm
|
||||
<< " (" << nm1 << ") "
|
||||
<< " base_part= " << nm2
|
||||
<< " tables_are_built= " << tables_are_built[j]
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
all_tables_are_built = true;
|
||||
for (G4int ii=0; ii<n_loss; ii++) {
|
||||
if ( !tables_are_built[ii] ) {
|
||||
all_tables_are_built = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// identify all particles and built electron table
|
||||
if(aParticle == theElectron) {
|
||||
electron_table_are_built = true;
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
if(loss_vector[i]->SecondaryParticle() == theElectron) {
|
||||
loss_vector[i]->SetSecondaryRangeTable(theModel->RangeTable());
|
||||
}
|
||||
}
|
||||
if(0 < verbose) {
|
||||
G4cout << "G4LossTableManager::RetrievePhysicsTable: end; "
|
||||
<< "all_tables_are_built= " << all_tables_are_built
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,8 +437,8 @@ void G4LossTableManager::RetrieveDEDXTable(const G4ParticleDefinition* aParticle
|
||||
|
||||
G4VEnergyLossSTD* G4LossTableManager::BuildTables(const G4ParticleDefinition* aParticle)
|
||||
{
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildTables() for "
|
||||
if(0 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildTables() for "
|
||||
<< aParticle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
@@ -364,42 +447,41 @@ G4VEnergyLossSTD* G4LossTableManager::BuildTables(const G4ParticleDefinition* aP
|
||||
list.clear();
|
||||
G4std::vector<G4VEnergyLossSTD*> loss_list;
|
||||
loss_list.clear();
|
||||
G4VEnergyLossSTD* em = 0;
|
||||
G4VEnergyLossSTD* em = 0;
|
||||
G4int iem = 0;
|
||||
G4bool no_el = true;
|
||||
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
if(aParticle == part_vector[i]) {
|
||||
base_part_vector[i] = loss_vector[i]->BaseParticle();
|
||||
for (G4int i=0; i<n_loss; i++) {
|
||||
if (aParticle == part_vector[i]) {
|
||||
loss_vector[i]->Initialise();
|
||||
if(no_el && loss_vector[i]->SecondaryParticle() == theElectron) {
|
||||
em = loss_vector[i];
|
||||
iem= i;
|
||||
no_el = false;
|
||||
}
|
||||
}
|
||||
if(!em) {
|
||||
em = loss_vector[i];
|
||||
iem= i;
|
||||
}
|
||||
}
|
||||
tables_are_built[i] = true;
|
||||
list.push_back(loss_vector[i]->BuildDEDXTable());
|
||||
loss_list.push_back(loss_vector[i]);
|
||||
}
|
||||
}
|
||||
|
||||
G4int n_dedx = list.size();
|
||||
if(!n_dedx) return 0;
|
||||
G4int n_dedx = list.size();
|
||||
if (!n_dedx) return 0;
|
||||
|
||||
if(aParticle == theElectron) eIonisation = em;
|
||||
if (aParticle == theElectron) eIonisation = em;
|
||||
|
||||
if(0 < verbose) {
|
||||
if (1 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildTables() start to build range tables"
|
||||
<< " and the sum of " << n_dedx << " processes"
|
||||
<< " and the sum of " << n_dedx << " processes"
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4PhysicsTable* dedx = list[0];
|
||||
if(1 < n_dedx) {
|
||||
if (1 < n_dedx) {
|
||||
dedx = tableBuilder->BuildDEDXTable(list);
|
||||
for(G4int i=0; i<n_dedx; i++) {
|
||||
list[i]->clearAndDestroy();
|
||||
@@ -415,14 +497,21 @@ G4VEnergyLossSTD* G4LossTableManager::BuildTables(const G4ParticleDefinition* aP
|
||||
inv_range_vector[iem] = invrange;
|
||||
|
||||
loss_map[aParticle] = em;
|
||||
for(G4int j=0; j<n_dedx; j++) {
|
||||
if(loss_list[j]->SecondaryParticle() == theElectron) {
|
||||
loss_list[j]->SetSecondaryRangeTable(eIonisation->RangeTable());
|
||||
for (G4int j=0; j<n_dedx; j++) {
|
||||
if(loss_list[j]->SecondaryParticle() == theElectron)
|
||||
loss_list[j]->SetSecondaryRangeTable(eIonisation->RangeTable());
|
||||
|
||||
G4PhysicsTable* lambdaTable = loss_list[j]->BuildLambdaTable();
|
||||
loss_list[j]->SetLambdaTable(lambdaTable);
|
||||
if (0 < loss_list[j]->NumberOfSubCutoffRegions()) {
|
||||
lambdaTable = loss_list[j]->BuildLambdaSubTable();
|
||||
loss_list[j]->SetSubLambdaTable(lambdaTable);
|
||||
}
|
||||
}
|
||||
if(1 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildTables: Tables are built"
|
||||
<< " for " << em->GetProcessName()
|
||||
if (0 < verbose) {
|
||||
G4cout << "G4LossTableManager::BuildTables: Tables are built for "
|
||||
<< aParticle->GetParticleName()
|
||||
<< "; ionisation process: " << em->GetProcessName()
|
||||
<< G4endl;
|
||||
}
|
||||
return em;
|
||||
@@ -430,7 +519,7 @@ G4VEnergyLossSTD* G4LossTableManager::BuildTables(const G4ParticleDefinition* aP
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::SetLossFluctuations(G4bool val)
|
||||
void G4LossTableManager::SetLossFluctuations(G4bool val)
|
||||
{
|
||||
lossFluctuationFlag = val;
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
@@ -440,7 +529,7 @@ void G4LossTableManager::SetLossFluctuations(G4bool val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::SetSubCutoff(G4bool val)
|
||||
void G4LossTableManager::SetSubCutoff(G4bool val)
|
||||
{
|
||||
subCutoffFlag = val;
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
@@ -460,7 +549,7 @@ void G4LossTableManager::SetIntegral(G4bool val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::SetMinSubRange(G4double val)
|
||||
void G4LossTableManager::SetMinSubRange(G4double val)
|
||||
{
|
||||
minSubRange = val;
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
@@ -480,7 +569,7 @@ void G4LossTableManager::SetRandomStep(G4bool val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::SetMinEnergy(G4double val)
|
||||
void G4LossTableManager::SetMinEnergy(G4double val)
|
||||
{
|
||||
minKinEnergy = val;
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
@@ -490,7 +579,7 @@ void G4LossTableManager::SetMinEnergy(G4double val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::SetMaxEnergy(G4double val)
|
||||
void G4LossTableManager::SetMaxEnergy(G4double val)
|
||||
{
|
||||
maxKinEnergy = val;
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
@@ -500,9 +589,9 @@ void G4LossTableManager::SetMaxEnergy(G4double val)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
void G4LossTableManager::SetStepLimits(G4double v1, G4double v2)
|
||||
void G4LossTableManager::SetStepLimits(G4double v1, G4double v2)
|
||||
{
|
||||
maxRangeVariation = v1;
|
||||
maxRangeVariation = v1;
|
||||
maxFinalStep = v2;
|
||||
for(G4int i=0; i<n_loss; i++) {
|
||||
loss_vector[i]->SetStepLimits(v1, v2);
|
||||
@@ -511,47 +600,4 @@ void G4LossTableManager::SetStepLimits(G4double v1, G4double v2)
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4bool G4LossTableManager::StorePhysicsTable(G4VEnergyLossSTD* el,
|
||||
const G4String& dedx_file,
|
||||
const G4String& range_file,
|
||||
const G4String& inv_range_file,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4int i=0;
|
||||
for(i=0; i<n_loss; i++) {
|
||||
if(el == loss_vector[i]) break;
|
||||
}
|
||||
|
||||
// store stopping power table
|
||||
if (dedx_vector[i]) {
|
||||
if ( !dedx_vector[i]->StorePhysicsTable(dedx_file, ascii) ){
|
||||
G4cout << "Fatal error theDEDXTable->StorePhysicsTable in <"
|
||||
<< dedx_file << ">"
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (range_vector[i]) {
|
||||
if ( !range_vector[i]->StorePhysicsTable(range_file, ascii) ){
|
||||
G4cout << "Fatal error theRangeTable->StorePhysicsTable in <"
|
||||
<< range_file << ">"
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (inv_range_vector[i]) {
|
||||
if ( !inv_range_vector[i]->StorePhysicsTable(inv_range_file, ascii) ){
|
||||
G4cout << "Fatal error theInverseRangeTable->StorePhysicsTable in <"
|
||||
<< inv_range_file << ">"
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4MultipleScattering.cc,v 1.30 2002/12/11 12:05:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4MultipleScattering.cc,v 1.39 2003/04/28 15:31:40 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// 16/05/01 value of cparm changed , L.Urban
|
||||
@@ -52,8 +52,14 @@
|
||||
// 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
|
||||
// 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)
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -64,13 +70,13 @@
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4MultipleScattering::G4MultipleScattering(const G4String& processName)
|
||||
: G4VContinuousDiscreteProcess(processName),
|
||||
theTransportMeanFreePathTable(0),
|
||||
fTransportMeanFreePath (1.e12),kappa(2.5),
|
||||
taubig(8.0),tausmall(1.e-14),taulim(1.e-5),
|
||||
LowestKineticEnergy(0.1*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
@@ -84,8 +90,10 @@ G4MultipleScattering::G4MultipleScattering(const G4String& processName)
|
||||
stepno(0),stepnolastmsc(-1000000),nsmallstep(5),
|
||||
laststep(0.),
|
||||
valueGPILSelectionMSC(NotCandidateForSelection),
|
||||
pcz(0.17),zmean(0.),
|
||||
range(1.0),T1(1.0),lambda1(-1.),cth1(1.),z1(1.e10),dtrl(0.15),
|
||||
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),
|
||||
@@ -110,12 +118,13 @@ void G4MultipleScattering::BuildPhysicsTable(
|
||||
{
|
||||
// set values of some data members
|
||||
if((aParticleType.GetParticleName() == "e-") ||
|
||||
(aParticleType.GetParticleName() == "e+"))
|
||||
(aParticleType.GetParticleName() == "e+"))
|
||||
{
|
||||
// parameters for e+/e-
|
||||
alfa1 = 1.45 ;
|
||||
alfa2 = 0.60 ;
|
||||
alfa3 = 1.80 ;
|
||||
alfa3 = 0.30 ;
|
||||
b = 1. ;
|
||||
xsi = facxsi*2.22 ;
|
||||
c0 = 2.30 ;
|
||||
}
|
||||
@@ -124,11 +133,15 @@ void G4MultipleScattering::BuildPhysicsTable(
|
||||
// parameters for heavy particles
|
||||
alfa1 = 1.10 ;
|
||||
alfa2 = 0.14 ;
|
||||
alfa3 = 0.42 ;
|
||||
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;
|
||||
@@ -143,13 +156,14 @@ void G4MultipleScattering::BuildPhysicsTable(
|
||||
}
|
||||
|
||||
// create table
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
theTransportMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
|
||||
theTransportMeanFreePathTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t i=0; i<numOfCouples; i++)
|
||||
{
|
||||
|
||||
// create physics vector and fill it
|
||||
@@ -157,13 +171,14 @@ void G4MultipleScattering::BuildPhysicsTable(
|
||||
LowestKineticEnergy,HighestKineticEnergy,TotBin);
|
||||
|
||||
// get elements in the material
|
||||
const G4Material* material = (*theMaterialTable)[J];
|
||||
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++)
|
||||
{
|
||||
@@ -194,6 +209,7 @@ void G4MultipleScattering::BuildPhysicsTable(
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4MultipleScattering::ComputeTransportCrossSection(
|
||||
const G4ParticleDefinition& aParticleType,
|
||||
G4double KineticEnergy,
|
||||
@@ -314,11 +330,11 @@ G4double G4MultipleScattering::ComputeTransportCrossSection(
|
||||
G4double ParticleMass = aParticleType.GetPDGMass();
|
||||
|
||||
// correction if particle .ne. e-/e+
|
||||
// compute equivalent kinetic energy
|
||||
// compute equivalent kinetic energy
|
||||
// lambda depends on p*beta ....
|
||||
G4double Mass = ParticleMass ;
|
||||
if((aParticleType.GetParticleName() != "e-") &&
|
||||
(aParticleType.GetParticleName() != "e+") )
|
||||
(aParticleType.GetParticleName() != "e+") )
|
||||
{
|
||||
// TAU = Tkin/ParticleMass , tau = Tkin_scaled/electronmass
|
||||
// p*beta = Mass*TAU*(TAU+2.)/(TAU+1.) =
|
||||
@@ -434,15 +450,17 @@ G4double G4MultipleScattering::ComputeTransportCrossSection(
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4MultipleScattering::GetContinuousStepLimit(
|
||||
const G4Track& track,
|
||||
const G4Track& track,
|
||||
G4double,
|
||||
G4double currentMinimumStep,
|
||||
G4double&)
|
||||
{
|
||||
G4double zPathLength,tPathLength;
|
||||
const G4DynamicParticle* aParticle;
|
||||
G4Material* aMaterial;
|
||||
G4double KineticEnergy,tau,z0,kz;
|
||||
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
|
||||
@@ -450,20 +468,28 @@ G4double G4MultipleScattering::GetContinuousStepLimit(
|
||||
|
||||
tPathLength = currentMinimumStep;
|
||||
|
||||
aMaterial = track.GetMaterial();
|
||||
materialIndex = aMaterial->GetIndex();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
materialIndex = couple->GetIndex();
|
||||
|
||||
aParticle = track.GetDynamicParticle();
|
||||
KineticEnergy = aParticle->GetKineticEnergy();
|
||||
T0 = aParticle->GetKineticEnergy();
|
||||
|
||||
lambda0 = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(T0,isOut);
|
||||
|
||||
fTransportMeanFreePath = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(KineticEnergy,isOut);
|
||||
|
||||
range = G4EnergyLossTables::GetRange(aParticle->GetDefinition(),
|
||||
KineticEnergy,aMaterial);
|
||||
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)
|
||||
if (boundary && range >= currentMinimumStep)
|
||||
{
|
||||
// step limitation at boundary ?
|
||||
stepno = track.GetCurrentStepNumber() ;
|
||||
@@ -471,125 +497,165 @@ G4double G4MultipleScattering::GetContinuousStepLimit(
|
||||
{
|
||||
stepnolastmsc = -1000000 ;
|
||||
tlimit = 1.e10 ;
|
||||
}
|
||||
}
|
||||
|
||||
if(stepno > 1)
|
||||
if(stepno > 1)
|
||||
{
|
||||
if(track.GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary)
|
||||
{
|
||||
stepnolastmsc = stepno ;
|
||||
// if : diff.treatment for small/not small Z
|
||||
if(range > fTransportMeanFreePath)
|
||||
if(range > lambda0)
|
||||
tlimit = facrange*range ;
|
||||
else
|
||||
tlimit = facrange*fTransportMeanFreePath ;
|
||||
tlimit = facrange*lambda0 ;
|
||||
if(tlimit < tlimitmin) tlimit = tlimitmin ;
|
||||
laststep = tlimit ;
|
||||
if(tPathLength > tlimit)
|
||||
{
|
||||
tPathLength = tlimit ;
|
||||
valueGPILSelectionMSC = CandidateForSelection;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(stepno > stepnolastmsc)
|
||||
else if(stepno > stepnolastmsc)
|
||||
{
|
||||
if((stepno - stepnolastmsc) < nsmallstep)
|
||||
if((stepno - stepnolastmsc) < nsmallstep)
|
||||
{
|
||||
if(tPathLength > tlimit)
|
||||
{
|
||||
laststep *= cf ;
|
||||
tPathLength = laststep ;
|
||||
valueGPILSelectionMSC = CandidateForSelection;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// do the true -> geom transformation
|
||||
lambda1 = -1.;
|
||||
z1 = 1.e10 ;
|
||||
zmean = tPathLength;
|
||||
|
||||
tau = tPathLength/fTransportMeanFreePath ;
|
||||
|
||||
if(tau < tausmall) zPathLength = tPathLength;
|
||||
tau = tPathLength/lambda0 ;
|
||||
|
||||
if (tau < tausmall || range < currentMinimumStep) zPathLength = tPathLength;
|
||||
else
|
||||
{
|
||||
if(tPathLength/range < dtrl) zmean = fTransportMeanFreePath*(1.-exp(-tau));
|
||||
if(tPathLength/range < dtrl) zmean = lambda0*(1.-exp(-tau));
|
||||
else
|
||||
{
|
||||
{
|
||||
T1 = G4EnergyLossTables::GetPreciseEnergyFromRange(
|
||||
aParticle->GetDefinition(),range-0.5*tPathLength,aMaterial);
|
||||
aParticle->GetDefinition(),range-tPathLength,couple);
|
||||
lambda1 = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(T1,isOut);
|
||||
z1 = fTransportMeanFreePath*(1.-exp(-0.5*tau));
|
||||
cth1 = exp(-0.5*tau);
|
||||
zmean = z1 + lambda1*(1.-exp(-0.5*tPathLength/lambda1))*cth1;
|
||||
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
|
||||
if ((pcz > 0.) && (2.*zmean > tPathLength))
|
||||
zt = zmean/tPathLength ;
|
||||
if (samplez && (zt < ztmax) && (zt > 0.5))
|
||||
{
|
||||
z0 = zmean+pcz*(tPathLength-zmean);
|
||||
kz = (2.*zmean-tPathLength)/(z0-zmean)+1.;
|
||||
if (G4UniformRand() < z0/tPathLength)
|
||||
zPathLength = z0*exp(log(G4UniformRand())/kz);
|
||||
else zPathLength = tPathLength-(tPathLength-z0)
|
||||
*exp(log(1.-G4UniformRand())/kz);
|
||||
}
|
||||
else
|
||||
{
|
||||
zPathLength = zmean;
|
||||
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;
|
||||
zLast = zPathLength;
|
||||
|
||||
return zPathLength;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VParticleChange* G4MultipleScattering::AlongStepDoIt(
|
||||
const G4Track& track,const G4Step& Step)
|
||||
{
|
||||
const G4Track& track,const G4Step& step)
|
||||
{
|
||||
// only a geom path->true path transformation is performed
|
||||
|
||||
fParticleChange.Initialize(track);
|
||||
|
||||
G4double geomPathLength = track.GetStepLength();
|
||||
|
||||
G4double truePathLength;
|
||||
|
||||
if (geomPathLength/fTransportMeanFreePath < tausmall)
|
||||
truePathLength = geomPathLength;
|
||||
else if(geomPathLength == zLast) truePathLength = tLast;
|
||||
else
|
||||
{
|
||||
if (geomPathLength <= z1)
|
||||
{
|
||||
if (geomPathLength < fTransportMeanFreePath)
|
||||
truePathLength = -fTransportMeanFreePath
|
||||
*log(1.-geomPathLength/fTransportMeanFreePath);
|
||||
else truePathLength = range;
|
||||
G4double geomPathLength = step.GetStepLength();
|
||||
|
||||
lambda1 = -1.;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((geomPathLength-z1)/(cth1*lambda1) < 1.)
|
||||
truePathLength = 0.5*tLast-lambda1
|
||||
*log(1.-(geomPathLength-z1)/(cth1*lambda1));
|
||||
else truePathLength = range;
|
||||
}
|
||||
}
|
||||
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.SetTrueStepLength(truePathLength);
|
||||
|
||||
return &fParticleChange;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -599,8 +665,7 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
const G4Step& stepData)
|
||||
{
|
||||
// angle distribution parameters
|
||||
const G4double kappapl1 = kappa+1., kappami1 = kappa-1. ;
|
||||
G4bool isOut;
|
||||
const G4double kappa = 2.5, kappapl1 = kappa+1., kappami1 = kappa-1. ;
|
||||
|
||||
fParticleChange.Initialize(trackData);
|
||||
G4double truestep = stepData.GetStepLength();
|
||||
@@ -608,30 +673,31 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
|
||||
G4double KineticEnergy = aParticle->GetKineticEnergy();
|
||||
|
||||
fTransportMeanFreePath = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(KineticEnergy,isOut);
|
||||
|
||||
// change direction first ( scattering )
|
||||
G4double cth =1 ;
|
||||
G4double tau = truestep/fTransportMeanFreePath;
|
||||
|
||||
if(KineticEnergy <= 0.)
|
||||
;
|
||||
else
|
||||
// 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.) tau = 0.5*tLast/lambda1
|
||||
+(truestep-0.5*tLast)/fTransportMeanFreePath;
|
||||
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 b = 1. ;
|
||||
|
||||
|
||||
G4double a,x0,c,xmean1,xmean2,
|
||||
xmeanth,prob,qprob ;
|
||||
G4double ea,eaa,b1,bx,eb1,ebx,cnorm1,cnorm2,f1x0,f2x0,w ;
|
||||
@@ -642,11 +708,11 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
else
|
||||
a = (alfa1+alfa3*w)/tau ;
|
||||
|
||||
x0 = 1.-xsi/a ;
|
||||
x0 = 1.-xsi/a ;
|
||||
if(x0 < 0.) x0 = 0. ;
|
||||
|
||||
// from continuity of the 1st derivatives
|
||||
c = a*(b-x0) ;
|
||||
c = a*(b-x0) ;
|
||||
if(a*tau < c0)
|
||||
c = c0*(b-x0)/tau ;
|
||||
|
||||
@@ -659,7 +725,7 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
else
|
||||
ea = 0. ;
|
||||
eaa = 1.-ea ;
|
||||
xmean1 = 1.-1./a+(1.-x0)*ea/eaa ;
|
||||
xmean1 = 1.-1./a+(1.-x0)*ea/eaa ;
|
||||
|
||||
b1 = b+1. ;
|
||||
bx=b-x0 ;
|
||||
@@ -669,7 +735,7 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
|
||||
xmeanth = exp(-tau) ;
|
||||
|
||||
cnorm1 = a/eaa ;
|
||||
cnorm1 = a/eaa ;
|
||||
cnorm2 = (c-1.)*eb1*ebx/(eb1-ebx) ;
|
||||
f1x0 = cnorm1*exp(-a*(1.-x0)) ;
|
||||
f2x0 = cnorm2/exp(c*log(b-x0)) ;
|
||||
@@ -697,10 +763,9 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
cth = b-b1*bx/exp(log(ebx-G4UniformRand()*(ebx-eb1))/(c-1.)) ;
|
||||
}
|
||||
else
|
||||
cth = -1.+2.*G4UniformRand() ;
|
||||
cth = -1.+2.*G4UniformRand() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4double sth = sqrt(1.-cth*cth);
|
||||
G4double phi = twopi*G4UniformRand();
|
||||
@@ -716,13 +781,13 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
|
||||
if (fLatDisplFlag)
|
||||
{
|
||||
// compute mean lateral displacement, only for safety > tolerance !
|
||||
// compute mean lateral displacement, only for safety > tolerance !
|
||||
G4double safetyminustolerance = stepData.GetPostStepPoint()->GetSafety();
|
||||
G4double rmean, etau;
|
||||
|
||||
|
||||
if (safetyminustolerance > 0.)
|
||||
{
|
||||
if (tau < tausmall) rmean = 0.;
|
||||
if (tau < tausmall) rmean = 0.;
|
||||
else if(tau < taulim) rmean = kappa*tau*tau*tau*(1.-kappapl1*tau/4.)/6. ;
|
||||
else
|
||||
{
|
||||
@@ -733,7 +798,7 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
rmean += tau-kappapl1/kappa+kappa*etau/kappami1;
|
||||
}
|
||||
|
||||
if (rmean>0.) rmean = 2.*fTransportMeanFreePath*sqrt(rmean/3.);
|
||||
if (rmean>0.) rmean = 2.*lambda0*sqrt(rmean/3.);
|
||||
else rmean = 0.;
|
||||
|
||||
// for rmean > 0) only
|
||||
@@ -751,7 +816,7 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
// compute new endpoint of the Step
|
||||
G4ThreeVector newPosition = stepData.GetPostStepPoint()->GetPosition()
|
||||
+ rmean*latDirection;
|
||||
|
||||
|
||||
G4Navigator* navigator =
|
||||
G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
@@ -761,6 +826,7 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &fParticleChange;
|
||||
}
|
||||
@@ -779,7 +845,7 @@ G4VParticleChange* G4MultipleScattering::PostStepDoIt(
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
@@ -793,6 +859,32 @@ G4bool G4MultipleScattering::RetrievePhysicsTable(
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
// set values of some data members
|
||||
G4String name = particle->GetParticleName();
|
||||
if(name == "e-" || name == "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 = particle->GetPDGMass();
|
||||
|
||||
// delete theTransportMeanFreePathTable
|
||||
if (theTransportMeanFreePathTable != 0) {
|
||||
theTransportMeanFreePathTable->clearAndDestroy();
|
||||
@@ -803,22 +895,25 @@ G4bool G4MultipleScattering::RetrievePhysicsTable(
|
||||
|
||||
// retreive mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
theTransportMeanFreePathTable =
|
||||
theTransportMeanFreePathTable =
|
||||
new G4PhysicsTable(G4Material::GetNumberOfMaterials());
|
||||
if (!theTransportMeanFreePathTable->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;
|
||||
|
||||
if (name == "e-" || name == "mu+" || name == "proton") PrintInfoDefinition();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
void G4MultipleScattering::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = " Tables of transport mean free paths.";
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
// * statement, and all its terms. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4MultipleScatteringSTD.cc,v 1.6 2002/12/11 12:05:02 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4MultipleScatteringSTD.cc,v 1.18 2003/04/28 15:31:40 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// 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)
|
||||
// 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)
|
||||
@@ -52,8 +52,14 @@
|
||||
// 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
|
||||
// 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 (L.Urban)
|
||||
// 13-04-03 add initialisation in GetContinuesStepLimit + change table size (V.Ivanchenko)
|
||||
// 26-04-03 fix problems of retrieve tables (V.Ivanchenko)
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
@@ -65,13 +71,13 @@
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4MultipleScatteringSTD::G4MultipleScatteringSTD(const G4String& processName)
|
||||
: G4VContinuousDiscreteProcess(processName),
|
||||
theTransportMeanFreePathTable(0),
|
||||
fTransportMeanFreePath (1.e12),kappa(2.5),
|
||||
taubig(8.0),tausmall(1.e-14),taulim(1.e-5),
|
||||
LowestKineticEnergy(0.1*keV),
|
||||
HighestKineticEnergy(100.*TeV),
|
||||
@@ -83,16 +89,18 @@ G4MultipleScatteringSTD::G4MultipleScatteringSTD(const G4String& processName)
|
||||
facrange(0.199),tlimit(1.e10*mm),tlimitmin(1.e-7*mm),
|
||||
cf(1.001),
|
||||
stepno(0),stepnolastmsc(-1000000),nsmallstep(5),
|
||||
laststep(0.),
|
||||
laststep(0.),
|
||||
valueGPILSelectionMSC(NotCandidateForSelection),
|
||||
pcz(0.17),zmean(0.),
|
||||
range(1.0),T1(1.0),lambda1(-1.),cth1(1.),z1(1.e10),dtrl(0.15),
|
||||
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......
|
||||
|
||||
G4MultipleScatteringSTD::~G4MultipleScatteringSTD()
|
||||
@@ -111,12 +119,13 @@ void G4MultipleScatteringSTD::BuildPhysicsTable(
|
||||
{
|
||||
// set values of some data members
|
||||
if((aParticleType.GetParticleName() == "e-") ||
|
||||
(aParticleType.GetParticleName() == "e+"))
|
||||
(aParticleType.GetParticleName() == "e+"))
|
||||
{
|
||||
// parameters for e+/e-
|
||||
alfa1 = 1.45 ;
|
||||
alfa2 = 0.60 ;
|
||||
alfa3 = 1.80 ;
|
||||
alfa3 = 0.30 ;
|
||||
b = 1. ;
|
||||
xsi = facxsi*2.22 ;
|
||||
c0 = 2.30 ;
|
||||
}
|
||||
@@ -125,10 +134,13 @@ void G4MultipleScatteringSTD::BuildPhysicsTable(
|
||||
// parameters for heavy particles
|
||||
alfa1 = 1.10 ;
|
||||
alfa2 = 0.14 ;
|
||||
alfa3 = 0.42 ;
|
||||
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*
|
||||
@@ -144,13 +156,14 @@ void G4MultipleScatteringSTD::BuildPhysicsTable(
|
||||
}
|
||||
|
||||
// create table
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
theTransportMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
|
||||
theTransportMeanFreePathTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t i=0; i<numOfCouples; i++)
|
||||
{
|
||||
|
||||
// create physics vector and fill it
|
||||
@@ -158,13 +171,14 @@ void G4MultipleScatteringSTD::BuildPhysicsTable(
|
||||
LowestKineticEnergy,HighestKineticEnergy,TotBin);
|
||||
|
||||
// get elements in the material
|
||||
const G4Material* material = (*theMaterialTable)[J];
|
||||
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++)
|
||||
{
|
||||
@@ -317,12 +331,12 @@ G4double G4MultipleScatteringSTD::ComputeTransportCrossSection(
|
||||
|
||||
G4double ParticleMass = aParticleType.GetPDGMass();
|
||||
|
||||
// correction if particle .ne. e-/e+
|
||||
// compute equivalent kinetic energy
|
||||
// correction if particle .ne. e-/e+
|
||||
// compute equivalent kinetic energy
|
||||
// lambda depends on p*beta ....
|
||||
|
||||
if((aParticleType.GetParticleName() != "e-") &&
|
||||
(aParticleType.GetParticleName() != "e+") )
|
||||
|
||||
if((aParticleType.GetParticleName() != "e-") &&
|
||||
(aParticleType.GetParticleName() != "e+") )
|
||||
{
|
||||
G4double TAU = KineticEnergy/ParticleMass ;
|
||||
G4double c = ParticleMass*TAU*(TAU+2.)/(electron_mass_c2*(TAU+1.)) ;
|
||||
@@ -367,7 +381,7 @@ G4double G4MultipleScatteringSTD::ComputeTransportCrossSection(
|
||||
corrnuclsize = exp(-FactPar*ParticleMass/KineticEnergy)*
|
||||
(corrnuclsize-1.)+1.;
|
||||
}
|
||||
|
||||
|
||||
// interpolate in AtomicNumber and beta2
|
||||
// get bin number in Z
|
||||
G4int iZ = 14;
|
||||
@@ -391,10 +405,10 @@ G4double G4MultipleScatteringSTD::ComputeTransportCrossSection(
|
||||
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);
|
||||
@@ -429,20 +443,21 @@ G4double G4MultipleScatteringSTD::ComputeTransportCrossSection(
|
||||
|
||||
return sigma;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double G4MultipleScatteringSTD::GetContinuousStepLimit(
|
||||
const G4Track& track,
|
||||
const G4Track& track,
|
||||
G4double,
|
||||
G4double currentMinimumStep,
|
||||
G4double&)
|
||||
{
|
||||
G4double zPathLength,tPathLength;
|
||||
const G4DynamicParticle* aParticle;
|
||||
G4Material* aMaterial;
|
||||
G4double KineticEnergy,tau,z0,kz;
|
||||
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;
|
||||
|
||||
G4LossTableManager* theManager = G4LossTableManager::Instance();
|
||||
@@ -452,20 +467,27 @@ G4double G4MultipleScatteringSTD::GetContinuousStepLimit(
|
||||
|
||||
tPathLength = currentMinimumStep;
|
||||
|
||||
aMaterial = track.GetMaterial();
|
||||
materialIndex = aMaterial->GetIndex();
|
||||
const G4MaterialCutsCouple* couple = track.GetMaterialCutsCouple();
|
||||
materialIndex = couple->GetIndex();
|
||||
|
||||
aParticle = track.GetDynamicParticle();
|
||||
KineticEnergy = aParticle->GetKineticEnergy();
|
||||
T0 = aParticle->GetKineticEnergy();
|
||||
|
||||
fTransportMeanFreePath = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(KineticEnergy,isOut);
|
||||
lambda0 = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(T0,isOut);
|
||||
|
||||
range = theManager->GetRange(aParticle->GetDefinition(),
|
||||
KineticEnergy,aMaterial);
|
||||
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)
|
||||
if (boundary && range >= currentMinimumStep)
|
||||
{
|
||||
// step limitation at boundary ?
|
||||
stepno = track.GetCurrentStepNumber() ;
|
||||
@@ -473,126 +495,169 @@ G4double G4MultipleScatteringSTD::GetContinuousStepLimit(
|
||||
{
|
||||
stepnolastmsc = -1000000 ;
|
||||
tlimit = 1.e10 ;
|
||||
}
|
||||
}
|
||||
|
||||
if(stepno > 1)
|
||||
if(stepno > 1)
|
||||
{
|
||||
if(track.GetStep()->GetPreStepPoint()->GetStepStatus() == fGeomBoundary)
|
||||
{
|
||||
stepnolastmsc = stepno ;
|
||||
// if : diff.treatment for small/not small Z
|
||||
if(range > fTransportMeanFreePath)
|
||||
if(range > lambda0)
|
||||
tlimit = facrange*range ;
|
||||
else
|
||||
tlimit = facrange*fTransportMeanFreePath ;
|
||||
|
||||
if(tlimit < tlimitmin) tlimit = tlimitmin ;
|
||||
tlimit = facrange*lambda0 ;
|
||||
if(tlimit < tlimitmin) tlimit = tlimitmin ;
|
||||
laststep = tlimit ;
|
||||
if(tPathLength > tlimit)
|
||||
if(tPathLength > tlimit)
|
||||
{
|
||||
tPathLength = tlimit ;
|
||||
valueGPILSelectionMSC = CandidateForSelection;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(stepno > stepnolastmsc)
|
||||
{
|
||||
if((stepno - stepnolastmsc) < nsmallstep)
|
||||
if((stepno - stepnolastmsc) < nsmallstep)
|
||||
{
|
||||
if(tPathLength > tlimit)
|
||||
{
|
||||
laststep *= cf ;
|
||||
tPathLength = laststep ;
|
||||
valueGPILSelectionMSC = CandidateForSelection;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// do the true -> geom transformation
|
||||
lambda1 = -1.;
|
||||
z1 = 1.e10 ;
|
||||
zmean = tPathLength;
|
||||
|
||||
tau = tPathLength/fTransportMeanFreePath ;
|
||||
|
||||
if(tau < tausmall) zPathLength = tPathLength;
|
||||
tau = tPathLength/lambda0 ;
|
||||
|
||||
//G4cout << "StepLimit: tpl= " << tPathLength << " lambda0= " << lambda0
|
||||
// << " range= " << range << " currentMinStep= " << currentMinimumStep << G4endl;
|
||||
|
||||
if(tau < tausmall || range < currentMinimumStep ) zPathLength = tPathLength;
|
||||
else
|
||||
{
|
||||
if(tPathLength/range < dtrl) zmean = fTransportMeanFreePath*(1.-exp(-tau));
|
||||
if(tPathLength/range < dtrl) zmean = lambda0*(1.-exp(-tau));
|
||||
else
|
||||
{
|
||||
{
|
||||
T1 = theManager->GetEnergy(
|
||||
aParticle->GetDefinition(),range-0.5*tPathLength,aMaterial);
|
||||
aParticle->GetDefinition(),range-tPathLength,couple);
|
||||
lambda1 = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(T1,isOut);
|
||||
z1 = fTransportMeanFreePath*(1.-exp(-0.5*tau));
|
||||
cth1 = exp(-0.5*tau);
|
||||
zmean = z1 + lambda1*(1.-exp(-0.5*tPathLength/lambda1))*cth1;
|
||||
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
|
||||
if ((pcz > 0.) && (2.*zmean > tPathLength))
|
||||
zt = zmean/tPathLength ;
|
||||
if (samplez && (zt < ztmax) && (zt > 0.5))
|
||||
{
|
||||
z0 = zmean+pcz*(tPathLength-zmean);
|
||||
kz = (2.*zmean-tPathLength)/(z0-zmean)+1.;
|
||||
if (G4UniformRand() < z0/tPathLength)
|
||||
zPathLength = z0*exp(log(G4UniformRand())/kz);
|
||||
else zPathLength = tPathLength-(tPathLength-z0)
|
||||
*exp(log(1.-G4UniformRand())/kz);
|
||||
}
|
||||
else
|
||||
{
|
||||
zPathLength = zmean;
|
||||
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;
|
||||
zLast = zPathLength;
|
||||
|
||||
return zPathLength;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4VParticleChange* G4MultipleScatteringSTD::AlongStepDoIt(
|
||||
const G4Track& track,const G4Step& Step)
|
||||
{
|
||||
const G4Track& track,const G4Step& step)
|
||||
{
|
||||
// only a geom path->true path transformation is performed
|
||||
|
||||
fParticleChange.Initialize(track);
|
||||
|
||||
G4double geomPathLength = track.GetStepLength();
|
||||
|
||||
G4double truePathLength;
|
||||
|
||||
if (geomPathLength/fTransportMeanFreePath < tausmall)
|
||||
truePathLength = geomPathLength;
|
||||
else if(geomPathLength == zLast) truePathLength = tLast;
|
||||
else
|
||||
{
|
||||
if (geomPathLength <= z1)
|
||||
{
|
||||
if (geomPathLength < fTransportMeanFreePath)
|
||||
truePathLength = -fTransportMeanFreePath
|
||||
*log(1.-geomPathLength/fTransportMeanFreePath);
|
||||
else truePathLength = range;
|
||||
G4double geomPathLength = step.GetStepLength();
|
||||
|
||||
lambda1 = -1.;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((geomPathLength-z1)/(cth1*lambda1) < 1.)
|
||||
truePathLength = 0.5*tLast-lambda1
|
||||
*log(1.-(geomPathLength-z1)/(cth1*lambda1));
|
||||
else truePathLength = range;
|
||||
}
|
||||
}
|
||||
G4double truePathLength = 0. ;
|
||||
if(geomPathLength == zLast) truePathLength = tLast;
|
||||
else if(geomPathLength/lambda0 < tausmall) truePathLength = geomPathLength;
|
||||
else
|
||||
{
|
||||
// G4cout << "alam= " << alam << " blam= " << blam << " lambda1= " << lambda1 << G4endl;
|
||||
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
|
||||
{
|
||||
//G4cout << "clam= " << clam << " zm= " << zm << " cthm= " << cthm << G4endl;
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
// G4cout << "tLenth= " << truePathLength << " tpl= " << tLast << G4endl;
|
||||
// protection ....
|
||||
if(truePathLength > tLast)
|
||||
truePathLength = tLast ;
|
||||
}
|
||||
//VI truePath length cannot be smaller than geomPathLength
|
||||
if (truePathLength < geomPathLength) truePathLength = geomPathLength;
|
||||
//G4cout << "AlongStep: trueLength= " << truePathLength << " geomLength= "
|
||||
// << geomPathLength << " zlast= " << zLast << G4endl;
|
||||
fParticleChange.SetTrueStepLength(truePathLength);
|
||||
|
||||
return &fParticleChange;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
@@ -602,8 +667,7 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
const G4Step& stepData)
|
||||
{
|
||||
// angle distribution parameters
|
||||
const G4double kappapl1 = kappa+1., kappami1 = kappa-1. ;
|
||||
G4bool isOut;
|
||||
const G4double kappa = 2.5, kappapl1 = kappa+1., kappami1 = kappa-1. ;
|
||||
|
||||
fParticleChange.Initialize(trackData);
|
||||
G4double truestep = stepData.GetStepLength();
|
||||
@@ -611,29 +675,31 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
|
||||
G4double KineticEnergy = aParticle->GetKineticEnergy();
|
||||
|
||||
fTransportMeanFreePath = (*theTransportMeanFreePathTable)
|
||||
(materialIndex)->GetValue(KineticEnergy,isOut);
|
||||
|
||||
// change direction first ( scattering )
|
||||
G4double cth =1 ;
|
||||
G4double tau = truestep/fTransportMeanFreePath;
|
||||
|
||||
if(KineticEnergy <= 0.)
|
||||
;
|
||||
else
|
||||
// do nothing for stopped particles !
|
||||
if(KineticEnergy > 0.)
|
||||
{
|
||||
// change direction first ( scattering )
|
||||
G4double cth = 1. ;
|
||||
G4double tau = truestep/lambda0 ;
|
||||
//G4cout << "tau= " << tau << " lambda1= " << lambda1 << " lambdam= " << lambdam << G4endl;
|
||||
|
||||
if (tau < tausmall) cth = 1.;
|
||||
else if(tau > taubig) cth = -1.+2.*G4UniformRand();
|
||||
else
|
||||
{
|
||||
if(lambda1 > 0.) tau = 0.5*tLast/lambda1
|
||||
+(truestep-0.5*tLast)/fTransportMeanFreePath;
|
||||
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 b = 1. ;
|
||||
|
||||
G4double a,x0,c,xmean1,xmean2,
|
||||
xmeanth,prob,qprob ;
|
||||
@@ -645,11 +711,11 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
else
|
||||
a = (alfa1+alfa3*w)/tau ;
|
||||
|
||||
x0 = 1.-xsi/a ;
|
||||
x0 = 1.-xsi/a ;
|
||||
if(x0 < 0.) x0 = 0. ;
|
||||
|
||||
// from continuity of the 1st derivatives
|
||||
c = a*(b-x0) ;
|
||||
c = a*(b-x0) ;
|
||||
if(a*tau < c0)
|
||||
c = c0*(b-x0)/tau ;
|
||||
|
||||
@@ -661,9 +727,8 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
ea = exp(-a*(1.-x0)) ;
|
||||
else
|
||||
ea = 0. ;
|
||||
eaa = 1.-ea ;
|
||||
|
||||
xmean1 = 1.-1./a+(1.-x0)*ea/eaa ;
|
||||
eaa = 1.-ea ;
|
||||
xmean1 = 1.-1./a+(1.-x0)*ea/eaa ;
|
||||
|
||||
b1 = b+1. ;
|
||||
bx=b-x0 ;
|
||||
@@ -673,7 +738,7 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
|
||||
xmeanth = exp(-tau) ;
|
||||
|
||||
cnorm1 = a/eaa ;
|
||||
cnorm1 = a/eaa ;
|
||||
cnorm2 = (c-1.)*eb1*ebx/(eb1-ebx) ;
|
||||
f1x0 = cnorm1*exp(-a*(1.-x0)) ;
|
||||
f2x0 = cnorm2/exp(c*log(b-x0)) ;
|
||||
@@ -688,11 +753,18 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
if(qprob > 1.)
|
||||
{
|
||||
qprob = 1. ;
|
||||
prob = (xmeanth-xmean2)/(xmean1-xmean2) ;
|
||||
prob = (xmeanth-xmean2)/(xmean1-xmean2) ;
|
||||
}
|
||||
// *******************************************
|
||||
|
||||
// sampling of costheta
|
||||
/*
|
||||
G4cout << "tau= " << tau << " prob= " << prob << " qprob= " << qprob << G4endl;
|
||||
G4cout << "ea= " << ea << " eaa= " << eaa << " a= " << a
|
||||
<< " b= " << b << " b1= " << b1 << " bx= " << bx
|
||||
<< " ebx= " << ebx << " eb1= " << eb1 << " c= " << c
|
||||
<< G4endl;
|
||||
*/
|
||||
if(G4UniformRand() < qprob)
|
||||
{
|
||||
if(G4UniformRand() < prob)
|
||||
@@ -704,12 +776,13 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
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;
|
||||
|
||||
//G4cout << "PostStep: sth= " << sth << " trueLength= " << truestep << " tLast= " << tLast << G4endl;
|
||||
|
||||
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection();
|
||||
|
||||
G4ThreeVector newDirection(dirx,diry,dirz);
|
||||
@@ -717,34 +790,35 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
fParticleChange.SetMomentumChange(newDirection.x(),
|
||||
newDirection.y(),
|
||||
newDirection.z());
|
||||
|
||||
if (fLatDisplFlag)
|
||||
{
|
||||
// compute mean lateral displacement, only for safety > tolerance !
|
||||
// compute mean lateral displacement, only for safety > tolerance !
|
||||
G4double safetyminustolerance = stepData.GetPostStepPoint()->GetSafety();
|
||||
G4double rmean, etau;
|
||||
|
||||
if (safetyminustolerance > 0.)
|
||||
G4double rmean = 0.0;
|
||||
|
||||
if (safetyminustolerance > 0. && tau>=tausmall)
|
||||
{
|
||||
if (tau < tausmall) rmean = 0.;
|
||||
else if(tau < taulim) rmean = kappa*tau*tau*tau*(1.-kappapl1*tau/4.)/6. ;
|
||||
if(tau < taulim) rmean = kappa*tau*tau*tau*(1.-kappapl1*tau*0.25)/6. ;
|
||||
else
|
||||
{
|
||||
G4double etau = 0.0;
|
||||
if(tau<taubig) etau = exp(-tau);
|
||||
else etau = 0.;
|
||||
rmean = -kappa*tau;
|
||||
rmean = -exp(rmean)/(kappa*kappami1);
|
||||
rmean += tau-kappapl1/kappa+kappa*etau/kappami1;
|
||||
//G4cout << "tau= " << tau << " lambda0= " << lambda0 << " etau= " << etau << " kappa= " << kappa << G4endl;
|
||||
}
|
||||
|
||||
if (rmean>0.) rmean = 2.*fTransportMeanFreePath*sqrt(rmean/3.);
|
||||
if (rmean>0.) rmean = 2.*lambda0*sqrt(rmean/3.0);
|
||||
else rmean = 0.;
|
||||
|
||||
|
||||
// for rmean > 0) only
|
||||
if (rmean > 0.)
|
||||
{
|
||||
if (rmean>safetyminustolerance) rmean = safetyminustolerance;
|
||||
|
||||
//G4cout << "r= " << rmean << " safety= " << safetyminustolerance << G4endl;
|
||||
// sample direction of lateral displacement
|
||||
phi = twopi*G4UniformRand();
|
||||
dirx = cos(phi); diry = sin(phi); dirz = 0.;
|
||||
@@ -755,7 +829,7 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
// compute new endpoint of the Step
|
||||
G4ThreeVector newPosition = stepData.GetPostStepPoint()->GetPosition()
|
||||
+ rmean*latDirection;
|
||||
|
||||
|
||||
G4Navigator* navigator =
|
||||
G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
@@ -765,14 +839,14 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4MultipleScatteringSTD::StorePhysicsTable(G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4String filename;
|
||||
@@ -783,9 +857,9 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
<< G4endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
G4cout << GetProcessName() << " for " << particle->GetParticleName()
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< ": Success to store the PhysicsTables in "
|
||||
<< directory << G4endl;
|
||||
return true;
|
||||
}
|
||||
@@ -794,9 +868,34 @@ G4VParticleChange* G4MultipleScatteringSTD::PostStepDoIt(
|
||||
|
||||
G4bool G4MultipleScatteringSTD::RetrievePhysicsTable(
|
||||
G4ParticleDefinition* particle,
|
||||
const G4String& directory,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
// set values of some data members
|
||||
G4String name = particle->GetParticleName();
|
||||
if(name == "e-" || name == "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 = particle->GetPDGMass();
|
||||
|
||||
// delete theTransportMeanFreePathTable
|
||||
if (theTransportMeanFreePathTable != 0) {
|
||||
theTransportMeanFreePathTable->clearAndDestroy();
|
||||
@@ -807,22 +906,25 @@ G4bool G4MultipleScatteringSTD::RetrievePhysicsTable(
|
||||
|
||||
// retreive mean free path table
|
||||
filename = GetPhysicsTableFileName(particle,directory,"MeanFreePath",ascii);
|
||||
theTransportMeanFreePathTable =
|
||||
theTransportMeanFreePathTable =
|
||||
new G4PhysicsTable(G4Material::GetNumberOfMaterials());
|
||||
if (!theTransportMeanFreePathTable->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;
|
||||
|
||||
if (name == "e-" || name == "mu+" || name == "proton") PrintInfoDefinition();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
|
||||
void G4MultipleScatteringSTD::PrintInfoDefinition()
|
||||
{
|
||||
G4String comments = " Tables of transport mean free paths.";
|
||||
@@ -830,10 +932,14 @@ void G4MultipleScatteringSTD::PrintInfoDefinition()
|
||||
comments += " displacement of the particle , too.";
|
||||
|
||||
G4cout << G4endl << GetProcessName() << ": " << comments
|
||||
<< "\n PhysicsTables from "
|
||||
<< "\n PhysicsTables from "
|
||||
<< G4BestUnit(LowestKineticEnergy ,"Energy")
|
||||
<< " to " << G4BestUnit(HighestKineticEnergy,"Energy")
|
||||
<< " in " << TotBin << " bins. \n";
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "LambdaTable address= " << theTransportMeanFreePathTable << G4endl;
|
||||
if(theTransportMeanFreePathTable) G4cout << (*theTransportMeanFreePathTable) << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
@@ -29,10 +29,16 @@
|
||||
// File name: G4SCProcessorStand
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
//
|
||||
// Creation date: 10.05.2002
|
||||
//
|
||||
// Modifications: 09.12.2002 VI remove warning
|
||||
// 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)
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
@@ -46,73 +52,63 @@
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4EmModelManager.hh"
|
||||
#include "G4MaterialTable.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4Step.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4SCProcessorStand::G4SCProcessorStand()
|
||||
: G4VSubCutoffProcessor(),
|
||||
G4SCProcessorStand::G4SCProcessorStand(const G4String& nam)
|
||||
: G4VSubCutoffProcessor(nam),
|
||||
theLambdaSubTable(0),
|
||||
thePositron(G4Positron::Positron()),
|
||||
modelManager(0)
|
||||
thePositron(G4Positron::Positron())
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4SCProcessorStand::~G4SCProcessorStand()
|
||||
{
|
||||
if(theLambdaSubTable) theLambdaSubTable->clearAndDestroy();
|
||||
}
|
||||
G4SCProcessorStand::~G4SCProcessorStand()
|
||||
{}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4SCProcessorStand::Initialise(const G4ParticleDefinition* p,
|
||||
const G4ParticleDefinition* sp,
|
||||
G4EmModelManager* m)
|
||||
const G4ParticleDefinition* sp,
|
||||
const G4DataVector* vCuts,
|
||||
const G4DataVector* vSubCuts)
|
||||
{
|
||||
particle = p;
|
||||
secondaryParticle = sp;
|
||||
modelManager = m;
|
||||
navigator = (G4TransportationManager::GetTransportationManager())
|
||||
->GetNavigatorForTracking();
|
||||
theCuts = modelManager->Cuts();
|
||||
theSubCuts = modelManager->Cuts();
|
||||
theCuts = vCuts;
|
||||
theSubCuts = vSubCuts;
|
||||
initialMass= particle->GetPDGMass();
|
||||
|
||||
// Access to materials
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
size_t nMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
rangeCuts.clear();
|
||||
|
||||
for(size_t i=0; i<nMaterials; i++) {
|
||||
|
||||
const G4Material* aMaterial = (*theMaterialTable)[i];
|
||||
rangeCuts.push_back(secondaryParticle->GetRangeThreshold(aMaterial));
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4std::vector<G4Track*>* G4SCProcessorStand::SampleSecondary(const G4Step& step,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double meanLoss)
|
||||
G4std::vector<G4Track*>* G4SCProcessorStand::SampleSecondaries(
|
||||
const G4Step& step,
|
||||
G4double& tmax,
|
||||
G4double& meanLoss,
|
||||
G4VEmModel* currentModel)
|
||||
{
|
||||
G4bool b;
|
||||
const G4Material* mat = (step.GetTrack())->GetMaterial();
|
||||
const G4Track* track = step.GetTrack();
|
||||
const G4MaterialCutsCouple* couple = track->GetMaterialCutsCouple();
|
||||
|
||||
if(mat != material) {
|
||||
material = mat;
|
||||
materialIndex = material->GetIndex();
|
||||
cut = (*theCuts)[materialIndex];
|
||||
subcut = (*theSubCuts)[materialIndex];
|
||||
rcut = rangeCuts[materialIndex];
|
||||
}
|
||||
size_t index = couple->GetIndex();
|
||||
G4double subcut = (*theSubCuts)[index];
|
||||
|
||||
if(subcut >= cut) return 0;
|
||||
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;
|
||||
@@ -123,9 +119,9 @@ G4std::vector<G4Track*>* G4SCProcessorStand::SampleSecondary(const G4Step& step
|
||||
massRatio = initialMass/mass;
|
||||
G4double q = particle->GetPDGCharge()/dp->GetCharge();
|
||||
effChargeFactor = q*q;
|
||||
}
|
||||
}
|
||||
|
||||
G4double cross = (*theLambdaSubTable)[materialIndex]->GetValue(ekin*massRatio, b);
|
||||
G4double cross = (*theLambdaSubTable)[index]->GetValue(ekin*massRatio, b);
|
||||
|
||||
if(0.0 >= cross) return 0;
|
||||
|
||||
@@ -135,7 +131,7 @@ G4std::vector<G4Track*>* G4SCProcessorStand::SampleSecondary(const G4Step& step
|
||||
G4double postsafety = navigator->ComputeSafety(postpoint);
|
||||
G4double safety = G4std::min(presafety,postsafety);
|
||||
if(safety >= rcut) return 0;
|
||||
|
||||
|
||||
|
||||
G4ThreeVector prepoint = pre->GetPosition();
|
||||
G4ThreeVector dr = postpoint - prepoint;
|
||||
@@ -145,7 +141,6 @@ G4std::vector<G4Track*>* G4SCProcessorStand::SampleSecondary(const G4Step& step
|
||||
G4double length = step.GetStepLength();
|
||||
G4double inv_v = (ekin + mass)/(c_light*dp->GetTotalMomentum());
|
||||
|
||||
G4VEmModel* currentModel = modelManager->SelectModel(ekin);
|
||||
G4std::vector<G4Track*>* vtr = new G4std::vector<G4Track*>;
|
||||
|
||||
do {
|
||||
@@ -153,10 +148,10 @@ G4std::vector<G4Track*>* G4SCProcessorStand::SampleSecondary(const G4Step& step
|
||||
G4double del = G4UniformRand()*effChargeFactor / cross;
|
||||
fragment += del/length;
|
||||
if (fragment > 1.0) break;
|
||||
|
||||
dt += del * inv_v;
|
||||
G4std::vector<G4DynamicParticle*>* newp =
|
||||
currentModel->SampleSecondary(material, dp, subcut, cut);
|
||||
|
||||
dt += del * inv_v;
|
||||
G4std::vector<G4DynamicParticle*>* newp =
|
||||
currentModel->SampleSecondaries(couple, dp, subcut, cut);
|
||||
if (newp) {
|
||||
|
||||
G4DynamicParticle* p;
|
||||
@@ -183,7 +178,7 @@ G4std::vector<G4Track*>* G4SCProcessorStand::SampleSecondary(const G4Step& step
|
||||
return vtr;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
//
|
||||
// Modifications:
|
||||
//
|
||||
// 28-12-02 add method Dispersion (V.Ivanchenko)
|
||||
// 07-02-03 change signature (V.Ivanchenko)
|
||||
// 13-02-03 Add name (V.Ivanchenko)
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
@@ -51,8 +55,8 @@
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4UniversalFluctuation::G4UniversalFluctuation()
|
||||
:G4VEmFluctuationModel(),
|
||||
G4UniversalFluctuation::G4UniversalFluctuation(const G4String& nam)
|
||||
:G4VEmFluctuationModel(nam),
|
||||
minNumberInteractionsBohr(10.0),
|
||||
theBohrBeta2(50.0*keV/proton_mass_c2),
|
||||
minLoss(0.000001*eV),
|
||||
@@ -74,94 +78,67 @@ G4UniversalFluctuation::~G4UniversalFluctuation()
|
||||
|
||||
void G4UniversalFluctuation::Initialise(const G4ParticleDefinition* part)
|
||||
{
|
||||
particle = part;
|
||||
particleMass = part->GetPDGMass();
|
||||
G4double q = part->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
particle = part;
|
||||
particleMass = part->GetPDGMass();
|
||||
G4double q = part->GetPDGCharge()/eplus;
|
||||
chargeSquare = q*q;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length,
|
||||
G4double meanLoss)
|
||||
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
|
||||
// The model used to get the fluctuation is essentially the same
|
||||
// as in Glandz in Geant3.
|
||||
|
||||
|
||||
// shortcut for very very small loss
|
||||
if(meanLoss < minLoss) return;
|
||||
|
||||
G4double preStepKinEnergy = dp->GetKineticEnergy();
|
||||
if(meanLoss < minLoss) return meanLoss;
|
||||
|
||||
if(dp->GetDefinition() != particle) {
|
||||
particleMass = dp->GetMass();
|
||||
G4double q = dp->GetCharge();
|
||||
chargeSquare = q*q;
|
||||
particleMass = dp->GetMass();
|
||||
G4double q = dp->GetCharge();
|
||||
chargeSquare = q*q;
|
||||
}
|
||||
|
||||
// data members for a given material
|
||||
|
||||
if(material != lastMaterial) {
|
||||
ipotFluct = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
electronDensity = material->GetElectronDensity();
|
||||
// zeff = electronDensity/(material->GetTotNbOfAtomsPerVolume());
|
||||
}
|
||||
|
||||
// get particle data
|
||||
|
||||
G4double tau = preStepKinEnergy/particleMass;
|
||||
G4double tau1 = tau + 1.0;
|
||||
G4double tau2 = tau * (tau+2.0);
|
||||
G4double beta2 = tau2/(tau1*tau1);
|
||||
|
||||
ipotFluct = material->GetIonisation()->GetMeanExcitationEnergy();
|
||||
|
||||
G4double gam = (dp->GetKineticEnergy())/particleMass + 1.0;
|
||||
G4double gam2 = gam*gam;
|
||||
G4double beta2 = 1.0 - 1.0/gam2;
|
||||
|
||||
// Validity range for delta electron cross section
|
||||
G4double loss, siga;
|
||||
|
||||
// Gaussian fluctuation
|
||||
if(meanLoss >= minNumberInteractionsBohr*tmax || tmax <= ipotFluct*minNumberInteractionsBohr)
|
||||
{
|
||||
siga = tmax * (1.0-0.5*beta2) * length * twopi_mc2_rcl2
|
||||
* electronDensity / beta2;
|
||||
siga = sqrt(siga * chargeSquare);
|
||||
/*
|
||||
// High velocity or negatively charged particle
|
||||
if( beta2 > 3.0*theBohrBeta2*zeff || charge < 0.0) {
|
||||
siga = sqrt( siga * chargeSquare ) ;
|
||||
|
||||
// Low velocity - additional ion charge fluctuations according to
|
||||
// Q.Yang et al., NIM B61(1991)149-155.
|
||||
} else {
|
||||
G4double chu = theIonChuFluctuationModel->TheValue(particle, material);
|
||||
G4double yang = theIonYangFluctuationModel->TheValue(particle, material);
|
||||
siga = sqrt( siga * (chargeSquare * chu + yang)) ;
|
||||
}
|
||||
*/
|
||||
electronDensity = material->GetElectronDensity();
|
||||
siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
|
||||
* electronDensity * chargeSquare ;
|
||||
siga = sqrt(siga);
|
||||
do {
|
||||
loss = G4RandGauss::shoot(meanLoss,siga);
|
||||
} while (loss < 0.);
|
||||
} while (loss < 0. || loss > 2.*meanLoss);
|
||||
|
||||
meanLoss = loss;
|
||||
if(lastMaterial != material) lastMaterial = material;
|
||||
return;
|
||||
return loss;
|
||||
}
|
||||
|
||||
// Non Gaussian fluctuation
|
||||
|
||||
if(material != lastMaterial) {
|
||||
zeff = electronDensity/(material->GetTotNbOfAtomsPerVolume());
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -173,7 +150,7 @@ void G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
|
||||
G4double dp3;
|
||||
|
||||
w1 = tmax/ipotFluct;
|
||||
w2 = log(2.*electron_mass_c2*tau2);
|
||||
w2 = log(2.*electron_mass_c2*(gam2 - 1.0));
|
||||
|
||||
C = meanLoss*(1.-rateFluct)/(w2-ipotLogFluct-beta2);
|
||||
|
||||
@@ -315,7 +292,43 @@ void G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
|
||||
}
|
||||
}
|
||||
|
||||
meanLoss = loss;
|
||||
return loss;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4double G4UniversalFluctuation::Dispersion(
|
||||
const G4Material* material,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double& tmax,
|
||||
G4double& length)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// High velocity or negatively charged particle
|
||||
zeff = electronDensity/(material->GetTotNbOfAtomsPerVolume());
|
||||
if( beta2 > 3.0*theBohrBeta2*zeff || charge < 0.0) {
|
||||
siga = sqrt( siga * chargeSquare ) ;
|
||||
|
||||
// Low velocity - additional ion charge fluctuations according to
|
||||
// Q.Yang et al., NIM B61(1991)149-155.
|
||||
} else {
|
||||
G4double chu = theIonChuFluctuationModel->TheValue(particle, material);
|
||||
G4double yang = theIonYangFluctuationModel->TheValue(particle, material);
|
||||
siga = sqrt( siga * (chargeSquare * chu + yang)) ;
|
||||
}
|
||||
*/
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4VEnergyLoss.cc,v 1.33 2002/07/22 10:55:26 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-00 $
|
||||
// $Id: G4VEnergyLoss.cc,v 1.40 2003/04/04 14:33:34 vnivanch Exp $
|
||||
// GEANT4 tag $Name: geant4-05-01 $
|
||||
//
|
||||
|
||||
// --------------------------------------------------------------
|
||||
@@ -32,21 +32,26 @@
|
||||
// bug fixed in fluct., L.Urban 22/11/00
|
||||
// bugfix in fluct.
|
||||
// (some variables are doubles instead of ints now),L.Urban 23/03/01
|
||||
// 18/05/01 V.Ivanchenko Clean up againist Linux ANSI compilation
|
||||
// 18/05/01 V.Ivanchenko Clean up againist Linux ANSI compilation
|
||||
// 17-09-01 migration of Materials to pure STL (mma)
|
||||
// 26-10-01 static inline functions moved from .hh file (mma)
|
||||
// 26-10-01 static inline functions moved from .hh file (mma)
|
||||
// 08.11.01 some static methods,data members are not static L.Urban
|
||||
// 11.02.02 subSecFlag = false --> No sucutoff generation (mma)
|
||||
// 11.02.02 subSecFlag = false --> No sucutoff generation (mma)
|
||||
// 14.02.02 initial value of data member finalRange has been changed L.Urban
|
||||
// 26.02.02 initial value of data member finalRange = 1 mm (mma)
|
||||
// 21.07.02 V.Ivanchenko Fix at low energies - if tmax below ionisation
|
||||
// 21.07.02 V.Ivanchenko Fix at low energies - if tmax below ionisation
|
||||
// potential then only Gaussian fluctuations are sampled.
|
||||
//
|
||||
// 15.01.03 Migrade to cut per region (V.Ivanchenko)
|
||||
// 05.02.03 Minor fix for several region case (V.Ivanchenko)
|
||||
// 25.03.03 add finalRangeRequested (mma)
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4VEnergyLoss.hh"
|
||||
#include "G4EnergyLossMessenger.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -61,6 +66,7 @@ G4bool G4VEnergyLoss::setMinDeltaCutInRange = false;
|
||||
|
||||
G4double G4VEnergyLoss::dRoverRange = 20*perCent;
|
||||
G4double G4VEnergyLoss::finalRange = 1*mm;
|
||||
G4double G4VEnergyLoss::finalRangeRequested = -1*mm;
|
||||
G4double G4VEnergyLoss::c1lim = dRoverRange;
|
||||
G4double G4VEnergyLoss::c2lim = 2.*(1.-dRoverRange)*finalRange;
|
||||
G4double G4VEnergyLoss::c3lim = -(1.-dRoverRange)*finalRange*finalRange;
|
||||
@@ -86,8 +92,9 @@ G4VEnergyLoss::G4VEnergyLoss(const G4String& aName , G4ProcessType aType)
|
||||
nmaxCont1(4),
|
||||
nmaxCont2(16)
|
||||
{
|
||||
//create (only once) EnergyLoss messenger
|
||||
if(!ELossMessenger) ELossMessenger = new G4EnergyLossMessenger();
|
||||
//create (only once) EnergyLoss messenger
|
||||
// if(!ELossMessenger) ELossMessenger = new G4EnergyLossMessenger();
|
||||
if(!ELossMessenger) ELossMessenger = G4LossTableManager::Instance()->GetMessenger();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
@@ -125,20 +132,20 @@ void G4VEnergyLoss::SetMinDeltaCutInRange(G4double value)
|
||||
|
||||
void G4VEnergyLoss::SetStepFunction(G4double c1, G4double c2)
|
||||
{
|
||||
dRoverRange = c1; finalRange = c2;
|
||||
dRoverRange = c1; finalRangeRequested = c2;
|
||||
c1lim=dRoverRange;
|
||||
c2lim=2.*(1-dRoverRange)*finalRange;
|
||||
c3lim=-(1.-dRoverRange)*finalRange*finalRange;
|
||||
c2lim=2.*(1-dRoverRange)*finalRangeRequested;
|
||||
c3lim=-(1.-dRoverRange)*finalRangeRequested*finalRangeRequested;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4PhysicsTable* G4VEnergyLoss::BuildRangeTable(
|
||||
G4PhysicsTable* theDEDXTable,G4PhysicsTable* theRangeTable,
|
||||
G4PhysicsTable* theDEDXTable,G4PhysicsTable* theRangeTable,
|
||||
G4double LowestKineticEnergy,G4double HighestKineticEnergy,G4int TotBin)
|
||||
// Build range table from the energy loss table
|
||||
{
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
size_t numOfMaterials = theDEDXTable->length();
|
||||
|
||||
if(theRangeTable)
|
||||
{ theRangeTable->clearAndDestroy();
|
||||
@@ -147,7 +154,7 @@ G4PhysicsTable* G4VEnergyLoss::BuildRangeTable(
|
||||
|
||||
// loop for materials
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector;
|
||||
aVector = new G4PhysicsLogVector(LowestKineticEnergy,
|
||||
@@ -158,7 +165,7 @@ G4PhysicsTable* G4VEnergyLoss::BuildRangeTable(
|
||||
theRangeTable->insert(aVector);
|
||||
}
|
||||
return theRangeTable ;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
@@ -373,15 +380,15 @@ G4PhysicsTable* G4VEnergyLoss::BuildLabTimeTable(G4PhysicsTable* theDEDXTable,
|
||||
G4double HighestKineticEnergy,G4int TotBin)
|
||||
|
||||
{
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
size_t numOfMaterials = theDEDXTable->length();
|
||||
|
||||
if(theLabTimeTable)
|
||||
{ theLabTimeTable->clearAndDestroy();
|
||||
delete theLabTimeTable; }
|
||||
theLabTimeTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector;
|
||||
|
||||
@@ -403,17 +410,17 @@ G4PhysicsTable* G4VEnergyLoss::BuildProperTimeTable(G4PhysicsTable* theDEDXTable
|
||||
G4PhysicsTable* theProperTimeTable,
|
||||
G4double LowestKineticEnergy,
|
||||
G4double HighestKineticEnergy,G4int TotBin)
|
||||
|
||||
|
||||
{
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
|
||||
size_t numOfMaterials = theDEDXTable->length();
|
||||
|
||||
if(theProperTimeTable)
|
||||
{ theProperTimeTable->clearAndDestroy();
|
||||
delete theProperTimeTable; }
|
||||
theProperTimeTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
G4PhysicsLogVector* aVector;
|
||||
|
||||
@@ -629,7 +636,7 @@ G4PhysicsTable* G4VEnergyLoss::BuildInverseRangeTable(G4PhysicsTable* theRangeTa
|
||||
{
|
||||
G4double SmallestRange,BiggestRange ;
|
||||
G4bool isOut ;
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
size_t numOfMaterials = theRangeTable->length();
|
||||
|
||||
if(theInverseRangeTable)
|
||||
{ theInverseRangeTable->clearAndDestroy();
|
||||
@@ -637,7 +644,7 @@ G4PhysicsTable* G4VEnergyLoss::BuildInverseRangeTable(G4PhysicsTable* theRangeTa
|
||||
theInverseRangeTable = new G4PhysicsTable(numOfMaterials);
|
||||
|
||||
// loop for materials
|
||||
for (G4int J=0; J<numOfMaterials; J++)
|
||||
for (size_t J=0; J<numOfMaterials; J++)
|
||||
{
|
||||
SmallestRange = (*theRangeTable)(J)->
|
||||
GetValue(LowestKineticEnergy,isOut) ;
|
||||
@@ -723,7 +730,7 @@ G4PhysicsTable* G4VEnergyLoss::BuildRangeCoeffATable(G4PhysicsTable* theRangeTab
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "A"
|
||||
{
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfMaterials = theRangeTable->length();
|
||||
|
||||
if(theRangeCoeffATable)
|
||||
{ theRangeCoeffATable->clearAndDestroy();
|
||||
@@ -784,7 +791,7 @@ G4PhysicsTable* G4VEnergyLoss::BuildRangeCoeffBTable(G4PhysicsTable* theRangeTab
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "B"
|
||||
{
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfMaterials = theRangeTable->length();
|
||||
|
||||
if(theRangeCoeffBTable)
|
||||
{ theRangeCoeffBTable->clearAndDestroy();
|
||||
@@ -844,7 +851,7 @@ G4PhysicsTable* G4VEnergyLoss::BuildRangeCoeffCTable(G4PhysicsTable* theRangeTab
|
||||
// Build tables of coefficients for the energy loss calculation
|
||||
// create table for coefficients "C"
|
||||
{
|
||||
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
|
||||
G4int numOfMaterials = theRangeTable->length();
|
||||
|
||||
if(theRangeCoeffCTable)
|
||||
{ theRangeCoeffCTable->clearAndDestroy();
|
||||
@@ -898,27 +905,27 @@ G4PhysicsTable* G4VEnergyLoss::BuildRangeCoeffCTable(G4PhysicsTable* theRangeTab
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4double G4VEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4Material* aMaterial,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4double ChargeSquare,
|
||||
G4double MeanLoss,
|
||||
G4double step )
|
||||
// calculate actual loss from the mean loss
|
||||
// The model used to get the fluctuation is essentially the same as in Glandz in Geant3.
|
||||
{
|
||||
const G4double minLoss = 1.*eV ;
|
||||
const G4double probLim = 0.01 ;
|
||||
const G4double sumaLim = -log(probLim) ;
|
||||
const G4double alim=10.;
|
||||
const G4double kappa = 10. ;
|
||||
const G4double factor = twopi_mc2_rcl2 ;
|
||||
|
||||
const G4double minLoss = 1.*eV ;
|
||||
const G4double probLim = 0.01 ;
|
||||
const G4double sumaLim = -log(probLim) ;
|
||||
const G4double alim=10.;
|
||||
const G4double kappa = 10. ;
|
||||
const G4double factor = twopi_mc2_rcl2 ;
|
||||
const G4Material* aMaterial = couple->GetMaterial();
|
||||
|
||||
// check if the material has changed ( cache mechanism)
|
||||
|
||||
if (aMaterial != lastMaterial)
|
||||
{
|
||||
lastMaterial = aMaterial;
|
||||
imat = aMaterial->GetIndex();
|
||||
imat = couple->GetIndex();
|
||||
f1Fluct = aMaterial->GetIonisation()->GetF1fluct();
|
||||
f2Fluct = aMaterial->GetIonisation()->GetF2fluct();
|
||||
e1Fluct = aMaterial->GetIonisation()->GetEnergy1fluct();
|
||||
@@ -938,14 +945,15 @@ G4double G4VEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
G4double dp3;
|
||||
G4double siga ;
|
||||
|
||||
// shortcut for very very small loss
|
||||
// shortcut for very very small loss
|
||||
if(MeanLoss < minLoss) return MeanLoss ;
|
||||
|
||||
// get particle data
|
||||
G4double Tkin = aParticle->GetKineticEnergy();
|
||||
ParticleMass = aParticle->GetMass() ;
|
||||
|
||||
threshold =((G4Electron::Electron())->GetEnergyCuts())[imat];
|
||||
threshold = (*((G4ProductionCutsTable::GetProductionCutsTable())
|
||||
->GetEnergyCutsVector(1)))[imat];
|
||||
G4double rmass = electron_mass_c2/ParticleMass;
|
||||
G4double tau = Tkin/ParticleMass, tau1 = tau+1., tau2 = tau*(tau+2.);
|
||||
G4double Tm = 2.*electron_mass_c2*tau2/(1.+2.*tau1*rmass+rmass*rmass);
|
||||
@@ -1058,7 +1066,7 @@ G4double G4VEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
|
||||
loss = p1*e1Fluct+p2*e2Fluct;
|
||||
// smearing to avoid unphysical peaks
|
||||
if(p2 > 0)
|
||||
loss += (1.-2.*G4UniformRand())*e2Fluct;
|
||||
loss += (1.-2.*G4UniformRand())*e2Fluct;
|
||||
else if (loss>0.)
|
||||
loss += (1.-2.*G4UniformRand())*e1Fluct;
|
||||
|
||||
@@ -1124,7 +1132,7 @@ G4bool G4VEnergyLoss::EqualCutVectors( G4double* vec1, G4double* vec2 )
|
||||
for (size_t j=0; flag && j<G4Material::GetNumberOfMaterials(); j++){
|
||||
flag = (vec1[j] == vec2[j]);
|
||||
}
|
||||
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
@@ -1141,3 +1149,21 @@ G4double* G4VEnergyLoss::CopyCutVectors( G4double* dest, G4double* source )
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4VEnergyLoss::CutsWhereModified()
|
||||
{
|
||||
G4bool wasModified = false;
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
for (size_t j=0; j<numOfCouples; j++){
|
||||
if (theCoupleTable->GetMaterialCutsCouple(j)->IsRecalcNeeded()) {
|
||||
wasModified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return wasModified;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,339 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * 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. *
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4VMultipleScattering
|
||||
//
|
||||
// Author: Vladimir Ivanchenko on base of Laszlo Urban code
|
||||
//
|
||||
// Creation date: 25.03.2003
|
||||
//
|
||||
// Modifications: 13.04.03 Change printout (V.Ivanchenko)
|
||||
//
|
||||
//
|
||||
// Class Description:
|
||||
//
|
||||
// It is the generic process of multiple scattering it includes common
|
||||
// part of calculations for all charged particles
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
#include "G4VMultipleScattering.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4VEmFluctuationModel.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "G4PhysicsTable.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4PhysicsLogVector.hh"
|
||||
#include "G4UnitsTable.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4TransportationManager.hh"
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VMultipleScattering::G4VMultipleScattering(const G4String& name, G4ProcessType type):
|
||||
G4VContinuousDiscreteProcess(name, type),
|
||||
navigator(0),
|
||||
theLambdaTable(0),
|
||||
currentCouple(0),
|
||||
nBins(110),
|
||||
minKinEnergy(1.0*eV),
|
||||
maxKinEnergy(100.0*GeV),
|
||||
boundary(false),
|
||||
latDisplasment(true),
|
||||
buildLambdaTable(true)
|
||||
{
|
||||
modelManager = new G4EmModelManager();
|
||||
(G4LossTableManager::Instance())->Register(this);
|
||||
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VMultipleScattering::~G4VMultipleScattering()
|
||||
{
|
||||
(G4LossTableManager::Instance())->DeRegister(this);
|
||||
delete modelManager;
|
||||
if (theLambdaTable) {
|
||||
theLambdaTable->clearAndDestroy();
|
||||
delete theLambdaTable;
|
||||
}
|
||||
(G4LossTableManager::Instance())->DeRegister(this);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VMultipleScattering::BuildPhysicsTable(const G4ParticleDefinition& part)
|
||||
{
|
||||
currentCouple = 0;
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4VMultipleScattering::BuildPhysicsTable() for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4bool cutsWasModified = false;
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
for (size_t j=0; j<numOfCouples; j++){
|
||||
if (theCoupleTable->GetMaterialCutsCouple(j)->IsRecalcNeeded()) {
|
||||
cutsWasModified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !cutsWasModified ) return;
|
||||
InitialiseProcess(part);
|
||||
|
||||
if(latDisplasment) navigator = G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
modelManager->Clear();
|
||||
const G4DataVector* theCuts = modelManager->Initialise(&part, 0, 10.0, verboseLevel);
|
||||
|
||||
if (buildLambdaTable) {
|
||||
|
||||
theLambdaTable = new G4PhysicsTable(numOfCouples);
|
||||
|
||||
for (size_t i=0; i<numOfCouples; i++) {
|
||||
|
||||
// create physics vector and fill it
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
G4PhysicsVector* aVector = PhysicsVector(couple);
|
||||
modelManager->FillLambdaVector(aVector, couple, false);
|
||||
|
||||
// Insert vector for this material into the table
|
||||
theLambdaTable->insert(aVector) ;
|
||||
}
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "Lambda table is built for "
|
||||
<< part.GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
if(2 < verboseLevel) G4cout << *theLambdaTable << G4endl;
|
||||
if(5 < verboseLevel) G4cout << theCuts << G4endl;
|
||||
|
||||
}
|
||||
|
||||
G4String num = part.GetParticleName();
|
||||
if (verboseLevel>0 || num == "e-" || num == "mu+" || num == "proton")
|
||||
PrintInfoDefinition();
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4VMultipleScattering::BuildPhysicsTable() done for "
|
||||
<< GetProcessName()
|
||||
<< " and particle " << part.GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VMultipleScattering::AddEmModel(G4int order, G4VEmModel* p,
|
||||
const G4Region* region)
|
||||
{
|
||||
G4VEmFluctuationModel* fm = 0;
|
||||
modelManager->AddEmModel(order, p, fm, region);
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4VParticleChange* G4VMultipleScattering::PostStepDoIt(const G4Track& track,
|
||||
const G4Step& step)
|
||||
{
|
||||
fParticleChange.Initialize(track);
|
||||
G4double kineticEnergy = track.GetKineticEnergy();
|
||||
G4double truestep = step.GetStepLength();
|
||||
|
||||
if (kineticEnergy > 0.0) {
|
||||
G4double cth = currentModel->SampleCosineTheta(truestep);
|
||||
G4double sth = sqrt(1.-cth*cth);
|
||||
G4double phi = twopi*G4UniformRand();
|
||||
G4double dirx = sth*cos(phi);
|
||||
G4double diry = sth*sin(phi);
|
||||
|
||||
G4ThreeVector oldDirection = track.GetMomentumDirection();
|
||||
G4ThreeVector newDirection(dirx,diry,cth);
|
||||
newDirection.rotateUz(oldDirection);
|
||||
fParticleChange.SetMomentumChange(newDirection);
|
||||
|
||||
|
||||
/*
|
||||
if(0 < verboseLevel) {
|
||||
const G4ParticleDefinition* pd = dynParticle->GetDefinition();
|
||||
G4cout << "G4VMultipleScattering::PostStepDoIt: Sample secondary; E= " << finalT/MeV
|
||||
<< " MeV; model= (" << currentModel->LowEnergyLimit(pd)
|
||||
<< ", " << currentModel->HighEnergyLimit(pd) << ")"
|
||||
<< G4endl;
|
||||
}
|
||||
*/
|
||||
|
||||
// G4cout << "PostStep: sth= " << sth << " trueLength= " << truestep << " tLast= " << truePathLength << G4endl;
|
||||
|
||||
if (latDisplasment) {
|
||||
|
||||
G4double safety = step.GetPostStepPoint()->GetSafety();
|
||||
if ( safety > 0.0) {
|
||||
G4double r = currentModel->SampleDisplacement();
|
||||
if (r > safety) r = safety;
|
||||
|
||||
// G4cout << "r= " << r << " safety= " << safety << G4endl;
|
||||
|
||||
// sample direction of lateral displacement
|
||||
G4double phi = twopi*G4UniformRand();
|
||||
G4double dirx = cos(phi);
|
||||
G4double diry = sin(phi);
|
||||
|
||||
G4ThreeVector latDirection(dirx,diry,0.0);
|
||||
latDirection.rotateUz(oldDirection);
|
||||
|
||||
// compute new endpoint of the Step
|
||||
G4ThreeVector newPosition = (step.GetPostStepPoint())->GetPosition()
|
||||
+ r*latDirection;
|
||||
|
||||
navigator->LocateGlobalPointWithinVolume(newPosition);
|
||||
|
||||
fParticleChange.SetPositionChange(newPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &fParticleChange;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4VMultipleScattering::PrintInfoDefinition() const
|
||||
{
|
||||
G4cout << G4endl << GetProcessName() << ": Model variant of multiple scattering " << G4endl;
|
||||
if (theLambdaTable) {
|
||||
G4cout << " Lambda tables from "
|
||||
<< G4BestUnit(MinKinEnergy(),"Energy")
|
||||
<< " to "
|
||||
<< G4BestUnit(MaxKinEnergy(),"Energy")
|
||||
<< " in " << nBins << " bins."
|
||||
<< G4endl;
|
||||
}
|
||||
if (1 < verboseLevel) {
|
||||
G4cout << "LambdaTable address= " << theLambdaTable << G4endl;
|
||||
if(theLambdaTable) G4cout << (*theLambdaTable) << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4PhysicsVector* G4VMultipleScattering::PhysicsVector(const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
G4int nbins = 3;
|
||||
//G4int nbins = nDEDXBins;
|
||||
if( couple->IsUsed() ) nbins = nBins;
|
||||
// G4double xmax = maxKinEnergy*exp( log(maxKinEnergy/minKinEnergy) / ((G4double)(nbins-1)) );
|
||||
G4PhysicsVector* v = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nbins);
|
||||
return v;
|
||||
}
|
||||
|
||||
G4bool G4VMultipleScattering::StorePhysicsTable(G4ParticleDefinition* part,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
G4bool res = true;
|
||||
if ( theLambdaTable ) {
|
||||
const G4String name = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
|
||||
G4bool yes = theLambdaTable->StorePhysicsTable(name,ascii);
|
||||
if( !yes ) res = false;
|
||||
}
|
||||
|
||||
if ( res ) {
|
||||
G4cout << "Physics table are stored for " << part->GetParticleName()
|
||||
<< " and process " << GetProcessName()
|
||||
<< " in the directory <" << directory
|
||||
<< "> " << G4endl;
|
||||
} else {
|
||||
G4cout << "Fail to store Physics Table for " << part->GetParticleName()
|
||||
<< " and process " << GetProcessName()
|
||||
<< " in the directory <" << directory
|
||||
<< "> " << G4endl;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4bool G4VMultipleScattering::RetrievePhysicsTable(G4ParticleDefinition* part,
|
||||
const G4String& directory,
|
||||
G4bool ascii)
|
||||
{
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4VMultipleScattering::RetrievePhysicsTable() for "
|
||||
<< part->GetParticleName() << " and process "
|
||||
<< GetProcessName() << G4endl;
|
||||
}
|
||||
G4bool res = true;
|
||||
if(!buildLambdaTable) return res;
|
||||
|
||||
G4String num = part->GetParticleName();
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
|
||||
G4String filename = GetPhysicsTableFileName(part,directory,"Lambda",ascii);
|
||||
theLambdaTable = new G4PhysicsTable(numOfCouples);
|
||||
res = theLambdaTable->RetrievePhysicsTable(filename,ascii);
|
||||
if ( res ) {
|
||||
if (0 < verboseLevel) {
|
||||
G4cout << "Lambda table for " << num << " is retrieved from <"
|
||||
<< filename << ">"
|
||||
<< G4endl;
|
||||
}
|
||||
} else {
|
||||
theLambdaTable->clearAndDestroy();
|
||||
theLambdaTable = 0;
|
||||
if (0 < verboseLevel) {
|
||||
G4cout << "Lambda table for " << num << " in file <"
|
||||
<< filename << "> is not exist"
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (verboseLevel>0 || num == "e-" || num == "mu+" || num == "proton")
|
||||
PrintInfoDefinition();
|
||||
return res;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
Reference in New Issue
Block a user