Geant4  10.02
G4LossTableManager.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // $Id: G4LossTableManager.cc 92921 2015-09-21 15:06:51Z gcosmo $
27 //
28 // -------------------------------------------------------------------
29 //
30 // GEANT4 Class file
31 //
32 //
33 // File name: G4LossTableManager
34 //
35 // Author: Vladimir Ivanchenko
36 //
37 // Creation date: 03.01.2002
38 //
39 // Modifications:
40 //
41 // 20-01-03 Migrade to cut per region (V.Ivanchenko)
42 // 15-02-03 Lambda table can be scaled (V.Ivanchenko)
43 // 17-02-03 Fix problem of store/restore tables (V.Ivanchenko)
44 // 10-03-03 Add Ion registration (V.Ivanchenko)
45 // 25-03-03 Add deregistration (V.Ivanchenko)
46 // 02-04-03 Change messenger (V.Ivanchenko)
47 // 26-04-03 Fix retrieve tables (V.Ivanchenko)
48 // 13-05-03 Add calculation of precise range (V.Ivanchenko)
49 // 23-07-03 Add exchange with G4EnergyLossTables (V.Ivanchenko)
50 // 05-10-03 Add G4VEmProcesses registration and Verbose command (V.Ivanchenko)
51 // 17-10-03 Add SetParameters method (V.Ivanchenko)
52 // 23-10-03 Add control on inactive processes (V.Ivanchenko)
53 // 04-11-03 Add checks in RetrievePhysicsTable (V.Ivanchenko)
54 // 12-11-03 G4EnergyLossSTD -> G4EnergyLossProcess (V.Ivanchenko)
55 // 14-01-04 Activate precise range calculation (V.Ivanchenko)
56 // 10-03-04 Fix a problem of Precise Range table (V.Ivanchenko)
57 // 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivanchenko)
58 // 13-01-04 Fix problem which takes place for inactivate eIoni (V.Ivanchenko)
59 // 25-01-04 Fix initialisation problem for ions (V.Ivanchenko)
60 // 11-03-05 Shift verbose level by 1 (V.Ivantchenko)
61 // 10-01-06 PreciseRange -> CSDARange (V.Ivantchenko)
62 // 20-01-06 Introduce G4EmTableType to remove repeating code (VI)
63 // 23-03-06 Set flag isIonisation (VI)
64 // 10-05-06 Add methods SetMscStepLimitation, FacRange and MscFlag (VI)
65 // 22-05-06 Add methods Set/Get bremsTh (VI)
66 // 05-06-06 Do not clear loss_table map between runs (VI)
67 // 16-01-07 Create new energy loss table for e+,e-,mu+,mu- and
68 // left ionisation table for further usage (VI)
69 // 12-02-07 Add SetSkin, SetLinearLossLimit (V.Ivanchenko)
70 // 18-06-07 Move definition of msc parameters to G4EmProcessOptions (V.Ivanchenko)
71 // 21-02-08 Added G4EmSaturation (V.Ivanchenko)
72 // 12-04-10 Added PreparePhysicsTables and BuildPhysicsTables entries (V.Ivanchenko)
73 // 04-06-13 (V.Ivanchenko) Adaptation for MT mode; new method LocalPhysicsTables;
74 // ions expect G4GenericIon are not included in the map of energy loss
75 // processes for performnc reasons
76 //
77 // Class Description:
78 //
79 // -------------------------------------------------------------------
80 //
81 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
83 
84 #include "G4LossTableManager.hh"
85 #include "G4SystemOfUnits.hh"
86 #include "G4EnergyLossMessenger.hh"
87 
88 #include "G4VMultipleScattering.hh"
89 #include "G4VEmProcess.hh"
90 
91 #include "G4EmSaturation.hh"
92 #include "G4EmConfigurator.hh"
93 #include "G4ElectronIonPair.hh"
94 
95 #include "G4PhysicsTable.hh"
96 #include "G4ParticleDefinition.hh"
97 #include "G4MaterialCutsCouple.hh"
98 #include "G4ProcessManager.hh"
99 #include "G4Electron.hh"
100 #include "G4Proton.hh"
101 #include "G4ProductionCutsTable.hh"
102 #include "G4PhysicsTableHelper.hh"
103 #include "G4EmTableType.hh"
104 #include "G4Region.hh"
105 #include "G4PhysicalConstants.hh"
106 #include "G4Threading.hh"
107 
108 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
109 
111 
113 {
114  if(!instance) {
116  instance = inst.Instance();
117  }
118  return instance;
119 }
120 
121 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
122 
124 {
125  //G4cout << "### G4LossTableManager::~G4LossTableManager()" << G4endl;
126  for (G4int i=0; i<n_loss; ++i) {
127  //G4cout << "### eloss #" << i << G4endl;
128  if( loss_vector[i] ) {
129  delete loss_vector[i];
130  }
131  }
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]; }
135  }
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]; }
139  }
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]) {
146  fmod_vector[b] = 0;
147  }
148  }
149  delete mod_vector[a];
150  }
151  }
152  for (size_t b=0; b<fmod; ++b) {
153  if( fmod_vector[b] ) { delete fmod_vector[b]; }
154  }
155  Clear();
156  delete theMessenger;
157  delete tableBuilder;
158  delete emCorrections;
159  delete emSaturation;
160  delete emConfigurator;
161  delete emElectronIonPair;
162  delete atomDeexcitation;
163  delete subcutProducer;
164 }
165 
166 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
167 
169 {
171  n_loss = 0;
172  run = -1;
173  startInitialisation = false;
174  all_tables_are_built = false;
175  currentLoss = nullptr;
176  currentParticle = nullptr;
177  firstParticle = nullptr;
178  subCutoffFlag = false;
179  maxRangeVariation = 0.2;
181  integral = true;
182  integralActive = false;
183  stepFunctionActive = false;
184  isMaster = true;
188  theGenericIon= nullptr;
191  isMaster = false;
192  }
195  emSaturation = nullptr;
196  emConfigurator = nullptr;
197  emElectronIonPair = nullptr;
198  atomDeexcitation = nullptr;
199  subcutProducer = nullptr;
200 }
201 
202 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
203 
205 {
206  all_tables_are_built = false;
207  currentLoss = nullptr;
208  currentParticle = nullptr;
209  if(n_loss)
210  {
211  dedx_vector.clear();
212  range_vector.clear();
213  inv_range_vector.clear();
214  loss_map.clear();
215  loss_vector.clear();
216  part_vector.clear();
217  base_part_vector.clear();
218  tables_are_built.clear();
219  isActive.clear();
220  n_loss = 0;
221  }
222 }
223 
224 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
225 
227 {
228  if(!p) { return; }
229  for (G4int i=0; i<n_loss; ++i) {
230  if(loss_vector[i] == p) { return; }
231  }
232  if(verbose > 1) {
233  G4cout << "G4LossTableManager::Register G4VEnergyLossProcess : "
234  << p->GetProcessName() << " idx= " << n_loss << G4endl;
235  }
236  ++n_loss;
237  loss_vector.push_back(p);
238  part_vector.push_back(nullptr);
239  base_part_vector.push_back(nullptr);
240  dedx_vector.push_back(nullptr);
241  range_vector.push_back(nullptr);
242  inv_range_vector.push_back(nullptr);
243  tables_are_built.push_back(false);
244  isActive.push_back(true);
245  all_tables_are_built = false;
246  if(subCutoffFlag) { p->ActivateSubCutoff(true); }
248  maxFinalStep); }
249  if(integralActive) { p->SetIntegral(integral); }
250 }
251 
252 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
253 
255 {
257  if(!isMaster) {
259  }
266  if(atomDeexcitation) {
269  }
270 }
271 
272 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
273 
275 {
276  if(!p) { return; }
277  for (G4int i=0; i<n_loss; ++i) {
278  if(loss_vector[i] == p) { loss_vector[i] = nullptr; }
279  }
280 }
281 
282 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
283 
285 {
286  if(!p) { return; }
287  G4int n = msc_vector.size();
288  for (G4int i=0; i<n; ++i) {
289  if(msc_vector[i] == p) { return; }
290  }
291  if(verbose > 1) {
292  G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
293  << p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
294  }
295  msc_vector.push_back(p);
296 }
297 
298 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
299 
301 {
302  if(!p) { return; }
303  size_t msc = msc_vector.size();
304  for (size_t i=0; i<msc; ++i) {
305  if(msc_vector[i] == p) { msc_vector[i] = nullptr; }
306  }
307 }
308 
309 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
310 
312 {
313  if(!p) { return; }
314  G4int n = emp_vector.size();
315  for (G4int i=0; i<n; ++i) {
316  if(emp_vector[i] == p) { return; }
317  }
318  if(verbose > 1) {
319  G4cout << "G4LossTableManager::Register G4VEmProcess : "
320  << p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
321  }
322  emp_vector.push_back(p);
323 }
324 
325 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
326 
328 {
329  if(!p) { return; }
330  size_t emp = emp_vector.size();
331  for (size_t i=0; i<emp; ++i) {
332  if(emp_vector[i] == p) { emp_vector[i] = nullptr; }
333  }
334 }
335 
336 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
337 
339 {
340  mod_vector.push_back(p);
341  if(verbose > 1) {
342  G4cout << "G4LossTableManager::Register G4VEmModel : "
343  << p->GetName() << G4endl;
344  }
345 }
346 
347 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
348 
350 {
351  size_t n = mod_vector.size();
352  for (size_t i=0; i<n; ++i) {
353  if(mod_vector[i] == p) { mod_vector[i] = nullptr; }
354  }
355 }
356 
357 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
358 
360 {
361  fmod_vector.push_back(p);
362  if(verbose > 1) {
363  G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
364  << p->GetName() << G4endl;
365  }
366 }
367 
368 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
369 
371 {
372  size_t n = fmod_vector.size();
373  for (size_t i=0; i<n; ++i) {
374  if(fmod_vector[i] == p) { fmod_vector[i] = nullptr; }
375  }
376 }
377 
378 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
379 
381  const G4ParticleDefinition* part,
383 {
384  if(!p || !part) { return; }
385  for (G4int i=0; i<n_loss; ++i) {
386  if(loss_vector[i] == p) { return; }
387  }
388  if(verbose > 1) {
389  G4cout << "G4LossTableManager::RegisterExtraParticle "
390  << part->GetParticleName() << " G4VEnergyLossProcess : "
391  << p->GetProcessName() << " idx= " << n_loss << G4endl;
392  }
393  ++n_loss;
394  loss_vector.push_back(p);
395  part_vector.push_back(part);
396  base_part_vector.push_back(p->BaseParticle());
397  dedx_vector.push_back(nullptr);
398  range_vector.push_back(nullptr);
399  inv_range_vector.push_back(nullptr);
400  tables_are_built.push_back(false);
401  all_tables_are_built = false;
402 }
403 
404 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
405 
406 void
409  G4bool theMaster)
410 {
411  if (1 < verbose) {
412  G4cout << "G4LossTableManager::PreparePhysicsTable for "
413  << particle->GetParticleName()
414  << " and " << p->GetProcessName() << " run= " << run
415  << " loss_vector " << loss_vector.size() << G4endl;
416  }
417 
418  isMaster = theMaster;
419 
420  if(!startInitialisation) {
421  ResetParameters();
422  if (1 < verbose) {
423  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
424  << G4endl;
425  }
426  }
427 
428  // start initialisation for the first run
429  if( -1 == run ) {
430  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
431 
432  // initialise particles for given process
433  for (G4int j=0; j<n_loss; ++j) {
434  if (p == loss_vector[j] && !part_vector[j]) {
435  part_vector[j] = particle;
436  if(particle->GetParticleName() == "GenericIon") {
437  theGenericIon = particle;
438  }
439  }
440  }
441  }
442  startInitialisation = true;
443 }
444 
445 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
446 
447 void
449  G4VEmProcess* p, G4bool theMaster)
450 {
451  if (1 < verbose) {
452  G4cout << "G4LossTableManager::PreparePhysicsTable for "
453  << particle->GetParticleName()
454  << " and " << p->GetProcessName() << G4endl;
455  }
456  isMaster = theMaster;
457 
458  if(!startInitialisation) {
459  ResetParameters();
460  if (1 < verbose) {
461  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
462  << G4endl;
463  }
464  }
465 
466  // start initialisation for the first run
467  if( -1 == run ) {
468  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
469  }
470  startInitialisation = true;
471 }
472 
473 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
474 
475 void
478  G4bool theMaster)
479 {
480  if (1 < verbose) {
481  G4cout << "G4LossTableManager::PreparePhysicsTable for "
482  << particle->GetParticleName()
483  << " and " << p->GetProcessName() << G4endl;
484  }
485 
486  isMaster = theMaster;
487 
488  if(!startInitialisation) {
489  ResetParameters();
490  if (1 < verbose) {
491  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
492  << G4endl;
493  }
494  }
495 
496  // start initialisation for the first run
497  if( -1 == run ) {
498  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
499  }
500  startInitialisation = true;
501 }
502 
503 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
504 
505 void
507 {
508  if(-1 == run && startInitialisation) {
510  }
511 }
512 
513 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
514 
516  const G4ParticleDefinition* aParticle,
518 {
519  if(1 < verbose) {
520  G4cout << "### G4LossTableManager::LocalPhysicsTable() for "
521  << aParticle->GetParticleName()
522  << " and process " << p->GetProcessName()
523  << G4endl;
524  }
525 
526  if(-1 == run && startInitialisation) {
528  firstParticle = aParticle;
529  }
530 
531  if(startInitialisation) {
532  ++run;
534  if(1 < verbose) {
535  G4cout << "===== G4LossTableManager::LocalPhysicsTable() for run "
536  << run << " =====" << G4endl;
537  }
539  currentParticle = nullptr;
540  startInitialisation = false;
541  for (G4int i=0; i<n_loss; ++i) {
542  if(loss_vector[i]) {
543  tables_are_built[i] = false;
544  } else {
545  tables_are_built[i] = true;
546  part_vector[i] = nullptr;
547  }
548  }
549  }
550 
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;
555  isActive[i] = true;
556  part_vector[i] = p->Particle();
557  base_part_vector[i] = p->BaseParticle();
558  dedx_vector[i] = p->DEDXTable();
561  if(0 == run && p->IsIonisationProcess()) {
563  }
564 
565  if(1 < verbose) {
566  G4cout << i <<". "<< p->GetProcessName();
567  if(part_vector[i]) {
568  G4cout << " for " << part_vector[i]->GetParticleName();
569  }
570  G4cout << " active= " << isActive[i]
571  << " table= " << tables_are_built[i]
572  << " isIonisation= " << p->IsIonisationProcess()
573  << G4endl;
574  }
575  break;
576  } else if(!tables_are_built[i]) {
577  all_tables_are_built = false;
578  }
579  }
580 
581  // Set run time parameters
582  SetParameters(aParticle, p);
583 
584  if(1 < verbose) {
585  G4cout << "### G4LossTableManager::LocalPhysicsTable end"
586  << G4endl;
587  }
588  if(all_tables_are_built) {
589  if(1 < verbose) {
590  G4cout << "%%%%% All dEdx and Range tables for worker are ready for run "
591  << run << " %%%%%" << G4endl;
592  }
593  }
594 }
595 
596 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
597 
599  const G4ParticleDefinition* aParticle,
601 {
602  if(1 < verbose) {
603  G4cout << "### G4LossTableManager::BuildPhysicsTable() for "
604  << aParticle->GetParticleName()
605  << " and process " << p->GetProcessName() << G4endl;
606  }
607  // clear configurator
608  if(-1 == run && startInitialisation) {
610  firstParticle = aParticle;
611  }
612  if(startInitialisation) {
613  ++run;
614  if(1 < verbose) {
615  G4cout << "===== G4LossTableManager::BuildPhysicsTable() for run "
616  << run << " ===== " << atomDeexcitation << G4endl;
617  }
618  currentParticle = nullptr;
619  all_tables_are_built= true;
620  }
621 
622  // initialisation before any table is built
623  if ( startInitialisation && aParticle == firstParticle ) {
624 
625  startInitialisation = false;
626  if(1 < verbose) {
627  G4cout << "### G4LossTableManager start initilisation for first particle "
629  << G4endl;
630  }
631  for (G4int i=0; i<n_loss; ++i) {
633 
634  if(el) {
635  isActive[i] = true;
636  base_part_vector[i] = el->BaseParticle();
637  tables_are_built[i] = false;
638  all_tables_are_built= false;
639  if(!isActive[i]) {
640  el->SetIonisation(false);
641  tables_are_built[i] = true;
642  }
643 
644  if(1 < verbose) {
645  G4cout << i <<". "<< el->GetProcessName();
646  if(el->Particle()) {
647  G4cout << " for " << el->Particle()->GetParticleName();
648  }
649  G4cout << " active= " << isActive[i]
650  << " table= " << tables_are_built[i]
651  << " isIonisation= " << el->IsIonisationProcess();
652  if(base_part_vector[i]) {
653  G4cout << " base particle "
654  << base_part_vector[i]->GetParticleName();
655  }
656  G4cout << G4endl;
657  }
658  } else {
659  tables_are_built[i] = true;
660  part_vector[i] = nullptr;
661  isActive[i] = false;
662  }
663  }
664  }
665 
666  // Set run time parameters
667  SetParameters(aParticle, p);
668 
669  if (all_tables_are_built) { return; }
670 
671  // Build tables for given particle
672  all_tables_are_built = true;
673 
674  for(G4int i=0; i<n_loss; ++i) {
675  if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
676  const G4ParticleDefinition* curr_part = part_vector[i];
677  if(1 < verbose) {
678  G4cout << "### Build Table for " << p->GetProcessName()
679  << " and " << curr_part->GetParticleName() << G4endl;
680  }
681  G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
682  if(curr_proc) { CopyTables(curr_part, curr_proc); }
683  }
684  if ( !tables_are_built[i] ) { all_tables_are_built = false; }
685  }
686  if(0 == run && p->IsIonisationProcess()) { loss_map[aParticle] = p; }
687 
688  if(1 < verbose) {
689  G4cout << "### G4LossTableManager::BuildPhysicsTable end: "
690  << "all_tables_are_built= " << all_tables_are_built
691  << G4endl;
692  }
693  if(all_tables_are_built) {
694  if(1 < verbose) {
695  G4cout << "%%%%% All dEdx and Range tables are built for master run= "
696  << run << " %%%%%" << G4endl;
697  }
698  }
699 }
700 
701 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
702 
704  G4VEnergyLossProcess* base_proc)
705 {
706  for (G4int j=0; j<n_loss; ++j) {
707 
709 
710  if (!tables_are_built[j] && part == base_part_vector[j]) {
711  tables_are_built[j] = true;
712  proc->SetDEDXTable(base_proc->IonisationTable(),fRestricted);
713  proc->SetDEDXTable(base_proc->DEDXTableForSubsec(),fSubRestricted);
714  proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
715  proc->SetCSDARangeTable(base_proc->CSDARangeTable());
716  proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
717  proc->SetInverseRangeTable(base_proc->InverseRangeTable());
718  proc->SetLambdaTable(base_proc->LambdaTable());
719  proc->SetSubLambdaTable(base_proc->SubLambdaTable());
720  proc->SetIonisation(base_proc->IsIonisationProcess());
721  if(proc->IsIonisationProcess()) {
722  range_vector[j] = base_proc->RangeTableForLoss();
723  inv_range_vector[j] = base_proc->InverseRangeTable();
724  loss_map[part_vector[j]] = proc;
725  }
726  if (1 < verbose) {
727  G4cout << "For " << proc->GetProcessName()
728  << " for " << part_vector[j]->GetParticleName()
729  << " base_part= " << part->GetParticleName()
730  << " tables are assigned "
731  << G4endl;
732  }
733  }
734 
735  if (theElectron == part && theElectron == proc->SecondaryParticle() ) {
736  proc->SetSecondaryRangeTable(base_proc->RangeTableForLoss());
737  }
738  }
739 }
740 
741 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
742 
744  const G4ParticleDefinition* aParticle)
745 {
746  if(1 < verbose) {
747  G4cout << "G4LossTableManager::BuildTables() for "
748  << aParticle->GetParticleName() << G4endl;
749  }
750 
751  std::vector<G4PhysicsTable*> t_list;
752  std::vector<G4VEnergyLossProcess*> loss_list;
753  std::vector<G4bool> build_flags;
754  G4VEnergyLossProcess* em = nullptr;
755  G4VEnergyLossProcess* p = nullptr;
756  G4int iem = 0;
757  G4PhysicsTable* dedx = 0;
758  G4int i;
759 
760  G4ProcessVector* pvec =
761  aParticle->GetProcessManager()->GetProcessList();
762  G4int nvec = pvec->size();
763 
764  for (i=0; i<n_loss; ++i) {
765  p = loss_vector[i];
766  if (p) {
767  G4bool yes = (aParticle == part_vector[i]);
768 
769  // possible case of process sharing between particle/anti-particle
770  if(!yes) {
771  G4VProcess* ptr = static_cast<G4VProcess*>(p);
772  for(G4int j=0; j<nvec; ++j) {
773  //G4cout << "j= " << j << " " << (*pvec)[j] << " " << ptr << G4endl;
774  if(ptr == (*pvec)[j]) {
775  yes = true;
776  break;
777  }
778  }
779  }
780  // process belong to this particle
781  if(yes && isActive[i]) {
782  if (p->IsIonisationProcess() || !em) {
783  em = p;
784  iem= i;
785  }
786  // tables may be shared between particle/anti-particle
787  G4bool val = false;
788  if (!tables_are_built[i]) {
789  val = true;
790  dedx = p->BuildDEDXTable(fRestricted);
791  //G4cout << "Build DEDX table for " << p->GetProcessName()
792  // << " idx= " << i << dedx << " " << dedx->length() << G4endl;
793  p->SetDEDXTable(dedx,fRestricted);
794  tables_are_built[i] = true;
795  } else {
796  dedx = p->DEDXTable();
797  }
798  t_list.push_back(dedx);
799  loss_list.push_back(p);
800  build_flags.push_back(val);
801  }
802  }
803  }
804 
805  G4int n_dedx = t_list.size();
806  if (0 == n_dedx || !em) {
807  G4cout << "G4LossTableManager WARNING: no DEDX processes for "
808  << aParticle->GetParticleName() << G4endl;
809  return 0;
810  }
811  G4int nSubRegions = em->NumberOfSubCutoffRegions();
812 
813  if (1 < verbose) {
814  G4cout << "G4LossTableManager::BuildTables() start to build range tables"
815  << " and the sum of " << n_dedx << " processes"
816  << " iem= " << iem << " em= " << em->GetProcessName()
817  << " buildCSDARange= " << theParameters->BuildCSDARange()
818  << " nSubRegions= " << nSubRegions;
819  if(subcutProducer) {
820  G4cout << " SubCutProducer " << subcutProducer->GetName();
821  }
822  G4cout << G4endl;
823  }
824  // do not build tables if producer class is defined
825  if(subcutProducer) { nSubRegions = 0; }
826 
827  dedx = em->DEDXTable();
828  em->SetIonisation(true);
829  em->SetDEDXTable(dedx, fIsIonisation);
830 
831  if (1 < n_dedx) {
832  dedx = 0;
834  tableBuilder->BuildDEDXTable(dedx, t_list);
835  em->SetDEDXTable(dedx, fRestricted);
836  }
837 
838  /*
839  if(2==run && "e-" == aParticle->GetParticleName()) {
840  G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
841  G4cout << (*dedx) << G4endl;
842  G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
843  G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
844  G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
845  }
846  */
847  dedx_vector[iem] = dedx;
848 
849  G4PhysicsTable* range = em->RangeTableForLoss();
850  if(!range) range = G4PhysicsTableHelper::PreparePhysicsTable(range);
851  range_vector[iem] = range;
852 
853  G4PhysicsTable* invrange = em->InverseRangeTable();
854  if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
855  inv_range_vector[iem] = invrange;
856 
857  tableBuilder->BuildRangeTable(dedx, range, true);
858  tableBuilder->BuildInverseRangeTable(range, invrange, true);
859 
860  // if(1<verbose) G4cout << *dedx << G4endl;
861 
862  em->SetRangeTableForLoss(range);
863  em->SetInverseRangeTable(invrange);
864 
865  // if(1<verbose) G4cout << *range << G4endl;
866 
867  std::vector<G4PhysicsTable*> listSub;
868  std::vector<G4PhysicsTable*> listCSDA;
869 
870  for (i=0; i<n_dedx; ++i) {
871  p = loss_list[i];
872  if(p != em) { p->SetIonisation(false); }
873  if(build_flags[i]) {
875  }
876  if (0 < nSubRegions) {
877  dedx = p->BuildDEDXTable(fSubRestricted);
878  p->SetDEDXTable(dedx,fSubRestricted);
879  listSub.push_back(dedx);
880  if(build_flags[i]) {
882  if(p != em) { em->AddCollaborativeProcess(p); }
883  }
884  }
885  if(theParameters->BuildCSDARange()) {
886  dedx = p->BuildDEDXTable(fTotal);
887  p->SetDEDXTable(dedx,fTotal);
888  listCSDA.push_back(dedx);
889  }
890  }
891 
892  if (0 < nSubRegions) {
893  G4PhysicsTable* dedxSub = em->IonisationTableForSubsec();
894  if (1 < listSub.size()) {
895  em->SetDEDXTable(dedxSub, fIsSubIonisation);
896  dedxSub = 0;
898  tableBuilder->BuildDEDXTable(dedxSub, listSub);
899  em->SetDEDXTable(dedxSub, fSubRestricted);
900  }
901  }
903  G4PhysicsTable* dedxCSDA = em->DEDXunRestrictedTable();
904  if (1 < n_dedx) {
905  dedxCSDA = nullptr;
906  dedxCSDA = G4PhysicsTableHelper::PreparePhysicsTable(dedxCSDA);
907  tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
908  em->SetDEDXTable(dedxCSDA,fTotal);
909  }
910  G4PhysicsTable* rCSDA = em->CSDARangeTable();
911  if(!rCSDA) { rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA); }
912  tableBuilder->BuildRangeTable(dedxCSDA, rCSDA, true);
913  em->SetCSDARangeTable(rCSDA);
914  }
915 
916  if (1 < verbose) {
917  G4cout << "G4LossTableManager::BuildTables: Tables are built for "
918  << aParticle->GetParticleName()
919  << "; ionisation process: " << em->GetProcessName()
920  << " " << em
921  << G4endl;
922  }
923  return em;
924 }
925 
926 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
927 
929 {
930  return theMessenger;
931 }
932 
933 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
934 
936  const G4ParticleDefinition* aParticle)
937 {
939  ed << "Energy loss process not found for " << aParticle->GetParticleName()
940  << " !";
941  G4Exception("G4LossTableManager::ParticleHaveNoLoss", "em0001",
942  FatalException, ed);
943 }
944 
945 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
946 
948 {
949 }
950 
951 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
952 
954 {
955  subCutoffFlag = val;
956  for(G4int i=0; i<n_loss; ++i) {
957  if(loss_vector[i]) { loss_vector[i]->ActivateSubCutoff(val, r); }
958  }
959 }
960 
961 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
962 
964 {
965  integral = val;
966  integralActive = true;
967  for(G4int i=0; i<n_loss; ++i) {
968  if(loss_vector[i]) { loss_vector[i]->SetIntegral(val); }
969  }
970  size_t emp = emp_vector.size();
971  for (size_t k=0; k<emp; ++k) {
972  if(emp_vector[k]) { emp_vector[k]->SetIntegral(val); }
973  }
974 }
975 
976 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
977 
979 {
980 }
981 
982 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
983 
985 {
986 }
987 
988 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
989 
991 {
993 }
994 
995 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
996 
998 {
1000 }
1001 
1002 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1003 
1005 {
1007 }
1008 
1009 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1010 
1012 {
1014 }
1015 
1016 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1017 
1019 {
1021 }
1022 
1023 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1024 
1026 {
1027 }
1028 
1029 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1030 
1032 {
1034 }
1035 
1036 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1037 
1039 {
1040 }
1041 
1042 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1043 
1045 {
1046  if(0.0 < v1 && 0.0 < v2 && v2 < 1.e+50) {
1047  stepFunctionActive = true;
1048  maxRangeVariation = v1;
1049  maxFinalStep = v2;
1050  for(G4int i=0; i<n_loss; ++i) {
1051  if(loss_vector[i]) { loss_vector[i]->SetStepFunction(v1, v2); }
1052  }
1053  } else if(v1 <= 0.0) {
1054  PrintEWarning("SetStepFunction", v1);
1055  } else {
1056  PrintEWarning("SetStepFunction", v2);
1057  }
1058 }
1059 
1060 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1061 
1063 {
1064 }
1065 
1066 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1067 
1069 {
1070 }
1071 
1072 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1073 
1074 void
1077 {
1078  if(stepFunctionActive) {
1080  }
1081  if(integralActive) { p->SetIntegral(integral); }
1082 }
1083 
1084 
1085 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1086 
1087 const std::vector<G4VEnergyLossProcess*>&
1089 {
1090  return loss_vector;
1091 }
1092 
1093 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1094 
1095 const std::vector<G4VEmProcess*>& G4LossTableManager::GetEmProcessVector()
1096 {
1097  return emp_vector;
1098 }
1099 
1100 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1101 
1102 const std::vector<G4VMultipleScattering*>&
1104 {
1105  return msc_vector;
1106 }
1107 
1108 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1109 
1111 {
1113  return emSaturation;
1114 }
1115 
1116 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1117 
1119 {
1121  return emConfigurator;
1122 }
1123 
1124 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1125 
1127 {
1128  if(!emElectronIonPair) {
1130  }
1131  return emElectronIonPair;
1132 }
1133 
1134 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1135 
1137 {
1138  if(atomDeexcitation != p) {
1139  delete atomDeexcitation;
1140  atomDeexcitation = p;
1141  }
1142 }
1143 
1144 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1145 
1147 {
1148  if(subcutProducer != p) {
1149  delete subcutProducer;
1150  subcutProducer = p;
1151  }
1152 }
1153 
1154 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1155 
1157 {
1158  G4String ss = "G4LossTableManager::" + tit;
1160  /*
1161  ed << "Parameter is out of range: " << val
1162  << " it will have no effect!\n" << " ## "
1163  << " nbins= " << nbinsLambda
1164  << " nbinsPerDecade= " << nbinsPerDecade
1165  << " Emin(keV)= " << minKinEnergy/keV
1166  << " Emax(GeV)= " << maxKinEnergy/GeV;
1167  */
1168  G4Exception(ss, "em0044", JustWarning, ed);
1169 }
1170 
1171 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
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 Spline() const
G4int WorkerVerbose() const
static G4LossTableManager * Instance()
G4VAtomDeexcitation * atomDeexcitation
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
void SetVerbose(G4int verb)
void SetIonisation(G4bool val)
G4VSubCutProducer * subcutProducer
std::vector< G4VEmModel * > mod_vector
G4PhysicsTable * SubLambdaTable() const
G4ElectronIonPair * emElectronIonPair
void DeRegister(G4VEnergyLossProcess *p)
G4PhysicsTable * RangeTableForLoss() const
void SetLambdaBinning(G4int val)
G4EmSaturation * emSaturation
void push_back(G4PhysicsVector *)
static G4ThreadLocal G4LossTableManager * instance
void AddCollaborativeProcess(G4VEnergyLossProcess *)
void SetStepFunction(G4double v1, G4double v2)
G4PhysicsTable * CSDARangeTable() const
const G4String & GetName() const
void SetNumberOfBins(G4int val)
G4EnergyLossMessenger * GetMessenger()
void CopyTables(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *)
void SetMaxEnergyForCSDARange(G4double val)
std::vector< G4PhysicsTable * > range_vector
G4PhysicsTable * IonisationTableForSubsec() const
G4double a
Definition: TRTMaterials.hh:39
#define G4ThreadLocal
Definition: tls.hh:89
G4PhysicsTable * IonisationTable() const
G4ProcessManager * GetProcessManager() const
const std::vector< G4VEmProcess * > & GetEmProcessVector()
int G4int
Definition: G4Types.hh:78
G4PhysicsTable * BuildLambdaTable(G4EmTableType tType=fRestricted)
void SetMaxEnergy(G4double val)
void SetVerbose(G4int)
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
const G4String & GetParticleName() const
std::map< PD, G4VEnergyLossProcess *, std::less< PD > > loss_map
G4EmConfigurator * emConfigurator
void SetBuildCSDARange(G4bool val)
void SetInitialisationFlag(G4bool flag)
G4VEnergyLossProcess * BuildTables(const G4ParticleDefinition *aParticle)
G4bool BuildCSDARange() const
G4PhysicsTable * LambdaTable() const
void ParticleHaveNoLoss(const G4ParticleDefinition *aParticle)
void SetInverseRangeTable(G4PhysicsTable *p)
const G4ParticleDefinition * SecondaryParticle() const
void SetSubCutProducer(G4VSubCutProducer *)
void SetParameters(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *)
G4GLOB_DLL std::ostream G4cout
G4int Verbose() const
G4PhysicsTable * DEDXTable() const
std::vector< G4VEmFluctuationModel * > fmod_vector
bool G4bool
Definition: G4Types.hh:79
G4VEnergyLossProcess * currentLoss
G4ElectronIonPair * ElectronIonPair()
G4EmSaturation * EmSaturation()
void SetMaxEnergyForCSDARange(G4double val)
G4int NumberOfSubCutoffRegions() const
void Register(G4VEnergyLossProcess *p)
const G4ParticleDefinition * BaseParticle() const
const G4int n
void SetDEDXBinningForCSDARange(G4int val)
void BuildInverseRangeTable(const G4PhysicsTable *rangeTable, G4PhysicsTable *invRangeTable, G4bool isIonisation=false)
G4PhysicsTable * DEDXTableForSubsec() const
const G4String & GetProcessName() const
Definition: G4VProcess.hh:408
const std::vector< G4VEnergyLossProcess * > & GetEnergyLossProcessVector()
void SetSubCutoff(G4bool val, const G4Region *r=0)
void RegisterExtraParticle(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::vector< G4PhysicsTable * > inv_range_vector
G4bool IsWorkerThread()
Definition: G4Threading.cc:129
void BuildDEDXTable(G4PhysicsTable *dedxTable, const std::vector< G4PhysicsTable * > &)
void SetVerbose(G4int value)
void SetMinSubRange(G4double val)
G4EmParameters * theParameters
G4int size() const
G4EmCorrections * emCorrections
void SetMinEnergy(G4double val)
void SetLambdaTable(G4PhysicsTable *p)
void SetMaxEnergy(G4double val)
const G4String & GetName() const
void SetStepFunction(G4double v1, G4double v2)
G4PhysicsTable * InverseRangeTable() const
void DumpG4BirksCoefficients()
void BuildPhysicsTable(const G4ParticleDefinition *aParticle)
G4LossTableBuilder * tableBuilder
const G4ParticleDefinition * Particle() const
void SetLinearLossLimit(G4double val)
void SetMinEnergy(G4double val)
std::vector< G4PhysicsTable * > dedx_vector
void PrepareModels(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
static G4EmParameters * Instance()
std::vector< G4VEnergyLossProcess * > loss_vector
void PreparePhysicsTable(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p, G4bool theMaster)
void SetCSDARangeTable(G4PhysicsTable *pRange)
void PrintEWarning(G4String, G4double)
void SetVerbose(G4int val)
void LocalPhysicsTables(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void SetDEDXBinning(G4int val)
void SetMaxEnergyForMuons(G4double val)
static G4Electron * Electron()
Definition: G4Electron.cc:94
std::vector< PD > part_vector
#define G4endl
Definition: G4ios.hh:61
void SetIntegral(G4bool val)
void SetLossFluctuations(G4bool val)
const G4String & GetName() const
Definition: G4VEmModel.hh:795
std::vector< G4bool > isActive
void SetSecondaryRangeTable(G4PhysicsTable *p)
std::vector< G4VEmProcess * > emp_vector
G4PhysicsTable * DEDXunRestrictedTable() const
double G4double
Definition: G4Types.hh:76
void SetSubLambdaTable(G4PhysicsTable *p)
std::vector< PD > base_part_vector
void ActivateSubCutoff(G4bool val, const G4Region *region=0)
void SetRangeTableForLoss(G4PhysicsTable *p)
std::vector< G4VMultipleScattering * > msc_vector
static const double mm
Definition: G4SIunits.hh:114
void SetAtomDeexcitation(G4VAtomDeexcitation *)
G4EnergyLossMessenger * theMessenger
G4PhysicsTable * BuildDEDXTable(G4EmTableType tType=fRestricted)
const std::vector< G4VMultipleScattering * > & GetMultipleScatteringVector()
G4ProcessVector * GetProcessList() const
std::vector< G4bool > tables_are_built
void SetSplineFlag(G4bool flag)
G4bool IsIonisationProcess() const