129 for (
G4int i=0; i<n_loss; ++i) {
130 if( loss_vector[i] ) {
delete loss_vector[i]; }
132 size_t msc = msc_vector.size();
133 for (
size_t j=0; j<msc; ++j) {
134 if( msc_vector[j] ) {
delete msc_vector[j]; }
136 size_t emp = emp_vector.size();
137 for (
size_t k=0; k<emp; ++k) {
138 if( emp_vector[k] ) {
delete emp_vector[k]; }
140 size_t mod = mod_vector.size();
141 size_t fmod = fmod_vector.size();
142 for (
size_t a=0;
a<mod; ++
a) {
143 if( mod_vector[
a] ) {
144 for (
size_t b=0;
b<fmod; ++
b) {
145 if((
G4VEmModel*)(fmod_vector[
b]) == mod_vector[a]) {
149 delete mod_vector[
a];
152 for (
size_t b=0;
b<fmod; ++
b) {
153 if( fmod_vector[
b] ) {
delete fmod_vector[
b]; }
158 delete emCorrections;
160 delete emConfigurator;
161 delete emElectronIonPair;
162 delete atomDeexcitation;
167 G4LossTableManager::G4LossTableManager()
171 startInitialisation =
false;
172 all_tables_are_built =
false;
176 lossFluctuationFlag =
true;
177 subCutoffFlag =
false;
178 rndmStepFlag =
false;
180 maxRangeVariation = 1.0;
182 minKinEnergy = 0.1*
keV;
183 maxKinEnergy = 10.0*
TeV;
186 maxKinEnergyForMuons = 10.*
TeV;
188 integralActive =
false;
189 buildCSDARange =
false;
190 minEnergyActive =
false;
191 maxEnergyActive =
false;
192 maxEnergyForMuonsActive =
false;
193 stepFunctionActive =
false;
198 factorForAngleLimit = 1.0;
209 atomDeexcitation = 0;
220 all_tables_are_built =
false;
226 range_vector.clear();
227 inv_range_vector.clear();
231 base_part_vector.clear();
232 tables_are_built.clear();
243 for (
G4int i=0; i<n_loss; ++i) {
244 if(loss_vector[i] == p) {
return; }
247 G4cout <<
"G4LossTableManager::Register G4VEnergyLossProcess : "
251 loss_vector.push_back(p);
252 part_vector.push_back(0);
253 base_part_vector.push_back(0);
254 dedx_vector.push_back(0);
255 range_vector.push_back(0);
256 inv_range_vector.push_back(0);
257 tables_are_built.push_back(
false);
258 isActive.push_back(
true);
259 all_tables_are_built =
false;
275 for (
G4int i=0; i<n_loss; ++i) {
276 if(loss_vector[i] == p) { loss_vector[i] = 0; }
285 G4int n = msc_vector.size();
286 for (
G4int i=0; i<
n; ++i) {
287 if(msc_vector[i] == p) {
return; }
290 G4cout <<
"G4LossTableManager::Register G4VMultipleScattering : "
293 msc_vector.push_back(p);
301 size_t msc = msc_vector.size();
302 for (
size_t i=0; i<msc; ++i) {
303 if(msc_vector[i] == p) { msc_vector[i] = 0; }
312 G4int n = emp_vector.size();
313 for (
G4int i=0; i<
n; ++i) {
314 if(emp_vector[i] == p) {
return; }
317 G4cout <<
"G4LossTableManager::Register G4VEmProcess : "
320 emp_vector.push_back(p);
328 size_t emp = emp_vector.size();
329 for (
size_t i=0; i<emp; ++i) {
330 if(emp_vector[i] == p) { emp_vector[i] = 0; }
338 mod_vector.push_back(p);
340 G4cout <<
"G4LossTableManager::Register G4VEmModel : "
349 size_t n = mod_vector.size();
350 for (
size_t i=0; i<
n; ++i) {
351 if(mod_vector[i] == p) { mod_vector[i] = 0; }
359 fmod_vector.push_back(p);
361 G4cout <<
"G4LossTableManager::Register G4VEmFluctuationModel : "
370 size_t n = fmod_vector.size();
371 for (
size_t i=0; i<
n; ++i) {
372 if(fmod_vector[i] == p) { fmod_vector[i] = 0; }
382 if(!p || !part) {
return; }
383 for (
G4int i=0; i<n_loss; ++i) {
384 if(loss_vector[i] == p) {
return; }
387 G4cout <<
"G4LossTableManager::RegisterExtraParticle "
392 loss_vector.push_back(p);
393 part_vector.push_back(part);
395 dedx_vector.push_back(0);
396 range_vector.push_back(0);
397 inv_range_vector.push_back(0);
398 tables_are_built.push_back(
false);
399 all_tables_are_built =
false;
410 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
413 <<
" loss_vector " << loss_vector.size() <<
G4endl;
416 isMaster = theMaster;
418 if(!startInitialisation) {
421 G4cout <<
"====== G4LossTableManager::PreparePhysicsTable start ====="
431 for (
G4int j=0; j<n_loss; ++j) {
432 if (p == loss_vector[j] && !part_vector[j]) {
433 part_vector[j] = particle;
435 theGenericIon = particle;
440 startInitialisation =
true;
450 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
454 isMaster = theMaster;
456 if(!startInitialisation) {
459 G4cout <<
"====== G4LossTableManager::PreparePhysicsTable start ====="
468 startInitialisation =
true;
479 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
484 isMaster = theMaster;
486 if(!startInitialisation) {
489 G4cout <<
"====== G4LossTableManager::PreparePhysicsTable start ====="
498 startInitialisation =
true;
506 if(-1 == run && startInitialisation) {
507 emConfigurator->
Clear();
518 G4cout <<
"### G4LossTableManager::SlavePhysicsTable() for "
524 if(-1 == run && startInitialisation) {
525 emConfigurator->
Clear();
526 firstParticle = aParticle;
529 if(startInitialisation) {
533 G4cout <<
"===== G4LossTableManager::SlavePhysicsTable() for run "
534 << run <<
" =====" <<
G4endl;
536 if(atomDeexcitation) {
540 startInitialisation =
false;
541 for (
G4int i=0; i<n_loss; ++i) {
543 tables_are_built[i] =
false;
545 tables_are_built[i] =
true;
551 all_tables_are_built=
true;
552 for (
G4int i=0; i<n_loss; ++i) {
553 if(p == loss_vector[i]) {
554 tables_are_built[i] =
true;
567 loss_map[part_vector[i]] = loss_vector[i];
573 G4cout <<
" for " << part_vector[i]->GetParticleName();
575 G4cout <<
" active= " << isActive[i]
576 <<
" table= " << tables_are_built[i]
581 }
else if(!tables_are_built[i]) {
582 all_tables_are_built =
false;
587 SetParameters(aParticle, p);
590 G4cout <<
"### G4LossTableManager::SlavePhysicsTable end"
593 if(all_tables_are_built) {
595 G4cout <<
"%%%%% All dEdx and Range tables for worker are ready for run "
596 << run <<
" %%%%%" <<
G4endl;
608 G4cout <<
"### G4LossTableManager::BuildPhysicsTable() for "
613 if(-1 == run && startInitialisation) {
614 emConfigurator->
Clear();
615 firstParticle = aParticle;
617 if(startInitialisation) {
620 G4cout <<
"===== G4LossTableManager::BuildPhysicsTable() for run "
621 << run <<
" =====" <<
G4endl;
623 if(atomDeexcitation) {
627 all_tables_are_built=
true;
631 if ( startInitialisation && aParticle == firstParticle ) {
633 startInitialisation =
false;
635 G4cout <<
"### G4LossTableManager start initilisation for first particle "
639 for (
G4int i=0; i<n_loss; ++i) {
650 tables_are_built[i] =
false;
651 all_tables_are_built=
false;
654 tables_are_built[i] =
true;
662 G4cout <<
" active= " << isActive[i]
663 <<
" table= " << tables_are_built[i]
665 if(base_part_vector[i]) {
666 G4cout <<
" base particle "
667 << base_part_vector[i]->GetParticleName();
672 tables_are_built[i] =
true;
680 SetParameters(aParticle, p);
682 if (all_tables_are_built) {
return; }
685 all_tables_are_built =
true;
687 for(
G4int i=0; i<n_loss; ++i) {
688 if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
695 if(curr_proc) { CopyTables(curr_part, curr_proc); }
697 if ( !tables_are_built[i] ) { all_tables_are_built =
false; }
702 G4cout <<
"### G4LossTableManager::BuildPhysicsTable end: "
703 <<
"all_tables_are_built= " << all_tables_are_built
706 if(all_tables_are_built) {
708 G4cout <<
"%%%%% All dEdx and Range tables are built for master run= "
709 << run <<
" %%%%%" <<
G4endl;
719 for (
G4int j=0; j<n_loss; ++j) {
723 if (!tables_are_built[j] && part == base_part_vector[j]) {
724 tables_are_built[j] =
true;
737 loss_map[part_vector[j]] = proc;
741 <<
" for " << part_vector[j]->GetParticleName()
743 <<
" tables are assigned "
760 G4cout <<
"G4LossTableManager::BuildTables() for "
764 std::vector<G4PhysicsTable*> t_list;
765 std::vector<G4VEnergyLossProcess*> loss_list;
777 for (i=0; i<n_loss; ++i) {
780 G4bool yes = (aParticle == part_vector[i]);
785 for(
G4int j=0; j<nvec; ++j) {
787 if(ptr == (*pvec)[j]) {
794 if(yes && isActive[i]) {
800 if (!tables_are_built[i]) {
805 tables_are_built[i] =
true;
810 loss_list.push_back(p);
815 G4int n_dedx = t_list.size();
816 if (0 == n_dedx || !em) {
817 G4cout <<
"G4LossTableManager WARNING: no DEDX processes for "
824 G4cout <<
"G4LossTableManager::BuildTables() start to build range tables"
825 <<
" and the sum of " << n_dedx <<
" processes"
827 <<
" buildCSDARange= " << buildCSDARange
828 <<
" nSubRegions= " << nSubRegions
851 dedx_vector[iem] = dedx;
855 range_vector[iem] = range;
859 inv_range_vector[iem] = invrange;
871 std::vector<G4PhysicsTable*> listSub;
872 std::vector<G4PhysicsTable*> listCSDA;
874 for (i=0; i<n_dedx; ++i) {
878 if (0 < nSubRegions) {
881 listSub.push_back(dedx);
888 listCSDA.push_back(dedx);
892 if (0 < nSubRegions) {
894 if (1 < listSub.size()) {
917 G4cout <<
"G4LossTableManager::BuildTables: Tables are built for "
934 void G4LossTableManager::ParticleHaveNoLoss(
938 ed <<
"Energy loss process not found for " << aParticle->
GetParticleName()
940 G4Exception(
"G4LossTableManager::ParticleHaveNoLoss",
"em0001",
949 return buildCSDARange;
956 lossFluctuationFlag = val;
957 for(
G4int i=0; i<n_loss; ++i) {
958 if(loss_vector[i]) { loss_vector[i]->SetLossFluctuations(val); }
967 for(
G4int i=0; i<n_loss; ++i) {
968 if(loss_vector[i]) { loss_vector[i]->ActivateSubCutoff(val, r); }
977 integralActive =
true;
978 for(
G4int i=0; i<n_loss; ++i) {
979 if(loss_vector[i]) { loss_vector[i]->SetIntegral(val); }
981 size_t emp = emp_vector.size();
982 for (
size_t k=0; k<emp; ++k) {
983 if(emp_vector[k]) { emp_vector[k]->SetIntegral(val); }
992 for(
G4int i=0; i<n_loss; ++i) {
993 if(loss_vector[i]) { loss_vector[i]->SetMinSubRange(val); }
1002 for(
G4int i=0; i<n_loss; ++i) {
1003 if(loss_vector[i]) { loss_vector[i]->SetRandomStep(val); }
1011 minEnergyActive =
true;
1013 for(
G4int i=0; i<n_loss; ++i) {
1014 if(loss_vector[i]) { loss_vector[i]->SetMinKinEnergy(val); }
1016 size_t emp = emp_vector.size();
1017 for (
size_t k=0; k<emp; ++k) {
1018 if(emp_vector[k]) { emp_vector[k]->SetMinKinEnergy(val); }
1026 maxEnergyActive =
true;
1028 for(
G4int i=0; i<n_loss; ++i) {
1029 if(loss_vector[i]) { loss_vector[i]->SetMaxKinEnergy(val); }
1031 size_t emp = emp_vector.size();
1032 for (
size_t k=0; k<emp; ++k) {
1033 if(emp_vector[k]) { emp_vector[k]->SetMaxKinEnergy(val); }
1041 for(
G4int i=0; i<n_loss; ++i) {
1042 if(loss_vector[i]) { loss_vector[i]->SetMaxKinEnergyForCSDARange(val); }
1050 maxEnergyForMuonsActive =
true;
1051 maxKinEnergyForMuons = val;
1058 for(
G4int i=0; i<n_loss; ++i) {
1059 if(loss_vector[i]) { loss_vector[i]->SetDEDXBinning(val); }
1067 for(
G4int i=0; i<n_loss; ++i) {
1068 if(loss_vector[i]) { loss_vector[i]->SetDEDXBinningForCSDARange(val); }
1076 G4int n = val/
G4int(std::log10(maxKinEnergy/minKinEnergy) + 0.5);
1078 G4cout <<
"G4LossTableManager::SetLambdaBinning WARNING "
1079 <<
"too small number of bins " << val <<
" ignored"
1085 size_t emp = emp_vector.size();
1086 for (
size_t k=0; k<emp; ++k) {
1087 if(emp_vector[k]) { emp_vector[k]->SetLambdaBinning(val); }
1095 return nbinsPerDecade;
1103 for(
G4int i=0; i<n_loss; ++i) {
1104 if(loss_vector[i]) { loss_vector[i]->SetVerboseLevel(val); }
1106 size_t msc = msc_vector.size();
1107 for (
size_t j=0; j<msc; ++j) {
1108 if(msc_vector[j]) { msc_vector[j]->SetVerboseLevel(val); }
1110 size_t emp = emp_vector.size();
1111 for (
size_t k=0; k<emp; ++k) {
1112 if(emp_vector[k]) { emp_vector[k]->SetVerboseLevel(val); }
1126 stepFunctionActive =
true;
1127 maxRangeVariation = v1;
1129 for(
G4int i=0; i<n_loss; ++i) {
1130 if(loss_vector[i]) { loss_vector[i]->SetStepFunction(v1, v2); }
1138 for(
G4int i=0; i<n_loss; ++i) {
1139 if(loss_vector[i]) { loss_vector[i]->SetLinearLossLimit(val); }
1147 buildCSDARange = val;
1156 if(stepFunctionActive) {
1163 if(maxEnergyForMuonsActive) {
1171 const std::vector<G4VEnergyLossProcess*>&
1186 const std::vector<G4VMultipleScattering*>&
1246 if(val > 0.0) { factorForAngleLimit = val; }
1253 return factorForAngleLimit;
1260 return minKinEnergy;
1267 return maxKinEnergy;
1274 return emCorrections;
1281 return emSaturation;
1288 return emConfigurator;
1295 return emElectronIonPair;
1302 return atomDeexcitation;
1309 return tableBuilder;
1316 atomDeexcitation =
p;
1324 if(aParticle != currentParticle) {
1325 currentParticle = aParticle;
1326 std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
1327 if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
1328 currentLoss = (*pos).second;
1332 if ((pos = loss_map.find(theGenericIon)) != loss_map.end()) {
1333 currentLoss = (*pos).second;
1349 if(currentLoss) { x = currentLoss->
GetDEDX(kineticEnergy, couple); }
1361 if(currentLoss) { x = currentLoss->
GetDEDXForSubsec(kineticEnergy, couple); }
1373 if(currentLoss) { x = currentLoss->
GetCSDARange(kineticEnergy, couple); }
1386 if(currentLoss) { x = currentLoss->
GetRangeForLoss(kineticEnergy, couple); }
1398 if(currentLoss) { x = currentLoss->
GetRange(kineticEnergy, couple); }
G4double GetKineticEnergy(G4double &range, const G4MaterialCutsCouple *)
G4EmConfigurator * EmConfigurator()
void SetRandomStep(G4bool val)
void BuildRangeTable(const G4PhysicsTable *dedxTable, G4PhysicsTable *rangeTable, G4bool isIonisation=false)
void SetDEDXTable(G4PhysicsTable *p, G4EmTableType tType)
void SetIntegral(G4bool val)
G4bool SplineFlag() const
static G4LossTableManager * Instance()
void InitialiseAtomicDeexcitation()
std::ostringstream G4ExceptionDescription
G4double GetDEDX(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
void SetIonisation(G4bool val)
void SetBremsstrahlungTh(G4double val)
G4double GetDEDX(G4double &kineticEnergy, const G4MaterialCutsCouple *)
G4PhysicsTable * SubLambdaTable() const
G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple, const G4DynamicParticle *dp, G4double &length)
void DeRegister(G4VEnergyLossProcess *p)
G4PhysicsTable * RangeTableForLoss() const
void SetLambdaBinning(G4int val)
G4double GetSubDEDX(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
G4bool BuildCSDARange() const
void push_back(G4PhysicsVector *)
G4double GetRangeForLoss(G4double &kineticEnergy, const G4MaterialCutsCouple *)
void AddCollaborativeProcess(G4VEnergyLossProcess *)
void SetStepFunction(G4double v1, G4double v2)
G4PhysicsTable * CSDARangeTable() const
G4double GetCSDARange(G4double &kineticEnergy, const G4MaterialCutsCouple *)
G4EnergyLossMessenger * GetMessenger()
G4double FactorForAngleLimit() const
void SetFactorForAngleLimit(G4double val)
G4PhysicsTable * IonisationTableForSubsec() const
G4double GetDEDXForSubsec(G4double &kineticEnergy, const G4MaterialCutsCouple *)
G4ProcessManager * GetProcessManager() const
const std::vector< G4VEmProcess * > & GetEmProcessVector()
G4PhysicsTable * BuildLambdaTable(G4EmTableType tType=fRestricted)
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
const G4String & GetParticleName() const
G4double GetCSDARange(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
G4LossTableBuilder * GetTableBuilder()
void SetVerboseLevel(G4int)
void SetBuildCSDARange(G4bool val)
void SetInitialisationFlag(G4bool flag)
G4PhysicsTable * LambdaTable() const
void SetInverseRangeTable(G4PhysicsTable *p)
const G4ParticleDefinition * SecondaryParticle() const
G4GLOB_DLL std::ostream G4cout
G4PhysicsTable * DEDXTable() const
G4double MinKinEnergy() const
void SetLPMFlag(G4bool val)
G4EmCorrections * EmCorrections()
void SetLossFluctuations(G4bool val)
G4ElectronIonPair * ElectronIonPair()
G4EmSaturation * EmSaturation()
void SetMaxEnergyForCSDARange(G4double val)
G4int NumberOfSubCutoffRegions() const
const G4String & GetParticleType() const
void SetMaxKinEnergy(G4double e)
void Register(G4VEnergyLossProcess *p)
const G4ParticleDefinition * BaseParticle() const
const G4ParticleDefinition * GetParticleDefinition() const
void SetDEDXBinningForCSDARange(G4int val)
void BuildInverseRangeTable(const G4PhysicsTable *rangeTable, G4PhysicsTable *invRangeTable, G4bool isIonisation=false)
G4PhysicsTable * DEDXTableForSubsec() const
G4double GetEnergy(const G4ParticleDefinition *aParticle, G4double range, const G4MaterialCutsCouple *couple)
const G4String & GetProcessName() const
const std::vector< G4VEnergyLossProcess * > & GetEnergyLossProcessVector()
void SetSubCutoff(G4bool val, const G4Region *r=0)
G4double BremsstrahlungTh() const
G4double GetRangeFromRestricteDEDX(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
void RegisterExtraParticle(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
void BuildDEDXTable(G4PhysicsTable *dedxTable, const std::vector< G4PhysicsTable * > &)
void SetVerbose(G4int value)
void SetMinSubRange(G4double val)
void SetMinEnergy(G4double val)
G4VEnergyLossProcess * GetEnergyLossProcess(const G4ParticleDefinition *)
void SetLambdaTable(G4PhysicsTable *p)
void SetMaxEnergy(G4double val)
void SetStepFunction(G4double v1, G4double v2)
G4PhysicsTable * InverseRangeTable() const
void BuildPhysicsTable(const G4ParticleDefinition *aParticle)
G4double GetPDGMass() const
const G4ParticleDefinition * Particle() const
void SetLinearLossLimit(G4double val)
G4int GetNumberOfBinsPerDecade() const
void PrepareModels(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void PreparePhysicsTable(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p, G4bool theMaster)
void SetCSDARangeTable(G4PhysicsTable *pRange)
G4double GetDEDXDispersion(const G4MaterialCutsCouple *couple, const G4DynamicParticle *dp, G4double length)
void SetVerbose(G4int val)
void LocalPhysicsTables(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void SetDEDXBinning(G4int val)
void SetMaxEnergyForMuons(G4double val)
static G4Electron * Electron()
void SetIntegral(G4bool val)
void SetLossFluctuations(G4bool val)
const G4String & GetName() const
void SetSecondaryRangeTable(G4PhysicsTable *p)
G4VAtomDeexcitation * AtomDeexcitation()
G4PhysicsTable * DEDXunRestrictedTable() const
void SetSubLambdaTable(G4PhysicsTable *p)
void ActivateSubCutoff(G4bool val, const G4Region *region=0)
void SetRangeTableForLoss(G4PhysicsTable *p)
G4double MaxKinEnergy() const
G4double GetRange(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
void SetAtomDeexcitation(G4VAtomDeexcitation *)
G4PhysicsTable * BuildDEDXTable(G4EmTableType tType=fRestricted)
void SetSplineFlag(G4bool val)
const std::vector< G4VMultipleScattering * > & GetMultipleScatteringVector()
G4ProcessVector * GetProcessList() const
G4double GetRange(G4double &kineticEnergy, const G4MaterialCutsCouple *)
void SetRandomStep(G4bool val)
void SetSplineFlag(G4bool flag)
G4bool IsIonisationProcess() const
void SetMinKinEnergy(G4double e)