00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include "config.h"
00026 #endif
00027
00028 #include "EGS.h"
00029
00030 #include "PEGSData.h"
00031
00032 #include "Random.h"
00033 #include "facilities/error.h"
00034 #include <math.h>
00035 #include <iomanip>
00036
00037
00038
00039 EGS::EGS(EGS* old)
00040 {
00041
00042
00043
00044 if (old )
00045 {
00046 *this = *old;
00047 old->next = this;
00048 prev = old;
00049 next = 0;
00050
00051 }
00052 else
00053 {
00054 next=prev=0;
00055 x=y=z=0;
00056 u=v=0; w=1.;
00057 iq = 0;
00058 }
00059 }
00060
00061
00062
00063 EGS::~EGS()
00064 {
00065
00066
00067 EGS* pt = next;
00068 if (prev ) prev->next = 0;
00069
00070 if( next )
00071 delete pt;
00072 }
00073
00074
00075
00076 void EGS::printOn(std::ostream& cout)
00077 {
00078
00079 #if 1
00080 std::cout << std::setw(5) << iq
00081 << std::setw(10) << e
00082 << std::setw(10) << u
00083 << std::setw(10) << v
00084 << std::setw(10) << w
00085 << '\n';
00086 #else
00087 std::cout << iq << e << u << v << w << '\n';
00088 #endif
00089 if (next != NULL) next->printOn(cout);
00090 }
00091
00092
00093
00094
00095 void EGS::rotate(double costhe, double phi)
00096 {
00097 double sinthsq = 1.-costhe*costhe;
00098 rotate(costhe, phi, sinthsq<0? 0: sqrt(sinthsq) );
00099 }
00100 void EGS::rotate(double costhe, double phi, double sinthe)
00101 {
00102
00103
00104
00105
00106
00107
00108 static float phiold=0, sinphi=0, cosphi=1;
00109
00110 if (phi!=phiold)
00111 { if (phi==phiold+M_PI )
00112 {
00113 sinphi = -sinphi; cosphi = -cosphi;
00114 }
00115 else
00116 { sinphi = sin(phi); cosphi = cos(phi);
00117 }
00118 phiold = phi;
00119 }
00120
00121 float sinps2=u*u+v*v;
00122
00123
00124
00125 if (sinps2 < 1.0e-20)
00126 {
00127
00128 u = sinthe*cosphi;
00129 v = sinthe*sinphi;
00130 w = w*costhe;
00131 }
00132 else
00133 {
00134
00135 float a=u, b=v, c=w,
00136 sinpsi=sqrt(sinps2),
00137 us=sinthe*cosphi,
00138 vs=sinthe*sinphi,
00139 sindel=b/sinpsi,
00140 cosdel=a/sinpsi;
00141 u = c*cosdel*us - sindel*vs + a*costhe;
00142 v = c*sindel*us + cosdel*vs + b*costhe;
00143 w = -sinpsi*us + c*costhe;
00144 }
00145 }
00146
00147
00148
00149 void EGS::interact(const PEGSData &m)
00150 {
00151
00152
00153
00154
00155
00156
00157 PEGSData::channel which = m.chooseChannel(Random::flat(),e,iq);
00158 switch (which) {
00159 case PEGSData::STOP: e=rm; break;
00160 case PEGSData::BREMS: brems(m); break;
00161 case PEGSData::MOLLER: moller(m);break;
00162 case PEGSData::ANNIH: annih(); break;
00163 case PEGSData::BHABHA: bhabha(m);break;
00164 case PEGSData::PAIR: pairProd(m);break;
00165 case PEGSData::COMPT: compt(); break;
00166 case PEGSData::PHOTO: photo(m); break;
00167 case PEGSData::RAYLEIGH: rayleigh(m); break;
00168
00169
00170 }
00171
00172
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 void EGS::rayleigh(const PEGSData &m )
00200 {
00201 float costhe, rejf;
00202 do {
00203 float x2 = m.ph.rsct(Random::flat());
00204 float q2 = x2*rmsq/(20.60744*20.60744);
00205 costhe=1.-q2/(2.*e*e);
00206 if( abs(costhe) > 1.0 ) continue;
00207 float csqthe=costhe*costhe;
00208 rejf=(1.0+csqthe)/2.0;
00209 if( Random::flat() <= rejf ) break;
00210 } while(1);
00211
00212 rotate( costhe, Random::flat(2.*M_PI) );
00213 }
00214
00215
00216 double EGS::rm2 = 0.51100340;
00217 double EGS::rm = rm2;
00218
00219 double EGS::rmsq = rm2*rm2;
00220
00221
00222