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

#include <G4LowEPPolarizedComptonModel.hh>

+ Inheritance diagram for G4LowEPPolarizedComptonModel:

Public Member Functions

 G4LowEPPolarizedComptonModel (const G4ParticleDefinition *p=0, const G4String &nam="LowEPComptonModel")
 
virtual ~G4LowEPPolarizedComptonModel ()
 
virtual void Initialise (const G4ParticleDefinition *, const G4DataVector &)
 
virtual void InitialiseLocal (const G4ParticleDefinition *, G4VEmModel *masterModel)
 
virtual void InitialiseForElement (const G4ParticleDefinition *, G4int Z)
 
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)
 
- 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 void InitialiseLocal (const G4ParticleDefinition *, G4VEmModel *masterModel)
 
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 GetPartialCrossSection (const G4Material *, G4int level, const G4ParticleDefinition *, G4double kineticEnergy)
 
virtual G4double ComputeCrossSectionPerAtom (const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0., G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
virtual G4double ComputeCrossSectionPerShell (const G4ParticleDefinition *, G4int Z, G4int shellIdx, G4double kinEnergy, 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 *)
 
virtual void ModelDescription (std::ostream &outFile) const
 
void InitialiseElementSelectors (const G4ParticleDefinition *, const G4DataVector &)
 
std::vector< G4EmElementSelector * > * GetElementSelectors ()
 
void SetElementSelectors (std::vector< G4EmElementSelector * > *)
 
virtual 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)
 
const G4ElementSelectRandomAtom (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
 
const G4ElementSelectTargetAtom (const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double logKineticEnergy, 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 *)
 
G4int SelectIsotopeNumber (const G4Element *)
 
void SetParticleChange (G4VParticleChange *, G4VEmFluctuationModel *f=nullptr)
 
void SetCrossSectionTable (G4PhysicsTable *, G4bool isLocal)
 
G4ElementDataGetElementData ()
 
G4PhysicsTableGetCrossSectionTable ()
 
G4VEmFluctuationModelGetModelOfFluctuations ()
 
G4VEmAngularDistributionGetAngularDistribution ()
 
G4VEmModelGetTripletModel ()
 
void SetTripletModel (G4VEmModel *)
 
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) const
 
void SetPolarAngleLimit (G4double)
 
void SetSecondaryThreshold (G4double)
 
void SetLPMFlag (G4bool val)
 
void SetDeexcitationFlag (G4bool val)
 
void SetForceBuildTable (G4bool val)
 
void SetFluctuationFlag (G4bool val)
 
void SetMasterThread (G4bool val)
 
G4bool IsMaster () const
 
void SetUseBaseMaterials (G4bool val)
 
G4bool UseBaseMaterials () const
 
G4double MaxSecondaryKinEnergy (const G4DynamicParticle *dynParticle)
 
const G4StringGetName () const
 
void SetCurrentCouple (const G4MaterialCutsCouple *)
 
const G4ElementGetCurrentElement () const
 
const G4IsotopeGetCurrentIsotope () const
 
G4bool IsLocked () const
 
void SetLocked (G4bool)
 
G4VEmModeloperator= (const G4VEmModel &right)=delete
 
 G4VEmModel (const G4VEmModel &)=delete
 

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 *)
 
- Protected Attributes inherited from G4VEmModel
G4ElementDatafElementData
 
G4VParticleChangepParticleChange
 
G4PhysicsTablexSectionTable
 
const G4MaterialpBaseMaterial
 
const std::vector< G4double > * theDensityFactor
 
const std::vector< G4int > * theDensityIdx
 
size_t idxTable
 
G4bool lossFlucFlag
 
G4double inveplus
 
G4double pFactor
 

Detailed Description

Definition at line 94 of file G4LowEPPolarizedComptonModel.hh.

Constructor & Destructor Documentation

◆ G4LowEPPolarizedComptonModel()

G4LowEPPolarizedComptonModel::G4LowEPPolarizedComptonModel ( const G4ParticleDefinition p = 0,
const G4String nam = "LowEPComptonModel" 
)

Definition at line 83 of file G4LowEPPolarizedComptonModel.cc.

