Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PolarizedCompton.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// File name: G4PolarizedCompton
27//
28// Author: Andreas Schaelicke
29// based on code by Michel Maire / Vladimir IVANTCHENKO
30//
31// Class description
32// modified version respecting media and beam polarization
33// using the stokes formalism
34
35#include "G4PolarizedCompton.hh"
36
37#include "G4Electron.hh"
38#include "G4EmParameters.hh"
44#include "G4StokesVector.hh"
45#include "G4SystemOfUnits.hh"
46
47//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
48G4PhysicsTable* G4PolarizedCompton::theAsymmetryTable = nullptr;
49
51 G4ProcessType type)
52 : G4VEmProcess(processName, type)
53 , fType(10)
54 , fBuildAsymmetryTable(true)
55 , fUseAsymmetryTable(true)
56 , fIsInitialised(false)
57{
62 SetMinKinEnergyPrim(1. * MeV);
63 SetSplineFlag(true);
64 fEmModel = nullptr;
65}
66
67//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
69
70//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
71void G4PolarizedCompton::ProcessDescription(std::ostream& out) const
72{
73 out << "Polarized model for Compton scattering.\n";
74
76}
77
78//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
79void G4PolarizedCompton::CleanTable()
80{
81 if(theAsymmetryTable)
82 {
83 theAsymmetryTable->clearAndDestroy();
84 delete theAsymmetryTable;
85 theAsymmetryTable = nullptr;
86 }
87}
88
89//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
94
95//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
97{
98 if(!fIsInitialised)
99 {
100 fIsInitialised = true;
101 if(0 == fType)
102 {
103 if(nullptr == EmModel(0))
104 {
106 }
107 }
108 else
109 {
110 fEmModel = new G4PolarizedComptonModel();
111 SetEmModel(fEmModel);
112 }
116 AddEmModel(1, EmModel(0));
117 }
118}
119
120//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
122{
123 if(ss == "Klein-Nishina")
124 {
125 fType = 0;
126 }
127 if(ss == "Polarized-Compton")
128 {
129 fType = 10;
130 }
131}
132
133//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
135 G4double previousStepSize,
137{
138 // *** get unploarised mean free path from lambda table ***
139 G4double mfp =
140 G4VEmProcess::GetMeanFreePath(aTrack, previousStepSize, condition);
141
142 if(theAsymmetryTable && fUseAsymmetryTable && mfp < DBL_MAX)
143 {
144 mfp *= ComputeSaturationFactor(aTrack);
145 }
146 if(verboseLevel >= 2)
147 {
148 G4cout << "G4PolarizedCompton::MeanFreePath: " << mfp / mm << " mm "
149 << G4endl;
150 }
151 return mfp;
152}
153
154//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
156 const G4Track& aTrack, G4double previousStepSize, G4ForceCondition* condition)
157{
158 // save previous values
161
162 // *** compute unpolarized step limit ***
163 // this changes theNumberOfInteractionLengthLeft and currentInteractionLength
165 aTrack, previousStepSize, condition);
166 G4double x0 = x;
167 G4double satFact = 1.0;
168
169 // *** add corrections on polarisation ***
170 if(theAsymmetryTable && fUseAsymmetryTable && x < DBL_MAX)
171 {
172 satFact = ComputeSaturationFactor(aTrack);
173 G4double curLength = currentInteractionLength * satFact;
174 G4double prvLength = iLength * satFact;
175 if(nLength > 0.0)
176 {
178 std::max(nLength - previousStepSize / prvLength, 0.0);
179 }
180 x = theNumberOfInteractionLengthLeft * curLength;
181 }
182 if(verboseLevel >= 2)
183 {
184 G4cout << "G4PolarizedCompton::PostStepGPIL: " << std::setprecision(8)
185 << x / mm << " mm;" << G4endl
186 << " unpolarized value: " << std::setprecision(8)
187 << x0 / mm << " mm." << G4endl;
188 }
189 return x;
190}
191
192//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
193G4double G4PolarizedCompton::ComputeSaturationFactor(const G4Track& aTrack)
194{
195 G4double factor = 1.0;
196
197 // *** get asymmetry, if target is polarized ***
198 const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
199 const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
200 const G4StokesVector GammaPolarization =
202 const G4ParticleMomentum GammaDirection0 =
203 aDynamicGamma->GetMomentumDirection();
204
205 const G4Material* aMaterial = aTrack.GetMaterial();
206 G4VPhysicalVolume* aPVolume = aTrack.GetVolume();
207 G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
208
209 G4PolarizationManager* polarizationManager =
211
212 const G4bool VolumeIsPolarized = polarizationManager->IsPolarized(aLVolume);
213 G4StokesVector ElectronPolarization =
214 polarizationManager->GetVolumePolarization(aLVolume);
215
216 if(VolumeIsPolarized)
217 {
218 if(verboseLevel >= 2)
219 {
220 G4cout << "G4PolarizedCompton::ComputeSaturationFactor: " << G4endl;
221 G4cout << " Mom " << GammaDirection0 << G4endl;
222 G4cout << " Polarization " << GammaPolarization << G4endl;
223 G4cout << " MaterialPol. " << ElectronPolarization << G4endl;
224 G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
225 G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
226 G4cout << " Material " << aMaterial << G4endl;
227 }
228
229 std::size_t midx = CurrentMaterialCutsCoupleIndex();
230 const G4PhysicsVector* aVector = nullptr;
231 if(midx < theAsymmetryTable->size())
232 {
233 aVector = (*theAsymmetryTable)(midx);
234 }
235 if(aVector)
236 {
237 G4double asymmetry = aVector->Value(GammaEnergy);
238
239 // we have to determine angle between particle motion
240 // and target polarisation here
241 // circ pol * Vec(ElectronPol)*Vec(PhotonMomentum)
242 // both vectors in global reference frame
243
244 G4double pol = ElectronPolarization * GammaDirection0;
245 G4double polProduct = GammaPolarization.p3() * pol;
246 factor /= (1. + polProduct * asymmetry);
247 if(verboseLevel >= 2)
248 {
249 G4cout << " Asymmetry: " << asymmetry << G4endl;
250 G4cout << " PolProduct: " << polProduct << G4endl;
251 G4cout << " Factor: " << factor << G4endl;
252 }
253 }
254 else
255 {
257 ed << "Problem with asymmetry table: material index " << midx
258 << " is out of range or the table is not filled";
259 G4Exception("G4PolarizedComptonModel::ComputeSaturationFactor", "em0048",
260 JustWarning, ed, "");
261 }
262 }
263 return factor;
264}
265
266//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
268{
269 // *** build (unpolarized) cross section tables (Lambda)
271 if(fBuildAsymmetryTable && fEmModel)
272 {
273 G4bool isMaster = true;
274 const G4PolarizedCompton* masterProcess =
275 static_cast<const G4PolarizedCompton*>(GetMasterProcess());
276 if(masterProcess && masterProcess != this)
277 {
278 isMaster = false;
279 }
280 if(isMaster)
281 {
282 BuildAsymmetryTable(part);
283 }
284 }
285}
286
287//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
288void G4PolarizedCompton::BuildAsymmetryTable(const G4ParticleDefinition& part)
289{
290 // cleanup old, initialise new table
291 CleanTable();
292 theAsymmetryTable =
294
295 // Access to materials
296 const G4ProductionCutsTable* theCoupleTable =
298 G4int numOfCouples = (G4int)theCoupleTable->GetTableSize();
299 if(!theAsymmetryTable)
300 {
301 return;
302 }
303 G4int nbins = LambdaBinning();
304 G4double emin = MinKinEnergy();
305 G4double emax = MaxKinEnergy();
306 G4PhysicsLogVector* aVector = nullptr;
307 G4PhysicsLogVector* bVector = nullptr;
308
309 for(G4int i = 0; i < numOfCouples; ++i)
310 {
311 if(theAsymmetryTable->GetFlag(i))
312 {
313 // create physics vector and fill it
314 const G4MaterialCutsCouple* couple =
315 theCoupleTable->GetMaterialCutsCouple(i);
316 // use same parameters as for lambda
317 if(!aVector)
318 {
319 aVector = new G4PhysicsLogVector(emin, emax, nbins, true);
320 bVector = aVector;
321 }
322 else
323 {
324 bVector = new G4PhysicsLogVector(*aVector);
325 }
326
327 for(G4int j = 0; j <= nbins; ++j)
328 {
329 G4double energy = bVector->Energy(j);
330 G4double tasm = 0.;
331 G4double asym = ComputeAsymmetry(energy, couple, part, 0., tasm);
332 bVector->PutValue(j, asym);
333 }
334 bVector->FillSecondDerivatives();
335 G4PhysicsTableHelper::SetPhysicsVector(theAsymmetryTable, i, bVector);
336 }
337 }
338}
339
340//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
341G4double G4PolarizedCompton::ComputeAsymmetry(
342 G4double energy, const G4MaterialCutsCouple* couple,
343 const G4ParticleDefinition& aParticle, G4double cut, G4double& tAsymmetry)
344{
345 G4double lAsymmetry = 0.0;
346 tAsymmetry = 0;
347
348 // calculate polarized cross section
349 G4ThreeVector thePolarization = G4ThreeVector(0., 0., 1.);
350 fEmModel->SetTargetPolarization(thePolarization);
351 fEmModel->SetBeamPolarization(thePolarization);
352 G4double sigma2 =
353 fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
354
355 // calculate unpolarized cross section
356 thePolarization = G4ThreeVector();
357 fEmModel->SetTargetPolarization(thePolarization);
358 fEmModel->SetBeamPolarization(thePolarization);
359 G4double sigma0 =
360 fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
361
362 // determine asymmetries
363 if(sigma0 > 0.)
364 {
365 lAsymmetry = sigma2 / sigma0 - 1.;
366 }
367 return lAsymmetry;
368}
@ fComptonScattering
G4double condition(const G4ErrorSymMatrix &m)
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4ForceCondition
G4ProcessType
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition G4Electron.cc:91
static G4EmParameters * Instance()
G4double MinKinEnergy() const
G4double MaxKinEnergy() const
static G4Gamma * Gamma()
Definition G4Gamma.cc:81
const G4String & GetName() const
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
static void SetPhysicsVector(G4PhysicsTable *physTable, std::size_t idx, G4PhysicsVector *vec)
void clearAndDestroy()
G4bool GetFlag(std::size_t i) const
void PutValue(const std::size_t index, const G4double value)
G4double Energy(const std::size_t index) const
G4double Value(const G4double energy, std::size_t &lastidx) const
void FillSecondDerivatives(const G4SplineType=G4SplineType::Base, const G4double dir1=0.0, const G4double dir2=0.0)
bool IsPolarized(G4LogicalVolume *lVol) const
const G4StokesVector GetVolumePolarization(G4LogicalVolume *lVol) const
static G4PolarizationManager * GetInstance()
void SetTargetPolarization(const G4ThreeVector &pTarget)
void SetBeamPolarization(const G4ThreeVector &pBeam)
virtual void BuildPhysicsTable(const G4ParticleDefinition &) override
void SetModel(const G4String &name)
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
virtual void ProcessDescription(std::ostream &) const override
virtual G4double GetMeanFreePath(const G4Track &aTrack, G4double previousStepSize, G4ForceCondition *condition) override
virtual ~G4PolarizedCompton() override
virtual G4bool IsApplicable(const G4ParticleDefinition &) override
G4PolarizedCompton(const G4String &processName="pol-compt", G4ProcessType type=fElectromagnetic)
virtual void InitialiseProcess(const G4ParticleDefinition *) override
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
G4double p3() const
G4VPhysicalVolume * GetVolume() const
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
const G4ThreeVector & GetPolarization() const
void SetHighEnergyLimit(G4double)
void SetLowEnergyLimit(G4double)
G4double CrossSection(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void BuildPhysicsTable(const G4ParticleDefinition &) override
G4VEmModel * EmModel(size_t index=0) const
void SetBuildTableFlag(G4bool val)
void AddEmModel(G4int, G4VEmModel *, const G4Region *region=nullptr)
void SetEmModel(G4VEmModel *, G4int index=0)
void SetSecondaryParticle(const G4ParticleDefinition *p)
void SetSplineFlag(G4bool val)
void ProcessDescription(std::ostream &outFile) const override
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
G4double MaxKinEnergy() const
G4double MinKinEnergy() const
void SetStartFromNullFlag(G4bool val)
G4int LambdaBinning() const
void SetMinKinEnergyPrim(G4double e)
size_t CurrentMaterialCutsCoupleIndex() const
G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4double currentInteractionLength
const G4VProcess * GetMasterProcess() const
G4int verboseLevel
G4double theNumberOfInteractionLengthLeft
void SetProcessSubType(G4int)
G4double energy(const ThreeVector &p, const G4double m)
#define DBL_MAX
Definition templates.hh:62