00001 // -*- C++ -*- $Id: compt.cxx,v 1.2 2001/01/25 22:24:33 burnett Exp $ 00002 // 00003 // This file is part of Gismo 2 00004 // 00005 // file: compt.cc 00006 // created 1-Dec-1991 T. Burnett 00007 00008 // Contents ------------------------------------------------------- 00009 // 00010 // EGS::compt 00011 // 00012 // End ----------------------------------------------------------- 00013 00014 00015 #include "EGS.h" 00016 #include "Random.h" 00017 #include <algorithm> 00018 00019 00020 void EGS::compt() 00021 { 00022 // version 4.00 -- 26 jan 1986/1900 00023 //****************************************************************** 00024 // Butcher and Messel's cross section expression is used 00025 // (Butcher and Messel, op.cit., p. 17-19,25), but the 00026 // 1/epsilon part is not sampled in the way that they do. 00027 // this routine calls their 'epsilon' variable by the name 'br'. 00028 // br=final photon energy /initial photon energy. 00029 // br0 = minimum br = 1./(1.+2.*(e(np)/rm)) 00030 // maximum br is 1. 00031 // Butcher and Messel's expression for the differential cross 00032 // section is proportional to 00033 // (1./br+br)*(1.-br*sinthe**2/(1.+br*br)) 00034 // we shall sample from the first factor from the interval (br0,1) 00035 // and use the second factor as a rejection function. 00036 //****************************************************************** 00037 00038 double prm = rm; 00039 float eig = this->e; 00040 double peig=eig; //precise energy of incident gamma 00041 float egp=eig/rm, 00042 br0i=1.+2.*egp, // br0i is the inverse of br0 00043 alph1=log(br0i), 00044 alph2=egp*(br0i+1.)/(br0i*br0i), 00045 sumalp = alph1+alph2, 00046 sinthe,temp, 00047 a1mibr, 00048 esg, 00049 br; 00050 EGS& newp = *new EGS(this); // create the electron 00051 00052 // due to rejection, some expressions which only appear once in 00053 // the code below, may actually be needed more than once. 00054 for(;;) 00055 { //retry if rejected 00056 // which part of 1./br + br to sample from ? 00057 float rnno15 = Random::flat(); 00058 if (alph1 >= sumalp*rnno15) 00059 { //use 1/br part of distribution 00060 float rnno16 = Random::flat(); 00061 br=exp(alph1*rnno16)/br0i; 00062 } //end of 1/br part 00063 else 00064 { //use linear ( br ) part of distribution 00065 float brp = Random::flat(); 00066 float rnno18 = Random::flat(); 00067 if ( egp >= (egp+1.)*rnno18 ) 00068 { float rnno19 = Random::flat(); 00069 brp=std::max(brp,rnno19); 00070 } 00071 br=((br0i-1.)*brp+1.)/br0i; 00072 } //end sampling of linear part 00073 00074 // br=final photon energy fraction 00075 esg=br*eig; //energy of secondary gamma 00076 // the compton angles for photon and recoil electron are uniquely 00077 // determined by the conservation laws 00078 a1mibr = 1.-br; 00079 temp=rm*a1mibr/esg; 00080 // the amax1 in the ff. is to prevent sinthe.lt.0 from trunc error 00081 sinthe=std::max(0.0,temp*(2.0-temp)); 00082 // compare rejection function with random number. 00083 float rnno20 = Random::flat(); 00084 float rejf3=1.0-br*sinthe/(1.0+br*br); 00085 if ( rnno20 <= rejf3) break; //loop until accepted 00086 } 00087 sinthe=sqrt(sinthe); 00088 float costhe=1.0-temp; 00089 00090 // the recoil electron is added to the shower memory. the extra 00091 // rest mass energy will be discarded when the 00092 // electron is thrown away. 00093 // (how? --THB) 00094 00095 double pesg=esg; //precise energy of secondary gamma 00096 double pese=peig-pesg+prm; //precise energy of secondary electron 00097 float ese=pese; //energy of secondary electron 00098 00099 float phi = Random::flat(2.*M_PI); // generate uniform phi 00100 rotate(costhe, phi); // and rotate old photon 00101 00102 // related change and (x,y,z) setup for new elctron 00103 float psq=ese*ese-rmsq; 00104 00105 // psq here is the momentum squared. 00106 costhe = (psq<0.)? 0. : (ese+esg)*a1mibr/sqrt(psq); 00107 newp.rotate(costhe, phi+M_PI); // and rotate its direction 00108 00109 // now put the lowest energy particle on top of stack 00110 if (ese<= esg) 00111 { newp.iq = -1; // electron is on top 00112 newp.e = pese; 00113 this->e = pesg; 00114 }else 00115 { newp.iq = 0; this->iq = -1; 00116 newp.e = pesg; 00117 this->e = pese; 00118 float t; 00119 t=newp.u; newp.u=u; u=t; 00120 t=newp.v; newp.v=v; v=t; 00121 t=newp.w; newp.w=w; w=t; 00122 } 00123 }//end of subroutine compt 00124
1.2.3 written by Dimitri van Heesch,
© 1997-2000