source: trunk/source/processes/hadronic/models/chiral_inv_phase_space/processes/src/G4QSynchRad.cc @ 1340

Last change on this file since 1340 was 1340, checked in by garnier, 14 years ago

update ti head

File size: 7.5 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//
27// $Id: G4QSynchRad.cc,v 1.1 2009/11/17 10:36:55 mkossov Exp $
28// GEANT4 tag $Name: hadr-chips-V09-03-08 $
29//
30// Created by Mikhail Kosov 6-Nov-2009
31//
32// --------------------------------------------------------------
33// Short description: Algorithm of Synchrotron Radiation from PDG
34// gamma>>1: dI/dw=(8pi/9)*alpha*gamma*F(w/wc), wc=3*gamma^3*c/2/R
35// F(y)=(9*sqrt(3)/8/pi)*y*int{y,inf}(K_(5/3)(x)dx) (approximated)
36// N_gamma=[5pi/sqrt(3)]*alpha*gamma; <w>=[8/15/sqrt(3)]*wc
37// for electrons/positrons: wc(keV)=2.22*[E(GeV)]^3/R(m)
38// dE per revolution = (4pi/3)*e^2*beta^3*gamma/R
39// at beta=1, dE(MeV)=.o885*[E(GeV)]^4/R(m)
40//---------------------------------------------------------------
41
42//#define debug
43//#define pdebug
44
45#include "G4QSynchRad.hh"
46 
47// Constructor
48G4QSynchRad::G4QSynchRad(const G4String& Name, G4ProcessType Type):
49  G4VDiscreteProcess (Name, Type), minGamma(227.), Polarization(0.,0.,1.) {}
50
51// Calculates MeanFreePath in GEANT4 internal units
52G4double G4QSynchRad::GetMeanFreePath(const G4Track& track,G4double,G4ForceCondition* cond)
53{
54  static const G4double coef = 0.4*std::sqrt(3.)/fine_structure_const;
55  const G4DynamicParticle* particle = track.GetDynamicParticle();
56  *cond = NotForced ;
57  G4double gamma = particle->GetTotalEnergy() / particle->GetMass();
58#ifdef debug
59  G4cout<<"G4QSynchRad::MeanFreePath: gamma = "<<gamma<<G4endl;
60#endif
61  G4double MFP = DBL_MAX;
62  if( gamma > minGamma )                            // For smalle gamma neglect the process
63  {
64    G4double R = GetRadius(track);
65#ifdef debug
66    G4cout<<"G4QSynchRad::MeanFreePath: Radius = "<<R/meter<<" [m]"<<G4endl;
67#endif
68    if(R > 0.) MFP= coef*R/gamma;
69  }
70#ifdef debug
71  G4cout<<"G4QSynchRad::MeanFreePath = "<<MFP/centimeter<<" [cm]"<<G4endl;
72#endif
73  return MFP; 
74} 
75
76G4VParticleChange* G4QSynchRad::PostStepDoIt(const G4Track& track, const G4Step& step)
77
78{
79  static const G4double hc = 1.5 * c_light * hbar_Planck; // E_c=h*w_c=1.5*(hc)*(gamma^3)/R
80  aParticleChange.Initialize(track);
81  const G4DynamicParticle* particle=track.GetDynamicParticle();
82  G4double gamma = particle->GetTotalEnergy() / particle->GetMass();
83  if(gamma <= minGamma )
84  {
85#ifdef debug
86    G4cout<<"-Warning-G4QSynchRad::PostStepDoIt is called for small gamma="<<gamma<<G4endl;
87#endif
88    return G4VDiscreteProcess::PostStepDoIt(track,step);
89  }
90  // Photon energy calculation (E < 8.1*Ec restriction)
91  G4double R = GetRadius(track);
92  if(R <= 0.)
93  {
94#ifdef debug
95    G4cout<<"-Warning-G4QSynchRad::PostStepDoIt: zero or negativ radius ="
96          <<R/meter<<" [m]"<<G4endl;
97#endif
98    return G4VDiscreteProcess::PostStepDoIt(track, step);
99  }
100  G4double EPhoton = hc * gamma * gamma * gamma / R;           // E_c
101  G4double dd=5.e-8;
102  G4double rnd=G4UniformRand()*(1.+dd);
103  if     (rnd < 0.5 ) EPhoton *= .65 * rnd * rnd * rnd;
104  else if(rnd > .997) EPhoton *= 15.-1.03*std::log((1.-rnd)/dd+1.);
105  else
106  {
107    G4double r2=rnd*rnd;
108    G4double dr=1.-rnd;
109    EPhoton*=(2806.+28./rnd)/(1.+500./r2/r2+6500.*(std::sqrt(dr)+28.*dr*dr*dr));
110  }
111#ifdef debug
112  G4cout<<"G4SynchRad::PostStepDoIt: PhotonEnergy = "<<EPhoton/keV<<" [keV]"<<G4endl;
113#endif
114  if(EPhoton <= 0.)
115  {
116    G4cout<<"-Warning-G4QSynchRad::PostStepDoIt: zero or negativ photon energy="
117          <<EPhoton/keV<<" [keV]"<<G4endl;
118    return G4VDiscreteProcess::PostStepDoIt(track, step);
119  }
120  G4double kinEn = particle->GetKineticEnergy();
121  G4double newEn = kinEn - EPhoton ;
122  if (newEn > 0.)
123  {
124    aParticleChange.ProposeEnergy(newEn);
125    aParticleChange.ProposeLocalEnergyDeposit (0.); 
126  } 
127  else                                                // Very low probable event
128  {
129    G4cout<<"-Warning-G4QSynchRad::PostStepDoIt: PhotonEnergy > TotalKinEnergy"<<G4endl;
130    EPhoton = kinEn;
131    aParticleChange.ProposeEnergy(0.);
132    aParticleChange.ProposeLocalEnergyDeposit(0.);
133    aParticleChange.ProposeTrackStatus(fStopButAlive) ;
134  } 
135  G4ThreeVector MomDir = particle->GetMomentumDirection();
136  G4DynamicParticle* Photon = new G4DynamicParticle(G4Gamma::Gamma(), MomDir, EPhoton);
137  Photon->SetPolarization(Polarization.x(), Polarization.y(), Polarization.z());
138  aParticleChange.SetNumberOfSecondaries(1);
139  aParticleChange.AddSecondary(Photon);
140  return G4VDiscreteProcess::PostStepDoIt(track,step);
141}
142
143// Revolution Radius in independent units for the particle (general member function)
144G4double G4QSynchRad::GetRadius(const G4Track& track)
145{
146  static const G4double unk = meter*tesla/0.3/gigaelectronvolt;
147  const G4DynamicParticle* particle = track.GetDynamicParticle();
148  G4double z = particle->GetDefinition()->GetPDGCharge();
149  if(z == 0.) return 0.;                              // --> neutral particle
150  if(z < 0.) z=-z;
151  G4TransportationManager* transMan = G4TransportationManager::GetTransportationManager();
152  G4PropagatorInField* Field = transMan->GetPropagatorInField();
153  G4FieldManager* fMan = Field->FindAndSetFieldManager(track.GetVolume());
154  if(!fMan || !fMan->GetDetectorField()) return 0.;   // --> no field at all
155  const G4Field* pField = fMan->GetDetectorField();
156  G4ThreeVector  position = track.GetPosition();
157  G4double  PosArray[3]={position.x(), position.y(), position.z()};
158  G4double  BArray[3];
159  pField->GetFieldValue(PosArray, BArray);
160  G4ThreeVector B3D(BArray[0], BArray[1], BArray[2]);
161#ifdef debug
162  G4cout<<"G4QSynchRad::GetRadius: Pos="<<position/meter<<", B(tesla)="<<B3D/tesla<<G4endl;
163#endif
164  G4ThreeVector MomDir = particle->GetMomentumDirection();
165  G4ThreeVector Ort = B3D.cross(MomDir);
166  G4double OrtB = Ort.mag();                          // not negative (independent units)
167  if(OrtB == 0.) return 0.;                           // --> along the field line
168  Polarization = Ort/OrtB;                            // Polarization unit vector
169  G4double mom = particle->GetTotalMomentum();        // Momentum of the particle
170#ifdef debug
171  G4cout<<"G4QSynchRad::GetRadius: P(GeV)="<<mom/GeV<<", B(tesla)="<<OrtB/tesla<<G4endl;
172#endif
173  // R [m]= mom [GeV]/(0.3 * z * OrtB [tesla])
174  return mom * unk / z / OrtB; 
175}
Note: See TracBrowser for help on using the repository browser.