Geant4 11.3.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4PEEffectFluoModel.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// -------------------------------------------------------------------
28//
29// GEANT4 Class file
30//
31//
32// File name: G4PEEffectFluoModel
33//
34// Author: Vladimir Ivanchenko on base of G4PEEffectModel
35//
36// Creation date: 13.06.2010
37//
38// Modifications:
39//
40// Class Description:
41// Implementation of the photo-electric effect with deexcitation
42//
43// -------------------------------------------------------------------
44//
45//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
46//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
47
50#include "G4SystemOfUnits.hh"
51#include "G4Electron.hh"
52#include "G4Gamma.hh"
53#include "Randomize.hh"
54#include "G4Material.hh"
55#include "G4DataVector.hh"
58#include "G4LossTableManager.hh"
60
61//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
62
63using namespace std;
64
66 : G4VEmModel(nam)
67{
68 theGamma = G4Gamma::Gamma();
69 theElectron = G4Electron::Electron();
70 fminimalEnergy = 1.0*CLHEP::eV;
72
73 fSandiaCof.resize(4,0.0);
74
75 // default generator
77}
78
79//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
80
82
83//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
84
86 const G4DataVector&)
87{
88 fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
90 if(nullptr == fParticleChange) {
91 fParticleChange = GetParticleChangeForGamma();
92 }
93 std::size_t nmat = G4Material::GetNumberOfMaterials();
94 fMatEnergyTh.resize(nmat, 0.0);
95 for(std::size_t i=0; i<nmat; ++i) {
96 fMatEnergyTh[i] = (*(G4Material::GetMaterialTable()))[i]
97 ->GetSandiaTable()->GetSandiaCofForMaterial(0, 0);
98 //G4cout << "G4PEEffectFluoModel::Initialise Eth(eV)= "
99 // << fMatEnergyTh[i]/eV << G4endl;
100 }
101}
102
103//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
104
107 G4double energy,
110{
111 // This method may be used only if G4MaterialCutsCouple pointer
112 // has been set properly
114 ->GetSandiaTable()->GetSandiaCofPerAtom((G4int)Z, energy, fSandiaCof);
115
116 G4double x1 = 1 / energy;
117
118 return x1 * (fSandiaCof[0] + x1 * (fSandiaCof[1] +
119 x1 * (fSandiaCof[2] + x1 * fSandiaCof[3])));
120}
121
122//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
123
127 G4double energy,
129{
130 // This method may be used only if G4MaterialCutsCouple pointer
131 // has been set properly
132 energy = std::max(energy, fMatEnergyTh[material->GetIndex()]);
133 const G4double* SandiaCof =
134 material->GetSandiaTable()->GetSandiaCofForMaterial(energy);
135
136 G4double x1 = 1 / energy;
137
138 return x1 * (SandiaCof[0] + x1 * (SandiaCof[1] +
139 x1 * (SandiaCof[2] + x1 * SandiaCof[3])));
140}
141
142//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
143
144void
145G4PEEffectFluoModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
146 const G4MaterialCutsCouple* couple,
147 const G4DynamicParticle* aDynamicPhoton,
148 G4double,
149 G4double)
150{
151 SetCurrentCouple(couple);
152 const G4Material* aMaterial = couple->GetMaterial();
153
154 G4double energy = aDynamicPhoton->GetKineticEnergy();
155
156 // select randomly one element constituing the material.
157 const G4Element* anElement = SelectRandomAtom(aMaterial,theGamma,energy);
158
159 //
160 // Photo electron
161 //
162
163 // Select atomic shell
164 G4int nShells = anElement->GetNbOfAtomicShells();
165 G4int i = 0;
166 for(; i<nShells; ++i) {
167 /*
168 G4cout << "i= " << i << " E(eV)= " << energy/eV
169 << " Eb(eV)= " << anElement->GetAtomicShell(i)/eV
170 << " " << anElement->GetName()
171 << G4endl;
172 */
173 if(energy >= anElement->GetAtomicShell(i)) { break; }
174 }
175
176 G4double edep = energy;
177
178 // photo-electron is not sampled if shell is not found or
179 // the flag of photoeffect is "false" and shell is no K
180 if ( (fPEBelowKShell || 0 == i) && i < nShells ) {
181
182 G4double bindingEnergy = anElement->GetAtomicShell(i);
183 edep = bindingEnergy;
184 G4double esec = 0.0;
185
186 // sample deexcitation cascade
187 //
188 if(nullptr != fAtomDeexcitation) {
189 G4int index = couple->GetIndex();
190 if(fAtomDeexcitation->CheckDeexcitationActiveRegion(index)) {
191 G4int Z = G4lrint(anElement->GetZ());
192 auto as = (G4AtomicShellEnumerator)(i);
193 const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
194 G4double eshell = shell->BindingEnergy();
195 if(eshell > bindingEnergy && eshell <= energy) {
196 bindingEnergy = eshell;
197 edep = eshell;
198 }
199 std::size_t nbefore = fvect->size();
200 fAtomDeexcitation->GenerateParticles(fvect, shell, Z, index);
201 std::size_t nafter = fvect->size();
202 for (std::size_t j=nbefore; j<nafter; ++j) {
203 G4double e = ((*fvect)[j])->GetKineticEnergy();
204 if(esec + e > edep) {
205 // correct energy in order to have energy balance
206 e = edep - esec;
207 ((*fvect)[j])->SetKineticEnergy(e);
208 esec += e;
209 /*
210 G4cout << "### G4PEffectFluoModel Edep(eV)= " << edep/eV
211 << " Esec(eV)= " << esec/eV
212 << " E["<< j << "](eV)= " << e/eV
213 << " N= " << nafter
214 << " Z= " << Z << " shell= " << i
215 << " Ebind(keV)= " << bindingEnergy/keV
216 << " Eshell(keV)= " << shell->BindingEnergy()/keV
217 << G4endl;
218 */
219 // delete the rest of secondaries (should not happens)
220 for (std::size_t jj=nafter-1; jj>j; --jj) {
221 delete (*fvect)[jj];
222 fvect->pop_back();
223 }
224 break;
225 }
226 esec += e;
227 }
228 edep -= esec;
229 }
230 }
231 // create photo electron
232 //
233 G4double elecKineEnergy = energy - bindingEnergy;
234 if (elecKineEnergy > fminimalEnergy) {
235 auto aParticle = new G4DynamicParticle(theElectron,
236 GetAngularDistribution()->SampleDirection(aDynamicPhoton,
237 elecKineEnergy,
238 i, couple->GetMaterial()),
239 elecKineEnergy);
240 fvect->push_back(aParticle);
241 } else {
242 edep += elecKineEnergy;
243 elecKineEnergy = 0.0;
244 }
245 if(std::abs(energy - elecKineEnergy - esec - edep) > CLHEP::eV) {
246 G4cout << "### G4PEffectFluoModel dE(eV)= "
247 << (energy - elecKineEnergy - esec - edep)/eV
248 << " shell= " << i
249 << " E(keV)= " << energy/keV
250 << " Ebind(keV)= " << bindingEnergy/keV
251 << " Ee(keV)= " << elecKineEnergy/keV
252 << " Esec(keV)= " << esec/keV
253 << " Edep(keV)= " << edep/keV
254 << G4endl;
255 }
256 }
257
258 // kill primary photon
259 fParticleChange->SetProposedKineticEnergy(0.);
260 fParticleChange->ProposeTrackStatus(fStopAndKill);
261 if(edep > 0.0) {
262 fParticleChange->ProposeLocalEnergyDeposit(edep);
263 }
264}
265
266//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@ fStopAndKill
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4double BindingEnergy() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition G4Electron.cc:91
G4double GetZ() const
Definition G4Element.hh:119
G4int GetNbOfAtomicShells() const
Definition G4Element.hh:134
G4double GetAtomicShell(G4int index) const
Definition G4Element.cc:358
static G4EmParameters * Instance()
G4bool PhotoeffectBelowKShell() const
static G4Gamma * Gamma()
Definition G4Gamma.cc:81
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
G4SandiaTable * GetSandiaTable() const
static std::size_t GetNumberOfMaterials()
std::size_t GetIndex() const
static G4MaterialTable * GetMaterialTable()
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
~G4PEEffectFluoModel() override
G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy) override
G4PEEffectFluoModel(const G4String &nam="PhotoElectric")
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A, G4double, G4double) override
G4double GetSandiaCofForMaterial(G4int, G4int) const
void GetSandiaCofPerAtom(G4int Z, G4double energy, std::vector< G4double > &coeff) const
G4VEmAngularDistribution * GetAngularDistribution()
G4ParticleChangeForGamma * GetParticleChangeForGamma()
void SetCurrentCouple(const G4MaterialCutsCouple *)
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void SetDeexcitationFlag(G4bool val)
G4VEmModel(const G4String &nam)
Definition G4VEmModel.cc:67
void SetAngularDistribution(G4VEmAngularDistribution *)
const G4MaterialCutsCouple * CurrentCouple() const
int G4lrint(double ad)
Definition templates.hh:134