BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSLaserPhotoDetachment.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2024.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSAuxiliaryNavigator.hh"
20#include "BDSLaserPhotoDetachment.hh"
21#include "BDSLogicalVolumeLaser.hh"
22#include "BDSLaser.hh"
23#include "BDSPhotoDetachmentEngine.hh"
24#include "BDSStep.hh"
25#include "BDSGlobalConstants.hh"
26
27#include "globals.hh"
28#include "G4AffineTransform.hh"
29#include "G4Electron.hh"
30#include "G4LogicalVolume.hh"
31#include "G4ParticleTable.hh"
32#include "G4ProcessType.hh"
33#include "G4Proton.hh"
34#include "G4Step.hh"
35#include "G4StepPoint.hh"
36#include "G4ThreeVector.hh"
37#include "G4Track.hh"
38#include "G4VTouchable.hh"
39#include "Randomize.hh"
40#include "G4TransportationManager.hh"
41#include "G4VPhysicalVolume.hh"
42#include "G4RandomDirection.hh"
43
44#include "CLHEP/Units/PhysicalConstants.h"
45#include "CLHEP/Units/SystemOfUnits.h"
46
47#include <cmath>
48
49BDSLaserPhotoDetachment::BDSLaserPhotoDetachment(const G4String& processName):
50 G4VDiscreteProcess(processName, G4ProcessType::fElectromagnetic),
51 auxNavigator(new BDSAuxiliaryNavigator()),
52 photoDetachmentEngine(new BDSPhotoDetachmentEngine())
53{;}
54
55BDSLaserPhotoDetachment::~BDSLaserPhotoDetachment()
56{
57 delete auxNavigator;
58 delete photoDetachmentEngine;
59}
60
61G4double BDSLaserPhotoDetachment::GetMeanFreePath(const G4Track& track,
62 G4double /*previousStepSize*/,
63 G4ForceCondition* forceCondition)
64{
65 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
66 if (!lv->IsExtended())
67 {// not extended so can't be a laser logical volume
68 return DBL_MAX;
69 }
70 BDSLogicalVolumeLaser* lvv = dynamic_cast<BDSLogicalVolumeLaser*>(lv);
71 if (!lvv)
72 {// it's an extended volume but not ours (could be a crystal)
73 return DBL_MAX;
74 }
75
76 // else proceed
77 const BDSLaser* laser = lvv->Laser();
78
79 aParticleChange.Initialize(track);
80 const G4DynamicParticle* ion = track.GetDynamicParticle();
81
82 if (ion->GetCharge()==-1)
83 {
84 *forceCondition = Forced;
85 return laser->Sigma0()/10;
86 }
87 else
88 {return DBL_MAX;}
89}
90
91G4VParticleChange* BDSLaserPhotoDetachment::PostStepDoIt(const G4Track& track,
92 const G4Step& step)
93{
94 // get coordinates for photon desity calculations
95 aParticleChange.Initialize(track);
96
97 G4LogicalVolume* lv = track.GetVolume()->GetLogicalVolume();
98 if (!lv->IsExtended()) // not extended so can't be a laser logical volume
99 {return pParticleChange;}
100
101 BDSLogicalVolumeLaser* lvv = dynamic_cast<BDSLogicalVolumeLaser *>(lv);
102 if (!lvv) // it's an extended volume but not ours (could be a crystal)
103 {return pParticleChange;}
104
105 // else proceed
106 const BDSLaser* laser = lvv->Laser();
107
108 //G4double stepLength = step.GetStepLength();
109
110 G4DynamicParticle* ion = const_cast<G4DynamicParticle*>(track.GetDynamicParticle());
111
112 G4ThreeVector particlePositionPostStepGlobal = track.GetPosition();
113 G4ThreeVector particleDirectionMomentumGlobal = track.GetMomentumDirection();
114 const G4RotationMatrix* rot = track.GetTouchable()->GetRotation();
115 const G4AffineTransform transform = track.GetTouchable()->GetHistory()->GetTopTransform();
116 G4ThreeVector particlePositionLocal = transform.TransformPoint(particlePositionPostStepGlobal);
117 G4ThreeVector particleDirectionMomentumLocal = transform.TransformPoint(particleDirectionMomentumGlobal).unit();
118
119 // create photon
120 G4ThreeVector photonUnit(0,0,1);
121 photonUnit.transform(*rot);
122 G4double photonEnergy = (CLHEP::h_Planck*CLHEP::c_light)/laser->Wavelength();
123 G4ThreeVector photonVector = photonUnit*photonEnergy;
124 G4LorentzVector photonLorentz = G4LorentzVector(photonVector,photonEnergy);
125
126 G4double ionEnergy = ion->GetTotalEnergy();
127 G4ThreeVector ionMomentum = ion->GetMomentum();
128 G4double ionMass = ion->GetMass();
129 G4ThreeVector ionBeta = ionMomentum/ionEnergy;
130 //G4double ionGamma = ionEnergy/ionMass;
131 //G4double ionVelocity = ionBeta.mag()*CLHEP::c_light;
132 photonLorentz.boost(-ionBeta);
133 G4double photonEnergyLorentz = photonLorentz.e();
134 G4double crossSection = photoDetachmentEngine->CrossSection(photonEnergyLorentz);
135
136 G4double particleTimePostStepGlobal = track.GetGlobalTime();
137 G4double intensity =laser->Intensity(particlePositionLocal);
138 G4double timeProfile=laser->TemporalProfileGaussian(particleTimePostStepGlobal,particlePositionLocal.z());
139 G4double photonFlux = (intensity/photonEnergyLorentz)*timeProfile;
140
141 G4double ionTime = track.GetStep()->GetPreStepPoint()->GetGlobalTime();
142 G4double NeutralisationProbability = 1.0-std::exp(-crossSection*photonFlux*ionTime);
144 G4double scaleFactor = g->ScaleFactorLaser();
145 G4double randomNumber = G4UniformRand();
146
147 if((NeutralisationProbability*scaleFactor)>randomNumber)
148 {
149 // electron kinematics
150 G4ThreeVector randomDirection = G4RandomDirection();
151 G4double hydrogenMass = (CLHEP::electron_mass_c2 + CLHEP::proton_mass_c2);
152 G4double outgoingElectronEnergy = CLHEP::electron_mass_c2;
153
154 G4LorentzVector outgoingElectron;
155 outgoingElectron.setE(outgoingElectronEnergy);
156
157 // hydrogen kinematics
158
159 G4double outgoingH0Energy = ionMass+photonEnergyLorentz-outgoingElectronEnergy;
160 G4double outgoingH0Momentum = std::sqrt(outgoingH0Energy*outgoingH0Energy-hydrogenMass*hydrogenMass);
161 G4LorentzVector outgoingH0;
162 outgoingH0.setPx(-1.0*randomDirection.x()*outgoingH0Momentum);
163 outgoingH0.setPy(-1.0*randomDirection.y()*outgoingH0Momentum);
164 outgoingH0.setPz(-1.0*randomDirection.z()*outgoingH0Momentum);
165 outgoingH0.setE(outgoingH0Energy);
166
167 outgoingElectron.boost(ionBeta);
168 outgoingH0.boost(ionBeta);
169
170
171 // changes to ion to make H0
172 aParticleChange.SetNumberOfSecondaries(1);
173 aParticleChange.ProposeMass(hydrogenMass);
174 G4ThreeVector H0Momentum;
175 H0Momentum.set(outgoingH0.px(),outgoingH0.py(),outgoingH0.pz());
176 aParticleChange.ProposeMomentumDirection(H0Momentum.unit());
177 aParticleChange.ProposeCharge(0);
178 ion->RemoveElectron(1);
179 ion->SetCharge(0);
180
181 // create outgoing electron
182 G4DynamicParticle* electron = new G4DynamicParticle(G4Electron::ElectronDefinition(),
183 outgoingElectron.vect().unit(),
184 outgoingElectron.e());
185 aParticleChange.AddSecondary(electron);
186
187 aParticleChange.ProposeWeight(1.0/scaleFactor);
188
189 return G4VDiscreteProcess::PostStepDoIt(track, step);
190 }
191 else
192 {return G4VDiscreteProcess::PostStepDoIt(track, step);}
193}
194
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.
Definition BDSLaser.hh:36
G4double Wavelength() const
Accessor.
Definition BDSLaser.hh:64
G4double Sigma0() const
Accessor.
Definition BDSLaser.hh:68
Extended logical volume with laser definition.
const BDSLaser * Laser() const
Access the laser.