85 : G4VEmModel(nam),isInitialised(false)
86{
87 verboseLevel=1 ;
88 // Verbosity scale:
89 // 0 = nothing
90 // 1 = warning for energy non-conservation
91 // 2 = details of energy budget
92 // 3 = calculation of cross sections, file openings, sampling of atoms
93 // 4 = entering in methods
94
95 if( verboseLevel>1 ) {
96 G4cout << "Low energy photon Compton model is constructed " << G4endl;
97 }
98
99 //Mark this model as "applicable" for atomic deexcitation
101
102 fParticleChange = 0;
103 fAtomDeexcitation = 0;
104}
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
void SetDeexcitationFlag(G4bool val)
Definition: G4VEmModel.hh:813

◆ ~G4LowEPPolarizedComptonModel()

G4LowEPPolarizedComptonModel::~G4LowEPPolarizedComptonModel ( )
virtual

Definition at line 108 of file G4LowEPPolarizedComptonModel.cc.

109{
110 if(IsMaster()) {
111 delete shellData;
112 shellData = 0;
113 delete profileData;
114 profileData = 0;
115 }
116}
G4bool IsMaster() const
Definition: G4VEmModel.hh:736

Member Function Documentation

◆ ComputeCrossSectionPerAtom()

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

Reimplemented from G4VEmModel.

Definition at line 249 of file G4LowEPPolarizedComptonModel.cc.

253{
254 if (verboseLevel > 3) {
255 G4cout << "G4LowEPPolarizedComptonModel::ComputeCrossSectionPerAtom()"
256 << G4endl;
257 }
258 G4double cs = 0.0;
259
260 if (GammaEnergy < LowEnergyLimit()) { return 0.0; }
261
262 G4int intZ = G4lrint(Z);
263 if(intZ < 1 || intZ > maxZ) { return cs; }
264
265 G4LPhysicsFreeVector* pv = data[intZ];
266
267 // if element was not initialised
268 // do initialisation safely for MT mode
269 if(!pv)
270 {
271 InitialiseForElement(0, intZ);
272 pv = data[intZ];
273 if(!pv) { return cs; }
274 }
275
276 G4int n = pv->GetVectorLength() - 1;
277 G4double e1 = pv->Energy(0);
278 G4double e2 = pv->Energy(n);
279
280 if(GammaEnergy <= e1) { cs = GammaEnergy/(e1*e1)*pv->Value(e1); }
281 else if(GammaEnergy <= e2) { cs = pv->Value(GammaEnergy)/GammaEnergy; }
282 else if(GammaEnergy > e2) { cs = pv->Value(e2)/GammaEnergy; }
283
284 return cs;
285}
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
virtual void InitialiseForElement(const G4ParticleDefinition *, G4int Z)
G4double Energy(std::size_t index) const
G4double Value(G4double theEnergy, std::size_t &lastidx) const
std::size_t GetVectorLength() const
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:652
int G4lrint(double ad)
Definition: templates.hh:134

◆ Initialise()

void G4LowEPPolarizedComptonModel::Initialise ( const G4ParticleDefinition particle,
const G4DataVector cuts 
)
virtual

Implements G4VEmModel.

Definition at line 120 of file G4LowEPPolarizedComptonModel.cc.

