Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

pair.cxx

Go to the documentation of this file.
00001 // -*- C++ -*-  $Id: pair.cxx,v 1.1 2000/09/01 20:20:21 burnett Exp $
00002 //
00003 // This file is part of Gismo 2
00004 
00005 #include "EGS.h"
00006 #include "PEGSData.h"
00007 #include "Random.h"
00008 
00009 // used in angle sampling below
00010 static double set_pair_rejection_function(double input,double TTEIG,double ZTARG,double ESEDEI);
00011 
00012 // ----------------- member function pair ---------------------------//
00013 
00014 void EGS::pairProd(const PEGSData & mat)
00015 {
00016     float eig = this->e;   // energy of gamma
00017     float br;   // fraction to electron #2
00018     
00019     //******************************************************************
00020     //   for a photon energy less than 2.1 MeV, the approximation is
00021     //   made that one pair electron (or positron) has only its rest
00022     //   mass energy.   for photon energy between 2.1 mev and 50 mev the
00023     //   Bethe-Heitler cross section is employed.  above 50 mev the
00024     //   coulomb corrected Bethe-Heitler cross section is used.
00025     //   (Butcher and Messel, op. cit., p. 17-19, 22).
00026     //******************************************************************
00027     if (eig<=2.1)
00028     {
00029         //   below 2.1,use approximation
00030         br=rm/eig; //energy of secondary 'electron'
00031     }
00032     else
00033     {   //above 2.1, must sample
00034         
00035         //   decide whether to use bethe-heitler(lvx=0,lvl=0,2) or
00036         //   coulomb corrected(lvx=1,lvl=3,5) cross sections.
00037         //   see related comments in brems.
00038         int lvx = 1, lvl0=3;
00039         if (eig< 50.) {lvx=0;lvl0=0;}
00040         
00041         for (;;)
00042         {
00043             //retry if rejected because del out of range, or by screening
00044             float rnno30=Random::flat(); //we'll need at least one random number
00045             int lvl;
00046             
00047             //   now decide which of the two subdistributions to use.
00048             float rnno31=Random::flat();
00049             if (rnno31 >= mat.bpar(lvx) )
00050             {   //use the subdistribution that is
00051                 //   proportional to 12*(br-0.5)**2.  it uses a(delta) for
00052                 //   screening function.
00053                 lvl=lvl0;
00054                 //   from symmetry, only need to sample br in interval (0,.5)
00055                 float rnno32=Random::flat();
00056                 float rnno33=Random::flat();
00057                 br=0.5*(1.0-std::max(rnno32,std::max(rnno33,rnno30) ) );
00058             }
00059             else
00060             {   //use the subdistribution that is proportional to 1,
00061                 //   i.e., uniform.  it uses c(delta) for a screening
00062                 //   rejection function.
00063                 
00064                 lvl=lvl0+2;
00065                 br = rnno30*0.5;
00066             }
00067             
00068             //   the screening functions are functions of delta=delcm*del,
00069             //   where delcm= 136.0*exp(zg)*rm (same as for brems)
00070             //   and where del=1./(eg0*br*(1.0-br))
00071             //   with eg0 = incident photon energy and br=energy fraction.
00072             
00073             if (br==0.0) continue; //to avoid division by zero
00074             
00075             float del=1.0/(eig*br*(1.0-br));
00076             
00077             float rejf = mat.screening(del,lvx, lvl);
00078             if (rejf == 0.) continue;
00079             
00080             float rnscrn=Random::flat(); //random number for screening rejection
00081             if (rnscrn <= rejf) break ; //retry until accepted
00082         } // end of rejection loop
00083         
00084         
00085     } //end of eig.gt.2.1 else
00086     
00087     
00088     EGS& es1 = *this;   // use as an alias for incoming photon,
00089     // converted to a secondary
00090     EGS& es2 = *new EGS(this);   // create other secondary
00091     
00092     //   energy going to lower secondary has now been determined
00093     double pese2=br*eig;     //precise energy of secondary 'electron' 2
00094     double pese1=(double)eig-pese2; //precise energy of secondary 'electron' 1
00095     
00096     //negative kinetic energy fix
00097     //EGS4 DEFAULT code did not include a fix for this, it cropped up once
00098     //Dr. Bielajew's code was implemented, not suprising since
00099     //the EGS4 bug was not found until this distibution was
00100     //implemented (as a result of)--harrison
00101     
00102     //using Dr. Hartman's (NASA GSFC LHEA) fix
00103     //C    R.C. HARTMAN 94/11/19 - PROTECT AGAINST ENERGY BELOW REST MASS:            
00104     //C           GIVE LOWER ENERGY ELECTRON 1% OF AVAILABLE KINETIC ENERGY.          
00105     //      IF ((ESE2.LE.RM)) THEN                                                    
00106     //       ESE2 = RM + 0.01*(PEIG - 2*RM)                                          
00107     //      END IF 
00108     
00109     if ((pese2 <= rm2) || (pese1 < rm2)){
00110         pese2 = (rm2 + 0.01*((double)eig - 2*rm2));
00111         pese1 = (double) eig - pese2;
00112     }
00113     //end negative kinetic energy fix
00114 
00115     //assign energies
00116     es1.e = pese1;
00117     es2.e = pese2;
00118     
00119     //begin angular distribution sampling
00120     
00121     double theta;
00122     double costhe1 = 100000.0;  // set to crazy value to test
00123     double costhe2 = 100000.0; 
00124     double sinthe1 = 100000.0;
00125     double sinthe2 = 100000.0;
00126     //set IPRDST to choose which distribution to use
00127     //false for default EGS4, true for improved distributions
00128     //Should be done as a #define/#ifdef fix later....harrison
00129     static bool IPRDST = true;
00130     
00131     if (! IPRDST){
00132         //Default EGS4 routine
00133         
00134         //   this average angle of emission for both pair production and
00135         //   bremsstrahlung is much smaller than the average angle of
00136         //   multiple scattering for delta t transport=0.01 r.l.
00137         //   the initial and final directions are coplanar
00138         
00139         theta = (double)rm/eig;
00140         costhe1 = cos(theta);
00141         sinthe1 = sin(theta);
00142         sinthe2 = sinthe1;
00143         costhe2 = costhe1;
00144     }
00145     
00146     else if ((IPRDST) && (eig < 4.14)){ 
00147         //"lowest order approx" distribution from paper by 
00148         //Alex F. Bielajew:
00149         //"Improved angular sampling for pair production
00150         //in the EGS4 code system", 10/20/94, PIRS-0287R1 
00151         
00152         double E1,E2,p1,p2;
00153         
00154         E1 = (double) pese1; //Energy in MeV 
00155         E2 = (double) pese2;
00156         p1 = sqrt((E1 - rm2)*(E1+rm2));
00157         p2 = sqrt((E2 - rm2)*(E2+rm2));
00158         costhe1 = (double) Random::flat();
00159         costhe2 = (double) Random::flat();
00160         costhe1 = 1.0 - 2.0*costhe1;
00161         costhe2 = 1.0 - 2.0*costhe2;
00162         sinthe1 = rm2*sqrt((1.0-costhe1)*(1.0+costhe1))/(p1*costhe1+E1);
00163         sinthe2 = rm2*sqrt((1.0-costhe2)*(1.0+costhe2))/(p2*costhe2+E2);
00164         costhe1 = (E1 * costhe1+p1)/(p1*costhe1+E1);
00165         costhe2 = (E2 * costhe2+p2)/(p2*costhe2+E2);
00166         
00167     }
00168     
00169     else if ((IPRDST) && (eig >= 4.14)){
00170         //Schiff (Koch, Motz, & Olsen) Distribution from paper by Alex F. Bielajew:
00171         //"Improved angular sampling for pair production
00172         //in the EGS4 code system", 10/20/94, PIRS-0287R1 
00173         //function prototypes from other modifications:
00174         //from EGS.h/cxx: 
00175         //double set_pair_rejection_function(double input,double TTEIG,double ZTARG,double ESEDEI);
00176         //from PEGSData.h/cxx:
00177         //double hzbrang()const;
00178         
00179         int n;
00180         double ZTARG,TTEIG,ESEDEI,ESEDER,YA,test,XIMIN;
00181         double TTESE = 1000000.0;
00182         double GALPHA,GBETA,XITRY,XIMID,REJTST,REJMIN;
00183         double REJTOP = 1000000.0; // set to crazy value
00184         double RTEST,XITST,REJMID;
00185         
00186         ZTARG = (double) mat.hzbrang(); //((1/111)*zeff**(1/3))**2
00187         TTEIG = (double) eig/rm2; //energy of gamma in units of e- rest mass
00188         
00189         
00190         n = 0;
00191         while (n < 2){  
00192             if (n == 0) TTESE = (double)pese1/rm2; //energy of particle 1 in units of rest mass
00193             if (n == 1) TTESE = (double)pese2/rm2; //energy of particle 2 in units as above
00194             ESEDEI = TTESE/(TTEIG-TTESE); //r
00195             ESEDER = 1.0/ESEDEI; //1 over r
00196             XIMIN = 1.0/(1.0+pow((3.141593*TTESE),2));
00197             REJMIN = set_pair_rejection_function(XIMIN,TTEIG,ZTARG,ESEDEI);
00198             YA = pow((2.0/TTEIG),2);
00199             test = sqrt(YA/ZTARG);
00200             if (test >= 0.5) test = 0.5;
00201             if (test <= XIMIN) test = XIMIN;
00202             if (test <= 0.01) test = 0.01;
00203             XITRY = test;
00204             GALPHA = 1.0 + 0.25*log(YA+ZTARG*pow(XITRY,2));
00205             GBETA = 0.5*ZTARG*XITRY/(YA+ZTARG*pow(XITRY,2));
00206             GALPHA = GALPHA-GBETA*(XITRY-0.5);
00207             XIMID = GALPHA/(3.0*GBETA);
00208             if (GALPHA >= 0.0){
00209                 XIMID = 0.5-XIMID+sqrt(pow(XIMID,2)+0.25);
00210             }
00211             if (GALPHA < 0.0){
00212                 XIMID = 0.5-XIMID-sqrt(pow(XIMID,2)+0.25);
00213             }
00214             test = XIMID;
00215             if (test >= 0.5) test = 0.5;
00216             if (test <= XIMIN) test = XIMIN;
00217             if (test <= 0.01) test = 0.01;
00218             XIMID = test;
00219             REJMID = set_pair_rejection_function(XIMID,TTEIG,ZTARG,ESEDEI);
00220             if (REJMID <= REJMIN) REJTOP = 1.02*REJMIN;
00221             if (REJMIN < REJMID)  REJTOP = 1.02*REJMID;
00222             
00223             do {
00224                 XITST = (double) Random::flat();
00225                 RTEST = (double) Random::flat();
00226                 REJTST = set_pair_rejection_function(XITST,TTEIG,ZTARG,ESEDEI);
00227                 theta = sqrt((1.0/XITST)-1.0)/TTESE;
00228             } while ((RTEST > (REJTST/REJTOP)) || (theta >= 3.1415926535));
00229             if (n == 0){ 
00230                 costhe1 = cos(theta); 
00231                 sinthe1 = sin(theta);
00232                 //if (sinthe1 < 0) sinthe1 = -1.0 * sinthe1; //just in case     
00233             }
00234             
00235             if (n == 1){ 
00236                 costhe2 = cos(theta); 
00237                 sinthe2 = sin(theta);
00238                 //if (sinthe2 < 0) sinthe2 = sinthe2 * -1.0; //again, just in case
00239             }
00240             
00241             n++;
00242         }
00243     }
00244     
00245     
00246     
00247     //generate uniform phi for both secondaries
00248     double phi = Random::flat(2.*M_PI); 
00249     
00250     
00251     //set'm up, angles w/respect to gamma direction
00252     es1.rotate(costhe1, phi, sinthe1);
00253     es2.rotate(costhe2, phi+M_PI,sinthe2);
00254     
00255     //   now randomly decide which is the positron
00256     
00257     es2.iq = -( es1.iq = (Random::flat() <= 0.5)? 1 : -1 );
00258     
00259 } // end of EGS::pair
00260 
00261 static double set_pair_rejection_function(double input,double TTEIG,double ZTARG,double ESEDEI)
00262 { //harrison
00263     double term,ESEDER,result;
00264     ESEDER = 1.0/ESEDEI;
00265     term = pow(((1.0 + ESEDEI) * (1.0 + ESEDER)/(2.0*TTEIG)),2);
00266     result = 2.0 + 3.0*(ESEDEI+ESEDER) - 4.00*(ESEDEI+ESEDER + 1.0 - 4.0*pow((input - 0.5),2))*(1.0 + 0.25*log(term+ZTARG*pow(input,2)));
00267     return result;
00268 }
00269 

Generated at Wed Nov 21 12:20:26 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000