Main Page   File List  

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

Generated on Sat Jul 17 14:45:42 2004 for ReactorFsim by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002