Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4HeatedKleinNishinaCompton.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// $Id$
27//
28// -------------------------------------------------------------------
29//
30// GEANT4 Class file
31//
32//
33// File name: G4HeatedKleinNishinaCompton
34//
35// Author: Vladimir Grichine on base of M. Maire and V. Ivanchenko code
36//
37// Creation date: 15.03.2009
38//
39// Modifications:
40//
41//
42// Class Description:
43//
44// -------------------------------------------------------------------
45//
46//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
47//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
48
50#include "globals.hh"
52#include "G4SystemOfUnits.hh"
53#include "G4RandomDirection.hh"
54#include "Randomize.hh"
55
57#include "G4Electron.hh"
58#include "G4Gamma.hh"
59#include "Randomize.hh"
60#include "G4DataVector.hh"
62
63//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
64
65using namespace std;
66
68 const G4String& nam)
69 : G4VEmModel(nam)
70{
73 lowestGammaEnergy = 1.0*eV;
74 fTemperature = 1.0*keV;
76}
77
78//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
79
81{}
82
83//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
84
86 const G4DataVector&)
87{
89}
90
91////////////////////////////////////////////////////////////////////////////
92//
93//
94
97 G4double GammaEnergy,
100{
101 G4double xSection = 0.0 ;
102 if ( Z < 0.9999 ) return xSection;
103 if ( GammaEnergy < 0.01*keV ) return xSection;
104 // if ( GammaEnergy > (100.*GeV/Z) ) return xSection;
105
106 static const G4double a = 20.0 , b = 230.0 , c = 440.0;
107
108 static const G4double
109 d1= 2.7965e-1*barn, d2=-1.8300e-1*barn, d3= 6.7527 *barn, d4=-1.9798e+1*barn,
110 e1= 1.9756e-5*barn, e2=-1.0205e-2*barn, e3=-7.3913e-2*barn, e4= 2.7079e-2*barn,
111 f1=-3.9178e-7*barn, f2= 6.8241e-5*barn, f3= 6.0480e-5*barn, f4= 3.0274e-4*barn;
112
113 G4double p1Z = Z*(d1 + e1*Z + f1*Z*Z), p2Z = Z*(d2 + e2*Z + f2*Z*Z),
114 p3Z = Z*(d3 + e3*Z + f3*Z*Z), p4Z = Z*(d4 + e4*Z + f4*Z*Z);
115
116 G4double T0 = 15.0*keV;
117 if (Z < 1.5) T0 = 40.0*keV;
118
119 G4double X = max(GammaEnergy, T0) / electron_mass_c2;
120 xSection = p1Z*std::log(1.+2.*X)/X
121 + (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
122
123 // modification for low energy. (special case for Hydrogen)
124 if (GammaEnergy < T0) {
125 G4double dT0 = 1.*keV;
126 X = (T0+dT0) / electron_mass_c2 ;
127 G4double sigma = p1Z*log(1.+2*X)/X
128 + (p2Z + p3Z*X + p4Z*X*X)/(1. + a*X + b*X*X + c*X*X*X);
129 G4double c1 = -T0*(sigma-xSection)/(xSection*dT0);
130 G4double c2 = 0.150;
131 if (Z > 1.5) c2 = 0.375-0.0556*log(Z);
132 G4double y = log(GammaEnergy/T0);
133 xSection *= exp(-y*(c1+c2*y));
134 }
135 // G4cout << "e= " << GammaEnergy << " Z= " << Z << " cross= " << xSection << G4endl;
136 return xSection;
137}
138
139//////////////////////////////////////////////////////////////////////////
140//
141//
142
143void G4HeatedKleinNishinaCompton::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
145 const G4DynamicParticle* aDynamicGamma,
146 G4double,
147 G4double)
148{
149 // The scattered gamma energy is sampled according to Klein - Nishina formula.
150 // The random number techniques of Butcher & Messel are used
151 // (Nuc Phys 20(1960),15).
152 // Note : Effects due to binding of atomic electrons are negliged.
153
154 // We start to prepare a heated electron from Maxwell distribution.
155 // Then we try to boost to the electron rest frame and make scattering.
156 // The final step is to recover new gamma 4momentum in the lab frame
157
158 G4double eMomentumC2 = CLHEP::RandGamma::shoot(1.5,1.);
159 eMomentumC2 *= 2*electron_mass_c2*fTemperature; // electron (pc)^2
161 eMomDir *= std::sqrt(eMomentumC2);
162 G4double eEnergy = std::sqrt(eMomentumC2+electron_mass_c2*electron_mass_c2);
163 G4LorentzVector electron4v = G4LorentzVector(eMomDir,eEnergy);
164 G4ThreeVector bst = electron4v.boostVector();
165
166 G4LorentzVector gamma4v = aDynamicGamma->Get4Momentum();
167 gamma4v.boost(-bst);
168
169 G4ThreeVector gammaMomV = gamma4v.vect();
170 G4double gamEnergy0 = gammaMomV.mag();
171
172
173 // G4double gamEnergy0 = aDynamicGamma->GetKineticEnergy();
174 G4double E0_m = gamEnergy0 / electron_mass_c2 ;
175
176 // G4ThreeVector gamDirection0 = /aDynamicGamma->GetMomentumDirection();
177
178 G4ThreeVector gamDirection0 = gammaMomV/gamEnergy0;
179
180 // sample the energy rate of the scattered gamma in the electron rest frame
181 //
182
183 G4double epsilon, epsilonsq, onecost, sint2, greject ;
184
185 G4double eps0 = 1./(1. + 2.*E0_m);
186 G4double epsilon0sq = eps0*eps0;
187 G4double alpha1 = - log(eps0);
188 G4double alpha2 = 0.5*(1.- epsilon0sq);
189
190 do
191 {
192 if ( alpha1/(alpha1+alpha2) > G4UniformRand() )
193 {
194 epsilon = exp(-alpha1*G4UniformRand()); // eps0**r
195 epsilonsq = epsilon*epsilon;
196
197 }
198 else
199 {
200 epsilonsq = epsilon0sq + (1.- epsilon0sq)*G4UniformRand();
201 epsilon = sqrt(epsilonsq);
202 };
203
204 onecost = (1.- epsilon)/(epsilon*E0_m);
205 sint2 = onecost*(2.-onecost);
206 greject = 1. - epsilon*sint2/(1.+ epsilonsq);
207
208 } while (greject < G4UniformRand());
209
210 //
211 // scattered gamma angles. ( Z - axis along the parent gamma)
212 //
213
214 G4double cosTeta = 1. - onecost;
215 G4double sinTeta = sqrt (sint2);
216 G4double Phi = twopi * G4UniformRand();
217 G4double dirx = sinTeta*cos(Phi), diry = sinTeta*sin(Phi), dirz = cosTeta;
218
219 //
220 // update G4VParticleChange for the scattered gamma
221 //
222
223 G4ThreeVector gamDirection1 ( dirx,diry,dirz );
224 gamDirection1.rotateUz(gamDirection0);
225 G4double gamEnergy1 = epsilon*gamEnergy0;
226 gamDirection1 *= gamEnergy1;
227
228 G4LorentzVector gamma4vfinal = G4LorentzVector(gamDirection1,gamEnergy1);
229
230
231 // kinematic of the scattered electron
232 //
233
234 G4double eKinEnergy = gamEnergy0 - gamEnergy1;
235 G4ThreeVector eDirection = gamEnergy0*gamDirection0 - gamEnergy1*gamDirection1;
236 eDirection = eDirection.unit();
237 G4double eFinalMom = std::sqrt(eKinEnergy*(eKinEnergy+2*electron_mass_c2));
238 eDirection *= eFinalMom;
239 G4LorentzVector e4vfinal = G4LorentzVector(eDirection,gamEnergy1+electron_mass_c2);
240
241 gamma4vfinal.boost(bst);
242 e4vfinal.boost(bst);
243
244 gamDirection1 = gamma4vfinal.vect();
245 gamEnergy1 = gamDirection1.mag();
246 gamDirection1 /= gamEnergy1;
247
248
249
250
252
253 if( gamEnergy1 > lowestGammaEnergy )
254 {
255 gamDirection1 /= gamEnergy1;
257 }
258 else
259 {
261 gamEnergy1 += fParticleChange->GetLocalEnergyDeposit();
263 }
264
265 eKinEnergy = e4vfinal.t()-electron_mass_c2;
266
267 if( eKinEnergy > DBL_MIN )
268 {
269 // create G4DynamicParticle object for the electron.
270 eDirection = e4vfinal.vect();
271 G4double eFinMomMag = eDirection.mag();
272 eDirection /= eFinMomMag;
273 G4DynamicParticle* dp = new G4DynamicParticle(theElectron,eDirection,eKinEnergy);
274 fvect->push_back(dp);
275 }
276}
277
278//////////////////////////////////////////////////////////////////////////
279
280
CLHEP::HepLorentzVector G4LorentzVector
G4ThreeVector G4RandomDirection()
@ fStopAndKill
double G4double
Definition: G4Types.hh:64
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector unit() const
double mag() const
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:72
Hep3Vector boostVector() const
HepLorentzVector & boost(double, double, double)
Hep3Vector vect() const
static double shoot()
G4LorentzVector Get4Momentum() const
static G4Electron * Electron()
Definition: G4Electron.cc:94
static G4Gamma * Gamma()
Definition: G4Gamma.cc:86
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A, G4double cut, G4double emax)
G4ParticleChangeForGamma * fParticleChange
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
G4HeatedKleinNishinaCompton(const G4ParticleDefinition *p=0, const G4String &nam="Heated-Klein-Nishina")
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:109
void ProposeTrackStatus(G4TrackStatus status)
G4double GetLocalEnergyDeposit() const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
#define DBL_MIN
Definition: templates.hh:75