00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "G4AtomicDeexcitation.hh"
00040 #include "Randomize.hh"
00041 #include "G4PhysicalConstants.hh"
00042 #include "G4SystemOfUnits.hh"
00043 #include "G4Gamma.hh"
00044 #include "G4Electron.hh"
00045 #include "G4AtomicTransitionManager.hh"
00046 #include "G4FluoTransition.hh"
00047
00048 G4AtomicDeexcitation::G4AtomicDeexcitation():
00049 minGammaEnergy(100.*eV),
00050 minElectronEnergy(100.*eV),
00051 fAuger(false)
00052 {
00053
00054 G4cout << " ********************************************************** " << G4endl;
00055 G4cout << " * W A R N I N G ! ! ! * " << G4endl;
00056 G4cout << " ********************************************************** " << G4endl;
00057 G4cout << " * * " << G4endl;
00058 G4cout << " * Class G4AtomicDeexcitation is obsolete. It has been * " << G4endl;
00059 G4cout << " * discontinued and is going to be removed by next Geant4 * " << G4endl;
00060 G4cout << " * release please migrate to G4UAtomDeexcitation. * " << G4endl;
00061 G4cout << " * * " << G4endl;
00062 G4cout << " ********************************************************** " << G4endl;
00063
00064 augerVacancyId=0;
00065 newShellId=0;
00066 }
00067
00068 G4AtomicDeexcitation::~G4AtomicDeexcitation()
00069 {}
00070
00071 std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z,G4int givenShellId)
00072 {
00073
00074 std::vector<G4DynamicParticle*>* vectorOfParticles;
00075 vectorOfParticles = new std::vector<G4DynamicParticle*>;
00076
00077 G4DynamicParticle* aParticle;
00078 G4int provShellId = 0;
00079 G4int counter = 0;
00080
00081
00082
00083 do
00084 {
00085 if (counter == 0)
00086
00087
00088 {
00089 provShellId = SelectTypeOfTransition(Z, givenShellId);
00090
00091 if ( provShellId >0)
00092 {
00093 aParticle = GenerateFluorescence(Z,givenShellId,provShellId);
00094 }
00095 else if ( provShellId == -1)
00096 {
00097 aParticle = GenerateAuger(Z, givenShellId);
00098 }
00099 else
00100 {
00101 G4Exception("G4AtomicDeexcitation::Constructor", "de0002", JustWarning, "Transition selection invalid, energy local deposited");
00102 }
00103 }
00104 else
00105
00106
00107 {
00108 provShellId = SelectTypeOfTransition(Z,newShellId);
00109 if (provShellId >0)
00110 {
00111 aParticle = GenerateFluorescence(Z,newShellId,provShellId);
00112 }
00113 else if ( provShellId == -1)
00114 {
00115 aParticle = GenerateAuger(Z, newShellId);
00116 }
00117 else
00118 {
00119 G4Exception("G4AtomicDeexcitation::constructor", "de0002", JustWarning, "Transition selection invalid, energy local deposited" );
00120 }
00121 }
00122 counter++;
00123 if (aParticle != 0) {vectorOfParticles->push_back(aParticle);}
00124 else {provShellId = -2;}
00125 }
00126
00127
00128 while (provShellId > -2);
00129
00130
00131
00132
00133
00134
00135 return vectorOfParticles;
00136 }
00137
00138 G4int G4AtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId)
00139 {
00140 if (shellId <=0 )
00141 {G4Exception("G4AtomicDeexcitation::SelectTypeOfTransition()","de0002", JustWarning ,"zero or negative shellId");}
00142
00143
00144
00145 const G4AtomicTransitionManager* transitionManager =
00146 G4AtomicTransitionManager::Instance();
00147 G4int provShellId = -1;
00148 G4int shellNum = 0;
00149 G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
00150
00151 const G4FluoTransition* refShell = transitionManager->ReachableShell(Z,maxNumOfShells-1);
00152
00153
00154
00155
00156 if ( shellId <= refShell->FinalShellId())
00157 {
00158 while (shellId != transitionManager->ReachableShell(Z,shellNum)->FinalShellId())
00159 {
00160 if(shellNum ==maxNumOfShells-1)
00161 {
00162 break;
00163 }
00164 shellNum++;
00165 }
00166 G4int transProb = 0;
00167
00168 G4double partialProb = G4UniformRand();
00169 G4double partSum = 0;
00170 const G4FluoTransition* aShell = transitionManager->ReachableShell(Z,shellNum);
00171 G4int trSize = (aShell->TransitionProbabilities()).size();
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 while(transProb < trSize){
00182
00183 partSum += aShell->TransitionProbability(transProb);
00184
00185 if(partialProb <= partSum)
00186 {
00187 provShellId = aShell->OriginatingShellId(transProb);
00188
00189
00190 break;
00191 }
00192 transProb++;
00193 }
00194
00195
00196
00197 }
00198
00199
00200
00201 else
00202 {
00203
00204 provShellId = -1;
00205
00206 }
00207 return provShellId;
00208 }
00209
00210 G4DynamicParticle* G4AtomicDeexcitation::GenerateFluorescence(G4int Z,
00211 G4int shellId,
00212 G4int provShellId )
00213 {
00214
00215
00216 const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
00217
00218
00219
00220 G4double newcosTh = 1.-2.*G4UniformRand();
00221 G4double newsinTh = std::sqrt(1.-newcosTh*newcosTh);
00222 G4double newPhi = twopi*G4UniformRand();
00223
00224 G4double xDir = newsinTh*std::sin(newPhi);
00225 G4double yDir = newsinTh*std::cos(newPhi);
00226 G4double zDir = newcosTh;
00227
00228 G4ThreeVector newGammaDirection(xDir,yDir,zDir);
00229
00230 G4int shellNum = 0;
00231 G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
00232
00233
00234 while (shellId != transitionManager->
00235 ReachableShell(Z,shellNum)->FinalShellId())
00236 {
00237 if(shellNum == maxNumOfShells-1)
00238 {
00239 break;
00240 }
00241 shellNum++;
00242 }
00243
00244 size_t transitionSize = transitionManager->
00245 ReachableShell(Z,shellNum)->OriginatingShellIds().size();
00246
00247 size_t index = 0;
00248
00249
00250
00251 while (provShellId != transitionManager->
00252 ReachableShell(Z,shellNum)->OriginatingShellId(index))
00253 {
00254 if(index == transitionSize-1)
00255 {
00256 break;
00257 }
00258 index++;
00259 }
00260
00261 G4double transitionEnergy = transitionManager->
00262 ReachableShell(Z,shellNum)->TransitionEnergy(index);
00263
00264
00265
00266 newShellId = transitionManager->
00267 ReachableShell(Z,shellNum)->OriginatingShellId(index);
00268
00269
00270 G4DynamicParticle* newPart = new G4DynamicParticle(G4Gamma::Gamma(),
00271 newGammaDirection,
00272 transitionEnergy);
00273 return newPart;
00274 }
00275
00276 G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
00277 {
00278 if(!fAuger) return 0;
00279
00280
00281 const G4AtomicTransitionManager* transitionManager =
00282 G4AtomicTransitionManager::Instance();
00283
00284
00285
00286 if (shellId <=0 )
00287 {G4Exception("G4AtomicDeexcitation::GenerateAuger()","de0002", JustWarning ,"zero or negative shellId");}
00288
00289
00290 G4int maxNumOfShells = transitionManager->NumberOfReachableAugerShells(Z);
00291
00292 const G4AugerTransition* refAugerTransition =
00293 transitionManager->ReachableAugerShell(Z,maxNumOfShells-1);
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 G4int shellNum = 0;
00304
00305
00306 if ( shellId <= refAugerTransition->FinalShellId() )
00307
00308
00309 {
00310 G4int pippo = transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId();
00311 if (shellId != pippo ) {
00312 do {
00313 shellNum++;
00314 if(shellNum == maxNumOfShells)
00315 {
00316
00317
00318 return 0;
00319 }
00320 }
00321 while (shellId != (transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId()) ) ;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 G4int transitionLoopShellIndex = 0;
00333 G4double partSum = 0;
00334 const G4AugerTransition* anAugerTransition =
00335 transitionManager->ReachableAugerShell(Z,shellNum);
00336
00337
00338
00339
00340 G4int transitionSize =
00341 (anAugerTransition->TransitionOriginatingShellIds())->size();
00342 while (transitionLoopShellIndex < transitionSize) {
00343
00344 std::vector<G4int>::const_iterator pos =
00345 anAugerTransition->TransitionOriginatingShellIds()->begin();
00346
00347 G4int transitionLoopShellId = *(pos+transitionLoopShellIndex);
00348 G4int numberOfPossibleAuger =
00349 (anAugerTransition->AugerTransitionProbabilities(transitionLoopShellId))->size();
00350 G4int augerIndex = 0;
00351
00352
00353
00354 if (augerIndex < numberOfPossibleAuger) {
00355
00356 do
00357 {
00358 G4double thisProb = anAugerTransition->AugerTransitionProbability(augerIndex,
00359 transitionLoopShellId);
00360 partSum += thisProb;
00361 augerIndex++;
00362
00363 } while (augerIndex < numberOfPossibleAuger);
00364 }
00365 transitionLoopShellIndex++;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 G4double totalVacancyAugerProbability = partSum;
00394
00395
00396
00397 G4int transitionRandomShellIndex = 0;
00398 G4int transitionRandomShellId = 1;
00399 G4int augerIndex = 0;
00400 partSum = 0;
00401 G4double partialProb = G4UniformRand();
00402
00403
00404 G4int numberOfPossibleAuger = 0;
00405
00406 G4bool foundFlag = false;
00407
00408 while (transitionRandomShellIndex < transitionSize) {
00409
00410 std::vector<G4int>::const_iterator pos =
00411 anAugerTransition->TransitionOriginatingShellIds()->begin();
00412
00413 transitionRandomShellId = *(pos+transitionRandomShellIndex);
00414
00415 augerIndex = 0;
00416 numberOfPossibleAuger = (anAugerTransition->
00417 AugerTransitionProbabilities(transitionRandomShellId))->size();
00418
00419 while (augerIndex < numberOfPossibleAuger) {
00420 G4double thisProb =anAugerTransition->AugerTransitionProbability(augerIndex,
00421 transitionRandomShellId);
00422
00423 partSum += thisProb;
00424
00425 if (partSum >= (partialProb*totalVacancyAugerProbability) ) {
00426 foundFlag = true;
00427 break;
00428 }
00429 augerIndex++;
00430 }
00431 if (partSum >= (partialProb*totalVacancyAugerProbability) ) {break;}
00432 transitionRandomShellIndex++;
00433 }
00434
00435
00436
00437
00438
00439 if (!foundFlag) {return 0;}
00440
00441
00442 G4double newcosTh = 1.-2.*G4UniformRand();
00443 G4double newsinTh = std::sqrt(1.-newcosTh*newcosTh);
00444 G4double newPhi = twopi*G4UniformRand();
00445
00446 G4double xDir = newsinTh*std::sin(newPhi);
00447 G4double yDir = newsinTh*std::cos(newPhi);
00448 G4double zDir = newcosTh;
00449
00450 G4ThreeVector newElectronDirection(xDir,yDir,zDir);
00451
00452
00453
00454
00455 G4double transitionEnergy = anAugerTransition->AugerTransitionEnergy(augerIndex, transitionRandomShellId);
00456
00457
00458
00459
00460
00461
00462
00463
00464 newShellId = transitionRandomShellId;
00465
00466
00467 G4DynamicParticle* newPart = new G4DynamicParticle(G4Electron::Electron(),
00468 newElectronDirection,
00469 transitionEnergy);
00470 return newPart;
00471
00472 }
00473 else
00474 {
00475
00476 return 0;
00477 }
00478
00479 }
00480
00481 void G4AtomicDeexcitation::SetCutForSecondaryPhotons(G4double cut)
00482 {
00483 minGammaEnergy = cut;
00484 }
00485
00486 void G4AtomicDeexcitation::SetCutForAugerElectrons(G4double cut)
00487 {
00488 minElectronEnergy = cut;
00489 }
00490
00491 void G4AtomicDeexcitation::ActivateAugerElectronProduction(G4bool val)
00492 {
00493 fAuger = val;
00494 }
00495
00496
00497
00498
00499
00500
00501