Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PenelopeGammaConversionModel Class Reference

#include <G4PenelopeGammaConversionModel.hh>

+ Inheritance diagram for G4PenelopeGammaConversionModel:

Public Member Functions

 G4PenelopeGammaConversionModel (const G4ParticleDefinition *p=0, const G4String &processName="PenConversion")
 
virtual ~G4PenelopeGammaConversionModel ()
 
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 ()
 
- Public Member Functions inherited from G4VEmModel
 G4VEmModel (const G4String &nam)
 
virtual ~G4VEmModel ()
 
virtual void Initialise (const G4ParticleDefinition *, const G4DataVector &)=0
 
virtual void SampleSecondaries (std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin=0.0, G4double tmax=DBL_MAX)=0
 
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 ComputeCrossSectionPerAtom (const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0., 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 *)
 
virtual void SetupForMaterial (const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
 
virtual void DefineForRegion (const G4Region *)
 
void InitialiseElementSelectors (const G4ParticleDefinition *, const G4DataVector &)
 
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)
 
void SetParticleChange (G4VParticleChange *, G4VEmFluctuationModel *f=0)
 
void SetCrossSectionTable (G4PhysicsTable *)
 
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
 
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 ForceBuildTable (G4bool val)
 
G4double MaxSecondaryKinEnergy (const G4DynamicParticle *dynParticle)
 
const G4StringGetName () const
 
void SetCurrentCouple (const G4MaterialCutsCouple *)
 
const G4ElementGetCurrentElement () const
 

Protected Attributes

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

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 56 of file G4PenelopeGammaConversionModel.hh.

Constructor & Destructor Documentation

◆ G4PenelopeGammaConversionModel()

G4PenelopeGammaConversionModel::G4PenelopeGammaConversionModel ( const G4ParticleDefinition p = 0,
const G4String processName = "PenConversion" 
)

Definition at line 52 of file G4PenelopeGammaConversionModel.cc.

54 :G4VEmModel(nam),fParticleChange(0),logAtomicCrossSection(0),
55 fEffectiveCharge(0),fMaterialInvScreeningRadius(0),
56 fScreeningFunction(0),isInitialised(false)
57{
58 fIntrinsicLowEnergyLimit = 2.0*electron_mass_c2;
59 fIntrinsicHighEnergyLimit = 100.0*GeV;
60 fSmallEnergy = 1.1*MeV;
61 InitializeScreeningRadii();
62
63 // SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
64 SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
65 //
66 verboseLevel= 0;
67 // Verbosity scale:
68 // 0 = nothing
69 // 1 = warning for energy non-conservation
70 // 2 = details of energy budget
71 // 3 = calculation of cross sections, file openings, sampling of atoms
72 // 4 = entering in methods
73}
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:585

◆ ~G4PenelopeGammaConversionModel()

G4PenelopeGammaConversionModel::~G4PenelopeGammaConversionModel ( )
virtual

Definition at line 77 of file G4PenelopeGammaConversionModel.cc.

78{
79 std::map <G4int,G4PhysicsFreeVector*>::iterator i;
80 if (logAtomicCrossSection)
81 {
82 for (i=logAtomicCrossSection->begin();i != logAtomicCrossSection->end();i++)
83 if (i->second) delete i->second;
84 delete logAtomicCrossSection;
85 }
86 if (fEffectiveCharge)
87 delete fEffectiveCharge;
88 if (fMaterialInvScreeningRadius)
89 delete fMaterialInvScreeningRadius;
90 if (fScreeningFunction)
91 delete fScreeningFunction;
92}

Member Function Documentation

◆ ComputeCrossSectionPerAtom()

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

Reimplemented from G4VEmModel.

Definition at line 143 of file G4PenelopeGammaConversionModel.cc.

