Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4AdjointIonIonisationModel.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26
28
29#include "G4AdjointCSManager.hh"
30#include "G4AdjointElectron.hh"
31#include "G4BetheBlochModel.hh"
32#include "G4BraggIonModel.hh"
33#include "G4GenericIon.hh"
34#include "G4NistManager.hh"
35#include "G4ParticleChange.hh"
37#include "G4SystemOfUnits.hh"
38#include "G4TrackStatus.hh"
39
40////////////////////////////////////////////////////////////////////////////////
42 : G4VEmAdjointModel("Adjoint_IonIonisation")
43{
44 fUseMatrix = true;
46 fApplyCutInRange = true;
48 fSecondPartSameType = false;
49
50 // The direct EM Model is taken as BetheBloch. It is only used for the
51 // computation of the differential cross section.
52 // The Bragg model could be used as an alternative as it offers the same
53 // differential cross section
54
55 fBetheBlochDirectEMModel = new G4BetheBlochModel(G4GenericIon::GenericIon());
56 fBraggIonDirectEMModel = new G4BraggIonModel(G4GenericIon::GenericIon());
58 fDirectPrimaryPart = nullptr;
59}
60
61////////////////////////////////////////////////////////////////////////////////
63
64////////////////////////////////////////////////////////////////////////////////
66 const G4Track& aTrack, G4bool isScatProjToProj,
67 G4ParticleChange* fParticleChange)
68{
69 const G4DynamicParticle* theAdjointPrimary = aTrack.GetDynamicParticle();
70
71 // Elastic inverse scattering
72 G4double adjointPrimKinEnergy = theAdjointPrimary->GetKineticEnergy();
73 G4double adjointPrimP = theAdjointPrimary->GetTotalMomentum();
74
75 if(adjointPrimKinEnergy > GetHighEnergyLimit() * 0.999)
76 {
77 return;
78 }
79
80 // Sample secondary energy
81 G4double projectileKinEnergy =
82 SampleAdjSecEnergyFromCSMatrix(adjointPrimKinEnergy, isScatProjToProj);
83 // Caution !!!this weight correction should be always applied
84 CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(),
85 adjointPrimKinEnergy, projectileKinEnergy,
86 isScatProjToProj);
87
88 // Kinematics:
89 // we consider a two body elastic scattering for the forward processes where
90 // the projectile knock on an e- at rest and gives it part of its energy
92 G4double projectileTotalEnergy = projectileM0 + projectileKinEnergy;
93 G4double projectileP2 =
94 projectileTotalEnergy * projectileTotalEnergy - projectileM0 * projectileM0;
95
96 // Companion
98 if(isScatProjToProj)
99 {
100 companionM0 = fAdjEquivDirectSecondPart->GetPDGMass();
101 }
102 G4double companionTotalEnergy =
103 companionM0 + projectileKinEnergy - adjointPrimKinEnergy;
104 G4double companionP2 =
105 companionTotalEnergy * companionTotalEnergy - companionM0 * companionM0;
106
107 // Projectile momentum
108 G4double P_parallel =
109 (adjointPrimP * adjointPrimP + projectileP2 - companionP2) /
110 (2. * adjointPrimP);
111 G4double P_perp = std::sqrt(projectileP2 - P_parallel * P_parallel);
112 G4ThreeVector dir_parallel = theAdjointPrimary->GetMomentumDirection();
113 G4double phi = G4UniformRand() * twopi;
114 G4ThreeVector projectileMomentum =
115 G4ThreeVector(P_perp * std::cos(phi), P_perp * std::sin(phi), P_parallel);
116 projectileMomentum.rotateUz(dir_parallel);
117
118 if(!isScatProjToProj)
119 { // kill the primary and add a secondary
120 fParticleChange->ProposeTrackStatus(fStopAndKill);
121 fParticleChange->AddSecondary(
122 new G4DynamicParticle(fAdjEquivDirectPrimPart, projectileMomentum));
123 }
124 else
125 {
126 fParticleChange->ProposeEnergy(projectileKinEnergy);
127 fParticleChange->ProposeMomentumDirection(projectileMomentum.unit());
128 }
129}
130
131////////////////////////////////////////////////////////////////////////////////
133 G4double kinEnergyProj, G4double kinEnergyProd, G4double Z, G4double A)
134{
135 // Probably that here the Bragg Model should be also used for
136 // kinEnergyProj/nuc<2MeV
137 G4double dSigmadEprod = 0.;
138 G4double Emax_proj = GetSecondAdjEnergyMaxForProdToProj(kinEnergyProd);
139 G4double Emin_proj = GetSecondAdjEnergyMinForProdToProj(kinEnergyProd);
140
141 G4double kinEnergyProjScaled = fMassRatio * kinEnergyProj;
142
143 // the produced particle should have a kinetic energy smaller than the
144 // projectile
145 if(kinEnergyProj > Emin_proj && kinEnergyProj <= Emax_proj)
146 {
147 G4double Tmax = kinEnergyProj;
148
149 G4double E1 = kinEnergyProd;
150 G4double E2 = kinEnergyProd * 1.000001;
151 G4double dE = (E2 - E1);
152 G4double sigma1, sigma2;
153 fDirectModel = fBraggIonDirectEMModel;
154 if(kinEnergyProjScaled > 2. * MeV && !fUseOnlyBragg)
155 fDirectModel = fBetheBlochDirectEMModel;
157 fDirectPrimaryPart, kinEnergyProj, Z, A, E1, 1.e20);
159 fDirectPrimaryPart, kinEnergyProj, Z, A, E2, 1.e20);
160
161 dSigmadEprod = (sigma1 - sigma2) / dE;
162
163 if(dSigmadEprod > 1.)
164 {
165 G4cout << "sigma1 " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
166 << '\t' << sigma1 << G4endl;
167 G4cout << "sigma2 " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
168 << '\t' << sigma2 << G4endl;
169 G4cout << "dsigma " << kinEnergyProj / MeV << '\t' << kinEnergyProd / MeV
170 << '\t' << dSigmadEprod << G4endl;
171 }
172
173 if(fDirectModel == fBetheBlochDirectEMModel)
174 {
175 // correction of differential cross section at high energy to correct for
176 // the suppression of particle at secondary at high energy used in the
177 // Bethe Bloch Model. This correction consist to multiply by g the
178 // probability function used to test the rejection of a secondary Source
179 // code taken from G4BetheBlochModel::SampleSecondaries
180
181 G4double deltaKinEnergy = kinEnergyProd;
182
183 G4double x = fFormFact * deltaKinEnergy;
184 if(x > 1.e-6)
185 {
186 G4double totEnergy = kinEnergyProj + fMass;
187 G4double etot2 = totEnergy * totEnergy;
188 G4double beta2 = kinEnergyProj * (kinEnergyProj + 2.0 * fMass) / etot2;
189 G4double f1 = 0.0;
190 G4double f = 1.0 - beta2 * deltaKinEnergy / Tmax;
191 if(0.5 == fSpin)
192 {
193 f1 = 0.5 * deltaKinEnergy * deltaKinEnergy / etot2;
194 f += f1;
195 }
196 G4double x1 = 1.0 + x;
197 G4double gg = 1.0 / (x1 * x1);
198 if(0.5 == fSpin)
199 {
200 G4double x2 =
201 0.5 * electron_mass_c2 * deltaKinEnergy / (fMass * fMass);
202 gg *= (1.0 + fMagMoment2 * (x2 - f1 / f) / (1.0 + x2));
203 }
204 if(gg > 1.0)
205 {
206 G4cout << "### G4BetheBlochModel in Adjoint Sim WARNING: gg= " << gg
207 << G4endl;
208 gg = 1.;
209 }
210 dSigmadEprod *= gg;
211 }
212 }
213 }
214 return dSigmadEprod;
215}
216
217////////////////////////////////////////////////////////////////////////////////
219 G4ParticleDefinition* fwd_ion)
220{
221 fDirectPrimaryPart = fwd_ion;
222 fAdjEquivDirectPrimPart = adj_ion;
223
224 DefineProjectileProperty();
225}
226
227////////////////////////////////////////////////////////////////////////////////
229 G4ParticleChange* fParticleChange, G4double old_weight,
230 G4double adjointPrimKinEnergy, G4double projectileKinEnergy, G4bool)
231{
232 // It is needed because the direct cross section used to compute the
233 // differential cross section is not the one used in
234 // the direct model where the GenericIon stuff is considered with correction
235 // of effective charge. In the direct model the samnepl of secondaries does
236 // not reflect the integral cross section. The integral fwd cross section that
237 // we used to compute the differential CS match the sample of secondaries in
238 // the forward case despite the fact that its is not the same total CS than in
239 // the FWD case. For this reason an extra weight correction is needed at the
240 // end.
241
242 G4double new_weight = old_weight;
243
244 // the correction of CS due to the problem explained above
245 G4double kinEnergyProjScaled = fMassRatio * projectileKinEnergy;
246 fDirectModel = fBraggIonDirectEMModel;
247 if(kinEnergyProjScaled > 2. * MeV && !fUseOnlyBragg)
248 fDirectModel = fBetheBlochDirectEMModel;
250 fDirectPrimaryPart, projectileKinEnergy, 1, 1, fTcutSecond, 1.e20);
251 G4double chargeSqRatio = 1.;
252 if(fChargeSquare > 1.)
253 chargeSqRatio = fDirectModel->GetChargeSquareRatio(
254 fDirectPrimaryPart, fCurrentMaterial, projectileKinEnergy);
255 G4double CorrectFwdCS =
257 G4GenericIon::GenericIon(), kinEnergyProjScaled, 1, 1,
258 fTcutSecond, 1.e20);
259 // May be some check is needed if UsedFwdCS ==0 probably that then we should
260 // avoid a secondary to be produced,
261 if(UsedFwdCS > 0.)
262 new_weight *= CorrectFwdCS / UsedFwdCS;
263
264 // additional CS correction needed for cross section biasing in general.
265 // May be wrong for ions. Most of the time not used.
266 new_weight *=
269
270 new_weight *= projectileKinEnergy / adjointPrimKinEnergy;
271
272 fParticleChange->SetParentWeightByProcess(false);
273 fParticleChange->SetSecondaryWeightByProcess(false);
274 fParticleChange->ProposeParentWeight(new_weight);
275}
276
277////////////////////////////////////////////////////////////////////////////////
278void G4AdjointIonIonisationModel::DefineProjectileProperty()
279{
280 // Slightly modified code taken from G4BetheBlochModel::SetParticle
282
284 fMassRatio = G4GenericIon::GenericIon()->GetPDGMass() / fMass;
287 fChargeSquare = q * q;
288 fRatio = electron_mass_c2 / fMass;
289 fOnePlusRatio2 = (1. + fRatio) * (1. + fRatio);
290 fOneMinusRatio2 = (1. - fRatio) * (1. - fRatio);
292 (0.5 * eplus * hbar_Planck * c_squared);
293 fMagMoment2 = magmom * magmom - 1.0;
295 {
296 G4double x = 0.8426 * GeV;
297 if(fSpin == 0.0 && fMass < GeV)
298 {
299 x = 0.736 * GeV;
300 }
301 else if(fMass > GeV)
302 {
303 x /= G4NistManager::Instance()->GetZ13(fMass / proton_mass_c2);
304 }
305 fFormFact = 2.0 * electron_mass_c2 / (x * x);
306 }
307}
308
309//////////////////////////////////////////////////////////////////////////////
311 G4double primAdjEnergy)
312{
313 return primAdjEnergy * fOnePlusRatio2 /
314 (fOneMinusRatio2 - 2. * fRatio * primAdjEnergy / fMass);
315}
316
317//////////////////////////////////////////////////////////////////////////////
319 G4double primAdjEnergy, G4double tcut)
320{
321 return primAdjEnergy + tcut;
322}
323
324//////////////////////////////////////////////////////////////////////////////
326 G4double)
327{
328 return GetHighEnergyLimit();
329}
330
331//////////////////////////////////////////////////////////////////////////////
333 G4double primAdjEnergy)
334{
335 return (2. * primAdjEnergy - 4. * fMass +
336 std::sqrt(4. * primAdjEnergy * primAdjEnergy + 16. * fMass * fMass +
337 8. * primAdjEnergy * fMass * (1. / fRatio + fRatio))) /
338 4.;
339}
CLHEP::Hep3Vector G4ThreeVector
@ fStopAndKill
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
const G4int Z[17]
const G4double A[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector unit() const
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
G4double GetPostStepWeightCorrection()
static G4AdjointCSManager * GetAdjointCSManager()
static G4AdjointElectron * AdjointElectron()
void CorrectPostStepWeight(G4ParticleChange *fParticleChange, G4double old_weight, G4double adjointPrimKinEnergy, G4double projectileKinEnergy, G4bool isScatProjToProj) override
G4double DiffCrossSectionPerAtomPrimToSecond(G4double kinEnergyProj, G4double kinEnergyProd, G4double Z, G4double A=0.) override
G4double GetSecondAdjEnergyMaxForProdToProj(G4double primAdjEnergy) override
void SampleSecondaries(const G4Track &aTrack, G4bool isScatProjToProj, G4ParticleChange *fParticleChange) override
G4double GetSecondAdjEnergyMinForProdToProj(G4double primAdjEnergy) override
G4double GetSecondAdjEnergyMaxForScatProjToProj(G4double primAdjEnergy) override
void SetIon(G4ParticleDefinition *adj_ion, G4ParticleDefinition *fwd_ion)
G4double GetSecondAdjEnergyMinForScatProjToProj(G4double primAdjEnergy, G4double tcut=0.) override
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4double GetTotalMomentum() const
static G4GenericIon * GenericIon()
Definition: G4GenericIon.cc:92
G4double GetZ13(G4double Z) const
static G4NistManager * Instance()
void AddSecondary(G4Track *aSecondary)
void ProposeEnergy(G4double finalEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double GetPDGMagneticMoment() const
G4double GetPDGCharge() const
const G4String & GetParticleName() const
G4double GetWeight() const
const G4DynamicParticle * GetDynamicParticle() const
G4ParticleDefinition * fAdjEquivDirectSecondPart
G4ParticleDefinition * fAdjEquivDirectPrimPart
G4Material * fCurrentMaterial
G4VEmModel * fDirectModel
G4ParticleDefinition * fDirectPrimaryPart
G4double SampleAdjSecEnergyFromCSMatrix(std::size_t MatrixIndex, G4double prim_energy, G4bool isScatProjToProj)
G4double GetHighEnergyLimit()
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0., G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.cc:284
virtual G4double GetChargeSquareRatio(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
Definition: G4VEmModel.cc:325
void ProposeTrackStatus(G4TrackStatus status)
void SetSecondaryWeightByProcess(G4bool)
void SetParentWeightByProcess(G4bool)
void ProposeParentWeight(G4double finalWeight)