BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSComptonEngine.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSComptonEngine.hh"
20
21#include "G4ios.hh"
22#include "G4LorentzRotation.hh"
23#include "G4ThreeVector.hh"
24
25#include "Randomize.hh"
26#include "CLHEP/Units/PhysicalConstants.h"
27
28#include <cmath>
29
30BDSComptonEngine::BDSComptonEngine(){;}
31
32BDSComptonEngine::BDSComptonEngine(G4LorentzVector InGam,
33 G4LorentzVector InEl):
34 itsIncomingEl(InEl),itsIncomingGam(InGam)
35{
36 if(itsIncomingGam.e()<=0.)
37 {G4Exception("BDSComptonEngine: Invalid Photon Energy", "-1", FatalException, "");}
38}
39
40BDSComptonEngine::~BDSComptonEngine(){;}
41
42void BDSComptonEngine::PerformCompton()
43{
44 // Generate compton event; using method described in
45 // H.Burkardt, SL/Note 93-73
46
47 G4double phi = CLHEP::twopi * G4UniformRand();
48 G4double sinphi = std::sin(phi);
49 G4double cosphi = std::cos(phi);
50
51 G4int ntry=0;
52
53 G4LorentzVector GamInLab;
54 G4double x;
55 G4ThreeVector Boost;
56 G4double costh, costh2,sinth,sinth2;
57
58 Boost = itsIncomingEl.boostVector();
59 // BoostToLab.boost(-Boost);
60 G4LorentzRotation BoostToLab(-Boost);
61 GamInLab=BoostToLab*(itsIncomingGam);
62 G4ThreeVector LabGammaDir= GamInLab.vect().unit();
63
64 G4double weight_CovT=0; //ratio of Compton to Thompson cross sections:
65 do {ntry++;
66 // 1+cos^2 theta distribution
67 if(G4UniformRand()>0.25)
68 {costh=2.*G4UniformRand()-1.;}
69 else
70 {
71 costh=G4UniformRand();
72 G4double r1=G4UniformRand();
73 G4double r2=G4UniformRand();
74 if(r1>costh)
75 {costh=r1;}
76 if(r2>costh)
77 {costh=r2;}
78 if(G4UniformRand()<0.5)
79 {costh=-costh;}
80 }
81
82 costh2=costh*costh;
83 sinth2=1.-costh2;
84
85 // x is ratio of scattered to unscattered photon energy:
86 x = 1/(1+ GamInLab.e()*(1-costh)/CLHEP::electron_mass_c2);
87
88 //calculate weight of Compton relative to Thompson cross sections:
89 weight_CovT= x* x * (x+1/x-sinth2)/(1+costh2);
90 } while(ntry<ntryMax && G4UniformRand()>weight_CovT);
91
92 if(ntry==ntryMax)
93 {G4Exception("BDSComptonEngine:Max number of loops exceeded", "-1", FatalException, "");}
94
95 // G4LorentzVector ElInLab=BoostToLab*(itsIncomingEl);
96
97 G4double Egam = x * GamInLab.e();
98
99 // Generate final momenta:
100
101 sinth=std::sqrt(sinth2);
102 itsScatteredGam.setPx(Egam*sinth*cosphi);
103 itsScatteredGam.setPy(Egam*sinth*sinphi);
104 itsScatteredGam.setPz(Egam*costh);
105 itsScatteredGam.setE(Egam);
106
107 itsScatteredEl.setPx(-itsScatteredGam.px());
108 itsScatteredEl.setPy(-itsScatteredGam.py());
109 itsScatteredEl.setPz(GamInLab.e()-itsScatteredGam.pz());
110 itsScatteredEl.setE( std::sqrt( std::pow(CLHEP::electron_mass_c2,2) +
111 std::pow(itsScatteredEl.px(),2)+
112 std::pow(itsScatteredEl.py(),2)+
113 std::pow(itsScatteredEl.pz(),2) ) );
114
115 // Rotates the reference frame from Uz to newUz (unit vector).
116 itsScatteredGam.rotateUz(LabGammaDir);
117 itsScatteredEl.rotateUz(LabGammaDir);
118
119 // now boost back to the original frame:
120 G4LorentzRotation BoostFromLab(Boost);
121 itsScatteredGam *= BoostFromLab;
122 itsScatteredEl *= BoostFromLab;
123}