18#include "BDSAuxiliaryNavigator.hh"
19#include "BDSComptonEngine.hh"
20#include "BDSComptonScatteringEngine.hh"
21#include "BDSGlobalConstants.hh"
22#include "BDSLaserCumulativeCompton.hh"
23#include "BDSLogicalVolumeLaser.hh"
25#include "BDSParticleDefinition.hh"
27#include "G4AffineTransform.hh"
28#include "G4Electron.hh"
30#include "G4LogicalVolume.hh"
31#include "G4ParticleTable.hh"
32#include "G4ProcessType.hh"
35#include "G4StepPoint.hh"
36#include "G4ThreeVector.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"
48#include "CLHEP/Units/PhysicalConstants.h"
49#include "CLHEP/Units/SystemOfUnits.h"
54BDSLaserCumulativeCompton::BDSLaserCumulativeCompton(
const G4String& processName):
55 G4VDiscreteProcess(processName, G4ProcessType::fElectromagnetic),
60BDSLaserCumulativeCompton::~BDSLaserCumulativeCompton()
65G4double BDSLaserCumulativeCompton::GetMeanFreePath(
const G4Track& track,
67 G4ForceCondition* forceCondition)
75 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
76 if (!lv->IsExtended())
77 {
return std::numeric_limits<double>::max();}
81 {
return std::numeric_limits<double>::max();}
83 *forceCondition = Forced;
85 return std::numeric_limits<double>::max();
88G4VParticleChange* BDSLaserCumulativeCompton::PostStepDoIt(
const G4Track& track,
91 aParticleChange.Initialize(track);
92 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
93 if (!lv->IsExtended())
94 {
return pParticleChange;}
97 {
return pParticleChange;}
103 {
return pParticleChange;}
104 else if (trackInfo->GetComptonScattered())
105 {
return pParticleChange;}
109 const G4DynamicParticle* particle = track.GetDynamicParticle();
110 G4double particleEnergy = particle->GetTotalEnergy();
111 G4ThreeVector particleMomentum = particle->GetMomentum();
112 G4ThreeVector particlePolarization = trackInfo->GetPolarizationState()->GetPolarization();
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();
120 G4double particleTimePostStepGlobal = track.GetGlobalTime();
121 G4double particleTimePreStepGlobal = step.GetPreStepPoint()->GetGlobalTime();
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();
132 const G4RotationMatrix* rot = track.GetTouchable()->GetRotation();
133 const G4AffineTransform transform = track.GetTouchable()->GetHistory()->GetTopTransform();
136 G4ThreeVector particlePositionLocal = transform.TransformPoint(particlePositionPreStepGlobal);
137 G4ThreeVector particleMomentumDirectionLocal = transform.TransformPoint(particleMomentumDirectionGlobal).unit();
142 G4ThreeVector photonPolarization = laser->
Polarization();
143 G4ThreeVector photonUnit(0,0,1);
146 photonPolarization.transform(*rot);
147 particlePolarization.transform(*rot);
148 photonUnit.transform(*rot);
149 G4double photonEnergy = (CLHEP::h_Planck*CLHEP::c_light)/laser->
Wavelength();
152 G4ThreeVector photonVector = photonUnit*photonEnergy;
153 G4LorentzVector photonLorentz = G4LorentzVector(photonVector,photonEnergy);
156 photonLorentz.boost(-1.0*particleBeta);
157 particle4VectorMomentum.boost(-particleBeta);
158 G4double photonEnergyLorentz = photonLorentz.e();
161 G4double photonFluxSum = 0;
162 std::vector<G4double> fluxArray;
164 std::vector<G4LorentzVector> trajectoryPositions;
166 for(G4int i = 0;i<=99;i++)
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);
177 G4double crossSection = comptonEngine->CrossSection(photonEnergyLorentz,partID);
179 G4double stepTime = ((particleTimePostStepGlobal-particleTimePreStepGlobal)*particleGamma)/100.;
180 G4double cumulativeProbability = 1.0 - std::exp(-1.0*crossSection*photonFluxSum*stepTime);
181 G4double secondaryStepPosition;
183 if(photonFluxSum == 0)
184 {secondaryStepPosition = G4UniformRand();}
187 G4RandGeneral trajectoryPDFRandom = CLHEP::RandGeneral(*CLHEP::HepRandom::getTheEngine(),
188 fluxArray.data(),100,0);
189 secondaryStepPosition = trajectoryPDFRandom.shoot();
192 G4ThreeVector proposedPositionGlobal = particlePositionPreStepGlobal + (stepMagnitude*secondaryStepPosition*particleMomentumDirectionGlobal);
193 G4double proposedTime = particleTimePreStepGlobal + (stepMagnitude*secondaryStepPosition/particleVelocity);
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(),
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);
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.