87static std::once_flag applyOnce;
92 if(
nullptr == instance) {
103 for (
auto const & p : loss_vector) {
delete p; }
104 for (
auto const & p : msc_vector) {
delete p; }
105 for (
auto const & p : emp_vector) {
delete p; }
106 for (
auto const & p : p_vector) {
delete p; }
107 for (
auto const & p : xray_vector) {
delete p; }
109 std::size_t mod = mod_vector.size();
110 std::size_t fmod = fmod_vector.size();
111 for (std::size_t a=0; a<mod; ++a) {
112 if(
nullptr != mod_vector[a] ) {
113 for (std::size_t b=0; b<fmod; ++b) {
114 if((
G4VEmModel*)(fmod_vector[b]) == mod_vector[a]) {
115 fmod_vector[b] =
nullptr;
118 delete mod_vector[a];
119 mod_vector[a] =
nullptr;
122 for (
auto const & p : fmod_vector) {
delete p; }
126 delete emCorrections;
127 delete emConfigurator;
128 delete emElectronIonPair;
129 delete nielCalculator;
130 delete atomDeexcitation;
131 delete subcutProducer;
142 std::call_once(applyOnce, [
this]() { isMaster =
true; });
143 verbose = isMaster ? theParameters->Verbose() : theParameters->WorkerVerbose();
145 tableBuilder =
new G4LossTableBuilder(isMaster);
146 emCorrections =
new G4EmCorrections(verbose);
149 loss_vector.reserve(n);
150 part_vector.reserve(n);
151 base_part_vector.reserve(n);
152 dedx_vector.reserve(n);
153 range_vector.reserve(n);
154 inv_range_vector.reserve(n);
155 tables_are_built.reserve(n);
157 msc_vector.reserve(10);
158 emp_vector.reserve(16);
159 mod_vector.reserve(150);
160 fmod_vector.reserve(60);
165void G4LossTableManager::Clear()
167 all_tables_are_built =
false;
168 currentLoss =
nullptr;
169 currentParticle =
nullptr;
172 range_vector.clear();
173 inv_range_vector.clear();
177 base_part_vector.clear();
178 tables_are_built.clear();
188 if (
nullptr == p) {
return; }
189 for (
G4int i=0; i<n_loss; ++i) {
190 if(loss_vector[i] == p) {
return; }
193 G4cout <<
"G4LossTableManager::Register G4VEnergyLossProcess : "
197 loss_vector.push_back(p);
198 part_vector.push_back(
nullptr);
199 base_part_vector.push_back(
nullptr);
200 dedx_vector.push_back(
nullptr);
201 range_vector.push_back(
nullptr);
202 inv_range_vector.push_back(
nullptr);
203 tables_are_built.push_back(
false);
204 isActive.push_back(
true);
205 all_tables_are_built =
false;
213 if (!resetParam) {
return; }
215 startInitialisation =
true;
216 verbose = theParameters->Verbose();
218 verbose = theParameters->WorkerVerbose();
220 if(verbose > 0) { theParameters->Dump(); }
223 tableBuilder->InitialiseBaseMaterials();
224 if (
nullptr != nielCalculator) { nielCalculator->Initialise(); }
226 emCorrections->SetVerbose(verbose);
227 if(
nullptr != emConfigurator) { emConfigurator->SetVerbose(verbose); };
228 if(
nullptr != emElectronIonPair) { emElectronIonPair->SetVerbose(verbose); };
229 if(
nullptr != atomDeexcitation) {
230 atomDeexcitation->SetVerboseLevel(verbose);
231 atomDeexcitation->InitialiseAtomicDeexcitation();
234 G4cout <<
"====== G4LossTableManager::ResetParameters "
235 <<
" Nloss=" << loss_vector.size()
236 <<
" run=" << run <<
" master=" << isMaster
245 if (
nullptr == p) {
return; }
246 for (
G4int i=0; i<n_loss; ++i) {
247 if(loss_vector[i] == p) {
248 loss_vector[i] =
nullptr;
258 if (
nullptr == p) {
return; }
259 std::size_t n = msc_vector.size();
260 for (std::size_t i=0; i<n; ++i) {
261 if(msc_vector[i] == p) {
return; }
264 G4cout <<
"G4LossTableManager::Register G4VMultipleScattering : "
267 msc_vector.push_back(p);
274 if (
nullptr == p) {
return; }
275 std::size_t msc = msc_vector.size();
276 for (std::size_t i=0; i<msc; ++i) {
277 if(msc_vector[i] == p) {
278 msc_vector[i] =
nullptr;
288 if (
nullptr == p) {
return; }
289 std::size_t n = emp_vector.size();
290 for (std::size_t i=0; i<n; ++i) {
291 if(emp_vector[i] == p) {
return; }
294 G4cout <<
"G4LossTableManager::Register G4VEmProcess : "
297 emp_vector.push_back(p);
304 if (
nullptr == p) {
return; }
305 std::size_t emp = emp_vector.size();
306 for (std::size_t i=0; i<emp; ++i) {
307 if(emp_vector[i] == p) {
308 emp_vector[i] =
nullptr;
318 if (
nullptr == p) {
return; }
319 std::size_t n = p_vector.size();
320 for (std::size_t i=0; i<n; ++i) {
321 if(p_vector[i] == p) {
return; }
324 G4cout <<
"G4LossTableManager::Register G4VProcess : "
327 p_vector.push_back(p);
334 if (
nullptr == p) {
return; }
335 std::size_t emp = p_vector.size();
336 for (std::size_t i=0; i<emp; ++i) {
337 if(p_vector[i] == p) {
338 p_vector[i] =
nullptr;
348 if (
nullptr == p) {
return; }
349 std::size_t n = mod_vector.size();
350 for (std::size_t i=0; i<n; ++i) {
if (mod_vector[i] == p) {
return; } }
351 mod_vector.push_back(p);
353 G4cout <<
"G4LossTableManager::Register G4VEmModel : "
354 << p->
GetName() <<
" " << p <<
" " << mod_vector.size() <<
G4endl;
362 std::size_t n = mod_vector.size();
363 for (std::size_t i=0; i<n; ++i) {
364 if(mod_vector[i] == p) {
365 mod_vector[i] =
nullptr;
375 if (
nullptr == p) {
return; }
376 std::size_t n = fmod_vector.size();
377 for (std::size_t i=0; i<n; ++i) {
if (fmod_vector[i] == p) {
return; } }
378 fmod_vector.push_back(p);
380 G4cout <<
"G4LossTableManager::Register G4VEmFluctuationModel : "
389 std::size_t n = fmod_vector.size();
390 for (std::size_t i=0; i<n; ++i) {
391 if(fmod_vector[i] == p) {
392 fmod_vector[i] =
nullptr;
402 if (
nullptr == p) {
return; }
403 std::size_t n = xray_vector.size();
404 for (std::size_t i=0; i<n; ++i) {
if (xray_vector[i] == p) {
return; } }
405 xray_vector.push_back(p);
407 G4cout <<
"G4LossTableManager::Register G4VXRayModel : "
416 std::size_t n = xray_vector.size();
417 for (std::size_t i=0; i<n; ++i) {
418 if (xray_vector[i] == p) {
419 xray_vector[i] =
nullptr;
431 if (
nullptr == p ||
nullptr == part) {
return; }
432 for (
G4int i=0; i<n_loss; ++i) {
433 if(loss_vector[i] == p) {
return; }
436 G4cout <<
"G4LossTableManager::RegisterExtraParticle "
441 loss_vector.push_back(p);
442 part_vector.push_back(part);
444 dedx_vector.push_back(
nullptr);
445 range_vector.push_back(
nullptr);
446 inv_range_vector.push_back(
nullptr);
447 tables_are_built.push_back(
false);
448 all_tables_are_built =
false;
456 if(aParticle != currentParticle) {
457 currentParticle = aParticle;
458 std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
459 if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
460 currentLoss = (*pos).second;
462 currentLoss =
nullptr;
464 (pos = loss_map.find(theGenericIon)) != loss_map.end()) {
465 currentLoss = (*pos).second;
479 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
482 <<
" loss_vector " << loss_vector.size()
483 <<
" run=" << run <<
" master=" << isMaster
489 if (
nullptr != emConfigurator) {
490 emConfigurator->PrepareModels(particle, p);
494 for (
G4int j=0; j<n_loss; ++j) {
495 if (p == loss_vector[j] &&
nullptr == part_vector[j]) {
496 part_vector[j] = particle;
498 theGenericIon = particle;
513 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
516 <<
" run=" << run <<
" master=" << isMaster
522 if (
nullptr != emConfigurator) { emConfigurator->PrepareModels(particle, p); }
535 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
538 <<
" run=" << run <<
" master=" << isMaster
544 if (
nullptr != emConfigurator) {
545 emConfigurator->PrepareModels(particle, p);
557 if(-1 == run && startInitialisation) {
558 if (
nullptr != emConfigurator) { emConfigurator->Clear(); }
560 if (startInitialisation) { resetParam =
true; }
570 G4cout <<
"### G4LossTableManager::LocalPhysicsTable() for "
576 if(-1 == run && startInitialisation) {
577 if (
nullptr != emConfigurator) { emConfigurator->Clear(); }
578 firstParticle = aParticle;
581 if (startInitialisation) {
584 G4cout <<
"===== G4LossTableManager::LocalPhysicsTable() for run "
585 << run <<
" =====" <<
G4endl;
587 currentParticle =
nullptr;
588 startInitialisation =
false;
590 for (
G4int i=0; i<n_loss; ++i) {
591 if (
nullptr != loss_vector[i]) {
592 tables_are_built[i] =
false;
594 tables_are_built[i] =
true;
595 part_vector[i] =
nullptr;
600 all_tables_are_built=
true;
601 for (
G4int i=0; i<n_loss; ++i) {
602 if(p == loss_vector[i]) {
603 tables_are_built[i] =
true;
611 loss_map[part_vector[i]] = p;
617 G4cout <<
" for " << part_vector[i]->GetParticleName();
619 G4cout <<
" active= " << isActive[i]
620 <<
" table= " << tables_are_built[i]
625 }
else if(!tables_are_built[i]) {
626 all_tables_are_built =
false;
631 G4cout <<
"### G4LossTableManager::LocalPhysicsTable end"
634 if(all_tables_are_built) {
636 G4cout <<
"%%%%% All dEdx and Range tables for worker are ready for run "
637 << run <<
" %%%%%" <<
G4endl;
649 G4cout <<
"### G4LossTableManager::BuildPhysicsTable() for "
654 if(-1 == run && startInitialisation) {
655 if(
nullptr != emConfigurator) { emConfigurator->Clear(); }
656 firstParticle = aParticle;
658 if(startInitialisation) {
661 startInitialisation =
false;
663 G4cout <<
"===== G4LossTableManager::BuildPhysicsTable() for run "
664 << run <<
" ===== " << atomDeexcitation <<
G4endl;
666 currentParticle =
nullptr;
667 all_tables_are_built =
false;
669 for (
G4int i=0; i<n_loss; ++i) {
676 tables_are_built[i] =
false;
682 G4cout <<
" active= " << isActive[i]
683 <<
" table= " << tables_are_built[i]
685 if(base_part_vector[i]) {
686 G4cout <<
" base particle "
687 << base_part_vector[i]->GetParticleName();
692 tables_are_built[i] =
true;
693 part_vector[i] =
nullptr;
699 if (all_tables_are_built) {
700 theParameters->SetIsPrintedFlag(
true);
705 all_tables_are_built =
true;
707 for(
G4int i=0; i<n_loss; ++i) {
708 if(p == loss_vector[i] && !tables_are_built[i] &&
nullptr == base_part_vector[i]) {
713 <<
" " << tables_are_built[i] <<
" " << base_part_vector[i]
718 CopyTables(curr_part, curr_proc);
720 loss_map[aParticle] = p;
727 if ( !tables_are_built[i] ) { all_tables_are_built =
false; }
730 G4cout <<
"### G4LossTableManager::BuildPhysicsTable end: "
731 <<
"all_tables_are_built= " << all_tables_are_built <<
" "
741 for (
G4int j=0; j<n_loss; ++j) {
745 if (!tables_are_built[j] && part == base_part_vector[j]) {
746 tables_are_built[j] =
true;
757 loss_map[part_vector[j]] = proc;
764 <<
" for " << part_vector[j]->GetParticleName()
766 <<
" tables are assigned"
779 G4cout <<
" G4LossTableManager::BuildTables(part) for "
783 std::vector<G4PhysicsTable*> t_list;
784 std::vector<G4VEnergyLossProcess*> loss_list;
785 std::vector<G4bool> build_flags;
786 G4VEnergyLossProcess* em =
nullptr;
787 G4VEnergyLossProcess* p =
nullptr;
789 G4PhysicsTable* dedx =
nullptr;
792 G4ProcessVector* pvec =
796 for (i=0; i<n_loss; ++i) {
799 G4bool yes = (aParticle == part_vector[i]);
803 auto ptr =
static_cast<G4VProcess*
>(p);
804 for(
G4int j=0; j<nvec; ++j) {
806 if(ptr == (*pvec)[j]) {
813 if(yes && isActive[i]) {
820 if (!tables_are_built[i]) {
826 tables_are_built[i] =
true;
830 t_list.push_back(dedx);
831 loss_list.push_back(p);
832 build_flags.push_back(val);
838 if (0 == n_dedx || !em) {
839 G4cout <<
"G4LossTableManager WARNING: no DEDX processes for "
846 G4cout <<
" Start to build the sum of " << n_dedx <<
" processes"
848 <<
" buildCSDARange= " << theParameters->BuildCSDARange()
849 <<
" nSubRegions= " << nSubRegions;
851 G4cout <<
" SubCutProducer " << subcutProducer->GetName();
856 if(subcutProducer) { nSubRegions = 0; }
864 tableBuilder->BuildDEDXTable(dedx, t_list);
868 dedx_vector[iem] = dedx;
872 range_vector[iem] = range;
876 inv_range_vector[iem] = invrange;
878 tableBuilder->BuildRangeTable(dedx, range);
879 tableBuilder->BuildInverseRangeTable(range, invrange);
884 std::vector<G4PhysicsTable*> listCSDA;
886 for (i=0; i<n_dedx; ++i) {
891 if(theParameters->BuildCSDARange()) {
894 listCSDA.push_back(dedx);
898 if(theParameters->BuildCSDARange()) {
902 tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
907 tableBuilder->BuildRangeTable(dedxCSDA, rCSDA);
912 G4cout <<
"G4LossTableManager::BuildTables: Tables are built for "
923void G4LossTableManager::ParticleHaveNoLoss(
927 ed <<
"Energy loss process not found for " << aParticle->
GetParticleName()
929 G4Exception(
"G4LossTableManager::ParticleHaveNoLoss",
"em0001",
942const std::vector<G4VEnergyLossProcess*>&
957const std::vector<G4VMultipleScattering*>&
967 return theParameters->GetEmSaturation();
974 if(!emConfigurator) {
977 return emConfigurator;
984 if(!emElectronIonPair) {
987 return emElectronIonPair;
994 if(
nullptr != ptr && ptr != nielCalculator) {
995 delete nielCalculator;
996 nielCalculator = ptr;
1004 if(!nielCalculator) {
1007 return nielCalculator;
1014 if(atomDeexcitation != p) {
1015 delete atomDeexcitation;
1016 atomDeexcitation = p;
1024 if(subcutProducer != p) {
1025 delete subcutProducer;
1034 G4String ss =
"G4LossTableManager::" + tit;
1057 char* dirName = std::getenv(
"G4PhysListDocDir");
1058 char* physList = std::getenv(
"G4PhysListName");
1059 if (dirName && physList) {
1063 std::ofstream outFile;
1064 outFile.open(pathName);
1066 outFile << physListName <<
G4endl;
1067 outFile << std::string(physListName.length(),
'=') <<
G4endl;
1069 std::vector<G4ParticleDefinition*> particles {
1079 std::vector<G4VEnergyLossProcess*> enloss_vector =
1081 std::vector<G4VMultipleScattering*> mscat_vector =
1084 for (
auto theParticle : particles) {
1085 outFile <<
G4endl <<
"**" << theParticle->GetParticleName()
1092 for (
auto emproc : emproc_vector) {
1093 for (
G4int i = 0; i < plen; ++i) {
1095 if (proc == emproc) {
1103 for (
auto mscproc : mscat_vector) {
1104 for (
G4int i = 0; i < plen; ++i) {
1106 if (proc == mscproc) {
1114 for (
auto enlossproc : enloss_vector) {
1115 for (
G4int i = 0; i < plen; ++i) {
1117 if (proc == enlossproc) {
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
static G4Electron * Electron()
static G4EmParameters * Instance()
void SetAtomDeexcitation(G4VAtomDeexcitation *)
static G4LossTableManager * Instance()
const std::vector< G4VEmProcess * > & GetEmProcessVector()
G4VEnergyLossProcess * GetEnergyLossProcess(const G4ParticleDefinition *)
void LocalPhysicsTables(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void BuildPhysicsTable(const G4ParticleDefinition *aParticle)
const std::vector< G4VMultipleScattering * > & GetMultipleScatteringVector()
void SetVerbose(G4int val)
void DeRegister(G4VEnergyLossProcess *p)
G4NIELCalculator * NIELCalculator()
void SetNIELCalculator(G4NIELCalculator *)
G4EmConfigurator * EmConfigurator()
void Register(G4VEnergyLossProcess *p)
G4ElectronIonPair * ElectronIonPair()
G4EmSaturation * EmSaturation()
const std::vector< G4VEnergyLossProcess * > & GetEnergyLossProcessVector()
void PreparePhysicsTable(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void SetSubCutProducer(G4VSubCutProducer *)
void RegisterExtraParticle(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
G4LossTableManager(G4LossTableManager &)=delete
static G4MuonMinus * MuonMinusDefinition()
static G4MuonPlus * MuonPlusDefinition()
G4ProcessManager * GetProcessManager() const
G4double GetPDGCharge() const
const G4String & GetParticleName() const
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
static G4Positron * Positron()
G4int GetProcessListLength() const
G4ProcessVector * GetProcessList() const
static G4Proton * ProtonDefinition()
const G4String & GetName() const
const G4String & GetName() const
const G4ParticleDefinition * BaseParticle() const
G4PhysicsTable * RangeTableForLoss() const
G4PhysicsTable * InverseRangeTable() const
G4PhysicsTable * CSDARangeTable() const
void SetRangeTableForLoss(G4PhysicsTable *p)
G4int NumberOfSubCutoffRegions() const
G4PhysicsTable * BuildDEDXTable(G4EmTableType tType=fRestricted)
const G4ParticleDefinition * Particle() const
void SetInverseRangeTable(G4PhysicsTable *p)
G4bool IsIonisationProcess() const
void SetDEDXTable(G4PhysicsTable *p, G4EmTableType tType)
G4PhysicsTable * BuildLambdaTable(G4EmTableType tType=fRestricted)
void SetLambdaTable(G4PhysicsTable *p)
G4PhysicsTable * IonisationTable() const
G4PhysicsTable * LambdaTable() const
void SetCSDARangeTable(G4PhysicsTable *pRange)
G4PhysicsTable * DEDXunRestrictedTable() const
G4PhysicsTable * DEDXTable() const
virtual void ProcessDescription(std::ostream &outfile) const
const G4String & GetProcessName() const
const G4String & GetName() const