Import Geant4 8.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 14:36:02 +02:00
parent d93e1e39a9
commit 8a51e0bc40
5471 changed files with 99628 additions and 55248 deletions
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4EmCalculator.cc,v 1.19 2005/05/30 08:55:51 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4EmCalculator.cc,v 1.24 2005/11/26 15:33:08 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -39,6 +39,7 @@
// 17.11.2004 Change signature of methods, add new methods (V.Ivanchenko)
// 08.04.2005 Major optimisation of internal interfaces (V.Ivantchenko)
// 08.05.2005 Use updated interfaces (V.Ivantchenko)
// 23.10.2005 Fix computations for ions (V.Ivantchenko)
//
// Class Description:
//
@@ -63,6 +64,7 @@
#include "G4RegionStore.hh"
#include "G4Element.hh"
#include "G4EmCorrections.hh"
#include "G4GenericIon.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -76,6 +78,7 @@ G4EmCalculator::G4EmCalculator()
currentCouple = 0;
currentMaterial = 0;
currentParticle = 0;
baseParticle = 0;
currentLambda = 0;
chargeSquare = 1.0;
massRatio = 1.0;
@@ -106,7 +109,7 @@ G4double G4EmCalculator::GetDEDX(G4double kinEnergy, const G4ParticleDefinition*
if(couple && UpdateParticle(p, kinEnergy) ) {
res = manager->GetDEDX(p, kinEnergy, couple);
if(verbose>0) {
G4cout << "E(MeV)= " << kinEnergy/MeV
G4cout << "G4EmCalculator::GetDEDX: E(MeV)= " << kinEnergy/MeV
<< " DEDX(MeV/mm)= " << res*mm/MeV
<< " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
<< " " << p->GetParticleName()
@@ -135,7 +138,7 @@ G4double G4EmCalculator::GetRange(G4double kinEnergy, const G4ParticleDefinition
if(couple && UpdateParticle(p, kinEnergy)) {
res = manager->GetRange(p, kinEnergy, couple);
if(verbose>0) {
G4cout << "E(MeV)= " << kinEnergy/MeV
G4cout << "G4EmCalculator::GetRange: E(MeV)= " << kinEnergy/MeV
<< " range(mm)= " << res/mm
<< " " << p->GetParticleName()
<< " in " << mat->GetName()
@@ -163,7 +166,7 @@ G4double G4EmCalculator::GetKinEnergy(G4double range, const G4ParticleDefinition
if(couple && UpdateParticle(p, 1.0*GeV)) {
res = manager->GetEnergy(p, range, couple);
if(verbose>0) {
G4cout << "Range(mm)= " << range/mm
G4cout << "G4EmCalculator::GetKinEnergy: Range(mm)= " << range/mm
<< " KinE(MeV)= " << res/MeV
<< " " << p->GetParticleName()
<< " in " << mat->GetName()
@@ -261,7 +264,7 @@ G4double G4EmCalculator::GetMeanFreePath(G4double kinEnergy,
G4double x = GetCrossSectionPerVolume(kinEnergy,p, processName, mat,region);
if(x > 0.0) res = 1.0/x;
if(verbose>1) {
G4cout << "E(MeV)= " << kinEnergy/MeV
G4cout << "G4EmCalculator::GetMeanFreePath: E(MeV)= " << kinEnergy/MeV
<< " MFP(mm)= " << res/mm
<< " " << p->GetParticleName()
<< " in " << mat->GetName()
@@ -317,31 +320,38 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
const G4Material* mat,
G4double cut)
{
currentMaterial = mat;
currentMaterialName = mat->GetName();
G4double res = 0.0;
if(verbose > 1) {
G4cout << "ComputeDEDX: " << p->GetParticleName()
<< " in " << mat->GetName()
G4cout << "### G4EmCalculator::ComputeDEDX: " << p->GetParticleName()
<< " in " << currentMaterialName
<< " e(MeV)= " << kinEnergy/MeV << " cut(MeV)= " << cut/MeV << G4endl;
}
if(FindEmModel(p, processName, kinEnergy)) {
// G4cout << "currentModel= " << currentModel << G4endl;
if(UpdateParticle(p, kinEnergy)) {
G4double escaled = kinEnergy*massRatio;
G4double escaled = kinEnergy*massRatio;
if(baseParticle) {
res = currentModel->ComputeDEDXPerVolume(mat, baseParticle, escaled, cut)
* chargeSquare;
if(verbose > 1) {
G4cout << baseParticle->GetParticleName() << " E(MeV)= " << escaled
<< " DEDX(MeV/mm)= " << res*mm/MeV
<< " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
<< G4endl;
}
if(verbose > 1)
G4cout << baseParticle->GetParticleName() << " Escaled(MeV)= " << escaled;
} else {
res = currentModel->ComputeDEDXPerVolume(mat, p, kinEnergy, cut);
if(verbose > 1) G4cout << " no basePart E(MeV)= " << kinEnergy;
}
if(isIon && currentModel->HighEnergyLimit() > 100.*MeV)
if(verbose > 1)
G4cout << " DEDX(MeV/mm)= " << res*mm/MeV
<< " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
<< G4endl;
if(isIon && currentModel->HighEnergyLimit() > 100.*MeV) {
res += corr->HighOrderCorrections(p,mat,kinEnergy);
if(verbose > 1)
G4cout << "After Corrections: DEDX(MeV/mm)= " << res*mm/MeV
<< " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
<< G4endl;
}
// emulate boundary region for different parameterisations
G4double eth = currentModel->LowEnergyLimit();
if(eth > 0.05*MeV && eth < 10.*MeV && escaled > eth) {
@@ -352,7 +362,10 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
} else {
res1 = currentModel->ComputeDEDXPerVolume(mat, p, eth, cut);
}
if(isIon) res1 += corr->HighOrderCorrections(p,mat,eth/massRatio);
if(verbose > 1)
G4cout << "At boundary energy(MeV)= " << eth/MeV << " DEDX(MeV/mm)= " << res1*mm/MeV
<< G4endl;
if(isIon) res1 += corr->HighOrderCorrections(p,mat,eth/massRatio);
G4double res0 = res1;
if(FindEmModel(p, processName, eth-1.0*keV)) {
if(baseParticle) {
@@ -362,8 +375,8 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
res0 = currentModel->ComputeDEDXPerVolume(mat, p, eth, cut);
}
}
//G4cout << "eth= " << eth << " escaled= " << escaled << " res0= " << res0 << " res1= "
// << res1 << " q2= " << chargeSquare << G4endl;
//G4cout << "eth= " << eth << " escaled= " << escaled << " res0= " << res0 << " res1= "
// << res1 << " q2= " << chargeSquare << G4endl;
res *= (1.0 + (res0/res1 - 1.0)*eth/escaled);
}
if(verbose > 0) {
@@ -372,7 +385,7 @@ G4double G4EmCalculator::ComputeDEDX(G4double kinEnergy,
<< " DEDX(MeV*cm^2/g)= " << res*gram/(MeV*cm2*mat->GetDensity())
<< " cut(MeV)= " << cut/MeV
<< " " << p->GetParticleName()
<< " in " << mat->GetName()
<< " in " << currentMaterialName
<< " Zi^2= " << chargeSquare
<< G4endl;
}
@@ -429,6 +442,8 @@ G4double G4EmCalculator::ComputeCrossSectionPerVolume(
const G4Material* mat,
G4double cut)
{
currentMaterial = mat;
currentMaterialName = mat->GetName();
G4double res = 0.0;
if(FindEmModel(p, processName, kinEnergy)) {
UpdateParticle(p, kinEnergy);
@@ -546,54 +561,51 @@ G4bool G4EmCalculator::UpdateParticle(const G4ParticleDefinition* p, G4double ki
currentParticle = p;
baseParticle = 0;
currentParticleName = p->GetParticleName();
}
isApplicable = false;
if(p->GetPDGCharge() != 0.0) {
const G4VEnergyLossProcess* proc = FindEnergyLossProcess(p);
if(proc) {
isApplicable = true;
baseParticle = proc->BaseParticle();
massRatio = 1.0;
G4double qbase = 1.0;
G4double q = p->GetPDGCharge()/eplus;
if(baseParticle) {
massRatio = baseParticle->GetPDGMass()/p->GetPDGMass();
qbase = baseParticle->GetPDGCharge()/eplus;
}
if(p->GetParticleType() == "nucleus") {
isIon = true;
chargeSquare =
massRatio = 1.0;
chargeSquare = 1.0;
if(p->GetParticleType() == "nucleus" &&
currentParticleName != "deuteron" && currentParticleName != "triton") {
baseParticle = G4GenericIon::GenericIon();
massRatio = baseParticle->GetPDGMass()/p->GetPDGMass();
isIon = true;
// G4cout << p->GetParticleName() << " in " << currentMaterial->GetName()
// << " e= " << kinEnergy << G4endl;
chargeSquare =
ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy);
//G4double emax = currentModel->HighEnergyLimit(p);
//if(emax < 100.*MeV) chargeSquare *= q*q /
// ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, emax/massRatio);
//G4cout << "q2= " << chargeSquare << G4endl;
} else {
isIon = false;
const G4VEnergyLossProcess* proc = FindEnergyLossProcess(p);
if(proc) {
baseParticle = proc->BaseParticle();
} else {
isIon = false;
chargeSquare = q*q;
if(baseParticle) {
massRatio = baseParticle->GetPDGMass()/p->GetPDGMass();
G4double q = p->GetPDGCharge()/baseParticle->GetPDGCharge();
chargeSquare *= q*q;
}
}
chargeSquare /= (qbase*qbase);
}
}
return isApplicable;
if(isIon) chargeSquare =
ionEffCharge->EffectiveChargeSquareRatio(p, currentMaterial, kinEnergy);
return true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
const G4ParticleDefinition* G4EmCalculator::FindParticle(const G4String& name)
{
const G4ParticleDefinition* p = 0;
if(name != currentParticleName) {
currentParticle = G4ParticleTable::GetParticleTable()->FindParticle(name);
if(!currentParticle) {
p = G4ParticleTable::GetParticleTable()->FindParticle(name);
if(!p) {
G4cout << "### WARNING: G4EmCalculator::FindParticle fails to find " << name << G4endl;
}
currentParticleName = name;
} else {
p = currentParticle;
}
return currentParticle;
return p;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -669,11 +681,18 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
if (p != currentParticle || processName != currentName) {
currentName = processName;
currentLambda = 0;
G4String partname = p->GetParticleName();
const G4ParticleDefinition* part = p;
if(p->GetParticleType() == "nucleus" && partname != "deuteron" && partname != "triton")
part = G4GenericIon::GenericIon();
G4LossTableManager* lManager = G4LossTableManager::Instance();
const std::vector<G4VEnergyLossProcess*> vel = lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
for(G4int i=0; i<n; i++) {
if((vel[i])->GetProcessName() == currentName && (vel[i])->Particle() == p) {
if((vel[i])->GetProcessName() == currentName && (vel[i])->Particle() == part) {
currentLambda = (vel[i])->LambdaTable();
isApplicable = true;
break;
@@ -683,7 +702,7 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
const std::vector<G4VEmProcess*> vem = lManager->GetEmProcessVector();
G4int n = vem.size();
for(G4int i=0; i<n; i++) {
if((vem[i])->GetProcessName() == currentName && (vem[i])->Particle() == p) {
if((vem[i])->GetProcessName() == currentName && (vem[i])->Particle() == part) {
currentLambda = (vem[i])->LambdaTable();
isApplicable = true;
break;
@@ -694,7 +713,7 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
const std::vector<G4VMultipleScattering*> vmsc = lManager->GetMultipleScatteringVector();
G4int n = vmsc.size();
for(G4int i=0; i<n; i++) {
if((vmsc[i])->GetProcessName() == currentName && (vmsc[i])->Particle() == p) {
if((vmsc[i])->GetProcessName() == currentName && (vmsc[i])->Particle() == part) {
currentLambda = (vmsc[i])->LambdaTable();
isApplicable = true;
break;
@@ -708,14 +727,29 @@ void G4EmCalculator::FindLambdaTable(const G4ParticleDefinition* p,
G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
const G4String& processName,
G4double kinEnergy)
G4double kineticEnergy)
{
G4bool res = false;
if(verbose > 1) {
G4cout << "G4EmCalculator::FindEmModel for " << p->GetParticleName()
<< " and " << processName << " at e(MeV)= " << kinEnergy
<< G4endl;
if(!p) {
G4cout << "G4EmCalculator::FindEmModel WARNING: no particle defined" << G4endl;
return res;
}
G4String partname = p->GetParticleName();
const G4ParticleDefinition* part = p;
G4double kinEnergy = kineticEnergy;
if(p->GetParticleType() == "nucleus" && partname != "deuteron" && partname != "triton") {
part = G4GenericIon::GenericIon();
kinEnergy *= part->GetPDGMass()/p->GetPDGMass();
}
if(verbose > 1) {
G4cout << "G4EmCalculator::FindEmModel for " << partname
<< " (type= " << p->GetParticleType()
<< ") and " << processName << " at e(MeV)= " << kinEnergy;
if(p != part) G4cout << " GenericIon is the base particle";
G4cout << G4endl;
}
// Search for the process
currentName = processName;
currentModel = 0;
@@ -724,7 +758,9 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
const std::vector<G4VEnergyLossProcess*> vel = lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
for(G4int i=0; i<n; i++) {
if((vel[i])->GetProcessName() == currentName && (vel[i])->Particle() == p) {
// G4cout << "i= " << i << " part= " << (vel[i])->Particle()->GetParticleName()
// << " proc= " << (vel[i])->GetProcessName() << G4endl;
if((vel[i])->GetProcessName() == currentName && (vel[i])->Particle() == part) {
const G4ParticleDefinition* bp = (vel[i])->BaseParticle();
// G4cout << "i= " << i << " bp= " << bp << G4endl;
if(!bp) {
@@ -738,6 +774,7 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
}
}
}
// G4cout << "model= " << currentModel << G4endl;
break;
}
}
@@ -745,7 +782,7 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
const std::vector<G4VEmProcess*> vem = lManager->GetEmProcessVector();
G4int n = vem.size();
for(G4int i=0; i<n; i++) {
if((vem[i])->GetProcessName() == currentName && (vem[i])->Particle() == p) {
if((vem[i])->GetProcessName() == currentName && (vem[i])->Particle() == part) {
currentModel = (vem[i])->SelectModelForMaterial(kinEnergy, idx);
isApplicable = true;
break;
@@ -756,7 +793,7 @@ G4bool G4EmCalculator::FindEmModel(const G4ParticleDefinition* p,
const std::vector<G4VMultipleScattering*> vmsc = lManager->GetMultipleScatteringVector();
G4int n = vmsc.size();
for(G4int i=0; i<n; i++) {
if((vmsc[i])->GetProcessName() == currentName && (vmsc[i])->Particle() == p) {
if((vmsc[i])->GetProcessName() == currentName && (vmsc[i])->Particle() == part) {
currentModel = (vmsc[i])->SelectModelForMaterial(kinEnergy, idx);
isApplicable = true;
break;
@@ -773,12 +810,16 @@ const G4VEnergyLossProcess* G4EmCalculator::FindEnergyLossProcess(
const G4ParticleDefinition* p)
{
const G4VEnergyLossProcess* elp = 0;
G4String partname = p->GetParticleName();
const G4ParticleDefinition* part = p;
if(p->GetParticleType() == "nucleus" && partname != "deuteron" && partname != "triton")
part = G4GenericIon::GenericIon();
G4LossTableManager* lManager = G4LossTableManager::Instance();
const std::vector<G4VEnergyLossProcess*> vel = lManager->GetEnergyLossProcessVector();
G4int n = vel.size();
for(G4int i=0; i<n; i++) {
if((vel[i])->Particle() == p) {
if((vel[i])->Particle() == part) {
elp = vel[i];
break;
}
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4EmCorrections.cc,v 1.11 2005/06/27 15:29:41 gunter Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4EmCorrections.cc,v 1.13 2005/11/26 16:59:26 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -34,7 +34,8 @@
// Creation date: 13.01.2005
//
// Modifications:
// 05.05.2005 VI Fix misprint in Mott term
// 05.05.2005 V.Ivanchenko Fix misprint in Mott term
// 26.11.2005 V.Ivanchenko Fix effective charge for heavy ions using original paper
//
//
// Class Description:
@@ -73,6 +74,7 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
// Physical review B Vol.5 No.7 1 April 1972 pagg. 2393-2397
// and ICRU49 report
// valid for kineticEnergy < 0.5 MeV
// Other corrections from S.P.Ahlen Rev. Mod. Phys., Vol 52, No1, 1980
G4double tau = kineticEnergy / p->GetPDGMass();
if(tau <= 0.0) return 0.0;
@@ -80,8 +82,12 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
G4double gamma = 1.0 + tau;
G4double bg2 = tau * (tau+2.0);
G4double beta2 = bg2/(gamma*gamma);
G4double beta = std::sqrt(beta2);
G4double q = p->GetPDGCharge()/eplus;
if(q > 2.5) q *= (1.0 - std::exp(-130.0*beta/std::pow(q,0.66666667)));
else if(q > 1.5) q = effCharge.EffectiveCharge(p,material,kineticEnergy)/eplus;
G4double q = effCharge.EffectiveCharge(p,material,kineticEnergy)/eplus;
G4double q2 = q*q;
G4double ba = beta2/alpha2;
G4double BarkasTerm = 0.0;
@@ -89,6 +95,9 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
const G4double* atomDensity = material->GetAtomicNumDensityVector();
G4int numberOfElements = material->GetNumberOfElements();
G4double Zeff = 0.0;
G4double norm = 0.0;
for (G4int i = 0; i<numberOfElements; i++) {
G4double Z = (*theElementVector)[i]->GetZ();
@@ -122,8 +131,12 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
G4int iw = Index(W, engBarkas, 47);
val = Value(W, engBarkas[iw], engBarkas[iw+1], corBarkas[iw], corBarkas[iw+1]);
}
BarkasTerm += val*atomDensity[i] * std::sqrt(Z /X)/ X;
BarkasTerm += 1.29*val*atomDensity[i] * std::sqrt(Z /X)/ X;
Zeff += Z*atomDensity[i];
norm += atomDensity[i];
}
Zeff /= norm;
BarkasTerm *= 2.0*q;
@@ -144,8 +157,10 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
}
BlochTerm *= -2.0*y2;
G4double beta = std::sqrt(beta2);
G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
// Estimation of mean square root of the ionisation potential
G4double ze = 2.0*Zeff;
G4double ze1 = std::log(ze);
G4double eexc= material->GetIonisation()->GetMeanExcitationEnergy()*ze1*ze1/ze;
G4double invbeta = 1.0/beta;
G4double invbeta2= invbeta*invbeta;
@@ -168,7 +183,8 @@ G4double G4EmCorrections::HighOrderCorrections(const G4ParticleDefinition* p,
+ za2*za2*(4.569 - 0.494*beta2 - 2.696*invbeta2)
+ za3*za2*(1.254*beta + 0.222*invbeta - 1.17*invbeta*invbeta2);
G4double eloss = (BarkasTerm + (BlochTerm + mterm)*material->GetElectronDensity()) * q2 * twopi_mc2_rcl2 *invbeta2;
G4double eloss = (BarkasTerm + (BlochTerm + mterm)*material->GetElectronDensity()) *
q2 * twopi_mc2_rcl2 *invbeta2;
return eloss;
}
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4EmModelManager.cc,v 1.28 2005/05/13 16:54:05 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4EmModelManager.cc,v 1.31 2005/11/29 08:06:32 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -51,6 +51,8 @@
// 26-01-04 Fix in energy range conditions (V.Ivanchenko)
// 24-03-05 Remove check or IsInCharge (V.Ivanchenko)
// 08-04-05 Major optimisation of internal interfaces (V.Ivantchenko)
// 18-08-05 Fix cut for e+e- pair production (V.Ivanchenko)
// 29-11-05 Add protection for arithmetic operations with cut=DBL_MAX (V.Ivanchenko)
//
// Class Description:
//
@@ -187,7 +189,7 @@ void G4EmModelManager::AddEmModel(G4int num, G4VEmModel* p,
regions.push_back(r);
orderOfModels.push_back(num);
p->DefineForRegion(r);
if (nEmModels) {
if (nEmModels>0) {
G4int idx = nEmModels;
do {idx--;} while (idx && num < orderOfModels[idx]);
if (num >= orderOfModels[idx] && num <= orderOfModels[idx+1]) idx++;
@@ -252,10 +254,14 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
nRegions = 1;
std::vector<const G4Region*> set;
set.push_back(world);
G4bool isWorld = false;
for (G4int ii=0; ii<nEmModels; ii++) {
const G4Region* r = regions[ii];
if ( r && r != world) {
if ( r == 0 || r == world) {
isWorld = true;
regions[ii] = world;
} else {
G4bool newRegion = true;
if (nRegions>1) {
for (G4int j=1; j<nRegions; j++) {
@@ -290,38 +296,49 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
eLow.clear();
eHigh.clear();
for (G4int ii=0; ii<nEmModels; ii++) {
if(isWorld || 0 < reg) {
G4VEmModel* model = models[ii];
if ( 0 == regions[ii] || region == regions[ii] ) {
for (G4int ii=0; ii<nEmModels; ii++) {
G4double tmin = model->LowEnergyLimit();
G4double tmax = model->HighEnergyLimit();
if (n>0) tmin = std::max(tmin, eHigh[n-1]);
G4VEmModel* model = models[ii];
if ( region == regions[ii] ) {
if(1 < verboseLevel) {
G4cout << "Model # " << ii << " for region <";
if (region) G4cout << region->GetName();
G4cout << "> "
G4double tmin = model->LowEnergyLimit();
G4double tmax = model->HighEnergyLimit();
if (n>0) tmin = std::max(tmin, eHigh[n-1]);
if(1 < verboseLevel) {
G4cout << "Model #" << ii << " <" << model->GetName() << "> for region <";
if (region) G4cout << region->GetName();
G4cout << "> "
<< " tmin(MeV)= " << tmin/MeV
<< "; tmax(MeV)= " << tmax/MeV
<< "; order= " << orderOfModels[ii]
<< G4endl;
}
}
if (tmin < tmax) {
modelAtRegion.push_back(ii);
eLow.push_back(tmin);
eHigh.push_back(tmax);
upperEkin[ii] = tmax;
n++;
if (tmin < tmax) {
modelAtRegion.push_back(ii);
eLow.push_back(tmin);
eHigh.push_back(tmax);
upperEkin[ii] = tmax;
n++;
}
}
}
} else {
n = 1;
models.push_back(0);
modelAtRegion.push_back(nEmModels);
eLow.push_back(0.0);
eHigh.push_back(DBL_MAX);
upperEkin.push_back(DBL_MAX);
}
eLow[0] = 0.0;
if(1 < verboseLevel) {
G4cout << "New G4RegionModels set with " << n << " models for region <";
if (region) G4cout << region->GetName();
if (region) G4cout << region->GetName();
G4cout << "> Elow(MeV)= ";
for(G4int ii=0; ii<n; ii++) {G4cout << eLow[ii]/MeV << " ";}
G4cout << G4endl;
@@ -337,6 +354,7 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
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;
@@ -349,13 +367,15 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
<< G4endl;
}
G4double cut = 0.0;
G4double subcut = 0.0;
G4double cut = DBL_MAX;
G4double subcut = DBL_MAX;
if(secondaryParticle) {
size_t idx = 1;
if( secondaryParticle == G4Gamma::Gamma() ) idx = 0;
cut = (*theCoupleTable->GetEnergyCutsVector(idx))[i];
subcut = minSubRange*cut;
if( secondaryParticle == G4Positron::Positron() && cut < DBL_MAX )
cut += (*theCoupleTable->GetEnergyCutsVector(2))[i] + 2.0*electron_mass_c2;
if( cut < DBL_MAX ) subcut = minSubRange*cut;
}
G4int nm = setOfRegionModels[reg]->NumberOfModels();
@@ -366,12 +386,12 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
G4double tcutmin = model->MinEnergyCut(particle, couple);
cut = std::max(cut, tcutmin);
G4double x = std::max(cut*minSubRange, tcutmin);
subcut = std::max(subcut, x);
subcut = std::max(subcut, tcutmin);
if(1 < verboseLevel) {
G4cout << "The model # " << j
<< "; tcutmin(MeV)= " << tcutmin/MeV
<< "; tcut(MeV)= " << cut/MeV
<< "; tsubcut(MeV)= " << subcut/MeV
<< G4endl;
}
}
@@ -442,7 +462,9 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
dedxLow[0] = 0.0;
e = upperEkin[regModels->ModelIndex(0)];
dedxHigh[0] = models[regModels->ModelIndex(0)]->ComputeDEDX(couple,particle,e,cut);
G4VEmModel* model = models[regModels->ModelIndex(0)];
dedxHigh[0] = 0.0;
if(model) dedxHigh[0] = model->ComputeDEDX(couple,particle,e,cut);
if(nmod > 1) {
for(j=1; j<nmod; j++) {
@@ -478,7 +500,9 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
} while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
}
G4double dedx = models[regModels->ModelIndex(k)]->ComputeDEDX(couple,particle,e,cut)*fac;
model = models[regModels->ModelIndex(k)];
G4double dedx = 0.0;
if(model) dedx = model->ComputeDEDX(couple,particle,e,cut)*fac;
if(dedx < 0.0) dedx = 0.0;
if(2 < verboseLevel) {
@@ -510,7 +534,7 @@ void G4EmModelManager::FillDEDXVectorForPreciseRange(
size_t i = couple->GetIndex();
if(2 < verboseLevel) {
G4cout << "G4EmModelManager::FillDEDXVector() for "
G4cout << "G4EmModelManager::FillDEDXVectorForPreciseRange() for "
<< couple->GetMaterial()->GetName()
<< G4endl;
}
@@ -540,7 +564,9 @@ void G4EmModelManager::FillDEDXVectorForPreciseRange(
dedxLow[0] = 0.0;
e = upperEkin[regModels->ModelIndex(0)];
dedxHigh[0] = models[regModels->ModelIndex(0)]->ComputeDEDX(couple,particle,e,e);
G4VEmModel* model = models[regModels->ModelIndex(0)];
dedxHigh[0] = 0.0;
if(model) dedxHigh[0] = model->ComputeDEDX(couple,particle,e,e);
if(nmod > 1) {
for(j=1; j<nmod; j++) {
@@ -576,7 +602,9 @@ void G4EmModelManager::FillDEDXVectorForPreciseRange(
} while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
}
G4double dedx = models[regModels->ModelIndex(k)]->ComputeDEDX(couple,particle,e,e)*fac;
model = models[regModels->ModelIndex(k)];
G4double dedx = 0.0;
if(model) dedx = model->ComputeDEDX(couple,particle,e,e)*fac;
if(dedx < 0.0) dedx = 0.0;
if(2 < verboseLevel) {
@@ -635,7 +663,9 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
sigmaLow[0] = 0.0;
e = upperEkin[regModels->ModelIndex(0)];
sigmaHigh[0] = models[regModels->ModelIndex(0)]->CrossSection(couple,particle,e,cut,e);
G4VEmModel* model = models[regModels->ModelIndex(0)];
sigmaHigh[0] = 0.0;
if(model) sigmaHigh[0] = model->CrossSection(couple,particle,e,cut,e);
if(2 < verboseLevel) {
G4cout << "### For material " << couple->GetMaterial()->GetName()
@@ -685,7 +715,9 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
} while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
}
G4double cross = models[regModels->ModelIndex(k)]->CrossSection(couple,particle,e,cut,e)*fac;
model = models[regModels->ModelIndex(k)];
G4double cross = 0.0;
if(model) cross = model->CrossSection(couple,particle,e,cut,e)*fac;
if(j==0 && startFromNull) cross = 0.0;
if(2 < verboseLevel) {
@@ -707,7 +739,7 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
G4bool startFromNull)
{
if(1 < verboseLevel) {
G4cout << "G4EmModelManager::BuildLambdaSubTable() for particle "
G4cout << "G4EmModelManager::FillSubLambdaTable() for particle "
<< particle->GetParticleName() << G4endl;
}
@@ -730,7 +762,7 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
sigmaLow.resize(nmod);
sigmaHigh.resize(nmod);
if(0 < verboseLevel) {
if(2 < verboseLevel) {
G4cout << "There are " << nmod << " models for "
<< couple->GetMaterial()->GetName() << G4endl;
}
@@ -754,7 +786,9 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
<< G4endl;
}
sigmaHigh[0] = models[regModels->ModelIndex(0)]->CrossSection(couple,particle,e,subcut,cut);
G4VEmModel* model = models[regModels->ModelIndex(0)];
sigmaHigh[0] = 0.0;
if(model) sigmaHigh[0] = model->CrossSection(couple,particle,e,subcut,cut);
if(nmod > 1) {
@@ -786,7 +820,9 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
} while (k<nmod-1 && e > upperEkin[regModels->ModelIndex(k)] );
}
G4double cross=models[regModels->ModelIndex(k)]->CrossSection(couple,particle,e,subcut,cut)*fac;
model = models[regModels->ModelIndex(k)];
G4double cross = 0.0;
if(model) cross = model->CrossSection(couple,particle,e,subcut,cut)*fac;
if(j==0 && startFromNull) cross = 0.0;
if(2 < verboseLevel) {
@@ -21,7 +21,7 @@
// ********************************************************************
//
// $Id: G4EmMultiModel.cc,v 1.4 2005/04/15 11:40:46 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4EmProcessOptions.cc,v 1.7 2005/05/03 08:09:34 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4EmProcessOptions.cc,v 1.11 2005/12/05 12:13:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -80,14 +80,14 @@ void G4EmProcessOptions::SetLossFluctuations(G4bool val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetSubCutoff(G4bool val)
void G4EmProcessOptions::SetSubCutoff(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->SetSubCutoff(val);
if(p) p->ActivateSubCutoff(val, r);
}
}
@@ -330,6 +330,9 @@ void G4EmProcessOptions::SetVerbose(G4int val, const G4String& name)
if("all" == name) all = true;
const std::vector<G4VEnergyLossProcess*>& v =
theManager->GetEnergyLossProcessVector();
if(all) theManager->SetVerbose(val);
std::vector<G4VEnergyLossProcess*>::const_iterator itr;
for(itr = v.begin(); itr != v.end(); itr++) {
G4VEnergyLossProcess* p = *itr;
@@ -397,3 +400,16 @@ void G4EmProcessOptions::ActivateDeexcitation(G4bool val, const G4Region* r)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4EmProcessOptions::SetMscStepLimitation(G4bool algorithm, G4double factor)
{
const std::vector<G4VMultipleScattering*>& u =
theManager->GetMultipleScatteringVector();
std::vector<G4VMultipleScattering*>::const_iterator itm;
for(itm = u.begin(); itm != u.end(); itm++) {
G4VMultipleScattering* s = *itm;
if(s) s->MscStepLimitation(algorithm, factor);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4EnergyLossMessenger.cc,v 1.11 2003/10/13 10:49:18 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4EnergyLossMessenger.cc,v 1.12 2005/11/11 23:28:56 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
//
@@ -41,7 +41,7 @@
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include <strstream>
#include <sstream>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -172,11 +172,9 @@ void G4EnergyLossMessenger::SetNewValue(G4UIcommand* command,G4String newValue)
if (command == StepFuncCmd)
{
G4double v1,v2;
char unts[30];
const char* t = newValue;
std::istrstream is((char*)t);
is >> v1 >> v2 >> unts;
G4String unt = unts;
G4String unt;
std::istringstream is(newValue);
is >> v1 >> v2 >> unt;
v2 *= G4UIcommand::ValueOf(unt);
G4VEnergyLoss::SetStepFunction(v1,v2);
lossTables->SetStepLimits(v1,v2);
@@ -22,7 +22,7 @@
//
//
// $Id: G4EnergyLossTables.cc,v 1.32 2004/12/01 18:01:01 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
// first version created by P.Urban , 06/04/1998
@@ -21,7 +21,7 @@
// ********************************************************************
//
// $Id: G4LossTableBuilder.cc,v 1.17 2005/04/12 18:13:04 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4LossTableManager.cc,v 1.58 2005/05/27 18:38:33 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4LossTableManager.cc,v 1.61 2005/10/27 15:05:39 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -179,7 +179,7 @@ void G4LossTableManager::Register(G4VEnergyLossProcess* p)
tables_are_built.push_back(false);
all_tables_are_built = false;
if(!lossFluctuationFlag) p->SetLossFluctuations(false);
if(subCutoffFlag) p->SetSubCutoff(true);
if(subCutoffFlag) p->ActivateSubCutoff(true);
if(stepFunctionActive) p->SetStepFunction(maxRangeVariation, maxFinalStep);
if(integralActive) p->SetIntegral(integral);
if(minEnergyActive) p->SetMinKinEnergy(minKinEnergy);
@@ -488,11 +488,11 @@ G4VEnergyLossProcess* G4LossTableManager::BuildTables(const G4ParticleDefinition
loss_map[aParticle] = em;
for (G4int j=0; j<n_dedx; j++) {
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);
G4VEnergyLossProcess* p = loss_list[j];
p->SetLambdaTable(p->BuildLambdaTable());
if (0 < p->NumberOfSubCutoffRegions()) {
p->SetSubLambdaTable(p->BuildLambdaSubTable());
if( p != em) em->AddCollaborativeProcess(p);
}
}
if (1 < verbose) {
@@ -520,7 +520,7 @@ void G4LossTableManager::SetSubCutoff(G4bool val)
{
subCutoffFlag = val;
for(G4int i=0; i<n_loss; i++) {
if(loss_vector[i]) loss_vector[i]->SetSubCutoff(val);
if(loss_vector[i]) loss_vector[i]->ActivateSubCutoff(val);
}
}
@@ -0,0 +1,60 @@
//
// ********************************************************************
// * 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: G4VEmFluctuationModel.cc,v 1.1 2005/07/25 18:14:26 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4VEmFluctuationModel
//
// Author: Vladimir Ivanchenko
//
// Creation date: 25.07.2005
//
// Modifications:
//
//
// Class Description:
//
// Abstract class for interface to simualtion of energy loss fluctuations
// -------------------------------------------------------------------
//
#include "G4VEmFluctuationModel.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmFluctuationModel::G4VEmFluctuationModel(const G4String& nam)
: name(nam)
{}
G4VEmFluctuationModel::~G4VEmFluctuationModel()
{}
@@ -0,0 +1,82 @@
//
// ********************************************************************
// * 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: G4VEmModel.cc,v 1.3 2005/10/25 18:28:58 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4VEmModel
//
// Author: Vladimir Ivanchenko
//
// Creation date: 25.07.2005
//
// Modifications:
// 25.10.2005 Set default highLimit=100.TeV (V.Ivanchenko)
//
//
// Class Description:
//
// Abstract interface to energy loss models
// -------------------------------------------------------------------
//
#include "G4VEmModel.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEmModel::G4VEmModel(const G4String& nam):
lowLimit(0.1*keV), highLimit(100.0*TeV), fluc(0), name(nam), pParticleChange(0)
{}
G4VEmModel::~G4VEmModel()
{}
G4double G4VEmModel::CrossSectionPerVolume(
const G4Material* material,
const G4ParticleDefinition* p,
G4double ekin,
G4double emin,
G4double emax)
{
G4double cross = 0.0;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetVecNbOfAtomsPerVolume();
size_t nelm = material->GetNumberOfElements();
for (size_t i=0; i<nelm; i++) {
const G4Element* elm = (*theElementVector)[i];
cross += theAtomNumDensityVector[i]*
ComputeCrossSectionPerAtom(p,ekin,elm->GetZ(),elm->GetN(),emin,emax);
xsec[i] = cross;
}
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4VEmProcess.cc,v 1.30 2005/05/30 08:22:38 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4VEmProcess.cc,v 1.32 2005/09/04 17:03:53 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -40,8 +40,10 @@
// 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivanchenko)
// 11-03-05 Shift verbose level by 1, add applyCuts and killPrimary flags (V.Ivanchenko)
// 14-03-05 Update logic PostStepDoIt (V.Ivanchenko)
// 08-04-05 Major optimisation of internal interfaces (V.Ivantchenko)
// 18-04-05 Use G4ParticleChangeForGamma (V.Ivantchenko)
// 08-04-05 Major optimisation of internal interfaces (V.Ivanchenko)
// 18-04-05 Use G4ParticleChangeForGamma (V.Ivanchenko)
// 25-07-05 Add protection: integral mode only for charged particles (V.Ivanchenko)
// 04-09-05 default lambdaFactor 0.8 (V.Ivanchenko)
//
//
// Class Description:
@@ -81,7 +83,7 @@ G4VEmProcess::G4VEmProcess(const G4String& name, G4ProcessType type):
particle(0),
secondaryParticle(0),
nLambdaBins(90),
lambdaFactor(0.1),
lambdaFactor(0.8),
currentCouple(0),
integral(false),
meanFreePath(true),
@@ -338,6 +340,9 @@ void G4VEmProcess::PrintInfoDefinition()
if(verboseLevel > 0) {
G4cout << G4endl << GetProcessName() << ": " ;
PrintInfo();
if(integral) {
G4cout << " Integral mode is used "<< G4endl;
}
}
if (!buildLambdaTable) return;
@@ -570,7 +575,7 @@ const G4PhysicsTable* G4VEmProcess::LambdaTable() const
void G4VEmProcess::SetIntegral(G4bool val)
{
integral = val;
if(particle && particle != theGamma) integral = val;
if(integral) buildLambdaTable = true;
}
@@ -22,7 +22,7 @@
//
//
// $Id: G4VEnergyLoss.cc,v 1.45 2004/12/01 18:01:01 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// GEANT4 tag $Name: geant4-08-00 $
//
// --------------------------------------------------------------
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4VEnergyLossProcess.cc,v 1.57 2005/05/27 18:38:33 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4VEnergyLossProcess.cc,v 1.69 2005/10/27 14:04:35 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -81,6 +81,13 @@
// 11-03-05 Shift verbose level by 1 (V.Ivantchenko)
// 08-04-05 Major optimisation of internal interfaces (V.Ivantchenko)
// 11-04-05 Use MaxSecondaryEnergy from a model (V.Ivanchenko)
// 25-07-05 Add extra protection PostStep for non-integral mode (V.Ivanchenko)
// 12-08-05 Integral=false; SetStepFunction(0.2, 0.1*mm) (mma)
// 18-08-05 Return back both AlongStep and PostStep from 7.0 (V.Ivanchenko)
// 02-09-05 Default StepFunction 0.2 1 mm + integral (V.Ivanchenko)
// 04-09-05 default lambdaFactor 0.8 (V.Ivanchenko)
// 05-10-05 protection against 0 energy loss added (L.Urban)
// 17-10-05 protection above has been removed (L.Urban)
//
// Class Description:
//
@@ -109,7 +116,6 @@
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Proton.hh"
#include "G4VSubCutoffProcessor.hh"
#include "G4ProcessManager.hh"
#include "G4UnitsTable.hh"
#include "G4GenericIon.hh"
@@ -117,13 +123,16 @@
#include "G4Region.hh"
#include "G4RegionStore.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4Navigator.hh"
#include "G4TransportationManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name, G4ProcessType type):
G4VContinuousDiscreteProcess(name, type),
G4VContinuousDiscreteProcess(name, type),
nSCoffRegions(0),
idxSCoffRegions(0),
nProcesses(0),
theDEDXTable(0),
theRangeTableForLoss(0),
theDEDXunRestrictedTable(0),
@@ -143,11 +152,10 @@ G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name, G4ProcessType t
nDEDXBins(90),
nDEDXBinsForRange(70),
nLambdaBins(90),
nWarnings(0),
linLossLimit(0.05),
minSubRange(0.1),
defaultRoverRange(0.2),
defaultIntegralRange(1.0),
lambdaFactor(0.1),
lambdaFactor(0.8),
mfpKinEnergy(0.0),
lossFluctuationFlag(true),
lossFluctuationArePossible(true),
@@ -156,7 +164,8 @@ G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name, G4ProcessType t
integral(true),
meanFreePath(false),
aboveCSmax(true),
isIonisation(true)
isIonisation(true),
useSubCutoff(false)
{
lowestKinEnergy = 1.*eV;
@@ -167,13 +176,17 @@ G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name, G4ProcessType t
pParticleChange = &fParticleChange;
// default dRoverRange and finalRange
SetStepFunction(defaultIntegralRange, 1.0*mm);
SetStepFunction(0.2, 1.0*mm);
SetVerboseLevel(1);
thePositron = G4Positron::Positron();
modelManager = new G4EmModelManager();
(G4LossTableManager::Instance())->Register(this);
scoffProcessors.clear();
scoffRegions.clear();
scProcesses.clear();
navigator = (G4TransportationManager::GetTransportationManager())
->GetNavigatorForTracking();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -193,18 +206,6 @@ G4VEnergyLossProcess::~G4VEnergyLossProcess()
if(theSubLambdaTable) theSubLambdaTable->clearAndDestroy();
}
if (nSCoffRegions) {
for (G4int i=0; i<nSCoffRegions; i++) {
if (scoffProcessors[i]) {
for (G4int j=i+1; j<nSCoffRegions; j++) {
if(scoffProcessors[i] == scoffProcessors[j]) scoffProcessors[j] = 0;
}
delete scoffProcessors[i];
}
}
scoffProcessors.clear();
scoffRegions.clear();
}
delete modelManager;
(G4LossTableManager::Instance())->DeRegister(this);
}
@@ -221,12 +222,16 @@ void G4VEnergyLossProcess::Clear()
if(theRangeAtMaxEnergy) delete [] theRangeAtMaxEnergy;
if(theEnergyOfCrossSectionMax) delete [] theEnergyOfCrossSectionMax;
if(theCrossSectionMax) delete [] theCrossSectionMax;
if(idxSCoffRegions) delete [] idxSCoffRegions;
theDEDXAtMaxEnergy = 0;
theRangeAtMaxEnergy = 0;
theEnergyOfCrossSectionMax = 0,
theCrossSectionMax = 0,
theEnergyOfCrossSectionMax = 0;
theCrossSectionMax = 0;
tablesAreBuilt = false;
scTracks.clear();
scProcesses.clear();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -281,7 +286,7 @@ void G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
theRangeTableForLoss = G4PhysicsTableHelper::PreparePhysicsTable(theRangeTableForLoss);
theInverseRangeTable = G4PhysicsTableHelper::PreparePhysicsTable(theInverseRangeTable);
}
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
if (nSCoffRegions)
theSubLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theSubLambdaTable);
}
@@ -303,26 +308,23 @@ void G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
theCuts = modelManager->Initialise(particle, secondaryParticle, minSubRange, verboseLevel);
// Sub Cutoff Regime
if (nSCoffRegions>0) {
theSubCuts = modelManager->SubCutoff();
idxSCoffRegions.clear();
const G4ProductionCutsTable* theCoupleTable=
const G4ProductionCutsTable* theCoupleTable=
G4ProductionCutsTable::GetProductionCutsTable();
size_t numOfCouples = theCoupleTable->GetTableSize();
if (nSCoffRegions) {
const G4DataVector* theSubCuts = modelManager->SubCutoff();
for (G4int i=0; i<nSCoffRegions; i++) {
scoffProcessors[i]->Initialise(particle, secondaryParticle, theCuts, theSubCuts);
}
size_t numOfCouples = theCoupleTable->GetTableSize();
idxSCoffRegions = new G4int[numOfCouples];
for (size_t j=0; j<numOfCouples; j++) {
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(j);
const G4ProductionCuts* pcuts = couple->GetProductionCuts();
G4int reg = nSCoffRegions;
do {reg--;} while (reg && pcuts != (scoffRegions[reg]->GetProductionCuts()));
idxSCoffRegions.push_back(reg);
G4int reg = 0;
for(G4int i=0; i<nSCoffRegions; i++) {
if( pcuts == scoffRegions[i]->GetProductionCuts()) reg = 1;
}
idxSCoffRegions[j] = reg;
}
}
@@ -392,28 +394,22 @@ void G4VEnergyLossProcess::UpdateEmModel(const G4String& nam, G4double emin, G4d
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::AddSubCutoffProcessor(G4VSubCutoffProcessor* p,
const G4Region* r)
void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r)
{
if( !p ) {
G4cout << "G4VEnergyLossProcess::AddSubCutoffProcessor WARNING: no SubCutoffProcessor defined."
<< G4endl;
return;
}
G4RegionStore* regionStore = G4RegionStore::GetInstance();
if (!r) r = regionStore->GetRegion("DefaultRegionForTheWorld", false);
if (nSCoffRegions) {
for (G4int i=0; i<nSCoffRegions; i++) {
if (r == scoffRegions[i]) {
if ( scoffProcessors[i] ) delete scoffProcessors[i];
scoffProcessors[i] = p;
return;
if(val) {
if (!r) r = regionStore->GetRegion("DefaultRegionForTheWorld", false);
if (nSCoffRegions) {
for (G4int i=0; i<nSCoffRegions; i++) {
if (r == scoffRegions[i]) return;
}
}
scoffRegions.push_back(r);
nSCoffRegions++;
useSubCutoff = true;
} else {
useSubCutoff = false;
}
scoffProcessors.push_back(p);
scoffRegions.push_back(r);
nSCoffRegions++;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -614,10 +610,11 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
<< GetProcessName() << " and particle "
<< d->GetParticleName()
<< " eScaled(MeV)= " << preStepScaledEnergy/MeV
<< " slim(mm)= " << fRange/mm
<< " range(mm)= " << fRange/mm
<< " s(mm)= " << length/mm
<< " q^2= " << chargeSqRatio
<< " md= " << d->GetPDGMass()
<< " status= " << track.GetTrackStatus()
<< G4endl;
}
*/
@@ -644,126 +641,241 @@ G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
}
eloss = (ScaledKinEnergyForLoss(r) - ScaledKinEnergyForLoss(x))/massRatio;
/*
if(-1 < verboseLevel) {
/*
if(-1 < verboseLevel && eloss == 0.0) {
G4cout << "Long STEP: rPre(mm)= " << r/mm
<< " rPost(mm)= " << x/mm
<< " ePre(MeV)= " << preStepScaledEnergy/MeV
<< " eloss(MeV)= " << eloss/MeV
<< " eloss0(MeV)= "
<< " eloss0(MeV)= "
<< GetDEDXForScaledEnergy(preStepScaledEnergy)*length/MeV
<< G4endl;
}
*/
*/
}
const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
G4VEmModel* currentModel = SelectModel(preStepScaledEnergy);
G4double tmax = currentModel->MaxSecondaryKinEnergy(dynParticle);
tmax = std::min(tmax,(*theCuts)[currentMaterialIndex]);
/*
G4double eloss0 = eloss;
if(-1 < verboseLevel) {
/*
// G4double eloss0 = eloss;
if(-1 < verboseLevel && eloss == 0.0) {
G4cout << "Before fluct: eloss(MeV)= " << eloss/MeV
<< " tmax= " << tmax
<< " e-eloss= " << preStepKinEnergy-eloss
<< " fluct= " << lossFluctuationFlag
<< " step(mm)= " << length/mm
<< " range(mm)= " << fRange/mm
<< " fluct= " << lossFluctuationFlag
<< G4endl;
}
*/
*/
// Corrections, which cannot be tabulated
CorrectionsAlongStep(currentCouple, dynParticle, eloss, length);
// Sample fluctuations
if (lossFluctuationFlag && eloss < preStepKinEnergy) {
if (lossFluctuationFlag && eloss + lowestKinEnergy < preStepKinEnergy) {
G4double tmax = std::min(currentModel->MaxSecondaryKinEnergy(dynParticle),
(*theCuts)[currentMaterialIndex]);
eloss = currentModel->GetModelOfFluctuations()->
SampleFluctuations(currentMaterial,dynParticle,tmax,length,eloss);
}
/*
if(-1 < verboseLevel) {
G4cout << "After fluct: eloss(MeV)= " << eloss/MeV
<< " fluc= " << (eloss-eloss0)/MeV
<< " currentChargeSquare= " << chargeSquare
<< " massRatio= " << massRatio
<< G4endl;
}
if(-1 < verboseLevel) {
G4cout << "After fluct: eloss(MeV)= " << eloss/MeV
<< " fluc= " << (eloss-eloss0)/MeV
<< " currentChargeSquare= " << chargeSquare
<< " massRatio= " << massRatio
<< " tmax= " << tmax
<< G4endl;
}
*/
}
// Corrections, which cannot be tabulated
CorrectionsAlongStep(currentCouple, dynParticle, eloss, length);
G4double finalT = preStepKinEnergy - eloss;
if (finalT <= lowestKinEnergy) finalT = 0.0;
eloss = preStepKinEnergy-finalT;
if (finalT <= lowestKinEnergy) {
eloss += finalT;
finalT = 0.0;
}
// SubCutOff
if(useSubCutoff) {
if(idxSCoffRegions[currentMaterialIndex]) {
G4double preSafety = step.GetPreStepPoint()->GetSafety();
G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(0);
if(preSafety - length < rcut) {
G4double postSafety =
navigator->ComputeSafety(step.GetPostStepPoint()->GetPosition());
if(std::min(preSafety, postSafety) < rcut) {
SampleSubCutSecondaries(scTracks, step, eloss, currentModel);
if(nProcesses) {
for(G4int i=0; i<nProcesses; i++) {
(scProcesses[i])->AddSubCutoffSecondaries(scTracks, step,
eloss, preStepScaledEnergy);
}
}
G4int n = scTracks.size();
if(n) {
fParticleChange.SetNumberOfSecondaries(n);
for(G4int i=0; i<n; i++) {
pParticleChange->AddSecondary(scTracks[i]);
}
scTracks.clear();
}
}
}
}
}
// Energy balanse
fParticleChange.SetProposedKineticEnergy(finalT);
fParticleChange.ProposeLocalEnergyDeposit(eloss);
/*
if(-1 < verboseLevel) {
/*
if(-1 < verboseLevel && eloss == 0.0) {
G4cout << "Final value eloss(MeV)= " << eloss/MeV
<< " preStepKinEnergy= " << preStepKinEnergy
<< " postStepKinEnergy= " << finalT
<< " lossFlag= " << lossFluctuationFlag
<< " status= " << track.GetTrackStatus()
<< G4endl;
}
*/
*/
return &fParticleChange;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SampleSubCutSecondaries(std::vector<G4Track*>& tracks,
const G4Step& step,
G4double& eloss,
G4VEmModel* model)
{
G4double subcut = (*theSubCuts)[currentMaterialIndex];
if(eloss < subcut) return;
G4bool b;
G4double cross = chargeSqRatio*(((*theSubLambdaTable)[currentMaterialIndex])->
GetValue(preStepScaledEnergy, b));
if(cross <= 0.0) return;
G4StepPoint* preStepPoint = step.GetPreStepPoint();
G4double length = step.GetStepLength();
G4ThreeVector prepoint = preStepPoint->GetPosition();
G4ThreeVector dr = step.GetPostStepPoint()->GetPosition() - prepoint;
G4double pretime = preStepPoint->GetGlobalTime();
G4double dt = length/preStepPoint->GetVelocity();
G4double fragment = 0.0;
const G4Track* track = step.GetTrack();
const G4DynamicParticle* dp = track->GetDynamicParticle();
const G4TouchableHandle& hand = track->GetTouchableHandle();
G4double cut = (*theCuts)[currentMaterialIndex];
do {
G4double del = -std::log(G4UniformRand())/cross;
fragment += del/length;
if (fragment > 1.0) break;
std::vector<G4DynamicParticle*>* newp =
model->SampleSecondaries(currentCouple, dp, subcut, cut);
if (newp) {
G4DynamicParticle* p;
G4int nNew = newp->size();
for (G4int i=0; i<nNew; i++) {
p = (*newp)[i];
G4double e = p->GetKineticEnergy();
if (p->GetDefinition() == thePositron) e += electron_mass_c2;
if (e <= eloss) {
eloss -= e;
G4ThreeVector r = prepoint + fragment*dr;
G4Track* t = new G4Track(p, pretime + fragment*dt, r);
t->SetTouchableHandle(hand);
tracks.push_back(t);
} else {
delete p;
}
}
delete newp;
}
} while (fragment < 1.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
const G4Step& step)
const G4Step& step)
{
fParticleChange.InitializeForPostStep(track);
G4double finalT = track.GetKineticEnergy();
G4double postStepScaledEnergy = finalT*massRatio;
if(finalT == 0.0) return &fParticleChange;
G4double postStepScaledEnergy = finalT*massRatio;
/*
if(-1 < verboseLevel) {
G4cout << GetProcessName()
<< "::PostStepDoIt: E(MeV)= " << finalT/MeV
<< G4endl;
}
*/
// Integral approach
if (integral) {
G4double lx = GetLambdaForScaledEnergy(postStepScaledEnergy);
if(preStepLambda<lx && 1 < verboseLevel) {
G4cout << "WARING: for " << particle->GetParticleName()
/*
if(preStepLambda<lx && 1 < verboseLevel && nWarnings<200) {
G4cout << "WARNING: for " << particle->GetParticleName()
<< " and " << GetProcessName()
<< " E(MeV)= " << finalT/MeV
<< " preLambda= " << preStepLambda << " < " << lx << " (postLambda) "
<< G4endl;
nWarnings++;
}
*/
if(preStepLambda*G4UniformRand() > lx)
return G4VContinuousDiscreteProcess::PostStepDoIt(track,step);
}
G4VEmModel* currentModel = SelectModel(postStepScaledEnergy);
G4double tmax = (*theCuts)[currentMaterialIndex];
const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
G4double tcut = (*theCuts)[currentMaterialIndex];
G4double tmax = currentModel->MaxSecondaryKinEnergy(dynParticle);
std::vector<G4DynamicParticle*>* newp = SecondariesPostStep(
currentModel, currentCouple, track.GetDynamicParticle(), tmax);
if (tcut < tmax) {
std::vector<G4DynamicParticle*>* newp = SecondariesPostStep(
currentModel, currentCouple, dynParticle, tcut);
if (newp) {
G4int num = newp->size();
fParticleChange.SetNumberOfSecondaries(num);
for (G4int i=0; i<num; i++) {
fParticleChange.AddSecondary((*newp)[i]);
if(newp) {
G4int num = newp->size();
fParticleChange.SetNumberOfSecondaries(num);
for (G4int i=0; i<num; i++) {
fParticleChange.AddSecondary((*newp)[i]);
}
delete newp;
}
delete newp;
finalT = fParticleChange.GetProposedKineticEnergy();
}
/*
if(-1 < verboseLevel) {
const G4ParticleDefinition* pd = track.GetDynamicParticle()->GetDefinition();
G4cout << GetProcessName()
<< "::PostStepDoIt: Sample secondary; E= " << finalT/MeV
<< " MeV; model= (" << currentModel->LowEnergyLimit(pd)
<< ", " << currentModel->HighEnergyLimit(pd) << ")"
G4cout << "::PostStepDoIt: Sample secondary; Efin= " << finalT/MeV
<< " MeV; model= (" << currentModel->LowEnergyLimit()
<< ", " << currentModel->HighEnergyLimit() << ")"
<< " preStepLambda= " << preStepLambda
<< " dir= " << track.GetMomentumDirection()
<< " status= " << track.GetTrackStatus()
<< G4endl;
}
*/
finalT = fParticleChange.GetProposedKineticEnergy();
if (finalT <= lowestKinEnergy) {
fParticleChange.SetProposedKineticEnergy(0.0);
return &fParticleChange;
@@ -789,17 +901,19 @@ void G4VEnergyLossProcess::PrintInfoDefinition()
<< " in " << nLambdaBins << " bins."
<< G4endl;
PrintInfo();
if(theRangeTableForLoss) {
if(theRangeTableForLoss)
G4cout << " Step function: finalRange(mm)= " << finalRange/mm
<< ", dRoverRange= " << dRoverRange
<< ", integral: " << integral
<< G4endl;
}
if(thePreciseRangeTable) {
if(thePreciseRangeTable)
G4cout << " Precise range table up"
<< " to " << G4BestUnit(maxKinEnergyForRange,"Energy")
<< " in " << nDEDXBinsForRange << " bins." << G4endl;
}
if(nSCoffRegions>0)
G4cout << " Subcutoff sampling in " << nSCoffRegions << " regions" << G4endl;
if(2 < verboseLevel) {
G4cout << "DEDXTable address= " << theDEDXTable << G4endl;
@@ -954,12 +1068,6 @@ void G4VEnergyLossProcess::SetLambdaTable(G4PhysicsTable* p)
void G4VEnergyLossProcess::SetSubLambdaTable(G4PhysicsTable* p)
{
if(theSubLambdaTable != p) theSubLambdaTable = p;
if (nSCoffRegions) {
for (G4int i=0; i<nSCoffRegions; i++) {
scoffProcessors[i]->SetLambdaSubTable(theSubLambdaTable);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -998,7 +1106,13 @@ G4PhysicsVector* G4VEnergyLossProcess::LambdaPhysicsVector(const G4MaterialCutsC
G4PhysicsVector* G4VEnergyLossProcess::SubLambdaPhysicsVector(const G4MaterialCutsCouple* couple)
{
return LambdaPhysicsVector(couple);
G4double cut = (*theSubCuts)[couple->GetIndex()];
G4int nbins = nLambdaBins;
G4double tmin = std::max(MinPrimaryEnergy(particle, couple->GetMaterial(), cut),
minKinEnergy);
if(tmin >= maxKinEnergy) tmin = 0.5*maxKinEnergy;
G4PhysicsVector* v = new G4PhysicsLogVector(tmin, maxKinEnergy, nbins);
return v;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1050,10 +1164,6 @@ void G4VEnergyLossProcess::SetStepLimits(G4double v1, G4double v2)
void G4VEnergyLossProcess::SetIntegral(G4bool val)
{
if(integral != val) {
if(val) dRoverRange = defaultIntegralRange;
else dRoverRange = defaultRoverRange;
}
integral = val;
}
@@ -1313,11 +1423,6 @@ void G4VEnergyLossProcess::SetLossFluctuations(G4bool val)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetSubCutoff(G4bool)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VEnergyLossProcess::SetRandomStep(G4bool val)
{
rndmStepFlag = val;
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4VMultipleScattering.cc,v 1.36 2005/04/18 17:31:56 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// $Id: G4VMultipleScattering.cc,v 1.37 2005/10/27 11:33:26 vnivanch Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//
@@ -48,6 +48,7 @@
// 11-03-05 Shift verbose level by 1 (V.Ivantchenko)
// 15-04-05 optimize internal interface (V.Ivanchenko)
// 15-04-05 remove boundary flag (V.Ivanchenko)
// 27-10-05 introduce virtual function MscStepLimitation() (V.Ivanchenko)
//
// Class Description:
//
@@ -297,3 +298,8 @@ G4bool G4VMultipleScattering::RetrievePhysicsTable(const G4ParticleDefinition* p
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4VMultipleScattering::MscStepLimitation(G4bool, G4double)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -21,7 +21,7 @@
// ********************************************************************
//
// $Id: G4ionEffectiveCharge.cc,v 1.10 2005/02/27 18:07:33 vnivanch Exp $
// GEANT4 tag $Name: geant4-07-01 $
// GEANT4 tag $Name: geant4-08-00 $
//
// -------------------------------------------------------------------
//