Files
geant4/source/processes/electromagnetic/utils/src/G4LossTableManager.cc
T
2023-06-19 17:17:14 +02:00

1147 lines
34 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * 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. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4LossTableManager
//
// Author: Vladimir Ivanchenko
//
// Creation date: 03.01.2002
//
// Modifications: by V.Ivanchenko
//
//
// Class Description:
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4LossTableManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4VMultipleScattering.hh"
#include "G4VEmProcess.hh"
#include "G4EmParameters.hh"
#include "G4EmSaturation.hh"
#include "G4EmConfigurator.hh"
#include "G4ElectronIonPair.hh"
#include "G4NIELCalculator.hh"
#include "G4EmCorrections.hh"
#include "G4LossTableBuilder.hh"
#include "G4VAtomDeexcitation.hh"
#include "G4VSubCutProducer.hh"
#include "G4PhysicsTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4ProcessManager.hh"
#include "G4Electron.hh"
#include "G4Proton.hh"
#include "G4ProductionCutsTable.hh"
#include "G4PhysicsTableHelper.hh"
#include "G4EmTableType.hh"
#include "G4Region.hh"
#include "G4PhysicalConstants.hh"
#include "G4Threading.hh"
#include "G4Gamma.hh"
#include "G4Positron.hh"
#include "G4OpticalPhoton.hh"
#include "G4Neutron.hh"
#include "G4MuonPlus.hh"
#include "G4MuonMinus.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4ThreadLocal G4LossTableManager* G4LossTableManager::instance = nullptr;
G4LossTableManager* G4LossTableManager::Instance()
{
if(!instance) {
static G4ThreadLocalSingleton<G4LossTableManager> inst;
instance = inst.Instance();
}
return instance;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4LossTableManager::~G4LossTableManager()
{
for (G4int i=0; i<n_loss; ++i) {
delete loss_vector[i];
}
std::size_t msc = msc_vector.size();
for (std::size_t j=0; j<msc; ++j) {
delete msc_vector[j];
}
std::size_t emp = emp_vector.size();
for (std::size_t k=0; k<emp; ++k) {
delete emp_vector[k];
}
emp = p_vector.size();
for (std::size_t k=0; k<emp; ++k) {
delete p_vector[k];
}
std::size_t mod = mod_vector.size();
std::size_t fmod = fmod_vector.size();
//G4cout << " Nmod" << mod << " Nfluc= " << fmod << G4endl;
for (std::size_t a=0; a<mod; ++a) {
//G4cout << "Delete model #" << a << " " << mod_vector[a] << G4endl;
if( nullptr != mod_vector[a] ) {
for (std::size_t b=0; b<fmod; ++b) {
if((G4VEmModel*)(fmod_vector[b]) == mod_vector[a]) {
fmod_vector[b] = nullptr;
}
}
delete mod_vector[a];
mod_vector[a] = nullptr;
}
}
for (std::size_t b=0; b<fmod; ++b) {
delete fmod_vector[b];
}
Clear();
delete tableBuilder;
delete emCorrections;
delete emConfigurator;
delete emElectronIonPair;
delete nielCalculator;
delete atomDeexcitation;
delete subcutProducer;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4LossTableManager::G4LossTableManager()
{
theParameters = G4EmParameters::Instance();
n_loss = 0;
run = -1;
startInitialisation = false;
all_tables_are_built = false;
currentLoss = nullptr;
currentParticle = nullptr;
firstParticle = nullptr;
isMaster = true;
verbose = theParameters->Verbose();
theElectron = G4Electron::Electron();
theGenericIon= nullptr;
if(G4Threading::IsWorkerThread()) {
verbose = theParameters->WorkerVerbose();
isMaster = false;
}
tableBuilder = new G4LossTableBuilder(isMaster);
emCorrections= new G4EmCorrections(verbose);
emConfigurator = nullptr;
emElectronIonPair = nullptr;
atomDeexcitation = nullptr;
subcutProducer = nullptr;
nielCalculator = nullptr;
gGeneral = nullptr;
eGeneral = pGeneral = nullptr;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::Clear()
{
all_tables_are_built = false;
currentLoss = nullptr;
currentParticle = nullptr;
if(n_loss) {
dedx_vector.clear();
range_vector.clear();
inv_range_vector.clear();
loss_map.clear();
loss_vector.clear();
part_vector.clear();
base_part_vector.clear();
tables_are_built.clear();
isActive.clear();
n_loss = 0;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::Register(G4VEnergyLossProcess* p)
{
if(!p) { return; }
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VEnergyLossProcess : "
<< p->GetProcessName() << " idx= " << n_loss << G4endl;
}
++n_loss;
loss_vector.push_back(p);
part_vector.push_back(nullptr);
base_part_vector.push_back(nullptr);
dedx_vector.push_back(nullptr);
range_vector.push_back(nullptr);
inv_range_vector.push_back(nullptr);
tables_are_built.push_back(false);
isActive.push_back(true);
all_tables_are_built = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::ResetParameters()
{
verbose = theParameters->Verbose();
if(!isMaster) {
verbose = theParameters->WorkerVerbose();
} else {
if(verbose > 0) { theParameters->Dump(); }
}
tableBuilder->SetInitialisationFlag(false);
emCorrections->SetVerbose(verbose);
if(nullptr != emConfigurator) { emConfigurator->SetVerbose(verbose); };
if(nullptr != emElectronIonPair) { emElectronIonPair->SetVerbose(verbose); };
if(nullptr != atomDeexcitation) {
atomDeexcitation->SetVerboseLevel(verbose);
atomDeexcitation->InitialiseAtomicDeexcitation();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VEnergyLossProcess* p)
{
if(!p) { return; }
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) {
loss_vector[i] = nullptr;
break;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::Register(G4VMultipleScattering* p)
{
if(!p) { return; }
std::size_t n = msc_vector.size();
for (std::size_t i=0; i<n; ++i) {
if(msc_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
<< p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
}
msc_vector.push_back(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VMultipleScattering* p)
{
if(!p) { return; }
std::size_t msc = msc_vector.size();
for (std::size_t i=0; i<msc; ++i) {
if(msc_vector[i] == p) {
msc_vector[i] = nullptr;
break;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::Register(G4VEmProcess* p)
{
if(!p) { return; }
std::size_t n = emp_vector.size();
for (std::size_t i=0; i<n; ++i) {
if(emp_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VEmProcess : "
<< p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
}
emp_vector.push_back(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VEmProcess* p)
{
if(!p) { return; }
std::size_t emp = emp_vector.size();
for (std::size_t i=0; i<emp; ++i) {
if(emp_vector[i] == p) {
emp_vector[i] = nullptr;
break;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::Register(G4VProcess* p)
{
if(!p) { return; }
std::size_t n = p_vector.size();
for (std::size_t i=0; i<n; ++i) {
if(p_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VProcess : "
<< p->GetProcessName() << " idx= " << p_vector.size() << G4endl;
}
p_vector.push_back(p);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VProcess* p)
{
if(!p) { return; }
std::size_t emp = p_vector.size();
for (std::size_t i=0; i<emp; ++i) {
if(p_vector[i] == p) {
p_vector[i] = nullptr;
break;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::Register(G4VEmModel* p)
{
mod_vector.push_back(p);
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VEmModel : "
<< p->GetName() << " " << p << " " << mod_vector.size() << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VEmModel* p)
{
//G4cout << "G4LossTableManager::DeRegister G4VEmModel : " << p << G4endl;
std::size_t n = mod_vector.size();
for (std::size_t i=0; i<n; ++i) {
if(mod_vector[i] == p) {
mod_vector[i] = nullptr;
break;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::Register(G4VEmFluctuationModel* p)
{
fmod_vector.push_back(p);
if(verbose > 1) {
G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
<< p->GetName() << " " << fmod_vector.size() << G4endl;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::DeRegister(G4VEmFluctuationModel* p)
{
std::size_t n = fmod_vector.size();
for (std::size_t i=0; i<n; ++i) {
if(fmod_vector[i] == p) { fmod_vector[i] = nullptr; }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::RegisterExtraParticle(
const G4ParticleDefinition* part,
G4VEnergyLossProcess* p)
{
if(!p || !part) { return; }
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i] == p) { return; }
}
if(verbose > 1) {
G4cout << "G4LossTableManager::RegisterExtraParticle "
<< part->GetParticleName() << " G4VEnergyLossProcess : "
<< p->GetProcessName() << " idx= " << n_loss << G4endl;
}
++n_loss;
loss_vector.push_back(p);
part_vector.push_back(part);
base_part_vector.push_back(p->BaseParticle());
dedx_vector.push_back(nullptr);
range_vector.push_back(nullptr);
inv_range_vector.push_back(nullptr);
tables_are_built.push_back(false);
all_tables_are_built = false;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4VEnergyLossProcess*
G4LossTableManager::GetEnergyLossProcess(const G4ParticleDefinition *aParticle)
{
if(aParticle != currentParticle) {
currentParticle = aParticle;
std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
currentLoss = (*pos).second;
} else {
currentLoss = nullptr;
if(0.0 != aParticle->GetPDGCharge() &&
(pos = loss_map.find(theGenericIon)) != loss_map.end()) {
currentLoss = (*pos).second;
}
}
}
return currentLoss;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VEnergyLossProcess* p,
G4bool theMaster)
{
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << " run= " << run
<< " loss_vector " << loss_vector.size() << G4endl;
}
isMaster = theMaster;
if(!startInitialisation) {
ResetParameters();
if (1 < verbose) {
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
<< G4endl;
}
}
// start initialisation for the first run
if( -1 == run ) {
if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
// initialise particles for given process
for (G4int j=0; j<n_loss; ++j) {
if (p == loss_vector[j] && !part_vector[j]) {
part_vector[j] = particle;
if(particle->GetParticleName() == "GenericIon") {
theGenericIon = particle;
}
}
}
}
startInitialisation = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VEmProcess* p, G4bool theMaster)
{
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << G4endl;
}
isMaster = theMaster;
if(!startInitialisation) {
ResetParameters();
if (1 < verbose) {
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
<< G4endl;
}
}
// start initialisation for the first run
if( -1 == run ) {
if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
}
startInitialisation = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4LossTableManager::PreparePhysicsTable(const G4ParticleDefinition* particle,
G4VMultipleScattering* p,
G4bool theMaster)
{
if (1 < verbose) {
G4cout << "G4LossTableManager::PreparePhysicsTable for "
<< particle->GetParticleName()
<< " and " << p->GetProcessName() << G4endl;
}
isMaster = theMaster;
if(!startInitialisation) {
ResetParameters();
if (1 < verbose) {
G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
<< G4endl;
}
}
// start initialisation for the first run
if( -1 == run ) {
if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
}
startInitialisation = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void
G4LossTableManager::BuildPhysicsTable(const G4ParticleDefinition*)
{
if(-1 == run && startInitialisation) {
if(emConfigurator) { emConfigurator->Clear(); }
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::LocalPhysicsTables(
const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p)
{
if(1 < verbose) {
G4cout << "### G4LossTableManager::LocalPhysicsTable() for "
<< aParticle->GetParticleName()
<< " and process " << p->GetProcessName()
<< G4endl;
}
if(-1 == run && startInitialisation) {
if(emConfigurator) { emConfigurator->Clear(); }
firstParticle = aParticle;
}
if(startInitialisation) {
++run;
if(1 < verbose) {
G4cout << "===== G4LossTableManager::LocalPhysicsTable() for run "
<< run << " =====" << G4endl;
}
currentParticle = nullptr;
startInitialisation = false;
for (G4int i=0; i<n_loss; ++i) {
if(loss_vector[i]) {
tables_are_built[i] = false;
} else {
tables_are_built[i] = true;
part_vector[i] = nullptr;
}
}
}
all_tables_are_built= true;
for (G4int i=0; i<n_loss; ++i) {
if(p == loss_vector[i]) {
tables_are_built[i] = true;
isActive[i] = true;
part_vector[i] = p->Particle();
base_part_vector[i] = p->BaseParticle();
dedx_vector[i] = p->DEDXTable();
range_vector[i] = p->RangeTableForLoss();
inv_range_vector[i] = p->InverseRangeTable();
if(0 == run && p->IsIonisationProcess()) {
loss_map[part_vector[i]] = p;
//G4cout << "G4LossTableManager::LocalPhysicsTable " << part_vector[i]->GetParticleName()
// << " added to map " << p << G4endl;
}
if(1 < verbose) {
G4cout << i <<". "<< p->GetProcessName();
if(part_vector[i]) {
G4cout << " for " << part_vector[i]->GetParticleName();
}
G4cout << " active= " << isActive[i]
<< " table= " << tables_are_built[i]
<< " isIonisation= " << p->IsIonisationProcess()
<< G4endl;
}
break;
} else if(!tables_are_built[i]) {
all_tables_are_built = false;
}
}
if(1 < verbose) {
G4cout << "### G4LossTableManager::LocalPhysicsTable end"
<< G4endl;
}
if(all_tables_are_built) {
if(1 < verbose) {
G4cout << "%%%%% All dEdx and Range tables for worker are ready for run "
<< run << " %%%%%" << G4endl;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::BuildPhysicsTable(
const G4ParticleDefinition* aParticle,
G4VEnergyLossProcess* p)
{
if(1 < verbose) {
G4cout << "### G4LossTableManager::BuildPhysicsTable() for "
<< aParticle->GetParticleName()
<< " and process " << p->GetProcessName() << G4endl;
}
// clear configurator
if(-1 == run && startInitialisation) {
if(emConfigurator) { emConfigurator->Clear(); }
firstParticle = aParticle;
}
if(startInitialisation) {
++run;
if(1 < verbose) {
G4cout << "===== G4LossTableManager::BuildPhysicsTable() for run "
<< run << " ===== " << atomDeexcitation << G4endl;
}
currentParticle = nullptr;
all_tables_are_built= true;
}
// initialisation before any table is built
if ( startInitialisation && aParticle == firstParticle ) {
startInitialisation = false;
if(1 < verbose) {
G4cout << "### G4LossTableManager start initialisation for first particle "
<< firstParticle->GetParticleName()
<< G4endl;
}
if(nielCalculator) { nielCalculator->Initialise(); }
for (G4int i=0; i<n_loss; ++i) {
G4VEnergyLossProcess* el = loss_vector[i];
if(el) {
isActive[i] = true;
base_part_vector[i] = el->BaseParticle();
tables_are_built[i] = false;
all_tables_are_built= false;
if(1 < verbose) {
G4cout << i <<". "<< el->GetProcessName();
if(el->Particle()) {
G4cout << " for " << el->Particle()->GetParticleName();
}
G4cout << " active= " << isActive[i]
<< " table= " << tables_are_built[i]
<< " isIonisation= " << el->IsIonisationProcess();
if(base_part_vector[i]) {
G4cout << " base particle "
<< base_part_vector[i]->GetParticleName();
}
G4cout << G4endl;
}
} else {
tables_are_built[i] = true;
part_vector[i] = nullptr;
isActive[i] = false;
}
}
}
if (all_tables_are_built) {
theParameters->SetIsPrintedFlag(true);
return;
}
// Build tables for given particle
all_tables_are_built = true;
for(G4int i=0; i<n_loss; ++i) {
if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
const G4ParticleDefinition* curr_part = part_vector[i];
if(1 < verbose) {
G4cout << "### Build Table for " << p->GetProcessName()
<< " and " << curr_part->GetParticleName()
<< " " << tables_are_built[i] << " " << base_part_vector[i]
<< G4endl;
}
G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
if(curr_proc) {
CopyTables(curr_part, curr_proc);
if(p == curr_proc && 0 == run && p->IsIonisationProcess()) {
loss_map[aParticle] = p;
//G4cout << "G4LossTableManager::BuildPhysicsTable: "
// << aParticle->GetParticleName()
// << " added to map " << p << G4endl;
}
}
}
if ( !tables_are_built[i] ) { all_tables_are_built = false; }
}
if(1 < verbose) {
G4cout << "### G4LossTableManager::BuildPhysicsTable end: "
<< "all_tables_are_built= " << all_tables_are_built << " "
<< aParticle->GetParticleName() << " proc: " << p << G4endl;
}
if(all_tables_are_built) {
if(1 < verbose) {
G4cout << "%%%%% All dEdx and Range tables are built for master run= "
<< run << " %%%%%" << G4endl;
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
G4VEnergyLossProcess* base_proc)
{
for (G4int j=0; j<n_loss; ++j) {
G4VEnergyLossProcess* proc = loss_vector[j];
if (!tables_are_built[j] && part == base_part_vector[j]) {
tables_are_built[j] = true;
proc->SetDEDXTable(base_proc->IonisationTable(),fRestricted);
proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
proc->SetCSDARangeTable(base_proc->CSDARangeTable());
proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
proc->SetInverseRangeTable(base_proc->InverseRangeTable());
proc->SetLambdaTable(base_proc->LambdaTable());
proc->SetIonisation(base_proc->IsIonisationProcess());
if(proc->IsIonisationProcess()) {
range_vector[j] = base_proc->RangeTableForLoss();
inv_range_vector[j] = base_proc->InverseRangeTable();
loss_map[part_vector[j]] = proc;
//G4cout << "G4LossTableManager::CopyTable "
// << part_vector[j]->GetParticleName()
// << " added to map " << proc << G4endl;
}
if (1 < verbose) {
G4cout << "For " << proc->GetProcessName()
<< " for " << part_vector[j]->GetParticleName()
<< " base_part= " << part->GetParticleName()
<< " tables are assigned"
<< G4endl;
}
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
G4VEnergyLossProcess* G4LossTableManager::BuildTables(
const G4ParticleDefinition* aParticle)
{
if(1 < verbose) {
G4cout << "G4LossTableManager::BuildTables() for "
<< aParticle->GetParticleName() << G4endl;
}
std::vector<G4PhysicsTable*> t_list;
std::vector<G4VEnergyLossProcess*> loss_list;
std::vector<G4bool> build_flags;
G4VEnergyLossProcess* em = nullptr;
G4VEnergyLossProcess* p = nullptr;
G4int iem = 0;
G4PhysicsTable* dedx = nullptr;
G4int i;
G4ProcessVector* pvec =
aParticle->GetProcessManager()->GetProcessList();
G4int nvec = (G4int)pvec->size();
for (i=0; i<n_loss; ++i) {
p = loss_vector[i];
if (p) {
G4bool yes = (aParticle == part_vector[i]);
// possible case of process sharing between particle/anti-particle
if(!yes) {
auto ptr = static_cast<G4VProcess*>(p);
for(G4int j=0; j<nvec; ++j) {
//G4cout << "j= " << j << " " << (*pvec)[j] << " " << ptr << G4endl;
if(ptr == (*pvec)[j]) {
yes = true;
break;
}
}
}
// process belong to this particle
if(yes && isActive[i]) {
if (p->IsIonisationProcess() || !em) {
em = p;
iem= i;
}
// tables may be shared between particle/anti-particle
G4bool val = false;
if (!tables_are_built[i]) {
val = true;
dedx = p->BuildDEDXTable(fRestricted);
//G4cout << "Build DEDX table for " << p->GetProcessName()
// << " idx= " << i << dedx << " " << dedx->length() << G4endl;
p->SetDEDXTable(dedx,fRestricted);
tables_are_built[i] = true;
} else {
dedx = p->DEDXTable();
}
t_list.push_back(dedx);
loss_list.push_back(p);
build_flags.push_back(val);
}
}
}
G4int n_dedx = (G4int)t_list.size();
if (0 == n_dedx || !em) {
G4cout << "G4LossTableManager WARNING: no DEDX processes for "
<< aParticle->GetParticleName() << G4endl;
return nullptr;
}
G4int nSubRegions = em->NumberOfSubCutoffRegions();
if (1 < verbose) {
G4cout << "G4LossTableManager::BuildTables() start to build range tables"
<< " and the sum of " << n_dedx << " processes"
<< " iem= " << iem << " em= " << em->GetProcessName()
<< " buildCSDARange= " << theParameters->BuildCSDARange()
<< " nSubRegions= " << nSubRegions;
if(subcutProducer) {
G4cout << " SubCutProducer " << subcutProducer->GetName();
}
G4cout << G4endl;
}
// do not build tables if producer class is defined
if(subcutProducer) { nSubRegions = 0; }
dedx = em->DEDXTable();
em->SetIonisation(true);
em->SetDEDXTable(dedx, fIsIonisation);
if (1 < n_dedx) {
dedx = nullptr;
dedx = G4PhysicsTableHelper::PreparePhysicsTable(dedx);
tableBuilder->BuildDEDXTable(dedx, t_list);
em->SetDEDXTable(dedx, fRestricted);
}
/*
if(2==run && "e-" == aParticle->GetParticleName()) {
G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
G4cout << (*dedx) << G4endl;
G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
}
*/
dedx_vector[iem] = dedx;
G4PhysicsTable* range = em->RangeTableForLoss();
if(!range) range = G4PhysicsTableHelper::PreparePhysicsTable(range);
range_vector[iem] = range;
G4PhysicsTable* invrange = em->InverseRangeTable();
if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
inv_range_vector[iem] = invrange;
tableBuilder->BuildRangeTable(dedx, range);
tableBuilder->BuildInverseRangeTable(range, invrange);
// if(1<verbose) G4cout << *dedx << G4endl;
em->SetRangeTableForLoss(range);
em->SetInverseRangeTable(invrange);
// if(1<verbose) G4cout << *range << G4endl;
std::vector<G4PhysicsTable*> listCSDA;
for (i=0; i<n_dedx; ++i) {
p = loss_list[i];
if(p != em) { p->SetIonisation(false); }
if(build_flags[i]) {
p->SetLambdaTable(p->BuildLambdaTable(fRestricted));
}
if(theParameters->BuildCSDARange()) {
dedx = p->BuildDEDXTable(fTotal);
p->SetDEDXTable(dedx,fTotal);
listCSDA.push_back(dedx);
}
}
if(theParameters->BuildCSDARange()) {
G4PhysicsTable* dedxCSDA = em->DEDXunRestrictedTable();
if (1 < n_dedx) {
dedxCSDA = nullptr;
dedxCSDA = G4PhysicsTableHelper::PreparePhysicsTable(dedxCSDA);
tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
em->SetDEDXTable(dedxCSDA,fTotal);
}
G4PhysicsTable* rCSDA = em->CSDARangeTable();
if(!rCSDA) { rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA); }
tableBuilder->BuildRangeTable(dedxCSDA, rCSDA);
em->SetCSDARangeTable(rCSDA);
}
if (1 < verbose) {
G4cout << "G4LossTableManager::BuildTables: Tables are built for "
<< aParticle->GetParticleName()
<< "; ionisation process: " << em->GetProcessName()
<< " " << em
<< G4endl;
}
return em;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::ParticleHaveNoLoss(
const G4ParticleDefinition* aParticle)
{
G4ExceptionDescription ed;
ed << "Energy loss process not found for " << aParticle->GetParticleName()
<< " !";
G4Exception("G4LossTableManager::ParticleHaveNoLoss", "em0001",
FatalException, ed);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::SetVerbose(G4int val)
{
verbose = val;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
const std::vector<G4VEnergyLossProcess*>&
G4LossTableManager::GetEnergyLossProcessVector()
{
return loss_vector;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
const std::vector<G4VEmProcess*>& G4LossTableManager::GetEmProcessVector()
{
return emp_vector;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
const std::vector<G4VMultipleScattering*>&
G4LossTableManager::GetMultipleScatteringVector()
{
return msc_vector;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmSaturation* G4LossTableManager::EmSaturation()
{
return theParameters->GetEmSaturation();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4EmConfigurator* G4LossTableManager::EmConfigurator()
{
if(!emConfigurator) {
emConfigurator = new G4EmConfigurator(verbose);
}
return emConfigurator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4ElectronIonPair* G4LossTableManager::ElectronIonPair()
{
if(!emElectronIonPair) {
emElectronIonPair = new G4ElectronIonPair(verbose);
}
return emElectronIonPair;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4LossTableManager::SetNIELCalculator(G4NIELCalculator* ptr)
{
if(ptr && ptr != nielCalculator) {
delete nielCalculator;
nielCalculator = ptr;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4NIELCalculator* G4LossTableManager::NIELCalculator()
{
if(!nielCalculator) {
nielCalculator = new G4NIELCalculator(nullptr, verbose);
}
return nielCalculator;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4LossTableManager::SetAtomDeexcitation(G4VAtomDeexcitation* p)
{
if(atomDeexcitation != p) {
delete atomDeexcitation;
atomDeexcitation = p;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
void G4LossTableManager::SetSubCutProducer(G4VSubCutProducer* p)
{
if(subcutProducer != p) {
delete subcutProducer;
subcutProducer = p;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4LossTableManager::PrintEWarning(G4String tit, G4double /*val*/)
{
G4String ss = "G4LossTableManager::" + tit;
G4ExceptionDescription ed;
/*
ed << "Parameter is out of range: " << val
<< " it will have no effect!\n" << " ## "
<< " nbins= " << nbinsLambda
<< " nbinsPerDecade= " << nbinsPerDecade
<< " Emin(keV)= " << minKinEnergy/keV
<< " Emax(GeV)= " << maxKinEnergy/GeV;
*/
G4Exception(ss, "em0044", JustWarning, ed);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4LossTableManager::DumpHtml()
{
// Automatic generation of html documentation page for physics lists
// List processes and models for the most important
// particles in descending order of importance
// NB. for model names with length > 18 characters the .rst file needs
// to be edited by hand. Or modify G4EmModelManager::DumpModelList
char* dirName = std::getenv("G4PhysListDocDir");
char* physList = std::getenv("G4PhysListName");
if (dirName && physList) {
G4String physListName = G4String(physList);
G4String pathName = G4String(dirName) + "/" + physListName + ".rst";
std::ofstream outFile;
outFile.open(pathName);
outFile << physListName << G4endl;
outFile << std::string(physListName.length(), '=') << G4endl;
std::vector<G4ParticleDefinition*> particles {
G4Gamma::Gamma(),
G4Electron::Electron(),
G4Positron::Positron(),
G4Proton::ProtonDefinition(),
G4MuonPlus::MuonPlusDefinition(),
G4MuonMinus::MuonMinusDefinition(),
};
std::vector<G4VEmProcess*> emproc_vector = GetEmProcessVector();
std::vector<G4VEnergyLossProcess*> enloss_vector =
GetEnergyLossProcessVector();
std::vector<G4VMultipleScattering*> mscat_vector =
GetMultipleScatteringVector();
for (auto theParticle : particles) {
outFile << G4endl << "**" << theParticle->GetParticleName()
<< "**" << G4endl << G4endl << " .. code-block:: none" << G4endl;
G4ProcessManager* pm = theParticle->GetProcessManager();
G4ProcessVector* pv = pm->GetProcessList();
G4int plen = pm->GetProcessListLength();
for (auto emproc : emproc_vector) {
for (G4int i = 0; i < plen; ++i) {
G4VProcess* proc = (*pv)[i];
if (proc == emproc) {
outFile << G4endl;
proc->ProcessDescription(outFile);
break;
}
}
}
for (auto mscproc : mscat_vector) {
for (G4int i = 0; i < plen; ++i) {
G4VProcess* proc = (*pv)[i];
if (proc == mscproc) {
outFile << G4endl;
proc->ProcessDescription(outFile);
break;
}
}
}
for (auto enlossproc : enloss_vector) {
for (G4int i = 0; i < plen; ++i) {
G4VProcess* proc = (*pv)[i];
if (proc == enlossproc) {
outFile << G4endl;
proc->ProcessDescription(outFile);
break;
}
}
}
}
outFile.close();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....