Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Protected Attributes
G4PenelopeComptonModel Class Reference

#include <G4PenelopeComptonModel.hh>

Inheritance diagram for G4PenelopeComptonModel:
G4VEmModel

Public Member Functions

 G4PenelopeComptonModel (const G4ParticleDefinition *p=0, const G4String &processName="PenCompton")
 
virtual ~G4PenelopeComptonModel ()
 
virtual void Initialise (const G4ParticleDefinition *, const G4DataVector &)
 
virtual void InitialiseLocal (const G4ParticleDefinition *, G4VEmModel *masterModel)
 
virtual G4double CrossSectionPerVolume (const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
virtual G4double ComputeCrossSectionPerAtom (const G4ParticleDefinition *, G4double, G4double, G4double, G4double, G4double)
 
virtual void SampleSecondaries (std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
 
void SetVerbosityLevel (G4int lev)
 
G4int GetVerbosityLevel ()
 
- Public Member Functions inherited from G4VEmModel
 G4VEmModel (const G4String &nam)
 
virtual ~G4VEmModel ()
 
virtual void InitialiseForMaterial (const G4ParticleDefinition *, const G4Material *)
 
virtual void InitialiseForElement (const G4ParticleDefinition *, G4int Z)
 
virtual G4double ComputeDEDXPerVolume (const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=DBL_MAX)
 
virtual G4double ChargeSquareRatio (const G4Track &)
 
virtual G4double GetChargeSquareRatio (const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
 
virtual G4double GetParticleCharge (const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
 
virtual void StartTracking (G4Track *)
 
virtual void CorrectionsAlongStep (const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double &eloss, G4double &niel, G4double length)
 
virtual G4double Value (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy)
 
virtual G4double MinPrimaryEnergy (const G4Material *, const G4ParticleDefinition *, G4double cut=0.0)
 
virtual G4double MinEnergyCut (const G4ParticleDefinition *, const G4MaterialCutsCouple *)
 
virtual void SetupForMaterial (const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
 
virtual void DefineForRegion (const G4Region *)
 
void InitialiseElementSelectors (const G4ParticleDefinition *, const G4DataVector &)
 
std::vector
< G4EmElementSelector * > * 
GetElementSelectors ()
 
void SetElementSelectors (std::vector< G4EmElementSelector * > *)
 
G4double ComputeDEDX (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=DBL_MAX)
 
G4double CrossSection (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
G4double ComputeMeanFreePath (const G4ParticleDefinition *, G4double kineticEnergy, const G4Material *, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
G4double ComputeCrossSectionPerAtom (const G4ParticleDefinition *, const G4Element *, G4double kinEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
G4int SelectIsotopeNumber (const G4Element *)
 
const G4ElementSelectRandomAtom (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
const G4ElementSelectRandomAtom (const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
G4int SelectRandomAtomNumber (const G4Material *)
 
void SetParticleChange (G4VParticleChange *, G4VEmFluctuationModel *f=0)
 
void SetCrossSectionTable (G4PhysicsTable *, G4bool isLocal)
 
G4ElementDataGetElementData ()
 
G4PhysicsTableGetCrossSectionTable ()
 
G4VEmFluctuationModelGetModelOfFluctuations ()
 
G4VEmAngularDistributionGetAngularDistribution ()
 
void SetAngularDistribution (G4VEmAngularDistribution *)
 
G4double HighEnergyLimit () const
 
G4double LowEnergyLimit () const
 
G4double HighEnergyActivationLimit () const
 
G4double LowEnergyActivationLimit () const
 
G4double PolarAngleLimit () const
 
G4double SecondaryThreshold () const
 
G4bool LPMFlag () const
 
G4bool DeexcitationFlag () const
 
G4bool ForceBuildTableFlag () const
 
G4bool UseAngularGeneratorFlag () const
 
void SetAngularGeneratorFlag (G4bool)
 
void SetHighEnergyLimit (G4double)
 
void SetLowEnergyLimit (G4double)
 
void SetActivationHighEnergyLimit (G4double)
 
void SetActivationLowEnergyLimit (G4double)
 
G4bool IsActive (G4double kinEnergy)
 
void SetPolarAngleLimit (G4double)
 
void SetSecondaryThreshold (G4double)
 
void SetLPMFlag (G4bool val)
 
void SetDeexcitationFlag (G4bool val)
 
void SetForceBuildTable (G4bool val)
 
void SetMasterThread (G4bool val)
 
G4bool IsMaster () const
 
G4double MaxSecondaryKinEnergy (const G4DynamicParticle *dynParticle)
 
const G4StringGetName () const
 
void SetCurrentCouple (const G4MaterialCutsCouple *)
 
const G4ElementGetCurrentElement () const
 

Protected Attributes

G4ParticleChangeForGammafParticleChange
 
const G4ParticleDefinitionfParticle
 
- Protected Attributes inherited from G4VEmModel
G4ElementDatafElementData
 
G4VParticleChangepParticleChange
 
G4PhysicsTablexSectionTable
 
const std::vector< G4double > * theDensityFactor
 
const std::vector< G4int > * theDensityIdx
 
size_t idxTable
 

Additional Inherited Members

- Protected Member Functions inherited from G4VEmModel
G4ParticleChangeForLossGetParticleChangeForLoss ()
 
G4ParticleChangeForGammaGetParticleChangeForGamma ()
 
virtual G4double MaxSecondaryEnergy (const G4ParticleDefinition *, G4double kineticEnergy)
 
const G4MaterialCutsCoupleCurrentCouple () const
 
void SetCurrentElement (const G4Element *)
 

Detailed Description

Definition at line 63 of file G4PenelopeComptonModel.hh.

Constructor & Destructor Documentation

G4PenelopeComptonModel::G4PenelopeComptonModel ( const G4ParticleDefinition p = 0,
const G4String processName = "PenCompton" 
)

Definition at line 62 of file G4PenelopeComptonModel.cc.

References python.hepunit::eV, G4PenelopeOscillatorManager::GetOscillatorManager(), python.hepunit::GeV, G4AtomicTransitionManager::Instance(), G4VEmModel::SetDeexcitationFlag(), and G4VEmModel::SetHighEnergyLimit().

65  isInitialised(false),fAtomDeexcitation(0),
66  oscManager(0)
67 {
68  fIntrinsicLowEnergyLimit = 100.0*eV;
69  fIntrinsicHighEnergyLimit = 100.0*GeV;
70  // SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
71  SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
72  //
74 
75  if (part)
76  SetParticle(part);
77 
78  verboseLevel= 0;
79  // Verbosity scale:
80  // 0 = nothing
81  // 1 = warning for energy non-conservation
82  // 2 = details of energy budget
83  // 3 = calculation of cross sections, file openings, sampling of atoms
84  // 4 = entering in methods
85 
86  //Mark this model as "applicable" for atomic deexcitation
87  SetDeexcitationFlag(true);
88 
89  fTransitionManager = G4AtomicTransitionManager::Instance();
90 }
G4VEmModel(const G4String &nam)
Definition: G4VEmModel.cc:65
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:683
static G4PenelopeOscillatorManager * GetOscillatorManager()
G4ParticleChangeForGamma * fParticleChange
const G4ParticleDefinition * fParticle
void SetDeexcitationFlag(G4bool val)
Definition: G4VEmModel.hh:739
static G4AtomicTransitionManager * Instance()
G4PenelopeComptonModel::~G4PenelopeComptonModel ( )
virtual

Definition at line 94 of file G4PenelopeComptonModel.cc.

95 {;}

Member Function Documentation

G4double G4PenelopeComptonModel::ComputeCrossSectionPerAtom ( const G4ParticleDefinition ,
G4double  ,
G4double  ,
G4double  ,
G4double  ,
G4double   
)
virtual

Reimplemented from G4VEmModel.

Definition at line 234 of file G4PenelopeComptonModel.cc.

References G4cout, and G4endl.

240 {
241  G4cout << "*** G4PenelopeComptonModel -- WARNING ***" << G4endl;
242  G4cout << "Penelope Compton model v2008 does not calculate cross section _per atom_ " << G4endl;
243  G4cout << "so the result is always zero. For physics values, please invoke " << G4endl;
244  G4cout << "GetCrossSectionPerVolume() or GetMeanFreePath() via the G4EmCalculator" << G4endl;
245  return 0;
246 }
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61
G4double G4PenelopeComptonModel::CrossSectionPerVolume ( const G4Material material,
const G4ParticleDefinition p,
G4double  kineticEnergy,
G4double  cutEnergy = 0.0,
G4double  maxEnergy = DBL_MAX 
)
virtual

Reimplemented from G4VEmModel.

Definition at line 164 of file G4PenelopeComptonModel.cc.

References python.hepunit::classic_electr_radius, G4cout, G4endl, G4PenelopeOscillatorManager::GetAtomsPerMolecule(), G4Material::GetName(), G4PenelopeOscillatorManager::GetOscillatorTableCompton(), G4Material::GetTotNbOfAtomsPerVolume(), python.hepunit::keV, python.hepunit::MeV, python.hepunit::mm, python.hepunit::pi, and G4VEmModel::SetupForMaterial().

169 {
170  // Penelope model v2008 to calculate the Compton scattering cross section:
171  // D. Brusa et al., Nucl. Instrum. Meth. A 379 (1996) 167
172  //
173  // The cross section for Compton scattering is calculated according to the Klein-Nishina
174  // formula for energy > 5 MeV.
175  // For E < 5 MeV it is used a parametrization for the differential cross-section dSigma/dOmega,
176  // which is integrated numerically in cos(theta), G4PenelopeComptonModel::DifferentialCrossSection().
177  // The parametrization includes the J(p)
178  // distribution profiles for the atomic shells, that are tabulated from Hartree-Fock calculations
179  // from F. Biggs et al., At. Data Nucl. Data Tables 16 (1975) 201
180  //
181  if (verboseLevel > 3)
182  G4cout << "Calling CrossSectionPerVolume() of G4PenelopeComptonModel" << G4endl;
183  SetupForMaterial(p, material, energy);
184 
185  //Retrieve the oscillator table for this material
186  G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material);
187 
188  G4double cs = 0;
189 
190  if (energy < 5*MeV) //explicit calculation for E < 5 MeV
191  {
192  size_t numberOfOscillators = theTable->size();
193  for (size_t i=0;i<numberOfOscillators;i++)
194  {
195  G4PenelopeOscillator* theOsc = (*theTable)[i];
196  //sum contributions coming from each oscillator
197  cs += OscillatorTotalCrossSection(energy,theOsc);
198  }
199  }
200  else //use Klein-Nishina for E>5 MeV
201  cs = KleinNishinaCrossSection(energy,material);
202 
203  //cross sections are in units of pi*classic_electr_radius^2
205 
206  //Now, cs is the cross section *per molecule*, let's calculate the
207  //cross section per volume
208 
209  G4double atomDensity = material->GetTotNbOfAtomsPerVolume();
210  G4double atPerMol = oscManager->GetAtomsPerMolecule(material);
211 
212  if (verboseLevel > 3)
213  G4cout << "Material " << material->GetName() << " has " << atPerMol <<
214  "atoms per molecule" << G4endl;
215 
216  G4double moleculeDensity = 0.;
217 
218  if (atPerMol)
219  moleculeDensity = atomDensity/atPerMol;
220 
221  G4double csvolume = cs*moleculeDensity;
222 
223  if (verboseLevel > 2)
224  G4cout << "Compton mean free path at " << energy/keV << " keV for material " <<
225  material->GetName() << " = " << (1./csvolume)/mm << " mm" << G4endl;
226  return csvolume;
227 }
const G4String & GetName() const
Definition: G4Material.hh:176
virtual void SetupForMaterial(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
Definition: G4VEmModel.cc:380
G4PenelopeOscillatorTable * GetOscillatorTableCompton(const G4Material *)
double precision function energy(A, Z)
Definition: dpm25nuc6.f:4106
G4GLOB_DLL std::ostream G4cout
G4double GetTotNbOfAtomsPerVolume() const
Definition: G4Material.hh:207
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4double GetAtomsPerMolecule(const G4Material *)
Returns the total number of atoms per molecule.
G4int G4PenelopeComptonModel::GetVerbosityLevel ( )
inline

Definition at line 100 of file G4PenelopeComptonModel.hh.

100 {return verboseLevel;};
void G4PenelopeComptonModel::Initialise ( const G4ParticleDefinition part,
const G4DataVector  
)
virtual

Implements G4VEmModel.

Definition at line 99 of file G4PenelopeComptonModel.cc.

References G4LossTableManager::AtomDeexcitation(), fParticle, fParticleChange, G4cout, G4endl, G4VEmModel::GetParticleChangeForGamma(), python.hepunit::GeV, G4VEmModel::HighEnergyLimit(), G4LossTableManager::Instance(), G4VEmModel::IsMaster(), python.hepunit::keV, and G4VEmModel::LowEnergyLimit().

101 {
102  if (verboseLevel > 3)
103  G4cout << "Calling G4PenelopeComptonModel::Initialise()" << G4endl;
104 
105  fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
106  //Issue warning if the AtomicDeexcitation has not been declared
107  if (!fAtomDeexcitation)
108  {
109  G4cout << G4endl;
110  G4cout << "WARNING from G4PenelopeComptonModel " << G4endl;
111  G4cout << "Atomic de-excitation module is not instantiated, so there will not be ";
112  G4cout << "any fluorescence/Auger emission." << G4endl;
113  G4cout << "Please make sure this is intended" << G4endl;
114  }
115 
116  SetParticle(part);
117 
118  if (IsMaster() && part == fParticle)
119  {
120 
121  if (verboseLevel > 0)
122  {
123  G4cout << "Penelope Compton model v2008 is initialized " << G4endl
124  << "Energy range: "
125  << LowEnergyLimit() / keV << " keV - "
126  << HighEnergyLimit() / GeV << " GeV";
127  }
128  }
129 
130  if(isInitialised) return;
132  isInitialised = true;
133 
134 }
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:599
static G4LossTableManager * Instance()
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:592
G4bool IsMaster() const
Definition: G4VEmModel.hh:676
G4GLOB_DLL std::ostream G4cout
G4ParticleChangeForGamma * fParticleChange
const G4ParticleDefinition * fParticle
#define G4endl
Definition: G4ios.hh:61
G4VAtomDeexcitation * AtomDeexcitation()
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:121
void G4PenelopeComptonModel::InitialiseLocal ( const G4ParticleDefinition part,
G4VEmModel masterModel 
)
virtual

Reimplemented from G4VEmModel.

Definition at line 138 of file G4PenelopeComptonModel.cc.

References fParticle, G4cout, and G4endl.

140 {
141  if (verboseLevel > 3)
142  G4cout << "Calling G4PenelopeComptonModel::InitialiseLocal()" << G4endl;
143 
144  //
145  //Check that particle matches: one might have multiple master models (e.g.
146  //for e+ and e-).
147  //
148  if (part == fParticle)
149  {
150  //Get the const table pointers from the master to the workers
151  const G4PenelopeComptonModel* theModel =
152  static_cast<G4PenelopeComptonModel*> (masterModel);
153 
154  //Same verbosity for all workers, as the master
155  verboseLevel = theModel->verboseLevel;
156  }
157 
158  return;
159 }
G4GLOB_DLL std::ostream G4cout
const G4ParticleDefinition * fParticle
#define G4endl
Definition: G4ios.hh:61
void G4PenelopeComptonModel::SampleSecondaries ( std::vector< G4DynamicParticle * > *  fvect,
const G4MaterialCutsCouple couple,
const G4DynamicParticle aDynamicGamma,
G4double  tmin,
G4double  maxEnergy 
)
virtual

Implements G4VEmModel.

Definition at line 250 of file G4PenelopeComptonModel.cc.

References G4InuclSpecialFunctions::bindingEnergy(), G4AtomicShell::BindingEnergy(), G4VAtomDeexcitation::CheckDeexcitationActiveRegion(), G4Electron::Definition(), G4Gamma::Definition(), G4InuclParticleNames::electron, G4Electron::Electron(), python.hepunit::electron_mass_c2, python.hepunit::eV, fParticleChange, fStopAndKill, G4cout, G4endl, G4UniformRand, G4VAtomDeexcitation::GenerateParticles(), G4MaterialCutsCouple::GetIndex(), G4DynamicParticle::GetKineticEnergy(), G4MaterialCutsCouple::GetMaterial(), G4DynamicParticle::GetMomentumDirection(), G4PenelopeOscillatorManager::GetOscillatorTableCompton(), G4PenelopeOscillatorManager::GetTotalZ(), python.hepunit::keV, eplot::material, G4INCL::Math::max(), python.hepunit::MeV, G4INCL::Math::min(), nmax, python.hepunit::pi, G4VParticleChange::ProposeLocalEnergyDeposit(), G4ParticleChangeForGamma::ProposeMomentumDirection(), G4VParticleChange::ProposeTrackStatus(), CLHEP::Hep3Vector::rotateUz(), G4InuclParticleNames::s0, G4ParticleChangeForGamma::SetProposedKineticEnergy(), G4AtomicTransitionManager::Shell(), and python.hepunit::twopi.

255 {
256 
257  // Penelope model v2008 to sample the Compton scattering final state.
258  // D. Brusa et al., Nucl. Instrum. Meth. A 379 (1996) 167
259  // The model determines also the original shell from which the electron is expelled,
260  // in order to produce fluorescence de-excitation (from G4DeexcitationManager)
261  //
262  // The final state for Compton scattering is calculated according to the Klein-Nishina
263  // formula for energy > 5 MeV. In this case, the Doppler broadening is negligible and
264  // one can assume that the target electron is at rest.
265  // For E < 5 MeV it is used the parametrization for the differential cross-section dSigma/dOmega,
266  // to sample the scattering angle and the energy of the emerging electron, which is
267  // G4PenelopeComptonModel::DifferentialCrossSection(). The rejection method is
268  // used to sample cos(theta). The efficiency increases monotonically with photon energy and is
269  // nearly independent on the Z; typical values are 35%, 80% and 95% for 1 keV, 1 MeV and 10 MeV,
270  // respectively.
271  // The parametrization includes the J(p) distribution profiles for the atomic shells, that are
272  // tabulated
273  // from Hartree-Fock calculations from F. Biggs et al., At. Data Nucl. Data Tables 16 (1975) 201.
274  // Doppler broadening is included.
275  //
276 
277  if (verboseLevel > 3)
278  G4cout << "Calling SampleSecondaries() of G4PenelopeComptonModel" << G4endl;
279 
280  G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy();
281 
282  if (photonEnergy0 <= fIntrinsicLowEnergyLimit)
283  {
287  return ;
288  }
289 
290  G4ParticleMomentum photonDirection0 = aDynamicGamma->GetMomentumDirection();
291  const G4Material* material = couple->GetMaterial();
292 
293  G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableCompton(material);
294 
295  const G4int nmax = 64;
296  G4double rn[nmax]={0.0};
297  G4double pac[nmax]={0.0};
298 
299  G4double S=0.0;
300  G4double epsilon = 0.0;
301  G4double cosTheta = 1.0;
302  G4double hartreeFunc = 0.0;
303  G4double oscStren = 0.0;
304  size_t numberOfOscillators = theTable->size();
305  size_t targetOscillator = 0;
306  G4double ionEnergy = 0.0*eV;
307 
308  G4double ek = photonEnergy0/electron_mass_c2;
309  G4double ek2 = 2.*ek+1.0;
310  G4double eks = ek*ek;
311  G4double ek1 = eks-ek2-1.0;
312 
313  G4double taumin = 1.0/ek2;
314  G4double a1 = std::log(ek2);
315  G4double a2 = a1+2.0*ek*(1.0+ek)/(ek2*ek2);
316 
317  G4double TST = 0;
318  G4double tau = 0.;
319 
320  //If the incoming photon is above 5 MeV, the quicker approach based on the
321  //pure Klein-Nishina formula is used
322  if (photonEnergy0 > 5*MeV)
323  {
324  do{
325  do{
326  if ((a2*G4UniformRand()) < a1)
327  tau = std::pow(taumin,G4UniformRand());
328  else
329  tau = std::sqrt(1.0+G4UniformRand()*(taumin*taumin-1.0));
330  //rejection function
331  TST = (1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
332  }while (G4UniformRand()> TST);
333  epsilon=tau;
334  cosTheta = 1.0 - (1.0-tau)/(ek*tau);
335 
336  //Target shell electrons
337  TST = oscManager->GetTotalZ(material)*G4UniformRand();
338  targetOscillator = numberOfOscillators-1; //last level
339  S=0.0;
340  G4bool levelFound = false;
341  for (size_t j=0;j<numberOfOscillators && !levelFound; j++)
342  {
343  S += (*theTable)[j]->GetOscillatorStrength();
344  if (S > TST)
345  {
346  targetOscillator = j;
347  levelFound = true;
348  }
349  }
350  //check whether the level is valid
351  ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
352  }while((epsilon*photonEnergy0-photonEnergy0+ionEnergy) >0);
353  }
354  else //photonEnergy0 < 5 MeV
355  {
356  //Incoherent scattering function for theta=PI
357  G4double s0=0.0;
358  G4double pzomc=0.0;
359  G4double rni=0.0;
360  G4double aux=0.0;
361  for (size_t i=0;i<numberOfOscillators;i++)
362  {
363  ionEnergy = (*theTable)[i]->GetIonisationEnergy();
364  if (photonEnergy0 > ionEnergy)
365  {
366  G4double aux2 = photonEnergy0*(photonEnergy0-ionEnergy)*2.0;
367  hartreeFunc = (*theTable)[i]->GetHartreeFactor();
368  oscStren = (*theTable)[i]->GetOscillatorStrength();
369  pzomc = hartreeFunc*(aux2-electron_mass_c2*ionEnergy)/
370  (electron_mass_c2*std::sqrt(2.0*aux2+ionEnergy*ionEnergy));
371  if (pzomc > 0)
372  rni = 1.0-0.5*std::exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
373  (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
374  else
375  rni = 0.5*std::exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
376  (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
377  s0 += oscStren*rni;
378  }
379  }
380  //Sampling tau
381  G4double cdt1 = 0.;
382  do
383  {
384  if ((G4UniformRand()*a2) < a1)
385  tau = std::pow(taumin,G4UniformRand());
386  else
387  tau = std::sqrt(1.0+G4UniformRand()*(taumin*taumin-1.0));
388  cdt1 = (1.0-tau)/(ek*tau);
389  //Incoherent scattering function
390  S = 0.;
391  for (size_t i=0;i<numberOfOscillators;i++)
392  {
393  ionEnergy = (*theTable)[i]->GetIonisationEnergy();
394  if (photonEnergy0 > ionEnergy) //sum only on excitable levels
395  {
396  aux = photonEnergy0*(photonEnergy0-ionEnergy)*cdt1;
397  hartreeFunc = (*theTable)[i]->GetHartreeFactor();
398  oscStren = (*theTable)[i]->GetOscillatorStrength();
399  pzomc = hartreeFunc*(aux-electron_mass_c2*ionEnergy)/
400  (electron_mass_c2*std::sqrt(2.0*aux+ionEnergy*ionEnergy));
401  if (pzomc > 0)
402  rn[i] = 1.0-0.5*std::exp(0.5-(std::sqrt(0.5)+std::sqrt(2.0)*pzomc)*
403  (std::sqrt(0.5)+std::sqrt(2.0)*pzomc));
404  else
405  rn[i] = 0.5*std::exp(0.5-(std::sqrt(0.5)-std::sqrt(2.0)*pzomc)*
406  (std::sqrt(0.5)-std::sqrt(2.0)*pzomc));
407  S += oscStren*rn[i];
408  pac[i] = S;
409  }
410  else
411  pac[i] = S-1e-6;
412  }
413  //Rejection function
414  TST = S*(1.0+tau*(ek1+tau*(ek2+tau*eks)))/(eks*tau*(1.0+tau*tau));
415  }while ((G4UniformRand()*s0) > TST);
416 
417  cosTheta = 1.0 - cdt1;
418  G4double fpzmax=0.0,fpz=0.0;
419  G4double A=0.0;
420  //Target electron shell
421  do
422  {
423  do
424  {
425  TST = S*G4UniformRand();
426  targetOscillator = numberOfOscillators-1; //last level
427  G4bool levelFound = false;
428  for (size_t i=0;i<numberOfOscillators && !levelFound;i++)
429  {
430  if (pac[i]>TST)
431  {
432  targetOscillator = i;
433  levelFound = true;
434  }
435  }
436  A = G4UniformRand()*rn[targetOscillator];
437  hartreeFunc = (*theTable)[targetOscillator]->GetHartreeFactor();
438  oscStren = (*theTable)[targetOscillator]->GetOscillatorStrength();
439  if (A < 0.5)
440  pzomc = (std::sqrt(0.5)-std::sqrt(0.5-std::log(2.0*A)))/
441  (std::sqrt(2.0)*hartreeFunc);
442  else
443  pzomc = (std::sqrt(0.5-std::log(2.0-2.0*A))-std::sqrt(0.5))/
444  (std::sqrt(2.0)*hartreeFunc);
445  } while (pzomc < -1);
446 
447  // F(EP) rejection
448  G4double XQC = 1.0+tau*(tau-2.0*cosTheta);
449  G4double AF = std::sqrt(XQC)*(1.0+tau*(tau-cosTheta)/XQC);
450  if (AF > 0)
451  fpzmax = 1.0+AF*0.2;
452  else
453  fpzmax = 1.0-AF*0.2;
454  fpz = 1.0+AF*std::max(std::min(pzomc,0.2),-0.2);
455  }while ((fpzmax*G4UniformRand())>fpz);
456 
457  //Energy of the scattered photon
458  G4double T = pzomc*pzomc;
459  G4double b1 = 1.0-T*tau*tau;
460  G4double b2 = 1.0-T*tau*cosTheta;
461  if (pzomc > 0.0)
462  epsilon = (tau/b1)*(b2+std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
463  else
464  epsilon = (tau/b1)*(b2-std::sqrt(std::abs(b2*b2-b1*(1.0-T))));
465  } //energy < 5 MeV
466 
467  //Ok, the kinematics has been calculated.
468  G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
469  G4double phi = twopi * G4UniformRand() ;
470  G4double dirx = sinTheta * std::cos(phi);
471  G4double diry = sinTheta * std::sin(phi);
472  G4double dirz = cosTheta ;
473 
474  // Update G4VParticleChange for the scattered photon
475  G4ThreeVector photonDirection1(dirx,diry,dirz);
476  photonDirection1.rotateUz(photonDirection0);
477  fParticleChange->ProposeMomentumDirection(photonDirection1) ;
478 
479  G4double photonEnergy1 = epsilon * photonEnergy0;
480 
481  if (photonEnergy1 > 0.)
482  fParticleChange->SetProposedKineticEnergy(photonEnergy1) ;
483  else
484  {
487  }
488 
489  //Create scattered electron
490  G4double diffEnergy = photonEnergy0*(1-epsilon);
491  ionEnergy = (*theTable)[targetOscillator]->GetIonisationEnergy();
492 
493  G4double Q2 =
494  photonEnergy0*photonEnergy0+photonEnergy1*(photonEnergy1-2.0*photonEnergy0*cosTheta);
495  G4double cosThetaE = 0.; //scattering angle for the electron
496 
497  if (Q2 > 1.0e-12)
498  cosThetaE = (photonEnergy0-photonEnergy1*cosTheta)/std::sqrt(Q2);
499  else
500  cosThetaE = 1.0;
501  G4double sinThetaE = std::sqrt(1-cosThetaE*cosThetaE);
502 
503  //Now, try to handle fluorescence
504  //Notice: merged levels are indicated with Z=0 and flag=30
505  G4int shFlag = (*theTable)[targetOscillator]->GetShellFlag();
506  G4int Z = (G4int) (*theTable)[targetOscillator]->GetParentZ();
507 
508  //initialize here, then check photons created by Atomic-Deexcitation, and the final state e-
510  const G4AtomicShell* shell = 0;
511 
512  //Real level
513  if (Z > 0 && shFlag<30)
514  {
515  shell = fTransitionManager->Shell(Z,shFlag-1);
516  bindingEnergy = shell->BindingEnergy();
517  }
518 
519  G4double ionEnergyInPenelopeDatabase = ionEnergy;
520  //protection against energy non-conservation
521  ionEnergy = std::max(bindingEnergy,ionEnergyInPenelopeDatabase);
522 
523  //subtract the excitation energy. If not emitted by fluorescence
524  //the ionization energy is deposited as local energy deposition
525  G4double eKineticEnergy = diffEnergy - ionEnergy;
526  G4double localEnergyDeposit = ionEnergy;
527  G4double energyInFluorescence = 0.; //testing purposes only
528  G4double energyInAuger = 0; //testing purposes
529 
530  if (eKineticEnergy < 0)
531  {
532  //It means that there was some problem/mismatch between the two databases.
533  //Try to make it work
534  //In this case available Energy (diffEnergy) < ionEnergy
535  //Full residual energy is deposited locally
536  localEnergyDeposit = diffEnergy;
537  eKineticEnergy = 0.0;
538  }
539 
540  //the local energy deposit is what remains: part of this may be spent for fluorescence.
541  //Notice: shell might be NULL (invalid!) if shFlag=30. Must be protected
542  //Now, take care of fluorescence, if required
543  if (fAtomDeexcitation && shell)
544  {
545  G4int index = couple->GetIndex();
546  if (fAtomDeexcitation->CheckDeexcitationActiveRegion(index))
547  {
548  size_t nBefore = fvect->size();
549  fAtomDeexcitation->GenerateParticles(fvect,shell,Z,index);
550  size_t nAfter = fvect->size();
551 
552  if (nAfter > nBefore) //actual production of fluorescence
553  {
554  for (size_t j=nBefore;j<nAfter;j++) //loop on products
555  {
556  G4double itsEnergy = ((*fvect)[j])->GetKineticEnergy();
557  localEnergyDeposit -= itsEnergy;
558  if (((*fvect)[j])->GetParticleDefinition() == G4Gamma::Definition())
559  energyInFluorescence += itsEnergy;
560  else if (((*fvect)[j])->GetParticleDefinition() == G4Electron::Definition())
561  energyInAuger += itsEnergy;
562 
563  }
564  }
565 
566  }
567  }
568 
569 
570  /*
571  if(DeexcitationFlag() && Z > 5 && shellId>0) {
572 
573  const G4ProductionCutsTable* theCoupleTable=
574  G4ProductionCutsTable::GetProductionCutsTable();
575 
576  size_t index = couple->GetIndex();
577  G4double cutg = (*(theCoupleTable->GetEnergyCutsVector(0)))[index];
578  G4double cute = (*(theCoupleTable->GetEnergyCutsVector(1)))[index];
579 
580  // Generation of fluorescence
581  // Data in EADL are available only for Z > 5
582  // Protection to avoid generating photons in the unphysical case of
583  // shell binding energy > photon energy
584  if (localEnergyDeposit > cutg || localEnergyDeposit > cute)
585  {
586  G4DynamicParticle* aPhoton;
587  deexcitationManager.SetCutForSecondaryPhotons(cutg);
588  deexcitationManager.SetCutForAugerElectrons(cute);
589 
590  photonVector = deexcitationManager.GenerateParticles(Z,shellId);
591  if(photonVector)
592  {
593  size_t nPhotons = photonVector->size();
594  for (size_t k=0; k<nPhotons; k++)
595  {
596  aPhoton = (*photonVector)[k];
597  if (aPhoton)
598  {
599  G4double itsEnergy = aPhoton->GetKineticEnergy();
600  G4bool keepIt = false;
601  if (itsEnergy <= localEnergyDeposit)
602  {
603  //check if good!
604  if(aPhoton->GetDefinition() == G4Gamma::Gamma()
605  && itsEnergy >= cutg)
606  {
607  keepIt = true;
608  energyInFluorescence += itsEnergy;
609  }
610  if (aPhoton->GetDefinition() == G4Electron::Electron() &&
611  itsEnergy >= cute)
612  {
613  energyInAuger += itsEnergy;
614  keepIt = true;
615  }
616  }
617  //good secondary, register it
618  if (keepIt)
619  {
620  localEnergyDeposit -= itsEnergy;
621  fvect->push_back(aPhoton);
622  }
623  else
624  {
625  delete aPhoton;
626  (*photonVector)[k] = 0;
627  }
628  }
629  }
630  delete photonVector;
631  }
632  }
633  }
634  */
635 
636 
637  //Always produce explicitely the electron
639 
640  G4double xEl = sinThetaE * std::cos(phi+pi);
641  G4double yEl = sinThetaE * std::sin(phi+pi);
642  G4double zEl = cosThetaE;
643  G4ThreeVector eDirection(xEl,yEl,zEl); //electron direction
644  eDirection.rotateUz(photonDirection0);
645  electron = new G4DynamicParticle (G4Electron::Electron(),
646  eDirection,eKineticEnergy) ;
647  fvect->push_back(electron);
648 
649 
650  if (localEnergyDeposit < 0)
651  {
652  G4cout << "WARNING-"
653  << "G4PenelopeComptonModel::SampleSecondaries - Negative energy deposit"
654  << G4endl;
655  localEnergyDeposit=0.;
656  }
657  fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
658 
659  G4double electronEnergy = 0.;
660  if (electron)
661  electronEnergy = eKineticEnergy;
662  if (verboseLevel > 1)
663  {
664  G4cout << "-----------------------------------------------------------" << G4endl;
665  G4cout << "Energy balance from G4PenelopeCompton" << G4endl;
666  G4cout << "Incoming photon energy: " << photonEnergy0/keV << " keV" << G4endl;
667  G4cout << "-----------------------------------------------------------" << G4endl;
668  G4cout << "Scattered photon: " << photonEnergy1/keV << " keV" << G4endl;
669  G4cout << "Scattered electron " << electronEnergy/keV << " keV" << G4endl;
670  if (energyInFluorescence)
671  G4cout << "Fluorescence x-rays: " << energyInFluorescence/keV << " keV" << G4endl;
672  if (energyInAuger)
673  G4cout << "Auger electrons: " << energyInAuger/keV << " keV" << G4endl;
674  G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
675  G4cout << "Total final state: " << (photonEnergy1+electronEnergy+energyInFluorescence+
676  localEnergyDeposit+energyInAuger)/keV <<
677  " keV" << G4endl;
678  G4cout << "-----------------------------------------------------------" << G4endl;
679  }
680  if (verboseLevel > 0)
681  {
682  G4double energyDiff = std::fabs(photonEnergy1+
683  electronEnergy+energyInFluorescence+
684  localEnergyDeposit+energyInAuger-photonEnergy0);
685  if (energyDiff > 0.05*keV)
686  G4cout << "Warning from G4PenelopeCompton: problem with energy conservation: " <<
687  (photonEnergy1+electronEnergy+energyInFluorescence+energyInAuger+localEnergyDeposit)/keV <<
688  " keV (final) vs. " <<
689  photonEnergy0/keV << " keV (initial)" << G4endl;
690  }
691 }
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
G4double GetKineticEnergy() const
static G4Electron * Definition()
Definition: G4Electron.cc:49
G4double BindingEnergy() const
int G4int
Definition: G4Types.hh:78
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4PenelopeOscillatorTable * GetOscillatorTableCompton(const G4Material *)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
string material
Definition: eplot.py:19
#define G4UniformRand()
Definition: Randomize.hh:87
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
const G4ThreeVector & GetMomentumDirection() const
const G4int nmax
float electron_mass_c2
Definition: hepunit.py:274
G4ParticleChangeForGamma * fParticleChange
T max(const T t1, const T t2)
brief Return the largest of the two arguments
std::vector< G4PenelopeOscillator * > G4PenelopeOscillatorTable
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
static G4Electron * Electron()
Definition: G4Electron.cc:94
void SetProposedKineticEnergy(G4double proposedKinEnergy)
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
void ProposeTrackStatus(G4TrackStatus status)
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
G4double bindingEnergy(G4int A, G4int Z)
G4AtomicShell * Shell(G4int Z, size_t shellIndex) const
G4double GetTotalZ(const G4Material *)
static G4Gamma * Definition()
Definition: G4Gamma.cc:49
const G4Material * GetMaterial() const
void G4PenelopeComptonModel::SetVerbosityLevel ( G4int  lev)
inline

Definition at line 99 of file G4PenelopeComptonModel.hh.

99 {verboseLevel = lev;};

Field Documentation

const G4ParticleDefinition* G4PenelopeComptonModel::fParticle
protected

Definition at line 105 of file G4PenelopeComptonModel.hh.

Referenced by Initialise(), and InitialiseLocal().

G4ParticleChangeForGamma* G4PenelopeComptonModel::fParticleChange
protected

Definition at line 100 of file G4PenelopeComptonModel.hh.

Referenced by Initialise(), and SampleSecondaries().


The documentation for this class was generated from the following files: