109 if(0 == theInstance) {
111 theInstance = &manager;
120 for (
G4int i=0; i<n_loss; ++i) {
121 if( loss_vector[i] ) {
delete loss_vector[i]; }
123 size_t msc = msc_vector.size();
124 for (
size_t j=0; j<msc; ++j) {
125 if( msc_vector[j] ) {
delete msc_vector[j]; }
127 size_t emp = emp_vector.size();
128 for (
size_t k=0; k<emp; ++k) {
129 if( emp_vector[k] ) {
delete emp_vector[k]; }
131 size_t mod = mod_vector.size();
132 for (
size_t a=0;
a<mod; ++
a) {
133 if( mod_vector[
a] ) {
delete mod_vector[
a]; }
135 size_t fmod = fmod_vector.size();
136 for (
size_t b=0;
b<fmod; ++
b) {
137 if( fmod_vector[
b] ) {
delete fmod_vector[
b]; }
142 delete emCorrections;
144 delete emConfigurator;
145 delete emElectronIonPair;
146 delete atomDeexcitation;
151 G4LossTableManager::G4LossTableManager()
155 startInitialisation =
false;
156 all_tables_are_built =
false;
160 lossFluctuationFlag =
true;
161 subCutoffFlag =
false;
162 rndmStepFlag =
false;
164 maxRangeVariation = 1.0;
166 minKinEnergy = 0.1*
keV;
167 maxKinEnergy = 10.0*
TeV;
170 maxKinEnergyForMuons = 10.*
TeV;
172 integralActive =
false;
173 buildCSDARange =
false;
174 minEnergyActive =
false;
175 maxEnergyActive =
false;
176 maxEnergyForMuonsActive =
false;
177 stepFunctionActive =
false;
181 factorForAngleLimit = 1.0;
191 atomDeexcitation = 0;
198 all_tables_are_built =
false;
204 range_vector.clear();
205 inv_range_vector.clear();
209 base_part_vector.clear();
210 tables_are_built.clear();
221 for (
G4int i=0; i<n_loss; ++i) {
222 if(loss_vector[i] == p) {
return; }
225 G4cout <<
"G4LossTableManager::Register G4VEnergyLossProcess : "
229 loss_vector.push_back(p);
230 part_vector.push_back(0);
231 base_part_vector.push_back(0);
232 dedx_vector.push_back(0);
233 range_vector.push_back(0);
234 inv_range_vector.push_back(0);
235 tables_are_built.push_back(
false);
236 isActive.push_back(
true);
237 all_tables_are_built =
false;
241 if(stepFunctionActive) { p->
SetStepFunction(maxRangeVariation, maxFinalStep); }
252 for (
G4int i=0; i<n_loss; ++i) {
253 if(loss_vector[i] == p) { loss_vector[i] = 0; }
262 G4int n = msc_vector.size();
263 for (
G4int i=0; i<
n; ++i) {
264 if(msc_vector[i] == p) {
return; }
267 G4cout <<
"G4LossTableManager::Register G4VMultipleScattering : "
270 msc_vector.push_back(p);
278 size_t msc = msc_vector.size();
279 for (
size_t i=0; i<msc; ++i) {
280 if(msc_vector[i] == p) { msc_vector[i] = 0; }
289 G4int n = emp_vector.size();
290 for (
G4int i=0; i<
n; ++i) {
291 if(emp_vector[i] == p) {
return; }
294 G4cout <<
"G4LossTableManager::Register G4VEmProcess : "
297 emp_vector.push_back(p);
305 size_t emp = emp_vector.size();
306 for (
size_t i=0; i<emp; ++i) {
307 if(emp_vector[i] == p) { emp_vector[i] = 0; }
315 mod_vector.push_back(p);
317 G4cout <<
"G4LossTableManager::Register G4VEmModel : "
326 size_t n = mod_vector.size();
327 for (
size_t i=0; i<
n; ++i) {
328 if(mod_vector[i] == p) { mod_vector[i] = 0; }
336 fmod_vector.push_back(p);
338 G4cout <<
"G4LossTableManager::Register G4VEmFluctuationModel : "
347 size_t n = fmod_vector.size();
348 for (
size_t i=0; i<
n; ++i) {
349 if(fmod_vector[i] == p) { fmod_vector[i] = 0; }
367 if(!p || !part) {
return; }
368 for (
G4int i=0; i<n_loss; ++i) {
369 if(loss_vector[i] == p) {
return; }
372 G4cout <<
"G4LossTableManager::RegisterExtraParticle "
377 loss_vector.push_back(p);
378 part_vector.push_back(part);
380 dedx_vector.push_back(0);
381 range_vector.push_back(0);
382 inv_range_vector.push_back(0);
383 tables_are_built.push_back(
false);
384 all_tables_are_built =
false;
394 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
397 <<
" loss_vector " << loss_vector.size() <<
G4endl;
402 startInitialisation =
true;
408 for (
G4int j=0; j<n_loss; ++j) {
409 if (p == loss_vector[j]) {
410 if (!part_vector[j]) { part_vector[j] = particle; }
423 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
433 startInitialisation =
true;
443 G4cout <<
"G4LossTableManager::PreparePhysicsTable for "
460 if(0 == run && startInitialisation) {
461 emConfigurator->
Clear();
472 G4cout <<
"### G4LossTableManager::BuildDEDXTable() is requested for "
477 if(0 == run && startInitialisation) {
478 emConfigurator->
Clear();
479 firstParticle = aParticle;
481 if(startInitialisation && atomDeexcitation) {
484 startInitialisation =
false;
487 if ( aParticle == firstParticle ) {
488 all_tables_are_built =
true;
491 G4cout <<
"### G4LossTableManager start initilisation for first particle "
495 for (
G4int i=0; i<n_loss; ++i) {
502 if(0 == run) { base_part_vector[i] = el->
BaseParticle(); }
503 tables_are_built[i] =
false;
504 all_tables_are_built=
false;
512 G4cout <<
" active= " << isActive[i]
513 <<
" table= " << tables_are_built[i]
515 if(base_part_vector[i]) {
516 G4cout <<
" base particle " << base_part_vector[i]->GetParticleName();
521 tables_are_built[i] =
true;
530 SetParameters(aParticle, p);
532 if (all_tables_are_built) {
return; }
535 all_tables_are_built =
true;
537 for(
G4int i=0; i<n_loss; ++i) {
538 if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
543 <<
" start BuildTable " <<
G4endl;
546 if(curr_proc) { CopyTables(curr_part, curr_proc); }
548 if ( !tables_are_built[i] ) { all_tables_are_built =
false; }
552 G4cout <<
"### G4LossTableManager::BuildDEDXTable end: "
553 <<
"all_tables_are_built= " << all_tables_are_built
556 if(all_tables_are_built) {
557 G4cout <<
"### All dEdx and Range tables are built #####" <<
G4endl;
567 for (
G4int j=0; j<n_loss; ++j) {
573 if (!tables_are_built[j] && part == base_part_vector[j]) {
574 tables_are_built[j] =
true;
584 loss_map[part_vector[j]] = proc;
587 <<
" for " << part_vector[j]->GetParticleName()
589 <<
" tables are assigned "
606 G4cout <<
"G4LossTableManager::BuildTables() for "
610 std::vector<G4PhysicsTable*> t_list;
611 std::vector<G4VEnergyLossProcess*> loss_list;
619 for (i=0; i<n_loss; ++i) {
621 if (p && aParticle == part_vector[i] && !tables_are_built[i]) {
623 !em || (em && !isActive[iem]) ) {
631 t_list.push_back(dedx);
632 loss_list.push_back(p);
633 tables_are_built[i] =
true;
637 G4int n_dedx = t_list.size();
638 if (0 == n_dedx || !em) {
639 G4cout <<
"G4LossTableManager WARNING: no DEDX processes for "
646 G4cout <<
"G4LossTableManager::BuildTables() start to build range tables"
647 <<
" and the sum of " << n_dedx <<
" processes"
649 <<
" buildCSDARange= " << buildCSDARange
650 <<
" nSubRegions= " << nSubRegions
662 dedx_vector[iem] = dedx;
666 range_vector[iem] = range;
670 inv_range_vector[iem] = invrange;
683 std::vector<G4PhysicsTable*> listSub;
684 std::vector<G4PhysicsTable*> listCSDA;
686 for (i=0; i<n_dedx; ++i) {
690 if (0 < nSubRegions) {
693 listSub.push_back(dedx);
700 listCSDA.push_back(dedx);
704 if (0 < nSubRegions) {
706 if (1 < listSub.size()) {
729 loss_map[aParticle] = em;
732 G4cout <<
"G4LossTableManager::BuildTables: Tables are built for "
749 void G4LossTableManager::ParticleHaveNoLoss(
753 ed <<
"Energy loss process not found for " << aParticle->
GetParticleName()
755 G4Exception(
"G4LossTableManager::ParticleHaveNoLoss",
"em0001",
764 return buildCSDARange;
771 lossFluctuationFlag = val;
772 for(
G4int i=0; i<n_loss; ++i) {
773 if(loss_vector[i]) { loss_vector[i]->SetLossFluctuations(val); }
782 for(
G4int i=0; i<n_loss; ++i) {
783 if(loss_vector[i]) { loss_vector[i]->ActivateSubCutoff(val, r); }
792 integralActive =
true;
793 for(
G4int i=0; i<n_loss; ++i) {
794 if(loss_vector[i]) { loss_vector[i]->SetIntegral(val); }
796 size_t emp = emp_vector.size();
797 for (
size_t k=0; k<emp; ++k) {
798 if(emp_vector[k]) { emp_vector[k]->SetIntegral(val); }
807 for(
G4int i=0; i<n_loss; ++i) {
808 if(loss_vector[i]) { loss_vector[i]->SetMinSubRange(val); }
817 for(
G4int i=0; i<n_loss; ++i) {
818 if(loss_vector[i]) { loss_vector[i]->SetRandomStep(val); }
826 minEnergyActive =
true;
828 for(
G4int i=0; i<n_loss; ++i) {
829 if(loss_vector[i]) { loss_vector[i]->SetMinKinEnergy(val); }
831 size_t emp = emp_vector.size();
832 for (
size_t k=0; k<emp; ++k) {
833 if(emp_vector[k]) { emp_vector[k]->SetMinKinEnergy(val); }
841 maxEnergyActive =
true;
843 for(
G4int i=0; i<n_loss; ++i) {
844 if(loss_vector[i]) { loss_vector[i]->SetMaxKinEnergy(val); }
846 size_t emp = emp_vector.size();
847 for (
size_t k=0; k<emp; ++k) {
848 if(emp_vector[k]) { emp_vector[k]->SetMaxKinEnergy(val); }
856 for(
G4int i=0; i<n_loss; ++i) {
857 if(loss_vector[i]) { loss_vector[i]->SetMaxKinEnergyForCSDARange(val); }
865 maxEnergyForMuonsActive =
true;
866 maxKinEnergyForMuons = val;
873 for(
G4int i=0; i<n_loss; ++i) {
874 if(loss_vector[i]) { loss_vector[i]->SetDEDXBinning(val); }
882 for(
G4int i=0; i<n_loss; ++i) {
883 if(loss_vector[i]) { loss_vector[i]->SetDEDXBinningForCSDARange(val); }
891 G4int n = val/
G4int(std::log10(maxKinEnergy/minKinEnergy) + 0.5);
893 G4cout <<
"G4LossTableManager::SetLambdaBinning WARNING "
894 <<
"too small number of bins " << val <<
" ignored"
900 size_t emp = emp_vector.size();
901 for (
size_t k=0; k<emp; ++k) {
902 if(emp_vector[k]) { emp_vector[k]->SetLambdaBinning(val); }
910 return nbinsPerDecade;
918 for(
G4int i=0; i<n_loss; ++i) {
919 if(loss_vector[i]) { loss_vector[i]->SetVerboseLevel(val); }
921 size_t msc = msc_vector.size();
922 for (
size_t j=0; j<msc; ++j) {
923 if(msc_vector[j]) { msc_vector[j]->SetVerboseLevel(val); }
925 size_t emp = emp_vector.size();
926 for (
size_t k=0; k<emp; ++k) {
927 if(emp_vector[k]) { emp_vector[k]->SetVerboseLevel(val); }
941 stepFunctionActive =
true;
942 maxRangeVariation = v1;
944 for(
G4int i=0; i<n_loss; ++i) {
945 if(loss_vector[i]) { loss_vector[i]->SetStepFunction(v1, v2); }
953 for(
G4int i=0; i<n_loss; ++i) {
954 if(loss_vector[i]) { loss_vector[i]->SetLinearLossLimit(val); }
962 buildCSDARange = val;
971 if(stepFunctionActive) { p->
SetStepFunction(maxRangeVariation, maxFinalStep); }
976 if(maxEnergyForMuonsActive) {
984 const std::vector<G4VEnergyLossProcess*>&
999 const std::vector<G4VMultipleScattering*>&
1052 if(val > 0.0) { factorForAngleLimit = val; }
1059 return factorForAngleLimit;
1066 return minKinEnergy;
1073 return maxKinEnergy;
1080 return emCorrections;
1087 return emSaturation;
1094 return emConfigurator;
1101 return emElectronIonPair;
1108 return atomDeexcitation;
1115 return tableBuilder;
1122 atomDeexcitation =
p;
1130 if(aParticle != currentParticle) {
1131 currentParticle = aParticle;
1132 std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
1133 if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
1134 currentLoss = (*pos).second;
1151 if(currentLoss) { x = currentLoss->
GetDEDX(kineticEnergy, couple); }
1153 kineticEnergy,couple,
false); }
1165 if(currentLoss) { x = currentLoss->
GetDEDXForSubsec(kineticEnergy, couple); }
1177 if(currentLoss) { x = currentLoss->
GetCSDARange(kineticEnergy, couple); }
1190 if(currentLoss) { x = currentLoss->
GetRangeForLoss(kineticEnergy, couple); }
1204 if(currentLoss) { x = currentLoss->
GetRange(kineticEnergy, couple); }