Warning, file /geant4/examples/advanced/eRosita/physics/src/G4RDAtomicDeexcitation.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include "G4RDAtomicDeexcitation.hh"
0040 #include "Randomize.hh"
0041 #include "G4PhysicalConstants.hh"
0042 #include "G4SystemOfUnits.hh"
0043 #include "G4Gamma.hh"
0044 #include "G4Electron.hh"
0045 #include "G4RDAtomicTransitionManager.hh"
0046 #include "G4RDFluoTransition.hh"
0047
0048 G4RDAtomicDeexcitation::G4RDAtomicDeexcitation():
0049 minGammaEnergy(100.*eV),
0050 minElectronEnergy(100.*eV),
0051 fAuger(false)
0052 {}
0053
0054 G4RDAtomicDeexcitation::~G4RDAtomicDeexcitation()
0055 {}
0056
0057 std::vector<G4DynamicParticle*>* G4RDAtomicDeexcitation::GenerateParticles(G4int Z,G4int givenShellId)
0058 {
0059
0060 std::vector<G4DynamicParticle*>* vectorOfParticles;
0061
0062 vectorOfParticles = new std::vector<G4DynamicParticle*>;
0063 G4DynamicParticle* aParticle;
0064 G4int provShellId = 0;
0065 G4int counter = 0;
0066
0067
0068
0069 do
0070 {
0071 if (counter == 0)
0072
0073
0074 {
0075 provShellId = SelectTypeOfTransition(Z, givenShellId);
0076
0077
0078
0079 if ( provShellId >0)
0080 {
0081 aParticle = GenerateFluorescence(Z,givenShellId,provShellId);
0082
0083 }
0084 else if ( provShellId == -1)
0085 {
0086 aParticle = GenerateAuger(Z, givenShellId);
0087
0088 }
0089 else
0090 {
0091 G4Exception("G4RDAtomicDeexcitation::GenerateParticles()",
0092 "InvalidSetup", FatalException,
0093 "Starting shell uncorrect: check it!");
0094 }
0095 }
0096 else
0097
0098
0099 {
0100 provShellId = SelectTypeOfTransition(Z,newShellId);
0101
0102
0103
0104
0105
0106 if (provShellId >0)
0107 {
0108 aParticle = GenerateFluorescence(Z,newShellId,provShellId);
0109
0110 }
0111 else if ( provShellId == -1)
0112 {
0113 aParticle = GenerateAuger(Z, newShellId);
0114
0115 }
0116 else
0117 {
0118 G4Exception("G4RDAtomicDeexcitation::GenerateParticles()",
0119 "InvalidSetup", FatalException,
0120 "Starting shell uncorrect: check it!");
0121 }
0122 }
0123 counter++;
0124 if (aParticle != 0) {vectorOfParticles->push_back(aParticle);}
0125 else {provShellId = -2;}
0126 }
0127
0128
0129 while (provShellId > -2);
0130
0131 return vectorOfParticles;
0132 }
0133
0134 G4int G4RDAtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId)
0135 {
0136 if (shellId <=0 )
0137 {
0138 G4Exception("G4RDAtomicDeexcitation::SelectTypeOfTransition()",
0139 "InvalidCondition", FatalException,
0140 "Zero or negative shellId!");
0141 }
0142
0143 const G4RDAtomicTransitionManager* transitionManager =
0144 G4RDAtomicTransitionManager::Instance();
0145 G4int provShellId = -1;
0146 G4int shellNum = 0;
0147 G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
0148
0149
0150
0151
0152 const G4RDFluoTransition* refShell = transitionManager->ReachableShell(Z,maxNumOfShells-1);
0153
0154
0155
0156
0157 if ( shellId <= refShell->FinalShellId())
0158 {
0159 while (shellId != transitionManager->ReachableShell(Z,shellNum)->FinalShellId())
0160 {
0161 if(shellNum ==maxNumOfShells-1)
0162 {
0163 break;
0164 }
0165 shellNum++;
0166 }
0167 G4int transProb = 0;
0168
0169 G4double partialProb = G4UniformRand();
0170 G4double partSum = 0;
0171 const G4RDFluoTransition* aShell = transitionManager->ReachableShell(Z,shellNum);
0172 G4int trSize = (aShell->TransitionProbabilities()).size();
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 while(transProb < trSize){
0183
0184 partSum += aShell->TransitionProbability(transProb);
0185
0186 if(partialProb <= partSum)
0187 {
0188 provShellId = aShell->OriginatingShellId(transProb);
0189 break;
0190 }
0191 transProb++;
0192 }
0193
0194
0195
0196 }
0197
0198
0199
0200 else
0201 {
0202
0203 provShellId = -1;
0204
0205 }
0206 return provShellId;
0207 }
0208
0209 G4DynamicParticle* G4RDAtomicDeexcitation::GenerateFluorescence(G4int Z,
0210 G4int shellId,
0211 G4int provShellId )
0212 {
0213
0214
0215 const G4RDAtomicTransitionManager* transitionManager = G4RDAtomicTransitionManager::Instance();
0216
0217
0218
0219 G4double newcosTh = 1.-2.*G4UniformRand();
0220 G4double newsinTh = std::sqrt(1.-newcosTh*newcosTh);
0221 G4double newPhi = twopi*G4UniformRand();
0222
0223 G4double xDir = newsinTh*std::sin(newPhi);
0224 G4double yDir = newsinTh*std::cos(newPhi);
0225 G4double zDir = newcosTh;
0226
0227 G4ThreeVector newGammaDirection(xDir,yDir,zDir);
0228
0229 G4int shellNum = 0;
0230 G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
0231
0232
0233 while (shellId != transitionManager->
0234 ReachableShell(Z,shellNum)->FinalShellId())
0235 {
0236 if(shellNum == maxNumOfShells-1)
0237 {
0238 break;
0239 }
0240 shellNum++;
0241 }
0242
0243 size_t transitionSize = transitionManager->
0244 ReachableShell(Z,shellNum)->OriginatingShellIds().size();
0245
0246 size_t index = 0;
0247
0248
0249
0250 while (provShellId != transitionManager->
0251 ReachableShell(Z,shellNum)->OriginatingShellId(index))
0252 {
0253 if(index == transitionSize-1)
0254 {
0255 break;
0256 }
0257 index++;
0258 }
0259
0260 G4double transitionEnergy = transitionManager->
0261 ReachableShell(Z,shellNum)->TransitionEnergy(index);
0262
0263
0264
0265 newShellId = transitionManager->
0266 ReachableShell(Z,shellNum)->OriginatingShellId(index);
0267
0268
0269 G4DynamicParticle* newPart = new G4DynamicParticle(G4Gamma::Gamma(),
0270 newGammaDirection,
0271 transitionEnergy);
0272 return newPart;
0273 }
0274
0275 G4DynamicParticle* G4RDAtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
0276 {
0277 if(!fAuger) return 0;
0278
0279
0280 const G4RDAtomicTransitionManager* transitionManager =
0281 G4RDAtomicTransitionManager::Instance();
0282
0283
0284
0285 if (shellId <=0 )
0286 {
0287 G4Exception("G4RDAtomicDeexcitation::GenerateAuger()",
0288 "InvalidCondition", FatalException,
0289 "Zero or negative shellId!");
0290 }
0291
0292
0293 G4int maxNumOfShells = transitionManager->NumberOfReachableAugerShells(Z);
0294
0295 const G4RDAugerTransition* refAugerTransition =
0296 transitionManager->ReachableAugerShell(Z,maxNumOfShells-1);
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306 G4int shellNum = 0;
0307
0308
0309 if ( shellId <= refAugerTransition->FinalShellId() )
0310
0311
0312 {
0313 G4int pippo = transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId();
0314 if (shellId != pippo ) {
0315 do {
0316 shellNum++;
0317 if(shellNum == maxNumOfShells)
0318 {
0319
0320
0321 return 0;
0322
0323 }
0324 }
0325 while (shellId != (transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId()) ) ;
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346 G4int transitionLoopShellIndex = 0;
0347 G4double partSum = 0;
0348 const G4RDAugerTransition* anAugerTransition =
0349 transitionManager->ReachableAugerShell(Z,shellNum);
0350
0351
0352
0353
0354 G4int transitionSize =
0355 (anAugerTransition->TransitionOriginatingShellIds())->size();
0356 while (transitionLoopShellIndex < transitionSize) {
0357
0358 std::vector<G4int>::const_iterator pos =
0359 anAugerTransition->TransitionOriginatingShellIds()->begin();
0360
0361 G4int transitionLoopShellId = *(pos+transitionLoopShellIndex);
0362 G4int numberOfPossibleAuger =
0363 (anAugerTransition->AugerTransitionProbabilities(transitionLoopShellId))->size();
0364 G4int augerIndex = 0;
0365
0366
0367
0368 if (augerIndex < numberOfPossibleAuger) {
0369
0370 do
0371 {
0372 G4double thisProb = anAugerTransition->AugerTransitionProbability(augerIndex,
0373 transitionLoopShellId);
0374 partSum += thisProb;
0375 augerIndex++;
0376
0377 } while (augerIndex < numberOfPossibleAuger);
0378 }
0379 transitionLoopShellIndex++;
0380 }
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407 G4double totalVacancyAugerProbability = partSum;
0408
0409
0410
0411 G4int transitionRandomShellIndex = 0;
0412 G4int transitionRandomShellId = 1;
0413 G4int augerIndex = 0;
0414 partSum = 0;
0415 G4double partialProb = G4UniformRand();
0416
0417
0418 G4int numberOfPossibleAuger =
0419 (anAugerTransition->AugerTransitionProbabilities(transitionRandomShellId))->size();
0420 G4bool foundFlag = false;
0421
0422 while (transitionRandomShellIndex < transitionSize) {
0423
0424 std::vector<G4int>::const_iterator pos =
0425 anAugerTransition->TransitionOriginatingShellIds()->begin();
0426
0427 transitionRandomShellId = *(pos+transitionRandomShellIndex);
0428
0429 augerIndex = 0;
0430 numberOfPossibleAuger = (anAugerTransition->
0431 AugerTransitionProbabilities(transitionRandomShellId))->size();
0432
0433 while (augerIndex < numberOfPossibleAuger) {
0434 G4double thisProb =anAugerTransition->AugerTransitionProbability(augerIndex,
0435 transitionRandomShellId);
0436
0437 partSum += thisProb;
0438
0439 if (partSum >= (partialProb*totalVacancyAugerProbability) ) {
0440 foundFlag = true;
0441 break;
0442 }
0443 augerIndex++;
0444 }
0445 if (partSum >= (partialProb*totalVacancyAugerProbability) ) {break;}
0446 transitionRandomShellIndex++;
0447 }
0448
0449
0450
0451
0452
0453 if (!foundFlag) {return 0;}
0454
0455
0456 G4double newcosTh = 1.-2.*G4UniformRand();
0457 G4double newsinTh = std::sqrt(1.-newcosTh*newcosTh);
0458 G4double newPhi = twopi*G4UniformRand();
0459
0460 G4double xDir = newsinTh*std::sin(newPhi);
0461 G4double yDir = newsinTh*std::cos(newPhi);
0462 G4double zDir = newcosTh;
0463
0464 G4ThreeVector newElectronDirection(xDir,yDir,zDir);
0465
0466
0467
0468
0469 G4double transitionEnergy = anAugerTransition->AugerTransitionEnergy(augerIndex, transitionRandomShellId);
0470
0471
0472
0473
0474
0475
0476
0477
0478 newShellId = transitionRandomShellId;
0479
0480
0481 G4DynamicParticle* newPart = new G4DynamicParticle(G4Electron::Electron(),
0482 newElectronDirection,
0483 transitionEnergy);
0484 return newPart;
0485
0486 }
0487 else
0488 {
0489
0490 return 0;
0491 }
0492
0493 }
0494
0495 void G4RDAtomicDeexcitation::SetCutForSecondaryPhotons(G4double cut)
0496 {
0497 minGammaEnergy = cut;
0498 }
0499
0500 void G4RDAtomicDeexcitation::SetCutForAugerElectrons(G4double cut)
0501 {
0502 minElectronEnergy = cut;
0503 }
0504
0505 void G4RDAtomicDeexcitation::ActivateAugerElectronProduction(G4bool val)
0506 {
0507 fAuger = val;
0508 }
0509
0510
0511
0512
0513
0514
0515