Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4LossTableManager.cc
이 파일의 문서화 페이지로 가기
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 110572 2018-05-30 13:08:12Z 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 #include "G4Gamma.hh"
109 #include "G4Positron.hh"
110 #include "G4OpticalPhoton.hh"
111 #include "G4Neutron.hh"
112 #include "G4MuonPlus.hh"
113 #include "G4MuonMinus.hh"
114 
115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
116 
118 
120 {
121  if(!instance) {
123  instance = inst.Instance();
124  }
125  return instance;
126 }
127 
128 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
129 
131 {
132  //G4cout << "### G4LossTableManager::~G4LossTableManager() "<< this << G4endl;
133  for (G4int i=0; i<n_loss; ++i) {
134  //G4cout << "### eloss #" << i << G4endl;
135  if( loss_vector[i] ) {
136  delete loss_vector[i];
137  }
138  }
139  size_t msc = msc_vector.size();
140  for (size_t j=0; j<msc; ++j) {
141  if( msc_vector[j] ) { delete msc_vector[j]; }
142  }
143  size_t emp = emp_vector.size();
144  for (size_t k=0; k<emp; ++k) {
145  if( emp_vector[k] ) { delete emp_vector[k]; }
146  }
147  size_t mod = mod_vector.size();
148  size_t fmod = fmod_vector.size();
149  //G4cout << " Nmod" << mod << " Nfluc= " << fmod << G4endl;
150  for (size_t a=0; a<mod; ++a) {
151  //G4cout << "Delete model #" << a << " " << mod_vector[a] << G4endl;
152  if( nullptr != mod_vector[a] ) {
153  for (size_t b=0; b<fmod; ++b) {
154  if((G4VEmModel*)(fmod_vector[b]) == mod_vector[a]) {
155  fmod_vector[b] = nullptr;
156  }
157  }
158  delete mod_vector[a];
159  mod_vector[a] = nullptr;
160  }
161  }
162  for (size_t b=0; b<fmod; ++b) {
163  if( fmod_vector[b] ) { delete fmod_vector[b]; }
164  }
165  Clear();
166  delete tableBuilder;
167  delete emCorrections;
168  delete emConfigurator;
169  delete emElectronIonPair;
170  delete atomDeexcitation;
171  delete subcutProducer;
172 }
173 
174 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
175 
177 {
178  //G4cout << "### G4LossTableManager::G4LossTableManager() " << this << G4endl;
180  n_loss = 0;
181  run = -1;
182  startInitialisation = false;
183  all_tables_are_built = false;
184  currentLoss = nullptr;
185  currentParticle = nullptr;
186  firstParticle = nullptr;
187  isMaster = true;
190  theGenericIon= nullptr;
193  isMaster = false;
194  }
197  emConfigurator = nullptr;
198  emElectronIonPair = nullptr;
199  atomDeexcitation = nullptr;
200  subcutProducer = nullptr;
201  gammaShark = nullptr;
202 }
203 
204 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
205 
207 {
208  all_tables_are_built = false;
209  currentLoss = nullptr;
210  currentParticle = nullptr;
211  if(n_loss)
212  {
213  dedx_vector.clear();
214  range_vector.clear();
215  inv_range_vector.clear();
216  loss_map.clear();
217  loss_vector.clear();
218  part_vector.clear();
219  base_part_vector.clear();
220  tables_are_built.clear();
221  isActive.clear();
222  n_loss = 0;
223  }
224 }
225 
226 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
227 
229 {
230  if(!p) { return; }
231  for (G4int i=0; i<n_loss; ++i) {
232  if(loss_vector[i] == p) { return; }
233  }
234  if(verbose > 1) {
235  G4cout << "G4LossTableManager::Register G4VEnergyLossProcess : "
236  << p->GetProcessName() << " idx= " << n_loss << G4endl;
237  }
238  ++n_loss;
239  loss_vector.push_back(p);
240  part_vector.push_back(nullptr);
241  base_part_vector.push_back(nullptr);
242  dedx_vector.push_back(nullptr);
243  range_vector.push_back(nullptr);
244  inv_range_vector.push_back(nullptr);
245  tables_are_built.push_back(false);
246  isActive.push_back(true);
247  all_tables_are_built = false;
248 }
249 
250 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
251 
253 {
255  if(!isMaster) {
257  }
263  if(atomDeexcitation) {
266  }
267 }
268 
269 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
270 
272 {
273  if(!p) { return; }
274  for (G4int i=0; i<n_loss; ++i) {
275  if(loss_vector[i] == p) { loss_vector[i] = nullptr; }
276  }
277 }
278 
279 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
280 
282 {
283  if(!p) { return; }
284  G4int n = msc_vector.size();
285  for (G4int i=0; i<n; ++i) {
286  if(msc_vector[i] == p) { return; }
287  }
288  if(verbose > 1) {
289  G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
290  << p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
291  }
292  msc_vector.push_back(p);
293 }
294 
295 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
296 
298 {
299  if(!p) { return; }
300  size_t msc = msc_vector.size();
301  for (size_t i=0; i<msc; ++i) {
302  if(msc_vector[i] == p) { msc_vector[i] = nullptr; }
303  }
304 }
305 
306 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
307 
309 {
310  if(!p) { return; }
311  G4int n = emp_vector.size();
312  for (G4int i=0; i<n; ++i) {
313  if(emp_vector[i] == p) { return; }
314  }
315  if(verbose > 1) {
316  G4cout << "G4LossTableManager::Register G4VEmProcess : "
317  << p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
318  }
319  emp_vector.push_back(p);
320 }
321 
322 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
323 
325 {
326  if(!p) { return; }
327  size_t emp = emp_vector.size();
328  for (size_t i=0; i<emp; ++i) {
329  if(emp_vector[i] == p) { emp_vector[i] = nullptr; }
330  }
331 }
332 
333 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
334 
336 {
337  mod_vector.push_back(p);
338  if(verbose > 1) {
339  G4cout << "G4LossTableManager::Register G4VEmModel : "
340  << p->GetName() << " " << p << " " << mod_vector.size() << G4endl;
341  }
342 }
343 
344 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
345 
347 {
348  //G4cout << "G4LossTableManager::DeRegister G4VEmModel : " << p << G4endl;
349  size_t n = mod_vector.size();
350  for (size_t i=0; i<n; ++i) {
351  if(mod_vector[i] == p) {
352  mod_vector[i] = nullptr;
353  break;
354  }
355  }
356 }
357 
358 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
359 
361 {
362  fmod_vector.push_back(p);
363  if(verbose > 1) {
364  G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
365  << p->GetName() << " " << fmod_vector.size() << G4endl;
366  }
367 }
368 
369 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
370 
372 {
373  size_t n = fmod_vector.size();
374  for (size_t i=0; i<n; ++i) {
375  if(fmod_vector[i] == p) { fmod_vector[i] = nullptr; }
376  }
377 }
378 
379 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
380 
382  const G4ParticleDefinition* part,
384 {
385  if(!p || !part) { return; }
386  for (G4int i=0; i<n_loss; ++i) {
387  if(loss_vector[i] == p) { return; }
388  }
389  if(verbose > 1) {
390  G4cout << "G4LossTableManager::RegisterExtraParticle "
391  << part->GetParticleName() << " G4VEnergyLossProcess : "
392  << p->GetProcessName() << " idx= " << n_loss << G4endl;
393  }
394  ++n_loss;
395  loss_vector.push_back(p);
396  part_vector.push_back(part);
397  base_part_vector.push_back(p->BaseParticle());
398  dedx_vector.push_back(nullptr);
399  range_vector.push_back(nullptr);
400  inv_range_vector.push_back(nullptr);
401  tables_are_built.push_back(false);
402  all_tables_are_built = false;
403 }
404 
405 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
406 
409 {
410  //G4cout << "G4LossTableManager::GetEnergyLossProcess: "
411  //<< aParticle << " " << currentParticle << " " << currentLoss << G4endl;
412  if(aParticle != currentParticle) {
413  currentParticle = aParticle;
414  std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
415  if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
416  currentLoss = (*pos).second;
417  } else {
418  currentLoss = nullptr;
419  if ((pos = loss_map.find(theGenericIon)) != loss_map.end()) {
420  currentLoss = (*pos).second;
421  }
422  }
423  }
424  return currentLoss;
425 }
426 
427 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
428 
429 void
432  G4bool theMaster)
433 {
434  if (1 < verbose) {
435  G4cout << "G4LossTableManager::PreparePhysicsTable for "
436  << particle->GetParticleName()
437  << " and " << p->GetProcessName() << " run= " << run
438  << " loss_vector " << loss_vector.size() << G4endl;
439  }
440 
441  isMaster = theMaster;
442 
443  if(!startInitialisation) {
444  ResetParameters();
445  if (1 < verbose) {
446  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
447  << G4endl;
448  }
449  }
450 
451  // start initialisation for the first run
452  if( -1 == run ) {
453  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
454 
455  // initialise particles for given process
456  for (G4int j=0; j<n_loss; ++j) {
457  if (p == loss_vector[j] && !part_vector[j]) {
458  part_vector[j] = particle;
459  if(particle->GetParticleName() == "GenericIon") {
460  theGenericIon = particle;
461  }
462  }
463  }
464  }
465  startInitialisation = true;
466 }
467 
468 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
469 
470 void
472  G4VEmProcess* p, G4bool theMaster)
473 {
474  if (1 < verbose) {
475  G4cout << "G4LossTableManager::PreparePhysicsTable for "
476  << particle->GetParticleName()
477  << " and " << p->GetProcessName() << G4endl;
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
501  G4bool theMaster)
502 {
503  if (1 < verbose) {
504  G4cout << "G4LossTableManager::PreparePhysicsTable for "
505  << particle->GetParticleName()
506  << " and " << p->GetProcessName() << G4endl;
507  }
508 
509  isMaster = theMaster;
510 
511  if(!startInitialisation) {
512  ResetParameters();
513  if (1 < verbose) {
514  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
515  << G4endl;
516  }
517  }
518 
519  // start initialisation for the first run
520  if( -1 == run ) {
521  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
522  }
523  startInitialisation = true;
524 }
525 
526 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
527 
528 void
530 {
531  if(-1 == run && startInitialisation) {
533  }
534 }
535 
536 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
537 
539  const G4ParticleDefinition* aParticle,
541 {
542  if(1 < verbose) {
543  G4cout << "### G4LossTableManager::LocalPhysicsTable() for "
544  << aParticle->GetParticleName()
545  << " and process " << p->GetProcessName()
546  << G4endl;
547  }
548 
549  if(-1 == run && startInitialisation) {
551  firstParticle = aParticle;
552  }
553 
554  if(startInitialisation) {
555  ++run;
556  if(1 < verbose) {
557  G4cout << "===== G4LossTableManager::LocalPhysicsTable() for run "
558  << run << " =====" << G4endl;
559  }
560  currentParticle = nullptr;
561  startInitialisation = false;
562  for (G4int i=0; i<n_loss; ++i) {
563  if(loss_vector[i]) {
564  tables_are_built[i] = false;
565  } else {
566  tables_are_built[i] = true;
567  part_vector[i] = nullptr;
568  }
569  }
570  }
571 
572  all_tables_are_built= true;
573  for (G4int i=0; i<n_loss; ++i) {
574  if(p == loss_vector[i]) {
575  tables_are_built[i] = true;
576  isActive[i] = true;
577  part_vector[i] = p->Particle();
578  base_part_vector[i] = p->BaseParticle();
579  dedx_vector[i] = p->DEDXTable();
582  if(0 == run && p->IsIonisationProcess()) {
583  loss_map[part_vector[i]] = p;
584  //G4cout << "G4LossTableManager::LocalPhysicsTable " << part_vector[i]->GetParticleName()
585  // << " added to map " << p << G4endl;
586  }
587 
588  if(1 < verbose) {
589  G4cout << i <<". "<< p->GetProcessName();
590  if(part_vector[i]) {
591  G4cout << " for " << part_vector[i]->GetParticleName();
592  }
593  G4cout << " active= " << isActive[i]
594  << " table= " << tables_are_built[i]
595  << " isIonisation= " << p->IsIonisationProcess()
596  << G4endl;
597  }
598  break;
599  } else if(!tables_are_built[i]) {
600  all_tables_are_built = false;
601  }
602  }
603 
604  if(1 < verbose) {
605  G4cout << "### G4LossTableManager::LocalPhysicsTable end"
606  << G4endl;
607  }
608  if(all_tables_are_built) {
609  if(1 < verbose) {
610  G4cout << "%%%%% All dEdx and Range tables for worker are ready for run "
611  << run << " %%%%%" << G4endl;
612  }
613  }
614 }
615 
616 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
617 
619  const G4ParticleDefinition* aParticle,
621 {
622  if(1 < verbose) {
623  G4cout << "### G4LossTableManager::BuildPhysicsTable() for "
624  << aParticle->GetParticleName()
625  << " and process " << p->GetProcessName() << G4endl;
626  }
627  // clear configurator
628  if(-1 == run && startInitialisation) {
630  firstParticle = aParticle;
631  }
632  if(startInitialisation) {
633  ++run;
634  if(1 < verbose) {
635  G4cout << "===== G4LossTableManager::BuildPhysicsTable() for run "
636  << run << " ===== " << atomDeexcitation << G4endl;
637  }
638  currentParticle = nullptr;
639  all_tables_are_built= true;
640  }
641 
642  // initialisation before any table is built
643  if ( startInitialisation && aParticle == firstParticle ) {
644 
645  startInitialisation = false;
646  if(1 < verbose) {
647  G4cout << "### G4LossTableManager start initilisation for first particle "
649  << G4endl;
650  }
651  for (G4int i=0; i<n_loss; ++i) {
653 
654  if(el) {
655  isActive[i] = true;
656  base_part_vector[i] = el->BaseParticle();
657  tables_are_built[i] = false;
658  all_tables_are_built= false;
659  if(!isActive[i]) {
660  el->SetIonisation(false);
661  tables_are_built[i] = true;
662  }
663 
664  if(1 < verbose) {
665  G4cout << i <<". "<< el->GetProcessName();
666  if(el->Particle()) {
667  G4cout << " for " << el->Particle()->GetParticleName();
668  }
669  G4cout << " active= " << isActive[i]
670  << " table= " << tables_are_built[i]
671  << " isIonisation= " << el->IsIonisationProcess();
672  if(base_part_vector[i]) {
673  G4cout << " base particle "
674  << base_part_vector[i]->GetParticleName();
675  }
676  G4cout << G4endl;
677  }
678  } else {
679  tables_are_built[i] = true;
680  part_vector[i] = nullptr;
681  isActive[i] = false;
682  }
683  }
684  }
685 
686  if (all_tables_are_built) { return; }
687 
688  // Build tables for given particle
689  all_tables_are_built = true;
690 
691  for(G4int i=0; i<n_loss; ++i) {
692  if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
693  const G4ParticleDefinition* curr_part = part_vector[i];
694  if(1 < verbose) {
695  G4cout << "### Build Table for " << p->GetProcessName()
696  << " and " << curr_part->GetParticleName()
697  << " " << tables_are_built[i] << " " << base_part_vector[i] << G4endl;
698  }
699  G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
700  if(curr_proc) {
701  CopyTables(curr_part, curr_proc);
702  if(p == curr_proc && 0 == run && p->IsIonisationProcess()) {
703  loss_map[aParticle] = p;
704  //G4cout << "G4LossTableManager::BuildPhysicsTable: " << aParticle->GetParticleName()
705  // << " added to map " << p << G4endl;
706  }
707  }
708  }
709  if ( !tables_are_built[i] ) { all_tables_are_built = false; }
710  }
711  if(1 < verbose) {
712  G4cout << "### G4LossTableManager::BuildPhysicsTable end: "
713  << "all_tables_are_built= " << all_tables_are_built << " "
714  << aParticle->GetParticleName() << " proc: " << p << G4endl;
715  }
716  if(all_tables_are_built) {
717  if(1 < verbose) {
718  G4cout << "%%%%% All dEdx and Range tables are built for master run= "
719  << run << " %%%%%" << G4endl;
720  }
721  }
722 }
723 
724 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
725 
727  G4VEnergyLossProcess* base_proc)
728 {
729  for (G4int j=0; j<n_loss; ++j) {
730 
732 
733  if (!tables_are_built[j] && part == base_part_vector[j]) {
734  tables_are_built[j] = true;
735  proc->SetDEDXTable(base_proc->IonisationTable(),fRestricted);
736  proc->SetDEDXTable(base_proc->DEDXTableForSubsec(),fSubRestricted);
737  proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
738  proc->SetCSDARangeTable(base_proc->CSDARangeTable());
739  proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
740  proc->SetInverseRangeTable(base_proc->InverseRangeTable());
741  proc->SetLambdaTable(base_proc->LambdaTable());
742  proc->SetSubLambdaTable(base_proc->SubLambdaTable());
743  proc->SetIonisation(base_proc->IsIonisationProcess());
744  if(proc->IsIonisationProcess()) {
745  range_vector[j] = base_proc->RangeTableForLoss();
746  inv_range_vector[j] = base_proc->InverseRangeTable();
747  loss_map[part_vector[j]] = proc;
748  //G4cout << "G4LossTableManager::CopyTable " << part_vector[j]->GetParticleName()
749  // << " added to map " << proc << G4endl;
750  }
751  if (1 < verbose) {
752  G4cout << "For " << proc->GetProcessName()
753  << " for " << part_vector[j]->GetParticleName()
754  << " base_part= " << part->GetParticleName()
755  << " tables are assigned"
756  << G4endl;
757  }
758  }
759 
760  if (theElectron == part && theElectron == proc->SecondaryParticle() ) {
761  proc->SetSecondaryRangeTable(base_proc->RangeTableForLoss());
762  }
763  }
764 }
765 
766 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
767 
769  const G4ParticleDefinition* aParticle)
770 {
771  if(1 < verbose) {
772  G4cout << "G4LossTableManager::BuildTables() for "
773  << aParticle->GetParticleName() << G4endl;
774  }
775 
776  std::vector<G4PhysicsTable*> t_list;
777  std::vector<G4VEnergyLossProcess*> loss_list;
778  std::vector<G4bool> build_flags;
779  G4VEnergyLossProcess* em = nullptr;
780  G4VEnergyLossProcess* p = nullptr;
781  G4int iem = 0;
782  G4PhysicsTable* dedx = 0;
783  G4int i;
784 
785  G4ProcessVector* pvec =
786  aParticle->GetProcessManager()->GetProcessList();
787  G4int nvec = pvec->size();
788 
789  for (i=0; i<n_loss; ++i) {
790  p = loss_vector[i];
791  if (p) {
792  G4bool yes = (aParticle == part_vector[i]);
793 
794  // possible case of process sharing between particle/anti-particle
795  if(!yes) {
796  G4VProcess* ptr = static_cast<G4VProcess*>(p);
797  for(G4int j=0; j<nvec; ++j) {
798  //G4cout << "j= " << j << " " << (*pvec)[j] << " " << ptr << G4endl;
799  if(ptr == (*pvec)[j]) {
800  yes = true;
801  break;
802  }
803  }
804  }
805  // process belong to this particle
806  if(yes && isActive[i]) {
807  if (p->IsIonisationProcess() || !em) {
808  em = p;
809  iem= i;
810  }
811  // tables may be shared between particle/anti-particle
812  G4bool val = false;
813  if (!tables_are_built[i]) {
814  val = true;
815  dedx = p->BuildDEDXTable(fRestricted);
816  //G4cout << "Build DEDX table for " << p->GetProcessName()
817  // << " idx= " << i << dedx << " " << dedx->length() << G4endl;
818  p->SetDEDXTable(dedx,fRestricted);
819  tables_are_built[i] = true;
820  } else {
821  dedx = p->DEDXTable();
822  }
823  t_list.push_back(dedx);
824  loss_list.push_back(p);
825  build_flags.push_back(val);
826  }
827  }
828  }
829 
830  G4int n_dedx = t_list.size();
831  if (0 == n_dedx || !em) {
832  G4cout << "G4LossTableManager WARNING: no DEDX processes for "
833  << aParticle->GetParticleName() << G4endl;
834  return 0;
835  }
836  G4int nSubRegions = em->NumberOfSubCutoffRegions();
837 
838  if (1 < verbose) {
839  G4cout << "G4LossTableManager::BuildTables() start to build range tables"
840  << " and the sum of " << n_dedx << " processes"
841  << " iem= " << iem << " em= " << em->GetProcessName()
842  << " buildCSDARange= " << theParameters->BuildCSDARange()
843  << " nSubRegions= " << nSubRegions;
844  if(subcutProducer) {
845  G4cout << " SubCutProducer " << subcutProducer->GetName();
846  }
847  G4cout << G4endl;
848  }
849  // do not build tables if producer class is defined
850  if(subcutProducer) { nSubRegions = 0; }
851 
852  dedx = em->DEDXTable();
853  em->SetIonisation(true);
854  em->SetDEDXTable(dedx, fIsIonisation);
855 
856  if (1 < n_dedx) {
857  dedx = 0;
859  tableBuilder->BuildDEDXTable(dedx, t_list);
860  em->SetDEDXTable(dedx, fRestricted);
861  }
862 
863  /*
864  if(2==run && "e-" == aParticle->GetParticleName()) {
865  G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
866  G4cout << (*dedx) << G4endl;
867  G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
868  G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
869  G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
870  }
871  */
872  dedx_vector[iem] = dedx;
873 
875  if(!range) range = G4PhysicsTableHelper::PreparePhysicsTable(range);
876  range_vector[iem] = range;
877 
878  G4PhysicsTable* invrange = em->InverseRangeTable();
879  if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
880  inv_range_vector[iem] = invrange;
881 
882  tableBuilder->BuildRangeTable(dedx, range, true);
883  tableBuilder->BuildInverseRangeTable(range, invrange, true);
884 
885  // if(1<verbose) G4cout << *dedx << G4endl;
886 
887  em->SetRangeTableForLoss(range);
888  em->SetInverseRangeTable(invrange);
889 
890  // if(1<verbose) G4cout << *range << G4endl;
891 
892  std::vector<G4PhysicsTable*> listSub;
893  std::vector<G4PhysicsTable*> listCSDA;
894 
895  for (i=0; i<n_dedx; ++i) {
896  p = loss_list[i];
897  if(p != em) { p->SetIonisation(false); }
898  if(build_flags[i]) {
900  }
901  if (0 < nSubRegions) {
902  dedx = p->BuildDEDXTable(fSubRestricted);
903  p->SetDEDXTable(dedx,fSubRestricted);
904  listSub.push_back(dedx);
905  if(build_flags[i]) {
907  if(p != em) { em->AddCollaborativeProcess(p); }
908  }
909  }
910  if(theParameters->BuildCSDARange()) {
911  dedx = p->BuildDEDXTable(fTotal);
912  p->SetDEDXTable(dedx,fTotal);
913  listCSDA.push_back(dedx);
914  }
915  }
916 
917  if (0 < nSubRegions) {
918  G4PhysicsTable* dedxSub = em->IonisationTableForSubsec();
919  if (1 < listSub.size()) {
920  em->SetDEDXTable(dedxSub, fIsSubIonisation);
921  dedxSub = 0;
923  tableBuilder->BuildDEDXTable(dedxSub, listSub);
924  em->SetDEDXTable(dedxSub, fSubRestricted);
925  }
926  }
928  G4PhysicsTable* dedxCSDA = em->DEDXunRestrictedTable();
929  if (1 < n_dedx) {
930  dedxCSDA = nullptr;
931  dedxCSDA = G4PhysicsTableHelper::PreparePhysicsTable(dedxCSDA);
932  tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
933  em->SetDEDXTable(dedxCSDA,fTotal);
934  }
935  G4PhysicsTable* rCSDA = em->CSDARangeTable();
936  if(!rCSDA) { rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA); }
937  tableBuilder->BuildRangeTable(dedxCSDA, rCSDA, true);
938  em->SetCSDARangeTable(rCSDA);
939  }
940 
941  if (1 < verbose) {
942  G4cout << "G4LossTableManager::BuildTables: Tables are built for "
943  << aParticle->GetParticleName()
944  << "; ionisation process: " << em->GetProcessName()
945  << " " << em
946  << G4endl;
947  }
948  return em;
949 }
950 
951 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
952 
954  const G4ParticleDefinition* aParticle)
955 {
957  ed << "Energy loss process not found for " << aParticle->GetParticleName()
958  << " !";
959  G4Exception("G4LossTableManager::ParticleHaveNoLoss", "em0001",
960  FatalException, ed);
961 }
962 
963 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
964 
966 {
967  verbose = val;
968 }
969 
970 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
971 
972 const std::vector<G4VEnergyLossProcess*>&
974 {
975  return loss_vector;
976 }
977 
978 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
979 
980 const std::vector<G4VEmProcess*>& G4LossTableManager::GetEmProcessVector()
981 {
982  return emp_vector;
983 }
984 
985 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
986 
987 const std::vector<G4VMultipleScattering*>&
989 {
990  return msc_vector;
991 }
992 
993 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
994 
996 {
997  return theParameters->GetEmSaturation();
998 }
999 
1000 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1001 
1003 {
1005  return emConfigurator;
1006 }
1007 
1008 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1009 
1011 {
1012  if(!emElectronIonPair) {
1014  }
1015  return emElectronIonPair;
1016 }
1017 
1018 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1019 
1021 {
1022  if(atomDeexcitation != p) {
1023  delete atomDeexcitation;
1024  atomDeexcitation = p;
1025  }
1026 }
1027 
1028 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1029 
1031 {
1032  if(subcutProducer != p) {
1033  delete subcutProducer;
1034  subcutProducer = p;
1035  }
1036 }
1037 
1038 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1039 
1041 {
1042  G4String ss = "G4LossTableManager::" + tit;
1044  /*
1045  ed << "Parameter is out of range: " << val
1046  << " it will have no effect!\n" << " ## "
1047  << " nbins= " << nbinsLambda
1048  << " nbinsPerDecade= " << nbinsPerDecade
1049  << " Emin(keV)= " << minKinEnergy/keV
1050  << " Emax(GeV)= " << maxKinEnergy/GeV;
1051  */
1052  G4Exception(ss, "em0044", JustWarning, ed);
1053 }
1054 
1055 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1056 
1058 {
1059  // Automatic generation of html documentation page for physics lists
1060  // List processes and models for the most important
1061  // particles in descending order of importance
1062 
1063  char* dirName = getenv("G4PhysListDocDir");
1064  char* physListName = getenv("G4PhysListName");
1065  if (dirName && physListName) {
1066  G4String pathName = G4String(dirName) + "/" + G4String(physListName)
1067  + ".html";
1068 
1069  std::ofstream outFile;
1070  outFile.open(pathName);
1071 
1072  outFile << "<html>\n";
1073  outFile << "<head>\n";
1074  outFile << "<title>Physics List Summary</title>\n";
1075  outFile << "</head>\n";
1076  outFile << "<body>\n";
1077  outFile << "<h2> Summary of Electromagnetic Processes, Models and Cross "
1078  << "Sections for Physics List "
1079  << G4String(physListName) << "</h2>\n";
1080  outFile << "<ul>\n";
1081 
1082  std::vector<G4ParticleDefinition*> particles {
1083  G4Gamma::Gamma(),
1089  };
1090 
1091  std::vector<G4VEmProcess*> emproc_vector = GetEmProcessVector();
1092  std::vector<G4VEnergyLossProcess*> enloss_vector =
1094  std::vector<G4VMultipleScattering*> mscat_vector =
1096 
1097  for (auto theParticle : particles) {
1098  outFile << "<li><h3>" << theParticle->GetParticleName() << "</h3><ul>\n";
1099 
1100  G4ProcessManager* pm = theParticle->GetProcessManager();
1101  G4ProcessVector* pv = pm->GetProcessList();
1102  G4int plen = pm->GetProcessListLength();
1103 
1104  for (auto emproc : emproc_vector) {
1105  for (G4int i = 0; i < plen; ++i) {
1106  G4VProcess* proc = (*pv)[i];
1107  if (proc == emproc) {
1108  outFile << "<li>\n";
1109  proc->ProcessDescription(outFile);
1110  outFile << "</li>\n";
1111  break;
1112  }
1113  }
1114  }
1115 
1116  for (auto mscproc : mscat_vector) {
1117  for (G4int i = 0; i < plen; ++i) {
1118  G4VProcess* proc = (*pv)[i];
1119  if (proc == mscproc) {
1120  outFile << "<li>\n";
1121  proc->ProcessDescription(outFile);
1122  outFile << "</li>\n";
1123  break;
1124  }
1125  }
1126  }
1127 
1128  for (auto enlossproc : enloss_vector) {
1129  for (G4int i = 0; i < plen; ++i) {
1130  G4VProcess* proc = (*pv)[i];
1131  if (proc == enlossproc) {
1132  outFile << "<li>\n";
1133  proc->ProcessDescription(outFile);
1134  outFile << "</li>\n";
1135  break;
1136  }
1137  }
1138  }
1139  outFile << "</ul>\n";
1140  outFile << "</li>\n";
1141  }
1142  outFile << "</ul>\n";
1143  outFile << "</body>\n";
1144  outFile << "</html>\n";
1145  outFile.close();
1146  }
1147 }
1148 
1149 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1150 
void SetDEDXTable(G4PhysicsTable *p, G4EmTableType tType)
std::vector< G4VMultipleScattering * > msc_vector
G4LossTableBuilder * tableBuilder
G4VSubCutProducer * subcutProducer
G4int NumberOfSubCutoffRegions() const
G4PhysicsTable * DEDXTable() const
void AddCollaborativeProcess(G4VEnergyLossProcess *)
void BuildRangeTable(const G4PhysicsTable *dedxTable, G4PhysicsTable *rangeTable, G4bool isIonisation=false)
G4PhysicsTable * BuildDEDXTable(G4EmTableType tType=fRestricted)
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:45
std::vector< ExP01TrackerHit * > a
Definition: ExP01Classes.hh:33
std::vector< G4VEmModel * > mod_vector
static const G4double pos
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
const G4String & GetName() const
G4PhysicsTable * IonisationTableForSubsec() const
G4int GetProcessListLength() const
G4EmSaturation * GetEmSaturation()
void SetInitialisationFlag(G4bool flag)
void SetSplineFlag(G4bool flag)
G4VEnergyLossProcess * GetEnergyLossProcess(const G4ParticleDefinition *)
#define G4endl
Definition: G4ios.hh:61
const char * p
Definition: xmltok.h:285
void BuildPhysicsTable(const G4ParticleDefinition *aParticle)
G4bool BuildCSDARange() const
G4PhysicsTable * RangeTableForLoss() const
void PreparePhysicsTable(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p, G4bool theMaster)
const G4String & GetParticleName() const
void BuildInverseRangeTable(const G4PhysicsTable *rangeTable, G4PhysicsTable *invRangeTable, G4bool isIonisation=false)
const G4ParticleDefinition * BaseParticle() const
std::vector< G4PhysicsTable * > inv_range_vector
void SetSubLambdaTable(G4PhysicsTable *p)
G4PhysicsTable * SubLambdaTable() const
static G4ThreadLocal G4LossTableManager * instance
G4EmCorrections * emCorrections
void SetVerbose(G4int val)
G4ProcessVector * GetProcessList() const
#define G4ThreadLocal
Definition: tls.hh:69
std::vector< G4VEnergyLossProcess * > loss_vector
void BuildDEDXTable(G4PhysicsTable *dedxTable, const std::vector< G4PhysicsTable * > &)
const G4String & GetName() const
const std::vector< G4VEnergyLossProcess * > & GetEnergyLossProcessVector()
std::vector< G4VEmFluctuationModel * > fmod_vector
static G4MuonMinus * MuonMinusDefinition()
Definition: G4MuonMinus.cc:95
G4ElectronIonPair * emElectronIonPair
void ParticleHaveNoLoss(const G4ParticleDefinition *aParticle)
std::vector< G4PhysicsTable * > dedx_vector
static G4Gamma * Gamma()
Definition: G4Gamma.cc:86
G4ElectronIonPair * ElectronIonPair()
void CopyTables(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *)
std::vector< G4PhysicsTable * > range_vector
void SetRangeTableForLoss(G4PhysicsTable *p)
void Register(G4VEnergyLossProcess *p)
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
G4VAtomDeexcitation * atomDeexcitation
TString part[npart]
Definition: Style.C:32
const std::vector< G4VEmProcess * > & GetEmProcessVector()
void SetSubCutProducer(G4VSubCutProducer *)
static G4Proton * ProtonDefinition()
Definition: G4Proton.cc:88
G4bool IsWorkerThread()
Definition: G4Threading.cc:129
void SetIonisation(G4bool val)
G4VEnergyLossProcess * currentLoss
G4PhysicsTable * InverseRangeTable() const
const G4ParticleDefinition const G4Material *G4double range
void SetCSDARangeTable(G4PhysicsTable *pRange)
G4EmConfigurator * emConfigurator
std::vector< G4bool > tables_are_built
G4int WorkerVerbose() const
void SetLambdaTable(G4PhysicsTable *p)
G4PhysicsTable * BuildLambdaTable(G4EmTableType tType=fRestricted)
const G4String & GetProcessName() const
Definition: G4VProcess.hh:411
void DeRegister(G4VEnergyLossProcess *p)
static G4Positron * Positron()
Definition: G4Positron.cc:94
void LocalPhysicsTables(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
G4PhysicsTable * DEDXTableForSubsec() const
void PrintEWarning(G4String, G4double)
G4int Verbose() const
static G4Electron * Electron()
Definition: G4Electron.cc:94
const G4ParticleDefinition * SecondaryParticle() const
G4VEnergyLossProcess * BuildTables(const G4ParticleDefinition *aParticle)
G4GammaShark * gammaShark
const std::vector< G4VMultipleScattering * > & GetMultipleScatteringVector()
void SetSecondaryRangeTable(G4PhysicsTable *p)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
G4bool IsIonisationProcess() const
void push_back(G4PhysicsVector *)
int G4int
Definition: G4Types.hh:78
G4EmSaturation * EmSaturation()
void SetVerbose(G4int verb)
const G4String & GetName() const
Definition: G4VEmModel.hh:777
G4ProcessManager * GetProcessManager() const
G4PhysicsTable * LambdaTable() const
virtual void ProcessDescription(std::ostream &outfile) const
Definition: G4VProcess.cc:186
void PrepareModels(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
G4EmParameters * theParameters
G4int size() const
G4GLOB_DLL std::ostream G4cout
static G4LossTableManager * Instance()
void SetAtomDeexcitation(G4VAtomDeexcitation *)
G4PhysicsTable * IonisationTable() const
G4PhysicsTable * CSDARangeTable() const
Char_t n[5]
void SetInverseRangeTable(G4PhysicsTable *p)
void SetVerbose(G4int value)
static G4MuonPlus * MuonPlusDefinition()
Definition: G4MuonPlus.cc:94
G4PhysicsTable * DEDXunRestrictedTable() const
std::vector< G4VEmProcess * > emp_vector
std::vector< G4bool > isActive
G4EmConfigurator * EmConfigurator()
std::map< PD, G4VEnergyLossProcess *, std::less< PD > > loss_map
G4bool Spline() const
std::vector< PD > base_part_vector
void RegisterExtraParticle(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
static G4EmParameters * Instance()
std::vector< PD > part_vector
const G4ParticleDefinition * Particle() const