ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4eplusPolarizedAnnihilation.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4eplusPolarizedAnnihilation.cc
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 
57 #include "G4PhysicalConstants.hh"
58 #include "G4SystemOfUnits.hh"
59 #include "G4MaterialCutsCouple.hh"
60 #include "G4Gamma.hh"
61 #include "G4PhysicsVector.hh"
62 #include "G4PhysicsLogVector.hh"
63 
65 #include "G4PhysicsTableHelper.hh"
66 #include "G4ProductionCutsTable.hh"
67 #include "G4PolarizationManager.hh"
68 #include "G4PolarizationHelper.hh"
69 #include "G4StokesVector.hh"
70 
71 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
72 
74  : G4eplusAnnihilation(name), isInitialised(false),
75  theAsymmetryTable(nullptr),
76  theTransverseAsymmetryTable(nullptr)
77 {
80 }
81 
82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
83 
85 {
86  CleanTables();
87 }
88 
89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
90 
92 {
93  if(theAsymmetryTable) {
95  delete theAsymmetryTable;
96  theAsymmetryTable = nullptr;
97  }
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 
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 ***
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 
164 G4double
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 
249  const G4ParticleDefinition& part)
250 {
251  // cleanup old, initialise new table
252  CleanTables();
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  }
286  }
287  }
288 }
289 
290 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
291 
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
305  G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
306 
307  // calculate transversely polarized cross section
311  G4double sigma3=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
312 
313  // calculate unpolarized cross section
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....