148{
149 //
150 // Penelope model v2008.
151 // Cross section (including triplet production) read from database and managed
152 // through the G4CrossSectionHandler utility. Cross section data are from
153 // M.J. Berger and J.H. Hubbel (XCOM), Report NBSIR 887-3598
154 //
155
156 if (energy < fIntrinsicLowEnergyLimit)
157 return 0;
158
159 G4int iZ = (G4int) Z;
160
161 //read data files
162 if (!logAtomicCrossSection->count(iZ))
163 ReadDataFile(iZ);
164 //now it should be ok
165 if (!logAtomicCrossSection->count(iZ))
166 {
168 ed << "Unable to retrieve cross section table for Z=" << iZ << G4endl;
169 G4Exception("G4PenelopeGammaConversionModel::ComputeCrossSectionPerAtom()",
170 "em2018",FatalException,ed);
171 }
172
173 G4double cs = 0;
174 G4double logene = std::log(energy);
175 G4PhysicsFreeVector* theVec = logAtomicCrossSection->find(iZ)->second;
176
177 G4double logXS = theVec->Value(logene);
178 cs = std::exp(logXS);
179
180 if (verboseLevel > 2)
181 G4cout << "Gamma conversion cross section at " << energy/MeV << " MeV for Z=" << Z <<
182 " = " << cs/barn << " barn" << G4endl;
183 return cs;
184}
@ FatalException
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
G4double Value(G4double theEnergy)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76

◆ GetVerbosityLevel()

G4int G4PenelopeGammaConversionModel::GetVerbosityLevel ( )
inline

Definition at line 83 of file G4PenelopeGammaConversionModel.hh.

83{return verboseLevel;};

◆ Initialise()

void G4PenelopeGammaConversionModel::Initialise ( const G4ParticleDefinition ,
const G4DataVector  
)
virtual

Implements G4VEmModel.

Definition at line 97 of file G4PenelopeGammaConversionModel.cc.

99{
100 if (verboseLevel > 3)
101 G4cout << "Calling G4PenelopeGammaConversionModel::Initialise()" << G4endl;
102
103 // logAtomicCrossSection is created only once, since it is never cleared
104 if (!logAtomicCrossSection)
105 logAtomicCrossSection = new std::map<G4int,G4PhysicsFreeVector*>;
106
107 //delete old material data...
108 if (fEffectiveCharge)
109 {
110 delete fEffectiveCharge;
111 fEffectiveCharge = 0;
112 }
113 if (fMaterialInvScreeningRadius)
114 {
115 delete fMaterialInvScreeningRadius;
116 fMaterialInvScreeningRadius = 0;
117 }
118 if (fScreeningFunction)
119 {
120 delete fScreeningFunction;
121 fScreeningFunction = 0;
122 }
123 //and create new ones
124 fEffectiveCharge = new std::map<const G4Material*,G4double>;
125 fMaterialInvScreeningRadius = new std::map<const G4Material*,G4double>;
126 fScreeningFunction = new std::map<const G4Material*,std::pair<G4double,G4double> >;
127
128 if (verboseLevel > 0) {
129 G4cout << "Penelope Gamma Conversion model v2008 is initialized " << G4endl
130 << "Energy range: "
131 << LowEnergyLimit() / MeV << " MeV - "
132 << HighEnergyLimit() / GeV << " GeV"
133 << G4endl;
134 }
135
136 if(isInitialised) return;
138 isInitialised = true;
139}
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:109
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:529
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:522

◆ SampleSecondaries()

void G4PenelopeGammaConversionModel::SampleSecondaries ( std::vector< G4DynamicParticle * > *  fvect,
const G4MaterialCutsCouple couple,
const G4DynamicParticle aDynamicGamma,
G4double  tmin,
G4double  maxEnergy 
)
virtual

Implements G4VEmModel.

Definition at line 189 of file G4PenelopeGammaConversionModel.cc.

