66 #include "G4PenelopeIonisationXSHandler.hh" 75 :
G4VEmModel(nam),fParticleChange(0),fParticle(0),isInitialised(false),
76 fAtomDeexcitation(0),fPIXEflag(false),kineticEnergy1(0.*
eV),
77 cosThetaPrimary(1.0),energySecondary(0.*
eV),
78 cosThetaSecondary(0.0),targetOscillator(-1),
79 theCrossSectionHandler(0),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;
160 G4cout <<
"======================================================================" <<
G4endl;
200 G4cout <<
"Penelope Ionisation model v2008 is initialized " << G4endl
223 G4cout <<
"Calling G4PenelopeIonisationModel::InitialiseLocal()" <<
G4endl;
275 G4cout <<
"Calling CrossSectionPerVolume() of G4PenelopeIonisationModel" <<
G4endl;
304 ed <<
"Unable to retrieve the cross section table for " << theParticle->
GetParticleName() <<
305 " in " << material->
GetName() <<
", cut = " << cutEnergy/
keV <<
" keV " <<
G4endl;
306 ed <<
"This can happen only in Unit Tests or via G4EmCalculator" <<
G4endl;
307 G4Exception(
"G4PenelopeIonisationModel::CrossSectionPerVolume()",
311 G4AutoLock lock(&PenelopeIonisationModelMutex);
329 G4cout <<
"Material " << material->
GetName() <<
" has " << atPerMol <<
330 "atoms per molecule" <<
G4endl;
334 moleculeDensity = atomDensity/atPerMol;
336 G4double crossPerVolume = crossPerMolecule*moleculeDensity;
341 G4cout <<
"Mean free path for delta emission > " << cutEnergy/
keV <<
" keV at " <<
342 energy/
keV <<
" keV = " << (1./crossPerVolume)/
mm <<
" mm" << G4endl;
345 G4cout <<
"Total free path for ionisation (no threshold) at " <<
346 energy/
keV <<
" keV = " << (1./totalCross)/
mm <<
" mm" << G4endl;
348 return crossPerVolume;
363 G4cout <<
"*** G4PenelopeIonisationModel -- WARNING ***" <<
G4endl;
364 G4cout <<
"Penelope Ionisation model v2008 does not calculate cross section _per atom_ " <<
G4endl;
365 G4cout <<
"so the result is always zero. For physics values, please invoke " <<
G4endl;
366 G4cout <<
"GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" <<
G4endl;
393 G4cout <<
"Calling ComputeDEDX() of G4PenelopeIonisationModel" <<
G4endl;
417 ed <<
"Unable to retrieve the cross section table for " << theParticle->
GetParticleName() <<
418 " in " << material->
GetName() <<
", cut = " << cutEnergy/
keV <<
" keV " <<
G4endl;
419 ed <<
"This can happen only in Unit Tests or via G4EmCalculator" <<
G4endl;
420 G4Exception(
"G4PenelopeIonisationModel::ComputeDEDXPerVolume()",
424 G4AutoLock lock(&PenelopeIonisationModelMutex);
444 moleculeDensity = atomDensity/atPerMol;
446 G4double sPowerPerVolume = sPowerPerMolecule*moleculeDensity;
451 G4cout <<
"Stopping power < " << cutEnergy/
keV <<
" keV at " <<
452 kineticEnergy/
keV <<
" keV = " <<
453 sPowerPerVolume/(
keV/
mm) <<
" keV/mm" << G4endl;
455 return sPowerPerVolume;
506 G4cout <<
"Calling SamplingSecondaries() of G4PenelopeIonisationModel" <<
G4endl;
539 G4Exception(
"G4PenelopeIonisationModel::SamplingSecondaries()",
547 G4cout <<
"G4PenelopeIonisationModel::SamplingSecondaries() for " <<
559 G4double dirx = sint * std::cos(phiPrimary);
560 G4double diry = sint * std::sin(phiPrimary);
564 electronDirection1.
rotateUz(particleDirection0);
576 G4double ionEnergyInPenelopeDatabase =
591 if (Z > 0 && shFlag<30)
593 shell = transitionManager->
Shell(Z,shFlag-1);
603 G4double localEnergyDeposit = bindingEnergy;
628 size_t nBefore = fvect->size();
630 size_t nAfter = fvect->size();
632 if (nAfter > nBefore)
634 for (
size_t j=nBefore;j<nAfter;j++)
636 G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
637 localEnergyDeposit -= itsEnergy;
639 energyInFluorescence += itsEnergy;
641 energyInAuger += itsEnergy;
653 G4double xEl = sinThetaE * std::cos(phiEl);
654 G4double yEl = sinThetaE * std::sin(phiEl);
657 eDirection.
rotateUz(particleDirection0);
660 fvect->push_back(electron);
668 if (localEnergyDeposit < 0)
671 <<
"G4PenelopeIonisationModel::SampleSecondaries - Negative energy deposit" 673 localEnergyDeposit=0.;
679 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
680 G4cout <<
"Energy balance from G4PenelopeIonisation" <<
G4endl;
681 G4cout <<
"Incoming primary energy: " << kineticEnergy0/
keV <<
" keV" <<
G4endl;
682 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
685 if (energyInFluorescence)
686 G4cout <<
"Fluorescence x-rays: " << energyInFluorescence/
keV <<
" keV" <<
G4endl;
688 G4cout <<
"Auger electrons: " << energyInAuger/
keV <<
" keV" <<
G4endl;
689 G4cout <<
"Local energy deposit " << localEnergyDeposit/
keV <<
" keV" <<
G4endl;
691 localEnergyDeposit+energyInAuger)/
keV <<
693 G4cout <<
"-----------------------------------------------------------" <<
G4endl;
699 localEnergyDeposit+energyInAuger-kineticEnergy0);
700 if (energyDiff > 0.05*
keV)
701 G4cout <<
"Warning from G4PenelopeIonisation: problem with energy conservation: " <<
703 " keV (final) vs. " <<
704 kineticEnergy0/
keV <<
" keV (initial)" << G4endl;
723 size_t numberOfOscillators = theTable->size();
734 for (
size_t i=0;i<numberOfOscillators-1;i++)
779 if (resEne > cutEnergy && resEne < kineticEnergy)
781 cps = kineticEnergy*rb;
784 if (resEne > 1.0
e-6*kineticEnergy)
798 XHDT = XHDT0*invResEne;
817 G4double EE = kineticEnergy + ionEne;
826 XHC = (amol*(0.5-rcl)+1.0/rcl-rrl1+
827 (1.0-amol)*std::log(rcl*rrl1))/EE;
834 if (XHTOT < 1.
e-14*
barn)
862 rk = rcl/(1.0-fb*(1.0-(rcl+rcl)));
864 rk = rcl + (fb-1.0)*(0.5-rcl)/ARCL;
867 G4double phi = 1.0+rkf*rkf-rkf+amol*(rk2+rkf);
880 G4cout <<
"SampleFinalStateElectron: sampled close collision " <<
G4endl;
897 if (cosThetaPrimary > 1.)
898 cosThetaPrimary = 1.0;
901 cosThetaSecondary = 0.5*(deltaE*(kineticEnergy+rb-deltaE)+QTREV)/std::sqrt(cps*QTREV);
905 G4cout <<
"SampleFinalStateElectron: sampled distant longitudinal collision " <<
G4endl;
915 G4cout <<
"SampleFinalStateElectron: sampled distant transverse collision " <<
G4endl;
936 size_t numberOfOscillators = theTable->size();
946 for (
size_t i=0;i<numberOfOscillators-1;i++)
973 G4double bha1 = amol*(2.0*g12-1.0)/(gam2-1.0);
975 G4double bha3 = amol*2.0*gam*(gam-1.0)/g12;
976 G4double bha4 = amol*(gam-1.0)*(gam-1.0)/g12;
993 if (resEne > cutEnergy && resEne < kineticEnergy)
995 cps = kineticEnergy*rb;
998 if (resEne > 1.0
e-6*kineticEnergy)
1012 XHDT = XHDT0*invResEne;
1037 XHC = ((1.0/rcl-1.0)+bha1*std::log(rcl)+bha2*rl1
1038 + (bha3/2.0)*(rcl*rcl-1.0)
1039 + (bha4/3.0)*(1.0-rcl*rcl*rcl))/kineticEnergy;
1043 G4double XHTOT = XHC + XHDL + XHDT;
1046 if (XHTOT < 1.
e-14*
barn)
1065 G4bool loopAgain =
false;
1070 G4double phi = 1.0-rk*(bha1-rk*(bha2-rk*(bha3-bha4*rk)));
1075 G4double deltaE = rk*kineticEnergy;
1082 G4cout <<
"SampleFinalStatePositron: sampled close collision " <<
G4endl;
1098 if (cosThetaPrimary > 1.)
1099 cosThetaPrimary = 1.0;
1102 cosThetaSecondary = 0.5*(deltaE*(kineticEnergy+rb-deltaE)+QTREV)/std::sqrt(cps*QTREV);
1106 G4cout <<
"SampleFinalStatePositron: sampled distant longitudinal collision " <<
G4endl;
1117 G4cout <<
"SampleFinalStatePositron: sampled distant transverse collision " <<
G4endl;
G4double cosThetaSecondary
G4double LowEnergyLimit() const
G4VAtomDeexcitation * fAtomDeexcitation
G4PenelopeOscillatorTable * GetOscillatorTableIonisation(const G4Material *)
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
static G4LossTableManager * Instance()
G4ParticleChangeForLoss * GetParticleChangeForLoss()
G4AtomicShell * Shell(G4int Z, size_t shellIndex) const
std::ostringstream G4ExceptionDescription
const G4Material * GetMaterial() const
void SampleFinalStateElectron(const G4Material *, G4double cutEnergy, G4double kineticEnergy)
virtual G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *theParticle, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy=DBL_MAX)
G4PenelopeOscillatorManager * oscManager
G4double GetTotNbOfAtomsPerVolume() const
virtual void SetupForMaterial(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
static G4Electron * Definition()
virtual void SampleSecondaries(std::vector< G4DynamicParticle *> *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
virtual void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *)
#define G4MUTEX_INITIALIZER
G4double GetNormalizedShellCrossSection(size_t shellID, G4double energy) const
Returns the hard cross section for the given shell (normalized to 1)
G4double fIntrinsicLowEnergyLimit
void SetHighEnergyLimit(G4double)
G4double GetSoftStoppingPower(G4double energy) const
Returns the total stopping power due to soft collisions.
G4bool IsPIXEActive() const
G4double GetKineticEnergy() const
const G4String & GetParticleName() const
G4GLOB_DLL std::ostream G4cout
virtual ~G4PenelopeIonisationModel()
double A(double temperature)
G4double HighEnergyLimit() const
G4PenelopeIonisationXSHandler * theCrossSectionHandler
Hep3Vector & rotateUz(const Hep3Vector &)
static const double twopi
G4ParticleChangeForLoss * fParticleChange
static G4PenelopeOscillatorManager * GetOscillatorManager()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
void SetParticle(const G4ParticleDefinition *)
static G4ProductionCutsTable * GetProductionCutsTable()
virtual G4double MinEnergyCut(const G4ParticleDefinition *, const G4MaterialCutsCouple *)
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
static G4Positron * Positron()
G4double GetTotalCrossSection(G4double energy) const
Returns total cross section at the given energy.
G4double fIntrinsicHighEnergyLimit
const G4ThreeVector & GetMomentumDirection() const
void GenerateParticles(std::vector< G4DynamicParticle *> *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
static G4EmParameters * Instance()
G4double GetHardCrossSection(G4double energy) const
Returns hard cross section at the given energy.
size_t GetTableSize() const
static G4Electron * Electron()
G4ParticleDefinition * GetDefinition() const
G4VAtomDeexcitation * AtomDeexcitation()
virtual G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy)
const G4ParticleDefinition * fParticle
G4double BindingEnergy() const
void SetDeexcitationFlag(G4bool val)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
const G4String & GetName() const
G4double GetAtomsPerMolecule(const G4Material *)
Returns the total number of atoms per molecule.
G4PenelopeIonisationModel(const G4ParticleDefinition *p=0, const G4String &processName="PenIoni")
void SampleFinalStatePositron(const G4Material *, G4double cutEnergy, G4double kineticEnergy)
static G4AtomicTransitionManager * Instance()
const G4String & PIXEElectronCrossSectionModel()
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double, G4double, G4double, G4double, G4double)
static G4Gamma * Definition()