Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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// $Id$
27//
28// -------------------------------------------------------------------
29//
30// GEANT4 Class file
31//
32//
33// File name: G4eplusPolarizedAnnihilation
34//
35// Author: A. Schaelicke on base of Vladimir Ivanchenko / Michel Maire code
36//
37// Creation date: 02.07.2006
38//
39// Modifications:
40// 26-07-06 modified cross section (P. Starovoitov)
41// 21-08-06 interface updated (A. Schaelicke)
42// 11-06-07, add PostStepGetPhysicalInteractionLength (A.Schalicke)
43// 02-10-07, enable AtRest (V.Ivanchenko)
44//
45//
46// Class Description:
47//
48// Polarized process of e+ annihilation into 2 gammas
49//
50
51//
52// -------------------------------------------------------------------
53//
54//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
55//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
56
59#include "G4SystemOfUnits.hh"
61#include "G4Gamma.hh"
62#include "G4PhysicsVector.hh"
63#include "G4PhysicsLogVector.hh"
64
65
71#include "G4StokesVector.hh"
72
73//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
74
76 : G4VEmProcess(name), isInitialised(false),
77 theAsymmetryTable(NULL),
78 theTransverseAsymmetryTable(NULL)
79{
80 enableAtRestDoIt = true;
82 emModel = 0;
83}
84
85//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
86
88{
89 if (theAsymmetryTable) {
90 theAsymmetryTable->clearAndDestroy();
91 delete theAsymmetryTable;
92 }
93 if (theTransverseAsymmetryTable) {
94 theTransverseAsymmetryTable->clearAndDestroy();
95 delete theTransverseAsymmetryTable;
96 }
97}
98
99//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
100
102{
103 if(!isInitialised) {
104 isInitialised = true;
105 // SetVerboseLevel(3);
106 SetBuildTableFlag(true);
109 G4double emin = 0.1*keV;
110 G4double emax = 100.*TeV;
111 SetLambdaBinning(120);
112 SetMinKinEnergy(emin);
113 SetMaxKinEnergy(emax);
114 emModel = new G4PolarizedAnnihilationModel();
115 emModel->SetLowEnergyLimit(emin);
116 emModel->SetHighEnergyLimit(emax);
117 AddEmModel(1, emModel);
118 }
119}
120
121
122//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
123
124 // for polarization
125
127 G4double previousStepSize,
129{
130 G4double mfp = G4VEmProcess::GetMeanFreePath(track, previousStepSize, condition);
131
132 if (theAsymmetryTable) {
133
134 G4Material* aMaterial = track.GetMaterial();
135 G4VPhysicalVolume* aPVolume = track.GetVolume();
136 G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
137
138 // G4Material* bMaterial = aLVolume->GetMaterial();
140
141 const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
142 G4StokesVector electronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
143
144 if (!volumeIsPolarized || mfp == DBL_MAX) return mfp;
145
146 // *** get asymmetry, if target is polarized ***
147 const G4DynamicParticle* aDynamicPositron = track.GetDynamicParticle();
148 const G4double positronEnergy = aDynamicPositron->GetKineticEnergy();
149 const G4StokesVector positronPolarization = track.GetPolarization();
150 const G4ParticleMomentum positronDirection0 = aDynamicPositron->GetMomentumDirection();
151
152 if (verboseLevel>=2) {
153
154 G4cout << " Mom " << positronDirection0 << G4endl;
155 G4cout << " Polarization " << positronPolarization << G4endl;
156 G4cout << " MaterialPol. " << electronPolarization << G4endl;
157 G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
158 G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
159 G4cout << " Material " << aMaterial << G4endl;
160 }
161
162 G4bool isOutRange;
164 G4double lAsymmetry = (*theAsymmetryTable)(idx)->
165 GetValue(positronEnergy, isOutRange);
166 G4double tAsymmetry = (*theTransverseAsymmetryTable)(idx)->
167 GetValue(positronEnergy, isOutRange);
168
169 G4double polZZ = positronPolarization.z()*
170 electronPolarization*positronDirection0;
171 G4double polXX = positronPolarization.x()*
172 electronPolarization*G4PolarizationHelper::GetParticleFrameX(positronDirection0);
173 G4double polYY = positronPolarization.y()*
174 electronPolarization*G4PolarizationHelper::GetParticleFrameY(positronDirection0);
175
176 G4double impact = 1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry;
177
178 mfp *= 1. / impact;
179
180 if (verboseLevel>=2) {
181 G4cout << " MeanFreePath: " << mfp / mm << " mm " << G4endl;
182 G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
183 G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
184 }
185 }
186
187 return mfp;
188}
189
190//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
191
193 const G4Track& track,
194 G4double previousStepSize,
196{
198
199 if (theAsymmetryTable) {
200
201 G4Material* aMaterial = track.GetMaterial();
202 G4VPhysicalVolume* aPVolume = track.GetVolume();
203 G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
204
205 // G4Material* bMaterial = aLVolume->GetMaterial();
207
208 const G4bool volumeIsPolarized = polarizationManger->IsPolarized(aLVolume);
209 G4StokesVector electronPolarization = polarizationManger->GetVolumePolarization(aLVolume);
210
211 if (!volumeIsPolarized || mfp == DBL_MAX) return mfp;
212
213 // *** get asymmetry, if target is polarized ***
214 const G4DynamicParticle* aDynamicPositron = track.GetDynamicParticle();
215 const G4double positronEnergy = aDynamicPositron->GetKineticEnergy();
216 const G4StokesVector positronPolarization = track.GetPolarization();
217 const G4ParticleMomentum positronDirection0 = aDynamicPositron->GetMomentumDirection();
218
219 if (verboseLevel>=2) {
220
221 G4cout << " Mom " << positronDirection0 << G4endl;
222 G4cout << " Polarization " << positronPolarization << 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 G4bool isOutRange;
231 G4double lAsymmetry = (*theAsymmetryTable)(idx)->
232 GetValue(positronEnergy, isOutRange);
233 G4double tAsymmetry = (*theTransverseAsymmetryTable)(idx)->
234 GetValue(positronEnergy, isOutRange);
235
236 G4double polZZ = positronPolarization.z()*
237 electronPolarization*positronDirection0;
238 G4double polXX = positronPolarization.x()*
239 electronPolarization*G4PolarizationHelper::GetParticleFrameX(positronDirection0);
240 G4double polYY = positronPolarization.y()*
241 electronPolarization*G4PolarizationHelper::GetParticleFrameY(positronDirection0);
242
243 G4double impact = 1. + polZZ*lAsymmetry + (polXX + polYY)*tAsymmetry;
244
245 mfp *= 1. / impact;
246
247 if (verboseLevel>=2) {
248 G4cout << " MeanFreePath: " << mfp / mm << " mm " << G4endl;
249 G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry << G4endl;
250 G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ << G4endl;
251 }
252 }
253
254 return mfp;
255}
256//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
257
259{
262}
263//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
264
266{
268 theAsymmetryTable = G4PhysicsTableHelper::PreparePhysicsTable(theAsymmetryTable);
269 theTransverseAsymmetryTable = G4PhysicsTableHelper::PreparePhysicsTable(theTransverseAsymmetryTable);
270}
271
273{
274 // Access to materials
275 const G4ProductionCutsTable* theCoupleTable=
277 size_t numOfCouples = theCoupleTable->GetTableSize();
278 G4cout<<" annih-numOfCouples="<<numOfCouples<<"\n";
279 for(size_t i=0; i<numOfCouples; ++i) {
280 G4cout<<"annih- "<<i<<"/"<<numOfCouples<<"\n";
281 if (!theAsymmetryTable) break;
282 G4cout<<"annih- "<<theAsymmetryTable->GetFlag(i)<<"\n";
283 if (theAsymmetryTable->GetFlag(i)) {
284 G4cout<<" building pol-annih ... \n";
285
286 // create physics vector and fill it
287 const G4MaterialCutsCouple* couple = theCoupleTable->GetMaterialCutsCouple(i);
288
289 // use same parameters as for lambda
290 G4PhysicsVector* aVector = LambdaPhysicsVector(couple);
291 G4PhysicsVector* tVector = LambdaPhysicsVector(couple);
292
293 for (G4int j = 0 ; j < LambdaBinning() ; ++j ) {
294 G4double lowEdgeEnergy = aVector->GetLowEdgeEnergy(j);
295 G4double tasm=0.;
296 G4double asym = ComputeAsymmetry(lowEdgeEnergy, couple, part, 0., tasm);
297 aVector->PutValue(j,asym);
298 tVector->PutValue(j,tasm);
299 }
300
301 G4PhysicsTableHelper::SetPhysicsVector(theAsymmetryTable, i, aVector);
302 G4PhysicsTableHelper::SetPhysicsVector(theTransverseAsymmetryTable, i, tVector);
303 }
304 }
305
306}
307
308
309//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
310
312 const G4MaterialCutsCouple* couple,
313 const G4ParticleDefinition& aParticle,
314 G4double cut,
315 G4double &tAsymmetry)
316{
317 G4double lAsymmetry = 0.0;
318 tAsymmetry = 0.0;
319
320 // calculate polarized cross section
321 theTargetPolarization=G4ThreeVector(0.,0.,1.);
322 emModel->SetTargetPolarization(theTargetPolarization);
323 emModel->SetBeamPolarization(theTargetPolarization);
324 G4double sigma2=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
325
326 // calculate transversely polarized cross section
327 theTargetPolarization=G4ThreeVector(1.,0.,0.);
328 emModel->SetTargetPolarization(theTargetPolarization);
329 emModel->SetBeamPolarization(theTargetPolarization);
330 G4double sigma3=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
331
332 // calculate unpolarized cross section
333 theTargetPolarization=G4ThreeVector();
334 emModel->SetTargetPolarization(theTargetPolarization);
335 emModel->SetBeamPolarization(theTargetPolarization);
336 G4double sigma0=emModel->CrossSection(couple,&aParticle,energy,cut,energy);
337
338 // determine assymmetries
339 if (sigma0>0.) {
340 lAsymmetry=sigma2/sigma0-1.;
341 tAsymmetry=sigma3/sigma0-1.;
342 }
343 return lAsymmetry;
344
345}
346
347
348
349//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
350
352{
353 G4cout << " Polarized model for annihilation into 2 photons"
354 << G4endl;
355}
356
357//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
358
360 const G4Step& )
361//
362// Performs the e+ e- annihilation when both particles are assumed at rest.
363// It generates two back to back photons with energy = electron_mass.
364// The angular distribution is isotropic.
365// GEANT4 internal units
366//
367// Note : Effects due to binding of atomic electrons are negliged.
368{
370
372
373 G4double cosTeta = 2.*G4UniformRand()-1. , sinTeta = std::sqrt(1.-cosTeta*cosTeta);
374 G4double phi = twopi * G4UniformRand();
375 G4ThreeVector direction (sinTeta*std::cos(phi), sinTeta*std::sin(phi), cosTeta);
377 direction, electron_mass_c2) );
379 -direction, electron_mass_c2) );
380 // Kill the incident positron
381 //
383 return &fParticleChange;
384}
385
386//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@ fAnnihilation
G4double condition(const G4ErrorSymMatrix &m)
G4ForceCondition
CLHEP::Hep3Vector G4ThreeVector
@ fStopAndKill
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
double z() const
double x() const
double y() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Gamma * Gamma()
Definition: G4Gamma.cc:86
G4String GetName() const
void InitializeForPostStep(const G4Track &)
void AddSecondary(G4DynamicParticle *aParticle)
static void SetPhysicsVector(G4PhysicsTable *physTable, size_t idx, G4PhysicsVector *vec)
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
void clearAndDestroy()
G4bool GetFlag(size_t i) const
virtual G4double GetLowEdgeEnergy(size_t binNumber) const
void PutValue(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
static G4ProductionCutsTable * GetProductionCutsTable()
Definition: G4Step.hh:78
G4VPhysicalVolume * GetVolume() const
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
const G4ThreeVector & GetPolarization() const
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:585
void SetLowEnergyLimit(G4double)
Definition: G4VEmModel.hh:592
G4double CrossSection(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.hh:418
G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
G4PhysicsVector * LambdaPhysicsVector(const G4MaterialCutsCouple *)
void AddEmModel(G4int, G4VEmModel *, const G4Region *region=0)
void SetBuildTableFlag(G4bool val)
void SetMinKinEnergy(G4double e)
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
void SetLambdaBinning(G4int nbins)
void SetSecondaryParticle(const G4ParticleDefinition *p)
void BuildPhysicsTable(const G4ParticleDefinition &)
void PreparePhysicsTable(const G4ParticleDefinition &)
void SetStartFromNullFlag(G4bool val)
G4ParticleChangeForGamma fParticleChange
G4int LambdaBinning() const
void SetMaxKinEnergy(G4double e)
size_t CurrentMaterialCutsCoupleIndex() const
void ProposeTrackStatus(G4TrackStatus status)
void SetNumberOfSecondaries(G4int totSecondaries)
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4bool enableAtRestDoIt
Definition: G4VProcess.hh:350
G4int verboseLevel
Definition: G4VProcess.hh:368
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:403
G4eplusPolarizedAnnihilation(const G4String &name="pol-annihil")
virtual void PreparePhysicsTable(const G4ParticleDefinition &)
virtual G4VParticleChange * AtRestDoIt(const G4Track &track, const G4Step &stepData)
virtual void BuildPhysicsTable(const G4ParticleDefinition &)
G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
virtual void InitialiseProcess(const G4ParticleDefinition *)
void BuildAsymmetryTable(const G4ParticleDefinition &part)
G4double ComputeAsymmetry(G4double energy, const G4MaterialCutsCouple *couple, const G4ParticleDefinition &particle, G4double cut, G4double &tasm)
#define DBL_MAX
Definition: templates.hh:83