Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
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// -------------------------------------------------------------------
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 std::size_t msc = msc_vector.size();
104 for (std::size_t j=0; j<msc; ++j) {
105 delete msc_vector[j];
106 }
107 std::size_t emp = emp_vector.size();
108 for (std::size_t k=0; k<emp; ++k) {
109 delete emp_vector[k];
110 }
111 emp = p_vector.size();
112 for (std::size_t k=0; k<emp; ++k) {
113 delete p_vector[k];
114 }
115 std::size_t mod = mod_vector.size();
116 std::size_t fmod = fmod_vector.size();
117 //G4cout << " Nmod" << mod << " Nfluc= " << fmod << G4endl;
118 for (std::size_t a=0; a<mod; ++a) {
119 //G4cout << "Delete model #" << a << " " << mod_vector[a] << G4endl;
120 if( nullptr != mod_vector[a] ) {
121 for (std::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 (std::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 } else {
227 if(verbose > 0) { theParameters->Dump(); }
228 }
229 tableBuilder->SetInitialisationFlag(false);
230 emCorrections->SetVerbose(verbose);
231 if(nullptr != emConfigurator) { emConfigurator->SetVerbose(verbose); };
232 if(nullptr != emElectronIonPair) { emElectronIonPair->SetVerbose(verbose); };
233 if(nullptr != atomDeexcitation) {
234 atomDeexcitation->SetVerboseLevel(verbose);
235 atomDeexcitation->InitialiseAtomicDeexcitation();
236 }
237}
238
239//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
240
242{
243 if(!p) { return; }
244 for (G4int i=0; i<n_loss; ++i) {
245 if(loss_vector[i] == p) {
246 loss_vector[i] = nullptr;
247 break;
248 }
249 }
250}
251
252//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
253
255{
256 if(!p) { return; }
257 std::size_t n = msc_vector.size();
258 for (std::size_t i=0; i<n; ++i) {
259 if(msc_vector[i] == p) { return; }
260 }
261 if(verbose > 1) {
262 G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
263 << p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
264 }
265 msc_vector.push_back(p);
266}
267
268//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
269
271{
272 if(!p) { return; }
273 std::size_t msc = msc_vector.size();
274 for (std::size_t i=0; i<msc; ++i) {
275 if(msc_vector[i] == p) {
276 msc_vector[i] = nullptr;
277 break;
278 }
279 }
280}
281
282//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
283
285{
286 if(!p) { return; }
287 std::size_t n = emp_vector.size();
288 for (std::size_t i=0; i<n; ++i) {
289 if(emp_vector[i] == p) { return; }
290 }
291 if(verbose > 1) {
292 G4cout << "G4LossTableManager::Register G4VEmProcess : "
293 << p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
294 }
295 emp_vector.push_back(p);
296}
297
298//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
299
301{
302 if(!p) { return; }
303 std::size_t emp = emp_vector.size();
304 for (std::size_t i=0; i<emp; ++i) {
305 if(emp_vector[i] == p) {
306 emp_vector[i] = nullptr;
307 break;
308 }
309 }
310}
311
312//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
313
315{
316 if(!p) { return; }
317 std::size_t n = p_vector.size();
318 for (std::size_t i=0; i<n; ++i) {
319 if(p_vector[i] == p) { return; }
320 }
321 if(verbose > 1) {
322 G4cout << "G4LossTableManager::Register G4VProcess : "
323 << p->GetProcessName() << " idx= " << p_vector.size() << G4endl;
324 }
325 p_vector.push_back(p);
326}
327
328//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
329
331{
332 if(!p) { return; }
333 std::size_t emp = p_vector.size();
334 for (std::size_t i=0; i<emp; ++i) {
335 if(p_vector[i] == p) {
336 p_vector[i] = nullptr;
337 break;
338 }
339 }
340}
341
342//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
343
345{
346 mod_vector.push_back(p);
347 if(verbose > 1) {
348 G4cout << "G4LossTableManager::Register G4VEmModel : "
349 << p->GetName() << " " << p << " " << mod_vector.size() << G4endl;
350 }
351}
352
353//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
354
356{
357 //G4cout << "G4LossTableManager::DeRegister G4VEmModel : " << p << G4endl;
358 std::size_t n = mod_vector.size();
359 for (std::size_t i=0; i<n; ++i) {
360 if(mod_vector[i] == p) {
361 mod_vector[i] = nullptr;
362 break;
363 }
364 }
365}
366
367//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
368
370{
371 fmod_vector.push_back(p);
372 if(verbose > 1) {
373 G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
374 << p->GetName() << " " << fmod_vector.size() << G4endl;
375 }
376}
377
378//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
379
381{
382 std::size_t n = fmod_vector.size();
383 for (std::size_t i=0; i<n; ++i) {
384 if(fmod_vector[i] == p) { fmod_vector[i] = nullptr; }
385 }
386}
387
388//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
389
391 const G4ParticleDefinition* part,
393{
394 if(!p || !part) { return; }
395 for (G4int i=0; i<n_loss; ++i) {
396 if(loss_vector[i] == p) { return; }
397 }
398 if(verbose > 1) {
399 G4cout << "G4LossTableManager::RegisterExtraParticle "
400 << part->GetParticleName() << " G4VEnergyLossProcess : "
401 << p->GetProcessName() << " idx= " << n_loss << G4endl;
402 }
403 ++n_loss;
404 loss_vector.push_back(p);
405 part_vector.push_back(part);
406 base_part_vector.push_back(p->BaseParticle());
407 dedx_vector.push_back(nullptr);
408 range_vector.push_back(nullptr);
409 inv_range_vector.push_back(nullptr);
410 tables_are_built.push_back(false);
411 all_tables_are_built = false;
412}
413
414//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
415
418{
419 if(aParticle != currentParticle) {
420 currentParticle = aParticle;
421 std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
422 if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
423 currentLoss = (*pos).second;
424 } else {
425 currentLoss = nullptr;
426 if(0.0 != aParticle->GetPDGCharge() &&
427 (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) {
698 theParameters->SetIsPrintedFlag(true);
699 return;
700 }
701
702 // Build tables for given particle
703 all_tables_are_built = true;
704
705 for(G4int i=0; i<n_loss; ++i) {
706 if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
707 const G4ParticleDefinition* curr_part = part_vector[i];
708 if(1 < verbose) {
709 G4cout << "### Build Table for " << p->GetProcessName()
710 << " and " << curr_part->GetParticleName()
711 << " " << tables_are_built[i] << " " << base_part_vector[i]
712 << G4endl;
713 }
714 G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
715 if(curr_proc) {
716 CopyTables(curr_part, curr_proc);
717 if(p == curr_proc && 0 == run && p->IsIonisationProcess()) {
718 loss_map[aParticle] = p;
719 //G4cout << "G4LossTableManager::BuildPhysicsTable: "
720 // << aParticle->GetParticleName()
721 // << " added to map " << p << G4endl;
722 }
723 }
724 }
725 if ( !tables_are_built[i] ) { all_tables_are_built = false; }
726 }
727 if(1 < verbose) {
728 G4cout << "### G4LossTableManager::BuildPhysicsTable end: "
729 << "all_tables_are_built= " << all_tables_are_built << " "
730 << aParticle->GetParticleName() << " proc: " << p << G4endl;
731 }
732 if(all_tables_are_built) {
733 if(1 < verbose) {
734 G4cout << "%%%%% All dEdx and Range tables are built for master run= "
735 << run << " %%%%%" << G4endl;
736 }
737 }
738}
739
740//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
741
742void G4LossTableManager::CopyTables(const G4ParticleDefinition* part,
743 G4VEnergyLossProcess* base_proc)
744{
745 for (G4int j=0; j<n_loss; ++j) {
746
747 G4VEnergyLossProcess* proc = loss_vector[j];
748
749 if (!tables_are_built[j] && part == base_part_vector[j]) {
750 tables_are_built[j] = true;
751 proc->SetDEDXTable(base_proc->IonisationTable(),fRestricted);
752 proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
753 proc->SetCSDARangeTable(base_proc->CSDARangeTable());
754 proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
755 proc->SetInverseRangeTable(base_proc->InverseRangeTable());
756 proc->SetLambdaTable(base_proc->LambdaTable());
757 proc->SetIonisation(base_proc->IsIonisationProcess());
758 if(proc->IsIonisationProcess()) {
759 range_vector[j] = base_proc->RangeTableForLoss();
760 inv_range_vector[j] = base_proc->InverseRangeTable();
761 loss_map[part_vector[j]] = proc;
762 //G4cout << "G4LossTableManager::CopyTable "
763 // << part_vector[j]->GetParticleName()
764 // << " added to map " << proc << G4endl;
765 }
766 if (1 < verbose) {
767 G4cout << "For " << proc->GetProcessName()
768 << " for " << part_vector[j]->GetParticleName()
769 << " base_part= " << part->GetParticleName()
770 << " tables are assigned"
771 << G4endl;
772 }
773 }
774 }
775}
776
777//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
778
779G4VEnergyLossProcess* G4LossTableManager::BuildTables(
780 const G4ParticleDefinition* aParticle)
781{
782 if(1 < verbose) {
783 G4cout << "G4LossTableManager::BuildTables() for "
784 << aParticle->GetParticleName() << G4endl;
785 }
786
787 std::vector<G4PhysicsTable*> t_list;
788 std::vector<G4VEnergyLossProcess*> loss_list;
789 std::vector<G4bool> build_flags;
790 G4VEnergyLossProcess* em = nullptr;
791 G4VEnergyLossProcess* p = nullptr;
792 G4int iem = 0;
793 G4PhysicsTable* dedx = nullptr;
794 G4int i;
795
796 G4ProcessVector* pvec =
797 aParticle->GetProcessManager()->GetProcessList();
798 G4int nvec = (G4int)pvec->size();
799
800 for (i=0; i<n_loss; ++i) {
801 p = loss_vector[i];
802 if (p) {
803 G4bool yes = (aParticle == part_vector[i]);
804
805 // possible case of process sharing between particle/anti-particle
806 if(!yes) {
807 auto ptr = static_cast<G4VProcess*>(p);
808 for(G4int j=0; j<nvec; ++j) {
809 //G4cout << "j= " << j << " " << (*pvec)[j] << " " << ptr << G4endl;
810 if(ptr == (*pvec)[j]) {
811 yes = true;
812 break;
813 }
814 }
815 }
816 // process belong to this particle
817 if(yes && isActive[i]) {
818 if (p->IsIonisationProcess() || !em) {
819 em = p;
820 iem= i;
821 }
822 // tables may be shared between particle/anti-particle
823 G4bool val = false;
824 if (!tables_are_built[i]) {
825 val = true;
826 dedx = p->BuildDEDXTable(fRestricted);
827 //G4cout << "Build DEDX table for " << p->GetProcessName()
828 // << " idx= " << i << dedx << " " << dedx->length() << G4endl;
829 p->SetDEDXTable(dedx,fRestricted);
830 tables_are_built[i] = true;
831 } else {
832 dedx = p->DEDXTable();
833 }
834 t_list.push_back(dedx);
835 loss_list.push_back(p);
836 build_flags.push_back(val);
837 }
838 }
839 }
840
841 G4int n_dedx = (G4int)t_list.size();
842 if (0 == n_dedx || !em) {
843 G4cout << "G4LossTableManager WARNING: no DEDX processes for "
844 << aParticle->GetParticleName() << G4endl;
845 return nullptr;
846 }
847 G4int nSubRegions = em->NumberOfSubCutoffRegions();
848
849 if (1 < verbose) {
850 G4cout << "G4LossTableManager::BuildTables() start to build range tables"
851 << " and the sum of " << n_dedx << " processes"
852 << " iem= " << iem << " em= " << em->GetProcessName()
853 << " buildCSDARange= " << theParameters->BuildCSDARange()
854 << " nSubRegions= " << nSubRegions;
855 if(subcutProducer) {
856 G4cout << " SubCutProducer " << subcutProducer->GetName();
857 }
858 G4cout << G4endl;
859 }
860 // do not build tables if producer class is defined
861 if(subcutProducer) { nSubRegions = 0; }
862
863 dedx = em->DEDXTable();
864 em->SetIonisation(true);
865 em->SetDEDXTable(dedx, fIsIonisation);
866
867 if (1 < n_dedx) {
868 dedx = nullptr;
870 tableBuilder->BuildDEDXTable(dedx, t_list);
871 em->SetDEDXTable(dedx, fRestricted);
872 }
873
874 /*
875 if(2==run && "e-" == aParticle->GetParticleName()) {
876 G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
877 G4cout << (*dedx) << G4endl;
878 G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
879 G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
880 G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
881 }
882 */
883 dedx_vector[iem] = dedx;
884
885 G4PhysicsTable* range = em->RangeTableForLoss();
886 if(!range) range = G4PhysicsTableHelper::PreparePhysicsTable(range);
887 range_vector[iem] = range;
888
889 G4PhysicsTable* invrange = em->InverseRangeTable();
890 if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
891 inv_range_vector[iem] = invrange;
892
893 tableBuilder->BuildRangeTable(dedx, range);
894 tableBuilder->BuildInverseRangeTable(range, invrange);
895
896 // if(1<verbose) G4cout << *dedx << G4endl;
897
898 em->SetRangeTableForLoss(range);
899 em->SetInverseRangeTable(invrange);
900
901 // if(1<verbose) G4cout << *range << G4endl;
902
903 std::vector<G4PhysicsTable*> listSub;
904 std::vector<G4PhysicsTable*> listCSDA;
905
906 for (i=0; i<n_dedx; ++i) {
907 p = loss_list[i];
908 if(p != em) { p->SetIonisation(false); }
909 if(build_flags[i]) {
911 }
912 if(theParameters->BuildCSDARange()) {
913 dedx = p->BuildDEDXTable(fTotal);
914 p->SetDEDXTable(dedx,fTotal);
915 listCSDA.push_back(dedx);
916 }
917 }
918
919 if(theParameters->BuildCSDARange()) {
920 G4PhysicsTable* dedxCSDA = em->DEDXunRestrictedTable();
921 if (1 < n_dedx) {
922 dedxCSDA = nullptr;
924 tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
925 em->SetDEDXTable(dedxCSDA,fTotal);
926 }
927 G4PhysicsTable* rCSDA = em->CSDARangeTable();
928 if(!rCSDA) { rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA); }
929 tableBuilder->BuildRangeTable(dedxCSDA, rCSDA);
930 em->SetCSDARangeTable(rCSDA);
931 }
932
933 if (1 < verbose) {
934 G4cout << "G4LossTableManager::BuildTables: Tables are built for "
935 << aParticle->GetParticleName()
936 << "; ionisation process: " << em->GetProcessName()
937 << " " << em
938 << G4endl;
939 }
940 return em;
941}
942
943//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
944
945void G4LossTableManager::ParticleHaveNoLoss(
946 const G4ParticleDefinition* aParticle)
947{
949 ed << "Energy loss process not found for " << aParticle->GetParticleName()
950 << " !";
951 G4Exception("G4LossTableManager::ParticleHaveNoLoss", "em0001",
952 FatalException, ed);
953}
954
955//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
956
958{
959 verbose = val;
960}
961
962//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
963
964const std::vector<G4VEnergyLossProcess*>&
966{
967 return loss_vector;
968}
969
970//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
971
972const std::vector<G4VEmProcess*>& G4LossTableManager::GetEmProcessVector()
973{
974 return emp_vector;
975}
976
977//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
978
979const std::vector<G4VMultipleScattering*>&
981{
982 return msc_vector;
983}
984
985//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
986
988{
989 return theParameters->GetEmSaturation();
990}
991
992//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
993
995{
996 if(!emConfigurator) {
997 emConfigurator = new G4EmConfigurator(verbose);
998 }
999 return emConfigurator;
1000}
1001
1002//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1003
1005{
1006 if(!emElectronIonPair) {
1007 emElectronIonPair = new G4ElectronIonPair(verbose);
1008 }
1009 return emElectronIonPair;
1010}
1011
1012//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1013
1015{
1016 if(ptr && ptr != nielCalculator) {
1017 delete nielCalculator;
1018 nielCalculator = ptr;
1019 }
1020}
1021
1022//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1023
1025{
1026 if(!nielCalculator) {
1027 nielCalculator = new G4NIELCalculator(nullptr, verbose);
1028 }
1029 return nielCalculator;
1030}
1031
1032//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1033
1035{
1036 if(atomDeexcitation != p) {
1037 delete atomDeexcitation;
1038 atomDeexcitation = p;
1039 }
1040}
1041
1042//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1043
1045{
1046 if(subcutProducer != p) {
1047 delete subcutProducer;
1048 subcutProducer = p;
1049 }
1050}
1051
1052//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1053
1054void G4LossTableManager::PrintEWarning(G4String tit, G4double /*val*/)
1055{
1056 G4String ss = "G4LossTableManager::" + tit;
1058 /*
1059 ed << "Parameter is out of range: " << val
1060 << " it will have no effect!\n" << " ## "
1061 << " nbins= " << nbinsLambda
1062 << " nbinsPerDecade= " << nbinsPerDecade
1063 << " Emin(keV)= " << minKinEnergy/keV
1064 << " Emax(GeV)= " << maxKinEnergy/GeV;
1065 */
1066 G4Exception(ss, "em0044", JustWarning, ed);
1067}
1068
1069//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1070
1072{
1073 // Automatic generation of html documentation page for physics lists
1074 // List processes and models for the most important
1075 // particles in descending order of importance
1076 // NB. for model names with length > 18 characters the .rst file needs
1077 // to be edited by hand. Or modify G4EmModelManager::DumpModelList
1078
1079 char* dirName = std::getenv("G4PhysListDocDir");
1080 char* physList = std::getenv("G4PhysListName");
1081 if (dirName && physList) {
1082 G4String physListName = G4String(physList);
1083 G4String pathName = G4String(dirName) + "/" + physListName + ".rst";
1084
1085 std::ofstream outFile;
1086 outFile.open(pathName);
1087
1088 outFile << physListName << G4endl;
1089 outFile << std::string(physListName.length(), '=') << G4endl;
1090
1091 std::vector<G4ParticleDefinition*> particles {
1098 };
1099
1100 std::vector<G4VEmProcess*> emproc_vector = GetEmProcessVector();
1101 std::vector<G4VEnergyLossProcess*> enloss_vector =
1103 std::vector<G4VMultipleScattering*> mscat_vector =
1105
1106 for (auto theParticle : particles) {
1107 outFile << G4endl << "**" << theParticle->GetParticleName()
1108 << "**" << G4endl << G4endl << " .. code-block:: none" << G4endl;
1109
1110 G4ProcessManager* pm = theParticle->GetProcessManager();
1111 G4ProcessVector* pv = pm->GetProcessList();
1112 G4int plen = pm->GetProcessListLength();
1113
1114 for (auto emproc : emproc_vector) {
1115 for (G4int i = 0; i < plen; ++i) {
1116 G4VProcess* proc = (*pv)[i];
1117 if (proc == emproc) {
1118 outFile << G4endl;
1119 proc->ProcessDescription(outFile);
1120 break;
1121 }
1122 }
1123 }
1124
1125 for (auto mscproc : mscat_vector) {
1126 for (G4int i = 0; i < plen; ++i) {
1127 G4VProcess* proc = (*pv)[i];
1128 if (proc == mscproc) {
1129 outFile << G4endl;
1130 proc->ProcessDescription(outFile);
1131 break;
1132 }
1133 }
1134 }
1135
1136 for (auto enlossproc : enloss_vector) {
1137 for (G4int i = 0; i < plen; ++i) {
1138 G4VProcess* proc = (*pv)[i];
1139 if (proc == enlossproc) {
1140 outFile << G4endl;
1141 proc->ProcessDescription(outFile);
1142 break;
1143 }
1144 }
1145 }
1146 }
1147 outFile.close();
1148 }
1149}
1150
1151//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1152
@ fTotal
@ fRestricted
@ fIsIonisation
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
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
void SetIsPrintedFlag(G4bool val)
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
void BuildRangeTable(const G4PhysicsTable *dedxTable, G4PhysicsTable *rangeTable)
void BuildDEDXTable(G4PhysicsTable *dedxTable, const std::vector< G4PhysicsTable * > &)
void BuildInverseRangeTable(const G4PhysicsTable *rangeTable, G4PhysicsTable *invRangeTable)
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
G4double GetPDGCharge() 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:816
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)
const G4ParticleDefinition * Particle() const
void SetInverseRangeTable(G4PhysicsTable *p)
G4bool IsIonisationProcess() const
void SetDEDXTable(G4PhysicsTable *p, G4EmTableType tType)
G4PhysicsTable * BuildLambdaTable(G4EmTableType tType=fRestricted)
void SetIonisation(G4bool val)
void SetLambdaTable(G4PhysicsTable *p)
G4PhysicsTable * IonisationTable() const
G4PhysicsTable * LambdaTable() const
void SetCSDARangeTable(G4PhysicsTable *pRange)
G4PhysicsTable * DEDXunRestrictedTable() const
G4PhysicsTable * DEDXTable() const
virtual void ProcessDescription(std::ostream &outfile) const
Definition: G4VProcess.cc:181
const G4String & GetProcessName() const
Definition: G4VProcess.hh:386
const G4String & GetName() const
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
#define G4ThreadLocal
Definition: tls.hh:77