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
G4EmConfigurator.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//
29// GEANT4 Class
30//
31// File name: G4EmConfigurator
32//
33// Author: Vladimir Ivanchenko
34//
35// Creation date: 14.07.2008
36//
37// Modifications:
38//
39// Class Description:
40//
41// This class provides configuration EM models for
42// particles/processes/regions
43//
44
45// -------------------------------------------------------------------
46//
47
48#include "G4EmConfigurator.hh"
49#include "G4EmUtility.hh"
50#include "G4SystemOfUnits.hh"
51#include "G4ParticleTable.hh"
53#include "G4ProcessManager.hh"
54#include "G4VProcess.hh"
55#include "G4ProcessVector.hh"
56#include "G4RegionStore.hh"
57#include "G4Region.hh"
58#include "G4DummyModel.hh"
60#include "G4VEmProcess.hh"
63
64//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
65
67{
68 index = -10;
69}
70
71//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
72
74
75//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
76
78 const G4String& processName,
79 G4VEmModel* mod,
80 const G4String& regionName,
81 G4double emin,
82 G4double emax,
84{
85 if(nullptr == mod) { return; }
86 if(1 < verbose) {
87 G4cout << " G4EmConfigurator::SetExtraEmModel " << mod->GetName()
88 << " for " << particleName
89 << " and " << processName
90 << " in the region <" << regionName
91 << "> Emin(MeV)= " << emin/MeV
92 << " Emax(MeV)= " << emax/MeV
93 << G4endl;
94 }
95
96 models.push_back(mod);
97 flucModels.push_back(fm);
98 G4double emin0 = std::max(emin, mod->LowEnergyLimit());
99 G4double emax0 = std::min(emax, mod->HighEnergyLimit());
101
102 particles.push_back(particleName);
103 processes.push_back(processName);
104 regions.push_back(regionName);
105 lowEnergy.push_back(emin0);
106 highEnergy.push_back(emax0);
107}
108
109//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
110
112{
113 size_t n = models.size();
114 if(1 < verbose) {
115 G4cout << "### G4EmConfigurator::AddModels n= " << n << G4endl;
116 }
117 if(n > 0) {
118 for(size_t i=0; i<n; ++i) {
119 if(nullptr != models[i]) {
120 const G4Region* reg = G4EmUtility::FindRegion(regions[i]);
121 if(nullptr != reg) {
122 --index;
123 SetModelForRegion(models[i],flucModels[i],reg,
124 particles[i],processes[i],
125 lowEnergy[i],highEnergy[i]);
126 }
127 }
128 }
129 }
130 Clear();
131}
132
133//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
134
135void G4EmConfigurator::SetModelForRegion(G4VEmModel* mod,
137 const G4Region* reg,
138 const G4String& particleName,
139 const G4String& processName,
140 G4double emin, G4double emax)
141{
142 if(nullptr == mod) { return; }
143 if(1 < verbose) {
144 G4cout << " G4EmConfigurator::SetModelForRegion: " << mod->GetName()
145 << G4endl;
146 G4cout << " For " << particleName
147 << " and " << processName
148 << " in the region <" << reg->GetName()
149 << " Emin(MeV)= " << emin/MeV
150 << " Emax(MeV)= " << emax/MeV;
151 if(nullptr != fm) { G4cout << " FLmodel " << fm->GetName(); }
152 G4cout << G4endl;
153 }
154
155 // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
156 auto myParticleIterator = G4ParticleTable::GetParticleTable()->GetIterator();
157 myParticleIterator->reset();
158 while( (*myParticleIterator)() ) {
159 const G4ParticleDefinition* part = myParticleIterator->value();
160
161 if((part->GetParticleName() == particleName) ||
162 (particleName == "all") ||
163 (particleName == "charged" && part->GetPDGCharge() != 0.0)) {
164
165 // search for process
166 G4ProcessManager* pmanager = part->GetProcessManager();
167 G4ProcessVector* plist = pmanager->GetProcessList();
168 G4int np = pmanager->GetProcessListLength();
169
170 if(1 < verbose) {
171 G4cout << "Check process <" << processName << "> for "
172 << particleName << " in list of " << np << " processes"
173 << G4endl;
174 }
175 G4VProcess* proc = nullptr;
176 for(G4int i=0; i<np; ++i) {
177 if(processName == (*plist)[i]->GetProcessName()) {
178 proc = (*plist)[i];
179 break;
180 }
181 }
182 G4bool isCombinedMscTrans = false;
183 G4TransportationWithMsc* trans = nullptr;
184 if(nullptr == proc) {
185 if(processName == "msc") {
186 for(G4int i=0; i<np; ++i) {
187 trans = dynamic_cast<G4TransportationWithMsc*>((*plist)[i]);
188 if(nullptr != trans) {
189 G4cout << "G4TransportationWithMsc is found out!" << G4endl;
190 isCombinedMscTrans = true;
191 proc = trans;
192 break;
193 }
194 }
195 }
196 if(nullptr == proc) {
197 if(0 < verbose) {
198 G4cout << "### G4EmConfigurator WARNING: fails to find a process <"
199 << processName << "> for " << particleName << G4endl;
200 }
201 return;
202 }
203 }
204
205 if(!UpdateModelEnergyRange(mod, emin, emax)) { return; }
206 // classify process
207 G4int ii = proc->GetProcessSubType();
208 auto msc = dynamic_cast<G4VMscModel*>(mod);
209 if(isCombinedMscTrans && nullptr != msc) {
210 trans->AddMscModel(msc, index, reg);
211 if(1 < verbose) {
212 G4cout << "### Added msc model order= " << index << " for "
213 << particleName << " and " << proc->GetProcessName()
214 << G4endl;
215 }
216 } else if(10 == ii && nullptr != msc) {
217 auto p = dynamic_cast<G4VMultipleScattering*>(proc);
218 if(nullptr != p) {
219 p->AddEmModel(index, msc, reg);
220 if(1 < verbose) {
221 G4cout << "### Added msc model order= " << index << " for "
222 << particleName << " and " << processName << G4endl;
223 }
224 }
225 } else if(2 <= ii && 4 >= ii) {
226 auto p = dynamic_cast<G4VEnergyLossProcess*>(proc);
227 if(nullptr != p) {
228 p->AddEmModel(index,mod,fm,reg);
229 if(1 < verbose) {
230 G4cout << "### Added eloss model order= " << index << " for "
231 << particleName << " and " << processName << G4endl;
232 }
233 }
234 } else {
235 auto p = dynamic_cast<G4VEmProcess*>(proc);
236 if(nullptr != p) {
237 p->AddEmModel(index,mod,reg);
238 if(1 < verbose) {
239 G4cout << "### Added em model order= " << index << " for "
240 << particleName << " and " << processName << G4endl;
241 }
242 }
243 }
244 return;
245 }
246 }
247}
248
249//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
250
251void
254{
255 size_t n = particles.size();
256 if(1 < verbose) {
257 G4cout << " G4EmConfigurator::PrepareModels for EnergyLoss n= "
258 << n << G4endl;
259 }
260 if(n > 0) {
261 G4String particleName = aParticle->GetParticleName();
262 G4String processName = p->GetProcessName();
263 //G4cout << particleName << " " << processName << G4endl;
264 for(size_t i=0; i<n; ++i) {
265 //G4cout << particles[i] << " " << processes[i] << G4endl;
266 if(processName == processes[i]) {
267 if((particleName == particles[i]) ||
268 (particles[i] == "all") ||
269 (particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
270 const G4Region* reg = G4EmUtility::FindRegion(regions[i]);
271 //G4cout << "Region " << reg << G4endl;
272 if(nullptr != reg) {
273 --index;
274 G4VEmModel* mod = models[i];
275 G4VEmFluctuationModel* fm = flucModels[i];
276 if(nullptr != mod) {
277 if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
278 p->AddEmModel(index,mod,fm,reg);
279 if(1 < verbose) {
280 G4cout << "### Added eloss model order= " << index << " for "
281 << particleName << " and " << processName
282 << " for " << reg->GetName() << G4endl;
283 }
284 }
285 } else if(nullptr != fm) {
286 p->SetFluctModel(fm);
287 }
288 }
289 }
290 }
291 }
292 }
293}
294
295//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
296
297void
299 G4VEmProcess* p)
300{
301 size_t n = particles.size();
302 if(1 < verbose) {
303 G4cout << " G4EmConfigurator::PrepareModels for EM process n= "
304 << n << G4endl;
305 }
306 if(n > 0) {
307 G4String particleName = aParticle->GetParticleName();
308 G4String processName = p->GetProcessName();
309 //G4cout << particleName << " " << particleName << G4endl;
310 for(size_t i=0; i<n; ++i) {
311 if(processName == processes[i]) {
312 if((particleName == particles[i]) ||
313 (particles[i] == "all") ||
314 (particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
315 const G4Region* reg = G4EmUtility::FindRegion(regions[i]);
316 //G4cout << "Region " << reg << G4endl;
317 if(nullptr != reg) {
318 --index;
319 G4VEmModel* mod = models[i];
320 if(nullptr != mod) {
321 if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
322 p->AddEmModel(index,mod,reg);
323 if(1 < verbose) {
324 G4cout << "### Added em model order= " << index << " for "
325 << particleName << " and " << processName << G4endl;
326 }
327 }
328 }
329 }
330 }
331 }
332 }
333 }
334}
335
336//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
337
338void
342{
343 size_t n = particles.size();
344 if(1 < verbose) {
345 G4cout << " G4EmConfigurator::PrepareModels for MSC process n= "
346 << n << G4endl;
347 }
348
349 if(n > 0) {
350 G4String particleName = aParticle->GetParticleName();
351 G4String processName = (nullptr == p) ? "msc" : p->GetProcessName();
352 for(size_t i=0; i<n; ++i) {
353 if(processName == processes[i]) {
354 if((particleName == particles[i]) ||
355 (particles[i] == "all") ||
356 (particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
357 const G4Region* reg = G4EmUtility::FindRegion(regions[i]);
358 if(nullptr != reg) {
359 --index;
360 auto mod = dynamic_cast<G4VMscModel*>(models[i]);
361 if(nullptr != mod) {
362 if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
363 if(nullptr != p) {
364 p->AddEmModel(index,mod,reg);
365 } else {
366 trans->AddMscModel(mod,index,reg);
367 }
368 //G4cout << "### Added msc model order= " << index << " for "
369 // << particleName << " and " << processName << G4endl;
370 }
371 }
372 }
373 }
374 }
375 }
376 }
377}
378
379//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
380
382{
383 particles.clear();
384 processes.clear();
385 models.clear();
386 flucModels.clear();
387 regions.clear();
388 lowEnergy.clear();
389 highEnergy.clear();
390}
391
392//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
393
394G4bool G4EmConfigurator::UpdateModelEnergyRange(G4VEmModel* mod,
395 G4double emin, G4double emax)
396{
397 // energy limits
398 G4double e1 = std::max(emin,mod->LowEnergyLimit());
399 G4double e2 = std::min(emax,mod->HighEnergyLimit());
400 if(e2 <= e1) {
401 G4cout << "### G4EmConfigurator WARNING: empty energy interval"
402 << " for <" << mod->GetName()
403 << "> Emin(MeV)= " << e1/CLHEP::MeV
404 << "> Emax(MeV)= " << e2/CLHEP::MeV
405 << G4endl;
406 return false;
407 }
408 mod->SetLowEnergyLimit(e1);
409 mod->SetHighEnergyLimit(e2);
410 if(verbose > 1) {
411 G4cout << "### G4EmConfigurator for " << mod->GetName()
412 << " Emin(MeV)= " << e1/MeV << " Emax(MeV)= " << e2/MeV
413 << G4endl;
414 }
415 return true;
416}
417
418//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
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
void SetExtraEmModel(const G4String &particleName, const G4String &processName, G4VEmModel *, const G4String &regionName="", G4double emin=0.0, G4double emax=DBL_MAX, G4VEmFluctuationModel *fm=nullptr)
void PrepareModels(const G4ParticleDefinition *aParticle, G4VEnergyLossProcess *p)
G4EmConfigurator(G4int verboseLevel=1)
static const G4Region * FindRegion(const G4String &regionName, const G4int verbose=0)
Definition: G4EmUtility.cc:47
G4ProcessManager * GetProcessManager() const
G4double GetPDGCharge() const
const G4String & GetParticleName() const
void reset(G4bool ifSkipIon=true)
G4PTblDicIterator * GetIterator() const
static G4ParticleTable * GetParticleTable()
G4int GetProcessListLength() const
G4ProcessVector * GetProcessList() const
const G4String & GetName() const
void AddMscModel(G4VMscModel *mscModel, G4int order=0, const G4Region *region=nullptr)
const G4String & GetName() const
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:746
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:641
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:634
void SetLowEnergyLimit(G4double)
Definition: G4VEmModel.hh:753
void SetActivationHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:760
const G4String & GetName() const
Definition: G4VEmModel.hh:816
void AddEmModel(G4int, G4VEmModel *, const G4Region *region=nullptr)
void AddEmModel(G4int, G4VEmModel *, G4VEmFluctuationModel *fluc=nullptr, const G4Region *region=nullptr)
void SetFluctModel(G4VEmFluctuationModel *)
void AddEmModel(G4int order, G4VMscModel *, const G4Region *region=nullptr)
G4int GetProcessSubType() const
Definition: G4VProcess.hh:404
const G4String & GetProcessName() const
Definition: G4VProcess.hh:386