Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4AtomicTransitionManager.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// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
29// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
30//
31// History:
32// -----------
33// 16 Sep 2001 E. Guardincerri First Committed to cvs
34//
35// -------------------------------------------------------------------
36
38#include "G4EmParameters.hh"
39#include "G4FluoData.hh"
40#include "G4AugerData.hh"
41#include "G4AutoLock.hh"
42
43namespace { G4Mutex AtomicTransitionManagerMutex = G4MUTEX_INITIALIZER; }
44
45//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
46G4AtomicTransitionManager* G4AtomicTransitionManager::instance = nullptr;
47
48//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
50{
51 if (instance == nullptr) {
53 instance = &man;
54 }
55 return instance;
56}
57
58//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
60 : augerData(nullptr),
61 verboseLevel(0),
62 isInitialized(false)
63{}
64
65//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
67{
68 delete augerData;
69
70 for (auto const & pos : shellTable) {
71 std::vector<G4AtomicShell*> vec = pos.second;
72 for (auto const & p : vec) { delete p; }
73 }
74
75 for (auto const & ppos : transitionTable) {
76 std::vector<G4FluoTransition*> vec = ppos.second;
77 for (auto const & p : vec) { delete p; }
78 }
79}
80
81//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
83G4AtomicTransitionManager::Shell(G4int Z, std::size_t shellIndex) const
84{
85 auto pos = shellTable.find(Z);
86
87 if (pos!= shellTable.end())
88 {
89 std::vector<G4AtomicShell*> v = (*pos).second;
90 if (shellIndex < v.size()) { return v[shellIndex]; }
91
92 else
93 {
94 std::size_t lastShell = v.size();
96 ed << "No de-excitation for Z= " << Z
97 << " shellIndex= " << shellIndex
98 << ">= numberOfShells= " << lastShell;
99 if (verboseLevel > 0)
100 G4Exception("G4AtomicTransitionManager::Shell()","de0001",
101 JustWarning,ed," AtomicShell not found");
102 if (lastShell > 0) { return v[lastShell - 1]; }
103 }
104 }
105 else
106 {
108 ed << "No de-excitation for Z= " << Z
109 << " shellIndex= " << shellIndex
110 << ". AtomicShell not found - check if data are uploaded";
111 G4Exception("G4AtomicTransitionManager::Shell()","de0001",
112 FatalException,ed,"");
113 }
114 return nullptr;
115}
116
117//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
118
119// This function gives, upon Z and the Index of the initial shell where
120// the vacancy is, the radiative transition that can happen (originating
121// shell, energy, probability)
122const G4FluoTransition*
123G4AtomicTransitionManager::ReachableShell(G4int Z, std::size_t shellIndex) const
124{
125 auto pos = transitionTable.find(Z);
126 if (pos!= transitionTable.end())
127 {
128 std::vector<G4FluoTransition*> v = (*pos).second;
129 if (shellIndex < v.size()) { return(v[shellIndex]); }
130
131 else {
133 ed << "No fluo transition for Z= " << Z
134 << " shellIndex= " << shellIndex;
135 G4Exception("G4AtomicTransitionManager::ReachebleShell()","de0002",
136 FatalException,ed,"");
137 }
138 }
139 else
140 {
142 ed << "No transition table for Z= " << Z
143 << " shellIndex= " << shellIndex;
144 G4Exception("G4AtomicTransitionManager::ReachableShell()","de0001",
145 FatalException,ed,"");
146 }
147 return 0;
148}
149
150//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
151const G4AugerTransition*
153 G4int vacancyShellIndex) const
154{
155 return augerData->GetAugerTransition(Z,vacancyShellIndex);
156}
157
158//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
160{
161 auto pos = shellTable.find(Z);
162
163 std::size_t res = 0;
164 if (pos != shellTable.cend()){
165
166 res = ((*pos).second).size();
167
168 } else {
170 ed << "No deexcitation for Z= " << Z;
171 G4Exception("G4AtomicTransitionManager::NumberOfShells()","de0001",
172 FatalException, ed, "");
173 }
174 return (G4int)res;
175}
176
177//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
178// This function returns the number of possible radiative transitions for
179// the atom with atomic number Z i.e. the number of shell in wich a vacancy
180// can be filled with a radiative transition
182{
183 auto pos = transitionTable.find(Z);
184 std::size_t res = 0;
185 if (pos!= transitionTable.cend())
186 {
187 res = ((*pos).second).size();
188 }
189 else
190 {
192 ed << "No deexcitation for Z= " << Z
193 << ", so energy deposited locally";
194 G4Exception("G4AtomicTransitionManager::NumberOfReachebleShells()",
195 "de0001",FatalException,ed,"");
196 }
197 return (G4int)res;
198}
199
200//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
201// This function returns the number of possible NON-radiative transitions
202// for the atom with atomic number Z i.e. the number of shell in wich a
203// vacancy can be filled with a NON-radiative transition
205{
206 return (G4int)augerData->NumberOfVacancies(Z);
207}
208
209//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
211 G4int Z, std::size_t shellIndex) const
212{
213 auto pos = transitionTable.find(Z);
214 G4double totalRadTransProb = 0.0;
215
216 if (pos!= transitionTable.end())
217 {
218 std::vector<G4FluoTransition*> v = (*pos).second;
219
220 if (shellIndex < v.size())
221 {
222 G4FluoTransition* transition = v[shellIndex];
223 G4DataVector transProb = transition->TransitionProbabilities();
224
225 for (std::size_t j=0; j<transProb.size(); ++j)
226 {
227 totalRadTransProb += transProb[j];
228 }
229 }
230 else
231 {
233 ed << "Zero transition probability for Z=" << Z
234 << " shellIndex= " << shellIndex;
236 "G4AtomicTransitionManager::TotalRadiativeTransitionProbability()",
237 "de0002",FatalException,"Incorrect de-excitation");
238 }
239 }
240 else
241 {
243 ed << "No deexcitation for Z=" << Z
244 << " shellIndex= " << shellIndex;
246 "G4AtomicTransitionManager::TotalRadiativeTransitionProbability()",
247 "de0001",FatalException,ed,"Cannot compute transition probability");
248 }
249 return totalRadTransProb;
250}
251
252//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
254 G4int Z, std::size_t shellIndex) const
255{
256 G4double prob = 1.0 - TotalRadiativeTransitionProbability(Z, shellIndex);
257 if(prob > 1.0 || prob < 0.0) {
259 ed << "Total probability mismatch Z= " << Z
260 << " shellIndex= " << shellIndex
261 << " prob= " << prob;
263 "G4AtomicTransitionManager::TotalNonRadiativeTransitionProbability()",
264 "de0003",FatalException,ed,"Cannot compute non-radiative probability");
265 return 0.0;
266 }
267 return prob;
268}
269
270//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
272{
273 if(isInitialized) { return; }
274 G4AutoLock l(&AtomicTransitionManagerMutex);
275
276 if(isInitialized) { return; }
277 isInitialized = true;
278
279 // Selection of fluorescence files
280
281 const G4String& defaultDirectory = "/fluor";
282 G4String fluoDirectory = defaultDirectory;
283 G4String bindingDirectory = defaultDirectory;
285 G4int zLim = zMax + 1;
286 if(fdir == fluoBearden) {
287 zMax = 100;
288 supTableLimit = 100;
289 bindingDirectory = fluoDirectory = "/fluor_Bearden";
290 } else if(fdir == fluoANSTO) {
291 zLim = 93;
292 fluoDirectory = "/fluor_ANSTO";
293 } else if(fdir == fluoXDB_EADL) {
294 zMax = 100;
295 supTableLimit = 100;
296 bindingDirectory = fluoDirectory = "/fluor_XDB_EADL";
297 }
298
299 // infTableLimit is initialized to 6 because EADL lacks data for Z<=5
300 G4ShellData* shellManager = new G4ShellData(1, zMax, false);
301 shellManager->LoadData(bindingDirectory + "/binding");
302
303 // initialization of the data for auger effect
304 augerData = new G4AugerData;
305
306 // Fills shellTable with the data from EADL, identities and binding
307 // energies of shells
308 for (G4int Z = zMin; Z <= zMax; ++Z)
309 {
310 std::vector<G4AtomicShell*> vectorOfShells;
311 G4int shellIndex = 0;
312
313 G4int numberOfShells = (G4int)shellManager->NumberOfShells(Z);
314 for (shellIndex = 0; shellIndex<numberOfShells; ++shellIndex)
315 {
316 G4int shellId = shellManager->ShellId(Z,shellIndex);
317 G4double bindingEnergy = shellManager->BindingEnergy(Z,shellIndex);
318 G4AtomicShell * shell = new G4AtomicShell(shellId,bindingEnergy);
319 vectorOfShells.push_back(shell);
320 }
321 shellTable[Z] = std::move(vectorOfShells);
322 }
323
324 // Fills transitionTable with the data on identities, transition
325 // energies and transition probabilities
326 G4String dir = std::move(fluoDirectory);
327 for (G4int Znum= infTableLimit; Znum<=supTableLimit; ++Znum)
328 {
329 if (Znum == zLim) { dir = defaultDirectory; }
330 G4FluoData* fluoManager = new G4FluoData(dir);
331 std::vector<G4FluoTransition*> vectorOfTransitions;
332 fluoManager->LoadData(Znum);
333
334 G4int numberOfVacancies = (G4int)fluoManager->NumberOfVacancies();
335 for(G4int vacancyIndex = 0; vacancyIndex<numberOfVacancies;
336 ++vacancyIndex)
337 {
338 std::vector<G4int> vectorOfIds;
339 G4DataVector vectorOfEnergies;
340 G4DataVector vectorOfProbabilities;
341
342 G4int finalShell = fluoManager->VacancyId(vacancyIndex);
343 G4int numberOfTransitions = (G4int)
344 fluoManager->NumberOfTransitions(vacancyIndex);
345 for (G4int origShellIndex = 0; origShellIndex < numberOfTransitions;
346 ++origShellIndex)
347 {
348 G4int originatingShellId =
349 fluoManager->StartShellId(origShellIndex,vacancyIndex);
350 vectorOfIds.push_back(originatingShellId);
351
352 G4double transitionEnergy =
353 fluoManager->StartShellEnergy(origShellIndex,vacancyIndex);
354 vectorOfEnergies.push_back(transitionEnergy);
355 G4double transitionProbability =
356 fluoManager->StartShellProb(origShellIndex,vacancyIndex);
357 vectorOfProbabilities.push_back(transitionProbability);
358 }
359 G4FluoTransition* transition =
360 new G4FluoTransition (finalShell,vectorOfIds,
361 vectorOfEnergies,vectorOfProbabilities);
362 vectorOfTransitions.push_back(transition);
363 }
364 transitionTable[Znum] = std::move(vectorOfTransitions);
365 delete fluoManager;
366 }
367 delete shellManager;
368 l.unlock();
369}
G4TemplateAutoLock< G4Mutex > G4AutoLock
G4EmFluoDirectory
@ fluoBearden
@ fluoXDB_EADL
@ fluoANSTO
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
G4int NumberOfReachableShells(G4int Z) const
G4AtomicShell * Shell(G4int Z, std::size_t shellIndex) const
const G4AugerTransition * ReachableAugerShell(G4int Z, G4int shellIndex) const
G4double TotalRadiativeTransitionProbability(G4int Z, std::size_t shellIndex) const
const G4FluoTransition * ReachableShell(G4int Z, std::size_t shellIndex) const
G4double TotalNonRadiativeTransitionProbability(G4int Z, std::size_t shellIndex) const
G4AtomicTransitionManager(const G4AtomicTransitionManager &)=delete
void Initialise()
needs to be called once from other code before start of run
static G4AtomicTransitionManager * Instance()
G4int NumberOfReachableAugerShells(G4int Z) const
static G4EmParameters * Instance()
G4EmFluoDirectory FluoDirectory() const
std::size_t NumberOfTransitions(G4int vacancyIndex) const
G4double StartShellEnergy(G4int initIndex, G4int vacancyIndex) const
G4int VacancyId(G4int vacancyIndex) const
Given the index of the vacancy returns its identity.
Definition G4FluoData.cc:81
std::size_t NumberOfVacancies() const
Definition G4FluoData.cc:74
void LoadData(G4int Z)
G4int StartShellId(G4int initIndex, G4int vacancyIndex) const
G4double StartShellProb(G4int initIndex, G4int vacancyIndex) const
const G4DataVector & TransitionProbabilities() const
Return the probabilities of the transitions.
G4int ShellId(G4int Z, G4int shellIndex) const
G4double BindingEnergy(G4int Z, G4int shellIndex) const
void LoadData(const G4String &fileName)
std::size_t NumberOfShells(G4int Z) const