Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// -------------------------------------------------------------------
27//
28// GEANT4 Class file
29//
30//
31// File name: G4LossTableManager
32//
33// Author: Vladimir Ivanchenko
34//
35// Creation date: 03.01.2002
36//
37// Modifications: by V.Ivanchenko
38//
39//
40// Class Description:
41//
42// -------------------------------------------------------------------
43//
44//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
45//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
46
47#include "G4LossTableManager.hh"
48#include "G4SystemOfUnits.hh"
49
51#include "G4VEmProcess.hh"
52
53#include "G4EmParameters.hh"
54#include "G4EmSaturation.hh"
55#include "G4EmConfigurator.hh"
56#include "G4ElectronIonPair.hh"
57#include "G4NIELCalculator.hh"
58#include "G4EmCorrections.hh"
59#include "G4LossTableBuilder.hh"
61#include "G4VSubCutProducer.hh"
62
63#include "G4PhysicsTable.hh"
66#include "G4ProcessManager.hh"
67#include "G4Electron.hh"
68#include "G4Proton.hh"
71#include "G4EmTableType.hh"
72#include "G4Region.hh"
74#include "G4Threading.hh"
75
76#include "G4Gamma.hh"
77#include "G4Positron.hh"
78#include "G4OpticalPhoton.hh"
79#include "G4Neutron.hh"
80#include "G4MuonPlus.hh"
81#include "G4MuonMinus.hh"
82
83//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
84
85G4ThreadLocal G4LossTableManager* G4LossTableManager::instance = nullptr;
86
88{
89 if(!instance) {
91 instance = inst.Instance();
92 }
93 return instance;
94}
95
96//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
97
99{
100 for (G4int i=0; i<n_loss; ++i) {
101 delete loss_vector[i];
102 }
103 size_t msc = msc_vector.size();
104 for (size_t j=0; j<msc; ++j) {
105 delete msc_vector[j];
106 }
107 size_t emp = emp_vector.size();
108 for (size_t k=0; k<emp; ++k) {
109 delete emp_vector[k];
110 }
111 emp = p_vector.size();
112 for (size_t k=0; k<emp; ++k) {
113 delete p_vector[k];
114 }
115 size_t mod = mod_vector.size();
116 size_t fmod = fmod_vector.size();
117 //G4cout << " Nmod" << mod << " Nfluc= " << fmod << G4endl;
118 for (size_t a=0; a<mod; ++a) {
119 //G4cout << "Delete model #" << a << " " << mod_vector[a] << G4endl;
120 if( nullptr != mod_vector[a] ) {
121 for (size_t b=0; b<fmod; ++b) {
122 if((G4VEmModel*)(fmod_vector[b]) == mod_vector[a]) {
123 fmod_vector[b] = nullptr;
124 }
125 }
126 delete mod_vector[a];
127 mod_vector[a] = nullptr;
128 }
129 }
130 for (size_t b=0; b<fmod; ++b) {
131 delete fmod_vector[b];
132 }
133 Clear();
134 delete tableBuilder;
135 delete emCorrections;
136 delete emConfigurator;
137 delete emElectronIonPair;
138 delete nielCalculator;
139 delete atomDeexcitation;
140 delete subcutProducer;
141}
142
143//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
144
145G4LossTableManager::G4LossTableManager()
146{
147 theParameters = G4EmParameters::Instance();
148 n_loss = 0;
149 run = -1;
150 startInitialisation = false;
151 all_tables_are_built = false;
152 currentLoss = nullptr;
153 currentParticle = nullptr;
154 firstParticle = nullptr;
155 isMaster = true;
156 verbose = theParameters->Verbose();
157 theElectron = G4Electron::Electron();
158 theGenericIon= nullptr;
160 verbose = theParameters->WorkerVerbose();
161 isMaster = false;
162 }
163 tableBuilder = new G4LossTableBuilder(isMaster);
164 emCorrections= new G4EmCorrections(verbose);
165 emConfigurator = nullptr;
166 emElectronIonPair = nullptr;
167 atomDeexcitation = nullptr;
168 subcutProducer = nullptr;
169 nielCalculator = nullptr;
170 gGeneral = nullptr;
171 eGeneral = pGeneral = nullptr;
172}
173
174//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
175
176void G4LossTableManager::Clear()
177{
178 all_tables_are_built = false;
179 currentLoss = nullptr;
180 currentParticle = nullptr;
181 if(n_loss) {
182 dedx_vector.clear();
183 range_vector.clear();
184 inv_range_vector.clear();
185 loss_map.clear();
186 loss_vector.clear();
187 part_vector.clear();
188 base_part_vector.clear();
189 tables_are_built.clear();
190 isActive.clear();
191 n_loss = 0;
192 }
193}
194
195//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
196
198{
199 if(!p) { return; }
200 for (G4int i=0; i<n_loss; ++i) {
201 if(loss_vector[i] == p) { return; }
202 }
203 if(verbose > 1) {
204 G4cout << "G4LossTableManager::Register G4VEnergyLossProcess : "
205 << p->GetProcessName() << " idx= " << n_loss << G4endl;
206 }
207 ++n_loss;
208 loss_vector.push_back(p);
209 part_vector.push_back(nullptr);
210 base_part_vector.push_back(nullptr);
211 dedx_vector.push_back(nullptr);
212 range_vector.push_back(nullptr);
213 inv_range_vector.push_back(nullptr);
214 tables_are_built.push_back(false);
215 isActive.push_back(true);
216 all_tables_are_built = false;
217}
218
219//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
220
222{
223 verbose = theParameters->Verbose();
224 if(!isMaster) {
225 verbose = theParameters->WorkerVerbose();
226 }
227 tableBuilder->SetSplineFlag(theParameters->Spline());
228 tableBuilder->SetInitialisationFlag(false);
229 emCorrections->SetVerbose(verbose);
230 if(emConfigurator) { emConfigurator->SetVerbose(verbose); };
231 if(emElectronIonPair) { emElectronIonPair->SetVerbose(verbose); };
232 if(atomDeexcitation) {
233 atomDeexcitation->SetVerboseLevel(verbose);
234 atomDeexcitation->InitialiseAtomicDeexcitation();
235 }
236}
237
238//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
239
241{
242 if(!p) { return; }
243 for (G4int i=0; i<n_loss; ++i) {
244 if(loss_vector[i] == p) {
245 loss_vector[i] = nullptr;
246 break;
247 }
248 }
249}
250
251//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
252
254{
255 if(!p) { return; }
256 G4int n = msc_vector.size();
257 for (G4int i=0; i<n; ++i) {
258 if(msc_vector[i] == p) { return; }
259 }
260 if(verbose > 1) {
261 G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
262 << p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
263 }
264 msc_vector.push_back(p);
265}
266
267//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
268
270{
271 if(!p) { return; }
272 size_t msc = msc_vector.size();
273 for (size_t i=0; i<msc; ++i) {
274 if(msc_vector[i] == p) {
275 msc_vector[i] = nullptr;
276 break;
277 }
278 }
279}
280
281//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
282
284{
285 if(!p) { return; }
286 G4int n = emp_vector.size();
287 for (G4int i=0; i<n; ++i) {
288 if(emp_vector[i] == p) { return; }
289 }
290 if(verbose > 1) {
291 G4cout << "G4LossTableManager::Register G4VEmProcess : "
292 << p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
293 }
294 emp_vector.push_back(p);
295}
296
297//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
298
300{
301 if(!p) { return; }
302 size_t emp = emp_vector.size();
303 for (size_t i=0; i<emp; ++i) {
304 if(emp_vector[i] == p) {
305 emp_vector[i] = nullptr;
306 break;
307 }
308 }
309}
310
311//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
312
314{
315 if(!p) { return; }
316 G4int n = p_vector.size();
317 for (G4int i=0; i<n; ++i) {
318 if(p_vector[i] == p) { return; }
319 }
320 if(verbose > 1) {
321 G4cout << "G4LossTableManager::Register G4VProcess : "
322 << p->GetProcessName() << " idx= " << p_vector.size() << G4endl;
323 }
324 p_vector.push_back(p);
325}
326
327//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
328
330{
331 if(!p) { return; }
332 size_t emp = p_vector.size();
333 for (size_t i=0; i<emp; ++i) {
334 if(p_vector[i] == p) {
335 p_vector[i] = nullptr;
336 break;
337 }
338 }
339}
340
341//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
342
344{
345 mod_vector.push_back(p);
346 if(verbose > 1) {
347 G4cout << "G4LossTableManager::Register G4VEmModel : "
348 << p->GetName() << " " << p << " " << mod_vector.size() << G4endl;
349 }
350}
351
352//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
353
355{
356 //G4cout << "G4LossTableManager::DeRegister G4VEmModel : " << p << G4endl;
357 size_t n = mod_vector.size();
358 for (size_t i=0; i<n; ++i) {
359 if(mod_vector[i] == p) {
360 mod_vector[i] = nullptr;
361 break;
362 }
363 }
364}
365
366//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
367
369{
370 fmod_vector.push_back(p);
371 if(verbose > 1) {
372 G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
373 << p->GetName() << " " << fmod_vector.size() << G4endl;
374 }
375}
376
377//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
378
380{
381 size_t n = fmod_vector.size();
382 for (size_t i=0; i<n; ++i) {
383 if(fmod_vector[i] == p) { fmod_vector[i] = nullptr; }
384 }
385}
386
387//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
388
390 const G4ParticleDefinition* part,
392{
393 if(!p || !part) { return; }
394 for (G4int i=0; i<n_loss; ++i) {
395 if(loss_vector[i] == p) { return; }
396 }
397 if(verbose > 1) {
398 G4cout << "G4LossTableManager::RegisterExtraParticle "
399 << part->GetParticleName() << " G4VEnergyLossProcess : "
400 << p->GetProcessName() << " idx= " << n_loss << G4endl;
401 }
402 ++n_loss;
403 loss_vector.push_back(p);
404 part_vector.push_back(part);
405 base_part_vector.push_back(p->BaseParticle());
406 dedx_vector.push_back(nullptr);
407 range_vector.push_back(nullptr);
408 inv_range_vector.push_back(nullptr);
409 tables_are_built.push_back(false);
410 all_tables_are_built = false;
411}
412
413//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
414
417{
418 //G4cout << "G4LossTableManager::GetEnergyLossProcess: "
419 //<< aParticle << " " << currentParticle << " " << currentLoss << G4endl;
420 if(aParticle != currentParticle) {
421 currentParticle = aParticle;
422 std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
423 if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
424 currentLoss = (*pos).second;
425 } else {
426 currentLoss = nullptr;
427 if ((pos = loss_map.find(theGenericIon)) != loss_map.end()) {
428 currentLoss = (*pos).second;
429 }
430 }
431 }
432 return currentLoss;
433}
434
435//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
436
437void
440 G4bool theMaster)
441{
442 if (1 < verbose) {
443 G4cout << "G4LossTableManager::PreparePhysicsTable for "
444 << particle->GetParticleName()
445 << " and " << p->GetProcessName() << " run= " << run
446 << " loss_vector " << loss_vector.size() << G4endl;
447 }
448
449 isMaster = theMaster;
450
451 if(!startInitialisation) {
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 // initialise particles for given process
464 for (G4int j=0; j<n_loss; ++j) {
465 if (p == loss_vector[j] && !part_vector[j]) {
466 part_vector[j] = particle;
467 if(particle->GetParticleName() == "GenericIon") {
468 theGenericIon = particle;
469 }
470 }
471 }
472 }
473 startInitialisation = true;
474}
475
476//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
477
478void
480 G4VEmProcess* p, G4bool theMaster)
481{
482 if (1 < verbose) {
483 G4cout << "G4LossTableManager::PreparePhysicsTable for "
484 << particle->GetParticleName()
485 << " and " << p->GetProcessName() << G4endl;
486 }
487 isMaster = theMaster;
488
489 if(!startInitialisation) {
491 if (1 < verbose) {
492 G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
493 << G4endl;
494 }
495 }
496
497 // start initialisation for the first run
498 if( -1 == run ) {
499 if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
500 }
501 startInitialisation = true;
502}
503
504//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
505
506void
509 G4bool theMaster)
510{
511 if (1 < verbose) {
512 G4cout << "G4LossTableManager::PreparePhysicsTable for "
513 << particle->GetParticleName()
514 << " and " << p->GetProcessName() << G4endl;
515 }
516
517 isMaster = theMaster;
518
519 if(!startInitialisation) {
521 if (1 < verbose) {
522 G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
523 << G4endl;
524 }
525 }
526
527 // start initialisation for the first run
528 if( -1 == run ) {
529 if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
530 }
531 startInitialisation = true;
532}
533
534//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
535
536void
538{
539 if(-1 == run && startInitialisation) {
540 if(emConfigurator) { emConfigurator->Clear(); }
541 }
542}
543
544//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
545
547 const G4ParticleDefinition* aParticle,
549{
550 if(1 < verbose) {
551 G4cout << "### G4LossTableManager::LocalPhysicsTable() for "
552 << aParticle->GetParticleName()
553 << " and process " << p->GetProcessName()
554 << G4endl;
555 }
556
557 if(-1 == run && startInitialisation) {
558 if(emConfigurator) { emConfigurator->Clear(); }
559 firstParticle = aParticle;
560 }
561
562 if(startInitialisation) {
563 ++run;
564 if(1 < verbose) {
565 G4cout << "===== G4LossTableManager::LocalPhysicsTable() for run "
566 << run << " =====" << G4endl;
567 }
568 currentParticle = nullptr;
569 startInitialisation = false;
570 for (G4int i=0; i<n_loss; ++i) {
571 if(loss_vector[i]) {
572 tables_are_built[i] = false;
573 } else {
574 tables_are_built[i] = true;
575 part_vector[i] = nullptr;
576 }
577 }
578 }
579
580 all_tables_are_built= true;
581 for (G4int i=0; i<n_loss; ++i) {
582 if(p == loss_vector[i]) {
583 tables_are_built[i] = true;
584 isActive[i] = true;
585 part_vector[i] = p->Particle();
586 base_part_vector[i] = p->BaseParticle();
587 dedx_vector[i] = p->DEDXTable();
588 range_vector[i] = p->RangeTableForLoss();
589 inv_range_vector[i] = p->InverseRangeTable();
590 if(0 == run && p->IsIonisationProcess()) {
591 loss_map[part_vector[i]] = p;
592 //G4cout << "G4LossTableManager::LocalPhysicsTable " << part_vector[i]->GetParticleName()
593 // << " added to map " << p << G4endl;
594 }
595
596 if(1 < verbose) {
597 G4cout << i <<". "<< p->GetProcessName();
598 if(part_vector[i]) {
599 G4cout << " for " << part_vector[i]->GetParticleName();
600 }
601 G4cout << " active= " << isActive[i]
602 << " table= " << tables_are_built[i]
603 << " isIonisation= " << p->IsIonisationProcess()
604 << G4endl;
605 }
606 break;
607 } else if(!tables_are_built[i]) {
608 all_tables_are_built = false;
609 }
610 }
611
612 if(1 < verbose) {
613 G4cout << "### G4LossTableManager::LocalPhysicsTable end"
614 << G4endl;
615 }
616 if(all_tables_are_built) {
617 if(1 < verbose) {
618 G4cout << "%%%%% All dEdx and Range tables for worker are ready for run "
619 << run << " %%%%%" << G4endl;
620 }
621 }
622}
623
624//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
625
627 const G4ParticleDefinition* aParticle,
629{
630 if(1 < verbose) {
631 G4cout << "### G4LossTableManager::BuildPhysicsTable() for "
632 << aParticle->GetParticleName()
633 << " and process " << p->GetProcessName() << G4endl;
634 }
635 // clear configurator
636 if(-1 == run && startInitialisation) {
637 if(emConfigurator) { emConfigurator->Clear(); }
638 firstParticle = aParticle;
639 }
640 if(startInitialisation) {
641 ++run;
642 if(1 < verbose) {
643 G4cout << "===== G4LossTableManager::BuildPhysicsTable() for run "
644 << run << " ===== " << atomDeexcitation << G4endl;
645 }
646 currentParticle = nullptr;
647 all_tables_are_built= true;
648 }
649
650 // initialisation before any table is built
651 if ( startInitialisation && aParticle == firstParticle ) {
652
653 startInitialisation = false;
654 if(1 < verbose) {
655 G4cout << "### G4LossTableManager start initialisation for first particle "
656 << firstParticle->GetParticleName()
657 << G4endl;
658 }
659
660 if(nielCalculator) { nielCalculator->Initialise(); }
661
662 for (G4int i=0; i<n_loss; ++i) {
663 G4VEnergyLossProcess* el = loss_vector[i];
664
665 if(el) {
666 isActive[i] = true;
667 base_part_vector[i] = el->BaseParticle();
668 tables_are_built[i] = false;
669 all_tables_are_built= false;
670 if(!isActive[i]) {
671 el->SetIonisation(false);
672 tables_are_built[i] = true;
673 }
674
675 if(1 < verbose) {
676 G4cout << i <<". "<< el->GetProcessName();
677 if(el->Particle()) {
678 G4cout << " for " << el->Particle()->GetParticleName();
679 }
680 G4cout << " active= " << isActive[i]
681 << " table= " << tables_are_built[i]
682 << " isIonisation= " << el->IsIonisationProcess();
683 if(base_part_vector[i]) {
684 G4cout << " base particle "
685 << base_part_vector[i]->GetParticleName();
686 }
687 G4cout << G4endl;
688 }
689 } else {
690 tables_are_built[i] = true;
691 part_vector[i] = nullptr;
692 isActive[i] = false;
693 }
694 }
695 }
696
697 if (all_tables_are_built) { return; }
698
699 // Build tables for given particle
700 all_tables_are_built = true;
701
702 for(G4int i=0; i<n_loss; ++i) {
703 if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
704 const G4ParticleDefinition* curr_part = part_vector[i];
705 if(1 < verbose) {
706 G4cout << "### Build Table for " << p->GetProcessName()
707 << " and " << curr_part->GetParticleName()
708 << " " << tables_are_built[i] << " " << base_part_vector[i]
709 << G4endl;
710 }
711 G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
712 if(curr_proc) {
713 CopyTables(curr_part, curr_proc);
714 if(p == curr_proc && 0 == run && p->IsIonisationProcess()) {
715 loss_map[aParticle] = p;
716 //G4cout << "G4LossTableManager::BuildPhysicsTable: "
717 // << aParticle->GetParticleName()
718 // << " added to map " << p << G4endl;
719 }
720 }
721 }
722 if ( !tables_are_built[i] ) { all_tables_are_built = false; }
723 }
724 if(1 < verbose) {
725 G4cout << "### G4LossTableManager::BuildPhysicsTable end: "
726 << "all_tables_are_built= " << all_tables_are_built << " "
727 << aParticle->GetParticleName() << " proc: " << p << G4endl;
728 }
729 if(all_tables_are_built) {
730 if(1 < verbose) {
731 G4cout << "%%%%% All dEdx and Range tables are built for master run= "
732 << run << " %%%%%" << G4endl;
733 }
734 }
735}
736
737//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
738
739void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
740 G4VEnergyLossProcess* base_proc)
741{
742 for (G4int j=0; j<n_loss; ++j) {
743
744 G4VEnergyLossProcess* proc = loss_vector[j];
745
746 if (!tables_are_built[j] && part == base_part_vector[j]) {
747 tables_are_built[j] = true;
748 proc->SetDEDXTable(base_proc->IonisationTable(),fRestricted);
750 proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
751 proc->SetCSDARangeTable(base_proc->CSDARangeTable());
752 proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
753 proc->SetInverseRangeTable(base_proc->InverseRangeTable());
754 proc->SetLambdaTable(base_proc->LambdaTable());
755 proc->SetSubLambdaTable(base_proc->SubLambdaTable());
756 proc->SetIonisation(base_proc->IsIonisationProcess());
757 if(proc->IsIonisationProcess()) {
758 range_vector[j] = base_proc->RangeTableForLoss();
759 inv_range_vector[j] = base_proc->InverseRangeTable();
760 loss_map[part_vector[j]] = proc;
761 //G4cout << "G4LossTableManager::CopyTable "
762 // << part_vector[j]->GetParticleName()
763 // << " added to map " << proc << G4endl;
764 }
765 if (1 < verbose) {
766 G4cout << "For " << proc->GetProcessName()
767 << " for " << part_vector[j]->GetParticleName()
768 << " base_part= " << part->GetParticleName()
769 << " tables are assigned"
770 << G4endl;
771 }
772 }
773
774 if (theElectron == part && theElectron == proc->SecondaryParticle() ) {
775 proc->SetSecondaryRangeTable(base_proc->RangeTableForLoss());
776 }
777 }
778}
779
780//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
781
782G4VEnergyLossProcess* G4LossTableManager::BuildTables(
783 const G4ParticleDefinition* aParticle)
784{
785 if(1 < verbose) {
786 G4cout << "G4LossTableManager::BuildTables() for "
787 << aParticle->GetParticleName() << G4endl;
788 }
789
790 std::vector<G4PhysicsTable*> t_list;
791 std::vector<G4VEnergyLossProcess*> loss_list;
792 std::vector<G4bool> build_flags;
793 G4VEnergyLossProcess* em = nullptr;
794 G4VEnergyLossProcess* p = nullptr;
795 G4int iem = 0;
796 G4PhysicsTable* dedx = nullptr;
797 G4int i;
798
799 G4ProcessVector* pvec =
800 aParticle->GetProcessManager()->GetProcessList();
801 G4int nvec = pvec->size();
802
803 for (i=0; i<n_loss; ++i) {
804 p = loss_vector[i];
805 if (p) {
806 G4bool yes = (aParticle == part_vector[i]);
807
808 // possible case of process sharing between particle/anti-particle
809 if(!yes) {
810 G4VProcess* ptr = static_cast<G4VProcess*>(p);
811 for(G4int j=0; j<nvec; ++j) {
812 //G4cout << "j= " << j << " " << (*pvec)[j] << " " << ptr << G4endl;
813 if(ptr == (*pvec)[j]) {
814 yes = true;
815 break;
816 }
817 }
818 }
819 // process belong to this particle
820 if(yes && isActive[i]) {
821 if (p->IsIonisationProcess() || !em) {
822 em = p;
823 iem= i;
824 }
825 // tables may be shared between particle/anti-particle
826 G4bool val = false;
827 if (!tables_are_built[i]) {
828 val = true;
829 dedx = p->BuildDEDXTable(fRestricted);
830 //G4cout << "Build DEDX table for " << p->GetProcessName()
831 // << " idx= " << i << dedx << " " << dedx->length() << G4endl;
832 p->SetDEDXTable(dedx,fRestricted);
833 tables_are_built[i] = true;
834 } else {
835 dedx = p->DEDXTable();
836 }
837 t_list.push_back(dedx);
838 loss_list.push_back(p);
839 build_flags.push_back(val);
840 }
841 }
842 }
843
844 G4int n_dedx = t_list.size();
845 if (0 == n_dedx || !em) {
846 G4cout << "G4LossTableManager WARNING: no DEDX processes for "
847 << aParticle->GetParticleName() << G4endl;
848 return 0;
849 }
850 G4int nSubRegions = em->NumberOfSubCutoffRegions();
851
852 if (1 < verbose) {
853 G4cout << "G4LossTableManager::BuildTables() start to build range tables"
854 << " and the sum of " << n_dedx << " processes"
855 << " iem= " << iem << " em= " << em->GetProcessName()
856 << " buildCSDARange= " << theParameters->BuildCSDARange()
857 << " nSubRegions= " << nSubRegions;
858 if(subcutProducer) {
859 G4cout << " SubCutProducer " << subcutProducer->GetName();
860 }
861 G4cout << G4endl;
862 }
863 // do not build tables if producer class is defined
864 if(subcutProducer) { nSubRegions = 0; }
865
866 dedx = em->DEDXTable();
867 em->SetIonisation(true);
868 em->SetDEDXTable(dedx, fIsIonisation);
869
870 if (1 < n_dedx) {
871 dedx = 0;
873 tableBuilder->BuildDEDXTable(dedx, t_list);
874 em->SetDEDXTable(dedx, fRestricted);
875 }
876
877 /*
878 if(2==run && "e-" == aParticle->GetParticleName()) {
879 G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
880 G4cout << (*dedx) << G4endl;
881 G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
882 G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
883 G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
884 }
885 */
886 dedx_vector[iem] = dedx;
887
888 G4PhysicsTable* range = em->RangeTableForLoss();
889 if(!range) range = G4PhysicsTableHelper::PreparePhysicsTable(range);
890 range_vector[iem] = range;
891
892 G4PhysicsTable* invrange = em->InverseRangeTable();
893 if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
894 inv_range_vector[iem] = invrange;
895
896 tableBuilder->BuildRangeTable(dedx, range, true);
897 tableBuilder->BuildInverseRangeTable(range, invrange, true);
898
899 // if(1<verbose) G4cout << *dedx << G4endl;
900
901 em->SetRangeTableForLoss(range);
902 em->SetInverseRangeTable(invrange);
903
904 // if(1<verbose) G4cout << *range << G4endl;
905
906 std::vector<G4PhysicsTable*> listSub;
907 std::vector<G4PhysicsTable*> listCSDA;
908
909 for (i=0; i<n_dedx; ++i) {
910 p = loss_list[i];
911 if(p != em) { p->SetIonisation(false); }
912 if(build_flags[i]) {
914 }
915 if (0 < nSubRegions) {
918 listSub.push_back(dedx);
919 if(build_flags[i]) {
921 if(p != em) { em->AddCollaborativeProcess(p); }
922 }
923 }
924 if(theParameters->BuildCSDARange()) {
925 dedx = p->BuildDEDXTable(fTotal);
926 p->SetDEDXTable(dedx,fTotal);
927 listCSDA.push_back(dedx);
928 }
929 }
930
931 if (0 < nSubRegions) {
933 if (1 < listSub.size()) {
934 em->SetDEDXTable(dedxSub, fIsSubIonisation);
935 dedxSub = 0;
937 tableBuilder->BuildDEDXTable(dedxSub, listSub);
938 em->SetDEDXTable(dedxSub, fSubRestricted);
939 }
940 }
941 if(theParameters->BuildCSDARange()) {
942 G4PhysicsTable* dedxCSDA = em->DEDXunRestrictedTable();
943 if (1 < n_dedx) {
944 dedxCSDA = nullptr;
946 tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
947 em->SetDEDXTable(dedxCSDA,fTotal);
948 }
949 G4PhysicsTable* rCSDA = em->CSDARangeTable();
950 if(!rCSDA) { rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA); }
951 tableBuilder->BuildRangeTable(dedxCSDA, rCSDA, true);
952 em->SetCSDARangeTable(rCSDA);
953 }
954
955 if (1 < verbose) {
956 G4cout << "G4LossTableManager::BuildTables: Tables are built for "
957 << aParticle->GetParticleName()
958 << "; ionisation process: " << em->GetProcessName()
959 << " " << em
960 << G4endl;
961 }
962 return em;
963}
964
965//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
966
967void G4LossTableManager::ParticleHaveNoLoss(
968 const G4ParticleDefinition* aParticle)
969{
971 ed << "Energy loss process not found for " << aParticle->GetParticleName()
972 << " !";
973 G4Exception("G4LossTableManager::ParticleHaveNoLoss", "em0001",
974 FatalException, ed);
975}
976
977//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
978
980{
981 verbose = val;
982}
983
984//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
985
986const std::vector<G4VEnergyLossProcess*>&
988{
989 return loss_vector;
990}
991
992//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
993
994const std::vector<G4VEmProcess*>& G4LossTableManager::GetEmProcessVector()
995{
996 return emp_vector;
997}
998
999//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1000
1001const std::vector<G4VMultipleScattering*>&
1003{
1004 return msc_vector;
1005}
1006
1007//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1008
1010{
1011 return theParameters->GetEmSaturation();
1012}
1013
1014//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1015
1017{
1018 if(!emConfigurator) {
1019 emConfigurator = new G4EmConfigurator(verbose);
1020 }
1021 return emConfigurator;
1022}
1023
1024//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1025
1027{
1028 if(!emElectronIonPair) {
1029 emElectronIonPair = new G4ElectronIonPair(verbose);
1030 }
1031 return emElectronIonPair;
1032}
1033
1034//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1035
1037{
1038 if(ptr && ptr != nielCalculator) {
1039 delete nielCalculator;
1040 nielCalculator = ptr;
1041 }
1042}
1043
1044//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1045
1047{
1048 if(!nielCalculator) {
1049 nielCalculator = new G4NIELCalculator(nullptr, verbose);
1050 }
1051 return nielCalculator;
1052}
1053
1054//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1055
1057{
1058 if(atomDeexcitation != p) {
1059 delete atomDeexcitation;
1060 atomDeexcitation = p;
1061 }
1062}
1063
1064//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1065
1067{
1068 if(subcutProducer != p) {
1069 delete subcutProducer;
1070 subcutProducer = p;
1071 }
1072}
1073
1074//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1075
1076void G4LossTableManager::PrintEWarning(G4String tit, G4double /*val*/)
1077{
1078 G4String ss = "G4LossTableManager::" + tit;
1080 /*
1081 ed << "Parameter is out of range: " << val
1082 << " it will have no effect!\n" << " ## "
1083 << " nbins= " << nbinsLambda
1084 << " nbinsPerDecade= " << nbinsPerDecade
1085 << " Emin(keV)= " << minKinEnergy/keV
1086 << " Emax(GeV)= " << maxKinEnergy/GeV;
1087 */
1088 G4Exception(ss, "em0044", JustWarning, ed);
1089}
1090
1091//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1092
1094{
1095 // Automatic generation of html documentation page for physics lists
1096 // List processes and models for the most important
1097 // particles in descending order of importance
1098 // NB. for model names with length > 18 characters the .rst file needs
1099 // to be edited by hand. Or modify G4EmModelManager::DumpModelList
1100
1101 char* dirName = std::getenv("G4PhysListDocDir");
1102 char* physList = std::getenv("G4PhysListName");
1103 if (dirName && physList) {
1104 G4String physListName = G4String(physList);
1105 G4String pathName = G4String(dirName) + "/" + physListName + ".rst";
1106
1107 std::ofstream outFile;
1108 outFile.open(pathName);
1109
1110 outFile << physListName << G4endl;
1111 outFile << std::string(physListName.length(), '=') << G4endl;
1112
1113 std::vector<G4ParticleDefinition*> particles {
1120 };
1121
1122 std::vector<G4VEmProcess*> emproc_vector = GetEmProcessVector();
1123 std::vector<G4VEnergyLossProcess*> enloss_vector =
1125 std::vector<G4VMultipleScattering*> mscat_vector =
1127
1128 for (auto theParticle : particles) {
1129 outFile << G4endl << "**" << theParticle->GetParticleName()
1130 << "**" << G4endl << G4endl << " .. code-block:: none" << G4endl;
1131
1132 G4ProcessManager* pm = theParticle->GetProcessManager();
1133 G4ProcessVector* pv = pm->GetProcessList();
1134 G4int plen = pm->GetProcessListLength();
1135
1136 for (auto emproc : emproc_vector) {
1137 for (G4int i = 0; i < plen; ++i) {
1138 G4VProcess* proc = (*pv)[i];
1139 if (proc == emproc) {
1140 outFile << G4endl;
1141 proc->ProcessDescription(outFile);
1142 break;
1143 }
1144 }
1145 }
1146
1147 for (auto mscproc : mscat_vector) {
1148 for (G4int i = 0; i < plen; ++i) {
1149 G4VProcess* proc = (*pv)[i];
1150 if (proc == mscproc) {
1151 outFile << G4endl;
1152 proc->ProcessDescription(outFile);
1153 break;
1154 }
1155 }
1156 }
1157
1158 for (auto enlossproc : enloss_vector) {
1159 for (G4int i = 0; i < plen; ++i) {
1160 G4VProcess* proc = (*pv)[i];
1161 if (proc == enlossproc) {
1162 outFile << G4endl;
1163 proc->ProcessDescription(outFile);
1164 break;
1165 }
1166 }
1167 }
1168 }
1169 outFile.close();
1170 }
1171}
1172
1173//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1174
@ fSubRestricted
@ fTotal
@ fIsSubIonisation
@ fRestricted
@ fIsIonisation
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4Electron * Electron()
Definition: G4Electron.cc:93
void SetVerbose(G4int value)
void PrepareModels(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void SetVerbose(G4int verb)
static G4EmParameters * Instance()
G4bool BuildCSDARange() const
G4EmSaturation * GetEmSaturation()
G4int Verbose() const
G4int WorkerVerbose() const
G4bool Spline() const
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
void BuildInverseRangeTable(const G4PhysicsTable *rangeTable, G4PhysicsTable *invRangeTable, G4bool useBM=false)
void BuildRangeTable(const G4PhysicsTable *dedxTable, G4PhysicsTable *rangeTable, G4bool useBM=false)
void BuildDEDXTable(G4PhysicsTable *dedxTable, const std::vector< G4PhysicsTable * > &)
void SetSplineFlag(G4bool flag)
void SetInitialisationFlag(G4bool flag)
void SetAtomDeexcitation(G4VAtomDeexcitation *)
static G4LossTableManager * Instance()
const std::vector< G4VEmProcess * > & GetEmProcessVector()
G4VEnergyLossProcess * GetEnergyLossProcess(const G4ParticleDefinition *)
void LocalPhysicsTables(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
void PreparePhysicsTable(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p, G4bool theMaster)
void BuildPhysicsTable(const G4ParticleDefinition *aParticle)
const std::vector< G4VMultipleScattering * > & GetMultipleScatteringVector()
void SetVerbose(G4int val)
void DeRegister(G4VEnergyLossProcess *p)
G4NIELCalculator * NIELCalculator()
void SetNIELCalculator(G4NIELCalculator *)
G4EmConfigurator * EmConfigurator()
void Register(G4VEnergyLossProcess *p)
G4ElectronIonPair * ElectronIonPair()
G4EmSaturation * EmSaturation()
const std::vector< G4VEnergyLossProcess * > & GetEnergyLossProcessVector()
void SetSubCutProducer(G4VSubCutProducer *)
void RegisterExtraParticle(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
static G4MuonMinus * MuonMinusDefinition()
Definition: G4MuonMinus.cc:94
static G4MuonPlus * MuonPlusDefinition()
Definition: G4MuonPlus.cc:93
G4ProcessManager * GetProcessManager() const
const G4String & GetParticleName() const
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
void push_back(G4PhysicsVector *)
static G4Positron * Positron()
Definition: G4Positron.cc:93
G4int GetProcessListLength() const
G4ProcessVector * GetProcessList() const
std::size_t size() const
static G4Proton * ProtonDefinition()
Definition: G4Proton.cc:87
const G4String & GetName() const
const G4String & GetName() const
Definition: G4VEmModel.hh:827
const G4ParticleDefinition * BaseParticle() const
G4PhysicsTable * RangeTableForLoss() const
G4PhysicsTable * InverseRangeTable() const
G4PhysicsTable * CSDARangeTable() const
void SetRangeTableForLoss(G4PhysicsTable *p)
G4int NumberOfSubCutoffRegions() const
G4PhysicsTable * BuildDEDXTable(G4EmTableType tType=fRestricted)
void AddCollaborativeProcess(G4VEnergyLossProcess *)
G4PhysicsTable * DEDXTableForSubsec() const
G4PhysicsTable * IonisationTableForSubsec() const
const G4ParticleDefinition * Particle() const
void SetInverseRangeTable(G4PhysicsTable *p)
G4PhysicsTable * SubLambdaTable() const
G4bool IsIonisationProcess() const
void SetDEDXTable(G4PhysicsTable *p, G4EmTableType tType)
void SetSecondaryRangeTable(G4PhysicsTable *p)
G4PhysicsTable * BuildLambdaTable(G4EmTableType tType=fRestricted)
void SetIonisation(G4bool val)
void SetSubLambdaTable(G4PhysicsTable *p)
void SetLambdaTable(G4PhysicsTable *p)
G4PhysicsTable * IonisationTable() const
G4PhysicsTable * LambdaTable() const
void SetCSDARangeTable(G4PhysicsTable *pRange)
G4PhysicsTable * DEDXunRestrictedTable() const
G4PhysicsTable * DEDXTable() const
const G4ParticleDefinition * SecondaryParticle() const
virtual void ProcessDescription(std::ostream &outfile) const
Definition: G4VProcess.cc:175
const G4String & GetProcessName() const
Definition: G4VProcess.hh:382
const G4String & GetName() const
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
#define G4ThreadLocal
Definition: tls.hh:77