Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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) ? G4String("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:67
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)
G4ProcessManager * GetProcessManager() 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)
G4double LowEnergyLimit() const
G4double HighEnergyLimit() const
void SetLowEnergyLimit(G4double)
void SetActivationHighEnergyLimit(G4double)
const G4String & GetName() const
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
const G4String & GetProcessName() const