Geant4-11
G4MollerBhabhaModel.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//
27// -------------------------------------------------------------------
28//
29// GEANT4 Class file
30//
31//
32// File name: G4MollerBhabhaModel
33//
34// Author: Vladimir Ivanchenko on base of Laszlo Urban code
35//
36// Creation date: 03.01.2002
37//
38// Modifications:
39//
40// 13-11-02 Minor fix - use normalised direction (V.Ivanchenko)
41// 04-12-02 Change G4DynamicParticle constructor in PostStepDoIt (V.Ivanchenko)
42// 23-12-02 Change interface in order to move to cut per region (V.Ivanchenko)
43// 27-01-03 Make models region aware (V.Ivanchenko)
44// 13-02-03 Add name (V.Ivanchenko)
45// 08-04-05 Major optimisation of internal interfaces (V.Ivantchenko)
46// 25-07-05 Add protection in calculation of recoil direction for the case
47// of complete energy transfer from e+ to e- (V.Ivanchenko)
48// 06-02-06 ComputeCrossSectionPerElectron, ComputeCrossSectionPerAtom (mma)
49// 15-05-06 Fix MinEnergyCut (V.Ivanchenko)
50//
51//
52// Class Description:
53//
54// Implementation of energy loss and delta-electron production by e+/e-
55//
56// -------------------------------------------------------------------
57//
58//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
59//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
60
63#include "G4SystemOfUnits.hh"
64#include "G4Electron.hh"
65#include "G4Positron.hh"
66#include "Randomize.hh"
68#include "G4Log.hh"
69#include "G4DeltaAngle.hh"
70
71//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
72
73using namespace std;
74
76 const G4String& nam)
77 : G4VEmModel(nam),
78 particle(nullptr),
79 isElectron(true),
80 twoln10(2.0*G4Log(10.0)),
81 lowLimit(0.02*keV),
82 isInitialised(false)
83{
85 if(nullptr != p) { SetParticle(p); }
86 fParticleChange = nullptr;
87}
88
89//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
90
92{}
93
94//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
95
97 G4double kinEnergy)
98{
99 G4double tmax = kinEnergy;
100 if(isElectron) { tmax *= 0.5; }
101 return tmax;
102}
103
104//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
105
107 const G4DataVector&)
108{
109 if(p != particle) { SetParticle(p); }
110
111 if(isInitialised) { return; }
112
113 isInitialised = true;
117 }
118}
119
120//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
121
123 const G4ParticleDefinition* p, G4double kineticEnergy,
124 G4double cutEnergy, G4double maxEnergy)
125{
126 if(p != particle) { SetParticle(p); }
127
128 G4double cross = 0.0;
129 G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
130 tmax = std::min(maxEnergy, tmax);
131 //G4cout << "E= " << kineticEnergy << " cut= " << cutEnergy
132 // << " Emax= " << tmax << G4endl;
133 if(cutEnergy < tmax) {
134
135 G4double xmin = cutEnergy/kineticEnergy;
136 G4double xmax = tmax/kineticEnergy;
137 G4double tau = kineticEnergy/electron_mass_c2;
138 G4double gam = tau + 1.0;
139 G4double gamma2= gam*gam;
140 G4double beta2 = tau*(tau + 2)/gamma2;
141
142 //Moller (e-e-) scattering
143 if (isElectron) {
144
145 G4double gg = (2.0*gam - 1.0)/gamma2;
146 cross = ((xmax - xmin)*(1.0 - gg + 1.0/(xmin*xmax)
147 + 1.0/((1.0-xmin)*(1.0 - xmax)))
148 - gg*G4Log( xmax*(1.0 - xmin)/(xmin*(1.0 - xmax)) ) ) / beta2;
149
150 //Bhabha (e+e-) scattering
151 } else {
152
153 G4double y = 1.0/(1.0 + gam);
154 G4double y2 = y*y;
155 G4double y12 = 1.0 - 2.0*y;
156 G4double b1 = 2.0 - y2;
157 G4double b2 = y12*(3.0 + y2);
158 G4double y122= y12*y12;
159 G4double b4 = y122*y12;
160 G4double b3 = b4 + y122;
161
162 cross = (xmax - xmin)*(1.0/(beta2*xmin*xmax) + b2
163 - 0.5*b3*(xmin + xmax)
164 + b4*(xmin*xmin + xmin*xmax + xmax*xmax)/3.0)
165 - b1*G4Log(xmax/xmin);
166 }
167
168 cross *= twopi_mc2_rcl2/kineticEnergy;
169 }
170 return cross;
171}
172
173//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
174
176 const G4ParticleDefinition* p,
177 G4double kineticEnergy,
179 G4double cutEnergy,
180 G4double maxEnergy)
181{
182 return Z*ComputeCrossSectionPerElectron(p,kineticEnergy,cutEnergy,maxEnergy);
183}
184
185//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
186
188 const G4Material* material,
189 const G4ParticleDefinition* p,
190 G4double kinEnergy,
191 G4double cutEnergy,
192 G4double maxEnergy)
193{
194 G4double eDensity = material->GetElectronDensity();
195 return eDensity*ComputeCrossSectionPerElectron(p,kinEnergy,cutEnergy,maxEnergy);
196}
197
198//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
199
201 const G4Material* material,
202 const G4ParticleDefinition* p,
203 G4double kineticEnergy,
204 G4double cut)
205{
206 if(p != particle) { SetParticle(p); }
207 // calculate the dE/dx due to the ionization by Seltzer-Berger formula
208 // checl low-energy limit
209 G4double electronDensity = material->GetElectronDensity();
210
211 G4double Zeff = material->GetIonisation()->GetZeffective();
212 G4double th = 0.25*sqrt(Zeff)*keV;
213 G4double tkin = std::max(kineticEnergy, th);
214
215 G4double tau = tkin/electron_mass_c2;
216 G4double gam = tau + 1.0;
217 G4double gamma2= gam*gam;
218 G4double bg2 = tau*(tau + 2);
219 G4double beta2 = bg2/gamma2;
220
221 G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
222 eexc /= electron_mass_c2;
223 G4double eexc2 = eexc*eexc;
224
226 G4double dedx;
227
228 // electron
229 if (isElectron) {
230
231 dedx = G4Log(2.0*(tau + 2.0)/eexc2) - 1.0 - beta2
232 + G4Log((tau-d)*d) + tau/(tau-d)
233 + (0.5*d*d + (2.0*tau + 1.)*G4Log(1. - d/tau))/gamma2;
234
235 //positron
236 } else {
237
238 G4double d2 = d*d*0.5;
239 G4double d3 = d2*d/1.5;
240 G4double d4 = d3*d*0.75;
241 G4double y = 1.0/(1.0 + gam);
242 dedx = G4Log(2.0*(tau + 2.0)/eexc2) + G4Log(tau*d)
243 - beta2*(tau + 2.0*d - y*(3.0*d2
244 + y*(d - d3 + y*(d2 - tau*d3 + d4))))/tau;
245 }
246
247 //density correction
248 G4double x = G4Log(bg2)/twoln10;
249 dedx -= material->GetIonisation()->DensityCorrection(x);
250
251 // now you can compute the total ionization loss
252 dedx *= twopi_mc2_rcl2*electronDensity/beta2;
253 if (dedx < 0.0) { dedx = 0.0; }
254
255 // lowenergy extrapolation
256
257 if (kineticEnergy < th) {
258 x = kineticEnergy/th;
259 if(x > 0.25) { dedx /= sqrt(x); }
260 else { dedx *= 1.4*sqrt(x)/(0.1 + x); }
261 }
262 return dedx;
263}
264
265//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
266
267void
268G4MollerBhabhaModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
269 const G4MaterialCutsCouple* couple,
270 const G4DynamicParticle* dp,
271 G4double cutEnergy,
272 G4double maxEnergy)
273{
274 G4double kineticEnergy = dp->GetKineticEnergy();
275 //G4cout << "G4MollerBhabhaModel::SampleSecondaries: E= " << kineticEnergy
276 // << " in " << couple->GetMaterial()->GetName() << G4endl;
277 G4double tmax;
278 G4double tmin = cutEnergy;
279 if(isElectron) {
280 tmax = 0.5*kineticEnergy;
281 } else {
282 tmax = kineticEnergy;
283 }
284 if(maxEnergy < tmax) { tmax = maxEnergy; }
285 if(tmin >= tmax) { return; }
286
287 G4double energy = kineticEnergy + electron_mass_c2;
288 G4double xmin = tmin/kineticEnergy;
289 G4double xmax = tmax/kineticEnergy;
291 G4double gamma2 = gam*gam;
292 G4double beta2 = 1.0 - 1.0/gamma2;
293 G4double x, z, grej;
294 CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
295 G4double rndm[2];
296
297 //Moller (e-e-) scattering
298 if (isElectron) {
299
300 G4double gg = (2.0*gam - 1.0)/gamma2;
301 G4double y = 1.0 - xmax;
302 grej = 1.0 - gg*xmax + xmax*xmax*(1.0 - gg + (1.0 - gg*y)/(y*y));
303
304 do {
305 rndmEngine->flatArray(2, rndm);
306 x = xmin*xmax/(xmin*(1.0 - rndm[0]) + xmax*rndm[0]);
307 y = 1.0 - x;
308 z = 1.0 - gg*x + x*x*(1.0 - gg + (1.0 - gg*y)/(y*y));
309 /*
310 if(z > grej) {
311 G4cout << "G4MollerBhabhaModel::SampleSecondary Warning! "
312 << "Majorant " << grej << " < "
313 << z << " for x= " << x
314 << " e-e- scattering"
315 << G4endl;
316 }
317 */
318 // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
319 } while(grej * rndm[1] > z);
320
321 //Bhabha (e+e-) scattering
322 } else {
323
324 G4double y = 1.0/(1.0 + gam);
325 G4double y2 = y*y;
326 G4double y12 = 1.0 - 2.0*y;
327 G4double b1 = 2.0 - y2;
328 G4double b2 = y12*(3.0 + y2);
329 G4double y122= y12*y12;
330 G4double b4 = y122*y12;
331 G4double b3 = b4 + y122;
332
333 y = xmax*xmax;
334 grej = 1.0 + (y*y*b4 - xmin*xmin*xmin*b3 + y*b2 - xmin*b1)*beta2;
335 do {
336 rndmEngine->flatArray(2, rndm);
337 x = xmin*xmax/(xmin*(1.0 - rndm[0]) + xmax*rndm[0]);
338 y = x*x;
339 z = 1.0 + (y*y*b4 - x*y*b3 + y*b2 - x*b1)*beta2;
340 /*
341 if(z > grej) {
342 G4cout << "G4MollerBhabhaModel::SampleSecondary Warning! "
343 << "Majorant " << grej << " < "
344 << z << " for x= " << x
345 << " e+e- scattering"
346 << G4endl;
347 }
348 */
349 // Loop checking, 03-Aug-2015, Vladimir Ivanchenko
350 } while(grej * rndm[1] > z);
351 }
352
353 G4double deltaKinEnergy = x * kineticEnergy;
354
355 G4ThreeVector deltaDirection;
356
358 const G4Material* mat = couple->GetMaterial();
360
361 deltaDirection =
362 GetAngularDistribution()->SampleDirection(dp, deltaKinEnergy, Z, mat);
363
364 } else {
365
366 G4double deltaMomentum =
367 sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
368 G4double cost = deltaKinEnergy * (energy + electron_mass_c2) /
369 (deltaMomentum * dp->GetTotalMomentum());
370 if(cost > 1.0) { cost = 1.0; }
371 G4double sint = sqrt((1.0 - cost)*(1.0 + cost));
372
373 G4double phi = twopi * rndmEngine->flat() ;
374
375 deltaDirection.set(sint*cos(phi),sint*sin(phi), cost) ;
376 deltaDirection.rotateUz(dp->GetMomentumDirection());
377 }
378
379 // create G4DynamicParticle object for delta ray
380 G4DynamicParticle* delta =
381 new G4DynamicParticle(theElectron,deltaDirection,deltaKinEnergy);
382 vdp->push_back(delta);
383
384 // primary change
385 kineticEnergy -= deltaKinEnergy;
386 G4ThreeVector finalP = dp->GetMomentum() - delta->GetMomentum();
387 finalP = finalP.unit();
388
391}
392
393//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
static const G4double d2
G4double G4Log(G4double x)
Definition: G4Log.hh:226
static constexpr double twopi
Definition: G4SIunits.hh:56
static constexpr double keV
Definition: G4SIunits.hh:202
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
Hep3Vector unit() const
void set(double x, double y, double z)
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
virtual double flat()=0
virtual void flatArray(const int size, double *vect)=0
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4ThreeVector GetMomentum() const
G4double GetTotalMomentum() const
static G4Electron * Electron()
Definition: G4Electron.cc:93
const G4Material * GetMaterial() const
const G4ParticleDefinition * particle
void SetParticle(const G4ParticleDefinition *p)
G4ParticleChangeForLoss * fParticleChange
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kineticEnergy, G4double Z, G4double A, G4double cutEnergy, G4double maxEnergy) override
G4MollerBhabhaModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="MollerBhabha")
G4ParticleDefinition * theElectron
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
G4double ComputeDEDXPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy) override
virtual G4double ComputeCrossSectionPerElectron(const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy)
G4double MaxSecondaryEnergy(const G4ParticleDefinition *, G4double kinEnergy) final
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy) override
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void SetProposedMomentumDirection(const G4ThreeVector &dir)
virtual G4ThreeVector & SampleDirection(const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, const G4Material *)=0
G4VEmAngularDistribution * GetAngularDistribution()
Definition: G4VEmModel.hh:621
G4int SelectRandomAtomNumber(const G4Material *)
Definition: G4VEmModel.cc:297
void SetAngularDistribution(G4VEmAngularDistribution *)
Definition: G4VEmModel.hh:628
G4bool UseAngularGeneratorFlag() const
Definition: G4VEmModel.hh:718
G4ParticleChangeForLoss * GetParticleChangeForLoss()
Definition: G4VEmModel.cc:108
G4double energy(const ThreeVector &p, const G4double m)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4bool isElectron(G4int ityp)
string material
Definition: eplot.py:19
float electron_mass_c2
Definition: hepunit.py:273
int twopi_mc2_rcl2
Definition: hepunit.py:293