G4PenelopePhotoElectricModel Class Reference

#include <G4PenelopePhotoElectricModel.hh>

Inheritance diagram for G4PenelopePhotoElectricModel:

G4VEmModel

Public Member Functions

 G4PenelopePhotoElectricModel (const G4ParticleDefinition *p=0, const G4String &processName="PenPhotoElec")
virtual ~G4PenelopePhotoElectricModel ()
virtual void Initialise (const G4ParticleDefinition *, const G4DataVector &)
virtual G4double ComputeCrossSectionPerAtom (const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX)
virtual void SampleSecondaries (std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
void SetVerbosityLevel (G4int lev)
G4int GetVerbosityLevel ()
size_t GetNumberOfShellXS (G4int)
G4double GetShellCrossSection (G4int Z, size_t shellID, G4double energy)

Protected Attributes

G4ParticleChangeForGammafParticleChange

Detailed Description

Definition at line 58 of file G4PenelopePhotoElectricModel.hh.


Constructor & Destructor Documentation

G4PenelopePhotoElectricModel::G4PenelopePhotoElectricModel ( const G4ParticleDefinition p = 0,
const G4String processName = "PenPhotoElec" 
)

Definition at line 60 of file G4PenelopePhotoElectricModel.cc.

References G4AtomicTransitionManager::Instance(), G4VEmModel::SetDeexcitationFlag(), and G4VEmModel::SetHighEnergyLimit().

00062   :G4VEmModel(nam),fParticleChange(0),isInitialised(false),fAtomDeexcitation(0),
00063    logAtomicShellXS(0)
00064 {
00065   fIntrinsicLowEnergyLimit = 100.0*eV;
00066   fIntrinsicHighEnergyLimit = 100.0*GeV;
00067   //  SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
00068   SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
00069   //
00070   verboseLevel= 0;
00071   // Verbosity scale:
00072   // 0 = nothing 
00073   // 1 = warning for energy non-conservation 
00074   // 2 = details of energy budget
00075   // 3 = calculation of cross sections, file openings, sampling of atoms
00076   // 4 = entering in methods
00077 
00078   //Mark this model as "applicable" for atomic deexcitation
00079   SetDeexcitationFlag(true);
00080 
00081   fTransitionManager = G4AtomicTransitionManager::Instance();
00082 }

G4PenelopePhotoElectricModel::~G4PenelopePhotoElectricModel (  )  [virtual]

Definition at line 86 of file G4PenelopePhotoElectricModel.cc.

00087 {  
00088   std::map <G4int,G4PhysicsTable*>::iterator i;
00089   if (logAtomicShellXS)
00090     {
00091       for (i=logAtomicShellXS->begin();i != logAtomicShellXS->end();i++)
00092         {
00093           G4PhysicsTable* tab = i->second;
00094           tab->clearAndDestroy();
00095           delete tab;
00096         }
00097     }
00098   delete logAtomicShellXS;
00099 }


Member Function Documentation

G4double G4PenelopePhotoElectricModel::ComputeCrossSectionPerAtom ( const G4ParticleDefinition ,
G4double  kinEnergy,
G4double  Z,
G4double  A = 0,
G4double  cut = 0,
G4double  emax = DBL_MAX 
) [virtual]

Reimplemented from G4VEmModel.

Definition at line 141 of file G4PenelopePhotoElectricModel.cc.

References FatalException, G4cout, G4endl, G4Exception(), and G4PhysicsVector::Value().

00146 {
00147   //
00148   // Penelope model v2008
00149   //
00150 
00151   if (verboseLevel > 3)
00152     G4cout << "Calling ComputeCrossSectionPerAtom() of G4PenelopePhotoElectricModel" << G4endl;
00153 
00154   G4int iZ = (G4int) Z;
00155 
00156   //read data files
00157   if (!logAtomicShellXS->count(iZ))
00158     ReadDataFile(iZ);
00159   //now it should be ok
00160   if (!logAtomicShellXS->count(iZ))     
00161     G4Exception("G4PenelopePhotoElectricModel::ComputeCrossSectionPerAtom()",
00162                 "em2038",FatalException,
00163                 "Unable to retrieve the shell cross section table");     
00164   
00165   G4double cross = 0;
00166 
00167   G4PhysicsTable* theTable =  logAtomicShellXS->find(iZ)->second;
00168   G4PhysicsFreeVector* totalXSLog = (G4PhysicsFreeVector*) (*theTable)[0];
00169 
00170    if (!totalXSLog)
00171      {
00172        G4Exception("G4PenelopePhotoElectricModel::ComputeCrossSectionPerAtom()",
00173                    "em2039",FatalException,
00174                    "Unable to retrieve the total cross section table");       
00175        return 0;
00176      }
00177    G4double logene = std::log(energy);
00178    G4double logXS = totalXSLog->Value(logene);
00179    cross = std::exp(logXS);
00180  
00181   if (verboseLevel > 2)
00182     G4cout << "Photoelectric cross section at " << energy/MeV << " MeV for Z=" << Z <<
00183       " = " << cross/barn << " barn" << G4endl;
00184   return cross;
00185 }

size_t G4PenelopePhotoElectricModel::GetNumberOfShellXS ( G4int   ) 

Definition at line 620 of file G4PenelopePhotoElectricModel.cc.

References FatalException, and G4Exception().

Referenced by GetShellCrossSection().

00621 {
00622   //read data files
00623   if (!logAtomicShellXS->count(Z))
00624     ReadDataFile(Z);
00625   //now it should be ok
00626   if (!logAtomicShellXS->count(Z))
00627      {
00628        G4ExceptionDescription ed;
00629        ed << "Cannot find shell cross section data for Z=" << Z << G4endl;
00630        G4Exception("G4PenelopePhotoElectricModel::GetNumberOfShellXS()",
00631                    "em2038",FatalException,ed);
00632      }
00633   //one vector is allocated for the _total_ cross section
00634   size_t nEntries = logAtomicShellXS->find(Z)->second->entries();
00635   return  (nEntries-1);
00636 }

G4double G4PenelopePhotoElectricModel::GetShellCrossSection ( G4int  Z,
size_t  shellID,
G4double  energy 
)

Definition at line 640 of file G4PenelopePhotoElectricModel.cc.

References FatalException, G4cout, G4Exception(), GetNumberOfShellXS(), and G4PhysicsVector::Value().

00641 {
00642   //this forces also the loading of the data
00643   size_t entries = GetNumberOfShellXS(Z);
00644 
00645   if (shellID >= entries)
00646     {
00647       G4cout << "Element Z=" << Z << " has data for " << entries << " shells only" << G4endl;
00648       G4cout << "so shellID should be from 0 to " << entries-1 << G4endl;
00649       return 0;
00650     }
00651   
00652   G4PhysicsTable* theTable =  logAtomicShellXS->find(Z)->second;
00653   //[0] is the total XS, shellID is in the element [shellID+1]
00654   G4PhysicsFreeVector* totalXSLog = (G4PhysicsFreeVector*) (*theTable)[shellID+1];
00655  
00656   if (!totalXSLog)
00657      {
00658        G4Exception("G4PenelopePhotoElectricModel::GetShellCrossSection()",
00659                    "em2039",FatalException,
00660                    "Unable to retrieve the total cross section table");
00661        return 0;
00662      }
00663    G4double logene = std::log(energy);
00664    G4double logXS = totalXSLog->Value(logene);
00665    G4double cross = std::exp(logXS);
00666    if (cross < 2e-40*cm2) cross = 0;
00667    return cross;
00668 }

G4int G4PenelopePhotoElectricModel::GetVerbosityLevel (  )  [inline]

Definition at line 85 of file G4PenelopePhotoElectricModel.hh.

00085 {return verboseLevel;};

void G4PenelopePhotoElectricModel::Initialise ( const G4ParticleDefinition ,
const G4DataVector  
) [virtual]

Implements G4VEmModel.

Definition at line 103 of file G4PenelopePhotoElectricModel.cc.

References G4LossTableManager::AtomDeexcitation(), fParticleChange, G4cout, G4endl, G4VEmModel::GetParticleChangeForGamma(), G4VEmModel::HighEnergyLimit(), G4VEmModel::InitialiseElementSelectors(), G4LossTableManager::Instance(), and G4VEmModel::LowEnergyLimit().

00105 {
00106   if (verboseLevel > 3)
00107     G4cout << "Calling  G4PenelopePhotoElectricModel::Initialise()" << G4endl;
00108 
00109   // logAtomicShellXS is created only once, since it is  never cleared
00110   if (!logAtomicShellXS)
00111     logAtomicShellXS = new std::map<G4int,G4PhysicsTable*>;
00112 
00113   InitialiseElementSelectors(particle,cuts);
00114 
00115   fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
00116   //Issue warning if the AtomicDeexcitation has not been declared
00117   if (!fAtomDeexcitation)
00118     {
00119       G4cout << G4endl;
00120       G4cout << "WARNING from G4PenelopePhotoElectricModel " << G4endl;
00121       G4cout << "Atomic de-excitation module is not instantiated, so there will not be ";
00122       G4cout << "any fluorescence/Auger emission." << G4endl;
00123       G4cout << "Please make sure this is intended" << G4endl;
00124     }
00125 
00126   if (verboseLevel > 0) { 
00127     G4cout << "Penelope Photo-Electric model v2008 is initialized " << G4endl
00128            << "Energy range: "
00129            << LowEnergyLimit() / MeV << " MeV - "
00130            << HighEnergyLimit() / GeV << " GeV";
00131   }
00132 
00133   if(isInitialised) return;
00134   fParticleChange = GetParticleChangeForGamma();
00135   isInitialised = true;
00136 
00137 }

void G4PenelopePhotoElectricModel::SampleSecondaries ( std::vector< G4DynamicParticle * > *  ,
const G4MaterialCutsCouple ,
const G4DynamicParticle ,
G4double  tmin,
G4double  maxEnergy 
) [virtual]

Implements G4VEmModel.

Definition at line 189 of file G4PenelopePhotoElectricModel.cc.

References G4AtomicShell::BindingEnergy(), G4InuclSpecialFunctions::bindingEnergy(), G4VAtomDeexcitation::CheckDeexcitationActiveRegion(), G4Electron::Definition(), G4Gamma::Definition(), G4Electron::Electron(), fParticleChange, fStopAndKill, G4cout, G4endl, G4UniformRand, G4Gamma::GammaDefinition(), G4VAtomDeexcitation::GenerateParticles(), G4MaterialCutsCouple::GetIndex(), G4DynamicParticle::GetKineticEnergy(), G4MaterialCutsCouple::GetMaterial(), G4DynamicParticle::GetMomentumDirection(), G4Element::GetName(), G4Material::GetName(), G4Element::GetZ(), G4AtomicTransitionManager::Instance(), G4AtomicTransitionManager::NumberOfShells(), G4VParticleChange::ProposeLocalEnergyDeposit(), G4VParticleChange::ProposeTrackStatus(), G4VEmModel::SelectRandomAtom(), G4ParticleChangeForGamma::SetProposedKineticEnergy(), and G4AtomicTransitionManager::Shell().

00194 {
00195   //
00196   // Photoelectric effect, Penelope model v2008
00197   //
00198   // The target atom and the target shell are sampled according to the Livermore 
00199   // database 
00200   //  D.E. Cullen et al., Report UCRL-50400 (1989)
00201   // The angular distribution of the electron in the final state is sampled 
00202   // according to the Sauter distribution from 
00203   //  F. Sauter, Ann. Phys. 11 (1931) 454
00204   // The energy of the final electron is given by the initial photon energy minus 
00205   // the binding energy. Fluorescence de-excitation is subsequently produced 
00206   // (to fill the vacancy) according to the general Geant4 G4DeexcitationManager:
00207   //  J. Stepanek, Comp. Phys. Comm. 1206 pp 1-1-9 (1997)
00208 
00209   if (verboseLevel > 3)
00210     G4cout << "Calling SamplingSecondaries() of G4PenelopePhotoElectricModel" << G4endl;
00211 
00212   G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
00213 
00214   // always kill primary
00215   fParticleChange->ProposeTrackStatus(fStopAndKill);
00216   fParticleChange->SetProposedKineticEnergy(0.);
00217 
00218   if (photonEnergy <= fIntrinsicLowEnergyLimit)
00219     {
00220       fParticleChange->ProposeLocalEnergyDeposit(photonEnergy);
00221       return ;
00222     }
00223 
00224   G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
00225 
00226   // Select randomly one element in the current material
00227   if (verboseLevel > 2)
00228     G4cout << "Going to select element in " << couple->GetMaterial()->GetName() << G4endl;
00229 
00230   // atom can be selected efficiently if element selectors are initialised
00231   const G4Element* anElement =
00232     SelectRandomAtom(couple,G4Gamma::GammaDefinition(),photonEnergy);
00233   G4int Z = (G4int) anElement->GetZ();
00234   if (verboseLevel > 2)
00235     G4cout << "Selected " << anElement->GetName() << G4endl;
00236   
00237   // Select the ionised shell in the current atom according to shell cross sections
00238   //shellIndex = 0 --> K shell
00239   //             1-3 --> L shells
00240   //             4-8 --> M shells
00241   //             9 --> outer shells cumulatively
00242   //
00243   size_t shellIndex = SelectRandomShell(Z,photonEnergy);
00244 
00245   if (verboseLevel > 2)
00246     G4cout << "Selected shell " << shellIndex << " of element " << anElement->GetName() << G4endl;
00247 
00248   // Retrieve the corresponding identifier and binding energy of the selected shell
00249   const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
00250 
00251   //The number of shell cross section possibly reported in the Penelope database 
00252   //might be different from the number of shells in the G4AtomicTransitionManager
00253   //(namely, Penelope may contain more shell, especially for very light elements).
00254   //In order to avoid a warning message from the G4AtomicTransitionManager, I 
00255   //add this protection. Results are anyway changed, because when G4AtomicTransitionManager
00256   //has a shellID>maxID, it sets the shellID to the last valid shell. 
00257   size_t numberOfShells = (size_t) transitionManager->NumberOfShells(Z);
00258   if (shellIndex >= numberOfShells)
00259     shellIndex = numberOfShells-1;
00260 
00261   const G4AtomicShell* shell = fTransitionManager->Shell(Z,shellIndex);
00262   G4double bindingEnergy = shell->BindingEnergy();
00263   //G4int shellId = shell->ShellId();
00264 
00265   //Penelope considers only K, L and M shells. Cross sections of outer shells are 
00266   //not included in the Penelope database. If SelectRandomShell() returns 
00267   //shellIndex = 9, it means that an outer shell was ionized. In this case the 
00268   //Penelope recipe is to set bindingEnergy = 0 (the energy is entirely assigned 
00269   //to the electron) and to disregard fluorescence.
00270   if (shellIndex == 9)
00271     bindingEnergy = 0.*eV;
00272 
00273 
00274   G4double localEnergyDeposit = 0.0;
00275   G4double cosTheta = 1.0;
00276 
00277   // Primary outcoming electron
00278   G4double eKineticEnergy = photonEnergy - bindingEnergy;
00279   
00280   // There may be cases where the binding energy of the selected shell is > photon energy
00281   // In such cases do not generate secondaries
00282   if (eKineticEnergy > 0.)
00283     {
00284       // The electron is created
00285       // Direction sampled from the Sauter distribution
00286       cosTheta = SampleElectronDirection(eKineticEnergy);
00287       G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
00288       G4double phi = twopi * G4UniformRand() ;
00289       G4double dirx = sinTheta * std::cos(phi);
00290       G4double diry = sinTheta * std::sin(phi);
00291       G4double dirz = cosTheta ;
00292       G4ThreeVector electronDirection(dirx,diry,dirz); //electron direction
00293       electronDirection.rotateUz(photonDirection);
00294       G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(), 
00295                                                            electronDirection, 
00296                                                            eKineticEnergy);
00297       fvect->push_back(electron);
00298     } 
00299   else    
00300     bindingEnergy = photonEnergy;
00301 
00302 
00303   G4double energyInFluorescence = 0; //testing purposes
00304   G4double energyInAuger = 0; //testing purposes
00305  
00306   //Now, take care of fluorescence, if required. According to the Penelope
00307   //recipe, I have to skip fluoresence completely if shellIndex == 9 
00308   //(= sampling of a shell outer than K,L,M)
00309   if (fAtomDeexcitation && shellIndex<9)
00310     {      
00311       G4int index = couple->GetIndex();
00312       if (fAtomDeexcitation->CheckDeexcitationActiveRegion(index))
00313         {       
00314           size_t nBefore = fvect->size();
00315           fAtomDeexcitation->GenerateParticles(fvect,shell,Z,index);
00316           size_t nAfter = fvect->size();
00317 
00318           if (nAfter > nBefore) //actual production of fluorescence
00319             {
00320               for (size_t j=nBefore;j<nAfter;j++) //loop on products
00321                 {
00322                   G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
00323                   bindingEnergy -= itsEnergy;
00324                   if (((*fvect)[j])->GetParticleDefinition() == G4Gamma::Definition())
00325                     energyInFluorescence += itsEnergy;
00326                   else if (((*fvect)[j])->GetParticleDefinition() == G4Electron::Definition())
00327                     energyInAuger += itsEnergy;
00328                   
00329                 }
00330             }
00331 
00332         }
00333     }
00334 
00335   //Residual energy is deposited locally
00336   localEnergyDeposit += bindingEnergy;
00337       
00338   if (localEnergyDeposit < 0)
00339     {
00340       G4cout << "WARNING - "
00341              << "G4PenelopePhotoElectricModel::SampleSecondaries() - Negative energy deposit"
00342              << G4endl;
00343       localEnergyDeposit = 0;
00344     }
00345 
00346   fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
00347 
00348   if (verboseLevel > 1)
00349     {
00350       G4cout << "-----------------------------------------------------------" << G4endl;
00351       G4cout << "Energy balance from G4PenelopePhotoElectric" << G4endl;
00352       G4cout << "Selected shell: " << WriteTargetShell(shellIndex) << " of element " << 
00353         anElement->GetName() << G4endl;
00354       G4cout << "Incoming photon energy: " << photonEnergy/keV << " keV" << G4endl;
00355       G4cout << "-----------------------------------------------------------" << G4endl;
00356       if (eKineticEnergy)
00357         G4cout << "Outgoing electron " << eKineticEnergy/keV << " keV" << G4endl;
00358       if (energyInFluorescence)
00359         G4cout << "Fluorescence x-rays: " << energyInFluorescence/keV << " keV" << G4endl;
00360       if (energyInAuger)
00361         G4cout << "Auger electrons: " << energyInAuger/keV << " keV" << G4endl;
00362       G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
00363       G4cout << "Total final state: " << 
00364         (eKineticEnergy+energyInFluorescence+localEnergyDeposit+energyInAuger)/keV << 
00365         " keV" << G4endl;
00366       G4cout << "-----------------------------------------------------------" << G4endl;
00367     }
00368   if (verboseLevel > 0)
00369     {
00370       G4double energyDiff = 
00371         std::fabs(eKineticEnergy+energyInFluorescence+localEnergyDeposit+energyInAuger-photonEnergy);
00372       if (energyDiff > 0.05*keV)
00373         {
00374           G4cout << "Warning from G4PenelopePhotoElectric: problem with energy conservation: " << 
00375             (eKineticEnergy+energyInFluorescence+localEnergyDeposit+energyInAuger)/keV 
00376                  << " keV (final) vs. " << 
00377             photonEnergy/keV << " keV (initial)" << G4endl;
00378           G4cout << "-----------------------------------------------------------" << G4endl;
00379           G4cout << "Energy balance from G4PenelopePhotoElectric" << G4endl;
00380           G4cout << "Selected shell: " << WriteTargetShell(shellIndex) << " of element " << 
00381             anElement->GetName() << G4endl;
00382           G4cout << "Incoming photon energy: " << photonEnergy/keV << " keV" << G4endl;
00383           G4cout << "-----------------------------------------------------------" << G4endl;
00384           if (eKineticEnergy)
00385             G4cout << "Outgoing electron " << eKineticEnergy/keV << " keV" << G4endl;
00386           if (energyInFluorescence)
00387             G4cout << "Fluorescence x-rays: " << energyInFluorescence/keV << " keV" << G4endl;
00388           if (energyInAuger)
00389             G4cout << "Auger electrons: " << energyInAuger/keV << " keV" << G4endl;
00390           G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
00391           G4cout << "Total final state: " << 
00392             (eKineticEnergy+energyInFluorescence+localEnergyDeposit+energyInAuger)/keV << 
00393             " keV" << G4endl;
00394           G4cout << "-----------------------------------------------------------" << G4endl;
00395         }
00396     }
00397 }

void G4PenelopePhotoElectricModel::SetVerbosityLevel ( G4int  lev  )  [inline]

Definition at line 84 of file G4PenelopePhotoElectricModel.hh.

00084 {verboseLevel = lev;};


Field Documentation

G4ParticleChangeForGamma* G4PenelopePhotoElectricModel::fParticleChange [protected]

Definition at line 93 of file G4PenelopePhotoElectricModel.hh.

Referenced by Initialise(), and SampleSecondaries().


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:52:53 2013 for Geant4 by  doxygen 1.4.7