Geant4 10.7.0
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//
27//
28//
29// File name: G4PolarizedCompton
30//
31// Author: Andreas Schaelicke
32// based on code by Michel Maire / Vladimir IVANTCHENKO
33// Class description
34//
35// modified version respecting media and beam polarization
36// using the stokes formalism
37//
38// Creation date: 01.05.2005
39//
40// Modifications:
41//
42// 01-01-05, include polarization description (A.Stahl)
43// 01-01-05, create asymmetry table and determine interactionlength (A.Stahl)
44// 01-05-05, update handling of media polarization (A.Schalicke)
45// 01-05-05, update polarized differential cross section (A.Schalicke)
46// 20-05-05, added polarization transfer (A.Schalicke)
47// 10-06-05, transformation between different reference frames (A.Schalicke)
48// 17-10-05, correct reference frame dependence in GetMeanFreePath (A.Schalicke)
49// 26-07-06, cross section recalculated (P.Starovoitov)
50// 09-08-06, make it work under current geant4 release (A.Schalicke)
51// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
52// -----------------------------------------------------------------------------
53
54
55#include "G4PolarizedCompton.hh"
56#include "G4SystemOfUnits.hh"
57#include "G4Electron.hh"
58
59#include "G4StokesVector.hh"
66#include "G4EmParameters.hh"
67
68//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
69
70G4PhysicsTable* G4PolarizedCompton::theAsymmetryTable = nullptr;
71
73 G4ProcessType type):
74 G4VEmProcess (processName, type),
75 buildAsymmetryTable(true),
76 useAsymmetryTable(true),
77 isInitialised(false),
78 mType(10),
79 targetPolarization(0.0,0.0,0.0)
80{
86 SetSplineFlag(true);
87 emModel = nullptr;
88}
89
90//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
91
93{
94 CleanTable();
95}
96
97//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
98
99void G4PolarizedCompton::CleanTable()
100{
101 if( theAsymmetryTable) {
102 theAsymmetryTable->clearAndDestroy();
103 delete theAsymmetryTable;
104 theAsymmetryTable = nullptr;
105 }
106}
107
108//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
109
111{
112 return (&p == G4Gamma::Gamma());
113}
114
115//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
116
118{
119 if(!isInitialised) {
120 isInitialised = true;
121 if(0 == mType) {
122 if(!EmModel(0)) { SetEmModel(new G4KleinNishinaCompton()); }
123 } else {
124 emModel = new G4PolarizedComptonModel();
125 SetEmModel(emModel);
126 }
130 AddEmModel(1, EmModel(0));
131 }
132}
133
134//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
135
137{
138 G4cout << " Total cross sections has a good parametrisation"
139 << " from 10 KeV to (100/Z) GeV"
140 << "\n Sampling according " << EmModel(0)->GetName() << " model"
141 << G4endl;
142}
143
144//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
145
147{
148 if(ss == "Klein-Nishina") { mType = 0; }
149 if(ss == "Polarized-Compton") { mType = 10; }
150}
151
152//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
153
155 G4double previousStepSize,
157{
158 // *** get unploarised mean free path from lambda table ***
159 G4double mfp = G4VEmProcess::GetMeanFreePath(aTrack, previousStepSize, condition);
160
161 if (theAsymmetryTable && useAsymmetryTable && mfp < DBL_MAX) {
162 mfp *= ComputeSaturationFactor(aTrack);
163 }
164 if (verboseLevel>=2) {
165 G4cout << "G4PolarizedCompton::MeanFreePath: " << mfp / mm << " mm " << G4endl;
166 }
167 return mfp;
168}
169
170//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
171
173 const G4Track& aTrack,
174 G4double previousStepSize,
176{
177 // save previous values
180
181 // *** compute unpolarized step limit ***
182 // this changes theNumberOfInteractionLengthLeft and currentInteractionLength
184 previousStepSize,
185 condition);
186 G4double x0 = x;
187 G4double satFact = 1.0;
188
189 // *** add corrections on polarisation ***
190 if (theAsymmetryTable && useAsymmetryTable && x < DBL_MAX) {
191 satFact = ComputeSaturationFactor(aTrack);
192 G4double curLength = currentInteractionLength*satFact;
193 G4double prvLength = iLength*satFact;
194 if(nLength > 0.0) {
196 std::max(nLength - previousStepSize/prvLength, 0.0);
197 }
198 x = theNumberOfInteractionLengthLeft * curLength;
199 }
200 if (verboseLevel>=2) {
201 G4cout << "G4PolarizedCompton::PostStepGPIL: "
202 << std::setprecision(8) << x/mm << " mm;" << G4endl
203 << " unpolarized value: "
204 << std::setprecision(8) << x0/mm << " mm." << G4endl;
205 }
206 return x;
207}
208
209//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
210
211G4double G4PolarizedCompton::ComputeSaturationFactor(const G4Track& aTrack)
212{
213 G4double factor = 1.0;
214
215 // *** get asymmetry, if target is polarized ***
216 const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
217 const G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
218 const G4StokesVector GammaPolarization = aTrack.GetPolarization();
219 const G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
220
221 G4Material* aMaterial = aTrack.GetMaterial();
222 G4VPhysicalVolume* aPVolume = aTrack.GetVolume();
223 G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
224
225 // G4Material* bMaterial = aLVolume->GetMaterial();
227
228 const G4bool VolumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
229 G4StokesVector ElectronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
230
231 if (VolumeIsPolarized) {
232
233 if (verboseLevel>=2) {
234 G4cout << "G4PolarizedCompton::ComputeSaturationFactor: " << G4endl;
235 G4cout << " Mom " << GammaDirection0 << G4endl;
236 G4cout << " Polarization " << GammaPolarization << G4endl;
237 G4cout << " MaterialPol. " << ElectronPolarization << G4endl;
238 G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
239 G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
240 G4cout << " Material " << aMaterial << G4endl;
241 }
242
243 size_t midx = CurrentMaterialCutsCoupleIndex();
244 const G4PhysicsVector* aVector = nullptr;
245 if(midx < theAsymmetryTable->size()) {
246 aVector = (*theAsymmetryTable)(midx);
247 }
248 if (aVector) {
249 G4double asymmetry = aVector->Value(GammaEnergy);
250
251 // we have to determine angle between particle motion
252 // and target polarisation here
253 // circ pol * Vec(ElectronPol)*Vec(PhotonMomentum)
254 // both vectors in global reference frame
255
256 G4double pol = ElectronPolarization*GammaDirection0;
257 G4double polProduct = GammaPolarization.p3() * pol;
258 factor /= (1. + polProduct * asymmetry);
259 if (verboseLevel>=2) {
260 G4cout << " Asymmetry: " << asymmetry << G4endl;
261 G4cout << " PolProduct: " << polProduct << G4endl;
262 G4cout << " Factor: " << factor << G4endl;
263 }
264 } else {
266 ed << "Problem with asymmetry table: material index " << midx
267 << " is out of range or the table is not filled";
268 G4Exception("G4PolarizedComptonModel::ComputeSaturationFactor","em0048",
269 JustWarning, ed, "");
270 }
271 }
272 return factor;
273}
274
275//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
276
278{
279 // *** build (unpolarized) cross section tables (Lambda)
281 if(buildAsymmetryTable && emModel) {
282 G4bool isMaster = true;
283 const G4PolarizedCompton* masterProcess =
284 static_cast<const G4PolarizedCompton*>(GetMasterProcess());
285 if(masterProcess && masterProcess != this) { isMaster = false; }
286 if(isMaster) { BuildAsymmetryTable(part); }
287 }
288}
289
290//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
291
292void G4PolarizedCompton::BuildAsymmetryTable(const G4ParticleDefinition& part)
293{
294 // cleanup old, initialise new table
295 CleanTable();
296 theAsymmetryTable =
298
299 // Access to materials
300 const G4ProductionCutsTable* theCoupleTable=
302 size_t numOfCouples = theCoupleTable->GetTableSize();
303 if(!theAsymmetryTable) { return; }
304 G4int nbins = LambdaBinning();
305 G4double emin = MinKinEnergy();
306 G4double emax = MaxKinEnergy();
307 G4PhysicsLogVector* aVector = nullptr;
308 G4PhysicsLogVector* bVector = nullptr;
309
310 for(size_t i=0; i<numOfCouples; ++i) {
311 if (theAsymmetryTable->GetFlag(i)) {
312
313 // create physics vector and fill it
314 const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
315 // use same parameters as for lambda
316 if(!aVector) {
317 aVector = new G4PhysicsLogVector(emin, emax, nbins);
318 aVector->SetSpline(true);
319 bVector = aVector;
320 } else {
321 bVector = new G4PhysicsLogVector(*aVector);
322 }
323
324 for (G4int j = 0; j <= nbins; ++j ) {
325 G4double energy = bVector->Energy(j);
326 G4double tasm=0.;
327 G4double asym = ComputeAsymmetry(energy, couple, part, 0., tasm);
328 bVector->PutValue(j,asym);
329 }
330 G4PhysicsTableHelper::SetPhysicsVector(theAsymmetryTable, i, bVector);
331 }
332 }
333}
334
335//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
336
337G4double G4PolarizedCompton::ComputeAsymmetry(G4double energy,
338 const G4MaterialCutsCouple* couple,
339 const G4ParticleDefinition& aParticle,
340 G4double cut,
341 G4double & tAsymmetry)
342{
343 G4double lAsymmetry = 0.0;
344 tAsymmetry=0;
345
346 //
347 // calculate polarized cross section
348 //
349 G4ThreeVector thePolarization=G4ThreeVector(0.,0.,1.);
350 emModel->SetTargetPolarization(thePolarization);
351 emModel->SetBeamPolarization(thePolarization);
352 G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
353
354 //
355 // calculate unpolarized cross section
356 //
357 thePolarization=G4ThreeVector();
358 emModel->SetTargetPolarization(thePolarization);
359 emModel->SetBeamPolarization(thePolarization);
360 G4double sigma0=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
361
362 // determine assymmetries
363 if (sigma0 > 0.) {
364 lAsymmetry = sigma2/sigma0-1.;
365 }
366 return lAsymmetry;
367}
368
369//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@ fComptonScattering
G4double condition(const G4ErrorSymMatrix &m)
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
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:57
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition: G4Electron.cc:93
static G4EmParameters * Instance()
G4double MinKinEnergy() const
G4double MaxKinEnergy() const
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
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
G4double Energy(std::size_t index) const
G4double Value(G4double theEnergy, std::size_t &lastidx) const
void PutValue(std::size_t index, G4double theValue)
void SetSpline(G4bool)
bool IsPolarized(G4LogicalVolume *lVol) const
static G4PolarizationManager * GetInstance()
const G4ThreeVector & GetVolumePolarization(G4LogicalVolume *lVol) const
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 G4double GetMeanFreePath(const G4Track &aTrack, G4double previousStepSize, G4ForceCondition *condition) override
virtual G4bool IsApplicable(const G4ParticleDefinition &) override
G4PolarizedCompton(const G4String &processName="pol-compt", G4ProcessType type=fElectromagnetic)
virtual void PrintInfo() override
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)
Definition: G4VEmModel.hh:757
void SetLowEnergyLimit(G4double)
Definition: G4VEmModel.hh:764
G4double CrossSection(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.hh:529
const G4String & GetName() const
Definition: G4VEmModel.hh:827
virtual 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)
virtual 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
virtual G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4double currentInteractionLength
Definition: G4VProcess.hh:335
const G4VProcess * GetMasterProcess() const
Definition: G4VProcess.hh:518
G4int verboseLevel
Definition: G4VProcess.hh:356
G4double theNumberOfInteractionLengthLeft
Definition: G4VProcess.hh:331
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:406
G4double energy(const ThreeVector &p, const G4double m)
#define DBL_MAX
Definition: templates.hh:62