Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4BoldyshevTripletModel.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// GEANT4 tag $Name: $
28//
29//
30// Author: Gerardo Depaola & Francesco Longo
31//
32// History:
33// --------
34// 23-06-2010 First implementation as model
35
36
39#include "G4SystemOfUnits.hh"
40
41//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
42
43using namespace std;
44
45//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
46
48 const G4String& nam)
49 :G4VEmModel(nam),fParticleChange(0),smallEnergy(4.*MeV),isInitialised(false),
50 crossSectionHandler(0),meanFreePathTable(0)
51{
52 lowEnergyLimit = 4.0*electron_mass_c2;
53 highEnergyLimit = 100 * GeV;
54 SetHighEnergyLimit(highEnergyLimit);
55
56 verboseLevel= 0;
57 // Verbosity scale:
58 // 0 = nothing
59 // 1 = warning for energy non-conservation
60 // 2 = details of energy budget
61 // 3 = calculation of cross sections, file openings, sampling of atoms
62 // 4 = entering in methods
63
64 if(verboseLevel > 0) {
65 G4cout << "Triplet Gamma conversion is constructed " << G4endl
66 << "Energy range: "
67 << lowEnergyLimit / MeV << " MeV - "
68 << highEnergyLimit / GeV << " GeV"
69 << G4endl;
70 }
71}
72
73//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
74
76{
77 if (crossSectionHandler) delete crossSectionHandler;
78}
79
80//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
81
82void
84 const G4DataVector&)
85{
86 if (verboseLevel > 3)
87 G4cout << "Calling G4BoldyshevTripletModel::Initialise()" << G4endl;
88
89 if (crossSectionHandler)
90 {
91 crossSectionHandler->Clear();
92 delete crossSectionHandler;
93 }
94
95 // Read data tables for all materials
96
97 crossSectionHandler = new G4CrossSectionHandler();
98 crossSectionHandler->Initialise(0,lowEnergyLimit,100.*GeV,400);
99 G4String crossSectionFile = "tripdata/pp-trip-cs-"; // here only pair in electron field cs should be used
100 crossSectionHandler->LoadData(crossSectionFile);
101
102 //
103
104 if (verboseLevel > 0) {
105 G4cout << "Loaded cross section files for Livermore GammaConversion" << G4endl;
106 G4cout << "To obtain the total cross section this should be used only " << G4endl
107 << "in connection with G4NuclearGammaConversion " << G4endl;
108 }
109
110 if (verboseLevel > 0) {
111 G4cout << "Livermore Electron Gamma Conversion model is initialized " << G4endl
112 << "Energy range: "
113 << LowEnergyLimit() / MeV << " MeV - "
114 << HighEnergyLimit() / GeV << " GeV"
115 << G4endl;
116 }
117
118 if(isInitialised) return;
120 isInitialised = true;
121}
122
123//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
124
127 G4double GammaEnergy,
130{
131 if (verboseLevel > 3) {
132 G4cout << "Calling ComputeCrossSectionPerAtom() of G4BoldyshevTripletModel"
133 << G4endl;
134 }
135 if (GammaEnergy < lowEnergyLimit || GammaEnergy > highEnergyLimit) return 0;
136
137 G4double cs = crossSectionHandler->FindValue(G4int(Z), GammaEnergy);
138 return cs;
139}
140
141//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
142
143void G4BoldyshevTripletModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
144 const G4MaterialCutsCouple* ,
145 const G4DynamicParticle* aDynamicGamma,
146 G4double,
147 G4double)
148{
149
150// The energies of the secondary particles are sampled using
151// a modified Wheeler-Lamb model (see PhysRevD 7 (1973), 26)
152
153 if (verboseLevel > 3)
154 G4cout << "Calling SampleSecondaries() of G4BoldyshevTripletModel" << G4endl;
155
156 G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
157 G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
158
159 G4double epsilon ;
160 G4double p0 = electron_mass_c2;
161
162 G4double positronTotEnergy, electronTotEnergy, thetaEle, thetaPos;
163 G4double ener_re=0., theta_re, phi_re, phi;
164
165 // Calculo de theta - elecron de recoil
166
167 G4double energyThreshold = sqrt(2.)*electron_mass_c2; // -> momentumThreshold_N = 1
168 energyThreshold = 1.1*electron_mass_c2;
169 // G4cout << energyThreshold << G4endl;
170
171 G4double momentumThreshold_c = sqrt(energyThreshold * energyThreshold - electron_mass_c2*electron_mass_c2); // momentun in MeV/c unit
172 G4double momentumThreshold_N = momentumThreshold_c/electron_mass_c2; // momentun in mc unit
173
174 // Calculation of recoil electron production
175
176 G4double SigmaTot = (28./9.) * std::log ( 2.* photonEnergy / electron_mass_c2 ) - 218. / 27. ;
177 G4double X_0 = 2. * ( sqrt(momentumThreshold_N*momentumThreshold_N + 1) -1 );
178 G4double SigmaQ = (82./27. - (14./9.) * log (X_0) + 4./15.*X_0 - 0.0348 * X_0 * X_0);
179 G4double recoilProb = G4UniformRand();
180 //G4cout << "SIGMA TOT " << SigmaTot << " " << "SigmaQ " << SigmaQ << " " << SigmaQ/SigmaTot << " " << recoilProb << G4endl;
181
182 if (recoilProb >= SigmaQ/SigmaTot) // create electron recoil
183 {
184
185 G4double cosThetaMax = ( ( energyThreshold - electron_mass_c2 ) / (momentumThreshold_c) + electron_mass_c2*
186 ( energyThreshold + electron_mass_c2 ) / (photonEnergy*momentumThreshold_c) );
187
188 if (cosThetaMax > 1) G4cout << "ERRORE " << G4endl;
189
190 G4double r1;
191 G4double r2;
192 G4double are, bre, loga, f1_re, greject, cost;
193
194 do {
195 r1 = G4UniformRand();
196 r2 = G4UniformRand();
197 // cost = (pow(4./enern,0.5*r1)) ;
198 cost = pow(cosThetaMax,r1);
199 theta_re = acos(cost);
200 are = 1./(14.*cost*cost);
201 bre = (1.-5.*cost*cost)/(2.*cost);
202 loga = log((1.+ cost)/(1.- cost));
203 f1_re = 1. - bre*loga;
204
205 if ( theta_re >= 4.47*CLHEP::pi/180.)
206 {
207 greject = are*f1_re;
208 } else {
209 greject = 1. ;
210 }
211 } while(greject < r2);
212
213 // Calculo de phi - elecron de recoil
214
215 G4double r3, r4, rt;
216
217 do {
218
219 r3 = G4UniformRand();
220 r4 = G4UniformRand();
221 phi_re = twopi*r3 ;
222 G4double sint2 = 1. - cost*cost ;
223 G4double fp = 1. - sint2*loga/(2.*cost) ;
224 rt = (1.-cos(2.*phi_re)*fp/f1_re)/(2.*pi) ;
225
226 } while(rt < r4);
227
228 // Calculo de la energia - elecron de recoil - relacion momento maximo <-> angulo
229
230 G4double S = electron_mass_c2*(2.* photonEnergy + electron_mass_c2);
231 G4double D2 = 4.*S * electron_mass_c2*electron_mass_c2
232 + (S - electron_mass_c2*electron_mass_c2)
233 *(S - electron_mass_c2*electron_mass_c2)*sin(theta_re)*sin(theta_re);
234 ener_re = electron_mass_c2 * (S + electron_mass_c2*electron_mass_c2)/sqrt(D2);
235
236 // G4cout << "electron de retroceso " << ener_re << " " << theta_re << " " << phi_re << G4endl;
237
238 // Recoil electron creation
239 G4double dxEle_re=sin(theta_re)*std::cos(phi_re),dyEle_re=sin(theta_re)*std::sin(phi_re), dzEle_re=cos(theta_re);
240
241 G4double electronRKineEnergy = std::max(0.,ener_re - electron_mass_c2) ;
242
243 G4ThreeVector electronRDirection (dxEle_re, dyEle_re, dzEle_re);
244 electronRDirection.rotateUz(photonDirection);
245
247 electronRDirection,
248 electronRKineEnergy);
249 fvect->push_back(particle3);
250
251 }
252 else
253 {
254 // deposito la energia ener_re - electron_mass_c2
255 // G4cout << "electron de retroceso " << ener_re << G4endl;
256 fParticleChange->ProposeLocalEnergyDeposit(ener_re - electron_mass_c2);
257 }
258
259 // Depaola (2004) suggested distribution for e+e- energy
260
261 // G4double t = 0.5*asinh(momentumThreshold_N);
262 G4double t = 0.5*log(momentumThreshold_N + sqrt(momentumThreshold_N*momentumThreshold_N+1));
263
264 G4cout << 0.5*asinh(momentumThreshold_N) << " " << t << G4endl;
265
266 G4double J1 = 0.5*(t*cosh(t)/sinh(t) - log(2.*sinh(t)));
267 G4double J2 = (-2./3.)*log(2.*sinh(t)) + t*cosh(t)/sinh(t) + (sinh(t)-t*pow(cosh(t),3))/(3.*pow(sinh(t),3));
268 G4double b = 2.*(J1-J2)/J1;
269
270 G4double n = 1 - b/6.;
271 G4double re=0.;
272 re = G4UniformRand();
273 G4double a = 0.;
274 G4double b1 = 16. - 3.*b - 36.*b*re*n + 36.*b*pow(re,2.)*pow(n,2.) +
275 6.*pow(b,2.)*re*n;
276 a = pow((b1/b),0.5);
277 G4double c1 = (-6. + 12.*re*n + b + 2*a)*pow(b,2.);
278 epsilon = (pow(c1,1./3.))/(2.*b) + (b-4.)/(2.*pow(c1,1./3.))+0.5;
279
280 G4double photonEnergy1 = photonEnergy - ener_re ; // resto al foton la energia del electron de retro.
281 positronTotEnergy = epsilon*photonEnergy1;
282 electronTotEnergy = photonEnergy1 - positronTotEnergy; // temporarly
283
284 G4double momento_e = sqrt(electronTotEnergy*electronTotEnergy -
285 electron_mass_c2*electron_mass_c2) ;
286 G4double momento_p = sqrt(positronTotEnergy*positronTotEnergy -
287 electron_mass_c2*electron_mass_c2) ;
288
289 thetaEle = acos((sqrt(p0*p0/(momento_e*momento_e) +1.)- p0/momento_e)) ;
290 thetaPos = acos((sqrt(p0*p0/(momento_p*momento_p) +1.)- p0/momento_p)) ;
291 phi = twopi * G4UniformRand();
292
293 G4double dxEle= std::sin(thetaEle)*std::cos(phi),dyEle= std::sin(thetaEle)*std::sin(phi),dzEle=std::cos(thetaEle);
294 G4double dxPos=-std::sin(thetaPos)*std::cos(phi),dyPos=-std::sin(thetaPos)*std::sin(phi),dzPos=std::cos(thetaPos);
295
296
297 // Kinematics of the created pair:
298 // the electron and positron are assumed to have a symetric angular
299 // distribution with respect to the Z axis along the parent photon
300
301 G4double electronKineEnergy = std::max(0.,electronTotEnergy - electron_mass_c2) ;
302
303 // SI - The range test has been removed wrt original G4LowEnergyGammaconversion class
304
305 G4ThreeVector electronDirection (dxEle, dyEle, dzEle);
306 electronDirection.rotateUz(photonDirection);
307
309 electronDirection,
310 electronKineEnergy);
311
312 // The e+ is always created (even with kinetic energy = 0) for further annihilation
313 G4double positronKineEnergy = std::max(0.,positronTotEnergy - electron_mass_c2) ;
314
315 // SI - The range test has been removed wrt original G4LowEnergyGammaconversion class
316
317 G4ThreeVector positronDirection (dxPos, dyPos, dzPos);
318 positronDirection.rotateUz(photonDirection);
319
320 // Create G4DynamicParticle object for the particle2
322 positronDirection, positronKineEnergy);
323 // Fill output vector
324
325
326 fvect->push_back(particle1);
327 fvect->push_back(particle2);
328
329
330
331
332 // kill incident photon
335
336}
337
338//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
339
340
341
342
@ fStopAndKill
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:72
G4BoldyshevTripletModel(const G4ParticleDefinition *p=0, const G4String &nam="BoldyshevTriplet")
G4ParticleChangeForGamma * fParticleChange
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)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition: G4Electron.cc:94
void SetProposedKineticEnergy(G4double proposedKinEnergy)
static G4Positron * Positron()
Definition: G4Positron.cc:94
G4double FindValue(G4int Z, G4double e) const
void LoadData(const G4String &dataFile)
void Initialise(G4VDataSetAlgorithm *interpolation=0, G4double minE=250 *CLHEP::eV, G4double maxE=100 *CLHEP::GeV, G4int numberOfBins=200, G4double unitE=CLHEP::MeV, G4double unitData=CLHEP::barn, G4int minZ=1, G4int maxZ=99)
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:585
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:109
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:529
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:522
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)