/home/cern/BDSIM_new/src/BDSSynchrotronRadiation.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Last modified 24.7.2002
00004    Copyright (c) 2002 by G.A.Blair.  ALL RIGHTS RESERVED. 
00005 */ 
00006 //      ------------ BDSSynchrotronRadiation physics process --------
00007 //                     by Grahame Blair, 18 October 2001
00008 
00009 /* Modifications to BDSSynchrotronRadiation physics process
00010    Author of Mods: John Carter, Royal Holloway, Univ. of London
00011    Date: 16.11.2004
00012    Description: Modified to improve efficiency of process. It is now possible 
00013                 to use BDSInput.cards to create a given number of photons 
00014                 each time (rather than one) using SYNCH_PHOTON_MULTIPLICITY
00015 
00016                 Also modified to break up the meanfree path length into a given
00017                 number of smaller lengths. Use the following BDSInput.card
00018                 flag, SYNCH_MEANFREE_FACTOR
00019 */
00020 
00021 #include "BDSGlobalConstants.hh" // must be first in include list
00022 #include "BDSSynchrotronRadiation.hh"
00023 #include "G4ios.hh"
00024 #include "G4UnitsTable.hh"
00025 
00026 #include "BDSAcceleratorComponent.hh"
00027 
00028 
00029 extern G4int event_number;
00030 
00031 typedef list<BDSAcceleratorComponent*>  BDSBeamline;
00032 extern BDSBeamline theBeamline;
00033 
00034 
00035 BDSSynchrotronRadiation::BDSSynchrotronRadiation(const G4String& processName)
00036   : G4VDiscreteProcess(processName)
00037      // initialization
00038 {
00039   nExpConst=5*fine_structure_const/(2*sqrt(3.0))/electron_mass_c2;
00040   CritEngFac=3./2.*hbarc/pow(electron_mass_c2,3);
00041 
00042 } 
00043  
00044 
00045 G4VParticleChange* 
00046 BDSSynchrotronRadiation::PostStepDoIt(const G4Track& trackData,
00047                                      const G4Step& stepData)
00048 {
00049   aParticleChange.Initialize(trackData);
00050 
00051   G4double eEnergy=trackData.GetTotalEnergy();
00052 
00053   G4double R=BDSLocalRadiusOfCurvature;
00054 
00055   G4double NewKinEnergy = trackData.GetKineticEnergy();
00056  
00057   G4double GamEnergy=0;
00058 
00059   aParticleChange.SetNumberOfSecondaries(BDSGlobals->GetSynchPhotonMultiplicity());
00060   MeanFreePathCounter++;
00061   
00062   for (int i=0; i<BDSGlobals->GetSynchPhotonMultiplicity(); i++){
00063 
00064     if(fabs(R)>0)
00065       GamEnergy=SynGenC(BDSGlobals->GetSynchLowX())*
00066         CritEngFac*pow(eEnergy,3)/fabs(R);
00067     
00068     if(GamEnergy>0)
00069       {
00070         if((BDSGlobals->GetSynchTrackPhotons())&&
00071            (GamEnergy>BDSGlobals->GetSynchLowGamE()) )
00072           {
00073             G4DynamicParticle* aGamma= 
00074               new G4DynamicParticle (G4Gamma::Gamma(), 
00075                                      trackData.GetMomentumDirection(),
00076                                      GamEnergy);
00077 
00078             aParticleChange.AddSecondary(aGamma); 
00079           }
00080 
00081       BDSBeamline::const_iterator iBeam;
00082       //G4double zpos=trackData.GetPosition().z();
00083       
00084     //   for(iBeam=theBeamline.begin();
00085 //        iBeam!=theBeamline.end() && zpos>=(*iBeam)->GetZUpper(); 
00086 //        iBeam++){}
00087 
00088       if(i==0 && MeanFreePathCounter==1) NewKinEnergy -= GamEnergy;
00089                 
00090       if (NewKinEnergy > 0.)
00091         {
00092           //
00093           // Update the incident particle 
00094             aParticleChange.ProposeEnergy(NewKinEnergy);
00095         } 
00096       else
00097         { 
00098           aParticleChange.ProposeEnergy( 0. );
00099           aParticleChange.ProposeLocalEnergyDeposit (0.);
00100           G4double charge= trackData.GetDynamicParticle()->GetCharge();
00101           if (charge<0.) aParticleChange.ProposeTrackStatus(fStopAndKill);
00102           else       aParticleChange.ProposeTrackStatus(fStopButAlive);
00103         }
00104       }
00105   }
00106   return G4VDiscreteProcess::PostStepDoIt(trackData,stepData);
00107 }
00108 
00109 
00110 BDSSynchrotronRadiation::~BDSSynchrotronRadiation(){
00111 }
00112 
00113 //--------------------------------------------------------------------
00114 // routines from H. Burkhardt (Lep Note 632)
00115 G4double BDSSynchrotronRadiation::SynGenC(G4double xmin)
00116 // C++ version
00117 // synchrotron radiation photon spectrum generator
00118 // returns photon energy in units of the critical energy
00119 // xmin is the lower limit for the photon energy to be generated
00120 //          see H.Burkhardt, LEP Note 632
00121 { static bool DoInit=true;
00122   static G4double a1,a2,c1,xlow,ratio,LastXmin=-1.;
00123   
00124   if(DoInit | xmin!=LastXmin)
00125   { DoInit=false;
00126      LastXmin=xmin;
00127      if(xmin>1.) xlow=xmin; else xlow=1.;
00128      // initialize constants used in the approximate expressions
00129      // for SYNRAD   (integral over the modified Bessel function K5/3)
00130     a1=SynRadC(1.e-38)/pow(1.e-38,-2./3.); // = 2**2/3 GAMMA(2/3)
00131     a2=SynRadC(xlow)/exp(-xlow);
00132     c1=pow(xmin,1./3.);
00133      // calculate the integrals of the approximate expressions
00134     if(xmin<1.) // low and high approx needed
00135     { G4double sum1ap=3.*a1*(1.-pow(xmin,1./3.)); //     integral xmin --> 1
00136       G4double sum2ap=a2*exp(-1.);                    //     integral 1 --> infin
00137       ratio=sum1ap/(sum1ap+sum2ap);
00138     }
00139     else // only high approx needed
00140     {  ratio=0.;     //     generate only high energies using approx. 2
00141        a2=SynRadC(xlow)/exp(-xlow);
00142     }
00143   }
00144   // Init done, now generate
00145   G4double appr,exact,result;
00146   do
00147   { if(G4UniformRand()<ratio)           // use low energy approximation
00148      { result=c1+(1.-c1)*G4UniformRand();
00149        result*=result*result;  // take to 3rd power;
00150        exact=SynRadC(result);
00151        appr=a1*pow(result,-2./3.);
00152      }
00153      else                      // use high energy approximation
00154      { result=xlow-log(G4UniformRand());
00155        exact=SynRadC(result);
00156        appr=a2*exp(-result);
00157      }
00158   }
00159   while(exact<appr*G4UniformRand());    // reject in proportion of approx
00160   return result;               // result now exact spectrum with unity weight
00161 }
00162 
00163 G4double BDSSynchrotronRadiation::SynRadC(G4double x)
00164 /*   x :    energy normalized to the critical energy
00165      returns function value SynRadC   photon spectrum dn/dx
00166      (integral of modified 1/3 order Bessel function)
00167      principal: Chebyshev series see H.H.Umstaetter CERN/PS/SM/81-13 10-3-1981
00168      see also my LEP Note 632 of 12/1990
00169      converted to C++, H.Burkhardt 21-4-1996    */
00170 { G4double synrad=0.;
00171   if(x>0. & x<800.) // otherwise result synrad remains 0
00172   { if(x<6.)
00173      { G4double a,b,z;
00174        z=x*x/16.-2.;
00175        b=          .00000000000000000012;
00176        a=z*b  +    .00000000000000000460;
00177        b=z*a-b+    .00000000000000031738;
00178        a=z*b-a+    .00000000000002004426;
00179        b=z*a-b+    .00000000000111455474;
00180        a=z*b-a+    .00000000005407460944;
00181        b=z*a-b+    .00000000226722011790;
00182        a=z*b-a+    .00000008125130371644;
00183        b=z*a-b+    .00000245751373955212;
00184        a=z*b-a+    .00006181256113829740;
00185        b=z*a-b+    .00127066381953661690;
00186        a=z*b-a+    .02091216799114667278;
00187        b=z*a-b+    .26880346058164526514;
00188        a=z*b-a+   2.61902183794862213818;
00189        b=z*a-b+  18.65250896865416256398;
00190        a=z*b-a+  92.95232665922707542088;
00191        b=z*a-b+ 308.15919413131586030542;
00192        a=z*b-a+ 644.86979658236221700714;
00193        G4double p;
00194        p=.5*z*a-b+  414.56543648832546975110;
00195        a=          .00000000000000000004;
00196        b=z*a+      .00000000000000000289;
00197        a=z*b-a+    .00000000000000019786;
00198        b=z*a-b+    .00000000000001196168;
00199        a=z*b-a+    .00000000000063427729;
00200        b=z*a-b+    .00000000002923635681;
00201        a=z*b-a+    .00000000115951672806;
00202        b=z*a-b+    .00000003910314748244;
00203        a=z*b-a+    .00000110599584794379;
00204        b=z*a-b+    .00002581451439721298;
00205        a=z*b-a+    .00048768692916240683;
00206        b=z*a-b+    .00728456195503504923;
00207        a=z*b-a+    .08357935463720537773;
00208        b=z*a-b+    .71031361199218887514;
00209        a=z*b-a+   4.26780261265492264837;
00210        b=z*a-b+  17.05540785795221885751;
00211        a=z*b-a+  41.83903486779678800040;
00212        G4double q;
00213        q=.5*z*a-b+28.41787374362784178164;
00214        G4double y;
00215        G4double const twothird=2./3.;
00216        y=pow(x,twothird);
00217        synrad=(p/y-q*y-1.)*1.81379936423421784215530788143;
00218      }
00219      else // 6 < x < 174
00220      { G4double a,b,z;
00221        z=20./x-2.;
00222        a=      .00000000000000000001;
00223        b=z*a  -.00000000000000000002;
00224        a=z*b-a+.00000000000000000006;
00225        b=z*a-b-.00000000000000000020;
00226        a=z*b-a+.00000000000000000066;
00227        b=z*a-b-.00000000000000000216;
00228        a=z*b-a+.00000000000000000721;
00229        b=z*a-b-.00000000000000002443;
00230        a=z*b-a+.00000000000000008441;
00231        b=z*a-b-.00000000000000029752;
00232        a=z*b-a+.00000000000000107116;
00233        b=z*a-b-.00000000000000394564;
00234        a=z*b-a+.00000000000001489474;
00235        b=z*a-b-.00000000000005773537;
00236        a=z*b-a+.00000000000023030657;
00237        b=z*a-b-.00000000000094784973;
00238        a=z*b-a+.00000000000403683207;
00239        b=z*a-b-.00000000001785432348;
00240        a=z*b-a+.00000000008235329314;
00241        b=z*a-b-.00000000039817923621;
00242        a=z*b-a+.00000000203088939238;
00243        b=z*a-b-.00000001101482369622;
00244        a=z*b-a+.00000006418902302372;
00245        b=z*a-b-.00000040756144386809;
00246        a=z*b-a+.00000287536465397527;
00247        b=z*a-b-.00002321251614543524;
00248        a=z*b-a+.00022505317277986004;
00249        b=z*a-b-.00287636803664026799;
00250        a=z*b-a+.06239591359332750793;
00251        G4double p;
00252        p=.5*z*a-b    +1.06552390798340693166;
00253        G4double const pihalf=pi/2.;
00254        synrad=p*sqrt(pihalf/x)/exp(x);
00255      }
00256   }
00257   return synrad;
00258 }
00259 
00260 

Generated on Wed Mar 5 17:25:23 2008 for BDSIM by  doxygen 1.5.3