122{
123 if (verboseLevel > 1) {
124 G4cout << "Calling G4LowEPPolarizedComptonModel::Initialise()" << G4endl;
125 }
126
127 // Initialise element selector
128
129 if(IsMaster()) {
130
131 // Access to elements
132
133 char* path = std::getenv("G4LEDATA");
134
135 G4ProductionCutsTable* theCoupleTable =
137 G4int numOfCouples = theCoupleTable->GetTableSize();
138
139 for(G4int i=0; i<numOfCouples; ++i) {
140 const G4Material* material =
141 theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
142 const G4ElementVector* theElementVector = material->GetElementVector();
143 G4int nelm = material->GetNumberOfElements();
144
145 for (G4int j=0; j<nelm; ++j) {
146 G4int Z = G4lrint((*theElementVector)[j]->GetZ());
147 if(Z < 1) { Z = 1; }
148 else if(Z > maxZ){ Z = maxZ; }
149
150 if( (!data[Z]) ) { ReadData(Z, path); }
151 }
152 }
153
154 // For Doppler broadening
155 if(!shellData) {
156 shellData = new G4ShellData();
157 shellData->SetOccupancyData();
158 G4String file = "/doppler/shell-doppler";
159 shellData->LoadData(file);
160 }
161 if(!profileData) { profileData = new G4DopplerProfile(); }
162
163 InitialiseElementSelectors(particle, cuts);
164 }
165
166 if (verboseLevel > 2) {
167 G4cout << "Loaded cross section files" << G4endl;
168 }
169
170 if( verboseLevel>1 ) {
171 G4cout << "G4LowEPPolarizedComptonModel is initialized " << G4endl
172 << "Energy range: "
173 << LowEnergyLimit() / eV << " eV - "
174 << HighEnergyLimit() / GeV << " GeV"
175 << G4endl;
176 }
177
178 if(isInitialised) { return; }
179
180 fParticleChange = GetParticleChangeForGamma();
181 fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
182 isInitialised = true;
183}
std::vector< G4Element * > G4ElementVector
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:188
size_t GetNumberOfElements() const
Definition: G4Material.hh:184
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
void SetOccupancyData()
Definition: G4ShellData.hh:69
void LoadData(const G4String &fileName)
Definition: G4ShellData.cc:233
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:133
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:645
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
Definition: G4VEmModel.cc:148

◆ InitialiseForElement()

void G4LowEPPolarizedComptonModel::InitialiseForElement ( const G4ParticleDefinition ,
G4int  Z 
)
virtual

Reimplemented from G4VEmModel.

Definition at line 726 of file G4LowEPPolarizedComptonModel.cc.

728{
729 G4AutoLock l(&LowEPPolarizedComptonModelMutex);
730 if(!data[Z]) { ReadData(Z); }
731 l.unlock();
732}

Referenced by ComputeCrossSectionPerAtom().

◆ InitialiseLocal()

void G4LowEPPolarizedComptonModel::InitialiseLocal ( const G4ParticleDefinition ,
G4VEmModel masterModel 
)
virtual

Reimplemented from G4VEmModel.

Definition at line 187 of file G4LowEPPolarizedComptonModel.cc.

189{
191}
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
Definition: G4VEmModel.hh:842
std::vector< G4EmElementSelector * > * GetElementSelectors()
Definition: G4VEmModel.hh:834

◆ SampleSecondaries()

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

Implements G4VEmModel.

Definition at line 289 of file G4LowEPPolarizedComptonModel.cc.

