19#include "BDSAuxiliaryNavigator.hh"
20#include "BDSComptonEngine.hh"
21#include "BDSComptonScatteringEngine.hh"
22#include "BDSGlobalConstants.hh"
23#include "BDSLaserCumulativeCompton.hh"
24#include "BDSLogicalVolumeLaser.hh"
26#include "BDSParticleDefinition.hh"
28#include "G4AffineTransform.hh"
29#include "G4Electron.hh"
31#include "G4LogicalVolume.hh"
32#include "G4ParticleTable.hh"
33#include "G4ProcessType.hh"
36#include "G4StepPoint.hh"
37#include "G4ThreeVector.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"
49#include "CLHEP/Units/PhysicalConstants.h"
50#include "CLHEP/Units/SystemOfUnits.h"
55BDSLaserCumulativeCompton::BDSLaserCumulativeCompton(
const G4String& processName):
56 G4VDiscreteProcess(processName, G4ProcessType::fElectromagnetic),
61BDSLaserCumulativeCompton::~BDSLaserCumulativeCompton()
66G4double BDSLaserCumulativeCompton::GetMeanFreePath(
const G4Track& track,
68 G4ForceCondition* forceCondition)
76 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
77 if (!lv->IsExtended())
78 {
return std::numeric_limits<double>::max();}
82 {
return std::numeric_limits<double>::max();}
84 *forceCondition = Forced;
86 return std::numeric_limits<double>::max();
89G4VParticleChange* BDSLaserCumulativeCompton::PostStepDoIt(
const G4Track& track,
92 aParticleChange.Initialize(track);
93 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
94 if (!lv->IsExtended())
95 {
return pParticleChange;}
98 {
return pParticleChange;}
103 if (trackInfo->GetComptonScattered())
104 {
return pParticleChange;}
108 const G4DynamicParticle* particle = track.GetDynamicParticle();
109 G4double particleEnergy = particle->GetTotalEnergy();
110 G4ThreeVector particleMomentum = particle->GetMomentum();
111 G4ThreeVector particlePolarization = trackInfo->GetPolarizationState()->GetPolarization();
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();
119 G4double particleTimePostStepGlobal = track.GetGlobalTime();
120 G4double particleTimePreStepGlobal = step.GetPreStepPoint()->GetGlobalTime();
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();
131 const G4RotationMatrix* rot = track.GetTouchable()->GetRotation();
132 const G4AffineTransform transform = track.GetTouchable()->GetHistory()->GetTopTransform();
135 G4ThreeVector particlePositionLocal = transform.TransformPoint(particlePositionPreStepGlobal);
136 G4ThreeVector particleMomentumDirectionLocal = transform.TransformPoint(particleMomentumDirectionGlobal).unit();
141 G4ThreeVector photonPolarization = laser->
Polarization();
142 G4ThreeVector photonUnit(0,0,1);
145 photonPolarization.transform(*rot);
146 particlePolarization.transform(*rot);
147 photonUnit.transform(*rot);
148 G4double photonEnergy = (CLHEP::h_Planck*CLHEP::c_light)/laser->
Wavelength();
151 G4ThreeVector photonVector = photonUnit*photonEnergy;
152 G4LorentzVector photonLorentz = G4LorentzVector(photonVector,photonEnergy);
155 photonLorentz.boost(-1.0*particleBeta);
156 particle4VectorMomentum.boost(-particleBeta);
157 G4double photonEnergyLorentz = photonLorentz.e();
160 G4double photonFluxSum = 0;
161 std::vector<G4double> fluxArray;
163 std::vector<G4LorentzVector> trajectoryPositions;
165 for(G4int i = 0;i<=99;i++)
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);
176 G4double crossSection = comptonEngine->CrossSection(photonEnergyLorentz,partID);
178 G4double stepTime = ((particleTimePostStepGlobal-particleTimePreStepGlobal)*particleGamma)/100.;
179 G4double cumulativeProbability = 1.0 - std::exp(-1.0*crossSection*photonFluxSum*stepTime);
180 G4double secondaryStepPosition;
182 if(photonFluxSum == 0)
183 {secondaryStepPosition = G4UniformRand();}
186 G4RandGeneral trajectoryPDFRandom = CLHEP::RandGeneral(*CLHEP::HepRandom::getTheEngine(),
187 fluxArray.data(),100,0);
188 secondaryStepPosition = trajectoryPDFRandom.shoot();
191 G4ThreeVector proposedPositionGlobal = particlePositionPreStepGlobal + (stepMagnitude*secondaryStepPosition*particleMomentumDirectionGlobal);
192 G4double proposedTime = particleTimePreStepGlobal + (stepMagnitude*secondaryStepPosition/particleVelocity);
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(),
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);
Extra G4Navigator to get coordinate transforms.
Class to provide laser intensity at any point.
G4double Wavelength() const
Accessor.
G4ThreeVector Polarization() const
Accessor.
Extended logical volume with laser definition.
const BDSLaser * Laser() const
Access the laser.