source: trunk/source/processes/electromagnetic/lowenergy/src/G4PenelopeAnnihilation.cc @ 1196

Last change on this file since 1196 was 1055, checked in by garnier, 15 years ago

maj sur la beta de geant 4.9.3

File size: 11.4 KB
Line 
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// Author: Luciano Pandola
27//
28// History:
29// --------
30// 02 Jul 2003   L.Pandola    First implementation
31// 16 Mar 2004   L.Pandola    Removed unnecessary calls to std::pow(a,b)
32
33#include "G4PenelopeAnnihilation.hh"
34#include "Randomize.hh"
35#include "G4UnitsTable.hh"
36#include "G4PhysicsTable.hh"
37#include "G4ParticleDefinition.hh"
38#include "G4VParticleChange.hh"
39#include "G4Gamma.hh"
40#include "G4Positron.hh"
41#include "G4Track.hh"
42#include "G4Step.hh"
43#include "G4PhysicsLogVector.hh"
44#include "G4ElementTable.hh"
45#include "G4Material.hh"
46#include "G4MaterialCutsCouple.hh"
47
48// constructor
49 
50G4PenelopeAnnihilation::G4PenelopeAnnihilation(const G4String& processName)
51  : G4VRestDiscreteProcess (processName),
52    lowEnergyLimit(250*eV),
53    highEnergyLimit(100*GeV),
54    nBins(200),
55    cutForLowEnergySecondaryPhotons(250.0*eV)
56{
57  meanFreePathTable = 0;
58  if (verboseLevel > 0)
59    {
60      G4cout << GetProcessName() << " is created " << G4endl
61             << "Energy range: "
62             << lowEnergyLimit / keV << " keV - "
63             << highEnergyLimit / GeV << " GeV"
64             << G4endl;
65    }
66
67   G4cout << G4endl;
68   G4cout << "*******************************************************************************" << G4endl;
69   G4cout << "*******************************************************************************" << G4endl;
70   G4cout << "   The class G4PenelopeAnnihilation is NOT SUPPORTED ANYMORE. " << G4endl;
71   G4cout << "   It will be REMOVED with the next major release of Geant4. " << G4endl;
72   G4cout << "   Please consult: https://twiki.cern.ch/twiki/bin/view/Geant4/LoweProcesses" << G4endl;
73   G4cout << "*******************************************************************************" << G4endl;
74   G4cout << "*******************************************************************************" << G4endl;
75   G4cout << G4endl;
76}
77
78// destructor
79G4PenelopeAnnihilation::~G4PenelopeAnnihilation()
80{
81  if (meanFreePathTable) {
82      meanFreePathTable->clearAndDestroy();
83      delete meanFreePathTable;
84   }
85}
86 
87
88void G4PenelopeAnnihilation::BuildPhysicsTable(const G4ParticleDefinition& )
89{
90  G4double lowEdgeEnergy, value;
91  G4PhysicsLogVector* dataVector;
92
93  // Build mean free path table for the e+e- annihilation
94
95  if (meanFreePathTable) {
96    meanFreePathTable->clearAndDestroy(); delete meanFreePathTable;}
97
98  meanFreePathTable = 
99    new G4PhysicsTable(G4Material::GetNumberOfMaterials());
100  const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
101  G4Material* material;
102
103  for (size_t j=0;j<G4Material::GetNumberOfMaterials();j++) 
104    { 
105      //create physics vector then fill it ....
106      dataVector = new G4PhysicsLogVector(lowEnergyLimit, 
107                                         highEnergyLimit,nBins);
108      material = (*theMaterialTable)[j];
109      const G4ElementVector* theElementVector = material->GetElementVector();
110      const G4double* NbOfAtomsPerVolume = 
111        material->GetVecNbOfAtomsPerVolume(); 
112      for (G4int i=0;i<nBins;i++)     
113        {
114          lowEdgeEnergy = dataVector->GetLowEdgeEnergy(i);
115          G4double sigma=0.0 ;
116          for (size_t elm=0;elm<material->GetNumberOfElements();elm++)
117            {     
118              G4double Z = (*theElementVector)[elm]->GetZ();
119              sigma += NbOfAtomsPerVolume[elm] * Z * 
120                calculateCrossSectionPerElectron(lowEdgeEnergy);
121            }       
122          if (sigma > DBL_MIN) 
123            {
124              value = 1.0/sigma;
125            }
126          else
127            {
128              value = DBL_MAX;
129            }
130          dataVector->PutValue(i,value);
131        }
132      meanFreePathTable->insertAt(j,dataVector);
133    }
134  PrintInfoDefinition();
135}
136
137G4double G4PenelopeAnnihilation::calculateCrossSectionPerElectron
138                              (G4double ene)
139{
140  //Heitler dcs formula for annihilation with free electrons at rest
141  G4double crossSection=0.0;
142  G4double gamma = 1.0+std::max(ene,1.0*eV)/electron_mass_c2;
143  G4double gamma2 = gamma*gamma;
144  G4double f2 = gamma2-1.0;
145  G4double f1 = std::sqrt(f2);
146  G4double pielr2 = pi*classic_electr_radius*classic_electr_radius;
147  crossSection = pielr2*((gamma2+4.0*gamma+1.0)*std::log(gamma+f1)/f2
148                         - (gamma+3.0)/f1)/(gamma+1.0);
149  return crossSection;
150}
151
152G4VParticleChange* G4PenelopeAnnihilation::PostStepDoIt(const G4Track& aTrack,
153                                                     const G4Step& )
154{
155   aParticleChange.Initialize(aTrack);
156     
157   const G4DynamicParticle* incidentPositron = aTrack.GetDynamicParticle();
158   G4double kineticEnergy = incidentPositron->GetKineticEnergy();
159   G4ParticleMomentum positronDirection = 
160     incidentPositron->GetMomentumDirection();
161
162   // Do not make anything if particle is stopped, the annihilation then
163   // should be performed by the AtRestDoIt!
164   if (aTrack.GetTrackStatus() == fStopButAlive) return &aParticleChange;
165
166   //G4cout << "Sono nel PostStep" << G4endl;
167
168   //Annihilation in flight
169   G4double gamma = 1.0 + std::max(kineticEnergy,1.0*eV)/electron_mass_c2;
170   G4double gamma21 = std::sqrt(gamma*gamma-1);
171   G4double ani = 1.0+gamma;
172   G4double chimin = 1.0/(ani+gamma21);
173   G4double rchi = (1.0-chimin)/chimin;
174   G4double gt0 = ani*ani-2.0;
175   G4double epsilon=0.0, reject=0.0, test=0.0;
176   do{
177     epsilon = chimin*std::pow(rchi,G4UniformRand());
178     reject = ani*ani*(1.0-epsilon)+2.0*gamma-(1.0/epsilon);
179     test = G4UniformRand()*gt0-reject;
180   }while(test>0);
181   
182   G4double totalAvailableEnergy = kineticEnergy + 2.0*electron_mass_c2;
183   G4double photon1Energy = epsilon*totalAvailableEnergy;
184   G4double photon2Energy = (1.0-epsilon)*totalAvailableEnergy;
185   G4double cosTheta1 = (ani-1.0/epsilon)/gamma21;
186   G4double cosTheta2 = (ani-1.0/(1.0-epsilon))/gamma21;
187
188   aParticleChange.SetNumberOfSecondaries(2);
189   G4double localEnergyDeposit = 0.; 
190
191   G4double sinTheta1 = std::sqrt(1.-cosTheta1*cosTheta1);
192   G4double phi1  = twopi * G4UniformRand();
193   G4double dirx1 = sinTheta1 * std::cos(phi1);
194   G4double diry1 = sinTheta1 * std::sin(phi1);
195   G4double dirz1 = cosTheta1;
196 
197   G4double sinTheta2 = std::sqrt(1.-cosTheta2*cosTheta2);
198   G4double phi2  = phi1+pi;
199   G4double dirx2 = sinTheta2 * std::cos(phi2);
200   G4double diry2 = sinTheta2 * std::sin(phi2);
201   G4double dirz2 = cosTheta2;
202
203   if (photon1Energy > cutForLowEnergySecondaryPhotons) {
204     G4ThreeVector photon1Direction (dirx1,diry1,dirz1);
205     photon1Direction.rotateUz(positronDirection);   
206     // create G4DynamicParticle object for the particle1 
207     G4DynamicParticle* aParticle1= new G4DynamicParticle (G4Gamma::Gamma(),
208                                                           photon1Direction, 
209                                                           photon1Energy);
210     aParticleChange.AddSecondary(aParticle1);
211   }
212   else  localEnergyDeposit += photon1Energy; 
213
214   if (photon2Energy > cutForLowEnergySecondaryPhotons) {
215     G4ThreeVector photon2Direction(dirx2,diry2,dirz2);
216     photon2Direction.rotateUz(positronDirection); 
217     // create G4DynamicParticle object for the particle2
218     G4DynamicParticle* aParticle2= new G4DynamicParticle (G4Gamma::Gamma(),
219                                                           photon2Direction,
220                                                           photon2Energy);
221     aParticleChange.AddSecondary(aParticle2);
222   }   
223   else  localEnergyDeposit += photon2Energy;
224     
225   aParticleChange.ProposeLocalEnergyDeposit(localEnergyDeposit);
226
227   aParticleChange.ProposeMomentumDirection( 0., 0., 0. );
228   aParticleChange.ProposeEnergy(0.); 
229   aParticleChange.ProposeTrackStatus(fStopAndKill);
230
231   return &aParticleChange;
232}
233
234 
235G4VParticleChange* G4PenelopeAnnihilation::AtRestDoIt(const G4Track& aTrack,
236                                                  const G4Step& )
237{
238   aParticleChange.Initialize(aTrack);
239   aParticleChange.SetNumberOfSecondaries(2); 
240   G4double cosTheta = -1.0+2.0*G4UniformRand();
241   G4double sinTheta = std::sqrt(1.0-cosTheta*cosTheta);
242   G4double phi = twopi*G4UniformRand();
243   //G4cout << "cosTheta: " << cosTheta << " sinTheta: " << sinTheta << G4endl;
244   //G4cout << "phi: " << phi << G4endl;
245   G4ThreeVector direction (sinTheta*std::cos(phi),sinTheta*std::sin(phi),cosTheta);   
246   aParticleChange.AddSecondary(new G4DynamicParticle (G4Gamma::Gamma(),
247                                            direction, electron_mass_c2) );
248   aParticleChange.AddSecondary(new G4DynamicParticle (G4Gamma::Gamma(),
249                                           -direction, electron_mass_c2) ); 
250
251   aParticleChange.ProposeLocalEnergyDeposit(0.);
252
253   // Kill the incident positron
254   //
255   aParticleChange.ProposeTrackStatus(fStopAndKill);
256     
257   return &aParticleChange;
258}
259
260void G4PenelopeAnnihilation::PrintInfoDefinition()
261{
262  G4String comments = "Total cross section from Heilter formula" 
263                      "(annihilation into 2 photons).";
264  comments += "\n      Gamma energies sampled according Heitler"; 
265  comments += "\n      It can be used for positrons";
266  comments += " in the energy range [250eV,100GeV].";
267  G4cout << G4endl << GetProcessName() << ":  " << comments
268         << G4endl;
269}         
270
271G4bool G4PenelopeAnnihilation::IsApplicable(
272                                         const G4ParticleDefinition& particle)
273{
274   return ( &particle == G4Positron::Positron() ); 
275}
276
277 
278G4double G4PenelopeAnnihilation::GetMeanFreePath(const G4Track& aTrack,
279                                                     G4double,
280                                                     G4ForceCondition*)
281{
282  const G4DynamicParticle* incidentPositron = aTrack.GetDynamicParticle();
283  G4double kineticEnergy = incidentPositron->GetKineticEnergy();
284  const G4MaterialCutsCouple* couple = aTrack.GetMaterialCutsCouple();
285  const G4Material* material = couple->GetMaterial();
286  G4int materialIndex = material->GetIndex();
287  if (kineticEnergy<lowEnergyLimit)
288    {
289      kineticEnergy = lowEnergyLimit;
290    }
291
292  G4double meanFreePath;
293  G4bool isOutRange ;
294
295  if (kineticEnergy>highEnergyLimit) 
296    {
297      meanFreePath = DBL_MAX;
298    }
299  else 
300    {
301      meanFreePath = (*meanFreePathTable)(materialIndex)->
302                    GetValue(kineticEnergy,isOutRange);
303    }
304
305  return meanFreePath; 
306} 
307
308G4double G4PenelopeAnnihilation::GetMeanLifeTime(const G4Track&,
309                                                     G4ForceCondition*)
310 
311{
312  return 0.0; 
313} 
Note: See TracBrowser for help on using the repository browser.