Main Page   Compound List   File List   Compound Members   File Members  

MyCfSource.cpp

Go to the documentation of this file.
00001 
00008 #include <math.h>
00009 #include <iostream.h>
00010 #include <fstream.h>   // file I/O
00011 #include <iomanip.h>   // format manipulation
00012 #include <string>
00013 #include "ReactorConstants.hh"
00014 #include "ReactorFortran.hh"
00015 #include "MyCfSource.hh"
00016 
00017 long long factorial(int n);
00018 
00019 MyCfSource::MyCfSource(int newIsotope,
00020                        int newRmaxgen){
00021 
00022   Isotope = newIsotope;
00023   Rmaxgen = newRmaxgen;
00024 
00025   //  cout << "MyCfSource::MyCfSource(" << Isotope << "," << Rmaxgen 
00026   //       << ")" << endl;
00027 
00028   // Cf252
00029   if(Isotope == 252){
00030 
00031     // setup the probability density as a function of energy
00032     bool static first=1;
00033     float static fspace[200];
00034     float static mspace[200];
00035     float static gspace[200];
00036 
00037     if(first){
00038       float xlo = 0.;
00039       float xhi = 50.;
00040       funlxp_(Cf252NeutronSpectrum,fspace,xlo,xhi);
00041       xhi = 25.;
00042       funlxp_(Cf252GammaMultiplicityFit,mspace,xlo,xhi);
00043       funlxp_(Cf252GammaSpectrum,gspace,xlo,xhi);
00044       first = 0;
00045     } 
00046  
00047     // input the source number and position
00048     fstream cf252_position("data/cf252_position.txt", ios::in);
00049     //cout << "Cf input file: data/cf252_position.txt" << endl;
00050 
00051     Nsources = 0;
00052     char paramLine[256];
00053     string dummy;
00054     bool done = false;
00055     bool numSet = false;
00056     int positionNum = 0;
00057 
00058     while(!done){
00059 
00060       // '#' specifies a comment line -- ignore it
00061       if(cf252_position.peek() == '#'){
00062 
00063         cf252_position.getline(paramLine, 256);
00064         continue;
00065       }
00066 
00067       // 'E'ND or 'e'nd specifies end of file -- set done flag to true
00068       if(cf252_position.peek() == 'e' || cf252_position.peek() == 'E'){
00069 
00070         if(Nsources == 0) cout << "   Cf252 ERROR: " 
00071                                << "number of cf252 sources = 0" << endl;
00072         done = true;
00073         continue;
00074       }
00075 
00076       // 'N'SOURCES = or 'n'sources = specifies number of sources 
00077       if(cf252_position.peek() == 'n' || cf252_position.peek() == 'N'){
00078 
00079         if(numSet){
00080 
00081           cf252_position.getline( paramLine, 256 );
00082           continue;
00083         }
00084         cf252_position >> dummy;
00085         while(cf252_position.peek() == ' ' || cf252_position.peek() == '=') 
00086           cf252_position.ignore(1);
00087 
00088         cf252_position >> Nsources;
00089         if(Nsources == 0){
00090           cout << "   Cf252 ERROR: number of cf252 sources = 0" << endl;
00091           done = true;
00092           continue;
00093         }
00094 
00095         numSet = true;
00096         continue;
00097       }
00098 
00099       // 'P'OSITION = or 'p'osition = specifies position of the sourse(s)
00100       if(cf252_position.peek() == 'p' || cf252_position.peek() == 'P'){
00101 
00102         if(Nsources == 0 || positionNum >= Nsources){
00103 
00104           cout << "   Cf252 ERROR: too many positions " << positionNum+1 
00105                << " given for the number of sources " << Nsources << endl;
00106           cf252_position.getline( paramLine, 256 );
00107           positionNum++;
00108           continue;
00109         }
00110         cf252_position >> dummy;
00111         while(cf252_position.peek() == ' ' || cf252_position.peek() == '=') 
00112           cf252_position.ignore(1);
00113 
00114         cf252_position >> R[positionNum] >> zR[positionNum] 
00115                        >> phiR[positionNum];
00116 
00117         // check for unphysical source positions
00118         if(R[positionNum] > Rmaxgen){
00119           cout << "   Cf252 ERROR: R[" << positionNum << "] of " 
00120                << R[positionNum] << " > Rmaxgen" << endl;
00121           done = true;
00122           continue;
00123         }
00124         if(zR[positionNum] < -1. || zR[positionNum] > 1.){
00125           cout << "   Cf252 ERROR: CosTheta[" 
00126                << positionNum << "] of " << zR[positionNum] << endl;
00127           done = true;
00128           continue;
00129         }
00130         if(phiR[positionNum] > 2*k.pi){
00131           cout << "   Cf252 ERROR: Phi[" << positionNum << "] of " 
00132                << phiR[positionNum] << " > 2*pi" << endl;
00133           done = true;
00134           continue;
00135         }
00136 
00137         positionNum++;
00138         continue;
00139       }
00140 
00141       // ignore extra whitespace
00142       if(cf252_position.peek() == ' ' || cf252_position.peek() == '\n'){
00143 
00144         cf252_position.ignore(1);
00145         continue;
00146       }
00147     }
00148 
00149     if(positionNum < Nsources){
00150       cout << "   Cf252 ERROR: not enough positions " << positionNum 
00151            << " given for the number of sources " << Nsources << endl;
00152     }
00153     //
00154     // neutron multiplicity distribution (via Los Alamo manual)
00155     //
00156     double p[maxNeutron+1] = {0.002,0.028,0.155,0.428,
00157                               0.732,0.917,0.983,0.998,1.000};
00158     //
00159     for(int n=0;n<Nsources;n++){
00160       //cout << "Source " << n+1 << endl << "   Cf Source Position = " 
00161       //           << R[n] << ", " << zR[n] << ", " << phiR[n] << endl;
00162 
00163       // pick a neutron multiplicity
00164       bool passed = false;
00165       int len;
00166       while(!passed){
00167         len = 1;
00168         float r[len];
00169         ranlux_(r,len);
00170 
00171         for(int i=0;i<maxNeutron+1; i++){
00172 
00173           if(p[i] > r[0] && !passed){
00174             Nneutron[n] = i;
00175             if(Nneutron[n])passed = true;
00176           }
00177         }
00178       }
00179       //cout << "   " << Nneutron[n] << " neutrons" << endl;
00180       //
00181       // pick an energy for each neutron
00182       //
00183       for(int nn=0;nn<Nneutron[n]; nn++){
00184         len = 1;
00185         funlux_(fspace,neutronE[n][nn],len);
00186         //cout << "   Cf neutron energy = " << neutronE[n][nn] << endl;
00187         Tneutron[n][nn] = 0.;
00188       }
00189       /*
00190         The total energy in the prompt gammas is a function of the
00191         material and the number of prompt neutrons produced; these 
00192         formulae come from T. Valentine's summary
00193       */
00194       float Z = 98.;
00195       float A = 252.;
00196       //
00197       double avge = -1.33 + 119.6*pow(Z,0.3333)/A;
00198       double phi = 2.51 - 1.13e-5*Z*Z*sqrt(A);
00199       double etot = phi*Nneutron[n]+4.0;
00200       //
00201       // use the Brunson multiplicity (also via Valentine)
00202       //
00203       len = 1;
00204       float ng = 0.;
00205       funlux_(mspace,ng,len);
00206       Ngamma[n] = (int)ng;
00207       //cout << "   " << Ngamma[n] << " photons" << endl;
00208       //
00209       // pick an energy for each gamma
00210       //
00211       double tote = 0.;
00212       for(int nn=0;nn<Ngamma[n]; nn++){
00213         len = 1;
00214         funlux_(gspace,gammaE[n][nn],len);
00215         //cout << "   252Cf photon energy = " << gammaE[n][nn] << endl;
00216         tote += gammaE[n][nn];
00217 
00218         len = 2;
00219         float rv[len];
00220         ranlux_(rv,len);
00221         //
00222         // 80% of gammas have T_1/2 = 0.01 ns and 20% have T_1/2 = 1 ns
00223         //
00224         double halflife;
00225         if(rv[0] < 0.8)
00226           halflife = 0.01;
00227         else
00228           halflife = 1.0;
00229         Tgamma[n][nn] = halflife*log(1/rv[1]);
00230       }
00231       //cout << "          total energy = " << tote << endl;
00232     } // done looping over sources
00233 
00234     // zero out remaining energy and position arrays
00235     for(int n=0;n<Nsources;n++){
00236       for(int nn=Nneutron[n];nn<maxNeutron;nn++){
00237         neutronE[n][nn] = 0.;
00238         Tneutron[n][nn] = 0.;
00239       }
00240       for(int nn=Ngamma[n];nn<maxGamma;nn++){
00241         gammaE[n][nn] = 0.;
00242         Tgamma[n][nn] = 0.;
00243       }
00244     }
00245     for(int n=Nsources;n<k.Ndim;n++){
00246       Nneutron[n] = 0;
00247       Ngamma[n] = 0;
00248       R[n] = 0.;
00249       zR[n] = 0.;
00250       phiR[n] = 0.;
00251       for(int nn=0;nn<maxNeutron;nn++){
00252         neutronE[n][nn] = 0.;
00253         Tneutron[n][nn] = 0.;
00254       }
00255       for(int nn=0;nn<maxGamma;nn++){
00256         gammaE[n][nn] = 0.;
00257         Tgamma[n][nn] = 0.;
00258       }
00259     }
00260 
00261   } // done with Cf 252
00262 
00263   if(Isotope == 255){
00264 
00265     Nsources = 0;
00266     for(int n=Nsources;n<k.Ndim;n++){
00267       Nneutron[n] = 0;
00268       Ngamma[n] = 0;
00269       R[n] = 0.;
00270       zR[n] = 0.;
00271       phiR[n] = 0.;
00272       for(int nn=0;nn<maxNeutron;nn++){
00273         neutronE[n][nn] = 0.;
00274         Tneutron[n][nn] = 0.;
00275       }
00276       for(int nn=0;nn<maxGamma;nn++){
00277         gammaE[n][nn] = 0.;
00278         Tgamma[n][nn] = 0.;
00279       }
00280     }
00281   } // done with Cf 255
00282 }
00283 
00284 MyCfSource::~MyCfSource(){
00285   ;
00286 }
00287 
00288 MyCfSource::MyCfSource(const MyCfSource& CfSource){
00289 
00290   Isotope = CfSource.Isotope;
00291   Rmaxgen = CfSource.Rmaxgen;
00292 
00293   Nsources = CfSource.Nsources;
00294 
00295   for(int n=0;n<k.Ndim;n++){
00296     Nneutron[n] = CfSource.Nneutron[n];
00297     Ngamma[n] = CfSource.Ngamma[n];
00298     R[n] = CfSource.R[n];
00299     zR[n] = CfSource.zR[n];
00300     phiR[n] = CfSource.phiR[n];
00301 
00302     for(int nn=0;nn<maxNeutron;nn++){ 
00303       neutronE[n][nn] = CfSource.neutronE[n][nn];
00304       Tneutron[n][nn] = CfSource.Tneutron[n][nn];
00305     }
00306     for(int nn=0;nn<maxGamma;nn++){
00307       gammaE[n][nn] = CfSource.gammaE[n][nn];
00308       Tgamma[n][nn] = CfSource.Tgamma[n][nn];
00309     }
00310   }
00311 }    
00312 
00313 MyCfSource& MyCfSource::operator=(const MyCfSource& rhs){
00314 
00315   if(this == &rhs)return *this;
00316 
00317   Isotope = rhs.Isotope;  
00318   Rmaxgen = rhs.Rmaxgen;
00319 
00320   Nsources = rhs.Nsources;
00321 
00322   for(int n=0;n<k.Ndim;n++){
00323     Nneutron[n] = rhs.Nneutron[n];
00324     Ngamma[n] = rhs.Ngamma[n];
00325     R[n] = rhs.R[n];
00326     zR[n] = rhs.zR[n];
00327     phiR[n] = rhs.phiR[n];
00328 
00329     for(int nn=0;nn<maxNeutron;nn++){
00330       neutronE[n][nn] = rhs.neutronE[n][nn];
00331       Tneutron[n][nn] = rhs.Tneutron[n][nn];
00332     }
00333     for(int nn=0;nn<maxGamma;nn++){
00334       gammaE[n][nn] = rhs.gammaE[n][nn];
00335       Tgamma[n][nn] = rhs.Tgamma[n][nn];
00336     }
00337   }
00338   return *this;
00339 }    
00340 
00341 float MyCfSource::Cf252NeutronSpectrum(const float& x){
00342 
00343   // return the neutron spectrum N(x)
00344   float N = 0.;
00345 
00346   float scale = 1/(2*k.pi*0.359);
00347   //cout << "scale " << scale << endl;
00348 
00349   float fminus = exp(-(sqrt(x)-sqrt(0.359))*(sqrt(x)-sqrt(0.359))/1.175);
00350   float fplus  = exp(-(sqrt(x)+sqrt(0.359))*(sqrt(x)+sqrt(0.359))/1.175);
00351 
00352   N = scale*(fminus-fplus);
00353 
00354   //cout << "N " << N << endl;
00355   return N;
00356 }
00357 
00358 float MyCfSource::Cf252GammaMultiplicity(const int& x){
00359 
00360   // return the gamma multiplicity M(x)
00361   double M = 0.;
00362 
00363   double C1 = 0.675;
00364   double C2 = 6.78;
00365   double C3 = 9.92;
00366 
00367   M = C1*pow(C2,x)*exp(-C2)/factorial(x) + (1-C1)*pow(C3,x)*exp(-C3)/factorial(x);
00368 
00369   //cout << "M(" << x << ") " << M << endl;
00370 
00371   return M;
00372 }
00373 
00374 long long factorial(int n){
00375 
00376   // cannot return above n = 20 because of memory
00377   if(n < 1)
00378     return 1;
00379   else
00380     return n * factorial(n-1);
00381 }
00382 
00383 float MyCfSource::Cf252GammaMultiplicityFit(const float& x){
00384 
00385   // return the gamma multiplicity M(x)
00386   double M = 0.;
00387 
00388   float gaussian = 0.13345*exp(-0.5*((x-7.0322)/2.6301)*((x-7.0322)/2.6301));
00389   float exponential = 0.11255*(exp(-(sqrt(x)-sqrt(7.5987))
00390                                    *(sqrt(x)-sqrt(7.5987))/0.56213));
00391 
00392   if(x <= 9.0){
00393     M = gaussian;
00394   }
00395   else{
00396     M = exponential;
00397   }
00398 
00399   //cout << "M(" << x << ") " << M << endl;
00400 
00401   return M;
00402 }
00403 
00404 float MyCfSource::Cf252GammaSpectrum(const float& x){
00405 
00406   // return the gamma spectrum N(x)
00407   float N = 0.;
00408 
00409   float gaussian = 1.8367*exp(-0.5*((x-0.45934)/0.31290)*((x-0.45934)/0.31290));
00410   float exponential = exp(0.84774-0.89396*x);
00411 
00412   if(x <= 0.744){
00413     N = gaussian;
00414   }
00415   else{
00416     N = exponential;
00417   }
00418   
00419   //cout << "N " << N << endl;
00420   return N;
00421 }

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