18#include "BDSAuxiliaryNavigator.hh"
19#include "BDSLaserPhotoDetachment.hh"
20#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"
43#include "CLHEP/Units/PhysicalConstants.h"
44#include "CLHEP/Units/SystemOfUnits.h"
48BDSLaserPhotoDetachment::BDSLaserPhotoDetachment(
const G4String& processName):
49 G4VDiscreteProcess(processName, G4ProcessType::fElectromagnetic),
54BDSLaserPhotoDetachment::~BDSLaserPhotoDetachment()
57 delete photoDetachmentEngine;
60G4double BDSLaserPhotoDetachment::GetMeanFreePath(
const G4Track& track,
62 G4ForceCondition* forceCondition)
64 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
65 if (!lv->IsExtended())
78 aParticleChange.Initialize(track);
79 const G4DynamicParticle* ion = track.GetDynamicParticle();
81 if (ion->GetCharge()==-1)
83 *forceCondition = Forced;
90G4VParticleChange* BDSLaserPhotoDetachment::PostStepDoIt(
const G4Track& track,
94 aParticleChange.Initialize(track);
96 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
97 if (!lv->IsExtended())
98 {
return pParticleChange;}
102 {
return pParticleChange;}
109 G4DynamicParticle* ion =
const_cast<G4DynamicParticle*
>(track.GetDynamicParticle());
111 G4ThreeVector particlePositionPostStepGlobal = track.GetPosition();
112 G4ThreeVector particleDirectionMomentumGlobal = track.GetMomentumDirection();
113 const G4RotationMatrix* rot = track.GetTouchable()->GetRotation();
114 const G4AffineTransform transform = track.GetTouchable()->GetHistory()->GetTopTransform();
115 G4ThreeVector particlePositionLocal = transform.TransformPoint(particlePositionPostStepGlobal);
116 G4ThreeVector particleDirectionMomentumLocal = transform.TransformPoint(particleDirectionMomentumGlobal).unit();
119 G4ThreeVector photonUnit(0,0,1);
120 photonUnit.transform(*rot);
121 G4double photonEnergy = (CLHEP::h_Planck*CLHEP::c_light)/laser->
Wavelength();
122 G4ThreeVector photonVector = photonUnit*photonEnergy;
123 G4LorentzVector photonLorentz = G4LorentzVector(photonVector,photonEnergy);
125 G4double ionEnergy = ion->GetTotalEnergy();
126 G4ThreeVector ionMomentum = ion->GetMomentum();
127 G4double ionMass = ion->GetMass();
128 G4ThreeVector ionBeta = ionMomentum/ionEnergy;
131 photonLorentz.boost(-ionBeta);
132 G4double photonEnergyLorentz = photonLorentz.e();
133 G4double crossSection = photoDetachmentEngine->CrossSection(photonEnergyLorentz);
135 G4double particleTimePostStepGlobal = track.GetGlobalTime();
136 G4double intensity =laser->Intensity(particlePositionLocal);
137 G4double timeProfile=laser->TemporalProfileGaussian(particleTimePostStepGlobal,particlePositionLocal.z());
138 G4double photonFlux = (intensity/photonEnergyLorentz)*timeProfile;
140 G4double ionTime = track.GetStep()->GetPreStepPoint()->GetGlobalTime();
141 G4double NeutralisationProbability = 1.0-std::exp(-crossSection*photonFlux*ionTime);
143 G4double scaleFactor = g->ScaleFactorLaser();
144 G4double randomNumber = G4UniformRand();
146 if((NeutralisationProbability*scaleFactor)>randomNumber)
149 G4ThreeVector randomDirection = G4RandomDirection();
150 G4double hydrogenMass = (CLHEP::electron_mass_c2 + CLHEP::proton_mass_c2);
151 G4double outgoingElectronEnergy = CLHEP::electron_mass_c2;
153 G4LorentzVector outgoingElectron;
154 outgoingElectron.setE(outgoingElectronEnergy);
158 G4double outgoingH0Energy = ionMass+photonEnergyLorentz-outgoingElectronEnergy;
159 G4double outgoingH0Momentum = std::sqrt(outgoingH0Energy*outgoingH0Energy-hydrogenMass*hydrogenMass);
160 G4LorentzVector outgoingH0;
161 outgoingH0.setPx(-1.0*randomDirection.x()*outgoingH0Momentum);
162 outgoingH0.setPy(-1.0*randomDirection.y()*outgoingH0Momentum);
163 outgoingH0.setPz(-1.0*randomDirection.z()*outgoingH0Momentum);
164 outgoingH0.setE(outgoingH0Energy);
166 outgoingElectron.boost(ionBeta);
167 outgoingH0.boost(ionBeta);
171 aParticleChange.SetNumberOfSecondaries(1);
172 aParticleChange.ProposeMass(hydrogenMass);
173 G4ThreeVector H0Momentum;
174 H0Momentum.set(outgoingH0.px(),outgoingH0.py(),outgoingH0.pz());
175 aParticleChange.ProposeMomentumDirection(H0Momentum.unit());
176 aParticleChange.ProposeCharge(0);
177 ion->RemoveElectron(1);
181 G4DynamicParticle* electron =
new G4DynamicParticle(G4Electron::ElectronDefinition(),
182 outgoingElectron.vect().unit(),
183 outgoingElectron.e());
184 aParticleChange.AddSecondary(electron);
186 aParticleChange.ProposeWeight(1.0/scaleFactor);
188 return G4VDiscreteProcess::PostStepDoIt(track, step);
191 {
return G4VDiscreteProcess::PostStepDoIt(track, step);}
Extra G4Navigator to get coordinate transforms.
A class that holds global options and constants.
static BDSGlobalConstants * Instance()
Access method.
Class to provide laser intensity at any point.
G4double Wavelength() const
Accessor.
G4double Sigma0() const
Accessor.
Extended logical volume with laser definition.
const BDSLaser * Laser() const
Access the laser.