GGEMS  1.1
GPU GEant4-based Monte Carlo Simulations
GGEMSComptonScatteringModels.hh
Go to the documentation of this file.
1 #ifndef GUARD_GGEMS_PHYSICS_GGEMSCOMPTONSCATTERINGMODELS_HH
2 #define GUARD_GGEMS_PHYSICS_GGEMSCOMPTONSCATTERINGMODELS_HH
3 
4 // ************************************************************************
5 // * This file is part of GGEMS. *
6 // * *
7 // * GGEMS is free software: you can redistribute it and/or modify *
8 // * it under the terms of the GNU General Public License as published by *
9 // * the Free Software Foundation, either version 3 of the License, or *
10 // * (at your option) any later version. *
11 // * *
12 // * GGEMS is distributed in the hope that it will be useful, *
13 // * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 // * GNU General Public License for more details. *
16 // * *
17 // * You should have received a copy of the GNU General Public License *
18 // * along with GGEMS. If not, see <https://www.gnu.org/licenses/>. *
19 // * *
20 // ************************************************************************
21 
34 #ifdef __OPENCL_C_VERSION__
35 
39 
47 inline void KleinNishinaComptonSampleSecondaries(
48  global GGEMSPrimaryParticles* primary_particle,
49  global GGEMSRandom* random,
50  GGint const particle_id
51 )
52 {
53  // Energy
54  GGfloat kE0 = primary_particle->E_[particle_id];
55  GGfloat kE0_MeC2 = kE0 / ELECTRON_MASS_C2;
56 
57  // Direction
58  GGfloat3 kGammaDirection = {
59  primary_particle->dx_[particle_id],
60  primary_particle->dy_[particle_id],
61  primary_particle->dz_[particle_id]
62  };
63 
64  // sample the energy rate the scattered gamma
65  GGfloat kEps0 = 1.0f / (1.0f + 2.0f*kE0_MeC2);
66  GGfloat kEps0Eps0 = kEps0*kEps0;
67  GGfloat kAlpha1 = -log(kEps0);
68  GGfloat kAlpha2 = kAlpha1 + 0.5f*(1.0f-kEps0Eps0);
69 
70  #ifdef GGEMS_TRACKING
71  if (particle_id == primary_particle->particle_tracking_id) {
72  printf("\n");
73  printf("[GGEMS OpenCL function KleinNishinaComptonSampleSecondaries] Photon energy: %e keV\n", kE0/keV);
74  printf("[GGEMS OpenCL function KleinNishinaComptonSampleSecondaries] Photon direction: %e %e %e\n", kGammaDirection.x, kGammaDirection.y, kGammaDirection.z);
75  printf("[GGEMS OpenCL function KleinNishinaComptonSampleSecondaries] Min. photon energy (back scattering): %e keV\n", kE0*kEps0/keV);
76  }
77  #endif
78 
79  // sample the energy rate of the scattered gamma
80 
81  GGfloat3 rndm;
82  GGfloat epsilon, epsilonsq, onecost, sint2, greject, costheta, sintheta, phi;
83  GGint nloop = 0;
84  do {
85  ++nloop;
86  // false interaction if too many iterations
87  if (nloop > 1000) return;
88 
89  // Get 3 random numbers
90  rndm.x = KissUniform(random, particle_id);
91  rndm.y = KissUniform(random, particle_id);
92  rndm.z = KissUniform(random, particle_id);
93 
94  if (kAlpha1 > kAlpha2*rndm.x) {
95  epsilon = exp(-kAlpha1*rndm.y);
96  epsilonsq = epsilon*epsilon;
97  }
98  else {
99  epsilonsq = kEps0Eps0 + (1.0f - kEps0Eps0)*rndm.y;
100  epsilon = sqrt(epsilonsq);
101  }
102 
103  onecost = (1.0f - epsilon)/(epsilon*kE0_MeC2);
104  sint2 = onecost*(2.0f-onecost);
105  greject = 1.0f - epsilon*sint2/(1.0f+ epsilonsq);
106  } while (greject < rndm.z);
107 
108  // Scattered gamma angles
109  if (sint2 < 0.0f) sint2 = 0.0f;
110  costheta = 1.0f - onecost;
111  sintheta = sqrt(sint2);
112  phi = KissUniform(random, particle_id) * TWO_PI;
113 
114  // Update scattered gamma
115  GGfloat3 gamma_direction = {sintheta*cos(phi), sintheta*sin(phi), costheta};
116  gamma_direction = RotateUnitZ(&gamma_direction, &kGammaDirection);
117  gamma_direction = normalize(gamma_direction);
118  GGfloat kE1 = kE0*epsilon;
119 
120  #ifdef GGEMS_TRACKING
121  if (particle_id == primary_particle->particle_tracking_id) {
122  printf("[GGEMS OpenCL function KleinNishinaComptonSampleSecondaries] Scattered photon energy: %e keV\n", kE1/keV);
123  printf("[GGEMS OpenCL function KleinNishinaComptonSampleSecondaries] Scattered photon direction: %e %e %e\n", gamma_direction.x, gamma_direction.y, gamma_direction.z);
124  }
125  #endif
126 
127  primary_particle->E_[particle_id] = kE1;
128 
129  primary_particle->dx_[particle_id] = gamma_direction.x;
130  primary_particle->dy_[particle_id] = gamma_direction.y;
131  primary_particle->dz_[particle_id] = gamma_direction.z;
132 }
133 
134 #endif
135 
136 #endif // GUARD_GGEMS_PHYSICS_GGEMSCOMPTONSCATTERINGMODELS_HH
GGEMSPrimaryParticles_t
Structure storing informations about primary particles.
Definition: GGEMSPrimaryParticles.hh:42
GGint
#define GGint
Definition: GGEMSTypes.hh:224
keV
__constant GGfloat keV
Definition: GGEMSSystemOfUnits.hh:102
ELECTRON_MASS_C2
__constant GGfloat ELECTRON_MASS_C2
Definition: GGEMSConstants.hh:53
GGfloat3
#define GGfloat3
Definition: GGEMSTypes.hh:275
GGEMSRandom_t
Structure storing informations about random.
Definition: GGEMSRandom.hh:42
TWO_PI
__constant GGfloat TWO_PI
Definition: GGEMSConstants.hh:39
GGfloat
#define GGfloat
Definition: GGEMSTypes.hh:273