Import Geant4 5.1.0 source tree
This commit is contained in:
@@ -28,15 +28,23 @@
|
||||
//
|
||||
// File name: G4EmModelManager
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Author: Vladimir Ivanchenko
|
||||
//
|
||||
// Creation date: 07.05.2002
|
||||
//
|
||||
// Modifications:
|
||||
// Modifications:
|
||||
//
|
||||
// Class Description:
|
||||
// 23-12-02 V.Ivanchenko change interface in order to move
|
||||
// to cut per region
|
||||
// 20-01-03 Migrade to cut per region (V.Ivanchenko)
|
||||
// 24-01-03 Make models region aware (V.Ivanchenko)
|
||||
// 13-02-03 The set of models is defined for region (V.Ivanchenko)
|
||||
// 06-03-03 Fix in energy intervals for models (V.Ivanchenko)
|
||||
// 13-04-03 Add startFromNull (V.Ivanchenko)
|
||||
//
|
||||
// It is the unified energy loss process it calculates the continuous
|
||||
// Class Description:
|
||||
//
|
||||
// It is the unified energy loss process it calculates the continuous
|
||||
// energy loss for charged particles using a set of Energy Loss
|
||||
// models valid for different energy regions. There are a possibility
|
||||
// to create and access to dE/dx and range tables, or to calculate
|
||||
@@ -45,41 +53,88 @@
|
||||
//
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
#include "G4EmModelManager.hh"
|
||||
#include "G4LossTableManager.hh"
|
||||
#include "G4Step.hh"
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VEmModel.hh"
|
||||
#include "G4DataVector.hh"
|
||||
#include "G4PhysicsVector.hh"
|
||||
#include "G4VParticleChange.hh"
|
||||
#include "G4Gamma.hh"
|
||||
#include "G4Positron.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
#include "G4ProductionCutsTable.hh"
|
||||
#include "G4Region.hh"
|
||||
#include "G4RegionStore.hh"
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
G4RegionModels::G4RegionModels(G4int nMod, G4std::vector<G4int>& list, G4DataVector& lowE)
|
||||
{
|
||||
nModelsForRegion = nMod;
|
||||
theListOfModelIndexes = new G4int [nModelsForRegion];
|
||||
lowKineticEnergy = new G4double [nModelsForRegion];
|
||||
for (G4int i=0; i<nModelsForRegion; i++) {
|
||||
theListOfModelIndexes[i] = list[i];
|
||||
lowKineticEnergy[i] = lowE[i];
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4RegionModels::~G4RegionModels()
|
||||
{
|
||||
delete [] theListOfModelIndexes;
|
||||
delete [] lowKineticEnergy;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmModelManager::G4EmModelManager():
|
||||
nEmModels(0),
|
||||
nmax(4),
|
||||
orderIsChanged(false),
|
||||
nRegions(0),
|
||||
nCouples(0),
|
||||
minSubRange(0.1),
|
||||
particle(0)
|
||||
particle(0),
|
||||
verboseLevel(0)
|
||||
{
|
||||
verboseLevel = 0;
|
||||
for(G4int i = 0; i<nmax; i++) {
|
||||
emModels[i] = 0;
|
||||
order[i] = 0;
|
||||
upperEkin[i] = 0.0;
|
||||
}
|
||||
models.clear();
|
||||
flucModels.clear();
|
||||
regions.clear();
|
||||
orderOfModels.clear();
|
||||
upperEkin.clear();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
G4EmModelManager::~G4EmModelManager()
|
||||
{
|
||||
G4int i,j;
|
||||
Clear();
|
||||
for(G4int i = 0; i<nmax; i++) {
|
||||
if(emModels[i]) delete emModels[i];
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
orderOfModels[i] = 1;
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
if (orderOfModels[i]) {
|
||||
orderOfModels[i] = 0;
|
||||
for(j = i+1; j<nEmModels; j++) {
|
||||
if(models[i] == models[j]) orderOfModels[j] = 0;
|
||||
}
|
||||
delete models[i];
|
||||
}
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
orderOfModels[i] = 1;
|
||||
}
|
||||
for(i = 0; i<nEmModels; i++) {
|
||||
if (orderOfModels[i]) {
|
||||
orderOfModels[i] = 0;
|
||||
for(j = i+1; j<nEmModels; j++) {
|
||||
if(flucModels[i] == flucModels[j]) orderOfModels[j] = 0;
|
||||
}
|
||||
delete flucModels[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,18 +148,52 @@ void G4EmModelManager::Clear()
|
||||
|
||||
theCuts.clear();
|
||||
theSubCuts.clear();
|
||||
upperEkin.clear();
|
||||
idxOfRegionModels.clear();
|
||||
setOfRegionModels.clear();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
void G4EmModelManager::AddEmModel(G4int num, G4VEmModel* p,
|
||||
G4VEmFluctuationModel* fm, const G4Region* r)
|
||||
{
|
||||
if(!p) {
|
||||
G4cout << "G4EmModelManager::AddEmModel WARNING: no model defined." << G4endl;
|
||||
return;
|
||||
}
|
||||
models.push_back(p);
|
||||
flucModels.push_back(fm);
|
||||
regions.push_back(r);
|
||||
orderOfModels.push_back(num);
|
||||
if (nEmModels) {
|
||||
G4int idx = nEmModels;
|
||||
do {idx--;} while (idx && num < orderOfModels[idx]);
|
||||
if (num >= orderOfModels[idx] && num <= orderOfModels[idx+1]) idx++;
|
||||
if (idx < nEmModels) {
|
||||
models[nEmModels] = models[idx];
|
||||
flucModels[nEmModels] = flucModels[idx];
|
||||
regions[nEmModels] = regions[idx];
|
||||
orderOfModels[nEmModels] = orderOfModels[idx];
|
||||
models[idx] = p;
|
||||
flucModels[idx] = fm;
|
||||
regions[idx] = r;
|
||||
orderOfModels[idx] = num;
|
||||
}
|
||||
}
|
||||
nEmModels++;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
const G4ParticleDefinition* sp,
|
||||
G4double theMinSubRange,
|
||||
G4int val)
|
||||
{
|
||||
// Are models defined?
|
||||
if(!nEmModels) {
|
||||
G4Exception("G4EmModelManager::Initialise without any model defined");
|
||||
G4Exception("G4EmModelManager::Initialise without any model defined");
|
||||
}
|
||||
particle = p;
|
||||
secondaryParticle = sp;
|
||||
@@ -112,188 +201,161 @@ const G4DataVector* G4EmModelManager::Initialise(const G4ParticleDefinition* p,
|
||||
verboseLevel = val;
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::Initialise() for "
|
||||
<< p->GetParticleName()
|
||||
G4cout << "### G4EmModelManager::Initialise() for "
|
||||
<< p->GetParticleName()
|
||||
<< G4endl;
|
||||
}
|
||||
Clear();
|
||||
|
||||
// Ordering
|
||||
if(orderIsChanged) {
|
||||
G4int oldOrder[5];
|
||||
G4VEmModel* oldEmModels[5];
|
||||
for(G4int k = 0; k<nmax; k++) {
|
||||
oldEmModels[k] = emModels[k];
|
||||
oldOrder[k] = order[k];
|
||||
}
|
||||
G4RegionStore* regionStore = G4RegionStore::GetInstance();
|
||||
const G4Region* world = regionStore->GetRegion("DefaultRegionForTheWorld", false);
|
||||
|
||||
// Identify the list of regions with different set of models
|
||||
nRegions = 1;
|
||||
G4std::vector<const G4Region*> set;
|
||||
set.push_back(world);
|
||||
|
||||
for(G4int ik=0; ik<nEmModels; ik++) {
|
||||
|
||||
G4int low = INT_MAX;
|
||||
G4int index = 0;
|
||||
for(G4int kk=0; kk<nEmModels; kk++) {
|
||||
if(oldEmModels[kk]) {
|
||||
if(oldOrder[kk] < low) {
|
||||
low = oldOrder[kk];
|
||||
index = kk;
|
||||
}
|
||||
}
|
||||
for (G4int ii=0; ii<nEmModels; ii++) {
|
||||
const G4Region* r = regions[ii];
|
||||
if ( r && r != world) {
|
||||
G4bool newRegion = true;
|
||||
if (nRegions>1) {
|
||||
for (G4int j=1; j<nRegions; j++) {
|
||||
if ( r == set[j] ) newRegion = false;
|
||||
}
|
||||
}
|
||||
if (newRegion) {
|
||||
set.push_back(r);
|
||||
nRegions++;
|
||||
}
|
||||
emModels[ik] = oldEmModels[index];
|
||||
order[ik] = ik;
|
||||
oldEmModels[index] = 0;
|
||||
}
|
||||
orderIsChanged = false;
|
||||
}
|
||||
|
||||
G4DataVector eLow;
|
||||
eLow.clear();
|
||||
setOfRegionModels.clear();
|
||||
const G4ProductionCutsTable* theCoupleTable=
|
||||
G4ProductionCutsTable::GetProductionCutsTable();
|
||||
size_t numOfCouples = theCoupleTable->GetTableSize();
|
||||
idxOfRegionModels.resize(numOfCouples);
|
||||
upperEkin.resize(nEmModels);
|
||||
|
||||
G4int n = 0;
|
||||
// Order models for regions
|
||||
for (G4int reg=0; reg<nRegions; reg++) {
|
||||
|
||||
for(G4int j=0; j<nEmModels; j++) {
|
||||
const G4Region* region = set[reg];
|
||||
|
||||
G4double ep = 0.0;
|
||||
if(0 < n) ep = upperEkin[n-1];
|
||||
G4VEmModel* model = emModels[j];
|
||||
G4bool accepted = false;
|
||||
G4int n = 0;
|
||||
|
||||
if(model->IsInCharge(particle, 0)) {
|
||||
G4std::vector<G4int> modelAtRegion;
|
||||
G4DataVector eLow;
|
||||
G4DataVector eHigh;
|
||||
modelAtRegion.clear();
|
||||
eLow.clear();
|
||||
eHigh.clear();
|
||||
|
||||
G4double tmin = model->LowEnergyLimit(particle, 0);
|
||||
G4double tmax = model->HighEnergyLimit(particle, 0);
|
||||
for (G4int ii=0; ii<nEmModels; ii++) {
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "New model for tmin(MeV)= " << tmin/MeV
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< "; tlast(MeV)= " << ep/MeV
|
||||
G4VEmModel* model = models[ii];
|
||||
if ( (model->IsInCharge(particle)) &&
|
||||
(0 == regions[ii] || region == regions[ii]) )
|
||||
{
|
||||
|
||||
G4double tmin = model->LowEnergyLimit(particle);
|
||||
G4double tmax = model->HighEnergyLimit(particle);
|
||||
if (n) tmin = G4std::max(tmin, eHigh[n-1]);
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Model # " << ii << " for region <"
|
||||
<< region->GetName() << "> "
|
||||
<< " tmin(MeV)= " << tmin/MeV
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(tmax > tmin) {
|
||||
|
||||
if(n == 0 || tmax > upperEkin[n-1]) {
|
||||
|
||||
// First model or next model for more high energy range;
|
||||
upperEkin[n] = (tmax);
|
||||
if(0 < n) tmin = G4std::max(tmin, upperEkin[n-1]);
|
||||
eLow.push_back(tmin);
|
||||
n++;
|
||||
accepted = true;
|
||||
|
||||
} else {
|
||||
|
||||
G4cout << "The model number #" << j
|
||||
<< " has no active range "
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< "; tlast(MeV)= " << ep/MeV
|
||||
<< G4endl;
|
||||
if (tmin < tmax) {
|
||||
modelAtRegion.push_back(ii);
|
||||
eLow.push_back(tmin);
|
||||
eHigh.push_back(tmax);
|
||||
upperEkin[ii] = tmax;
|
||||
n++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
G4cout << "The model number #" << j
|
||||
<< " has no active range "
|
||||
<< "; tmin(MeV)= " << tmin/MeV
|
||||
<< "; tmax(MeV)= " << tmax/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
if(!accepted) {
|
||||
upperEkin[n] = ep;
|
||||
eLow.push_back(ep);
|
||||
n++;
|
||||
eLow[0] = 0.0;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "New G4RegionModels set with " << n << " models for region <"
|
||||
<< region->GetName() << "> " << G4endl;
|
||||
}
|
||||
G4RegionModels* rm = new G4RegionModels(n, modelAtRegion, eLow);
|
||||
setOfRegionModels.push_back(rm);
|
||||
}
|
||||
|
||||
// Access to materials and build cuts
|
||||
|
||||
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
|
||||
size_t nMaterials = G4Material::GetNumberOfMaterials();
|
||||
for(size_t i=0; i<numOfCouples; i++) {
|
||||
|
||||
for(size_t i=0; i<nMaterials; i++) {
|
||||
|
||||
const G4Material* material = (*theMaterialTable)[i];
|
||||
const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
const G4ProductionCuts* pcuts = couple->GetProductionCuts();
|
||||
G4int reg = nRegions;
|
||||
do {reg--;} while (reg>0 && pcuts != (set[reg]->GetProductionCuts()));
|
||||
idxOfRegionModels[i] = reg;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::Initialise() for "
|
||||
G4cout << "G4EmModelManager::Initialise() for "
|
||||
<< material->GetName() << G4endl;
|
||||
}
|
||||
|
||||
G4double cut = 0.0;
|
||||
G4double subcut = 0.0;
|
||||
if(secondaryParticle) {
|
||||
cut = secondaryParticle->GetEnergyThreshold(material);
|
||||
size_t idx = 1;
|
||||
if( secondaryParticle == G4Gamma::Gamma() ) idx = 0;
|
||||
cut = (*theCoupleTable->GetEnergyCutsVector(idx))[i];
|
||||
subcut = minSubRange*cut;
|
||||
}
|
||||
|
||||
for(G4int j=0; j<nEmModels; j++) {
|
||||
G4int nm = setOfRegionModels[reg]->NumberOfModels();
|
||||
for(G4int j=0; j<nm; j++) {
|
||||
|
||||
G4VEmModel* model = emModels[j];
|
||||
if(upperEkin[j] > eLow[j]) {
|
||||
G4VEmModel* model = models[setOfRegionModels[reg]->ModelIndex(j)];
|
||||
|
||||
G4double tcutmin = model->MinEnergyCut(particle, material);
|
||||
G4double tcutmin = model->MinEnergyCut(particle, couple);
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "The model # " << j
|
||||
<< "; tcutmin(MeV)= " << tcutmin/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
cut = G4std::max(cut, tcutmin);
|
||||
subcut = G4std::max(subcut, tcutmin);
|
||||
cut = G4std::max(cut, tcutmin);
|
||||
G4double x = G4std::max(cut*minSubRange, tcutmin);
|
||||
subcut = G4std::max(subcut, x);
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "The model # " << j
|
||||
<< "; tcutmin(MeV)= " << tcutmin/MeV
|
||||
<< "; tcut(MeV)= " << cut/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
}
|
||||
theCuts.push_back(cut);
|
||||
theSubCuts.push_back(subcut);
|
||||
}
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager is initialised "
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
return &theCuts;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::AddEmModel(G4VEmModel* p, G4int num)
|
||||
{
|
||||
if(nEmModels) {
|
||||
for(G4int i=0; i<nEmModels; i++) {
|
||||
if(num < order[i]) orderIsChanged = true;
|
||||
}
|
||||
for(G4int jj=0; jj<nEmModels; jj++) {
|
||||
models[jj]->Initialise(particle, theCuts);
|
||||
if(flucModels[jj]) flucModels[jj]->Initialise(particle);
|
||||
}
|
||||
|
||||
if(nEmModels == nmax) {
|
||||
|
||||
G4cout << "G4EmModelManager::AddEmModel WARNING: cannot accept model #"
|
||||
<< nEmModels << " - the list is closed"
|
||||
<< G4endl;
|
||||
|
||||
} else {
|
||||
|
||||
emModels[nEmModels] = p;
|
||||
order[nEmModels] = num;
|
||||
currentModel = p;
|
||||
nEmModels++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
const G4Material* material)
|
||||
{
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::FillDEDXVector() for "
|
||||
<< material->GetName()
|
||||
G4cout << "G4EmModelManager is initialised "
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
return &theCuts;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
const G4MaterialCutsCouple* couple)
|
||||
{
|
||||
|
||||
// vectors to provide continues dE/dx
|
||||
G4DataVector factor;
|
||||
G4DataVector dedxLow;
|
||||
@@ -301,42 +363,59 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
|
||||
G4double e;
|
||||
|
||||
G4int i = material->GetIndex();
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
size_t i = couple->GetIndex();
|
||||
G4double cut = theCuts[i];
|
||||
factor.resize(nEmModels);
|
||||
dedxLow.resize(nEmModels);
|
||||
dedxHigh.resize(nEmModels);
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "There are " << nEmModels << " models for "
|
||||
<< material->GetName() << G4endl;
|
||||
G4cout << "G4EmModelManager::FillDEDXVector() for "
|
||||
<< material->GetName()
|
||||
<< " Ecut(MeV)= " << cut/MeV
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
G4int reg = idxOfRegionModels[i];
|
||||
const G4RegionModels* regModels = setOfRegionModels[reg];
|
||||
G4int nmod = regModels->NumberOfModels();
|
||||
factor.resize(nmod);
|
||||
dedxLow.resize(nmod);
|
||||
dedxHigh.resize(nmod);
|
||||
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "There are " << nmod << " models for "
|
||||
<< material->GetName()
|
||||
<< " at the region #" << reg
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
// calculate factors to provide continuity of energy loss
|
||||
factor[0] = 1.0;
|
||||
G4int j;
|
||||
|
||||
G4int totBinsLoss = aVector->GetVectorLength();
|
||||
|
||||
dedxLow[0] = 0.0;
|
||||
|
||||
e = upperEkin[0];
|
||||
dedxHigh[0] = emModels[0]->ComputeDEDX(material,particle,e,cut);
|
||||
e = upperEkin[regModels->ModelIndex(0)];
|
||||
dedxHigh[0] = models[regModels->ModelIndex(0)]->ComputeDEDX(material,particle,e,cut);
|
||||
|
||||
if(nEmModels > 1) {
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(nmod > 1) {
|
||||
for(j=1; j<nmod; j++) {
|
||||
|
||||
e = upperEkin[j-1];
|
||||
dedxLow[j] = emModels[j]->ComputeDEDX(material,particle,e,cut);
|
||||
e = upperEkin[j];
|
||||
dedxHigh[j] = emModels[j]->ComputeDEDX(material,particle,e,cut);
|
||||
e = upperEkin[regModels->ModelIndex(j-1)];
|
||||
dedxLow[j] = models[regModels->ModelIndex(j)]->ComputeDEDX(material,particle,e,cut);
|
||||
e = upperEkin[regModels->ModelIndex(j)];
|
||||
dedxHigh[j] = models[regModels->ModelIndex(j)]->ComputeDEDX(material,particle,e,cut);
|
||||
}
|
||||
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(dedxLow[j] > 0.0) factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0);
|
||||
for(j=1; j<nmod; j++) {
|
||||
if(dedxLow[j] > 0.0) factor[j] = (dedxHigh[j-1]/dedxLow[j] - 1.0);
|
||||
else factor[j] = 0.0;
|
||||
}
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Loop over " << totBinsLoss << " bins start " << G4endl;
|
||||
}
|
||||
}
|
||||
@@ -349,22 +428,21 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
|
||||
// Choose a model of energy losses
|
||||
G4int k = 0;
|
||||
if(nEmModels > 1) {
|
||||
if (e >= upperEkin[0]) {
|
||||
for(k=1; k<nEmModels; k++) {
|
||||
fac *= (1.0 + factor[k]*upperEkin[k-1]/e);
|
||||
if(e <= upperEkin[k]) break;
|
||||
}
|
||||
}
|
||||
if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
|
||||
do {
|
||||
k++;
|
||||
fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
|
||||
} while (k<nmod-1 && e < upperEkin[regModels->ModelIndex(k)] );
|
||||
}
|
||||
|
||||
G4double dedx = emModels[k]->ComputeDEDX(material,particle,e,cut)*fac;
|
||||
G4double dedx = models[regModels->ModelIndex(k)]->ComputeDEDX(material,particle,e,cut)*fac;
|
||||
|
||||
if(dedx < 0.0) dedx = 0.0;
|
||||
if(0 < verboseLevel) {
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "Material= " << material->GetName()
|
||||
<< " E(MeV)= " << e/MeV
|
||||
<< " dEdx(MeV/mm)= " << dedx*mm/MeV
|
||||
<< " E(MeV)= " << e/MeV
|
||||
<< " dEdx(MeV/mm)= " << dedx*mm/MeV
|
||||
<< " fac= " << fac
|
||||
<< G4endl;
|
||||
}
|
||||
aVector->PutValue(j, dedx);
|
||||
@@ -374,16 +452,11 @@ void G4EmModelManager::FillDEDXVector(G4PhysicsVector* aVector,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
const G4Material* material)
|
||||
void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4bool startFromNull)
|
||||
{
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::FillLambdaVector() for particle "
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
|
||||
// vectors to provide continues dE/dx
|
||||
G4DataVector factor;
|
||||
G4DataVector sigmaLow;
|
||||
@@ -391,14 +464,28 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
G4double e;
|
||||
|
||||
G4int i = material->GetIndex();
|
||||
G4double cut = theCuts[i];
|
||||
factor.resize(nEmModels);
|
||||
sigmaLow.resize(nEmModels);
|
||||
sigmaHigh.resize(nEmModels);
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "There are " << nEmModels << " models for "
|
||||
G4cout << "G4EmModelManager::FillLambdaVector() for particle "
|
||||
<< particle->GetParticleName()
|
||||
<< " in " << material->GetName()
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
|
||||
size_t i = couple->GetIndex();
|
||||
G4double cut = theCuts[i];
|
||||
|
||||
G4int reg = idxOfRegionModels[i];
|
||||
const G4RegionModels* regModels = setOfRegionModels[reg];
|
||||
G4int nmod = regModels->NumberOfModels();
|
||||
factor.resize(nmod);
|
||||
sigmaLow.resize(nmod);
|
||||
sigmaHigh.resize(nmod);
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "There are " << nmod << " models for "
|
||||
<< material->GetName() << G4endl;
|
||||
}
|
||||
|
||||
@@ -409,31 +496,31 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
sigmaLow[0] = 0.0;
|
||||
|
||||
e = upperEkin[0];
|
||||
e = upperEkin[regModels->ModelIndex(0)];
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### For material " << material->GetName()
|
||||
<< " " << nEmModels
|
||||
<< " " << nmod
|
||||
<< " models"
|
||||
<< " Ecut(MeV)= " << cut/MeV
|
||||
<< " Emax(MeV)= " << e/MeV
|
||||
<< " nbins= " << totBinsLambda
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
sigmaHigh[0] = emModels[0]->CrossSection(material,particle,e,cut,e);
|
||||
|
||||
if(nEmModels > 1) {
|
||||
sigmaHigh[0] = models[regModels->ModelIndex(0)]->CrossSection(material,particle,e,cut,e);
|
||||
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(nmod > 1) {
|
||||
|
||||
e = upperEkin[j-1];
|
||||
sigmaLow[j] = emModels[j]->CrossSection(material,particle,e,cut,e);
|
||||
e = upperEkin[j];
|
||||
sigmaHigh[j] = emModels[j]->CrossSection(material,particle,e,cut,e);
|
||||
for(j=1; j<nmod; j++) {
|
||||
|
||||
e = upperEkin[regModels->ModelIndex(j-1)];
|
||||
sigmaLow[j] = models[regModels->ModelIndex(j)]->CrossSection(material,particle,e,cut,e);
|
||||
e = upperEkin[regModels->ModelIndex(j)];
|
||||
sigmaHigh[j] = models[regModels->ModelIndex(j)]->CrossSection(material,particle,e,cut,e);
|
||||
}
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
for(j=1; j<nmod; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
else factor[j] = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -446,30 +533,23 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
// Choose a model of energy losses
|
||||
G4int k = 0;
|
||||
G4double fac = 1.0;
|
||||
if(nEmModels > 1) {
|
||||
if(e >= upperEkin[0]) {
|
||||
for(k=1; k<nEmModels; k++) {
|
||||
fac *= (1.0 + factor[k]*upperEkin[k-1]/e);
|
||||
if(e <= upperEkin[k]) break;
|
||||
}
|
||||
}
|
||||
if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
|
||||
do {
|
||||
k++;
|
||||
fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
|
||||
} while (k<nmod-1 && e < upperEkin[regModels->ModelIndex(k)] );
|
||||
}
|
||||
|
||||
// Cross section interpolation should start from zero
|
||||
G4double cross = 0.0;
|
||||
if(j > 0) {
|
||||
cross = emModels[k]->CrossSection(material,particle,e,cut,e)*fac;
|
||||
}
|
||||
G4double cross = models[regModels->ModelIndex(k)]->CrossSection(material,particle,e,cut,e)*fac;
|
||||
if(j==0 && startFromNull) cross = 0.0;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "BuildLambdaTable: e(MeV)= " << e/MeV
|
||||
<< " cross(1/mm)= " << cross*mm
|
||||
G4cout << "FillLambdaVector: " << j << ". e(MeV)= " << e/MeV
|
||||
<< " cross(1/mm)= " << cross*mm
|
||||
<< " fac= " << fac
|
||||
<< G4endl;
|
||||
}
|
||||
if(cross <= 0.0) cross = 0.0;
|
||||
// if(cross <= 0.0) cross = DBL_MAX;
|
||||
// else cross = 1.0/cross;
|
||||
if(cross < 0.0) cross = 0.0;
|
||||
|
||||
aVector->PutValue(j, cross);
|
||||
}
|
||||
@@ -477,11 +557,12 @@ void G4EmModelManager::FillLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
const G4Material* material)
|
||||
void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
const G4MaterialCutsCouple* couple,
|
||||
G4bool startFromNull)
|
||||
{
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "G4EmModelManager::BuildLambdaSubTable() for particle "
|
||||
G4cout << "G4EmModelManager::BuildLambdaSubTable() for particle "
|
||||
<< particle->GetParticleName() << G4endl;
|
||||
}
|
||||
|
||||
@@ -493,15 +574,20 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
G4double e;
|
||||
|
||||
G4int i = material->GetIndex();
|
||||
const G4Material* material = couple->GetMaterial();
|
||||
size_t i = couple->GetIndex();
|
||||
G4double cut = theCuts[i];
|
||||
G4double subcut = theSubCuts[i];
|
||||
factor.resize(nEmModels);
|
||||
sigmaLow.resize(nEmModels);
|
||||
sigmaHigh.resize(nEmModels);
|
||||
|
||||
G4int reg = idxOfRegionModels[i];
|
||||
const G4RegionModels* regModels = setOfRegionModels[reg];
|
||||
G4int nmod = regModels->NumberOfModels();
|
||||
factor.resize(nmod);
|
||||
sigmaLow.resize(nmod);
|
||||
sigmaHigh.resize(nmod);
|
||||
|
||||
if(0 < verboseLevel) {
|
||||
G4cout << "There are " << nEmModels << " models for "
|
||||
G4cout << "There are " << nmod << " models for "
|
||||
<< material->GetName() << G4endl;
|
||||
}
|
||||
|
||||
@@ -512,31 +598,31 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
|
||||
sigmaLow[0] = 0.0;
|
||||
|
||||
e = upperEkin[0];
|
||||
e = upperEkin[regModels->ModelIndex(0)];
|
||||
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "### For material " << material->GetName()
|
||||
<< " are available " << nEmModels
|
||||
<< " are available " << nmod
|
||||
<< " models"
|
||||
<< " Ecut(MeV)= " << cut/MeV
|
||||
<< " nbins= " << totBinsLambda
|
||||
<< G4endl;
|
||||
}
|
||||
|
||||
sigmaHigh[0] = emModels[0]->CrossSection(material,particle,e,subcut,cut);
|
||||
|
||||
if(nEmModels > 1) {
|
||||
sigmaHigh[0] = models[regModels->ModelIndex(0)]->CrossSection(material,particle,e,subcut,cut);
|
||||
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(nmod > 1) {
|
||||
|
||||
e = upperEkin[j-1];
|
||||
sigmaLow[j] = emModels[j]->CrossSection(material,particle,e,subcut,cut);
|
||||
e = upperEkin[j];
|
||||
sigmaHigh[j] = emModels[j]->CrossSection(material,particle,e,subcut,cut);
|
||||
for(j=1; j<nmod; j++) {
|
||||
|
||||
e = upperEkin[regModels->ModelIndex(j-1)];
|
||||
sigmaLow[j] = models[regModels->ModelIndex(j)]->CrossSection(material,particle,e,subcut,cut);
|
||||
e = upperEkin[regModels->ModelIndex(j)];
|
||||
sigmaHigh[j] = models[regModels->ModelIndex(j)]->CrossSection(material,particle,e,subcut,cut);
|
||||
}
|
||||
for(j=1; j<nEmModels; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
for(j=1; j<nmod; j++) {
|
||||
if(sigmaLow[j] > 0.0) factor[j] = (sigmaHigh[j-1]/sigmaLow[j] - 1.0);
|
||||
else factor[j] = 0.0;
|
||||
}
|
||||
}
|
||||
@@ -549,37 +635,26 @@ void G4EmModelManager::FillSubLambdaVector(G4PhysicsVector* aVector,
|
||||
// Choose a model of energy losses
|
||||
G4int k = 0;
|
||||
G4double fac = 1.0;
|
||||
if(nEmModels > 1) {
|
||||
if(e >= upperEkin[0]) {
|
||||
for(k=1; k<nEmModels; k++) {
|
||||
fac *= (1.0 + factor[k]*upperEkin[k-1]/e);
|
||||
if(e <= upperEkin[k]) break;
|
||||
}
|
||||
}
|
||||
if (nmod > 1 && e > upperEkin[regModels->ModelIndex(0)]) {
|
||||
do {
|
||||
k++;
|
||||
fac *= (1.0 + factor[k]*upperEkin[regModels->ModelIndex(k-1)]/e);
|
||||
} while (k<nmod-1 && e < upperEkin[regModels->ModelIndex(k)] );
|
||||
}
|
||||
|
||||
G4double cross = 0.0;
|
||||
|
||||
// Cross section interpolation should start from zero
|
||||
if (j > 0) {
|
||||
cross = emModels[k]->CrossSection(material,particle,e,subcut,cut)*fac;
|
||||
}
|
||||
G4double cross=models[regModels->ModelIndex(k)]->CrossSection(material,particle,e,subcut,cut)*fac;
|
||||
if(j==0 && startFromNull) cross = 0.0;
|
||||
|
||||
if(1 < verboseLevel) {
|
||||
G4cout << "BuildLambdaTable: e(MeV)= " << e/MeV
|
||||
<< " cross(1/mm)= " << cross*mm
|
||||
G4cout << "BuildLambdaTable: e(MeV)= " << e/MeV
|
||||
<< " cross(1/mm)= " << cross*mm
|
||||
<< " fac= " << fac
|
||||
<< G4endl;
|
||||
}
|
||||
if(cross <= 0.0) cross = 0.0;
|
||||
if(cross < 0.0) cross = 0.0;
|
||||
|
||||
aVector->PutValue(j, cross);
|
||||
}
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user