Import Geant4 6.2.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 10:56:29 +02:00
parent 1d812b78b1
commit e083ffb441
1415 changed files with 111223 additions and 21207 deletions
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4BohrFluctuations.cc,v 1.7 2003/10/24 14:00:25 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-00-patch-01 $
// $Id: G4BohrFluctuations.cc,v 1.9 2004/05/11 15:35:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -60,7 +60,7 @@ G4BohrFluctuations::G4BohrFluctuations(const G4String& nam)
minNumberInteractionsBohr(10.0),
minFraction(0.2),
xmin(0.2),
minLoss(0.000001*eV)
minLoss(0.001*eV)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -89,6 +89,7 @@ G4double G4BohrFluctuations::SampleFluctuations(const G4Material* material,
if(meanLoss <= minLoss) return meanLoss;
G4double siga = Dispersion(material,dp,tmax,length);
G4double loss = meanLoss;
G4double navr = minNumberInteractionsBohr;
// Gaussian fluctuation
@@ -97,10 +98,11 @@ G4double G4BohrFluctuations::SampleFluctuations(const G4Material* material,
navr = meanLoss*meanLoss/siga;
if (navr < minNumberInteractionsBohr) gauss = false;
}
// G4cout << "### meanLoss= " << meanLoss << " navr= " << navr << " sig= " << sqrt(siga) << G4endl;
if(gauss) {
// Increase fluctuations for big fractional energy loss
if ( meanLoss > minFraction*kineticEnergy ) {
G4double gam = (kineticEnergy - meanLoss)/particleMass + 1.0;
G4double b2 = 1.0 - 1.0/(gam*gam);
@@ -111,17 +113,26 @@ G4double G4BohrFluctuations::SampleFluctuations(const G4Material* material,
}
siga = sqrt(siga);
G4double lossmax = meanLoss+meanLoss;
G4double twomeanLoss = meanLoss + meanLoss;
do {
loss = G4RandGauss::shoot(meanLoss,siga);
} while (0.0 > loss || loss > lossmax);
if(twomeanLoss < siga) {
G4double x;
do {
loss = twomeanLoss*G4UniformRand();
x = (loss - meanLoss)/siga;
} while (1.0 - 0.5*x*x < G4UniformRand());
} else {
do {
loss = G4RandGauss::shoot(meanLoss,siga);
} while (0.0 > loss || loss > twomeanLoss);
}
// Poisson fluctuations
} else {
G4double n = (G4double)(G4Poisson(navr));
loss = meanLoss*n/navr;
}
return loss;
}
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4EmModelManager.cc,v 1.22 2004/01/27 11:21:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-00-patch-01 $
// $Id: G4EmModelManager.cc,v 1.23 2004/05/10 18:45:33 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -321,7 +321,7 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
if(0 < verboseLevel) {
G4cout << "New G4RegionModels set with " << n << " models for region <"
<< region->GetName() << "> Elow(MeV)= ";
<< region->GetName() << "> Elow(MeV)= ";
for(G4int ii=0; ii<n; ii++) {G4cout << eLow[ii]/MeV << " ";}
G4cout << G4endl;
}
@@ -344,8 +344,7 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
G4cout << "G4EmModelManager::Initialise() for "
<< material->GetName()
<< " indexOfCouple= " << i
<< " indexOfRegion= " << reg
<< " indexOfRegion= " << reg
<< " indexOfRegion= " << reg
<< G4endl;
}
@@ -0,0 +1,293 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4EmMultiModel.cc,v 1.1 2004/05/03 13:13:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4EmMultiModel
//
// Author: Vladimir Ivanchenko
//
// Creation date: 03.05.2004
//
// Modifications:
//
// Class Description:
//
// Energy loss model using several G4VEmModels
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4EmMultiModel.hh"
#include "Randomize.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmMultiModel::G4EmMultiModel(const G4String& nam)
: G4VEmModel(nam),
nModels(0)
{
highKinEnergy = 100.0*GeV;
lowKinEnergy = 0.1*keV;
model.clear();
tsecmin.clear();
cross_section.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmMultiModel::~G4EmMultiModel()
{
if(nModels) {
for(G4int i=0; i<nModels; i++) {
delete model[i];
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmMultiModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector& cuts)
{
if(nModels) {
for(G4int i=0; i<nModels; i++) {
(model[i])->Initialise(p, cuts);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel::MinEnergyCut(const G4ParticleDefinition* p,
const G4MaterialCutsCouple* couple)
{
G4double cut = DBL_MAX;
if(nModels) {
cut = (model[0])->MinEnergyCut(p, couple);
}
return cut;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4EmMultiModel::IsInCharge(const G4ParticleDefinition* p)
{
G4bool yes = true;
if(nModels) {
for(G4int i=0; i<nModels; i++) {
G4bool x = (model[i])->IsInCharge(p);
if( !x ) yes = false;
}
}
return yes;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel::ComputeDEDX(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p,
G4double kineticEnergy,
G4double cutEnergy)
{
G4double dedx = 0.0;
if(nModels) {
dedx = (model[0])->ComputeDEDX(couple, p, cutEnergy, kineticEnergy);
}
return dedx;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel::CrossSection(const G4MaterialCutsCouple* couple,
const G4ParticleDefinition* p,
G4double kineticEnergy,
G4double cutEnergy,
G4double maxKinEnergy)
{
G4double cross = 0.0;
G4double t1 = cutEnergy;
G4double t2 = cutEnergy;
if(nModels) {
for(G4int i=0; i<nModels; i++) {
t1 = std::max(t2, tsecmin[i]);
t2 = std::min(maxKinEnergy, tsecmin[i+1]);
cross += (model[i])->CrossSection(couple, p, kineticEnergy, t1, t2);
}
}
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DynamicParticle* G4EmMultiModel::SampleSecondary(
const G4MaterialCutsCouple*,
const G4DynamicParticle*,
G4double,
G4double)
{
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
std::vector<G4DynamicParticle*>* G4EmMultiModel::SampleSecondaries(
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
G4double tmin,
G4double maxEnergy)
{
std::vector<G4DynamicParticle*>* vdp = 0;
if(nModels) {
G4int i;
G4double cross = 0.0;
G4double t1 = tmin;
G4double t2 = tmin;
for(i=0; i<nModels; i++) {
t1 = std::max(t2, tsecmin[i]);
t2 = std::min(maxEnergy, tsecmin[i+1]);
cross += (model[i])->CrossSection(couple, dp->GetDefinition(),
dp->GetKineticEnergy(), t1, t2);
cross_section[i] = cross;
}
cross *= G4UniformRand();
t2 = tmin;
for(i=0; i<nModels; i++) {
t1 = std::max(t2, tsecmin[i]);
t2 = std::min(maxEnergy, tsecmin[i+1]);
if(cross <= cross_section[i]) {
vdp = (model[i])->SampleSecondaries(couple, dp, t1, t2);
break;
}
}
}
return vdp;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel:: MaxSecondaryEnergy(const G4DynamicParticle* dp)
{
G4double tmax = 0.0;
if(nModels) {
tmax = (model[0])-> MaxSecondaryEnergy(dp);
}
return tmax;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4EmMultiModel:: MaxSecondaryEnergy(const G4ParticleDefinition*,
G4double kinEnergy)
{
G4cout << "Warning! G4EmMultiModel::"
<< "MaxSecondaryEnergy(const G4ParticleDefinition*,G4double kinEnergy)"
<< " should not be used!" << G4endl;
return kinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmMultiModel::DefineForRegion(const G4Region* r)
{
if(nModels) {
for(G4int i=0; i<nModels; i++) {(model[i])->DefineForRegion(r);}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmMultiModel::SetDynamicParticle(const G4DynamicParticle* dp)
{
if(nModels) {
for(G4int i=0; i<nModels; i++) {(model[i])->SetDynamicParticle(dp);}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmMultiModel::AddModel(G4VEmModel* p, G4double tmin, G4double tmax)
{
if(tmin < tmax && 0.0 < tmin) {
if(nModels == 0) {
tsecmin.push_back(tmin);
tsecmin.push_back(tmax);
cross_section.push_back(0.0);
model.push_back(p);
nModels++;
} else {
G4int i, j;
G4bool increment = false;
for(i=0; i<nModels; i++) {
if(tmin < tsecmin[i]) {
G4double t2 = std::min(tsecmin[i+1],tmax);
if(tmin < t2) {
tsecmin.push_back(0.0);
cross_section.push_back(0.0);
model.push_back(0);
for(j=nModels; j>i; j--) {
model[j] = model[j-1];
tsecmin[j+1] = tsecmin[j];
}
model[i] = p;
tsecmin[i+1] = t2;
tsecmin[i] = tmin;
increment = true;
}
} else if(i == nModels-1) {
G4double t1 = std::min(tsecmin[i+1],tmin);
G4double t2 = std::max(tsecmin[i+1],tmax);
if(t1 < t2) {
tsecmin.push_back(t2);
cross_section.push_back(0.0);
model.push_back(p);
increment = true;
}
}
}
if(increment) nModels++;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4EmProcessOptions.cc,v 1.1 2004/02/27 17:59:06 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-01 $
// $Id: G4EmProcessOptions.cc,v 1.2 2004/05/17 09:46:56 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -48,6 +48,7 @@
#include "G4VEmProcess.hh"
#include "G4VEnergyLossProcess.hh"
#include "G4VMultipleScattering.hh"
#include "G4Region.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -341,3 +342,63 @@ void G4EmProcessOptions::SetVerbose(G4int val, const G4String& name)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetLambdaFactor(G4double val)
{
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->SetLambdaFactor(val);
}
const std::vector<G4VEmProcess*>& w =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) q->SetLambdaFactor(val);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::ActivateFluorescence(G4bool val, const G4Region* r)
{
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->ActivateFluorescence(val,r);
}
const std::vector<G4VEmProcess*>& w =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) q->ActivateFluorescence(val,r);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::ActivateAugerElectronProduction(G4bool val, const G4Region* r)
{
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
if(p) p->ActivateAugerElectronProduction(val,r);
}
const std::vector<G4VEmProcess*>& w =
theManager->GetEmProcessVector();
std::vector<G4VEmProcess*>::const_iterator itp;
for(itp = w.begin(); itp != w.end(); itp++) {
G4VEmProcess* q = *itp;
if(q) q->ActivateAugerElectronProduction(val,r);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4IonFluctuations.cc,v 1.8 2003/11/12 10:24:18 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-00-patch-01 $
// $Id: G4IonFluctuations.cc,v 1.9 2004/05/11 15:35:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -66,7 +66,7 @@ G4IonFluctuations::G4IonFluctuations(const G4String& nam)
theBohrBeta2(50.0*keV/proton_mass_c2),
minFraction(0.2),
xmin(0.2),
minLoss(0.000001*eV)
minLoss(0.001*eV)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -99,13 +99,11 @@ G4double G4IonFluctuations::SampleFluctuations(const G4Material* material,
particle = dp->GetDefinition();
charge = particle->GetPDGCharge()/eplus;
}
particleMass = dp->GetMass();
G4double q = dp->GetCharge()/eplus;
chargeSquare = q*q;
chargeSqRatio = chargeSquare/(charge*charge);
G4double siga = Dispersion(material,dp,tmax,length);
G4double loss = meanLoss;
G4double navr = minNumberInteractionsBohr;
// Gaussian fluctuation
@@ -141,6 +139,7 @@ G4double G4IonFluctuations::SampleFluctuations(const G4Material* material,
G4double n = (G4double)(G4Poisson(navr));
loss = meanLoss*n/navr;
}
// G4cout << "meanLoss= " << meanLoss << " loss= " << loss << G4endl;
return loss;
}
@@ -153,6 +152,11 @@ G4double G4IonFluctuations::Dispersion(
G4double& tmax,
G4double& length)
{
particleMass = dp->GetMass();
G4double q = dp->GetCharge()/eplus;
chargeSquare = q*q;
chargeSqRatio = chargeSquare/(charge*charge);
G4double electronDensity = material->GetElectronDensity();
kineticEnergy = dp->GetKineticEnergy();
// G4cout << "e= " << kineticEnergy << " m= " << particleMass
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4LossTableManager.cc,v 1.42 2004/03/10 11:34:52 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-01 $
// $Id: G4LossTableManager.cc,v 1.44 2004/05/12 12:25:26 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -364,7 +364,7 @@ void G4LossTableManager::BuildPhysicsTable(const G4ParticleDefinition* aParticle
G4VEnergyLossProcess* em = loss_vector[j];
em->Initialise();
em->SetDEDXTable(hIonisation->DEDXTable());
em->SetRangeTable(hIonisation->RangeTable());
em->SetPreciseRangeTable(hIonisation->PreciseRangeTable());
em->SetRangeTableForLoss(hIonisation->RangeTableForLoss());
em->SetInverseRangeTable(hIonisation->InverseRangeTable());
em->SetLambdaTable(hIonisation->LambdaTable());
@@ -390,7 +390,7 @@ void G4LossTableManager::BuildPhysicsTable(const G4ParticleDefinition* aParticle
tables_are_built[i] = true;
em->Initialise();
em->SetDEDXTable(hIonisation->DEDXTable());
em->SetRangeTable(hIonisation->RangeTable());
em->SetPreciseRangeTable(hIonisation->PreciseRangeTable());
em->SetRangeTableForLoss(hIonisation->RangeTableForLoss());
em->SetInverseRangeTable(hIonisation->InverseRangeTable());
em->SetLambdaTable(hIonisation->LambdaTable());
@@ -479,7 +479,7 @@ void G4LossTableManager::RetrievePhysicsTables(const G4ParticleDefinition* aPart
tables_are_built[j] = true;
em->Initialise();
em->SetDEDXTable(theLoss->DEDXTable());
em->SetRangeTable(theLoss->RangeTable());
em->SetPreciseRangeTable(theLoss->PreciseRangeTable());
em->SetRangeTableForLoss(theLoss->RangeTableForLoss());
em->SetInverseRangeTable(theLoss->InverseRangeTable());
em->SetLambdaTable(theLoss->LambdaTable());
@@ -606,7 +606,7 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(const G4ParticleDefinition
}
newlist.clear();
range = tableBuilder->BuildRangeTable(dedxForRange);
em->SetRangeTable(range);
em->SetPreciseRangeTable(range);
delete dedxForRange;
}
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4MscModel.cc,v 1.15 2004/03/10 08:38:39 urban Exp $
// GEANT4 tag $Name: geant4-06-01 $
// $Id: G4MscModel.cc,v 1.17 2004/04/29 18:40:54 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -56,6 +56,8 @@
// energy dependence calculations has been simplified,
// 11-03-04 corrections in GeomPathLength,TrueStepLength,
// SampleCosineTheta
// 23-04-04 true -> geom and geom -> true transformation has been
// rewritten, changes in the angular distribution (L.Urban)
// Class Description:
//
@@ -114,12 +116,16 @@ void G4MscModel::Initialise(const G4ParticleDefinition* p,
const G4DataVector&)
{
// set values of some data members
xsi = facxsi*2.8215 ;
b = 1. ;
sigmafactor = twopi*classic_electr_radius*classic_electr_radius;
particle = p;
mass = particle->GetPDGMass();
charge = particle->GetPDGCharge()/eplus;
b = 1. ;
if(mass <= electron_mass_c2)
xsi = facxsi*2.22 ;
else
xsi = facxsi*2.70 ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -418,7 +424,8 @@ G4double G4MscModel::GeomPathLength(
currentRadLength = couple->GetMaterial()->GetRadlen();
lambda0 = lambda;
parlowen = 0. ;
par1 = -1. ;
par2 = par3 = 0. ;
tPathLength = truePathLength;
// this correction needed to run MSC with eIoni and eBrem inactivated
@@ -434,9 +441,11 @@ G4double G4MscModel::GeomPathLength(
if (tPathLength < range*dtrl) {
zmean = lambda0*(1.-exp(-tau));
if(tau < taulim) zmean = tPathLength*(1.-0.5*tPathLength/lambda0) ;
} else if((T0 < mass) || (tPathLength > 0.9*range)) {
parlowen = 1.+range/lambda0 ;
zmean = range*(1.-exp(parlowen*log(1.-tPathLength/range)))/parlowen ;
} else if(T0 < mass) {
par1 = 1./range ;
par2 = 1./(par1*lambda0) ;
par3 = 1.+par2 ;
zmean = (1.-exp(par3*log(1.-tPathLength/range)))/(par1*par3) ;
} else {
G4LossTableManager* theManager = G4LossTableManager::Instance();
G4double T1 = theManager->GetEnergy(particle,range-tPathLength,couple);
@@ -447,9 +456,10 @@ G4double G4MscModel::GeomPathLength(
} else {
lambda1 = CrossSection(couple,particle,T1,0.0,1.0);
}
G4double lambdaeff = 2./(1./lambda0+1./lambda1) ;
zmean = lambdaeff*(1.-exp(-tPathLength/lambdaeff));
par1 = (lambda0-lambda1)/(lambda0*tPathLength) ;
par2 = 1./(par1*lambda0) ;
par3 = 1.+par2 ;
zmean = (1.-exp(par3*log(lambda1/lambda0)))/(par1*par3) ;
}
// sample z
@@ -479,85 +489,108 @@ G4double G4MscModel::TrueStepLength(G4double geomStepLength)
trueLength = geomStepLength;
if(geomStepLength > lambda0*tausmall)
{
if(parlowen == 0.)
if(par1 < 0.)
trueLength = -lambda0*log(1.-geomStepLength/lambda0) ;
else
{
if(parlowen*geomStepLength/currentRange < 1.)
trueLength = currentRange*
(1.-exp(log(1.-parlowen*geomStepLength/currentRange)/parlowen)) ;
if(par1*par3*geomStepLength < 1.)
trueLength = (1.-exp(log(1.-par1*par3*geomStepLength)/par3))/par1 ;
else
trueLength = currentRange ;
}
}
if(trueLength > tPathLength) trueLength = tPathLength;
if(trueLength < geomStepLength) trueLength = geomStepLength;
if(trueLength > currentRange) trueLength = currentRange ;
if(trueLength < geomStepLength) trueLength = geomStepLength;
return trueLength;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MscModel::SampleCosineTheta(G4double trueStepLength, G4double KineticEnergy,
G4double lambda)
G4double G4MscModel::SampleCosineTheta(G4double trueStepLength,
G4double KineticEnergy)
{
currentKinEnergy = sqrt(currentKinEnergy*KineticEnergy) ;
G4double cth = 1. ;
G4double tau = trueStepLength/lambda0 ;
if(trueStepLength < currentRange*dtrl)
currentTau = trueStepLength/lambda;
else
currentTau = 0.5*trueStepLength*(1./lambda0+1./lambda) ;
if(trueStepLength >= currentRange*dtrl)
tau = -par2*log(1.-par1*trueStepLength) ;
currentTau = tau ;
if(trueStepLength < stepmin)
cth = exp(-currentTau) ;
cth = exp(-tau) ;
else
{
if (currentTau > taubig) cth = -1.+2.*G4UniformRand();
else if (currentTau >= tausmall)
if (tau > taubig) cth = -1.+2.*G4UniformRand();
else if (tau >= tausmall)
{
if(currentTau > taubig) cth = -1.+2.*G4UniformRand();
else
{
const G4double c_highland = 13.6*MeV, corr_highland=0.038 ;
const G4double xx0low = 1.e-6;
G4double a ;
// for all particles take the width of the central part
// from the Highland formula
// (Particle Physics Booklet, July 2002, eq. 26.10)
const G4double c_highland = 13.6*MeV, corr_highland=0.038 ;
G4double Q = abs(charge) ;
G4double xx0 = trueStepLength/currentRadLength;
G4double betacp = currentKinEnergy*(currentKinEnergy+2.*mass)/
(currentKinEnergy+mass) ;
G4double betacp = sqrt(currentKinEnergy*(currentKinEnergy+2.*mass)*
KineticEnergy*(KineticEnergy+2.*mass)/
((currentKinEnergy+mass)*(KineticEnergy+mass))) ;
G4double theta0 = c_highland*Q*sqrt(xx0)/betacp ;
if(xx0 > xx0low)
theta0 *= (1.+corr_highland*log(xx0)) ;
else
// protection for small thickness
theta0 *= (1.+corr_highland*log(xx0low)) ;
// correction term
G4double y ;
// for muons/hadron as in Highland's formula
if(mass > electron_mass_c2)
{
y = log(xx0) ;
theta0 *= (1.+corr_highland*y) ;
}
// for e+/e-
else
{
// corr. factor has been modified between xx0low and xx0high
// and below xx0low for e+/e- only ************************
const G4double xx0high = 1., xx0low = 1.e-3 ;
// quadratic corr.factor from Hanson's msc data (Au, 15.7 MeV e)
const G4double corrq1 = 0.01273, corrq2 = -0.006840 ;
const G4double corrlow = 0.05 ; // from some backscattering data
const G4double fach = 1.+corr_highland*log(xx0high),
facl = fach*(1.+log(xx0low/xx0high)*
(corrq1+log(xx0low/xx0high)*corrq2)) ;
if(xx0 >= xx0high)
{
y = log(xx0) ;
theta0 *= (1.+corr_highland*y) ;
}
else if(xx0 >= xx0low)
{
y = log(xx0/xx0high) ;
theta0 *= fach*(1.+y*(corrq1+y*corrq2)) ;
}
else
{
y = log(xx0/xx0low) ;
theta0 *= facl*(1.+corrlow*y) ;
}
}
if (theta0 > taulim) a = 0.5/(1.-cos(theta0)) ;
else a = 1.0/(theta0*theta0) ;
if(theta0 > taulim) a = 0.5/(1.-cos(theta0)) ;
else a = 1.0/(theta0*theta0) ;
G4double xmeanth = exp(-currentTau);
G4double xmeanth = exp(-tau);
G4double xmeanth1 = 1.-xmeanth ;
if(currentTau < taulim) xmeanth1 = currentTau ;
if(currentTau < taulim) xmeanth1 = tau ;
const G4double x1fac1 = exp(-xsi) ;
const G4double x1fac2 = (1.-(1.+xsi)*x1fac1)/(1.-x1fac1) ;
const G4double x1fac3 = 1.3 ; // x1fac3 >= 1. !!!!!!!!!
// exponent c is fixed to 2. in f2(x) now (tail) ~1/(b-x)**2
const G4double wb = 1.-2./xsi ;
const G4double x1fac3 = 1.3 ;
G4double ea,eaa,xmean1 ;
G4double b1 = 2., bx = 2.,
xmean2 = 0. ;
G4double c = 2.,b1 = 2., bx = 2.,
eb1 = b1, ebx = b1, xmean2 = 0. ;
G4double prob = 1., qprob ;
G4double x0 = 1.-xsi/a;
G4double oneminusx0=xsi/a ;
@@ -596,16 +629,21 @@ G4double G4MscModel::SampleCosineTheta(G4double trueStepLength, G4double Kinetic
eaa = 1.-ea ;
xmean1 = 1.-x1fac2/a ;
b = 1.-wb*xsi/a ;
// from continuity of the 1st derivatives
c = a*(b-x0) ;
if(c == 1.) c=1.000001 ;
if(c == 2.) c=2.000001 ;
b1 = b+1. ;
bx = (1.-wb)*xsi/a ;
xmean2 = b-b1*bx*log(b1/bx)/oneplusx0 ;
bx = b-x0 ;
eb1=exp((c-1.)*log(b1)) ;
ebx=exp((c-1.)*log(bx)) ;
xmean2 = (x0*eb1+ebx+(eb1*bx-b1*ebx)/(2.-c))/(eb1-ebx) ;
G4double f1x0 = a*ea/eaa ;
G4double f2x0 ;
f2x0 = b1/(oneplusx0*bx) ;
G4double f2x0 = (c-1.)*eb1*ebx/(eb1-ebx)/
exp(c*log(b-x0)) ;
// from continuity at x=x0
prob = f2x0/(f1x0+f2x0) ;
// from xmean = xmeanth
@@ -625,13 +663,12 @@ G4double G4MscModel::SampleCosineTheta(G4double trueStepLength, G4double Kinetic
if (G4UniformRand() < prob)
cth = 1.+log(ea+G4UniformRand()*eaa)/a ;
else
cth = b-b1*bx/(bx+oneplusx0*G4UniformRand()) ;
cth = b-b1*bx/exp(log(ebx-G4UniformRand()*(ebx-eb1))/(c-1.)) ;
}
else
{
cth = -1.+2.*G4UniformRand();
}
}
}
}
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4MultipleScattering.cc,v 1.46 2003/11/12 16:11:56 urban Exp $
// GEANT4 tag $Name: geant4-06-00-patch-01 $
// $Id: G4MultipleScattering.cc,v 1.47 2004/04/23 05:52:08 urban Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -----------------------------------------------------------------------------
// 16/05/01 value of cparm changed , L.Urban
@@ -60,6 +60,7 @@
// method
// 28-03-03 Move to model design (V.Ivanchenko)
// 08-08-03 STD substitute standard (V.Ivanchenko)
// 23-04-04 value of data member dtrl changed from 0.15 to 0.05 (L.Urban)
//
// -----------------------------------------------------------------------------
//
@@ -75,7 +76,7 @@ G4MultipleScattering::G4MultipleScattering(const G4String& processName)
: G4VMultipleScattering(processName),
totBins(120),
facrange(0.199),
dtrl(0.15),
dtrl(0.05),
NuclCorrPar (0.0615),
FactPar(0.40),
facxsi(1.0),
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4UniversalFluctuation.cc,v 1.15 2004/02/06 11:59:21 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-00-patch-01 $
// $Id: G4UniversalFluctuation.cc,v 1.20 2004/05/11 15:35:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -42,6 +42,7 @@
// 16-10-03 Changed interface to Initialisation (V.Ivanchenko)
// 07-11-03 Fix problem of rounding of double in G4UniversalFluctuations
// 06-02-04 Add control on big sigma > 2*meanLoss (V.Ivanchenko)
// 26-04-04 Comment out the case of very small step (V.Ivanchenko)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -61,14 +62,13 @@ G4UniversalFluctuation::G4UniversalFluctuation(const G4String& nam)
particle(0),
minNumberInteractionsBohr(10.0),
theBohrBeta2(50.0*keV/proton_mass_c2),
minLoss(0.000001*eV),
problim(0.01),
minLoss(0.001*eV),
sumalim(0.01),
alim(10.),
nmaxCont1(4.),
nmaxCont2(16.)
{
lastMaterial = 0;
sumalim = -log(problim);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -97,46 +97,48 @@ G4double G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
// calculate actual loss from the mean loss
// The model used to get the fluctuation is essentially the same
// as in Glandz in Geant3.
// shortcut for very very small loss
// G4cout << "### Mean loss= " << meanLoss << G4endl;
// shortcut for very very small loss
if(meanLoss < minLoss) return meanLoss;
if(dp->GetDefinition() != particle) {
particleMass = dp->GetMass();
G4double q = dp->GetCharge();
chargeSquare = q*q;
}
if(!particle) InitialiseMe(dp->GetDefinition());
ipotFluct = material->GetIonisation()->GetMeanExcitationEnergy();
G4double gam = (dp->GetKineticEnergy())/particleMass + 1.0;
G4double gam2 = gam*gam;
G4double beta2 = 1.0 - 1.0/gam2;
G4double tau = dp->GetKineticEnergy()/particleMass;
G4double gam = tau + 1.0;
G4double gam2 = gam*gam;
G4double beta2 = tau*(tau + 2.0)/gam2;
// Validity range for delta electron cross section
G4double loss, siga;
// G4cout << "### tmax= " << tmax << " kappa= " << minNumberInteractionsBohr << " l= " << length << G4endl;
// Gaussian fluctuation
// G4cout << "tmax= " << tmax << " kappa= " << minNumberInteractionsBohr << " l= " << length << G4endl;
// Gaussian fluctuation
if(meanLoss >= minNumberInteractionsBohr*tmax || tmax <= ipotFluct*minNumberInteractionsBohr)
{
electronDensity = material->GetElectronDensity();
siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
siga = (1.0/beta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
* electronDensity * chargeSquare ;
siga = sqrt(siga);
G4double twomeanLoss = meanLoss + meanLoss;
if(twomeanLoss < siga) {
loss = twomeanLoss*G4UniformRand();
G4double x;
do {
loss = twomeanLoss*G4UniformRand();
x = (loss - meanLoss)/siga;
} while (1.0 - 0.5*x*x < G4UniformRand());
} else {
do {
loss = G4RandGauss::shoot(meanLoss,siga);
} while (loss < 0. || loss > twomeanLoss);
}
// G4cout << "de= " << meanLoss << " fluc= " << loss-meanLoss << " sig= " << siga << G4endl;
//G4cout << "### meanLoss= " << meanLoss << " fluc= " << loss-meanLoss << " sig= " << siga << G4endl;
return loss;
}
// Non Gaussian fluctuation
// Non Gaussian fluctuation
if(material != lastMaterial) {
f1Fluct = material->GetIonisation()->GetF1fluct();
@@ -153,7 +155,7 @@ G4double G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
G4double p1,p2,p3;
G4double w1 = tmax/ipotFluct;
G4double w2 = log(2.*electron_mass_c2*(gam2 - 1.0));
G4double w2 = log(2.*electron_mass_c2*beta2*gam2);
G4double C = meanLoss*(1.-rateFluct)/(w2-ipotLogFluct-beta2);
@@ -165,11 +167,11 @@ G4double G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
if(a3 < 0.) a3 = 0.;
G4double suma = a1+a2+a3;
loss = 0. ;
if(suma < sumalim) // very small Step
{
//G4cout << "A very small step" << G4endl;
G4double e0 = material->GetIonisation()->GetEnergy0fluct();
if(tmax == ipotFluct)
@@ -209,11 +211,12 @@ G4double G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
for(G4int i=0; i<ip3; i++) {
loss += 1./(1.-w*G4UniformRand()) ;
}
loss *= e0*corrfac ;
}
loss *= e0*corrfac ;
}
}
// Not so small Step
} else {
} else {
//G4cout << "Excitation alim= " << alim << " a1= " << a1 << " a2= " << a2 << G4endl;
// excitation type 1
if(a1>alim) {
siga=sqrt(a1) ;
@@ -232,12 +235,12 @@ G4double G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
// 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;
if(loss < 0.) loss = 0.0;
// ionisation .......................................
// ionisation
if(a3 > 0.) {
if(a3>alim) {
siga=sqrt(a3) ;
@@ -265,7 +268,7 @@ G4double G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
if (p3 > na) {
w2 = alfa*ipotFluct;
G4double w = (tmax-w2)/tmax;
G4double w = (tmax-w2)/tmax;
G4int nb = G4int(p3-na);
for (G4int k=0; k<nb; k++) {
lossc += w2/(1.-w*G4UniformRand());
@@ -274,25 +277,27 @@ G4double G4UniversalFluctuation::SampleFluctuations(const G4Material* material,
}
loss += lossc;
}
}
}
//G4cout << "### Final loss= " << loss << G4endl;
return loss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4UniversalFluctuation::Dispersion(
const G4Material* material,
G4double G4UniversalFluctuation::Dispersion(
const G4Material* material,
const G4DynamicParticle* dp,
G4double& tmax,
G4double& tmax,
G4double& length)
{
if(!particle) InitialiseMe(dp->GetDefinition());
electronDensity = material->GetElectronDensity();
G4double gam = (dp->GetKineticEnergy())/particleMass + 1.0;
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;
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4VEmProcess.cc,v 1.4 2004/03/01 13:06:26 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-01 $
// $Id: G4VEmProcess.cc,v 1.5 2004/05/17 09:46:57 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -71,10 +71,14 @@
G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
G4VRestDiscreteProcess(name, type),
theLambdaTable(0),
theEnergyOfCrossSectionMax(0),
theCrossSectionMax(0),
particle(0),
secondaryParticle(0),
currentCouple(0),
nLambdaBins(90),
lambdaFactor(0.1),
mfpKinEnergy(0.0),
integral(true),
meanFreePath(true)
{
@@ -91,7 +95,8 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
G4VEmProcess::~G4VEmProcess()
{
if(theLambdaTable) theLambdaTable->clearAndDestroy();
theLambdaTable = 0;
if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax;
if(theCrossSectionMax) delete [] theCrossSectionMax;
modelManager->Clear();
delete modelManager;
(G4LossTableManager::Instance())->DeRegister(this);
@@ -102,6 +107,8 @@ G4VEmProcess::~G4VEmProcess()
void G4VEmProcess::Initialise()
{
if(theLambdaTable) theLambdaTable->clearAndDestroy();
if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax;
if(theCrossSectionMax) delete [] theCrossSectionMax;
theLambdaTable = 0;
modelManager->Clear();
theCuts = modelManager->Initialise(particle,secondaryParticle,2.,verboseLevel);
@@ -163,6 +170,8 @@ G4PhysicsTable* G4VEmProcess::BuildLambdaTable()
size_t numOfCouples = theCoupleTable->GetTableSize();
G4PhysicsTable* theTable = new G4PhysicsTable(numOfCouples);
theEnergyOfCrossSectionMax = new G4double [numOfCouples];
theCrossSectionMax = new G4double [numOfCouples];
for(size_t i=0; i<numOfCouples; i++) {
@@ -171,6 +180,20 @@ G4PhysicsTable* G4VEmProcess::BuildLambdaTable()
G4PhysicsVector* aVector = LambdaPhysicsVector(couple);
modelManager->FillLambdaVector(aVector, couple);
G4double e, s, emax = 0.0;
G4bool b;
G4double smax = 0.0;
for (G4int j=0; j<nLambdaBins; j++) {
e = aVector->GetLowEdgeEnergy(j);
s = aVector->GetValue(e,b);
if(s > smax) {
smax = s;
emax = e;
}
}
theEnergyOfCrossSectionMax[i] = emax;
theCrossSectionMax[i] = smax;
// Insert vector for this material into the table
theTable->insert(aVector) ;
}
@@ -228,12 +251,8 @@ G4VParticleChange* G4VEmProcess::PostStepDoIt(const G4Track& track,
// Integral approach
if (integral) {
G4bool b;
G4double postStepLambda =
(((*theLambdaTable)[currentMaterialIndex])->GetValue(finalT,b));
if(preStepLambda*G4UniformRand() > postStepLambda)
return G4VRestDiscreteProcess::PostStepDoIt(track,step);
if(preStepLambda*G4UniformRand() > GetLambda(finalT))
return G4VRestDiscreteProcess::PostStepDoIt(track,step);
}
G4VEmModel* currentModel = SelectModel(finalT);
@@ -399,4 +418,58 @@ G4bool G4VEmProcess::RetrievePhysicsTable(G4ParticleDefinition* part,
return yes;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetLambdaBinning(G4int nbins)
{
nLambdaBins = nbins;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetMinKinEnergy(G4double e)
{
minKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VEmProcess::MinKinEnergy() const
{
return minKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetMaxKinEnergy(G4double e)
{
maxKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VEmProcess::MaxKinEnergy() const
{
return maxKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::ActivateFluorescence(G4bool, const G4Region*)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::ActivateAugerElectronProduction(G4bool, const G4Region*)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEmProcess::SetLambdaFactor(G4double val)
{
if(val > 0.0 && val <= 1.0) lambdaFactor = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4VEnergyLossProcess.cc,v 1.10 2004/03/12 11:42:57 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-01 $
// $Id: G4VEnergyLossProcess.cc,v 1.22 2004/05/17 09:46:57 vnivanch Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -70,6 +70,8 @@
// 27-02-04 Fix problem of loss in low presure gases, cleanup precise range
// calculation, use functions ForLoss in AlongStepDoIt (V.Ivanchenko)
// 10-03-04 Fix a problem of Precise Range table (V.Ivanchenko)
// 19-03-04 Fix a problem energy below lowestKinEnergy (V.Ivanchenko)
// 31-03-04 Fix a problem of retrieve tables (V.Ivanchenko)
//
// Class Description:
//
@@ -96,6 +98,7 @@
#include "G4VParticleChange.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Proton.hh"
#include "G4VSubCutoffProcessor.hh"
#include "G4ProcessManager.hh"
@@ -120,6 +123,8 @@ G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name, G4ProcessType t
theSubLambdaTable(0),
theDEDXAtMaxEnergy(0),
theRangeAtMaxEnergy(0),
theEnergyOfCrossSectionMax(0),
theCrossSectionMax(0),
particle(0),
baseParticle(0),
secondaryParticle(0),
@@ -131,6 +136,8 @@ G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name, G4ProcessType t
minSubRange(0.1),
defaultRoverRange(0.2),
defaultIntegralRange(1.0),
lambdaFactor(0.1),
mfpKinEnergy(0.0),
lossFluctuationFlag(true),
rndmStepFlag(false),
hasRestProcess(true),
@@ -192,9 +199,11 @@ void G4VEnergyLossProcess::Clear()
if(theInverseRangeTable) theInverseRangeTable->clearAndDestroy();
if(theLambdaTable) theLambdaTable->clearAndDestroy();
if(theSubLambdaTable) theSubLambdaTable->clearAndDestroy();
if(theDEDXAtMaxEnergy) delete [] theDEDXAtMaxEnergy;
if(theRangeAtMaxEnergy) delete [] theRangeAtMaxEnergy;
}
if(theDEDXAtMaxEnergy) delete [] theDEDXAtMaxEnergy;
if(theRangeAtMaxEnergy) delete [] theRangeAtMaxEnergy;
if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax;
if(theCrossSectionMax) delete [] theCrossSectionMax;
theDEDXTable = 0;
thePreciseRangeTable = 0;
@@ -205,6 +214,8 @@ void G4VEnergyLossProcess::Clear()
theSubLambdaTable = 0;
theDEDXAtMaxEnergy = 0;
theRangeAtMaxEnergy = 0;
theEnergyOfCrossSectionMax = 0,
theCrossSectionMax = 0,
tablesAreBuilt = false;
}
@@ -286,6 +297,7 @@ void G4VEnergyLossProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
{
currentCouple = 0;
preStepLambda = 0.0;
preStepMFP = DBL_MAX;
if(0 < verboseLevel) {
G4cout << "========================================================" << G4endl;
G4cout << "### G4VEnergyLossProcess::BuildPhysicsTable() for "
@@ -333,30 +345,6 @@ void G4VEnergyLossProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetParticles(const G4ParticleDefinition* p1,
const G4ParticleDefinition* p2)
{
particle = p1;
baseParticle = p2;
G4bool yes = true;
if(particle && baseParticle) {
if((particle->GetPDGMass() < MeV && baseParticle->GetPDGMass() > MeV) ||
(particle->GetPDGMass() > MeV && baseParticle->GetPDGMass() < MeV)) yes = false;
}
if(!yes) {
G4cout << "Warning in G4VEnergyLossProcess::SetParticle: "
<< particle->GetParticleName()
<< " losses cannot be obtained from "
<< baseParticle->GetParticleName()
<< " losses" << G4endl;
} else {
DefineBaseParticle(p1);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::AddEmModel(G4int order, G4VEmModel* p, G4VEmFluctuationModel* fluc,
const G4Region* region)
{
@@ -373,10 +361,11 @@ void G4VEnergyLossProcess::UpdateEmModel(const G4String& nam, G4double emin, G4d
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::AddSubCutoffProcessor(G4VSubCutoffProcessor* p,
const G4Region* r)
const G4Region* r)
{
if( !p ) {
G4cout << "G4VEnergyLossProcess::AddSubCutoffProcessor WARNING: no SubCutoffProcessor defined." << G4endl;
G4cout << "G4VEnergyLossProcess::AddSubCutoffProcessor WARNING: no SubCutoffProcessor defined."
<< G4endl;
return;
}
G4RegionStore* regionStore = G4RegionStore::GetInstance();
@@ -594,7 +583,6 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
// Get the actual (true) Step length
G4double length = step.GetStepLength();
G4double eloss = 0.0;
// G4bool b;
/*
if(-1 < verboseLevel) {
@@ -620,24 +608,18 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
// Long step
} else {
G4double x = (GetRangeForLoss(preStepKinEnergy) - length)/reduceFactor;
G4double postStepScaledEnergy = GetKineticEnergyForLoss(x);
if (preStepScaledEnergy > postStepScaledEnergy)
eloss = (preStepScaledEnergy - postStepScaledEnergy)/massRatio;
else
eloss = GetDEDXForLoss(preStepKinEnergy)*length;
G4double r = GetRangeForLoss(preStepKinEnergy)/reduceFactor;
G4double x = r - length/reduceFactor;
eloss = (ScaledKinEnergyForLoss(r) - ScaledKinEnergyForLoss(x))/massRatio;
/*
if(-1 < verboseLevel) {
G4bool b;
G4cout << "fRange(mm)= " << fRange/mm
<< " xPost(mm)= " << x/mm
G4cout << "rPre(mm)= " << r/mm
<< " rPost(mm)= " << x/mm
<< " ePre(MeV)= " << preStepScaledEnergy/MeV
<< " ePost(MeV)= " << postStepScaledEnergy/MeV
<< " eloss(MeV)= " << eloss/MeV
<< " eloss0(MeV)= " << (((*theDEDXTable)[currentMaterialIndex])->
GetValue(preStepScaledEnergy, b))*length*chargeSqRatio
<< " eloss0(MeV)= " << GetDEDXForLoss(preStepKinEnergy)*length/MeV
<< G4endl;
}
*/
@@ -654,17 +636,12 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
G4bool b;
//G4cout << *theDEDXTable << G4endl;
G4cout << "eloss(MeV)= " << eloss/MeV
<< " eloss0(MeV)= " << (((*theDEDXTable)[currentMaterialIndex])->
GetValue(preStepScaledEnergy, b))*length*chargeSqRatio
<< " r0(mm)= " << (((*theRangeTableForLoss)[currentMaterialIndex])->
GetValue(preStepScaledEnergy, b))
<< " eloss0(MeV)= " << GetDEDXForLoss(preStepKinEnergy)*length
<< " r0(mm)= " << GetRangeForLoss(preStepKinEnergy)
<< " tmax= " << tmax
<< " e-eloss= " << preStepKinEnergy-eloss
// << " mat= " << currentMaterial
// << " matIdx= " << currentMaterialIndex
// << " preCouple= " << (step.GetPreStepPoint())->GetMaterialCutsCouple()
// << " postCouple= " << (step.GetPostStepPoint())->GetMaterialCutsCouple()
// << " rangeTable= " << theRangeTableForLoss
<< G4endl;
}
*/
@@ -687,6 +664,21 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
}
*/
G4double finalT = preStepKinEnergy - eloss;
if (finalT <= lowestKinEnergy) {
finalT = 0.0;
if (hasRestProcess) fParticleChange.SetStatusChange(fStopButAlive);
else fParticleChange.SetStatusChange(fStopAndKill);
}
eloss = preStepKinEnergy-finalT;
fParticleChange.SetProposedKineticEnergy(finalT);
// Subcutoff and/or deexcitation
std::vector<G4Track*>* newp =
SecondariesAlongStep(step, tmax, eloss, preStepScaledEnergy);
@@ -702,36 +694,26 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
t = (*newp)[i];
e = t->GetKineticEnergy();
const G4ParticleDefinition* pd = t->GetDefinition();
if (pd != G4Gamma::Gamma() && pd != G4Electron::Electron() ) e += pd->GetPDGMass();
if (pd != G4Positron::Positron() ) e += electron_mass_c2;
if (e > eloss) e = eloss;
preStepKinEnergy -= e;
eloss -= e;
pParticleChange->AddSecondary(t);
}
}
delete newp;
}
preStepKinEnergy -= eloss;
/*
if(-1 < verboseLevel) {
G4cout << "eloss(MeV)= " << eloss/MeV
G4cout << "Final value eloss(MeV)= " << eloss/MeV
<< " preStepKinEnergy= " << preStepKinEnergy
<< " postStepKinEnergy= " << finalT
<< " lossFlag= " << lossFluctuationFlag
<< G4endl;
}
*/
if (preStepKinEnergy <= lowestKinEnergy) {
eloss += preStepKinEnergy;
preStepKinEnergy = 0.0;
if (hasRestProcess) fParticleChange.SetStatusChange(fStopButAlive);
else fParticleChange.SetStatusChange(fStopAndKill);
}
fParticleChange.SetProposedKineticEnergy(preStepKinEnergy);
fParticleChange.SetLocalEnergyDeposit(eloss);
return &fParticleChange;
@@ -748,11 +730,7 @@ G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
// Integral approach
if (integral) {
G4bool b;
G4double postStepLambda = chargeSqRatio*
(((*theLambdaTable)[currentMaterialIndex])->GetValue(postStepScaledEnergy,b));
if(preStepLambda*G4UniformRand() > postStepLambda)
if(preStepLambda*G4UniformRand() > GetLambda(postStepScaledEnergy))
return G4VContinuousDiscreteProcess::PostStepDoIt(track,step);
}
@@ -837,15 +815,15 @@ void G4VEnergyLossProcess::PrintInfoDefinition()
void G4VEnergyLossProcess::SetDEDXTable(G4PhysicsTable* p)
{
if(theDEDXTable) theDEDXTable->clearAndDestroy();
if(theDEDXTable && !baseParticle) theDEDXTable->clearAndDestroy();
theDEDXTable = p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetRangeTable(G4PhysicsTable* p)
void G4VEnergyLossProcess::SetPreciseRangeTable(G4PhysicsTable* p)
{
if(thePreciseRangeTable) thePreciseRangeTable->clearAndDestroy();
if(thePreciseRangeTable && !baseParticle) thePreciseRangeTable->clearAndDestroy();
if(theDEDXAtMaxEnergy) delete [] theDEDXAtMaxEnergy;
if(theRangeAtMaxEnergy) delete [] theRangeAtMaxEnergy;
@@ -853,7 +831,8 @@ void G4VEnergyLossProcess::SetRangeTable(G4PhysicsTable* p)
if(p) {
size_t n = p->length();
G4PhysicsVector* pv = (*p)[0];
G4double emax = pv->GetLowEdgeEnergy(pv->GetVectorLength());
// G4double emax = pv->GetLowEdgeEnergy(pv->GetVectorLength());
G4double emax = maxKinEnergyForRange;
G4bool b;
theDEDXAtMaxEnergy = new G4double [n];
theRangeAtMaxEnergy = new G4double [n];
@@ -874,7 +853,7 @@ void G4VEnergyLossProcess::SetRangeTable(G4PhysicsTable* p)
void G4VEnergyLossProcess::SetRangeTableForLoss(G4PhysicsTable* p)
{
if(theRangeTableForLoss) theRangeTableForLoss->clearAndDestroy();
if(theRangeTableForLoss && !baseParticle) theRangeTableForLoss->clearAndDestroy();
theRangeTableForLoss = p;
}
@@ -889,7 +868,7 @@ void G4VEnergyLossProcess::SetSecondaryRangeTable(G4PhysicsTable* p)
void G4VEnergyLossProcess::SetInverseRangeTable(G4PhysicsTable* p)
{
if(theInverseRangeTable) theInverseRangeTable->clearAndDestroy();
if(theInverseRangeTable && !baseParticle) theInverseRangeTable->clearAndDestroy();
theInverseRangeTable = p;
}
@@ -897,16 +876,46 @@ void G4VEnergyLossProcess::SetInverseRangeTable(G4PhysicsTable* p)
void G4VEnergyLossProcess::SetLambdaTable(G4PhysicsTable* p)
{
if(theLambdaTable) theLambdaTable->clearAndDestroy();
if(theLambdaTable && !baseParticle) theLambdaTable->clearAndDestroy();
theLambdaTable = p;
tablesAreBuilt = true;
if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax;
if(theCrossSectionMax) delete [] theCrossSectionMax;
if(p) {
size_t n = p->length();
G4PhysicsVector* pv = (*p)[0];
size_t nb = pv->GetVectorLength();
G4double emax = pv->GetLowEdgeEnergy(nb);
G4double e, s, smax = 0.0;
theEnergyOfCrossSectionMax = new G4double [n];
theCrossSectionMax = new G4double [n];
G4bool b;
for (size_t i=0; i<n; i++) {
pv = (*p)[i];
smax = 0.0;
for (size_t j=0; j<nb; j++) {
e = pv->GetLowEdgeEnergy(j);
s = pv->GetValue(e,b);
if(s > smax) {
smax = s;
emax = e;
}
}
theEnergyOfCrossSectionMax[i] = emax;
theCrossSectionMax[i] = smax;
// G4cout << "i= " << i << " e2(MeV)= " << emax/MeV
// << " lambda= " << smax << G4endl;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetSubLambdaTable(G4PhysicsTable* p)
{
if(theSubLambdaTable) theSubLambdaTable->clearAndDestroy();
if(theSubLambdaTable && !baseParticle) theSubLambdaTable->clearAndDestroy();
theSubLambdaTable = p;
if (nSCoffRegions) {
for (G4int i=0; i<nSCoffRegions; i++) {
@@ -1195,7 +1204,7 @@ G4bool G4VEnergyLossProcess::RetrievePhysicsTable(G4ParticleDefinition* part,
yes = table->ExistPhysicsTable(filename);
if(yes) yes = table->RetrievePhysicsTable(filename,ascii);
if(yes) {
SetRangeTable(table);
SetPreciseRangeTable(table);
if (-1 < verboseLevel) {
G4cout << "Precise Range table for " << particleName << " is retrieved from <"
<< filename << ">"
@@ -1203,11 +1212,8 @@ G4bool G4VEnergyLossProcess::RetrievePhysicsTable(G4ParticleDefinition* part,
}
} else {
table->clearAndDestroy();
if(fpi) {
res = false;
G4cout << "Precise Range table for loss for " << particleName << " does not exist"
<< G4endl;
}
G4cout << "Precise Range table for loss for " << particleName << " does not exist"
<< G4endl;
}
filename = GetPhysicsTableFileName(part,directory,"InverseRange",ascii);
@@ -1275,8 +1281,8 @@ G4bool G4VEnergyLossProcess::RetrievePhysicsTable(G4ParticleDefinition* part,
}
if(res) PrintInfoDefinition();
else {
G4cout << "### BuildPhysicsTable will be requested for " << GetProcessName()
<< " for " << particleName << G4endl;
G4cout << "### BuildPhysicsTable will be requested for " << GetProcessName()
<< " for " << particleName << G4endl;
}
}
tablesAreBuilt = true;
@@ -1287,6 +1293,135 @@ G4bool G4VEnergyLossProcess::RetrievePhysicsTable(G4ParticleDefinition* part,
return res;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetLinearLossLimit(G4double val)
{
linLossLimit = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetLossFluctuations(G4bool val)
{
lossFluctuationFlag = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetSubCutoff(G4bool)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetRandomStep(G4bool val)
{
rndmStepFlag = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetMinSubRange(G4double val)
{
minSubRange = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4bool G4VEnergyLossProcess::TablesAreBuilt() const
{
return tablesAreBuilt;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4int G4VEnergyLossProcess::NumberOfSubCutoffRegions() const
{
return nSCoffRegions;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4ParticleDefinition* G4VEnergyLossProcess::DefineBaseParticle(
const G4ParticleDefinition*)
{
return 0;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetDEDXBinning(G4int nbins)
{
nDEDXBins = nbins;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetDEDXBinningForPreciseRange(G4int nbins)
{
nDEDXBinsForRange = nbins;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetLambdaBinning(G4int nbins)
{
nLambdaBins = nbins;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VEnergyLossProcess::MinKinEnergy() const
{
return minKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetMinKinEnergy(G4double e)
{
minKinEnergy = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetMaxKinEnergy(G4double e)
{
maxKinEnergy = e;
if(e < maxKinEnergyForRange) maxKinEnergyForRange = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetMaxKinEnergyForPreciseRange(G4double e)
{
maxKinEnergyForRange = e;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4VEnergyLossProcess::MaxKinEnergy() const
{
return maxKinEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::ActivateFluorescence(G4bool, const G4Region*)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::ActivateAugerElectronProduction(G4bool, const G4Region*)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetLambdaFactor(G4double val)
{
if(val > 0.0 && val <= 1.0) lambdaFactor = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4VMultipleScattering.cc,v 1.22 2004/03/01 12:17:07 urban Exp $
// GEANT4 tag $Name: geant4-06-01 $
// $Id: G4VMultipleScattering.cc,v 1.23 2004/04/23 05:52:07 urban Exp $
// GEANT4 tag $Name: geant4-06-02 $
//
// -------------------------------------------------------------------
//
@@ -42,6 +42,7 @@
// 03-11-03 Fix initialisation problem in RetrievePhysicsTable (V.Ivanchenko)
// 04-11-03 Update PrintInfoDefinition (V.Ivanchenko)
// 01-03-04 SampleCosineTheta signature changed
// 22-04-04 SampleCosineTheta signature changed back to original
//
// Class Description:
//
@@ -180,12 +181,8 @@ G4VParticleChange* G4VMultipleScattering::PostStepDoIt(const G4Track& track,
G4double kineticEnergy = track.GetKineticEnergy();
G4double truestep = step.GetStepLength();
G4double lambda = GetLambda(track.GetDynamicParticle()->GetDefinition(),
kineticEnergy) ;
if (kineticEnergy > 0.0) {
G4double cth = currentModel->SampleCosineTheta(truestep,kineticEnergy,lambda);
G4double cth = currentModel->SampleCosineTheta(truestep,kineticEnergy);
G4double sth = sqrt(1.-cth*cth);
G4double phi = twopi*G4UniformRand();
G4double dirx = sth*cos(phi);
@@ -206,8 +203,6 @@ G4VParticleChange* G4VMultipleScattering::PostStepDoIt(const G4Track& track,
}
*/
// G4cout << "PostStep: sth= " << sth << " trueLength= " << truestep << " tLast= " << truePathLength << G4endl;
if (latDisplasment) {
G4double safety = step.GetPostStepPoint()->GetSafety();
@@ -215,8 +210,6 @@ G4VParticleChange* G4VMultipleScattering::PostStepDoIt(const G4Track& track,
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);