72 :
G4VEmModel(nam),fParticleChange(nullptr),fParticle(nullptr),
73 fAtomDeexcitation(nullptr),fIsInitialised(false),fLocalTable(false)
121 G4cout <<
"Calling G4PenelopePhotoElectricModel::Initialise()" <<
G4endl;
128 G4cout <<
"WARNING from G4PenelopePhotoElectricModel " <<
G4endl;
129 G4cout <<
"Atomic de-excitation module is not instantiated, so there will not be ";
131 G4cout <<
"Please make sure this is intended" <<
G4endl;
148 for (
size_t j=0;j<
material->GetNumberOfElements();j++)
150 G4int iZ = theElementVector->at(j)->GetZasInt();
160 G4cout <<
"Penelope Photo-Electric model v2008 is initialized " <<
G4endl
177 G4cout <<
"Calling G4PenelopePhotoElectricModel::InitialiseLocal()" <<
G4endl;
210 G4cout <<
"Calling ComputeCrossSectionPerAtom() of G4PenelopePhotoElectricModel" <<
G4endl;
222 ed <<
"Unable to retrieve the shell cross section table for Z=" << iZ <<
G4endl;
223 ed <<
"This can happen only in Unit Tests or via G4EmCalculator" <<
G4endl;
224 G4Exception(
"G4PenelopePhotoElectricModel::ComputeCrossSectionPerAtom()",
239 G4Exception(
"G4PenelopePhotoElectricModel::ComputeCrossSectionPerAtom()",
241 "Unable to retrieve the total cross section table");
246 cross =
G4Exp(logXS);
249 G4cout <<
"Photoelectric cross section at " <<
energy/
MeV <<
" MeV for Z=" <<
Z <<
277 G4cout <<
"Calling SamplingSecondaries() of G4PenelopePhotoElectricModel" <<
G4endl;
313 G4cout <<
"Selected shell " << shellIndex <<
" of element " << anElement->
GetName() <<
G4endl;
325 if (shellIndex >= numberOfShells)
326 shellIndex = numberOfShells-1;
347 if (eKineticEnergy > 0.)
352 G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
354 G4double dirx = sinTheta * std::cos(phi);
355 G4double diry = sinTheta * std::sin(phi);
358 electronDirection.
rotateUz(photonDirection);
378 size_t nBefore = fvect->size();
380 size_t nAfter = fvect->size();
382 if (nAfter > nBefore)
384 for (
size_t j=nBefore;j<nAfter;j++)
386 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
391 energyInFluorescence += itsEnergy;
393 energyInAuger += itsEnergy;
398 (*fvect)[j] =
nullptr;
408 if (localEnergyDeposit < 0)
410 G4Exception(
"G4PenelopePhotoElectricModel::SampleSecondaries()",
411 "em2099",
JustWarning,
"WARNING: Negative local energy deposit");
412 localEnergyDeposit = 0;
419 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
420 G4cout <<
"Energy balance from G4PenelopePhotoElectric" <<
G4endl;
423 G4cout <<
"Incoming photon energy: " << photonEnergy/
keV <<
" keV" <<
G4endl;
424 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
426 G4cout <<
"Outgoing electron " << eKineticEnergy/
keV <<
" keV" <<
G4endl;
427 if (energyInFluorescence)
428 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/
keV <<
" keV" <<
G4endl;
430 G4cout <<
"Auger electrons: " << energyInAuger/
keV <<
" keV" <<
G4endl;
431 G4cout <<
"Local energy deposit " << localEnergyDeposit/
keV <<
" keV" <<
G4endl;
432 G4cout <<
"Total final state: " <<
433 (eKineticEnergy+energyInFluorescence+localEnergyDeposit+energyInAuger)/
keV <<
435 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
440 std::fabs(eKineticEnergy+energyInFluorescence+localEnergyDeposit+energyInAuger-photonEnergy);
441 if (energyDiff > 0.05*
keV)
443 G4cout <<
"Warning from G4PenelopePhotoElectric: problem with energy conservation: " <<
444 (eKineticEnergy+energyInFluorescence+localEnergyDeposit+energyInAuger)/
keV
445 <<
" keV (final) vs. " <<
446 photonEnergy/
keV <<
" keV (initial)" <<
G4endl;
447 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
448 G4cout <<
"Energy balance from G4PenelopePhotoElectric" <<
G4endl;
451 G4cout <<
"Incoming photon energy: " << photonEnergy/
keV <<
" keV" <<
G4endl;
452 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
454 G4cout <<
"Outgoing electron " << eKineticEnergy/
keV <<
" keV" <<
G4endl;
455 if (energyInFluorescence)
456 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/
keV <<
" keV" <<
G4endl;
458 G4cout <<
"Auger electrons: " << energyInAuger/
keV <<
" keV" <<
G4endl;
459 G4cout <<
"Local energy deposit " << localEnergyDeposit/
keV <<
" keV" <<
G4endl;
460 G4cout <<
"Total final state: " <<
461 (eKineticEnergy+energyInFluorescence+localEnergyDeposit+energyInAuger)/
keV <<
463 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
497 tsam = 2.0*ac * (2.0*rand + a2*std::sqrt(rand)) / (a2*a2 - 4.0*rand);
498 gtr = (2.0 - tsam) * (a1 + 1.0/(ac+tsam));
511 G4Exception(
"G4PenelopePhotoElectricModel::ReadDataFile()",
516 G4cout <<
"G4PenelopePhotoElectricModel::ReadDataFile()" <<
G4endl;
517 G4cout <<
"Going to read PhotoElectric data files for Z=" <<
Z <<
G4endl;
520 char* path = std::getenv(
"G4LEDATA");
523 G4String excep =
"G4PenelopePhotoElectricModel - G4LEDATA environment variable not set!";
524 G4Exception(
"G4PenelopePhotoElectricModel::ReadDataFile()",
532 std::ostringstream ost;
534 ost << path <<
"/penelope/photoelectric/pdgph" <<
Z <<
".p08";
536 ost << path <<
"/penelope/photoelectric/pdgph0" <<
Z <<
".p08";
537 std::ifstream
file(ost.str().c_str());
540 G4String excep =
"G4PenelopePhotoElectricModel - data file " +
G4String(ost.str()) +
" not found!";
541 G4Exception(
"G4PenelopePhotoElectricModel::ReadDataFile()",
548 while( getline(
file, line) )
555 file.open(ost.str().c_str());
559 file >> readZ >> nShells;
562 G4cout <<
"Element Z=" <<
Z <<
" , nShells = " << nShells <<
G4endl;
565 if (readZ !=
Z || nShells <= 0 || nShells > 50)
568 ed <<
"Corrupted data file for Z=" <<
Z <<
G4endl;
569 G4Exception(
"G4PenelopePhotoElectricModel::ReadDataFile()",
581 for (
size_t i=0;i<nShells+1;i++)
585 for (k=0;k<ndata && !
file.eof();k++)
593 for (
size_t i=0;i<nShells+1;i++)
598 if (aValue < 1e-40*
cm2)
606 G4cout <<
"G4PenelopePhotoElectricModel: read " << k <<
" points for element Z = "
622 G4Exception(
"G4PenelopePhotoElectricModel::GetNumberOfShellXS()",
632 ed <<
"Cannot find shell cross section data for Z=" <<
Z <<
G4endl;
633 G4Exception(
"G4PenelopePhotoElectricModel::GetNumberOfShellXS()",
648 if (shellID >= entries)
650 G4cout <<
"Element Z=" <<
Z <<
" has data for " << entries <<
" shells only" <<
G4endl;
651 G4cout <<
"so shellID should be from 0 to " << entries-1 <<
G4endl;
661 G4Exception(
"G4PenelopePhotoElectricModel::GetShellCrossSection()",
663 "Unable to retrieve the total cross section table");
669 if (cross < 2e-40*
cm2) cross = 0;
680 else if (shellID == 1)
682 else if (shellID == 2)
684 else if (shellID == 3)
686 else if (shellID == 4)
688 else if (shellID == 5)
690 else if (shellID == 6)
692 else if (shellID == 7)
694 else if (shellID == 8)
719 ed <<
"Cannot find shell cross section data for Z=" <<
Z <<
G4endl;
720 G4Exception(
"G4PenelopePhotoElectricModel::SelectRandomShell()",
739 for (
size_t k=1;k<theTable->
entries();k++)
std::vector< const G4Element * > G4ElementVector
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
static constexpr double twopi
static constexpr double barn
static constexpr double cm2
static constexpr double keV
static constexpr double eV
static constexpr double GeV
static constexpr double MeV
#define G4MUTEX_INITIALIZER
G4GLOB_DLL std::ostream G4cout
Hep3Vector & rotateUz(const Hep3Vector &)
G4double BindingEnergy() const
G4AtomicShell * Shell(G4int Z, size_t shellIndex) const
G4int NumberOfShells(G4int Z) const
static G4AtomicTransitionManager * Instance()
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Definition()
static G4Electron * Electron()
const G4String & GetName() const
static G4Gamma * GammaDefinition()
static G4Gamma * Definition()
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
const G4String & GetName() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
const G4AtomicTransitionManager * fTransitionManager
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
G4VAtomDeexcitation * fAtomDeexcitation
G4String WriteTargetShell(size_t shellID)
void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel) override
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
G4PenelopePhotoElectricModel(const G4ParticleDefinition *p=nullptr, const G4String &processName="PenPhotoElec")
G4double SampleElectronDirection(G4double energy)
G4double fIntrinsicLowEnergyLimit
G4double GetShellCrossSection(G4int Z, size_t shellID, G4double energy)
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX) override
size_t GetNumberOfShellXS(G4int)
G4ParticleChangeForGamma * fParticleChange
size_t SelectRandomShell(G4int Z, G4double energy)
static G4PhysicsTable * fLogAtomicShellXS[fMaxZ+1]
void ReadDataFile(G4int Z)
virtual ~G4PenelopePhotoElectricModel()
G4double fIntrinsicHighEnergyLimit
void SetParticle(const G4ParticleDefinition *)
const G4ParticleDefinition * fParticle
void PutValue(const std::size_t index, const G4double e, const G4double value)
void push_back(G4PhysicsVector *)
std::size_t entries() const
G4double Value(const G4double energy, std::size_t &lastidx) const
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)
void SetHighEnergyLimit(G4double)
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
G4ParticleChangeForGamma * GetParticleChangeForGamma()
G4double LowEnergyLimit() const
std::vector< G4EmElementSelector * > * GetElementSelectors()
G4double HighEnergyLimit() const
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void SetDeexcitationFlag(G4bool val)
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4double energy(const ThreeVector &p, const G4double m)
G4double bindingEnergy(G4int A, G4int Z)
G4Mutex PenelopePhotoElectricModelMutex