BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSLaserCumulativeCompton.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2024.
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 "BDSAuxiliaryNavigator.hh"
20#include "BDSComptonEngine.hh"
21#include "BDSComptonScatteringEngine.hh"
22#include "BDSGlobalConstants.hh"
23#include "BDSLaserCumulativeCompton.hh"
24#include "BDSLogicalVolumeLaser.hh"
25#include "BDSStep.hh"
26#include "BDSParticleDefinition.hh"
27#include "globals.hh"
28#include "G4AffineTransform.hh"
29#include "G4Electron.hh"
30#include "G4Gamma.hh"
31#include "G4LogicalVolume.hh"
32#include "G4ParticleTable.hh"
33#include "G4ProcessType.hh"
34#include "G4Proton.hh"
35#include "G4Step.hh"
36#include "G4StepPoint.hh"
37#include "G4ThreeVector.hh"
38#include "G4Track.hh"
39#include "G4TransportationManager.hh"
40#include "G4VPhysicalVolume.hh"
41#include "G4VTouchable.hh"
42#include "Randomize.hh"
43#include "G4RunManager.hh"
44#include "G4RandomTools.hh"
45#include "BDSUserTrackInformation.hh"
46#include "BDSPolarizationState.hh"
47
48
49#include "CLHEP/Units/PhysicalConstants.h"
50#include "CLHEP/Units/SystemOfUnits.h"
51
52#include <cmath>
53#include <limits>
54
55BDSLaserCumulativeCompton::BDSLaserCumulativeCompton(const G4String& processName):
56 G4VDiscreteProcess(processName, G4ProcessType::fElectromagnetic),
57 auxNavigator(new BDSAuxiliaryNavigator()),
58 comptonEngine(new BDSComptonScatteringEngine())
59{;}
60
61BDSLaserCumulativeCompton::~BDSLaserCumulativeCompton()
62{
63 delete auxNavigator;
64}
65
66G4double BDSLaserCumulativeCompton::GetMeanFreePath(const G4Track& track,
67 G4double /*previousStepSize*/,
68 G4ForceCondition* forceCondition)
69{
70
71
73
74 //########### Typical volume check here for process active or not ########################
75
76 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
77 if (!lv->IsExtended()) // not extended so can't be a laser logical volume
78 {return std::numeric_limits<double>::max();}
79
80 BDSLogicalVolumeLaser* lvv = dynamic_cast<BDSLogicalVolumeLaser*>(lv);
81 if (!lvv) // it's an extended volume but not ours (could be a crystal)
82 {return std::numeric_limits<double>::max();}
83
84 *forceCondition = Forced;
85
86 return std::numeric_limits<double>::max();
87}
88
89G4VParticleChange* BDSLaserCumulativeCompton::PostStepDoIt(const G4Track& track,
90 const G4Step& step)
91{
92 aParticleChange.Initialize(track);
93 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
94 if (!lv->IsExtended()) // not extended so can't be a laser logical volume
95 {return pParticleChange;}
96 BDSLogicalVolumeLaser* lvv = dynamic_cast<BDSLogicalVolumeLaser*>(lv);
97 if (!lvv)// it's an extended volume but not ours (could be a crystal)
98 {return pParticleChange;}
99 // else proceed
100
102 BDSUserTrackInformation* trackInfo = dynamic_cast<BDSUserTrackInformation*>(track.GetUserInformation());
103 if (trackInfo->GetComptonScattered())
104 {return pParticleChange;}
105 else
106 {
107 // ############ get particle info
108 const G4DynamicParticle* particle = track.GetDynamicParticle();
109 G4double particleEnergy = particle->GetTotalEnergy();
110 G4ThreeVector particleMomentum = particle->GetMomentum();
111 G4ThreeVector particlePolarization = trackInfo->GetPolarizationState()->GetPolarization();
112
113 G4ThreeVector particleBeta = particleMomentum/particleEnergy;
114 G4double particleGamma = particleEnergy/particle->GetMass();
115 G4double particleVelocity = particleBeta.mag()*CLHEP::c_light;
116 G4LorentzVector particle4VectorMomentum = particle->Get4Momentum();
117 G4int partID = particle->GetParticleDefinition()->GetPDGEncoding();
118
119 G4double particleTimePostStepGlobal = track.GetGlobalTime();
120 G4double particleTimePreStepGlobal = step.GetPreStepPoint()->GetGlobalTime();
121
122 //######### Get particle position and momentum direction ###############################
123 G4ThreeVector particlePositionPostStepGlobal = track.GetPosition();
124 G4ThreeVector particlePositionPreStepGlobal = track.GetStep()->GetPreStepPoint()->GetPosition();
125 G4ThreeVector particleMomentumDirectionGlobal = track.GetStep()->GetPreStepPoint()->GetMomentumDirection();
126 G4ThreeVector stepVector = particlePositionPostStepGlobal-particlePositionPreStepGlobal;
127 G4double stepMagnitude = stepVector.mag();
128
129 //#################### Get rotation and translation matrices for global to laser coordinates ############################
130
131 const G4RotationMatrix* rot = track.GetTouchable()->GetRotation();
132 const G4AffineTransform transform = track.GetTouchable()->GetHistory()->GetTopTransform();
133
134 // ############### Need local pre step points to step through laser ###############
135 G4ThreeVector particlePositionLocal = transform.TransformPoint(particlePositionPreStepGlobal);
136 G4ThreeVector particleMomentumDirectionLocal = transform.TransformPoint(particleMomentumDirectionGlobal).unit();
137
138 //########################## Get Laser #####################################
139 const BDSLaser* laser = lvv->Laser();
140 //######################## Get/Create photon information ##############################
141 G4ThreeVector photonPolarization = laser->Polarization();
142 G4ThreeVector photonUnit(0,0,1);
143
144 // ################ Rotate the photon information to the correct orientation ###########
145 photonPolarization.transform(*rot);
146 particlePolarization.transform(*rot);
147 photonUnit.transform(*rot);
148 G4double photonEnergy = (CLHEP::h_Planck*CLHEP::c_light)/laser->Wavelength();
149
150 // ################ Create a Lorentz Vector for the photon for easy boosting #################
151 G4ThreeVector photonVector = photonUnit*photonEnergy;
152 G4LorentzVector photonLorentz = G4LorentzVector(photonVector,photonEnergy);
153
154 // ################ boost to rest frame #################
155 photonLorentz.boost(-1.0*particleBeta);
156 particle4VectorMomentum.boost(-particleBeta);
157 G4double photonEnergyLorentz = photonLorentz.e();
158
159 //#################### create array and value for the total laser flux
160 G4double photonFluxSum = 0;
161 std::vector<G4double> fluxArray;
162
163 std::vector<G4LorentzVector> trajectoryPositions;
164
165 for(G4int i = 0;i<=99;i++)
166 {
167 G4ThreeVector stepPositionGlobal = particlePositionPreStepGlobal+float(i)*(stepMagnitude/100.)*particleMomentumDirectionGlobal;
168 G4ThreeVector stepPositionLocal = transform.TransformPoint(stepPositionGlobal);
169 G4double particleStepGlobalTime = particleTimePreStepGlobal+((float(i)*(stepMagnitude/100.))/particleVelocity);
170 G4double stepIntensity = ((laser->Intensity(stepPositionLocal)/photonEnergyLorentz)
171 * laser->TemporalProfileGaussian(particleStepGlobalTime,stepPositionLocal.z()));
172 photonFluxSum = photonFluxSum + stepIntensity;
173 fluxArray.push_back(stepIntensity);
174 }
175
176 G4double crossSection = comptonEngine->CrossSection(photonEnergyLorentz,partID);
177
178 G4double stepTime = ((particleTimePostStepGlobal-particleTimePreStepGlobal)*particleGamma)/100.;//divide by 100 for the 100 steps taken
179 G4double cumulativeProbability = 1.0 - std::exp(-1.0*crossSection*photonFluxSum*stepTime);
180 G4double secondaryStepPosition;
181
182 if(photonFluxSum == 0)
183 {secondaryStepPosition = G4UniformRand();}
184 else
185 {
186 G4RandGeneral trajectoryPDFRandom = CLHEP::RandGeneral(*CLHEP::HepRandom::getTheEngine(),
187 fluxArray.data(),100,0);
188 secondaryStepPosition = trajectoryPDFRandom.shoot();
189 }
190
191 G4ThreeVector proposedPositionGlobal = particlePositionPreStepGlobal + (stepMagnitude*secondaryStepPosition*particleMomentumDirectionGlobal);
192 G4double proposedTime = particleTimePreStepGlobal + (stepMagnitude*secondaryStepPosition/particleVelocity);
193
194 aParticleChange.ProposePosition(proposedPositionGlobal);
195 G4double initialWeight=aParticleChange.GetParentWeight();
196 aParticleChange.ProposeParentWeight(initialWeight*cumulativeProbability);
197 aParticleChange.SetNumberOfSecondaries(1);
198 comptonEngine->setIncomingElectron(particle4VectorMomentum);
199 comptonEngine->setIncomingGamma(photonLorentz);
200 comptonEngine->SetIncomingGammaPolarization(G4StokesVector(photonPolarization));
201 comptonEngine->SetIncomingElectronPolarization(G4StokesVector(particlePolarization));
202 comptonEngine->PerformCompton(particleBeta,partID);
203 G4LorentzVector scatteredGamma = comptonEngine->GetScatteredGamma();
204 G4DynamicParticle* gamma = new G4DynamicParticle(G4Gamma::Gamma(),
205 scatteredGamma.vect().unit(),// direction
206 scatteredGamma.e());
207
208 G4LorentzVector scatteredParticle = comptonEngine->GetScatteredElectron();
209 G4LorentzVector particleLorentz = G4LorentzVector(scatteredParticle.vect().unit(),scatteredParticle.e());
210 aParticleChange.AddSecondary(gamma,proposedTime);
211 aParticleChange.ProposeEnergy(particleLorentz.e());
212 aParticleChange.ProposeMomentumDirection(particleLorentz.getX(),particleLorentz.getY(),particleLorentz.getZ());
213 aParticleChange.ProposePosition(particlePositionPreStepGlobal + particleLorentz.vect()*stepVector.mag());
214 trackInfo->setComptonScatteredTrue();
215 return G4VDiscreteProcess::PostStepDoIt(track, step);
216 }
217}
Extra G4Navigator to get coordinate transforms.
Class to provide laser intensity at any point.
Definition BDSLaser.hh:36
G4double Wavelength() const
Accessor.
Definition BDSLaser.hh:64
G4ThreeVector Polarization() const
Accessor.
Definition BDSLaser.hh:72
Extended logical volume with laser definition.
const BDSLaser * Laser() const
Access the laser.