Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4eplusPolarizedAnnihilation.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// GEANT4 Class file
30//
31//
32// File name: G4eplusPolarizedAnnihilation
33//
34// Author: A. Schaelicke on base of Vladimir Ivanchenko / Michel Maire code
35//
36// Creation date: 02.07.2006
37//
38// Modifications:
39// 26-07-06 modified cross section (P. Starovoitov)
40// 21-08-06 interface updated (A. Schaelicke)
41// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
42// 02-10-07, enable AtRest (V.Ivanchenko)
43//
44//
45// Class Description:
46//
47// Polarized process of e+ annihilation into 2 gammas
48//
49
50//
51// -------------------------------------------------------------------
52//
53//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
54//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
55
58#include "G4SystemOfUnits.hh"
60#include "G4Gamma.hh"
61#include "G4PhysicsVector.hh"
62#include "G4PhysicsLogVector.hh"
63
69#include "G4StokesVector.hh"
70
71//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
72
74 : G4eplusAnnihilation(name), isInitialised(false),
75 theAsymmetryTable(nullptr),
76 theTransverseAsymmetryTable(nullptr)
77{
78 emModel = new G4PolarizedAnnihilationModel();
79 SetEmModel(emModel);
80}
81
82//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
83
85{
86 CleanTables();
87}
88
89//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
90
91void G4eplusPolarizedAnnihilation::CleanTables()
92{
93 if(theAsymmetryTable) {
94 theAsymmetryTable->clearAndDestroy();
95 delete theAsymmetryTable;
96 theAsymmetryTable = nullptr;
97 }
98 if(theTransverseAsymmetryTable) {
99 theTransverseAsymmetryTable->clearAndDestroy();
100 delete theTransverseAsymmetryTable;
101 theTransverseAsymmetryTable = nullptr;
102 }
103}
104
105//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
106
108 G4double previousStepSize,
110{
111 G4double mfp = G4VEmProcess::GetMeanFreePath(track, previousStepSize, condition);
112
113 if(theAsymmetryTable && theTransverseAsymmetryTable && mfp < DBL_MAX) {
114 mfp *= ComputeSaturationFactor(track);
115 }
116 if (verboseLevel>=2) {
117 G4cout << "G4eplusPolarizedAnnihilation::MeanFreePath: "
118 << mfp / mm << " mm " << G4endl;
119 }
120 return mfp;
121}
122
123//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
124
126 const G4Track& track,
127 G4double previousStepSize,
129{
130 // save previous values
133
134 // *** compute unpolarized step limit ***
135 // this changes theNumberOfInteractionLengthLeft and currentInteractionLength
137 previousStepSize,
138 condition);
139 G4double x0 = x;
140 G4double satFact = 1.0;
141
142 // *** add corrections on polarisation ***
143 if(theAsymmetryTable && theTransverseAsymmetryTable && x < DBL_MAX) {
144 satFact = ComputeSaturationFactor(track);
145 G4double curLength = currentInteractionLength*satFact;
146 G4double prvLength = iLength*satFact;
147 if(nLength > 0.0) {
149 std::max(nLength - previousStepSize/prvLength, 0.0);
150 }
151 x = theNumberOfInteractionLengthLeft * curLength;
152 }
153 if (verboseLevel>=2) {
154 G4cout << "G4eplusPolarizedAnnihilation::PostStepGPIL: "
155 << std::setprecision(8) << x/mm << " mm;" << G4endl
156 << " unpolarized value: "
157 << std::setprecision(8) << x0/mm << " mm." << G4endl;
158 }
159 return x;
160}
161
162//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
163
165G4eplusPolarizedAnnihilation::ComputeSaturationFactor(const G4Track& track)
166{
167 G4Material* aMaterial = track.GetMaterial();
168 G4VPhysicalVolume* aPVolume = track.GetVolume();
169 G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
170
172
173 const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
174 G4StokesVector electronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
175
176 G4double factor = 1.0;
177
178 if (volumeIsPolarized) {
179
180 // *** get asymmetry, if target is polarized ***
181 const G4DynamicParticle* aDynamicPositron = track.GetDynamicParticle();
182 const G4double positronEnergy = aDynamicPositron->GetKineticEnergy();
183 const G4StokesVector positronPolarization = track.GetPolarization();
184 const G4ParticleMomentum positronDirection0 = aDynamicPositron->GetMomentumDirection();
185
186 if (verboseLevel>=2) {
187 G4cout << "G4eplusPolarizedAnnihilation::ComputeSaturationFactor: " << G4endl;
188 G4cout << " Mom " << positronDirection0 << G4endl;
189 G4cout << " Polarization " << positronPolarization << G4endl;
190 G4cout << " MaterialPol. " << electronPolarization << G4endl;
191 G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
192 G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
193 G4cout << " Material " << aMaterial << G4endl;
194 }
195
196 size_t midx = CurrentMaterialCutsCoupleIndex();
197 const G4PhysicsVector* aVector = nullptr;
198 const G4PhysicsVector* bVector = nullptr;
199 if(midx < theAsymmetryTable->size()) {
200 aVector = (*theAsymmetryTable)(midx);
201 }
202 if(midx < theTransverseAsymmetryTable->size()) {
203 bVector = (*theTransverseAsymmetryTable)(midx);
204 }
205 if(aVector && bVector) {
206 G4double lAsymmetry = aVector->Value(positronEnergy);
207 G4double tAsymmetry = bVector->Value(positronEnergy);
208 G4double polZZ = positronPolarization.z()*
209 (electronPolarization*positronDirection0);
210 G4double polXX = positronPolarization.x()*
211 (electronPolarization*G4PolarizationHelper::GetParticleFrameX(positronDirection0));
212 G4double polYY = positronPolarization.y()*
213 (electronPolarization*G4PolarizationHelper::GetParticleFrameY(positronDirection0));
214
215 factor /= (1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry);
216
217 if (verboseLevel>=2) {
218 G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
219 G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
220 G4cout << " Factor: " << factor << G4endl;
221 }
222 } else {
224 ed << "Problem with asymmetry tables: material index " << midx
225 << " is out of range or tables are not filled";
226 G4Exception("G4eplusPolarizedAnnihilation::ComputeSaturationFactor","em0048",
227 JustWarning, ed, "");
228 }
229 }
230 return factor;
231}
232
233//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
234
236 const G4ParticleDefinition& part)
237{
239 G4bool isMaster = true;
240 const G4eplusPolarizedAnnihilation* masterProcess =
241 static_cast<const G4eplusPolarizedAnnihilation*>(GetMasterProcess());
242 if(masterProcess && masterProcess != this) { isMaster = false; }
243 if(isMaster) { BuildAsymmetryTables(part); }
244}
245
246//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
247
248void G4eplusPolarizedAnnihilation::BuildAsymmetryTables(
249 const G4ParticleDefinition& part)
250{
251 // cleanup old, initialise new table
252 CleanTables();
253 theAsymmetryTable =
255 theTransverseAsymmetryTable =
256 G4PhysicsTableHelper::PreparePhysicsTable(theTransverseAsymmetryTable);
257
258 // Access to materials
259 const G4ProductionCutsTable* theCoupleTable=
261 size_t numOfCouples = theCoupleTable->GetTableSize();
262 //G4cout<<" annih-numOfCouples="<<numOfCouples<<"\n";
263 for(size_t i=0; i<numOfCouples; ++i) {
264 //G4cout<<"annih- "<<i<<"/"<<numOfCouples<<"\n";
265 if (!theAsymmetryTable) break;
266 //G4cout<<"annih- "<<theAsymmetryTable->GetFlag(i)<<"\n";
267 if (theAsymmetryTable->GetFlag(i)) {
268 //G4cout<<" building pol-annih ... \n";
269
270 // create physics vector and fill it
271 const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
272
273 // use same parameters as for lambda
274 G4PhysicsVector* aVector = LambdaPhysicsVector(couple);
275 G4PhysicsVector* tVector = LambdaPhysicsVector(couple);
276
277 for (G4int j = 0 ; j < LambdaBinning() ; ++j ) {
278 G4double lowEdgeEnergy = aVector->GetLowEdgeEnergy(j);
279 G4double tasm=0.;
280 G4double asym = ComputeAsymmetry(lowEdgeEnergy, couple, part, 0., tasm);
281 aVector->PutValue(j,asym);
282 tVector->PutValue(j,tasm);
283 }
284 G4PhysicsTableHelper::SetPhysicsVector(theAsymmetryTable, i, aVector);
285 G4PhysicsTableHelper::SetPhysicsVector(theTransverseAsymmetryTable, i, tVector);
286 }
287 }
288}
289
290//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
291
292G4double G4eplusPolarizedAnnihilation::ComputeAsymmetry(G4double energy,
293 const G4MaterialCutsCouple* couple,
294 const G4ParticleDefinition& aParticle,
295 G4double cut,
296 G4double &tAsymmetry)
297{
298 G4double lAsymmetry = 0.0;
299 tAsymmetry = 0.0;
300
301 // calculate polarized cross section
302 theTargetPolarization=G4ThreeVector(0.,0.,1.);
303 emModel->SetTargetPolarization(theTargetPolarization);
304 emModel->SetBeamPolarization(theTargetPolarization);
305 G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
306
307 // calculate transversely polarized cross section
308 theTargetPolarization=G4ThreeVector(1.,0.,0.);
309 emModel->SetTargetPolarization(theTargetPolarization);
310 emModel->SetBeamPolarization(theTargetPolarization);
311 G4double sigma3=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
312
313 // calculate unpolarized cross section
314 theTargetPolarization=G4ThreeVector();
315 emModel->SetTargetPolarization(theTargetPolarization);
316 emModel->SetBeamPolarization(theTargetPolarization);
317 G4double sigma0=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
318
319 // determine assymmetries
320 if (sigma0>0.) {
321 lAsymmetry=sigma2/sigma0-1.;
322 tAsymmetry=sigma3/sigma0-1.;
323 }
324 return lAsymmetry;
325}
326
327//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
328
330{
331 G4cout << " Polarized model for annihilation into 2 photons"
332 << G4endl;
333}
334
335//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
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
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
G4double Value(G4double theEnergy, std::size_t &lastidx) const
G4double GetLowEdgeEnergy(std::size_t binNumber) const
void PutValue(std::size_t index, G4double theValue)
static G4ThreeVector GetParticleFrameY(const G4ThreeVector &)
static G4ThreeVector GetParticleFrameX(const G4ThreeVector &)
bool IsPolarized(G4LogicalVolume *lVol) const
static G4PolarizationManager * GetInstance()
const G4ThreeVector & GetVolumePolarization(G4LogicalVolume *lVol) const
void SetTargetPolarization(const G4ThreeVector &pTarget)
void SetBeamPolarization(const G4ThreeVector &pBeam)
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:529
G4PhysicsVector * LambdaPhysicsVector(const G4MaterialCutsCouple *)
virtual void BuildPhysicsTable(const G4ParticleDefinition &) override
void SetEmModel(G4VEmModel *, G4int index=0)
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
G4int LambdaBinning() const
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
G4eplusPolarizedAnnihilation(const G4String &name="pol-annihil")
virtual G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
virtual void BuildPhysicsTable(const G4ParticleDefinition &) override
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
#define DBL_MAX
Definition: templates.hh:62