19#include "BDSAuxiliaryNavigator.hh"
20#include "BDSLaserCumulativePhotodetachment.hh"
21#include "BDSLogicalVolumeLaser.hh"
22#include "BDSPhotoDetachmentEngine.hh"
24#include "BDSGlobalConstants.hh"
27#include "G4AffineTransform.hh"
28#include "G4Electron.hh"
29#include "G4LogicalVolume.hh"
30#include "G4ParticleTable.hh"
31#include "G4ProcessType.hh"
34#include "G4StepPoint.hh"
35#include "G4ThreeVector.hh"
37#include "G4VTouchable.hh"
38#include "Randomize.hh"
39#include "G4TransportationManager.hh"
40#include "G4VPhysicalVolume.hh"
41#include "G4RandomDirection.hh"
42#include "CLHEP/Units/PhysicalConstants.h"
43#include "CLHEP/Units/SystemOfUnits.h"
47BDSLaserCumulativePhotodetachment::BDSLaserCumulativePhotodetachment(
const G4String& processName):
48 G4VDiscreteProcess(processName, G4ProcessType::fElectromagnetic),
53BDSLaserCumulativePhotodetachment::~BDSLaserCumulativePhotodetachment()
56 delete photoDetachmentEngine;
59G4double BDSLaserCumulativePhotodetachment::GetMeanFreePath(
const G4Track& track,
61 G4ForceCondition* forceCondition)
66 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
67 if (!lv->IsExtended())
68 {
return std::numeric_limits<double>::max();}
72 {
return std::numeric_limits<double>::max();}
74 *forceCondition = Forced;
76 return std::numeric_limits<double>::max();
79G4VParticleChange* BDSLaserCumulativePhotodetachment::PostStepDoIt(
const G4Track& track,
83 aParticleChange.Initialize(track);
85 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
86 if (!lv->IsExtended())
87 {
return pParticleChange;}
91 {
return pParticleChange;}
96 G4DynamicParticle* ion =
const_cast<G4DynamicParticle*
>(track.GetDynamicParticle());
97 G4int ionCharge=ion->GetCharge();
98 if(ionCharge==0){
return G4VDiscreteProcess::PostStepDoIt(track, step); }
99 G4double particleEnergy = ion->GetTotalEnergy();
100 G4ThreeVector particleMomentum = ion->GetMomentum();
101 G4ThreeVector particleBeta = particleMomentum/particleEnergy;
102 G4double particleGamma = particleEnergy/ion->GetMass();
103 G4double particleVelocity = particleBeta.mag()*CLHEP::c_light;
104 G4LorentzVector particle4VectorMomentum = ion->Get4Momentum();
105 particle4VectorMomentum.boost(-particleBeta);
109 G4ThreeVector particlePositionPostStepGlobal = track.GetPosition();
110 G4ThreeVector particlePositionPreStepGlobal = track.GetStep()->GetPreStepPoint()->GetPosition();
111 G4ThreeVector particleMomentumDirectionPreStepGlobal = track.GetStep()->GetPreStepPoint()->GetMomentumDirection();
113 G4ThreeVector stepVector = particlePositionPostStepGlobal-particlePositionPreStepGlobal;
114 G4double stepMagnitude = stepVector.mag();
118 const G4RotationMatrix* rot = track.GetTouchable()->GetRotation();
119 const G4AffineTransform transform = track.GetTouchable()->GetHistory()->GetTopTransform();
122 G4ThreeVector photonUnit(0,0,1);
123 photonUnit.transform(*rot);
124 G4double photonEnergy = (CLHEP::h_Planck*CLHEP::c_light)/laser->
Wavelength();
125 G4ThreeVector photonVector = photonUnit*photonEnergy;
126 G4LorentzVector photonLorentzVector = G4LorentzVector(photonVector,photonEnergy);
128 photonLorentzVector.boost(particleBeta);
129 G4double photonEnergyLorentz = photonLorentzVector.e();
131 G4double photonFluxSum = 0;
133 G4double particleTimePreStepGlobal = track.GetStep()->GetPreStepPoint()->GetGlobalTime();
135 std::vector<G4double> fluxArray;
136 std::vector<G4LorentzVector> trajectoryPositions;
139 for(G4int i = 0;i<=99;i++)
141 G4ThreeVector stepPositionGlobal = particlePositionPreStepGlobal+float(i)*(stepMagnitude/100.)*particleMomentumDirectionPreStepGlobal;
142 G4ThreeVector stepPositionLocal = transform.TransformPoint(stepPositionGlobal);
143 G4double stepTimeGlobal = particleTimePreStepGlobal+(float(i)*(stepMagnitude/100.)/particleVelocity);
144 G4double stepIntensity = ((laser->Intensity(stepPositionLocal)/photonEnergyLorentz)
145 * laser->TemporalProfileGaussian(stepTimeGlobal,stepPositionLocal.z()));
146 photonFluxSum = photonFluxSum + stepIntensity;
147 fluxArray.push_back(stepIntensity);
150 G4double crossSection = photoDetachmentEngine->CrossSection(photonEnergyLorentz);
152 G4double stepTime = stepMagnitude/particleVelocity;
153 G4double cumulativeProbability = 1.0 - std::exp((-1.0*crossSection*photonFluxSum*(stepTime/100.)*particleGamma));
155 G4double secondaryStepPosition;
157 if (photonFluxSum == 0)
158 {secondaryStepPosition = G4UniformRand();}
161 G4RandGeneral trajectoryPDFRandom = CLHEP::RandGeneral(*CLHEP::HepRandom::getTheEngine(),
162 fluxArray.data(),100,0);
163 secondaryStepPosition = trajectoryPDFRandom.shoot();
166 G4ThreeVector proposedPositionGlobal = particlePositionPreStepGlobal + (stepMagnitude*secondaryStepPosition*particleMomentumDirectionPreStepGlobal);
167 G4double proposedTimeGlobal = particleTimePreStepGlobal + (stepMagnitude*secondaryStepPosition/particleVelocity);
169 aParticleChange.ProposePosition(proposedPositionGlobal);
170 G4double initialWeight=aParticleChange.GetParentWeight();
171 aParticleChange.ProposeParentWeight(initialWeight*cumulativeProbability);
172 aParticleChange.SetNumberOfSecondaries(1);
175 G4ThreeVector randomDirection = G4RandomDirection();
176 G4double hydrogenMass = (CLHEP::electron_mass_c2 + CLHEP::proton_mass_c2);
177 G4double outgoingElectronEnergy = CLHEP::electron_mass_c2;
178 G4double ionEnergy = ion->GetTotalEnergy();
179 G4ThreeVector ionMomentum = ion->GetMomentum();
180 G4ThreeVector ionBeta = ionMomentum/ionEnergy;
182 G4LorentzVector outgoingElectron;
183 outgoingElectron.setE(outgoingElectronEnergy);
185 G4double ionMass = ion->GetMass();
188 G4double outgoingH0Energy = ionMass+photonEnergyLorentz-outgoingElectronEnergy;
189 G4double outgoingH0Momentum = std::sqrt(outgoingH0Energy*outgoingH0Energy-hydrogenMass*hydrogenMass);
190 G4LorentzVector outgoingH0;
191 outgoingH0.setPx(-1.0*randomDirection.x()*outgoingH0Momentum);
192 outgoingH0.setPy(-1.0*randomDirection.y()*outgoingH0Momentum);
193 outgoingH0.setPz(-1.0*randomDirection.z()*outgoingH0Momentum);
194 outgoingH0.setE(outgoingH0Energy);
196 outgoingElectron.boost(ionBeta);
197 outgoingH0.boost(ionBeta);
199 aParticleChange.ProposeMass(hydrogenMass);
200 G4ThreeVector H0Momentum;
201 H0Momentum.set(outgoingH0.px(),outgoingH0.py(),outgoingH0.pz());
202 aParticleChange.ProposeMomentumDirection(H0Momentum.unit());
203 aParticleChange.ProposeCharge(0);
204 ion->RemoveElectron(1);
208 G4DynamicParticle* electron =
new G4DynamicParticle(G4Electron::ElectronDefinition(),
209 outgoingElectron.vect().unit(),
210 outgoingElectron.e());
211 aParticleChange.AddSecondary(electron,proposedTimeGlobal);
212 aParticleChange.ProposePosition(particlePositionPostStepGlobal);
214 aParticleChange.ProposeParentWeight(initialWeight*cumulativeProbability);
215 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.