18#include "BDSAuxiliaryNavigator.hh"
19#include "BDSLaserCumulativePhotodetachment.hh"
20#include "BDSLogicalVolumeLaser.hh"
21#include "BDSPhotoDetachmentEngine.hh"
23#include "BDSGlobalConstants.hh"
26#include "G4AffineTransform.hh"
27#include "G4Electron.hh"
28#include "G4LogicalVolume.hh"
29#include "G4ParticleTable.hh"
30#include "G4ProcessType.hh"
33#include "G4StepPoint.hh"
34#include "G4ThreeVector.hh"
36#include "G4VTouchable.hh"
37#include "Randomize.hh"
38#include "G4TransportationManager.hh"
39#include "G4VPhysicalVolume.hh"
40#include "G4RandomDirection.hh"
41#include "CLHEP/Units/PhysicalConstants.h"
42#include "CLHEP/Units/SystemOfUnits.h"
46BDSLaserCumulativePhotodetachment::BDSLaserCumulativePhotodetachment(
const G4String& processName):
47 G4VDiscreteProcess(processName, G4ProcessType::fElectromagnetic),
52BDSLaserCumulativePhotodetachment::~BDSLaserCumulativePhotodetachment()
55 delete photoDetachmentEngine;
58G4double BDSLaserCumulativePhotodetachment::GetMeanFreePath(
const G4Track& track,
60 G4ForceCondition* forceCondition)
65 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
66 if (!lv->IsExtended())
67 {
return std::numeric_limits<double>::max();}
71 {
return std::numeric_limits<double>::max();}
73 *forceCondition = Forced;
75 return std::numeric_limits<double>::max();
78G4VParticleChange* BDSLaserCumulativePhotodetachment::PostStepDoIt(
const G4Track& track,
82 aParticleChange.Initialize(track);
84 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
85 if (!lv->IsExtended())
86 {
return pParticleChange;}
90 {
return pParticleChange;}
95 G4DynamicParticle* ion =
const_cast<G4DynamicParticle*
>(track.GetDynamicParticle());
96 G4int ionCharge=ion->GetCharge();
97 if(ionCharge==0){
return G4VDiscreteProcess::PostStepDoIt(track, step); }
98 G4double particleEnergy = ion->GetTotalEnergy();
99 G4ThreeVector particleMomentum = ion->GetMomentum();
100 G4ThreeVector particleBeta = particleMomentum/particleEnergy;
101 G4double particleGamma = particleEnergy/ion->GetMass();
102 G4double particleVelocity = particleBeta.mag()*CLHEP::c_light;
103 G4LorentzVector particle4VectorMomentum = ion->Get4Momentum();
104 particle4VectorMomentum.boost(-particleBeta);
108 G4ThreeVector particlePositionPostStepGlobal = track.GetPosition();
109 G4ThreeVector particlePositionPreStepGlobal = track.GetStep()->GetPreStepPoint()->GetPosition();
110 G4ThreeVector particleMomentumDirectionPreStepGlobal = track.GetStep()->GetPreStepPoint()->GetMomentumDirection();
112 G4ThreeVector stepVector = particlePositionPostStepGlobal-particlePositionPreStepGlobal;
113 G4double stepMagnitude = stepVector.mag();
117 const G4RotationMatrix* rot = track.GetTouchable()->GetRotation();
118 const G4AffineTransform transform = track.GetTouchable()->GetHistory()->GetTopTransform();
121 G4ThreeVector photonUnit(0,0,1);
122 photonUnit.transform(*rot);
123 G4double photonEnergy = (CLHEP::h_Planck*CLHEP::c_light)/laser->
Wavelength();
124 G4ThreeVector photonVector = photonUnit*photonEnergy;
125 G4LorentzVector photonLorentzVector = G4LorentzVector(photonVector,photonEnergy);
127 photonLorentzVector.boost(particleBeta);
128 G4double photonEnergyLorentz = photonLorentzVector.e();
130 G4double photonFluxSum = 0;
132 G4double particleTimePreStepGlobal = track.GetStep()->GetPreStepPoint()->GetGlobalTime();
134 std::vector<G4double> fluxArray;
135 std::vector<G4LorentzVector> trajectoryPositions;
138 for(G4int i = 0;i<=99;i++)
140 G4ThreeVector stepPositionGlobal = particlePositionPreStepGlobal+float(i)*(stepMagnitude/100.)*particleMomentumDirectionPreStepGlobal;
141 G4ThreeVector stepPositionLocal = transform.TransformPoint(stepPositionGlobal);
142 G4double stepTimeGlobal = particleTimePreStepGlobal+(float(i)*(stepMagnitude/100.)/particleVelocity);
143 G4double stepIntensity = ((laser->Intensity(stepPositionLocal)/photonEnergyLorentz)
144 * laser->TemporalProfileGaussian(stepTimeGlobal,stepPositionLocal.z()));
145 photonFluxSum = photonFluxSum + stepIntensity;
146 fluxArray.push_back(stepIntensity);
149 G4double crossSection = photoDetachmentEngine->CrossSection(photonEnergyLorentz);
151 G4double stepTime = stepMagnitude/particleVelocity;
152 G4double cumulativeProbability = 1.0 - std::exp((-1.0*crossSection*photonFluxSum*(stepTime/100.)*particleGamma));
154 G4double secondaryStepPosition;
156 if (photonFluxSum == 0)
157 {secondaryStepPosition = G4UniformRand();}
160 G4RandGeneral trajectoryPDFRandom = CLHEP::RandGeneral(*CLHEP::HepRandom::getTheEngine(),
161 fluxArray.data(),100,0);
162 secondaryStepPosition = trajectoryPDFRandom.shoot();
165 G4ThreeVector proposedPositionGlobal = particlePositionPreStepGlobal + (stepMagnitude*secondaryStepPosition*particleMomentumDirectionPreStepGlobal);
166 G4double proposedTimeGlobal = particleTimePreStepGlobal + (stepMagnitude*secondaryStepPosition/particleVelocity);
168 aParticleChange.ProposePosition(proposedPositionGlobal);
169 G4double initialWeight=aParticleChange.GetParentWeight();
170 aParticleChange.ProposeParentWeight(initialWeight*cumulativeProbability);
171 aParticleChange.SetNumberOfSecondaries(1);
174 G4ThreeVector randomDirection = G4RandomDirection();
175 G4double hydrogenMass = (CLHEP::electron_mass_c2 + CLHEP::proton_mass_c2);
176 G4double outgoingElectronEnergy = CLHEP::electron_mass_c2;
177 G4double ionEnergy = ion->GetTotalEnergy();
178 G4ThreeVector ionMomentum = ion->GetMomentum();
179 G4ThreeVector ionBeta = ionMomentum/ionEnergy;
181 G4LorentzVector outgoingElectron;
182 outgoingElectron.setE(outgoingElectronEnergy);
184 G4double ionMass = ion->GetMass();
187 G4double outgoingH0Energy = ionMass+photonEnergyLorentz-outgoingElectronEnergy;
188 G4double outgoingH0Momentum = std::sqrt(outgoingH0Energy*outgoingH0Energy-hydrogenMass*hydrogenMass);
189 G4LorentzVector outgoingH0;
190 outgoingH0.setPx(-1.0*randomDirection.x()*outgoingH0Momentum);
191 outgoingH0.setPy(-1.0*randomDirection.y()*outgoingH0Momentum);
192 outgoingH0.setPz(-1.0*randomDirection.z()*outgoingH0Momentum);
193 outgoingH0.setE(outgoingH0Energy);
195 outgoingElectron.boost(ionBeta);
196 outgoingH0.boost(ionBeta);
198 aParticleChange.ProposeMass(hydrogenMass);
199 G4ThreeVector H0Momentum;
200 H0Momentum.set(outgoingH0.px(),outgoingH0.py(),outgoingH0.pz());
201 aParticleChange.ProposeMomentumDirection(H0Momentum.unit());
202 aParticleChange.ProposeCharge(0);
203 ion->RemoveElectron(1);
207 G4DynamicParticle* electron =
new G4DynamicParticle(G4Electron::ElectronDefinition(),
208 outgoingElectron.vect().unit(),
209 outgoingElectron.e());
210 aParticleChange.AddSecondary(electron,proposedTimeGlobal);
211 aParticleChange.ProposePosition(particlePositionPostStepGlobal);
213 aParticleChange.ProposeParentWeight(initialWeight*cumulativeProbability);
214 return G4VDiscreteProcess::PostStepDoIt(track, step);
Extra G4Navigator to get coordinate transforms.
Class to provide laser intensity at any point.
G4double Wavelength() const
Accessor.
Extended logical volume with laser definition.
const BDSLaser * Laser() const
Access the laser.