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

#include <G4PenelopeRayleighModel.hh>

Inheritance diagram for G4PenelopeRayleighModel:
G4VEmModel

Public Member Functions

 G4PenelopeRayleighModel (const G4ParticleDefinition *p=0, const G4String &processName="PenRayleigh")
 
virtual ~G4PenelopeRayleighModel ()
 
virtual void Initialise (const G4ParticleDefinition *, const G4DataVector &)
 
virtual void InitialiseLocal (const G4ParticleDefinition *, G4VEmModel *masterModel)
 
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 ()
 
void DumpFormFactorTable (const G4Material *)
 
- 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 CrossSectionPerVolume (const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=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 58 of file G4PenelopeRayleighModel.hh.

Constructor & Destructor Documentation

G4PenelopeRayleighModel::G4PenelopeRayleighModel ( const G4ParticleDefinition p = 0,
const G4String processName = "PenRayleigh" 
)

Definition at line 54 of file G4PenelopeRayleighModel.cc.

References python.hepunit::eV, python.hepunit::GeV, python.hepunit::keV, and G4VEmModel::SetHighEnergyLimit().

56  :G4VEmModel(nam),fParticleChange(0),fParticle(0),isInitialised(false),
57  logAtomicCrossSection(0),atomicFormFactor(0),logFormFactorTable(0),
58  pMaxTable(0),samplingTable(0),fLocalTable(false)
59 {
60  fIntrinsicLowEnergyLimit = 100.0*eV;
61  fIntrinsicHighEnergyLimit = 100.0*GeV;
62  // SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
63  SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
64 
65  if (part)
66  SetParticle(part);
67 
68  //
69  verboseLevel= 0;
70  // Verbosity scale:
71  // 0 = nothing
72  // 1 = warning for energy non-conservation
73  // 2 = details of energy budget
74  // 3 = calculation of cross sections, file openings, sampling of atoms
75  // 4 = entering in methods
76 
77  //build the energy grid. It is the same for all materials
78  G4double logenergy = std::log(fIntrinsicLowEnergyLimit/2.);
79  G4double logmaxenergy = std::log(1.5*fIntrinsicHighEnergyLimit);
80  //finer grid below 160 keV
81  G4double logtransitionenergy = std::log(160*keV);
82  G4double logfactor1 = std::log(10.)/250.;
83  G4double logfactor2 = logfactor1*10;
84  logEnergyGridPMax.push_back(logenergy);
85  do{
86  if (logenergy < logtransitionenergy)
87  logenergy += logfactor1;
88  else
89  logenergy += logfactor2;
90  logEnergyGridPMax.push_back(logenergy);
91  }while (logenergy < logmaxenergy);
92 }
G4VEmModel(const G4String &nam)
Definition: G4VEmModel.cc:65
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:683
G4ParticleChangeForGamma * fParticleChange
double G4double
Definition: G4Types.hh:76
const G4ParticleDefinition * fParticle
G4PenelopeRayleighModel::~G4PenelopeRayleighModel ( )
virtual

Definition at line 96 of file G4PenelopeRayleighModel.cc.

References G4VEmModel::IsMaster().

97 {
98  if (IsMaster() || fLocalTable)
99  {
100  //std::map <G4int,G4PhysicsFreeVector*>::iterator i;
101  if (logAtomicCrossSection)
102  {
103  /*
104  for (i=logAtomicCrossSection->begin();i != logAtomicCrossSection->end();i++)
105  if (i->second) delete i->second;
106  */
107  delete logAtomicCrossSection;
108  logAtomicCrossSection = 0;
109  }
110  //std::map <G4int,G4PhysicsFreeVector*>::iterator i;
111  if (atomicFormFactor)
112  {
113  /*
114  for (i=atomicFormFactor->begin();i != atomicFormFactor->end();i++)
115  if (i->second) delete i->second;
116  */
117  delete atomicFormFactor;
118  atomicFormFactor = 0;
119  }
120 
121  ClearTables();
122  }
123 }
G4bool IsMaster() const
Definition: G4VEmModel.hh:676

Member Function Documentation

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

Reimplemented from G4VEmModel.

Definition at line 285 of file G4PenelopeRayleighModel.cc.

References python.hepunit::barn, FatalException, G4cout, G4endl, G4Exception(), JustWarning, python.hepunit::keV, G4TemplateAutoLock< M, L, U >::unlock(), and G4PhysicsVector::Value().

291 {
292  // Cross section of Rayleigh scattering in Penelope v2008 is calculated by the EPDL97
293  // tabulation, Cuellen et al. (1997), with non-relativistic form factors from Hubbel
294  // et al. J. Phys. Chem. Ref. Data 4 (1975) 471; Erratum ibid. 6 (1977) 615.
295 
296  if (verboseLevel > 3)
297  G4cout << "Calling CrossSectionPerAtom() of G4PenelopeRayleighModel" << G4endl;
298 
299  G4int iZ = (G4int) Z;
300 
301  //Either Initialize() was not called, or we are in a slave and InitializeLocal() was
302  //not invoked
303  if (!logAtomicCrossSection)
304  {
305  //create a **thread-local** version of the table. Used only for G4EmCalculator and
306  //Unit Tests
307  fLocalTable = true;
308  logAtomicCrossSection = new std::map<G4int,G4PhysicsFreeVector*>;
309  }
310  //now it should be ok
311  if (!logAtomicCrossSection->count(iZ))
312  {
313  //If we are here, it means that Initialize() was inkoved, but the MaterialTable was
314  //not filled up. This can happen in a UnitTest or via G4EmCalculator
315  if (verboseLevel > 0)
316  {
317  //Issue a G4Exception (warning) only in verbose mode
319  ed << "Unable to retrieve the cross section table for Z=" << iZ << G4endl;
320  ed << "This can happen only in Unit Tests or via G4EmCalculator" << G4endl;
321  G4Exception("G4PenelopeRayleighModel::ComputeCrossSectionPerAtom()",
322  "em2040",JustWarning,ed);
323  }
324  //protect file reading via autolock
325  G4AutoLock lock(&PenelopeRayleighModelMutex);
326  ReadDataFile(iZ);
327  lock.unlock();
328  }
329 
330  G4double cross = 0;
331 
332  G4PhysicsFreeVector* atom = logAtomicCrossSection->find(iZ)->second;
333  if (!atom)
334  {
336  ed << "Unable to find Z=" << iZ << " in the atomic cross section table" << G4endl;
337  G4Exception("G4PenelopeRayleighModel::ComputeCrossSectionPerAtom()",
338  "em2041",FatalException,ed);
339  return 0;
340  }
341  G4double logene = std::log(energy);
342  G4double logXS = atom->Value(logene);
343  cross = std::exp(logXS);
344 
345  if (verboseLevel > 2)
346  G4cout << "Rayleigh cross section at " << energy/keV << " keV for Z=" << Z <<
347  " = " << cross/barn << " barn" << G4endl;
348  return cross;
349 }
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
int G4int
Definition: G4Types.hh:78
double precision function energy(A, Z)
Definition: dpm25nuc6.f:4106
G4GLOB_DLL std::ostream G4cout
G4double Value(G4double theEnergy, size_t &lastidx) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
void G4PenelopeRayleighModel::DumpFormFactorTable ( const G4Material mat)

Definition at line 1335 of file G4PenelopeRayleighModel.cc.

References G4cout, G4endl, G4PhysicsVector::GetLowEdgeEnergy(), G4Material::GetName(), and G4PhysicsVector::GetVectorLength().

1336 {
1337  G4cout << "*****************************************************************" << G4endl;
1338  G4cout << "G4PenelopeRayleighModel: Form Factor Table for " << mat->GetName() << G4endl;
1339  //try to use the same format as Penelope-Fortran, namely Q (/m_e*c) and F
1340  G4cout << "Q/(m_e*c) F(Q) " << G4endl;
1341  G4cout << "*****************************************************************" << G4endl;
1342  if (!logFormFactorTable->count(mat))
1343  BuildFormFactorTable(mat);
1344 
1345  G4PhysicsFreeVector* theVec = logFormFactorTable->find(mat)->second;
1346  for (size_t i=0;i<theVec->GetVectorLength();i++)
1347  {
1348  G4double logQ2 = theVec->GetLowEdgeEnergy(i);
1349  G4double Q = std::exp(0.5*logQ2);
1350  G4double logF2 = (*theVec)[i];
1351  G4double F = std::exp(0.5*logF2);
1352  G4cout << Q << " " << F << G4endl;
1353  }
1354  //DONE
1355  return;
1356 }
const G4String & GetName() const
Definition: G4Material.hh:176
size_t GetVectorLength() const
G4double GetLowEdgeEnergy(size_t binNumber) const
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4int G4PenelopeRayleighModel::GetVerbosityLevel ( )
inline

Definition at line 85 of file G4PenelopeRayleighModel.hh.

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

Implements G4VEmModel.

Definition at line 171 of file G4PenelopeRayleighModel.cc.

References fParticle, fParticleChange, G4cout, G4endl, G4Material::GetElementVector(), G4MaterialCutsCouple::GetMaterial(), G4ProductionCutsTable::GetMaterialCutsCouple(), G4Material::GetNumberOfElements(), G4VEmModel::GetParticleChangeForGamma(), G4ProductionCutsTable::GetProductionCutsTable(), G4ProductionCutsTable::GetTableSize(), python.hepunit::GeV, G4VEmModel::HighEnergyLimit(), G4VEmModel::IsMaster(), python.hepunit::keV, G4VEmModel::LowEnergyLimit(), and eplot::material.

173 {
174  if (verboseLevel > 3)
175  G4cout << "Calling G4PenelopeRayleighModel::Initialise()" << G4endl;
176 
177  SetParticle(part);
178 
179  //Only the master model creates/fills/destroys the tables
180  if (IsMaster() && part == fParticle)
181  {
182  //clear tables depending on materials, not the atomic ones
183  ClearTables();
184 
185  //create new tables
186  //
187  // logAtomicCrossSection and atomicFormFactor are created only once,
188  // since they are never cleared
189  if (!logAtomicCrossSection)
190  logAtomicCrossSection = new std::map<G4int,G4PhysicsFreeVector*>;
191  if (!atomicFormFactor)
192  atomicFormFactor = new std::map<G4int,G4PhysicsFreeVector*>;
193 
194  if (!logFormFactorTable)
195  logFormFactorTable = new std::map<const G4Material*,G4PhysicsFreeVector*>;
196  if (!pMaxTable)
197  pMaxTable = new std::map<const G4Material*,G4PhysicsFreeVector*>;
198  if (!samplingTable)
199  samplingTable = new std::map<const G4Material*,G4PenelopeSamplingData*>;
200 
201 
202  G4ProductionCutsTable* theCoupleTable =
204 
205  for (size_t i=0;i<theCoupleTable->GetTableSize();i++)
206  {
207  const G4Material* material =
208  theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
209  const G4ElementVector* theElementVector = material->GetElementVector();
210 
211  for (size_t j=0;j<material->GetNumberOfElements();j++)
212  {
213  G4int iZ = (G4int) theElementVector->at(j)->GetZ();
214  //read data files only in the master
215  if (!logAtomicCrossSection->count(iZ))
216  ReadDataFile(iZ);
217  }
218 
219  //1) If the table has not been built for the material, do it!
220  if (!logFormFactorTable->count(material))
221  BuildFormFactorTable(material);
222 
223  //2) retrieve or build the sampling table
224  if (!(samplingTable->count(material)))
225  InitializeSamplingAlgorithm(material);
226 
227  //3) retrieve or build the pMax data
228  if (!pMaxTable->count(material))
229  GetPMaxTable(material);
230 
231  }
232 
233  if (verboseLevel > 1) {
234  G4cout << "Penelope Rayleigh model v2008 is initialized " << G4endl
235  << "Energy range: "
236  << LowEnergyLimit() / keV << " keV - "
237  << HighEnergyLimit() / GeV << " GeV"
238  << G4endl;
239  }
240  }
241 
242  if(isInitialised) return;
244  isInitialised = true;
245 }
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:599
std::vector< G4Element * > G4ElementVector
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:592
G4bool IsMaster() const
Definition: G4VEmModel.hh:676
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:188
int G4int
Definition: G4Types.hh:78
string material
Definition: eplot.py:19
G4GLOB_DLL std::ostream G4cout
static G4ProductionCutsTable * GetProductionCutsTable()
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
G4ParticleChangeForGamma * fParticleChange
#define G4endl
Definition: G4ios.hh:61
size_t GetNumberOfElements() const
Definition: G4Material.hh:184
const G4ParticleDefinition * fParticle
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:121
const G4Material * GetMaterial() const
void G4PenelopeRayleighModel::InitialiseLocal ( const G4ParticleDefinition part,
G4VEmModel masterModel 
)
virtual

Reimplemented from G4VEmModel.

Definition at line 249 of file G4PenelopeRayleighModel.cc.

References fParticle, G4cout, and G4endl.

251 {
252  if (verboseLevel > 3)
253  G4cout << "Calling G4PenelopeRayleighModel::InitialiseLocal()" << G4endl;
254 
255  //
256  //Check that particle matches: one might have multiple master models (e.g.
257  //for e+ and e-).
258  //
259  if (part == fParticle)
260  {
261  //Get the const table pointers from the master to the workers
262  const G4PenelopeRayleighModel* theModel =
263  static_cast<G4PenelopeRayleighModel*> (masterModel);
264 
265  //Copy pointers to the data tables
266  logAtomicCrossSection = theModel->logAtomicCrossSection;
267  atomicFormFactor = theModel->atomicFormFactor;
268  logFormFactorTable = theModel->logFormFactorTable;
269  pMaxTable = theModel->pMaxTable;
270  samplingTable = theModel->samplingTable;
271 
272  //copy the G4DataVector with the grid
273  logQSquareGrid = theModel->logQSquareGrid;
274 
275  //Same verbosity for all workers, as the master
276  verboseLevel = theModel->verboseLevel;
277  }
278 
279  return;
280 }
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61
const G4ParticleDefinition * fParticle
void G4PenelopeRayleighModel::SampleSecondaries ( std::vector< G4DynamicParticle * > *  ,
const G4MaterialCutsCouple couple,
const G4DynamicParticle aDynamicGamma,
G4double  tmin,
G4double  maxEnergy 
)
virtual

Implements G4VEmModel.

Definition at line 424 of file G4PenelopeRayleighModel.cc.

References python.hepunit::electron_mass_c2, fParticleChange, fStopAndKill, G4cout, G4endl, G4Exception(), G4UniformRand, G4Material::GetElementVector(), G4DynamicParticle::GetKineticEnergy(), G4MaterialCutsCouple::GetMaterial(), G4DynamicParticle::GetMomentumDirection(), G4Material::GetName(), G4Material::GetNumberOfElements(), G4PenelopeSamplingData::GetNumberOfStoredPoints(), G4PenelopeSamplingData::GetX(), JustWarning, G4TemplateAutoLock< M, L, U >::lock(), G4INCL::Math::min(), G4VParticleChange::ProposeLocalEnergyDeposit(), G4ParticleChangeForGamma::ProposeMomentumDirection(), G4VParticleChange::ProposeTrackStatus(), CLHEP::Hep3Vector::rotateUz(), G4PenelopeSamplingData::SampleValue(), G4ParticleChangeForGamma::SetProposedKineticEnergy(), python.hepunit::twopi, G4TemplateAutoLock< M, L, U >::unlock(), and G4PhysicsVector::Value().

429 {
430  // Sampling of the Rayleigh final state (namely, scattering angle of the photon)
431  // from the Penelope2008 model. The scattering angle is sampled from the atomic
432  // cross section dOmega/d(cosTheta) from Born ("Atomic Phyisics", 1969), disregarding
433  // anomalous scattering effects. The Form Factor F(Q) function which appears in the
434  // analytical cross section is retrieved via the method GetFSquared(); atomic data
435  // are tabulated for F(Q). Form factor for compounds is calculated according to
436  // the additivity rule. The sampling from the F(Q) is made via a Rational Inverse
437  // Transform with Aliasing (RITA) algorithm; RITA parameters are calculated once
438  // for each material and managed by G4PenelopeSamplingData objects.
439  // The sampling algorithm (rejection method) has efficiency 67% at low energy, and
440  // increases with energy. For E=100 keV the efficiency is 100% and 86% for
441  // hydrogen and uranium, respectively.
442 
443  if (verboseLevel > 3)
444  G4cout << "Calling SamplingSecondaries() of G4PenelopeRayleighModel" << G4endl;
445 
446  G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy();
447 
448  if (photonEnergy0 <= fIntrinsicLowEnergyLimit)
449  {
453  return ;
454  }
455 
456  G4ParticleMomentum photonDirection0 = aDynamicGamma->GetMomentumDirection();
457 
458  const G4Material* theMat = couple->GetMaterial();
459 
460 
461  //1) Verify if tables are ready
462  //Either Initialize() was not called, or we are in a slave and InitializeLocal() was
463  //not invoked
464  if (!pMaxTable || !samplingTable || !logAtomicCrossSection || !atomicFormFactor ||
465  !logFormFactorTable)
466  {
467  //create a **thread-local** version of the table. Used only for G4EmCalculator and
468  //Unit Tests
469  fLocalTable = true;
470  if (!logAtomicCrossSection)
471  logAtomicCrossSection = new std::map<G4int,G4PhysicsFreeVector*>;
472  if (!atomicFormFactor)
473  atomicFormFactor = new std::map<G4int,G4PhysicsFreeVector*>;
474  if (!logFormFactorTable)
475  logFormFactorTable = new std::map<const G4Material*,G4PhysicsFreeVector*>;
476  if (!pMaxTable)
477  pMaxTable = new std::map<const G4Material*,G4PhysicsFreeVector*>;
478  if (!samplingTable)
479  samplingTable = new std::map<const G4Material*,G4PenelopeSamplingData*>;
480  }
481 
482  if (!samplingTable->count(theMat))
483  {
484  //If we are here, it means that Initialize() was inkoved, but the MaterialTable was
485  //not filled up. This can happen in a UnitTest
486  if (verboseLevel > 0)
487  {
488  //Issue a G4Exception (warning) only in verbose mode
490  ed << "Unable to find the samplingTable data for " <<
491  theMat->GetName() << G4endl;
492  ed << "This can happen only in Unit Tests" << G4endl;
493  G4Exception("G4PenelopeRayleighModel::SampleSecondaries()",
494  "em2019",JustWarning,ed);
495  }
496  const G4ElementVector* theElementVector = theMat->GetElementVector();
497  //protect file reading via autolock
498  G4AutoLock lock(&PenelopeRayleighModelMutex);
499  for (size_t j=0;j<theMat->GetNumberOfElements();j++)
500  {
501  G4int iZ = (G4int) theElementVector->at(j)->GetZ();
502  if (!logAtomicCrossSection->count(iZ))
503  {
504  lock.lock();
505  ReadDataFile(iZ);
506  lock.unlock();
507  }
508  }
509  lock.lock();
510  //1) If the table has not been built for the material, do it!
511  if (!logFormFactorTable->count(theMat))
512  BuildFormFactorTable(theMat);
513 
514  //2) retrieve or build the sampling table
515  if (!(samplingTable->count(theMat)))
516  InitializeSamplingAlgorithm(theMat);
517 
518  //3) retrieve or build the pMax data
519  if (!pMaxTable->count(theMat))
520  GetPMaxTable(theMat);
521  lock.unlock();
522  }
523 
524  //Ok, restart the job
525 
526  G4PenelopeSamplingData* theDataTable = samplingTable->find(theMat)->second;
527 
528 
529  G4PhysicsFreeVector* thePMax = pMaxTable->find(theMat)->second;
530 
531  G4double cosTheta = 1.0;
532 
533  //OK, ready to go!
534  G4double qmax = 2.0*photonEnergy0/electron_mass_c2; //this is non-dimensional now
535 
536  if (qmax < 1e-10) //very low momentum transfer
537  {
538  G4bool loopAgain=false;
539  do
540  {
541  loopAgain = false;
542  cosTheta = 1.0-2.0*G4UniformRand();
543  G4double G = 0.5*(1+cosTheta*cosTheta);
544  if (G4UniformRand()>G)
545  loopAgain = true;
546  }while(loopAgain);
547  }
548  else //larger momentum transfer
549  {
550  size_t nData = theDataTable->GetNumberOfStoredPoints();
551  G4double LastQ2inTheTable = theDataTable->GetX(nData-1);
552  G4double q2max = std::min(qmax*qmax,LastQ2inTheTable);
553 
554  G4bool loopAgain = false;
555  G4double MaxPValue = thePMax->Value(photonEnergy0);
556  G4double xx=0;
557 
558  //Sampling by rejection method. The rejection function is
559  //G = 0.5*(1+cos^2(theta))
560  //
561  do{
562  loopAgain = false;
563  G4double RandomMax = G4UniformRand()*MaxPValue;
564  xx = theDataTable->SampleValue(RandomMax);
565  //xx is a random value of q^2 in (0,q2max),sampled according to
566  //F(Q^2) via the RITA algorithm
567  if (xx > q2max)
568  loopAgain = true;
569  cosTheta = 1.0-2.0*xx/q2max;
570  G4double G = 0.5*(1+cosTheta*cosTheta);
571  if (G4UniformRand()>G)
572  loopAgain = true;
573  }while(loopAgain);
574  }
575 
576  G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
577 
578  // Scattered photon angles. ( Z - axis along the parent photon)
579  G4double phi = twopi * G4UniformRand() ;
580  G4double dirX = sinTheta*std::cos(phi);
581  G4double dirY = sinTheta*std::sin(phi);
582  G4double dirZ = cosTheta;
583 
584  // Update G4VParticleChange for the scattered photon
585  G4ThreeVector photonDirection1(dirX, dirY, dirZ);
586 
587  photonDirection1.rotateUz(photonDirection0);
588  fParticleChange->ProposeMomentumDirection(photonDirection1) ;
589  fParticleChange->SetProposedKineticEnergy(photonEnergy0) ;
590 
591  return;
592 }
std::vector< G4Element * > G4ElementVector
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4double GetKineticEnergy() const
const G4String & GetName() const
Definition: G4Material.hh:176
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:188
int G4int
Definition: G4Types.hh:78
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
#define G4UniformRand()
Definition: Randomize.hh:87
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
const G4ThreeVector & GetMomentumDirection() const
float electron_mass_c2
Definition: hepunit.py:274
G4double Value(G4double theEnergy, size_t &lastidx) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4double SampleValue(G4double rndm)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4double GetX(size_t index)
G4ParticleChangeForGamma * fParticleChange
void SetProposedKineticEnergy(G4double proposedKinEnergy)
#define G4endl
Definition: G4ios.hh:61
size_t GetNumberOfElements() const
Definition: G4Material.hh:184
double G4double
Definition: G4Types.hh:76
void ProposeTrackStatus(G4TrackStatus status)
const G4Material * GetMaterial() const
void G4PenelopeRayleighModel::SetVerbosityLevel ( G4int  lev)
inline

Definition at line 84 of file G4PenelopeRayleighModel.hh.

84 {verboseLevel = lev;};

Field Documentation

const G4ParticleDefinition* G4PenelopeRayleighModel::fParticle
protected

Definition at line 92 of file G4PenelopeRayleighModel.hh.

Referenced by Initialise(), and InitialiseLocal().

G4ParticleChangeForGamma* G4PenelopeRayleighModel::fParticleChange
protected

Definition at line 91 of file G4PenelopeRayleighModel.hh.

Referenced by Initialise(), and SampleSecondaries().


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