293{
294
295 //Determine number of digits (in decimal base) that G4double can accurately represent
296 G4double g4d_order = G4double(numeric_limits<G4double>::digits10);
297 G4double g4d_limit = std::pow(10.,-g4d_order);
298
299 // The scattered gamma energy is sampled according to Klein - Nishina formula.
300 // then accepted or rejected depending on the Scattering Function multiplied
301 // by factor from Klein - Nishina formula.
302 // Expression of the angular distribution as Klein Nishina
303 // angular and energy distribution and Scattering fuctions is taken from
304 // D. E. Cullen "A simple model of photon transport" Nucl. Instr. Meth.
305 // Phys. Res. B 101 (1995). Method of sampling with form factors is different
306 // data are interpolated while in the article they are fitted.
307 // Reference to the article is from J. Stepanek New Photon, Positron
308 // and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10
309 // TeV (draft).
310 // The random number techniques of Butcher & Messel are used
311 // (Nucl Phys 20(1960),15).
312
313
314 G4double photonEnergy0 = aDynamicGamma->GetKineticEnergy()/MeV;
315
316 if (verboseLevel > 3) {
317 G4cout << "G4LowEPPolarizedComptonModel::SampleSecondaries() E(MeV)= "
318 << photonEnergy0/MeV << " in " << couple->GetMaterial()->GetName()
319 << G4endl;
320 }
321 // do nothing below the threshold
322 // should never get here because the XS is zero below the limit
323 if (photonEnergy0 < LowEnergyLimit())
324 return ;
325
326 G4double e0m = photonEnergy0 / electron_mass_c2 ;
327 G4ParticleMomentum photonDirection0 = aDynamicGamma->GetMomentumDirection();
328
329
330 // Polarisation: check orientation of photon propagation direction and polarisation
331 // Fix if needed
332
333 G4ThreeVector photonPolarization0 = aDynamicGamma->GetPolarization();
334
335 // Check if polarisation vector is perpendicular and fix if not
336
337 if (!(photonPolarization0.isOrthogonal(photonDirection0, 1e-6))||(photonPolarization0.mag()==0))
338 {
339 photonPolarization0 = GetRandomPolarization(photonDirection0);
340 }
341
342 else
343 {
344 if ((photonPolarization0.howOrthogonal(photonDirection0) !=0) && (photonPolarization0.howOrthogonal(photonDirection0) > g4d_limit))
345 {
346 photonPolarization0 = GetPerpendicularPolarization(photonDirection0,photonPolarization0);
347 }
348 }
349
350 // Select randomly one element in the current material
351
352 const G4ParticleDefinition* particle = aDynamicGamma->GetDefinition();
353 const G4Element* elm = SelectRandomAtom(couple,particle,photonEnergy0);
354 G4int Z = (G4int)elm->GetZ();
355
356 G4double LowEPPCepsilon0 = 1. / (1. + 2. * e0m);
357 G4double LowEPPCepsilon0Sq = LowEPPCepsilon0 * LowEPPCepsilon0;
358 G4double alpha1 = -std::log(LowEPPCepsilon0);
359 G4double alpha2 = 0.5 * (1. - LowEPPCepsilon0Sq);
360
361 G4double wlPhoton = h_Planck*c_light/photonEnergy0;
362
363 // Sample the energy of the scattered photon
364 G4double LowEPPCepsilon;
365 G4double LowEPPCepsilonSq;
366 G4double oneCosT;
367 G4double sinT2;
368 G4double gReject;
369
370 if (verboseLevel > 3) {
371 G4cout << "Started loop to sample gamma energy" << G4endl;
372 }
373
374 do
375 {
376 if ( alpha1/(alpha1+alpha2) > G4UniformRand())
377 {
378 LowEPPCepsilon = G4Exp(-alpha1 * G4UniformRand());
379 LowEPPCepsilonSq = LowEPPCepsilon * LowEPPCepsilon;
380 }
381 else
382 {
383 LowEPPCepsilonSq = LowEPPCepsilon0Sq + (1. - LowEPPCepsilon0Sq) * G4UniformRand();
384 LowEPPCepsilon = std::sqrt(LowEPPCepsilonSq);
385 }
386
387 oneCosT = (1. - LowEPPCepsilon) / ( LowEPPCepsilon * e0m);
388 sinT2 = oneCosT * (2. - oneCosT);
389 G4double x = std::sqrt(oneCosT/2.) / (wlPhoton/cm);
390 G4double scatteringFunction = ComputeScatteringFunction(x, Z);
391 gReject = (1. - LowEPPCepsilon * sinT2 / (1. + LowEPPCepsilonSq)) * scatteringFunction;
392
393 } while(gReject < G4UniformRand()*Z);
394
395 G4double cosTheta = 1. - oneCosT;
396 G4double sinTheta = std::sqrt(sinT2);
397 G4double phi = SetPhi(LowEPPCepsilon,sinT2);
398 G4double dirx = sinTheta * std::cos(phi);
399 G4double diry = sinTheta * std::sin(phi);
400 G4double dirz = cosTheta ;
401
402 // Set outgoing photon polarization
403
404 G4ThreeVector photonPolarization1 = SetNewPolarization(LowEPPCepsilon,
405 sinT2,
406 phi,
407 cosTheta);
408
409 // Scatter photon energy and Compton electron direction - Method based on:
410 // J. M. C. Brown, M. R. Dimmock, J. E. Gillam and D. M. Paganin'
411 // "A low energy bound atomic electron Compton scattering model for Geant4"
412 // NIMB, Vol. 338, 77-88, 2014.
413
414 // Set constants and initialize scattering parameters
415
416 const G4double vel_c = c_light / (m/s);
417 const G4double momentum_au_to_nat = halfpi* hbar_Planck / Bohr_radius / (kg*m/s);
418 const G4double e_mass_kg = electron_mass_c2 / c_squared / kg ;
419
420 const G4int maxDopplerIterations = 1000;
421 G4double bindingE = 0.;
422 G4double pEIncident = photonEnergy0 ;
423 G4double pERecoil = -1.;
424 G4double eERecoil = -1.;
425 G4double e_alpha =0.;
426 G4double e_beta = 0.;
427
428 G4double CE_emission_flag = 0.;
429 G4double ePAU = -1;
430 G4int shellIdx = 0;
431 G4double u_temp = 0;
432 G4double cosPhiE =0;
433 G4double sinThetaE =0;
434 G4double cosThetaE =0;
435 G4int iteration = 0;
436
437 if (verboseLevel > 3) {
438 G4cout << "Started loop to sample photon energy and electron direction" << G4endl;
439 }
440
441 do{
442
443
444 // ******************************************
445 // | Determine scatter photon energy |
446 // ******************************************
447
448 do
449 {
450 iteration++;
451
452
453 // ********************************************
454 // | Sample bound electron information |
455 // ********************************************
456
457 // Select shell based on shell occupancy
458
459 shellIdx = shellData->SelectRandomShell(Z);
460 bindingE = shellData->BindingEnergy(Z,shellIdx)/MeV;
461
462
463 // Randomly sample bound electron momentum (memento: the data set is in Atomic Units)
464 ePAU = profileData->RandomSelectMomentum(Z,shellIdx);
465
466 // Convert to SI units
467 G4double ePSI = ePAU * momentum_au_to_nat;
468
469 //Calculate bound electron velocity and normalise to natural units
470 u_temp = sqrt( ((ePSI*ePSI)*(vel_c*vel_c)) / ((e_mass_kg*e_mass_kg)*(vel_c*vel_c)+(ePSI*ePSI)) )/vel_c;
471
472 // Sample incident electron direction, amorphous material, to scattering photon scattering plane
473
474 e_alpha = pi*G4UniformRand();
475 e_beta = twopi*G4UniformRand();
476
477 // Total energy of system
478
479 G4double eEIncident = electron_mass_c2 / sqrt( 1 - (u_temp*u_temp));
480 G4double systemE = eEIncident + pEIncident;
481
482
483 G4double gamma_temp = 1.0 / sqrt( 1 - (u_temp*u_temp));
484 G4double numerator = gamma_temp*electron_mass_c2*(1 - u_temp * std::cos(e_alpha));
485 G4double subdenom1 = u_temp*cosTheta*std::cos(e_alpha);
486 G4double subdenom2 = u_temp*sinTheta*std::sin(e_alpha)*std::cos(e_beta);
487 G4double denominator = (1.0 - cosTheta) + (gamma_temp*electron_mass_c2*(1 - subdenom1 - subdenom2) / pEIncident);
488 pERecoil = (numerator/denominator);
489 eERecoil = systemE - pERecoil;
490 CE_emission_flag = pEIncident - pERecoil;
491 } while ( (iteration <= maxDopplerIterations) && (CE_emission_flag < bindingE));
492
493// End of recalculation of photon energy with Doppler broadening
494
495
496
497 // *******************************************************
498 // | Determine ejected Compton electron direction |
499 // *******************************************************
500
501 // Calculate velocity of ejected Compton electron
502
503 G4double a_temp = eERecoil / electron_mass_c2;
504 G4double u_p_temp = sqrt(1 - (1 / (a_temp*a_temp)));
505
506 // Coefficients and terms from simulatenous equations
507
508 G4double sinAlpha = std::sin(e_alpha);
509 G4double cosAlpha = std::cos(e_alpha);
510 G4double sinBeta = std::sin(e_beta);
511 G4double cosBeta = std::cos(e_beta);
512
513 G4double gamma = 1.0 / sqrt(1 - (u_temp*u_temp));
514 G4double gamma_p = 1.0 / sqrt(1 - (u_p_temp*u_p_temp));
515
516 G4double var_A = pERecoil*u_p_temp*sinTheta;
517 G4double var_B = u_p_temp* (pERecoil*cosTheta-pEIncident);
518 G4double var_C = (pERecoil-pEIncident) - ( (pERecoil*pEIncident) / (gamma_p*electron_mass_c2))*(1 - cosTheta);
519
520 G4double var_D1 = gamma*electron_mass_c2*pERecoil;
521 G4double var_D2 = (1 - (u_temp*cosTheta*cosAlpha) - (u_temp*sinTheta*cosBeta*sinAlpha));
522 G4double var_D3 = ((electron_mass_c2*electron_mass_c2)*(gamma*gamma_p - 1)) - (gamma_p*electron_mass_c2*pERecoil);
523 G4double var_D = var_D1*var_D2 + var_D3;
524
525 G4double var_E1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosAlpha);
526 G4double var_E2 = gamma_p*electron_mass_c2*pERecoil*u_p_temp*cosTheta;
527 G4double var_E = var_E1 - var_E2;
528
529 G4double var_F1 = ((gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*cosBeta*sinAlpha);
530 G4double var_F2 = (gamma_p*electron_mass_c2*pERecoil*u_p_temp*sinTheta);
531 G4double var_F = var_F1 - var_F2;
532
533 G4double var_G = (gamma*gamma_p)*(electron_mass_c2*electron_mass_c2)*(u_temp*u_p_temp)*sinBeta*sinAlpha;
534
535 // Two equations form a quadratic form of Wx^2 + Yx + Z = 0
536 // Coefficents and solution to quadratic
537
538 G4double var_W1 = (var_F*var_B - var_E*var_A)*(var_F*var_B - var_E*var_A);
539 G4double var_W2 = (var_G*var_G)*(var_A*var_A) + (var_G*var_G)*(var_B*var_B);
540 G4double var_W = var_W1 + var_W2;
541
542 G4double var_Y = 2.0*(((var_A*var_D-var_F*var_C)*(var_F*var_B-var_E*var_A)) - ((var_G*var_G)*var_B*var_C));
543
544 G4double var_Z1 = (var_A*var_D - var_F*var_C)*(var_A*var_D - var_F*var_C);
545 G4double var_Z2 = (var_G*var_G)*(var_C*var_C) - (var_G*var_G)*(var_A*var_A);
546 G4double var_Z = var_Z1 + var_Z2;
547 G4double diff1 = var_Y*var_Y;
548 G4double diff2 = 4*var_W*var_Z;
549 G4double diff = diff1 - diff2;
550
551
552 // Check if diff is less than zero, if so ensure it is due to FPE
553
554 //Confirm that diff less than zero is due FPE, i.e if abs of diff / diff1 and diff/ diff2 is less
555 //than 10^(-g4d_order), then set diff to zero
556
557 if ((diff < 0.0) && (abs(diff / diff1) < g4d_limit) && (abs(diff / diff2) < g4d_limit) )
558 {
559 diff = 0.0;
560 }
561
562 // Plus and minus of quadratic
563 G4double X_p = (-var_Y + sqrt (diff))/(2*var_W);
564 G4double X_m = (-var_Y - sqrt (diff))/(2*var_W);
565
566
567 // Floating point precision protection
568 // Check if X_p and X_m are greater than or less than 1 or -1, if so clean up FPE
569 // Issue due to propagation of FPE and only impacts 8th sig fig onwards
570
571 if(X_p >1){X_p=1;} if(X_p<-1){X_p=-1;}
572 if(X_m >1){X_m=1;} if(X_m<-1){X_m=-1;}
573
574 // End of FP protection
575
576 G4double ThetaE = 0.;
577
578
579 // Randomly sample one of the two possible solutions and determin theta angle of ejected Compton electron
580 G4double sol_select = G4UniformRand();
581
582 if (sol_select < 0.5)
583 {
584 ThetaE = std::acos(X_p);
585 }
586 if (sol_select > 0.5)
587 {
588 ThetaE = std::acos(X_m);
589 }
590
591 cosThetaE = std::cos(ThetaE);
592 sinThetaE = std::sin(ThetaE);
593 G4double Theta = std::acos(cosTheta);
594
595 //Calculate electron Phi
596 G4double iSinThetaE = std::sqrt(1+std::tan((pi/2.0)-ThetaE)*std::tan((pi/2.0)-ThetaE));
597 G4double iSinTheta = std::sqrt(1+std::tan((pi/2.0)-Theta)*std::tan((pi/2.0)-Theta));
598 G4double ivar_A = iSinTheta/ (pERecoil*u_p_temp);
599 // Trigs
600 cosPhiE = (var_C - var_B*cosThetaE)*(ivar_A*iSinThetaE);
601
602 // End of calculation of ejection Compton electron direction
603
604 //Fix for floating point errors
605
606 } while ( (iteration <= maxDopplerIterations) && (abs(cosPhiE) > 1));
607
608 // Revert to original if maximum number of iterations threshold has been reached
609 if (iteration >= maxDopplerIterations)
610 {
611 pERecoil = photonEnergy0 ;
612 bindingE = 0.;
613 dirx=0.0;
614 diry=0.0;
615 dirz=1.0;
616 }
617
618 // Set "scattered" photon direction and energy
619
620 G4ThreeVector photonDirection1(dirx,diry,dirz);
621 SystemOfRefChange(photonDirection0,photonDirection1,
622 photonPolarization0,photonPolarization1);
623
624
625 if (pERecoil > 0.)
626 {
627 fParticleChange->SetProposedKineticEnergy(pERecoil) ;
628 fParticleChange->ProposeMomentumDirection(photonDirection1) ;
629 fParticleChange->ProposePolarization(photonPolarization1);
630
631 // Set ejected Compton electron direction and energy
632 G4double PhiE = std::acos(cosPhiE);
633 G4double eDirX = sinThetaE * std::cos(phi+PhiE);
634 G4double eDirY = sinThetaE * std::sin(phi+PhiE);
635 G4double eDirZ = cosThetaE;
636
637 G4double eKineticEnergy = pEIncident - pERecoil - bindingE;
638
639 G4ThreeVector eDirection(eDirX,eDirY,eDirZ);
640 SystemOfRefChangeElect(photonDirection0,eDirection,
641 photonPolarization0);
642
644 eDirection,eKineticEnergy) ;
645 fvect->push_back(dp);
646
647 }
648 else
649 {
650 fParticleChange->SetProposedKineticEnergy(0.);
651 fParticleChange->ProposeTrackStatus(fStopAndKill);
652 }
653
654 // sample deexcitation
655 //
656
657 if (verboseLevel > 3) {
658 G4cout << "Started atomic de-excitation " << fAtomDeexcitation << G4endl;
659 }
660
661 if(fAtomDeexcitation && iteration < maxDopplerIterations) {
662 G4int index = couple->GetIndex();
663 if(fAtomDeexcitation->CheckDeexcitationActiveRegion(index)) {
664 size_t nbefore = fvect->size();
666 const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
667 fAtomDeexcitation->GenerateParticles(fvect, shell, Z, index);
668 size_t nafter = fvect->size();
669 if(nafter > nbefore) {
670 for (size_t i=nbefore; i<nafter; ++i) {
671 //Check if there is enough residual energy
672 if (bindingE >= ((*fvect)[i])->GetKineticEnergy())
673 {
674 //Ok, this is a valid secondary: keep it
675 bindingE -= ((*fvect)[i])->GetKineticEnergy();
676 }
677 else
678 {
679 //Invalid secondary: not enough energy to create it!
680 //Keep its energy in the local deposit
681 delete (*fvect)[i];
682 (*fvect)[i]=0;
683 }
684 }
685 }
686 }
687 }
688
689 //This should never happen
690 if(bindingE < 0.0)
691 G4Exception("G4LowEPPolarizedComptonModel::SampleSecondaries()",
692 "em2051",FatalException,"Negative local energy deposit");
693
694 fParticleChange->ProposeLocalEnergyDeposit(bindingE);
695
696}
G4AtomicShellEnumerator
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:179
@ fStopAndKill
#define G4UniformRand()
Definition: Randomize.hh:52
bool isOrthogonal(const Hep3Vector &v, double epsilon=tolerance) const
Definition: SpaceVector.cc:233
double mag() const
double howOrthogonal(const Hep3Vector &v) const
Definition: SpaceVector.cc:215
G4double RandomSelectMomentum(G4int Z, G4int shellIndex) const
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
static G4Electron * Electron()
Definition: G4Electron.cc:93
G4double GetZ() const
Definition: G4Element.hh:130
const G4String & GetName() const
Definition: G4Material.hh:175
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposePolarization(const G4ThreeVector &dir)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double BindingEnergy(G4int Z, G4int shellIndex) const
Definition: G4ShellData.cc:165
G4int SelectRandomShell(G4int Z) const
Definition: G4ShellData.cc:362
G4bool CheckDeexcitationActiveRegion(G4int coupleIndex)
virtual const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.hh:570
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
const G4double pi

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