Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4AtomicDeexcitation.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 ([email protected])
29// Alfonso Mantero ([email protected])
30//
31// History:
32// -----------
33//
34// 16 Sept 2001 First committed to cvs
35// 12 Sep 2003 Bug in auger production fixed
36//
37// -------------------------------------------------------------------
38
40#include "Randomize.hh"
42#include "G4SystemOfUnits.hh"
43#include "G4Gamma.hh"
44#include "G4Electron.hh"
46#include "G4FluoTransition.hh"
47
49 minGammaEnergy(100.*eV),
50 minElectronEnergy(100.*eV),
51 fAuger(false)
52{
53
54 G4cout << " ********************************************************** " << G4endl;
55 G4cout << " * W A R N I N G ! ! ! * " << G4endl;
56 G4cout << " ********************************************************** " << G4endl;
57 G4cout << " * * " << G4endl;
58 G4cout << " * Class G4AtomicDeexcitation is obsolete. It has been * " << G4endl;
59 G4cout << " * discontinued and is going to be removed by next Geant4 * " << G4endl;
60 G4cout << " * release please migrate to G4UAtomDeexcitation. * " << G4endl;
61 G4cout << " * * " << G4endl;
62 G4cout << " ********************************************************** " << G4endl;
63
64 augerVacancyId=0;
65 newShellId=0;
66}
67
69{}
70
71std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z,G4int givenShellId)
72{
73
74 std::vector<G4DynamicParticle*>* vectorOfParticles;
75 vectorOfParticles = new std::vector<G4DynamicParticle*>;
76
77 G4DynamicParticle* aParticle = nullptr;
78 G4int provShellId = 0;
79 G4int counter = 0;
80
81 // The aim of this loop is to generate more than one fluorecence photon
82 // from the same ionizing event
83 do
84 {
85 if (counter == 0)
86 // First call to GenerateParticles(...):
87 // givenShellId is given by the process
88 {
89 provShellId = SelectTypeOfTransition(Z, givenShellId);
90
91 if ( provShellId >0)
92 {
93 aParticle = GenerateFluorescence(Z,givenShellId,provShellId);
94 }
95 else if ( provShellId == -1)
96 {
97 aParticle = GenerateAuger(Z, givenShellId);
98 }
99 else
100 {
101 G4Exception("G4AtomicDeexcitation::Constructor", "de0002", JustWarning, "Transition selection invalid, energy local deposited");
102 }
103 }
104 else
105 // Following calls to GenerateParticles(...):
106 // newShellId is given by GenerateFluorescence(...)
107 {
108 provShellId = SelectTypeOfTransition(Z,newShellId);
109 if (provShellId >0)
110 {
111 aParticle = GenerateFluorescence(Z,newShellId,provShellId);
112 }
113 else if ( provShellId == -1)
114 {
115 aParticle = GenerateAuger(Z, newShellId);
116 }
117 else
118 {
119 G4Exception("G4AtomicDeexcitation::constructor", "de0002", JustWarning, "Transition selection invalid, energy local deposited" );
120 }
121 }
122 counter++;
123 if (aParticle != nullptr) {vectorOfParticles->push_back(aParticle);}
124 else {provShellId = -2;}
125 }
126
127 // Look this in a particular way: only one auger emitted! // ????
128 while (provShellId > -2);
129
130 // debug
131 // if (vectorOfParticles->size() > 0) {
132 // G4cout << " DEEXCITATION!" << G4endl;
133 // }
134
135 return vectorOfParticles;
136}
137
138G4int G4AtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId)
139{
140 if (shellId <=0 )
141 {G4Exception("G4AtomicDeexcitation::SelectTypeOfTransition()","de0002", JustWarning ,"zero or negative shellId");}
142
143 //G4bool fluoTransitionFoundFlag = false;
144
145 const G4AtomicTransitionManager* transitionManager =
147 G4int provShellId = -1;
148 G4int shellNum = 0;
149 G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
150
151 const G4FluoTransition* refShell = transitionManager->ReachableShell(Z,maxNumOfShells-1);
152
153 // This loop gives shellNum the value of the index of shellId
154 // in the vector storing the list of the shells reachable through
155 // a radiative transition
156 if ( shellId <= refShell->FinalShellId())
157 {
158 while (shellId != transitionManager->ReachableShell(Z,shellNum)->FinalShellId())
159 {
160 if(shellNum ==maxNumOfShells-1)
161 {
162 break;
163 }
164 shellNum++;
165 }
166 G4int transProb = 0; //AM change 29/6/07 was 1
167
168 G4double partialProb = G4UniformRand();
169 G4double partSum = 0;
170 const G4FluoTransition* aShell = transitionManager->ReachableShell(Z,shellNum);
171 G4int trSize = (G4int)(aShell->TransitionProbabilities()).size();
172
173 // Loop over the shells wich can provide an electron for a
174 // radiative transition towards shellId:
175 // in every loop the partial sum of the first transProb shells
176 // is calculated and compared with a random number [0,1].
177 // If the partial sum is greater, the shell whose index is transProb
178 // is chosen as the starting shell for a radiative transition
179 // and its identity is returned
180 // Else, terminateded the loop, -1 is returned
181 while(transProb < trSize){
182
183 partSum += aShell->TransitionProbability(transProb);
184
185 if(partialProb <= partSum)
186 {
187 provShellId = aShell->OriginatingShellId(transProb);
188 //fluoTransitionFoundFlag = true;
189
190 break;
191 }
192 transProb++;
193 }
194
195 // here provShellId is the right one or is -1.
196 // if -1, the control is passed to the Auger generation part of the package
197 }
198 else
199 provShellId = -1;
200
201 return provShellId;
202}
203
204G4DynamicParticle* G4AtomicDeexcitation::GenerateFluorescence(G4int Z,
205 G4int shellId,
206 G4int provShellId )
207{
209 // G4int provenienceShell = provShellId;
210
211 //isotropic angular distribution for the outcoming photon
212 G4double newcosTh = 1.-2.*G4UniformRand();
213 G4double newsinTh = std::sqrt(1.-newcosTh*newcosTh);
214 G4double newPhi = twopi*G4UniformRand();
215
216 G4double xDir = newsinTh*std::sin(newPhi);
217 G4double yDir = newsinTh*std::cos(newPhi);
218 G4double zDir = newcosTh;
219
220 G4ThreeVector newGammaDirection(xDir,yDir,zDir);
221
222 G4int shellNum = 0;
223 G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
224
225 // find the index of the shell named shellId
226 while (shellId != transitionManager->
227 ReachableShell(Z,shellNum)->FinalShellId())
228 {
229 if(shellNum == maxNumOfShells-1)
230 {
231 break;
232 }
233 shellNum++;
234 }
235 // number of shell from wich an electron can reach shellId
236 G4int transitionSize = (G4int)transitionManager->
237 ReachableShell(Z,shellNum)->OriginatingShellIds().size();
238
239 G4int index = 0;
240
241 // find the index of the shell named provShellId in the vector
242 // storing the shells from which shellId can be reached
243 while (provShellId != transitionManager->
244 ReachableShell(Z,shellNum)->OriginatingShellId(index))
245 {
246 if(index == transitionSize-1)
247 {
248 break;
249 }
250 index++;
251 }
252 // energy of the gamma leaving provShellId for shellId
253 G4double transitionEnergy = transitionManager->
254 ReachableShell(Z,shellNum)->TransitionEnergy(index);
255
256 // This is the shell where the new vacancy is: it is the same
257 // shell where the electron came from
258 newShellId = transitionManager->
259 ReachableShell(Z,shellNum)->OriginatingShellId(index);
260
262 newGammaDirection,
263 transitionEnergy);
264 return newPart;
265}
266
267G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
268{
269 if(!fAuger) return 0;
270
271 const G4AtomicTransitionManager* transitionManager =
273
274 if (shellId <=0 )
275 {G4Exception("G4AtomicDeexcitation::GenerateAuger()","de0002", JustWarning ,"zero or negative shellId");}
276
277 // G4int provShellId = -1;
278 G4int maxNumOfShells = transitionManager->NumberOfReachableAugerShells(Z);
279
280 const G4AugerTransition* refAugerTransition =
281 transitionManager->ReachableAugerShell(Z,maxNumOfShells-1);
282
283
284 // This loop gives to shellNum the value of the index of shellId
285 // in the vector storing the list of the vacancies in the variuos shells
286 // that can originate a NON-radiative transition
287 G4int shellNum = 0;
288
289 if ( shellId <= refAugerTransition->FinalShellId() )
290 //"FinalShellId" is final from the point of view of the elctron who makes the transition,
291 // being the Id of the shell in which there is a vacancy
292 {
293 G4int pippo = transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId();
294 if (shellId != pippo ) {
295 do {
296 shellNum++;
297 if(shellNum == maxNumOfShells)
298 {
299
300 //G4Exception("G4AtomicDeexcitation: No Auger transition found");
301 return 0;
302 }
303 }
304 while (shellId != (transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId()) ) ;
305 }
306
307 G4int transitionLoopShellIndex = 0;
308 G4double partSum = 0;
309 const G4AugerTransition* anAugerTransition =
310 transitionManager->ReachableAugerShell(Z,shellNum);
311
312 G4int transitionSize = (G4int)
313 (anAugerTransition->TransitionOriginatingShellIds())->size();
314 while (transitionLoopShellIndex < transitionSize) {
315
316 std::vector<G4int>::const_iterator pos =
317 anAugerTransition->TransitionOriginatingShellIds()->begin();
318
319 G4int transitionLoopShellId = *(pos+transitionLoopShellIndex);
320 G4int numberOfPossibleAuger = (G4int)
321 (anAugerTransition->AugerTransitionProbabilities(transitionLoopShellId))->size();
322 G4int augerIndex = 0;
323
324 if (augerIndex < numberOfPossibleAuger) {
325 do
326 {
327 G4double thisProb = anAugerTransition->AugerTransitionProbability(augerIndex,
328 transitionLoopShellId);
329 partSum += thisProb;
330 augerIndex++;
331
332 } while (augerIndex < numberOfPossibleAuger);
333 }
334 transitionLoopShellIndex++;
335 }
336
337
338 // Now we have the entire probability of an auger transition for the vacancy
339 // located in shellNum (index of shellId)
340 G4double totalVacancyAugerProbability = partSum;
341
342 //And now we start to select the right auger transition and emission
343 G4int transitionRandomShellIndex = 0;
344 G4int transitionRandomShellId = 1;
345 G4int augerIndex = 0;
346 partSum = 0;
347 G4double partialProb = G4UniformRand();
348 // G4int augerOriginatingShellId = 0;
349
350 G4int numberOfPossibleAuger = 0;
351
352 G4bool foundFlag = false;
353
354 while (transitionRandomShellIndex < transitionSize) {
355 std::vector<G4int>::const_iterator pos =
356 anAugerTransition->TransitionOriginatingShellIds()->begin();
357
358 transitionRandomShellId = *(pos+transitionRandomShellIndex);
359
360 augerIndex = 0;
361 numberOfPossibleAuger = (G4int)(anAugerTransition->
362 AugerTransitionProbabilities(transitionRandomShellId))->size();
363
364 while (augerIndex < numberOfPossibleAuger) {
365 G4double thisProb =anAugerTransition->AugerTransitionProbability(augerIndex,
366 transitionRandomShellId);
367
368 partSum += thisProb;
369
370 if (partSum >= (partialProb*totalVacancyAugerProbability) ) { // was /
371 foundFlag = true;
372 break;
373 }
374 augerIndex++;
375 }
376 if (partSum >= (partialProb*totalVacancyAugerProbability) ) {break;} // was /
377 transitionRandomShellIndex++;
378 }
379
380 // Now we have the index of the shell from wich comes the auger electron (augerIndex),
381 // and the id of the shell, from which the transition e- come (transitionRandomShellid)
382 // If no Transition has been found, 0 is returned.
383
384 if (!foundFlag) {return 0;}
385
386 // Isotropic angular distribution for the outcoming e-
387 G4double newcosTh = 1.-2.*G4UniformRand();
388 G4double newsinTh = std::sqrt(1.-newcosTh*newcosTh);
389 G4double newPhi = twopi*G4UniformRand();
390
391 G4double xDir = newsinTh*std::sin(newPhi);
392 G4double yDir = newsinTh*std::cos(newPhi);
393 G4double zDir = newcosTh;
394
395 G4ThreeVector newElectronDirection(xDir,yDir,zDir);
396
397 // energy of the auger electron emitted
398
399 G4double transitionEnergy = anAugerTransition->AugerTransitionEnergy(augerIndex, transitionRandomShellId);
400 /*
401 G4cout << "AUger TransitionId " << anAugerTransition->FinalShellId() << G4endl;
402 G4cout << "augerIndex: " << augerIndex << G4endl;
403 G4cout << "transitionShellId: " << transitionRandomShellId << G4endl;
404 */
405
406 // This is the shell where the new vacancy is: it is the same
407 // shell where the electron came from
408 newShellId = transitionRandomShellId;
409
411 newElectronDirection,
412 transitionEnergy);
413 return newPart;
414 }
415 else
416 {
417 //G4Exception("G4AtomicDeexcitation: no auger transition found");
418 return 0;
419 }
420}
421
423{
424 minGammaEnergy = cut;
425}
426
428{
429 minElectronEnergy = cut;
430}
431
433{
434 fAuger = val;
435}
436
437
438
439
440
441
442
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
void ActivateAugerElectronProduction(G4bool val)
Set threshold energy for Auger electron production.
void SetCutForSecondaryPhotons(G4double cut)
std::vector< G4DynamicParticle * > * GenerateParticles(G4int Z, G4int shellId)
void SetCutForAugerElectrons(G4double cut)
Set threshold energy for fluorescence.
G4int NumberOfReachableShells(G4int Z) const
const G4AugerTransition * ReachableAugerShell(G4int Z, G4int shellIndex) const
const G4FluoTransition * ReachableShell(G4int Z, size_t shellIndex) const
static G4AtomicTransitionManager * Instance()
G4int NumberOfReachableAugerShells(G4int Z) const
G4int FinalShellId() const
returns the id of the shell in wich the transition electron arrives
const G4DataVector * AugerTransitionProbabilities(G4int startShellId) const
G4double AugerTransitionEnergy(G4int index, G4int startShellId) const
const std::vector< G4int > * TransitionOriginatingShellIds() const
Returns the ids of the shells from wich an electron cuuld fill the vacancy in finalShellId.
G4double AugerTransitionProbability(G4int index, G4int startShellId) const
static G4Electron * Electron()
Definition: G4Electron.cc:93
const G4DataVector & TransitionProbabilities() const
Return the probabilities of the transitions.
G4int OriginatingShellId(G4int index) const
Given the index of the originating shells returns its identity.
G4double TransitionProbability(G4int index) const
G4int FinalShellId() const
Return the identity if the vacancy.
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85