75 :
G4VEmModel(nam),fParticleChange(nullptr),fParticle(nullptr),
76 fCrossSectionHandler(nullptr),
77 fAtomDeexcitation(nullptr), fKineticEnergy1(0.*
eV),
78 fCosThetaPrimary(1.0),fEnergySecondary(0.*
eV),
79 fCosThetaSecondary(0.0),fTargetOscillator(-1),
80 fIsInitialised(false),fPIXEflag(false),fLocalTable(false)
123 G4cout <<
"Calling G4PenelopeIonisationModel::Initialise()" <<
G4endl;
130 G4cout <<
"WARNING from G4PenelopeIonisationModel " <<
G4endl;
131 G4cout <<
"Atomic de-excitation module is not instantiated, so there will not be ";
133 G4cout <<
"Please make sure this is intended" <<
G4endl;
145 G4cout <<
"======================================================================" <<
G4endl;
146 G4cout <<
"The G4PenelopeIonisationModel is being used with the PIXE flag ON." <<
G4endl;
147 G4cout <<
"Atomic de-excitation will be produced statistically by the PIXE " <<
G4endl;
148 G4cout <<
"interface by using the shell cross section --> " << theModel <<
G4endl;
149 G4cout <<
"The built-in model procedure for atomic de-excitation is disabled. " <<
G4endl;
150 G4cout <<
"*Please be sure this is intended*, or disable PIXE by" <<
G4endl;
152 G4cout <<
"======================================================================" <<
G4endl;
187 G4cout <<
"Penelope Ionisation model v2008 is initialized " <<
G4endl
210 G4cout <<
"Calling G4PenelopeIonisationModel::InitialiseLocal()" <<
G4endl;
260 G4cout <<
"Calling CrossSectionPerVolume() of G4PenelopeIonisationModel" <<
G4endl;
289 ed <<
"Unable to retrieve the cross section table for " <<
291 " in " <<
material->GetName() <<
", cut = " << cutEnergy/
keV <<
" keV " <<
G4endl;
292 ed <<
"This can happen only in Unit Tests or via G4EmCalculator" <<
G4endl;
293 G4Exception(
"G4PenelopeIonisationModel::CrossSectionPerVolume()",
314 G4cout <<
"Material " <<
material->GetName() <<
" has " << atPerMol <<
315 "atoms per molecule" <<
G4endl;
319 moleculeDensity = atomDensity/atPerMol;
320 G4double crossPerVolume = crossPerMolecule*moleculeDensity;
325 G4cout <<
"Mean free path for delta emission > " << cutEnergy/
keV <<
" keV at " <<
329 G4cout <<
"Total free path for ionisation (no threshold) at " <<
332 return crossPerVolume;
347 G4cout <<
"*** G4PenelopeIonisationModel -- WARNING ***" <<
G4endl;
348 G4cout <<
"Penelope Ionisation model v2008 does not calculate cross section _per atom_ " <<
G4endl;
349 G4cout <<
"so the result is always zero. For physics values, please invoke " <<
G4endl;
350 G4cout <<
"GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" <<
G4endl;
377 G4cout <<
"Calling ComputeDEDX() of G4PenelopeIonisationModel" <<
G4endl;
400 ed <<
"Unable to retrieve the cross section table for " <<
402 " in " <<
material->GetName() <<
", cut = " << cutEnergy/
keV <<
" keV " <<
G4endl;
403 ed <<
"This can happen only in Unit Tests or via G4EmCalculator" <<
G4endl;
404 G4Exception(
"G4PenelopeIonisationModel::ComputeDEDXPerVolume()",
427 moleculeDensity = atomDensity/atPerMol;
428 G4double sPowerPerVolume = sPowerPerMolecule*moleculeDensity;
433 G4cout <<
"Stopping power < " << cutEnergy/
keV <<
" keV at " <<
434 kineticEnergy/
keV <<
" keV = " <<
437 return sPowerPerVolume;
488 G4cout <<
"Calling SamplingSecondaries() of G4PenelopeIonisationModel" <<
G4endl;
521 G4Exception(
"G4PenelopeIonisationModel::SamplingSecondaries()",
529 G4cout <<
"G4PenelopeIonisationModel::SamplingSecondaries() for " <<
541 G4double dirx = sint * std::cos(phiPrimary);
542 G4double diry = sint * std::sin(phiPrimary);
546 electronDirection1.
rotateUz(particleDirection0);
557 G4double ionEnergyInPenelopeDatabase =
571 if (
Z > 0 && shFlag<30)
573 shell = transitionManager->
Shell(
Z,shFlag-1);
608 size_t nBefore = fvect->size();
610 size_t nAfter = fvect->size();
614 for (
size_t j=nBefore;j<nAfter;j++)
616 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
617 if (itsEnergy < localEnergyDeposit)
619 localEnergyDeposit -= itsEnergy;
621 energyInFluorescence += itsEnergy;
623 energyInAuger += itsEnergy;
628 (*fvect)[j] =
nullptr;
641 G4double xEl = sinThetaE * std::cos(phiEl);
642 G4double yEl = sinThetaE * std::sin(phiEl);
645 eDirection.
rotateUz(particleDirection0);
656 if (localEnergyDeposit < 0)
658 G4Exception(
"G4PenelopeIonisationModel::SampleSecondaries()",
659 "em2099",
JustWarning,
"WARNING: Negative local energy deposit");
660 localEnergyDeposit=0.;
666 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
667 G4cout <<
"Energy balance from G4PenelopeIonisation" <<
G4endl;
668 G4cout <<
"Incoming primary energy: " << kineticEnergy0/
keV <<
" keV" <<
G4endl;
669 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
672 if (energyInFluorescence)
673 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/
keV <<
" keV" <<
G4endl;
675 G4cout <<
"Auger electrons: " << energyInAuger/
keV <<
" keV" <<
G4endl;
676 G4cout <<
"Local energy deposit " << localEnergyDeposit/
keV <<
" keV" <<
G4endl;
678 localEnergyDeposit+energyInAuger)/
keV <<
680 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
686 localEnergyDeposit+energyInAuger-kineticEnergy0);
687 if (energyDiff > 0.05*
keV)
688 G4cout <<
"Warning from G4PenelopeIonisation: problem with energy conservation: " <<
690 " keV (final) vs. " <<
691 kineticEnergy0/
keV <<
" keV (initial)" <<
G4endl;
710 size_t numberOfOscillators = theTable->size();
721 for (
size_t i=0;i<numberOfOscillators-1;i++)
734 G4cout <<
"SampleFinalStateElectron: sampled oscillator #" <<
736 G4cout <<
"Ionisation energy: " <<
739 G4cout <<
"Resonance energy: : " <<
762 if (resEne > cutEnergy && resEne < kineticEnergy)
764 cps = kineticEnergy*rb;
767 if (resEne > 1.0e-6*kineticEnergy)
781 XHDT = XHDT0*invResEne;
800 G4double EE = kineticEnergy + ionEne;
809 XHC = (amol*(0.5-rcl)+1.0/rcl-rrl1+
810 (1.0-amol)*
G4Log(rcl*rrl1))/EE;
817 if (XHTOT < 1.e-14*
barn)
844 rk = rcl/(1.0-fb*(1.0-(rcl+rcl)));
846 rk = rcl + (fb-1.0)*(0.5-rcl)/ARCL;
849 G4double phi = 1.0+rkf*rkf-rkf+amol*(rk2+rkf);
862 G4cout <<
"SampleFinalStateElectron: sampled close collision " <<
G4endl;
883 fCosThetaSecondary = 0.5*(deltaE*(kineticEnergy+rb-deltaE)+QTREV)/std::sqrt(cps*QTREV);
887 G4cout <<
"SampleFinalStateElectron: sampled distant longitudinal collision " <<
G4endl;
897 G4cout <<
"SampleFinalStateElectron: sampled distant transverse collision " <<
G4endl;
917 size_t numberOfOscillators = theTable->size();
927 for (
size_t i=0;i<numberOfOscillators-1;i++)
939 G4cout <<
"SampleFinalStatePositron: sampled oscillator #" <<
955 G4double bha1 = amol*(2.0*g12-1.0)/(gam2-1.0);
975 if (resEne > cutEnergy && resEne < kineticEnergy)
977 cps = kineticEnergy*rb;
980 if (resEne > 1.0e-6*kineticEnergy)
994 XHDT = XHDT0*invResEne;
1019 XHC = ((1.0/rcl-1.0)+bha1*
G4Log(rcl)+bha2*rl1
1020 + (bha3/2.0)*(rcl*rcl-1.0)
1021 + (bha4/3.0)*(1.0-rcl*rcl*rcl))/kineticEnergy;
1025 G4double XHTOT = XHC + XHDL + XHDT;
1028 if (XHTOT < 1.e-14*
barn)
1047 G4bool loopAgain =
false;
1052 G4double phi = 1.0-rk*(bha1-rk*(bha2-rk*(bha3-bha4*rk)));
1057 G4double deltaE = rk*kineticEnergy;
1064 G4cout <<
"SampleFinalStatePositron: sampled close collision " <<
G4endl;
1084 fCosThetaSecondary = 0.5*(deltaE*(kineticEnergy+rb-deltaE)+QTREV)/std::sqrt(cps*QTREV);
1088 G4cout <<
"SampleFinalStatePositron: sampled distant longitudinal collision " <<
G4endl;
1099 G4cout <<
"SampleFinalStatePositron: sampled distant transverse collision " <<
G4endl;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Log(G4double x)
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
static constexpr double twopi
static constexpr double barn
static constexpr double mm
static constexpr double keV
static constexpr double eV
static constexpr double GeV
static constexpr double pi
#define G4MUTEX_INITIALIZER
G4GLOB_DLL std::ostream G4cout
Hep3Vector & rotateUz(const Hep3Vector &)
G4double BindingEnergy() const
G4AtomicShell * Shell(G4int Z, size_t shellIndex) const
static G4AtomicTransitionManager * Instance()
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Definition()
static G4Electron * Electron()
static G4EmParameters * Instance()
const G4String & PIXEElectronCrossSectionModel()
static G4Gamma * Definition()
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
const G4String & GetParticleName() const
G4double GetTotalCrossSection(G4double energy) const
Returns total cross section at the given energy.
G4double GetSoftStoppingPower(G4double energy) const
Returns the total stopping power due to soft collisions.
G4double GetHardCrossSection(G4double energy) const
Returns hard cross section at the given energy.
G4double GetNormalizedShellCrossSection(size_t shellID, G4double energy) const
Returns the hard cross section for the given shell (normalized to 1)
G4double fIntrinsicLowEnergyLimit
G4ParticleChangeForLoss * fParticleChange
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *) override
virtual ~G4PenelopeIonisationModel()
void SampleFinalStateElectron(const G4Material *, G4double cutEnergy, G4double kineticEnergy)
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
void SetParticle(const G4ParticleDefinition *)
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double, G4double, G4double, G4double, G4double) override
G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy) override
G4VAtomDeexcitation * fAtomDeexcitation
G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *theParticle, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy=DBL_MAX) override
G4PenelopeOscillatorManager * fOscManager
G4double fCosThetaPrimary
G4double fCosThetaSecondary
G4double MinEnergyCut(const G4ParticleDefinition *, const G4MaterialCutsCouple *) override
G4double fIntrinsicHighEnergyLimit
const G4ParticleDefinition * fParticle
G4double fEnergySecondary
void SampleFinalStatePositron(const G4Material *, G4double cutEnergy, G4double kineticEnergy)
G4PenelopeIonisationXSHandler * fCrossSectionHandler
G4PenelopeIonisationModel(const G4ParticleDefinition *p=nullptr, const G4String &processName="PenIoni")
G4double GetDensityCorrection(const G4Material *, const G4double energy) const
Returns the density coeection for the material at the given energy.
void BuildXSTable(const G4Material *, G4double cut, const G4ParticleDefinition *, G4bool isMaster=true)
This can be inkoved only by the master.
const G4PenelopeCrossSection * GetCrossSectionTableForCouple(const G4ParticleDefinition *, const G4Material *, const G4double cut) const
void SetVerboseLevel(G4int vl)
Setter for the verbosity level.
G4double GetAtomsPerMolecule(const G4Material *)
Returns the total number of atoms per molecule.
static G4PenelopeOscillatorManager * GetOscillatorManager()
G4PenelopeOscillatorTable * GetOscillatorTableIonisation(const G4Material *)
static G4Positron * Positron()
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
G4bool IsPIXEActive() const
void SetHighEnergyLimit(G4double)
G4double LowEnergyLimit() const
G4double HighEnergyLimit() const
virtual void SetupForMaterial(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
void SetDeexcitationFlag(G4bool val)
G4ParticleChangeForLoss * GetParticleChangeForLoss()
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4double energy(const ThreeVector &p, const G4double m)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4double bindingEnergy(G4int A, G4int Z)
G4Mutex PenelopeIonisationModelMutex