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