219{
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 if (verboseLevel > 3)
242 G4cout <<
"Calling SampleSecondaries() of G4PenelopeComptonModel" <<
G4endl;
243
245
246 if (photonEnergy0 <= fIntrinsicLowEnergyLimit)
247 {
251 return ;
252 }
253
256
258
259 const G4int nmax = 64;
262
268 size_t numberOfOscillators = theTable->size();
269 size_t targetOscillator = 0;
271
272 G4double ek = photonEnergy0/electron_mass_c2;
276
279 G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
280
283
284
285
286 if (photonEnergy0 > 5*MeV)
287 {
288 do{
289 do{
292 else
294
295 TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
297 epsilon=tau;
298 cosTheta = 1.0 - (1.0-tau)/(ek*tau);
299
300
302 targetOscillator = numberOfOscillators-1;
303 S=0.0;
304 G4bool levelFound =
false;
305 for (size_t j=0;j<numberOfOscillators && !levelFound; j++)
306 {
307 S += (*theTable)[j]->GetOscillatorStrength();
308 if (S > TST)
309 {
310 targetOscillator = j;
311 levelFound = true;
312 }
313 }
314
315 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
316 }while((epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
317 }
318 else
319 {
320
325 for (size_t i=0;i<numberOfOscillators;i++)
326 {
327 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
328 if (photonEnergy0 > ionEnergy)
329 {
330 G4double aux2 = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
331 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
332 oscStren = (*theTable)[i]->GetOscillatorStrength();
333 pzomc = hartreeFunc*(aux2-electron_mass_c2*ionEnergy)/
334 (electron_mass_c2*std::sqrt(2.0*aux2+ionEnergy*ionEnergy));
335 if (pzomc > 0)
336 rni = 1.0-0.5*std::exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
337 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
338 else
339 rni = 0.5*std::exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
340 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
342 }
343 }
344
346 do
347 {
350 else
352 cdt1 = (1.0-tau)/(ek*tau);
353
354 S = 0.;
355 for (size_t i=0;i<numberOfOscillators;i++)
356 {
357 ionEnergy = (*theTable)[i]->GetIonisationEnergy();
358 if (photonEnergy0 > ionEnergy)
359 {
360 aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
361 hartreeFunc = (*theTable)[i]->GetHartreeFactor();
362 oscStren = (*theTable)[i]->GetOscillatorStrength();
363 pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
364 (electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
365 if (pzomc > 0)
366 rn[i] = 1.0-0.5*std::exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
367 (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
368 else
369 rn[i] = 0.5*std::exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
370 (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
371 S += oscStren*rn[i];
372 pac[i] = S;
373 }
374 else
375 pac[i] = S-1e-6;
376 }
377
378 TST = S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
380
381 cosTheta = 1.0 - cdt1;
384
385 do
386 {
387 do
388 {
390 targetOscillator = numberOfOscillators-1;
391 G4bool levelFound =
false;
392 for (size_t i=0;i<numberOfOscillators && !levelFound;i++)
393 {
394 if (pac[i]>TST)
395 {
396 targetOscillator = i;
397 levelFound = true;
398 }
399 }
401 hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor();
402 oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
403 if (A < 0.5)
404 pzomc = (std::sqrt(0.5)-std::sqrt(0.5-std::log(2.0*A)))/
405 (std::sqrt(2.0)*hartreeFunc);
406 else
407 pzomc = (std::sqrt(0.5-std::log(2.0-2.0*A))-std::sqrt(0.5))/
408 (std::sqrt(2.0)*hartreeFunc);
409 } while (pzomc < -1);
410
411
412 G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
413 G4double AF = std::sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
414 if (AF > 0)
415 fpzmax = 1.0+AF*0.2;
416 else
417 fpzmax = 1.0-AF*0.2;
418 fpz = 1.0+AF*std::max(std::min(pzomc,0.2),-0.2);
420
421
425 if (pzomc > 0.0)
426 epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
427 else
428 epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
429 }
430
431
432 G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
434 G4double dirx = sinTheta * std::cos(phi);
435 G4double diry = sinTheta * std::sin(phi);
437
438
440 photonDirection1.rotateUz(photonDirection0);
442
443 G4double photonEnergy1 = epsilon * photonEnergy0;
444
445 if (photonEnergy1 > 0.)
447 else
448 {
451 }
452
453
454 G4double diffEnergy = photonEnergy0*(1-epsilon);
455 ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
456
458 photonEnergy0*photonEnergy0+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
460
461 if (Q2 > 1.0e-12)
462 cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/std::sqrt(Q2);
463 else
464 cosThetaE = 1.0;
465 G4double sinThetaE = std::sqrt(1-cosThetaE*cosThetaE);
466
467
468
469 G4int shFlag = (*theTable)[targetOscillator]->GetShellFlag();
470 G4int Z = (
G4int) (*theTable)[targetOscillator]->GetParentZ();
471
472
475
476
477 if (Z > 0 && shFlag<30)
478 {
479 shell = fTransitionManager->
Shell(Z,shFlag-1);
481 }
482
483 G4double ionEnergyInPenelopeDatabase = ionEnergy;
484
485 ionEnergy = std::max(bindingEnergy,ionEnergyInPenelopeDatabase);
486
487
488
489 G4double eKineticEnergy = diffEnergy - ionEnergy;
490 G4double localEnergyDeposit = ionEnergy;
493
494 if (eKineticEnergy < 0)
495 {
496
497
498
499
500 localEnergyDeposit = diffEnergy;
501 eKineticEnergy = 0.0;
502 }
503
504
505
506
507 if (fAtomDeexcitation && shell)
508 {
511 {
512 size_t nBefore = fvect->size();
514 size_t nAfter = fvect->size();
515
516 if (nAfter > nBefore)
517 {
518 for (size_t j=nBefore;j<nAfter;j++)
519 {
520 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
521 localEnergyDeposit -= itsEnergy;
523 energyInFluorescence += itsEnergy;
525 energyInAuger += itsEnergy;
526
527 }
528 }
529
530 }
531 }
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
603
604 G4double xEl = sinThetaE * std::cos(phi+pi);
605 G4double yEl = sinThetaE * std::sin(phi+pi);
608 eDirection.rotateUz(photonDirection0);
610 eDirection,eKineticEnergy) ;
611 fvect->push_back(electron);
612
613
614 if (localEnergyDeposit < 0)
615 {
617 << "G4PenelopeComptonModel::SampleSecondaries - Negative energy deposit"
619 localEnergyDeposit=0.;
620 }
622
624 if (electron)
625 electronEnergy = eKineticEnergy;
626 if (verboseLevel > 1)
627 {
628 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
629 G4cout <<
"Energy balance from G4PenelopeCompton" <<
G4endl;
630 G4cout <<
"Incoming photon energy: " << photonEnergy0/keV <<
" keV" <<
G4endl;
631 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
632 G4cout <<
"Scattered photon: " << photonEnergy1/keV <<
" keV" <<
G4endl;
633 G4cout <<
"Scattered electron " << electronEnergy/keV <<
" keV" <<
G4endl;
634 if (energyInFluorescence)
635 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/keV <<
" keV" <<
G4endl;
636 if (energyInAuger)
637 G4cout <<
"Auger electrons: " << energyInAuger/keV <<
" keV" <<
G4endl;
638 G4cout <<
"Local energy deposit " << localEnergyDeposit/keV <<
" keV" <<
G4endl;
639 G4cout <<
"Total final state: " << (photonEnergy1+electronEnergy+energyInFluorescence+
640 localEnergyDeposit+energyInAuger)/keV <<
642 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
643 }
644 if (verboseLevel > 0)
645 {
646 G4double energyDiff = std::fabs(photonEnergy1+
647 electronEnergy+energyInFluorescence+
648 localEnergyDeposit+energyInAuger-photonEnergy0);
649 if (energyDiff > 0.05*keV)
650 G4cout <<
"Warning from G4PenelopeCompton: problem with energy conservation: " <<
651 (photonEnergy1+electronEnergy+energyInFluorescence+energyInAuger+localEnergyDeposit)/keV <<
652 " keV (final) vs. " <<
653 photonEnergy0/keV <<
" keV (initial)" <<
G4endl;
654 }
655}
G4double BindingEnergy() const
G4AtomicShell * Shell(G4int Z, size_t shellIndex) const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Definition()
static G4Electron * Electron()
static G4Gamma * Definition()
const G4Material * GetMaterial() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double GetTotalZ(const G4Material *)
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4double bindingEnergy(G4int A, G4int Z)