456{
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489 if (fVerboseLevel > 3)
490 G4cout <<
"Calling SamplingSecondaries() of G4PenelopeIonisationModel" <<
G4endl;
491
493 const G4ParticleDefinition* theParticle = aDynamicParticle->
GetDefinition();
494
495 if (kineticEnergy0 <= fIntrinsicLowEnergyLimit)
496 {
499 return ;
500 }
501
502 const G4Material* material = couple->
GetMaterial();
504
506
507
508
509 fKineticEnergy1=kineticEnergy0;
510 fCosThetaPrimary=1.0;
511 fEnergySecondary=0.0;
512 fCosThetaSecondary=1.0;
513 fTargetOscillator = -1;
514
516 SampleFinalStateElectron(material,cutE,kineticEnergy0);
518 SampleFinalStatePositron(material,cutE,kineticEnergy0);
519 else
520 {
523 G4Exception(
"G4PenelopeIonisationModel::SamplingSecondaries()",
525
526 }
527 if (fEnergySecondary == 0) return;
528
529 if (fVerboseLevel > 3)
530 {
531 G4cout <<
"G4PenelopeIonisationModel::SamplingSecondaries() for " <<
533 G4cout <<
"Final eKin = " << fKineticEnergy1 <<
" keV" <<
G4endl;
534 G4cout <<
"Final cosTheta = " << fCosThetaPrimary <<
G4endl;
535 G4cout <<
"Delta-ray eKin = " << fEnergySecondary <<
" keV" <<
G4endl;
536 G4cout <<
"Delta-ray cosTheta = " << fCosThetaSecondary <<
G4endl;
537 G4cout <<
"Oscillator: " << fTargetOscillator <<
G4endl;
538 }
539
540
541 G4double sint = std::sqrt(1. - fCosThetaPrimary*fCosThetaPrimary);
543 G4double dirx = sint * std::cos(phiPrimary);
544 G4double diry = sint * std::sin(phiPrimary);
546
548 electronDirection1.rotateUz(particleDirection0);
549
550 if (fKineticEnergy1 > 0)
551 {
554 }
555 else
557
558
559 G4double ionEnergyInPenelopeDatabase =
560 (*theTable)[fTargetOscillator]->GetIonisationEnergy();
561
562
563
564 G4int shFlag = (*theTable)[fTargetOscillator]->GetShellFlag();
565 G4int Z = (
G4int) (*theTable)[fTargetOscillator]->GetParentZ();
566
567
570
571 const G4AtomicShell*
shell =
nullptr;
572
573 if (Z > 0 && shFlag<30)
574 {
577
578 }
579
580
581
582
583 fEnergySecondary += ionEnergyInPenelopeDatabase-
bindingEnergy;
584
586
589
590 if (fEnergySecondary < 0)
591 {
592
593
594
595
596 localEnergyDeposit += fEnergySecondary;
597 fEnergySecondary = 0.0;
598 }
599
600
601
602
603
604
605 if (fAtomDeexcitation && !fPIXEflag && shell)
606 {
608 if (fAtomDeexcitation->CheckDeexcitationActiveRegion(index))
609 {
610 std::size_t nBefore = fvect->size();
611 fAtomDeexcitation->GenerateParticles(fvect,shell,Z,index);
612 std::size_t nAfter = fvect->size();
613
614 if (nAfter>nBefore)
615 {
616 for (std::size_t j=nBefore;j<nAfter;++j)
617 {
618 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
619 if (itsEnergy < localEnergyDeposit)
620 {
621 localEnergyDeposit -= itsEnergy;
623 energyInFluorescence += itsEnergy;
625 energyInAuger += itsEnergy;
626 }
627 else
628 {
629 delete (*fvect)[j];
630 (*fvect)[j] = nullptr;
631 }
632 }
633 }
634 }
635 }
636
637
638 if (fEnergySecondary > cutE)
639 {
640 G4DynamicParticle*
electron =
nullptr;
641 G4double sinThetaE = std::sqrt(1.-fCosThetaSecondary*fCosThetaSecondary);
643 G4double xEl = sinThetaE * std::cos(phiEl);
644 G4double yEl = sinThetaE * std::sin(phiEl);
647 eDirection.rotateUz(particleDirection0);
649 eDirection,fEnergySecondary) ;
650 fvect->push_back(electron);
651 }
652 else
653 {
654 localEnergyDeposit += fEnergySecondary;
655 fEnergySecondary = 0;
656 }
657
658 if (localEnergyDeposit < 0)
659 {
660 G4Exception(
"G4PenelopeIonisationModel::SampleSecondaries()",
661 "em2099",
JustWarning,
"WARNING: Negative local energy deposit");
662 localEnergyDeposit=0.;
663 }
665
666 if (fVerboseLevel > 1)
667 {
668 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
669 G4cout <<
"Energy balance from G4PenelopeIonisation" <<
G4endl;
670 G4cout <<
"Incoming primary energy: " << kineticEnergy0/keV <<
" keV" <<
G4endl;
671 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
672 G4cout <<
"Outgoing primary energy: " << fKineticEnergy1/keV <<
" keV" <<
G4endl;
673 G4cout <<
"Delta ray " << fEnergySecondary/keV <<
" keV" <<
G4endl;
674 if (energyInFluorescence)
675 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/keV <<
" keV" <<
G4endl;
676 if (energyInAuger)
677 G4cout <<
"Auger electrons: " << energyInAuger/keV <<
" keV" <<
G4endl;
678 G4cout <<
"Local energy deposit " << localEnergyDeposit/keV <<
" keV" <<
G4endl;
679 G4cout <<
"Total final state: " << (fEnergySecondary+energyInFluorescence+fKineticEnergy1+
680 localEnergyDeposit+energyInAuger)/keV <<
682 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
683 }
684
685 if (fVerboseLevel > 0)
686 {
687 G4double energyDiff = std::fabs(fEnergySecondary+energyInFluorescence+fKineticEnergy1+
688 localEnergyDeposit+energyInAuger-kineticEnergy0);
689 if (energyDiff > 0.05*keV)
690 G4cout <<
"Warning from G4PenelopeIonisation: problem with energy conservation: " <<
691 (fEnergySecondary+energyInFluorescence+fKineticEnergy1+localEnergyDeposit+energyInAuger)/keV <<
692 " keV (final) vs. " <<
693 kineticEnergy0/keV <<
" keV (initial)" <<
G4endl;
694 }
695
696}
G4ThreeVector G4ParticleMomentum
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
CLHEP::Hep3Vector G4ThreeVector
G4AtomicShell * Shell(G4int Z, std::size_t shellIndex) const
static G4AtomicTransitionManager * Instance()
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Definition()
static G4Gamma * Definition()
static G4Positron * Positron()
G4double bindingEnergy(G4int A, G4int Z)