194{
195 //
196 // Penelope model v2008.
197 // Final state is sampled according to the Bethe-Heitler model with Coulomb
198 // corrections, according to the semi-empirical model of
199 // J. Baro' et al., Radiat. Phys. Chem. 44 (1994) 531.
200 //
201 // The model uses the high energy Coulomb correction from
202 // H. Davies et al., Phys. Rev. 93 (1954) 788
203 // and atomic screening radii tabulated from
204 // J.H. Hubbel et al., J. Phys. Chem. Ref. Data 9 (1980) 1023
205 // for Z= 1 to 92.
206 //
207 if (verboseLevel > 3)
208 G4cout << "Calling SamplingSecondaries() of G4PenelopeGammaConversionModel" << G4endl;
209
210 G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
211
212 // Always kill primary
215
216 if (photonEnergy <= fIntrinsicLowEnergyLimit)
217 {
219 return ;
220 }
221
222 G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
223 const G4Material* mat = couple->GetMaterial();
224
225 //check if material data are available
226 if (!fEffectiveCharge->count(mat))
227 InitializeScreeningFunctions(mat);
228 if (!fEffectiveCharge->count(mat))
229 {
231 ed << "Unable to allocate the EffectiveCharge data for " <<
232 mat->GetName() << G4endl;
233 G4Exception("G4PenelopeGammaConversion::SampleSecondaries()",
234 "em2019",FatalException,ed);
235 }
236
237 // eps is the fraction of the photon energy assigned to e- (including rest mass)
238 G4double eps = 0;
239 G4double eki = electron_mass_c2/photonEnergy;
240
241 //Do it fast for photon energy < 1.1 MeV (close to threshold)
242 if (photonEnergy < fSmallEnergy)
243 eps = eki + (1.0-2.0*eki)*G4UniformRand();
244 else
245 {
246 //Complete calculation
247 G4double effC = fEffectiveCharge->find(mat)->second;
248 G4double alz = effC*fine_structure_const;
249 G4double T = std::sqrt(2.0*eki);
250 G4double F00=(-1.774-1.210e1*alz+1.118e1*alz*alz)*T
251 +(8.523+7.326e1*alz-4.441e1*alz*alz)*T*T
252 -(1.352e1+1.211e2*alz-9.641e1*alz*alz)*T*T*T
253 +(8.946+6.205e1*alz-6.341e1*alz*alz)*T*T*T*T;
254
255 G4double F0b = fScreeningFunction->find(mat)->second.second;
256 G4double g0 = F0b + F00;
257 G4double invRad = fMaterialInvScreeningRadius->find(mat)->second;
258 G4double bmin = 4.0*eki/invRad;
259 std::pair<G4double,G4double> scree = GetScreeningFunctions(bmin);
260 G4double g1 = scree.first;
261 G4double g2 = scree.second;
262 G4double g1min = g1+g0;
263 G4double g2min = g2+g0;
264 G4double xr = 0.5-eki;
265 G4double a1 = 2.*g1min*xr*xr/3.;
266 G4double p1 = a1/(a1+g2min);
267
268 G4bool loopAgain = false;
269 //Random sampling of eps
270 do{
271 loopAgain = false;
272 if (G4UniformRand() <= p1)
273 {
274 G4double ru2m1 = 2.0*G4UniformRand()-1.0;
275 if (ru2m1 < 0)
276 eps = 0.5-xr*std::pow(std::abs(ru2m1),1./3.);
277 else
278 eps = 0.5+xr*std::pow(ru2m1,1./3.);
279 G4double B = eki/(invRad*eps*(1.0-eps));
280 scree = GetScreeningFunctions(B);
281 g1 = scree.first;
282 g1 = std::max(g1+g0,0.);
283 if (G4UniformRand()*g1min > g1)
284 loopAgain = true;
285 }
286 else
287 {
288 eps = eki+2.0*xr*G4UniformRand();
289 G4double B = eki/(invRad*eps*(1.0-eps));
290 scree = GetScreeningFunctions(B);
291 g2 = scree.second;
292 g2 = std::max(g2+g0,0.);
293 if (G4UniformRand()*g2min > g2)
294 loopAgain = true;
295 }
296 }while(loopAgain);
297
298 }
299 if (verboseLevel > 4)
300 G4cout << "Sampled eps = " << eps << G4endl;
301
302 G4double electronTotEnergy = eps*photonEnergy;
303 G4double positronTotEnergy = (1.0-eps)*photonEnergy;
304
305 // Scattered electron (positron) angles. ( Z - axis along the parent photon)
306
307 //electron kinematics
308 G4double electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
309 G4double costheta_el = G4UniformRand()*2.0-1.0;
310 G4double kk = std::sqrt(electronKineEnergy*(electronKineEnergy+2.*electron_mass_c2));
311 costheta_el = (costheta_el*electronTotEnergy+kk)/(electronTotEnergy+costheta_el*kk);
312 G4double phi_el = twopi * G4UniformRand() ;
313 G4double dirX_el = std::sqrt(1.-costheta_el*costheta_el) * std::cos(phi_el);
314 G4double dirY_el = std::sqrt(1.-costheta_el*costheta_el) * std::sin(phi_el);
315 G4double dirZ_el = costheta_el;
316
317 //positron kinematics
318 G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
319 G4double costheta_po = G4UniformRand()*2.0-1.0;
320 kk = std::sqrt(positronKineEnergy*(positronKineEnergy+2.*electron_mass_c2));
321 costheta_po = (costheta_po*positronTotEnergy+kk)/(positronTotEnergy+costheta_po*kk);
322 G4double phi_po = twopi * G4UniformRand() ;
323 G4double dirX_po = std::sqrt(1.-costheta_po*costheta_po) * std::cos(phi_po);
324 G4double dirY_po = std::sqrt(1.-costheta_po*costheta_po) * std::sin(phi_po);
325 G4double dirZ_po = costheta_po;
326
327 // Kinematics of the created pair:
328 // the electron and positron are assumed to have a symetric angular
329 // distribution with respect to the Z axis along the parent photon
330 G4double localEnergyDeposit = 0. ;
331
332 if (electronKineEnergy > 0.0)
333 {
334 G4ThreeVector electronDirection ( dirX_el, dirY_el, dirZ_el);
335 electronDirection.rotateUz(photonDirection);
337 electronDirection,
338 electronKineEnergy);
339 fvect->push_back(electron);
340 }
341 else
342 {
343 localEnergyDeposit += electronKineEnergy;
344 electronKineEnergy = 0;
345 }
346
347 //Generate the positron. Real particle in any case, because it will annihilate. If below
348 //threshold, produce it at rest
349 if (positronKineEnergy < 0.0)
350 {
351 localEnergyDeposit += positronKineEnergy;
352 positronKineEnergy = 0; //produce it at rest
353 }
354 G4ThreeVector positronDirection(dirX_po,dirY_po,dirZ_po);
355 positronDirection.rotateUz(photonDirection);
357 positronDirection, positronKineEnergy);
358 fvect->push_back(positron);
359
360 //Add rest of energy to the local energy deposit
361 fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
362
363 if (verboseLevel > 1)
364 {
365 G4cout << "-----------------------------------------------------------" << G4endl;
366 G4cout << "Energy balance from G4PenelopeGammaConversion" << G4endl;
367 G4cout << "Incoming photon energy: " << photonEnergy/keV << " keV" << G4endl;
368 G4cout << "-----------------------------------------------------------" << G4endl;
369 if (electronKineEnergy)
370 G4cout << "Electron (explicitely produced) " << electronKineEnergy/keV << " keV"
371 << G4endl;
372 if (positronKineEnergy)
373 G4cout << "Positron (not at rest) " << positronKineEnergy/keV << " keV" << G4endl;
374 G4cout << "Rest masses of e+/- " << 2.0*electron_mass_c2/keV << " keV" << G4endl;
375 if (localEnergyDeposit)
376 G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
377 G4cout << "Total final state: " << (electronKineEnergy+positronKineEnergy+
378 localEnergyDeposit+2.0*electron_mass_c2)/keV <<
379 " keV" << G4endl;
380 G4cout << "-----------------------------------------------------------" << G4endl;
381 }
382 if (verboseLevel > 0)
383 {
384 G4double energyDiff = std::fabs(electronKineEnergy+positronKineEnergy+
385 localEnergyDeposit+2.0*electron_mass_c2-photonEnergy);
386 if (energyDiff > 0.05*keV)
387 G4cout << "Warning from G4PenelopeGammaConversion: problem with energy conservation: "
388 << (electronKineEnergy+positronKineEnergy+
389 localEnergyDeposit+2.0*electron_mass_c2)/keV
390 << " keV (final) vs. " << photonEnergy/keV << " keV (initial)" << G4endl;
391 }
392}
#define F00
@ fStopAndKill
bool G4bool
Definition: G4Types.hh:67
#define G4UniformRand()
Definition: Randomize.hh:53
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition: G4Electron.cc:94
const G4Material * GetMaterial() const
const G4String & GetName() const
Definition: G4Material.hh:177
void SetProposedKineticEnergy(G4double proposedKinEnergy)
static G4Positron * Positron()
Definition: G4Positron.cc:94
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)

◆ SetVerbosityLevel()

void G4PenelopeGammaConversionModel::SetVerbosityLevel ( G4int  lev)
inline

Definition at line 82 of file G4PenelopeGammaConversionModel.hh.

82{verboseLevel = lev;};

Member Data Documentation

◆ fParticleChange

G4ParticleChangeForGamma* G4PenelopeGammaConversionModel::fParticleChange
protected

Definition at line 86 of file G4PenelopeGammaConversionModel.hh.

Referenced by Initialise(), and SampleSecondaries().


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