Main Page   Compound List   File List   Compound Members   File Members  

NeutronPropagator.cpp

00001 #include <math.h>
00002 #include <iostream.h>
00003 #include <fstream.h>
00004 #include <string.h>
00005 #include "ReactorFortran.hh"
00006 #include "ReactorConstants.hh"
00007 #include "ReactorNeutrons.hh"
00008 void NeutronPropagator$(double,double,double&,double&,double*,
00009                         double*,double&,double,double*,double*,double*);
00010 void NeutronPropagator(double R0,double R2,
00011                        double& ke,double& A,double& passes,
00012                        double* pn,double* rn,double& tn,
00013                        double Temperature,double* a,double* z,double* nn){
00014 
00015   double r=sqrt(rn[0]*rn[0]+rn[1]*rn[1]+rn[2]*rn[2]);
00016   while(ke>0 && r<R2){
00017     passes++;
00018     NeutronPropagator$(R0,R2,ke,A,pn,rn,tn,Temperature,a,z,nn);
00019     r=sqrt(rn[0]*rn[0]+rn[1]*rn[1]+rn[2]*rn[2]);
00020   }
00021   return;
00022 }
00023 void NeutronPropagator$(double R0,double R2,
00024                         double& ke,double& A,
00025                         double* pn,double* rn,double& tn,
00026                         double Temperature,double* a,double* z,double* nn){
00027   //
00028   if(ke==0)return;
00029   //
00030   static ReactorConstants RC;
00031   //
00032   double r=sqrt(rn[0]*rn[0]+rn[1]*rn[1]+rn[2]*rn[2]);
00033   if(r>R2)return;
00034   double rstart=r;
00035   // removed following section so that when you reset gd concentration,
00036   // these numbers get updated as well, passed through from ReactorDetector
00037   //
00038   // Set up cross section and materials data
00039   //
00040   static ReactorNeutrons XCdata;
00041   static bool first=1;
00042   //static double a[4];
00043   //static double z[4];
00044   //static double nn[4];
00045   //
00046   // Initialize on first call
00047   // 
00048   if(first){
00049     /*
00050       a[0] = RC.A0;
00051       a[1] = RC.A1;
00052       a[2] = RC.A2;
00053       a[3] = RC.A3;
00054       //
00055       z[0] = RC.Z0;
00056       z[1] = RC.Z1;
00057       z[2] = RC.Z2;
00058       z[3] = RC.Z3;
00059       //
00060       nn[0]=RC.Navogadro*RC.f0*RC.density/RC.A0;
00061       nn[1]=RC.Navogadro*RC.f1*RC.density/RC.A1;
00062       nn[2]=RC.Navogadro*RC.GdConcentration/100*RC.f2*RC.density/RC.A2;
00063       nn[3]=RC.Navogadro*RC.GdConcentration/100*RC.f3*RC.density/RC.A3;
00064     */
00065     ReactorNeutrons Init(0);
00066     XCdata=Init;
00067     first=0;
00068   }
00069   //
00070   // fetch cross section info
00071   //
00072   int nproc=8;
00073   double probproc[8];
00074   for(int i=0;i<nproc/2;i++){
00075     probproc[2*i]=nn[i]*XCdata.GetElastXC(z[i],a[i],1e6*ke);
00076     probproc[2*i+1]=nn[i]*XCdata.GetGammaXC(z[i],a[i],1e6*ke);
00077   }
00078   //
00079   // No Gd if outside inner volume
00080   //
00081   if(r>R0)for(int i=4;i<nproc;i++)probproc[i]=0;
00082   //
00083   // Normalize
00084   //
00085   double probtot=0;
00086   for(int i=0;i<nproc;i++)probtot+=probproc[i];
00087   for(int i=0;i<nproc;i++)probproc[i]/=probtot;
00088   for(int i=1;i<nproc;i++)probproc[i]+=probproc[i-1];
00089   //
00090   // Take steps until there is an interaction
00091   //
00092   double step=RC.SlowNeutronStep;
00093   double mn = RC.Mproton+RC.Delta;
00094   //
00095   double mfp=1/probtot/1e-24;
00096   double probint = 1-exp(-step/mfp);
00097   int len=5;
00098   float rv[5];
00099   double t[3];
00100   double p=sqrt(pn[0]*pn[0]+pn[1]*pn[1]+pn[2]*pn[2]);
00101   double v=p/mn*RC.c;
00102   for(int i=0;i<3;i++)t[i]=pn[i]/p;
00103   bool interacted=0;
00104   while(!interacted){
00105     ranlux_(rv,len);
00106     interacted=(rv[0]<probint);
00107     if(interacted){
00108       //
00109       // throw the exponential within the step 
00110       //
00111       double step2=-mfp*log(1-probint*rv[1]);
00112       for(int i=0;i<3;i++)rn[i]+=t[i]*step2;
00113       tn+=step2/v;
00114     }
00115     else{
00116       //
00117       // just step 
00118       //
00119       for(int i=0;i<3;i++)rn[i]+=t[i]*step;
00120       tn+=step/v;
00121     }
00122     //
00123     // Have to return if volume changes
00124     //
00125     r=sqrt(rn[0]*rn[0]+rn[1]*rn[1]+rn[2]*rn[2]);
00126     if(rstart<R0&&r>R0)return;
00127     if(rstart>R0&&r<R0)return;
00128   }
00129   //
00130   // figure out what kind of interaction
00131   // only consider elastic(odd) or absorb.(even)
00132   //
00133   bool stopped=0;
00134   if(rv[2]<probproc[0]){A=a[0];stopped=0;}
00135   else if(rv[2]<probproc[1]){A=a[0];stopped=1;}
00136   else if(rv[2]<probproc[2]){A=a[1];stopped=0;}
00137   else if(rv[2]<probproc[3]){A=a[1];stopped=1;}
00138   else if(rv[2]<probproc[4]){A=a[2];stopped=0;}
00139   else if(rv[2]<probproc[5]){A=a[2];stopped=1;}
00140   else if(rv[2]<probproc[6]){A=a[3];stopped=0;}
00141   else if(rv[2]<probproc[7]){A=a[3];stopped=1;}
00142   //
00143   // if stopped finished
00144   //
00145   if(stopped){
00146     ke=0;
00147     return;
00148   }
00149   //
00150   // otherwise generate an elastic scatter
00151   // throw target momentum via Max-Boltz. 
00152   //
00153   double Sqrt2mkT = sqrt(2*A*RC.Kboltzman*Temperature*RC.Mproton);
00154   float rw[3];
00155   len=3;
00156   rnormx_(rw,len,ranlux_);
00157   double pt[3];
00158   for(int i=0;i<3;i++)pt[i]=Sqrt2mkT*rw[i];
00159   //
00160   double vr[3];
00161   for(int i=0;i<3;i++)vr[i]=pn[i]-pt[i]/A;
00162   double vvr=sqrt(vr[0]*vr[0]+vr[1]*vr[1]+vr[2]*vr[2]);
00163   double u[3];
00164   double cosu = -1+2*rv[3];
00165   double phiu = 2*RC.pi*rv[4];
00166   u[0] = sqrt(1-cosu*cosu)*cos(phiu);
00167   u[1] = sqrt(1-cosu*cosu)*sin(phiu);
00168   u[2] = cosu;
00169   //
00170   for(int i=0;i<3;i++)pn[i] = pn[i]/(A+1)+pt[i]/(A+1)+vvr*A/(A+1)*u[i];
00171   ke=0;
00172   for(int i=0;i<3;i++)ke+=pn[i]*pn[i]/2/mn;
00173   //
00174   return;
00175 }
00176 

Generated on Mon Dec 27 11:10:13 2004 for ReactorFsim by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002