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
G4AdjointPhotoElectricModel.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 "G4AdjointGamma.hh"
32#include "G4Gamma.hh"
33#include "G4ParticleChange.hh"
36#include "G4TrackStatus.hh"
37
38////////////////////////////////////////////////////////////////////////////////
40 : G4VEmAdjointModel("AdjointPEEffect")
41
42{
43 SetUseMatrix(false);
44 SetApplyCutInRange(false);
45
49 fSecondPartSameType = false;
51}
52
53////////////////////////////////////////////////////////////////////////////////
55
56////////////////////////////////////////////////////////////////////////////////
58 const G4Track& aTrack, G4bool isScatProjToProj,
59 G4ParticleChange* fParticleChange)
60{
61 if(isScatProjToProj)
62 return;
63
64 // Compute the fTotAdjointCS vectors if not already done for the current
65 // couple and electron energy
66 const G4DynamicParticle* aDynPart = aTrack.GetDynamicParticle();
67 G4double electronEnergy = aDynPart->GetKineticEnergy();
68 G4ThreeVector electronDirection = aDynPart->GetMomentumDirection();
69 fPreStepAdjointCS =
70 fTotAdjointCS; // The last computed CS was at pre step point
71 AdjointCrossSection(aTrack.GetMaterialCutsCouple(), electronEnergy,
72 isScatProjToProj);
73 fPostStepAdjointCS = fTotAdjointCS;
74
75 // Sample element
76 const G4ElementVector* theElementVector =
79 G4double rand_CS = G4UniformRand() * fXsec[nelm - 1];
80 for(fIndexElement = 0; fIndexElement < nelm - 1; ++fIndexElement)
81 {
82 if(rand_CS < fXsec[fIndexElement])
83 break;
84 }
85
86 // Sample shell and binding energy
87 G4int nShells = (*theElementVector)[fIndexElement]->GetNbOfAtomicShells();
88 rand_CS = fShellProb[fIndexElement][nShells - 1] * G4UniformRand();
89 G4int i;
90 for(i = 0; i < nShells - 1; ++i)
91 {
92 if(rand_CS < fShellProb[fIndexElement][i])
93 break;
94 }
95 G4double gammaEnergy =
96 electronEnergy + (*theElementVector)[fIndexElement]->GetAtomicShell(i);
97
98 // Sample cos theta
99 // Copy of the G4PEEfectFluoModel cos theta sampling method
100 // ElecCosThetaDistribution. This method cannot be used directly from
101 // G4PEEffectFluoModel because it is a friend method.
102 G4double cos_theta = 1.;
103 G4double gamma = 1. + electronEnergy / electron_mass_c2;
104 if(gamma <= 5.)
105 {
106 G4double beta = std::sqrt(gamma * gamma - 1.) / gamma;
107 G4double b = 0.5 * gamma * (gamma - 1.) * (gamma - 2.);
108
109 G4double rndm, term, greject, grejsup;
110 if(gamma < 2.)
111 grejsup = gamma * gamma * (1. + b - beta * b);
112 else
113 grejsup = gamma * gamma * (1. + b + beta * b);
114
115 do
116 {
117 rndm = 1. - 2. * G4UniformRand();
118 cos_theta = (rndm + beta) / (rndm * beta + 1.);
119 term = 1. - beta * cos_theta;
120 greject = (1. - cos_theta * cos_theta) * (1. + b * term) / (term * term);
121 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
122 } while(greject < G4UniformRand() * grejsup);
123 }
124
125 // direction of the adjoint gamma electron
126 G4double sin_theta = std::sqrt(1. - cos_theta * cos_theta);
127 G4double phi = twopi * G4UniformRand();
128 G4double dirx = sin_theta * std::cos(phi);
129 G4double diry = sin_theta * std::sin(phi);
130 G4double dirz = cos_theta;
131 G4ThreeVector adjoint_gammaDirection(dirx, diry, dirz);
132 adjoint_gammaDirection.rotateUz(electronDirection);
133
134 // Weight correction
135 CorrectPostStepWeight(fParticleChange, aTrack.GetWeight(), electronEnergy,
136 gammaEnergy, isScatProjToProj);
137
138 // Create secondary and modify fParticleChange
139 G4DynamicParticle* anAdjointGamma = new G4DynamicParticle(
140 G4AdjointGamma::AdjointGamma(), adjoint_gammaDirection, gammaEnergy);
141
142 fParticleChange->ProposeTrackStatus(fStopAndKill);
143 fParticleChange->AddSecondary(anAdjointGamma);
144}
145
146////////////////////////////////////////////////////////////////////////////////
148 G4ParticleChange* fParticleChange, G4double old_weight,
149 G4double adjointPrimKinEnergy, G4double projectileKinEnergy, G4bool)
150{
151 G4double new_weight = old_weight;
152
153 G4double w_corr =
155 fFactorCSBiasing;
156 w_corr *= fPostStepAdjointCS / fPreStepAdjointCS;
157
158 new_weight *= w_corr * projectileKinEnergy / adjointPrimKinEnergy;
159 fParticleChange->SetParentWeightByProcess(false);
160 fParticleChange->SetSecondaryWeightByProcess(false);
161 fParticleChange->ProposeParentWeight(new_weight);
162}
163
164////////////////////////////////////////////////////////////////////////////////
166 const G4MaterialCutsCouple* aCouple, G4double electronEnergy,
167 G4bool isScatProjToProj)
168{
169 if(isScatProjToProj)
170 return 0.;
171
172 G4double totBiasedAdjointCS = 0.;
173 if(aCouple != fCurrentCouple || fCurrenteEnergy != electronEnergy)
174 {
175 fTotAdjointCS = 0.;
176 DefineCurrentMaterialAndElectronEnergy(aCouple, electronEnergy);
177 const G4ElementVector* theElementVector =
179 const G4double* theAtomNumDensityVector =
181 size_t nelm = fCurrentMaterial->GetNumberOfElements();
182 for(fIndexElement = 0; fIndexElement < nelm; ++fIndexElement)
183 {
184 fTotAdjointCS += AdjointCrossSectionPerAtom(
185 (*theElementVector)[fIndexElement], electronEnergy) *
186 theAtomNumDensityVector[fIndexElement];
187 fXsec[fIndexElement] = fTotAdjointCS;
188 }
189
190 totBiasedAdjointCS = std::min(fTotAdjointCS, 0.01);
191 fFactorCSBiasing = totBiasedAdjointCS / fTotAdjointCS;
192 }
193 return totBiasedAdjointCS;
194}
195
196////////////////////////////////////////////////////////////////////////////////
198 const G4Element* anElement, G4double electronEnergy)
199{
200 G4int nShells = anElement->GetNbOfAtomicShells();
201 G4double Z = anElement->GetZ();
202 G4double gammaEnergy = electronEnergy + anElement->GetAtomicShell(0);
204 G4Gamma::Gamma(), gammaEnergy, Z, 0., 0., 0.);
205 G4double adjointCS = 0.;
206 if(CS > 0.)
207 adjointCS += CS / gammaEnergy;
208 fShellProb[fIndexElement][0] = adjointCS;
209 for(G4int i = 1; i < nShells; ++i)
210 {
211 G4double Bi1 = anElement->GetAtomicShell(i - 1);
212 G4double Bi = anElement->GetAtomicShell(i);
213 if(electronEnergy < Bi1 - Bi)
214 {
215 gammaEnergy = electronEnergy + Bi;
217 gammaEnergy, Z, 0., 0., 0.);
218 if(CS > 0.)
219 adjointCS += CS / gammaEnergy;
220 }
221 fShellProb[fIndexElement][i] = adjointCS;
222 }
223 adjointCS *= electronEnergy;
224 return adjointCS;
225}
226
227////////////////////////////////////////////////////////////////////////////////
228void G4AdjointPhotoElectricModel::DefineCurrentMaterialAndElectronEnergy(
229 const G4MaterialCutsCouple* couple, G4double anEnergy)
230{
231 fCurrentCouple = const_cast<G4MaterialCutsCouple*>(couple);
232 fCurrentMaterial = const_cast<G4Material*>(couple->GetMaterial());
233 fCurrenteEnergy = anEnergy;
235}
std::vector< const G4Element * > G4ElementVector
@ fStopAndKill
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
G4double GetPostStepWeightCorrection()
static G4AdjointCSManager * GetAdjointCSManager()
static G4AdjointElectron * AdjointElectron()
static G4AdjointGamma * AdjointGamma()
void CorrectPostStepWeight(G4ParticleChange *fParticleChange, G4double old_weight, G4double adjointPrimKinEnergy, G4double projectileKinEnergy, G4bool isScatProjToProj) override
G4double AdjointCrossSection(const G4MaterialCutsCouple *aCouple, G4double primEnergy, G4bool isScatProjToProj) override
void SampleSecondaries(const G4Track &aTrack, G4bool isScatProjToProj, G4ParticleChange *fParticleChange) override
G4double AdjointCrossSectionPerAtom(const G4Element *anElement, G4double electronEnergy)
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4double GetZ() const
Definition: G4Element.hh:131
G4int GetNbOfAtomicShells() const
Definition: G4Element.hh:147
G4double GetAtomicShell(G4int index) const
Definition: G4Element.cc:372
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:185
size_t GetNumberOfElements() const
Definition: G4Material.hh:181
const G4double * GetVecNbOfAtomsPerVolume() const
Definition: G4Material.hh:201
void AddSecondary(G4Track *aSecondary)
G4double GetWeight() const
const G4DynamicParticle * GetDynamicParticle() const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
G4ParticleDefinition * fAdjEquivDirectSecondPart
void SetUseMatrix(G4bool aBool)
G4ParticleDefinition * fAdjEquivDirectPrimPart
G4MaterialCutsCouple * fCurrentCouple
G4Material * fCurrentMaterial
G4VEmModel * fDirectModel
G4ParticleDefinition * fDirectPrimaryPart
void SetApplyCutInRange(G4bool aBool)
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0., G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.cc:284
void SetCurrentCouple(const G4MaterialCutsCouple *)
Definition: G4VEmModel.hh:468
void ProposeTrackStatus(G4TrackStatus status)
void SetSecondaryWeightByProcess(G4bool)
void SetParentWeightByProcess(G4bool)
void ProposeParentWeight(G4double finalWeight)