Geant4  10.03.p01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 99151 2016-09-07 08:03:17Z 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 
87 #include "G4VMultipleScattering.hh"
88 #include "G4VEmProcess.hh"
89 
90 #include "G4EmParameters.hh"
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 
110 G4ThreadLocal G4LossTableManager* G4LossTableManager::instance = nullptr;
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() "<< this << 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  //G4cout << " Nmod" << mod << " Nfluc= " << fmod << G4endl;
143  for (size_t a=0; a<mod; ++a) {
144  //G4cout << "Delete model #" << a << " " << mod_vector[a] << G4endl;
145  if( nullptr != mod_vector[a] ) {
146  for (size_t b=0; b<fmod; ++b) {
147  if((G4VEmModel*)(fmod_vector[b]) == mod_vector[a]) {
148  fmod_vector[b] = nullptr;
149  }
150  }
151  delete mod_vector[a];
152  mod_vector[a] = nullptr;
153  }
154  }
155  for (size_t b=0; b<fmod; ++b) {
156  if( fmod_vector[b] ) { delete fmod_vector[b]; }
157  }
158  Clear();
159  delete tableBuilder;
160  delete emCorrections;
161  delete emConfigurator;
162  delete emElectronIonPair;
163  delete atomDeexcitation;
164  delete subcutProducer;
165 }
166 
167 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
168 
169 G4LossTableManager::G4LossTableManager()
170 {
171  //G4cout << "### G4LossTableManager::G4LossTableManager() " << this << G4endl;
172  theParameters = G4EmParameters::Instance();
173  n_loss = 0;
174  run = -1;
175  startInitialisation = false;
176  all_tables_are_built = false;
177  currentLoss = nullptr;
178  currentParticle = nullptr;
179  firstParticle = nullptr;
180  isMaster = true;
181  verbose = theParameters->Verbose();
182  theElectron = G4Electron::Electron();
183  theGenericIon= nullptr;
185  verbose = theParameters->WorkerVerbose();
186  isMaster = false;
187  }
188  tableBuilder = new G4LossTableBuilder();
189  emCorrections= new G4EmCorrections(verbose);
190  emConfigurator = nullptr;
191  emElectronIonPair = nullptr;
192  atomDeexcitation = nullptr;
193  subcutProducer = nullptr;
194 }
195 
196 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
197 
199 {
200  all_tables_are_built = false;
201  currentLoss = nullptr;
202  currentParticle = nullptr;
203  if(n_loss)
204  {
205  dedx_vector.clear();
206  range_vector.clear();
207  inv_range_vector.clear();
208  loss_map.clear();
209  loss_vector.clear();
210  part_vector.clear();
211  base_part_vector.clear();
212  tables_are_built.clear();
213  isActive.clear();
214  n_loss = 0;
215  }
216 }
217 
218 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
219 
221 {
222  if(!p) { return; }
223  for (G4int i=0; i<n_loss; ++i) {
224  if(loss_vector[i] == p) { return; }
225  }
226  if(verbose > 1) {
227  G4cout << "G4LossTableManager::Register G4VEnergyLossProcess : "
228  << p->GetProcessName() << " idx= " << n_loss << G4endl;
229  }
230  ++n_loss;
231  loss_vector.push_back(p);
232  part_vector.push_back(nullptr);
233  base_part_vector.push_back(nullptr);
234  dedx_vector.push_back(nullptr);
235  range_vector.push_back(nullptr);
236  inv_range_vector.push_back(nullptr);
237  tables_are_built.push_back(false);
238  isActive.push_back(true);
239  all_tables_are_built = false;
240 }
241 
242 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
243 
244 void G4LossTableManager::ResetParameters()
245 {
246  verbose = theParameters->Verbose();
247  if(!isMaster) {
248  verbose = theParameters->WorkerVerbose();
249  }
250  tableBuilder->SetSplineFlag(theParameters->Spline());
251  tableBuilder->SetInitialisationFlag(false);
252  emCorrections->SetVerbose(verbose);
253  if(emConfigurator) { emConfigurator->SetVerbose(verbose); };
254  if(emElectronIonPair) { emElectronIonPair->SetVerbose(verbose); };
255  if(atomDeexcitation) {
256  atomDeexcitation->SetVerboseLevel(verbose);
257  atomDeexcitation->InitialiseAtomicDeexcitation();
258  }
259 }
260 
261 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
262 
264 {
265  if(!p) { return; }
266  for (G4int i=0; i<n_loss; ++i) {
267  if(loss_vector[i] == p) { loss_vector[i] = nullptr; }
268  }
269 }
270 
271 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
272 
274 {
275  if(!p) { return; }
276  G4int n = msc_vector.size();
277  for (G4int i=0; i<n; ++i) {
278  if(msc_vector[i] == p) { return; }
279  }
280  if(verbose > 1) {
281  G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
282  << p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
283  }
284  msc_vector.push_back(p);
285 }
286 
287 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
288 
290 {
291  if(!p) { return; }
292  size_t msc = msc_vector.size();
293  for (size_t i=0; i<msc; ++i) {
294  if(msc_vector[i] == p) { msc_vector[i] = nullptr; }
295  }
296 }
297 
298 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
299 
301 {
302  if(!p) { return; }
303  G4int n = emp_vector.size();
304  for (G4int i=0; i<n; ++i) {
305  if(emp_vector[i] == p) { return; }
306  }
307  if(verbose > 1) {
308  G4cout << "G4LossTableManager::Register G4VEmProcess : "
309  << p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
310  }
311  emp_vector.push_back(p);
312 }
313 
314 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
315 
317 {
318  if(!p) { return; }
319  size_t emp = emp_vector.size();
320  for (size_t i=0; i<emp; ++i) {
321  if(emp_vector[i] == p) { emp_vector[i] = nullptr; }
322  }
323 }
324 
325 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
326 
328 {
329  mod_vector.push_back(p);
330  if(verbose > 1) {
331  G4cout << "G4LossTableManager::Register G4VEmModel : "
332  << p->GetName() << " " << p << " " << mod_vector.size() << G4endl;
333  }
334 }
335 
336 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
337 
339 {
340  //G4cout << "G4LossTableManager::DeRegister G4VEmModel : " << p << G4endl;
341  size_t n = mod_vector.size();
342  for (size_t i=0; i<n; ++i) {
343  if(mod_vector[i] == p) {
344  mod_vector[i] = nullptr;
345  break;
346  }
347  }
348 }
349 
350 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
351 
353 {
354  fmod_vector.push_back(p);
355  if(verbose > 1) {
356  G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
357  << p->GetName() << " " << fmod_vector.size() << G4endl;
358  }
359 }
360 
361 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
362 
364 {
365  size_t n = fmod_vector.size();
366  for (size_t i=0; i<n; ++i) {
367  if(fmod_vector[i] == p) { fmod_vector[i] = nullptr; }
368  }
369 }
370 
371 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
372 
374  const G4ParticleDefinition* part,
376 {
377  if(!p || !part) { return; }
378  for (G4int i=0; i<n_loss; ++i) {
379  if(loss_vector[i] == p) { return; }
380  }
381  if(verbose > 1) {
382  G4cout << "G4LossTableManager::RegisterExtraParticle "
383  << part->GetParticleName() << " G4VEnergyLossProcess : "
384  << p->GetProcessName() << " idx= " << n_loss << G4endl;
385  }
386  ++n_loss;
387  loss_vector.push_back(p);
388  part_vector.push_back(part);
389  base_part_vector.push_back(p->BaseParticle());
390  dedx_vector.push_back(nullptr);
391  range_vector.push_back(nullptr);
392  inv_range_vector.push_back(nullptr);
393  tables_are_built.push_back(false);
394  all_tables_are_built = false;
395 }
396 
397 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
398 
399 void
402  G4bool theMaster)
403 {
404  if (1 < verbose) {
405  G4cout << "G4LossTableManager::PreparePhysicsTable for "
406  << particle->GetParticleName()
407  << " and " << p->GetProcessName() << " run= " << run
408  << " loss_vector " << loss_vector.size() << G4endl;
409  }
410 
411  isMaster = theMaster;
412 
413  if(!startInitialisation) {
414  ResetParameters();
415  if (1 < verbose) {
416  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
417  << G4endl;
418  }
419  }
420 
421  // start initialisation for the first run
422  if( -1 == run ) {
423  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
424 
425  // initialise particles for given process
426  for (G4int j=0; j<n_loss; ++j) {
427  if (p == loss_vector[j] && !part_vector[j]) {
428  part_vector[j] = particle;
429  if(particle->GetParticleName() == "GenericIon") {
430  theGenericIon = particle;
431  }
432  }
433  }
434  }
435  startInitialisation = true;
436 }
437 
438 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
439 
440 void
442  G4VEmProcess* p, G4bool theMaster)
443 {
444  if (1 < verbose) {
445  G4cout << "G4LossTableManager::PreparePhysicsTable for "
446  << particle->GetParticleName()
447  << " and " << p->GetProcessName() << G4endl;
448  }
449  isMaster = theMaster;
450 
451  if(!startInitialisation) {
452  ResetParameters();
453  if (1 < verbose) {
454  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
455  << G4endl;
456  }
457  }
458 
459  // start initialisation for the first run
460  if( -1 == run ) {
461  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
462  }
463  startInitialisation = true;
464 }
465 
466 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
467 
468 void
471  G4bool theMaster)
472 {
473  if (1 < verbose) {
474  G4cout << "G4LossTableManager::PreparePhysicsTable for "
475  << particle->GetParticleName()
476  << " and " << p->GetProcessName() << G4endl;
477  }
478 
479  isMaster = theMaster;
480 
481  if(!startInitialisation) {
482  ResetParameters();
483  if (1 < verbose) {
484  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
485  << G4endl;
486  }
487  }
488 
489  // start initialisation for the first run
490  if( -1 == run ) {
491  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
492  }
493  startInitialisation = true;
494 }
495 
496 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
497 
498 void
500 {
501  if(-1 == run && startInitialisation) {
502  if(emConfigurator) { emConfigurator->Clear(); }
503  }
504 }
505 
506 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
507 
509  const G4ParticleDefinition* aParticle,
511 {
512  if(1 < verbose) {
513  G4cout << "### G4LossTableManager::LocalPhysicsTable() for "
514  << aParticle->GetParticleName()
515  << " and process " << p->GetProcessName()
516  << G4endl;
517  }
518 
519  if(-1 == run && startInitialisation) {
520  if(emConfigurator) { emConfigurator->Clear(); }
521  firstParticle = aParticle;
522  }
523 
524  if(startInitialisation) {
525  ++run;
526  if(1 < verbose) {
527  G4cout << "===== G4LossTableManager::LocalPhysicsTable() for run "
528  << run << " =====" << G4endl;
529  }
530  currentParticle = nullptr;
531  startInitialisation = false;
532  for (G4int i=0; i<n_loss; ++i) {
533  if(loss_vector[i]) {
534  tables_are_built[i] = false;
535  } else {
536  tables_are_built[i] = true;
537  part_vector[i] = nullptr;
538  }
539  }
540  }
541 
542  all_tables_are_built= true;
543  for (G4int i=0; i<n_loss; ++i) {
544  if(p == loss_vector[i]) {
545  tables_are_built[i] = true;
546  isActive[i] = true;
547  part_vector[i] = p->Particle();
548  base_part_vector[i] = p->BaseParticle();
549  dedx_vector[i] = p->DEDXTable();
550  range_vector[i] = p->RangeTableForLoss();
551  inv_range_vector[i] = p->InverseRangeTable();
552  if(0 == run && p->IsIonisationProcess()) {
553  loss_map[part_vector[i]] = p;
554  //G4cout << "G4LossTableManager::LocalPhysicsTable " << part_vector[i]->GetParticleName()
555  // << " added to map " << p << G4endl;
556  }
557 
558  if(1 < verbose) {
559  G4cout << i <<". "<< p->GetProcessName();
560  if(part_vector[i]) {
561  G4cout << " for " << part_vector[i]->GetParticleName();
562  }
563  G4cout << " active= " << isActive[i]
564  << " table= " << tables_are_built[i]
565  << " isIonisation= " << p->IsIonisationProcess()
566  << G4endl;
567  }
568  break;
569  } else if(!tables_are_built[i]) {
570  all_tables_are_built = false;
571  }
572  }
573 
574  if(1 < verbose) {
575  G4cout << "### G4LossTableManager::LocalPhysicsTable end"
576  << G4endl;
577  }
578  if(all_tables_are_built) {
579  if(1 < verbose) {
580  G4cout << "%%%%% All dEdx and Range tables for worker are ready for run "
581  << run << " %%%%%" << G4endl;
582  }
583  }
584 }
585 
586 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
587 
589  const G4ParticleDefinition* aParticle,
591 {
592  if(1 < verbose) {
593  G4cout << "### G4LossTableManager::BuildPhysicsTable() for "
594  << aParticle->GetParticleName()
595  << " and process " << p->GetProcessName() << G4endl;
596  }
597  // clear configurator
598  if(-1 == run && startInitialisation) {
599  if(emConfigurator) { emConfigurator->Clear(); }
600  firstParticle = aParticle;
601  }
602  if(startInitialisation) {
603  ++run;
604  if(1 < verbose) {
605  G4cout << "===== G4LossTableManager::BuildPhysicsTable() for run "
606  << run << " ===== " << atomDeexcitation << G4endl;
607  }
608  currentParticle = nullptr;
609  all_tables_are_built= true;
610  }
611 
612  // initialisation before any table is built
613  if ( startInitialisation && aParticle == firstParticle ) {
614 
615  startInitialisation = false;
616  if(1 < verbose) {
617  G4cout << "### G4LossTableManager start initilisation for first particle "
618  << firstParticle->GetParticleName()
619  << G4endl;
620  }
621  for (G4int i=0; i<n_loss; ++i) {
622  G4VEnergyLossProcess* el = loss_vector[i];
623 
624  if(el) {
625  isActive[i] = true;
626  base_part_vector[i] = el->BaseParticle();
627  tables_are_built[i] = false;
628  all_tables_are_built= false;
629  if(!isActive[i]) {
630  el->SetIonisation(false);
631  tables_are_built[i] = true;
632  }
633 
634  if(1 < verbose) {
635  G4cout << i <<". "<< el->GetProcessName();
636  if(el->Particle()) {
637  G4cout << " for " << el->Particle()->GetParticleName();
638  }
639  G4cout << " active= " << isActive[i]
640  << " table= " << tables_are_built[i]
641  << " isIonisation= " << el->IsIonisationProcess();
642  if(base_part_vector[i]) {
643  G4cout << " base particle "
644  << base_part_vector[i]->GetParticleName();
645  }
646  G4cout << G4endl;
647  }
648  } else {
649  tables_are_built[i] = true;
650  part_vector[i] = nullptr;
651  isActive[i] = false;
652  }
653  }
654  }
655 
656  if (all_tables_are_built) { return; }
657 
658  // Build tables for given particle
659  all_tables_are_built = true;
660 
661  for(G4int i=0; i<n_loss; ++i) {
662  if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
663  const G4ParticleDefinition* curr_part = part_vector[i];
664  if(1 < verbose) {
665  G4cout << "### Build Table for " << p->GetProcessName()
666  << " and " << curr_part->GetParticleName()
667  << " " << tables_are_built[i] << " " << base_part_vector[i] << G4endl;
668  }
669  G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
670  if(curr_proc) {
671  CopyTables(curr_part, curr_proc);
672  if(p == curr_proc && 0 == run && p->IsIonisationProcess()) {
673  loss_map[aParticle] = p;
674  //G4cout << "G4LossTableManager::BuildPhysicsTable: " << aParticle->GetParticleName()
675  // << " added to map " << p << G4endl;
676  }
677  }
678  }
679  if ( !tables_are_built[i] ) { all_tables_are_built = false; }
680  }
681  if(1 < verbose) {
682  G4cout << "### G4LossTableManager::BuildPhysicsTable end: "
683  << "all_tables_are_built= " << all_tables_are_built << " "
684  << aParticle->GetParticleName() << " proc: " << p << G4endl;
685  }
686  if(all_tables_are_built) {
687  if(1 < verbose) {
688  G4cout << "%%%%% All dEdx and Range tables are built for master run= "
689  << run << " %%%%%" << G4endl;
690  }
691  }
692 }
693 
694 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
695 
696 void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
697  G4VEnergyLossProcess* base_proc)
698 {
699  for (G4int j=0; j<n_loss; ++j) {
700 
701  G4VEnergyLossProcess* proc = loss_vector[j];
702 
703  if (!tables_are_built[j] && part == base_part_vector[j]) {
704  tables_are_built[j] = true;
705  proc->SetDEDXTable(base_proc->IonisationTable(),fRestricted);
706  proc->SetDEDXTable(base_proc->DEDXTableForSubsec(),fSubRestricted);
707  proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
708  proc->SetCSDARangeTable(base_proc->CSDARangeTable());
709  proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
710  proc->SetInverseRangeTable(base_proc->InverseRangeTable());
711  proc->SetLambdaTable(base_proc->LambdaTable());
712  proc->SetSubLambdaTable(base_proc->SubLambdaTable());
713  proc->SetIonisation(base_proc->IsIonisationProcess());
714  if(proc->IsIonisationProcess()) {
715  range_vector[j] = base_proc->RangeTableForLoss();
716  inv_range_vector[j] = base_proc->InverseRangeTable();
717  loss_map[part_vector[j]] = proc;
718  //G4cout << "G4LossTableManager::CopyTable " << part_vector[j]->GetParticleName()
719  // << " added to map " << proc << G4endl;
720  }
721  if (1 < verbose) {
722  G4cout << "For " << proc->GetProcessName()
723  << " for " << part_vector[j]->GetParticleName()
724  << " base_part= " << part->GetParticleName()
725  << " tables are assigned"
726  << G4endl;
727  }
728  }
729 
730  if (theElectron == part && theElectron == proc->SecondaryParticle() ) {
731  proc->SetSecondaryRangeTable(base_proc->RangeTableForLoss());
732  }
733  }
734 }
735 
736 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
737 
738 G4VEnergyLossProcess* G4LossTableManager::BuildTables(
739  const G4ParticleDefinition* aParticle)
740 {
741  if(1 < verbose) {
742  G4cout << "G4LossTableManager::BuildTables() for "
743  << aParticle->GetParticleName() << G4endl;
744  }
745 
746  std::vector<G4PhysicsTable*> t_list;
747  std::vector<G4VEnergyLossProcess*> loss_list;
748  std::vector<G4bool> build_flags;
749  G4VEnergyLossProcess* em = nullptr;
750  G4VEnergyLossProcess* p = nullptr;
751  G4int iem = 0;
752  G4PhysicsTable* dedx = 0;
753  G4int i;
754 
755  G4ProcessVector* pvec =
756  aParticle->GetProcessManager()->GetProcessList();
757  G4int nvec = pvec->size();
758 
759  for (i=0; i<n_loss; ++i) {
760  p = loss_vector[i];
761  if (p) {
762  G4bool yes = (aParticle == part_vector[i]);
763 
764  // possible case of process sharing between particle/anti-particle
765  if(!yes) {
766  G4VProcess* ptr = static_cast<G4VProcess*>(p);
767  for(G4int j=0; j<nvec; ++j) {
768  //G4cout << "j= " << j << " " << (*pvec)[j] << " " << ptr << G4endl;
769  if(ptr == (*pvec)[j]) {
770  yes = true;
771  break;
772  }
773  }
774  }
775  // process belong to this particle
776  if(yes && isActive[i]) {
777  if (p->IsIonisationProcess() || !em) {
778  em = p;
779  iem= i;
780  }
781  // tables may be shared between particle/anti-particle
782  G4bool val = false;
783  if (!tables_are_built[i]) {
784  val = true;
785  dedx = p->BuildDEDXTable(fRestricted);
786  //G4cout << "Build DEDX table for " << p->GetProcessName()
787  // << " idx= " << i << dedx << " " << dedx->length() << G4endl;
788  p->SetDEDXTable(dedx,fRestricted);
789  tables_are_built[i] = true;
790  } else {
791  dedx = p->DEDXTable();
792  }
793  t_list.push_back(dedx);
794  loss_list.push_back(p);
795  build_flags.push_back(val);
796  }
797  }
798  }
799 
800  G4int n_dedx = t_list.size();
801  if (0 == n_dedx || !em) {
802  G4cout << "G4LossTableManager WARNING: no DEDX processes for "
803  << aParticle->GetParticleName() << G4endl;
804  return 0;
805  }
806  G4int nSubRegions = em->NumberOfSubCutoffRegions();
807 
808  if (1 < verbose) {
809  G4cout << "G4LossTableManager::BuildTables() start to build range tables"
810  << " and the sum of " << n_dedx << " processes"
811  << " iem= " << iem << " em= " << em->GetProcessName()
812  << " buildCSDARange= " << theParameters->BuildCSDARange()
813  << " nSubRegions= " << nSubRegions;
814  if(subcutProducer) {
815  G4cout << " SubCutProducer " << subcutProducer->GetName();
816  }
817  G4cout << G4endl;
818  }
819  // do not build tables if producer class is defined
820  if(subcutProducer) { nSubRegions = 0; }
821 
822  dedx = em->DEDXTable();
823  em->SetIonisation(true);
824  em->SetDEDXTable(dedx, fIsIonisation);
825 
826  if (1 < n_dedx) {
827  dedx = 0;
829  tableBuilder->BuildDEDXTable(dedx, t_list);
830  em->SetDEDXTable(dedx, fRestricted);
831  }
832 
833  /*
834  if(2==run && "e-" == aParticle->GetParticleName()) {
835  G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
836  G4cout << (*dedx) << G4endl;
837  G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
838  G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
839  G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
840  }
841  */
842  dedx_vector[iem] = dedx;
843 
844  G4PhysicsTable* range = em->RangeTableForLoss();
845  if(!range) range = G4PhysicsTableHelper::PreparePhysicsTable(range);
846  range_vector[iem] = range;
847 
848  G4PhysicsTable* invrange = em->InverseRangeTable();
849  if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
850  inv_range_vector[iem] = invrange;
851 
852  tableBuilder->BuildRangeTable(dedx, range, true);
853  tableBuilder->BuildInverseRangeTable(range, invrange, true);
854 
855  // if(1<verbose) G4cout << *dedx << G4endl;
856 
857  em->SetRangeTableForLoss(range);
858  em->SetInverseRangeTable(invrange);
859 
860  // if(1<verbose) G4cout << *range << G4endl;
861 
862  std::vector<G4PhysicsTable*> listSub;
863  std::vector<G4PhysicsTable*> listCSDA;
864 
865  for (i=0; i<n_dedx; ++i) {
866  p = loss_list[i];
867  if(p != em) { p->SetIonisation(false); }
868  if(build_flags[i]) {
870  }
871  if (0 < nSubRegions) {
872  dedx = p->BuildDEDXTable(fSubRestricted);
873  p->SetDEDXTable(dedx,fSubRestricted);
874  listSub.push_back(dedx);
875  if(build_flags[i]) {
877  if(p != em) { em->AddCollaborativeProcess(p); }
878  }
879  }
880  if(theParameters->BuildCSDARange()) {
881  dedx = p->BuildDEDXTable(fTotal);
882  p->SetDEDXTable(dedx,fTotal);
883  listCSDA.push_back(dedx);
884  }
885  }
886 
887  if (0 < nSubRegions) {
888  G4PhysicsTable* dedxSub = em->IonisationTableForSubsec();
889  if (1 < listSub.size()) {
890  em->SetDEDXTable(dedxSub, fIsSubIonisation);
891  dedxSub = 0;
893  tableBuilder->BuildDEDXTable(dedxSub, listSub);
894  em->SetDEDXTable(dedxSub, fSubRestricted);
895  }
896  }
897  if(theParameters->BuildCSDARange()) {
898  G4PhysicsTable* dedxCSDA = em->DEDXunRestrictedTable();
899  if (1 < n_dedx) {
900  dedxCSDA = nullptr;
901  dedxCSDA = G4PhysicsTableHelper::PreparePhysicsTable(dedxCSDA);
902  tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
903  em->SetDEDXTable(dedxCSDA,fTotal);
904  }
905  G4PhysicsTable* rCSDA = em->CSDARangeTable();
906  if(!rCSDA) { rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA); }
907  tableBuilder->BuildRangeTable(dedxCSDA, rCSDA, true);
908  em->SetCSDARangeTable(rCSDA);
909  }
910 
911  if (1 < verbose) {
912  G4cout << "G4LossTableManager::BuildTables: Tables are built for "
913  << aParticle->GetParticleName()
914  << "; ionisation process: " << em->GetProcessName()
915  << " " << em
916  << G4endl;
917  }
918  return em;
919 }
920 
921 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
922 
923 void G4LossTableManager::ParticleHaveNoLoss(
924  const G4ParticleDefinition* aParticle)
925 {
927  ed << "Energy loss process not found for " << aParticle->GetParticleName()
928  << " !";
929  G4Exception("G4LossTableManager::ParticleHaveNoLoss", "em0001",
930  FatalException, ed);
931 }
932 
933 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
934 
936 {
937  verbose = val;
938 }
939 
940 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
941 
942 const std::vector<G4VEnergyLossProcess*>&
944 {
945  return loss_vector;
946 }
947 
948 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
949 
950 const std::vector<G4VEmProcess*>& G4LossTableManager::GetEmProcessVector()
951 {
952  return emp_vector;
953 }
954 
955 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
956 
957 const std::vector<G4VMultipleScattering*>&
959 {
960  return msc_vector;
961 }
962 
963 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
964 
966 {
967  return theParameters->GetEmSaturation();
968 }
969 
970 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
971 
973 {
974  if(!emConfigurator) { emConfigurator = new G4EmConfigurator(verbose); }
975  return emConfigurator;
976 }
977 
978 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
979 
981 {
982  if(!emElectronIonPair) {
983  emElectronIonPair = new G4ElectronIonPair(verbose);
984  }
985  return emElectronIonPair;
986 }
987 
988 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
989 
991 {
992  if(atomDeexcitation != p) {
993  delete atomDeexcitation;
994  atomDeexcitation = p;
995  }
996 }
997 
998 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
999 
1001 {
1002  if(subcutProducer != p) {
1003  delete subcutProducer;
1004  subcutProducer = p;
1005  }
1006 }
1007 
1008 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1009 
1010 void G4LossTableManager::PrintEWarning(G4String tit, G4double /*val*/)
1011 {
1012  G4String ss = "G4LossTableManager::" + tit;
1014  /*
1015  ed << "Parameter is out of range: " << val
1016  << " it will have no effect!\n" << " ## "
1017  << " nbins= " << nbinsLambda
1018  << " nbinsPerDecade= " << nbinsPerDecade
1019  << " Emin(keV)= " << minKinEnergy/keV
1020  << " Emax(GeV)= " << maxKinEnergy/GeV;
1021  */
1022  G4Exception(ss, "em0044", JustWarning, ed);
1023 }
1024 
1025 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4EmConfigurator * EmConfigurator()
void BuildRangeTable(const G4PhysicsTable *dedxTable, G4PhysicsTable *rangeTable, G4bool isIonisation=false)
void SetDEDXTable(G4PhysicsTable *p, G4EmTableType tType)
G4bool Spline() const
G4int WorkerVerbose() const
static G4LossTableManager * Instance()
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
void SetVerbose(G4int verb)
void SetIonisation(G4bool val)
G4PhysicsTable * SubLambdaTable() const
void DeRegister(G4VEnergyLossProcess *p)
G4PhysicsTable * RangeTableForLoss() const
const char * p
Definition: xmltok.h:285
void push_back(G4PhysicsVector *)
void AddCollaborativeProcess(G4VEnergyLossProcess *)
G4PhysicsTable * CSDARangeTable() const
const G4String & GetName() const
G4PhysicsTable * IonisationTableForSubsec() const
#define G4ThreadLocal
Definition: tls.hh:89
G4PhysicsTable * IonisationTable() const
const std::vector< G4VEmProcess * > & GetEmProcessVector()
int G4int
Definition: G4Types.hh:78
G4PhysicsTable * BuildLambdaTable(G4EmTableType tType=fRestricted)
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
const G4String & GetParticleName() const
void SetInitialisationFlag(G4bool flag)
G4bool BuildCSDARange() const
G4EmSaturation * GetEmSaturation()
G4PhysicsTable * LambdaTable() const
void SetInverseRangeTable(G4PhysicsTable *p)
const G4ParticleDefinition * SecondaryParticle() const
void SetSubCutProducer(G4VSubCutProducer *)
G4GLOB_DLL std::ostream G4cout
G4int Verbose() const
G4PhysicsTable * DEDXTable() const
bool G4bool
Definition: G4Types.hh:79
G4ElectronIonPair * ElectronIonPair()
G4EmSaturation * EmSaturation()
G4int NumberOfSubCutoffRegions() const
void Register(G4VEnergyLossProcess *p)
const G4ParticleDefinition * BaseParticle() const
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 RegisterExtraParticle(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4bool IsWorkerThread()
Definition: G4Threading.cc:145
void BuildDEDXTable(G4PhysicsTable *dedxTable, const std::vector< G4PhysicsTable * > &)
void SetVerbose(G4int value)
G4int size() const
void SetLambdaTable(G4PhysicsTable *p)
const G4String & GetName() const
G4PhysicsTable * InverseRangeTable() const
void BuildPhysicsTable(const G4ParticleDefinition *aParticle)
const G4ParticleDefinition * Particle() const
G4ProcessManager * GetProcessManager() const
void PrepareModels(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
static G4EmParameters * Instance()
void PreparePhysicsTable(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p, G4bool theMaster)
void SetCSDARangeTable(G4PhysicsTable *pRange)
void SetVerbose(G4int val)
void LocalPhysicsTables(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
static G4Electron * Electron()
Definition: G4Electron.cc:94
#define G4endl
Definition: G4ios.hh:61
const G4String & GetName() const
Definition: G4VEmModel.hh:794
void SetSecondaryRangeTable(G4PhysicsTable *p)
G4PhysicsTable * DEDXunRestrictedTable() const
double G4double
Definition: G4Types.hh:76
void SetSubLambdaTable(G4PhysicsTable *p)
void SetRangeTableForLoss(G4PhysicsTable *p)
void SetAtomDeexcitation(G4VAtomDeexcitation *)
G4PhysicsTable * BuildDEDXTable(G4EmTableType tType=fRestricted)
const std::vector< G4VMultipleScattering * > & GetMultipleScatteringVector()
G4ProcessVector * GetProcessList() const
void SetSplineFlag(G4bool flag)
G4bool IsIonisationProcess() const