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