Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PolarizedAnnihilation.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// Geant4 Class file
29//
30// File name: G4PolarizedAnnihilation
31//
32// Author: A. Schaelicke on base of Vladimir Ivanchenko / Michel Maire code
33//
34// Class Description:
35// Polarized process of e+ annihilation into 2 gammas
36
38
39#include "G4DynamicParticle.hh"
42#include "G4PhysicsVector.hh"
47#include "G4SystemOfUnits.hh"
48#include "G4StokesVector.hh"
49
50//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
53 , fAsymmetryTable(nullptr)
54 , fTransverseAsymmetryTable(nullptr)
55{
56 fEmModel = new G4PolarizedAnnihilationModel();
57 SetEmModel(fEmModel);
58}
59
60//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
62
63//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
64void G4PolarizedAnnihilation::CleanTables()
65{
66 if(fAsymmetryTable)
67 {
68 fAsymmetryTable->clearAndDestroy();
69 delete fAsymmetryTable;
70 fAsymmetryTable = nullptr;
71 }
72 if(fTransverseAsymmetryTable)
73 {
74 fTransverseAsymmetryTable->clearAndDestroy();
75 delete fTransverseAsymmetryTable;
76 fTransverseAsymmetryTable = nullptr;
77 }
78}
79
80//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
82 G4double previousStepSize,
84{
85 G4double mfp =
86 G4VEmProcess::GetMeanFreePath(track, previousStepSize, condition);
87
88 if(nullptr != fAsymmetryTable && nullptr != fTransverseAsymmetryTable && mfp < DBL_MAX)
89 {
90 mfp *= ComputeSaturationFactor(track);
91 }
92 if(verboseLevel >= 2)
93 {
94 G4cout << "G4PolarizedAnnihilation::MeanFreePath: " << mfp / mm << " mm "
95 << G4endl;
96 }
97 return mfp;
98}
99
100//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
102 const G4Track& track, G4double previousStepSize, G4ForceCondition* condition)
103{
104 // save previous values
107
108 // *** compute unpolarized step limit ***
109 // this changes theNumberOfInteractionLengthLeft and currentInteractionLength
111 track, previousStepSize, condition);
112 G4double x0 = x;
113 G4double satFact = 1.0;
114
115 // *** add corrections on polarisation ***
116 if(nullptr != fAsymmetryTable && nullptr != fTransverseAsymmetryTable && x < DBL_MAX)
117 {
118 satFact = ComputeSaturationFactor(track);
119 G4double curLength = currentInteractionLength * satFact;
120 G4double prvLength = iLength * satFact;
121 if(nLength > 0.0)
122 {
124 std::max(nLength - previousStepSize / prvLength, 0.0);
125 }
126 x = theNumberOfInteractionLengthLeft * curLength;
127 }
128 if(verboseLevel >= 2)
129 {
130 G4cout << "G4PolarizedAnnihilation::PostStepGPIL: " << std::setprecision(8)
131 << x / mm << " mm;" << G4endl
132 << " unpolarized value: "
133 << std::setprecision(8) << x0 / mm << " mm." << G4endl;
134 }
135 return x;
136}
137
138//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
139G4double G4PolarizedAnnihilation::ComputeSaturationFactor(const G4Track& track)
140{
141 const G4Material* aMaterial = track.GetMaterial();
142 G4VPhysicalVolume* aPVolume = track.GetVolume();
143 G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
144
145 G4PolarizationManager* polarizationManager =
147
148 const G4bool volumeIsPolarized = polarizationManager->IsPolarized(aLVolume);
149 G4StokesVector electronPolarization =
150 polarizationManager->GetVolumePolarization(aLVolume);
151
152 G4double factor = 1.0;
153
154 if(volumeIsPolarized)
155 {
156 // *** get asymmetry, if target is polarized ***
157 const G4DynamicParticle* aDynamicPositron = track.GetDynamicParticle();
158 const G4double positronEnergy = aDynamicPositron->GetKineticEnergy();
159 const G4StokesVector positronPolarization =
161 const G4ParticleMomentum positronDirection0 =
162 aDynamicPositron->GetMomentumDirection();
163
164 if(verboseLevel >= 2)
165 {
166 G4cout << "G4PolarizedAnnihilation::ComputeSaturationFactor: " << G4endl;
167 G4cout << " Mom " << positronDirection0 << G4endl;
168 G4cout << " Polarization " << positronPolarization << G4endl;
169 G4cout << " MaterialPol. " << electronPolarization << G4endl;
170 G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
171 G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
172 G4cout << " Material " << aMaterial << G4endl;
173 }
174
175 std::size_t midx = CurrentMaterialCutsCoupleIndex();
176 const G4PhysicsVector* aVector = nullptr;
177 const G4PhysicsVector* bVector = nullptr;
178 if(midx < fAsymmetryTable->size())
179 {
180 aVector = (*fAsymmetryTable)(midx);
181 }
182 if(midx < fTransverseAsymmetryTable->size())
183 {
184 bVector = (*fTransverseAsymmetryTable)(midx);
185 }
186 if(aVector && bVector)
187 {
188 G4double lAsymmetry = aVector->Value(positronEnergy);
189 G4double tAsymmetry = bVector->Value(positronEnergy);
190 G4double polZZ =
191 positronPolarization.z() * (electronPolarization * positronDirection0);
192 G4double polXX =
193 positronPolarization.x() *
194 (electronPolarization *
195 G4PolarizationHelper::GetParticleFrameX(positronDirection0));
196 G4double polYY =
197 positronPolarization.y() *
198 (electronPolarization *
199 G4PolarizationHelper::GetParticleFrameY(positronDirection0));
200
201 factor /= (1. + polZZ * lAsymmetry + (polXX + polYY) * tAsymmetry);
202
203 if(verboseLevel >= 2)
204 {
205 G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry
206 << G4endl;
207 G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ
208 << G4endl;
209 G4cout << " Factor: " << factor << G4endl;
210 }
211 }
212 else
213 {
215 ed << "Problem with asymmetry tables: material index " << midx
216 << " is out of range or tables are not filled";
217 G4Exception("G4PolarizedAnnihilation::ComputeSaturationFactor", "em0048",
218 JustWarning, ed, "");
219 }
220 }
221 return factor;
222}
223
224//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
226 const G4ParticleDefinition& part)
227{
229 if(isTheMaster)
230 {
231 BuildAsymmetryTables(part);
232 }
233}
234
235//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
236void G4PolarizedAnnihilation::BuildAsymmetryTables(
237 const G4ParticleDefinition& part)
238{
239 // cleanup old, initialise new table
240 CleanTables();
241 fAsymmetryTable = G4PhysicsTableHelper::PreparePhysicsTable(fAsymmetryTable);
242 fTransverseAsymmetryTable =
243 G4PhysicsTableHelper::PreparePhysicsTable(fTransverseAsymmetryTable);
244 if(nullptr == fAsymmetryTable) return;
245
246 // Access to materials
247 const G4ProductionCutsTable* theCoupleTable =
249 G4int numOfCouples = (G4int)theCoupleTable->GetTableSize();
250 for(G4int i = 0; i < numOfCouples; ++i)
251 {
252 if(fAsymmetryTable->GetFlag(i))
253 {
254 // create physics vector and fill it
255 const G4MaterialCutsCouple* couple =
256 theCoupleTable->GetMaterialCutsCouple(i);
257
258 // use same parameters as for lambda
259 G4PhysicsVector* aVector = LambdaPhysicsVector(couple);
260 G4PhysicsVector* tVector = LambdaPhysicsVector(couple);
261 G4int nn = (G4int)aVector->GetVectorLength();
262 for(G4int j = 0; j < nn; ++j)
263 {
264 G4double energy = aVector->Energy(j);
265 G4double tasm = 0.;
266 G4double asym = ComputeAsymmetry(energy, couple, part, 0., tasm);
267 aVector->PutValue(j, asym);
268 tVector->PutValue(j, tasm);
269 }
270 if(aVector->GetSpline()) {
271 aVector->FillSecondDerivatives();
272 tVector->FillSecondDerivatives();
273 }
274 G4PhysicsTableHelper::SetPhysicsVector(fAsymmetryTable, i, aVector);
275 G4PhysicsTableHelper::SetPhysicsVector(fTransverseAsymmetryTable, i,
276 tVector);
277 }
278 }
279}
280
281//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
282G4double G4PolarizedAnnihilation::ComputeAsymmetry(
283 G4double energy, const G4MaterialCutsCouple* couple,
284 const G4ParticleDefinition& aParticle, G4double cut, G4double& tAsymmetry)
285{
286 G4double lAsymmetry = 0.0;
287 tAsymmetry = 0.0;
288
289 // calculate polarized cross section
290 G4ThreeVector targetPolarization = G4ThreeVector(0., 0., 1.);
291 fEmModel->SetTargetPolarization(targetPolarization);
292 fEmModel->SetBeamPolarization(targetPolarization);
293 G4double sigma2 =
294 fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
295
296 // calculate transversely polarized cross section
297 targetPolarization = G4ThreeVector(1., 0., 0.);
298 fEmModel->SetTargetPolarization(targetPolarization);
299 fEmModel->SetBeamPolarization(targetPolarization);
300 G4double sigma3 =
301 fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
302
303 // calculate unpolarized cross section
304 targetPolarization = G4ThreeVector();
305 fEmModel->SetTargetPolarization(targetPolarization);
306 fEmModel->SetBeamPolarization(targetPolarization);
307 G4double sigma0 =
308 fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
309
310 // determine asymmetries
311 if(sigma0 > 0.)
312 {
313 lAsymmetry = sigma2 / sigma0 - 1.;
314 tAsymmetry = sigma3 / sigma0 - 1.;
315 }
316 return lAsymmetry;
317}
318
319//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
321{
322 out << "Polarized model for positron annihilation into 2 photons.\n";
323}
G4double condition(const G4ErrorSymMatrix &m)
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4ForceCondition
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
double z() const
double x() const
double y() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
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
std::size_t GetVectorLength() const
void FillSecondDerivatives(const G4SplineType=G4SplineType::Base, const G4double dir1=0.0, const G4double dir2=0.0)
G4bool GetSpline() const
static G4ThreeVector GetParticleFrameY(const G4ThreeVector &)
static G4ThreeVector GetParticleFrameX(const G4ThreeVector &)
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 ~G4PolarizedAnnihilation() override
virtual void ProcessDescription(std::ostream &) const override
G4PolarizedAnnihilation(const G4String &name="pol-annihil")
virtual G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
virtual void BuildPhysicsTable(const G4ParticleDefinition &) override
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
G4VPhysicalVolume * GetVolume() const
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
const G4ThreeVector & GetPolarization() const
G4double CrossSection(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.hh:520
G4PhysicsVector * LambdaPhysicsVector(const G4MaterialCutsCouple *)
void BuildPhysicsTable(const G4ParticleDefinition &) override
void SetEmModel(G4VEmModel *, G4int index=0)
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
G4bool isTheMaster
size_t CurrentMaterialCutsCoupleIndex() const
G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4double currentInteractionLength
Definition: G4VProcess.hh:339
G4int verboseLevel
Definition: G4VProcess.hh:360
G4double theNumberOfInteractionLengthLeft
Definition: G4VProcess.hh:335
#define DBL_MAX
Definition: templates.hh:62