Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

mf4classes.cpp

Go to the documentation of this file.
00001 /*
00002  * ******** fete: From ENDF To ENDL *********
00003  * 
00004  * Copyright (c) 2006, The Regents of the University of California. 
00005  * All rights reserved.
00006  * 
00007  * Produced at the Lawrence Livermore National Laboratory. 
00008  * Written by David A. Brown, Gerry Hedstrom, Tony Hill
00009  * 
00010  * This file is part of fete v1.0  (UCRL-CODE-218718)
00011  * 
00012  * Please read the COPYING file for "Our Notice and GNU General 
00013  * Public License" in the root of this software distribution.  
00014  * 
00015  * This program is free software; you can redistribute it and/or modify 
00016  * it under the terms of the GNU General Public License (as published by 
00017  * the Free Software Foundation) version 2, dated June 1991. 
00018  * 
00019  * This program is distributed in the hope that it will be useful, 
00020  * but WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF 
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms 
00022  * and conditions of the GNU General Public License for more details. 
00023  * 
00024  * You should have received a copy of the GNU General Public License along 
00025  * with this program; if not, write to the Free Software Foundation, Inc., 
00026  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
00027  * 
00028  * $Revision: 1888 $
00029  * $Date: 2006-08-28 10:37:08 -0700 (Mon, 28 Aug 2006) $
00030  * $Author: dbrown $
00031  * $Id: mf4classes.cpp 1888 2006-08-28 17:37:08Z dbrown $
00032  * 
00033  * ******** fete: From ENDF To ENDL *********
00034  */
00035 
00036 // implementation of the classes used to translate the MF=4 data
00037 
00038 #include "mf4classes.hpp"
00039 #include "endl_formats.hpp"
00040 #include "global_params.hpp"
00041 
00042 extern ENDLClass ENDL;
00043 extern GlobalParameterClass Global;
00044 
00045 // ********* for class two_d_isotropic *************
00046 // ----------- two_d_isotropic::expand_data -----------------
00047 void two_d_isotropic::expand_data(int MT)
00048 // Make an isotropic list
00049 {
00050   double e_in;
00051   // make a new link for the threshold energy
00052   one_d_isotropic new_link;
00053 
00054   if(MT > 0)
00055   {
00056     // get the threshold energy
00057     e_in = ENDL.threshold;
00058   }
00059   else
00060   {
00061     // this list is for gamma production; threshold set later
00062     e_in = 0.0;
00063   }
00064 
00065   double min_e_in = Global.Value( "Min_n_energy" );
00066   if ( e_in < min_e_in ) e_in = min_e_in;
00067 
00068   // insert the 1-d list as a link
00069   insert(end(), new_link);
00070   two_d_isotropic::iterator this_ein = end();
00071   --this_ein;
00072   this_ein->initiate(e_in);
00073 
00074   // Do it again the maximum incident energy
00075   e_in = ENDL.Max_E_in;
00076   insert(end(), new_link);
00077   this_ein = end();
00078   --this_ein;
00079   this_ein->initiate(e_in);
00080 }
00081 
00082 // ********* for class two_d_Legendre *************
00083 // ----------- two_d_Legendre::expand_data -----------------
00084 void two_d_Legendre::expand_data(mf4_file& inFile, int NE, int MF)
00085 // interpret the ENDF/B-VI Legendre data
00086 // NE is the number of incident energies
00087 {
00088   bool done = false;
00089   // handle each incident neutron energy
00090   for (int iNE=0; iNE < NE; iNE++ )
00091   {
00092     one_E_in( inFile, MF, &done );
00093   }
00094   // The Legendre coefficients may depend logarithmically on
00095   // the incident energy
00096   if ( ( INT.size() > 1 ) || ( INT[ 0 ] != 2 ) )
00097   {
00098     expand_interp();
00099   }
00100 }
00101 // ----------- two_d_Legendre::one_E_in -----------------
00102 void two_d_Legendre::one_E_in( mf4_file& inFile, int MF, bool *done )
00103 // interpret the ENDF/B-VI Legendre data for 1 incident energy
00104 // return true if E_in >= ENDL.Max_E_in
00105 {
00106   double ZERO;  // zero
00107   double E_1;   // incident neutron energy
00108   int iZERO;    // zero
00109   int nLC;      // number of Legendre Coefficients
00110 
00111   string linebuff;  // the input line
00112   string strbuff;   // a substring
00113   two_d_Legendre::iterator this_link;
00114 
00115   if ( MF == 6 )
00116   {
00117     int ND;
00118     int NA;
00119     int NW;   // number of Legendre coefficients (P_0 = 1 always)
00120     int NEP;
00121     
00122     getline( inFile, linebuff ); //read next line
00123     read_ddiiii(&linebuff, &ZERO, // zero 
00124         &E_1,             // incident energy
00125         &ND,              // number of discrete energies
00126         &NA,              // number of angular parameters (1)
00127         &NW,              // number of table entries
00128         &NEP);            // number of E_out values
00129 
00130     nLC=NW;
00131     if(ND > 0)
00132     {
00133       Unimplemented("two_d_Legendre::one_E_in",
00134         "Implement discrete energies for Legendre");
00135     }
00136   }
00137   else if ( MF==4 )
00138   {
00139     double dT;    // temperature
00140     int iLT;      // test for temperature dependence
00141     int NL;       // number of Legendre coefficients (P_0 = 1 always)
00142     
00143     getline( inFile, linebuff ); //read next line
00144     read_ddiiii(&linebuff, &dT,   // temperature
00145         &E_1,             // incident energy
00146         &iLT,             // test for temperature dependence
00147         &iZERO,           // zero
00148         &NL,              // number of Legendre Coefficients
00149         &iZERO);          // zero
00150 
00151     nLC=NL;
00152     if(dT != 0.0)
00153     {
00154       Warning("two_d_Legendre::one_E_in",
00155         pastenum("Non-zero temperature (",dT)+
00156         " eV) in Legendre data, zeroing it."
00157       );
00158     }
00159   }
00160   else
00161   {
00162     Unimplemented("two_d_Legendre::one_E_in",
00163       pastenum("No code written for Legendre in MF = ",MF));
00164   }
00165 
00166   // make a new link for this incident energy
00167   one_d_Legendre new_link;
00168 
00169   if( !(*done) )
00170   {
00171     // insert the 1-d list as a link
00172     insert(end(), new_link);
00173     this_link = end();
00174     --this_link;
00175 
00176     // change to MeV
00177     this_link->E_in() = E_1 * ENDL.eV2MeV;
00178 
00179     // set the Legendre coefficients
00180     this_link->coef.get_space( nLC + 1 );
00181     this_link->coef.at(0) = 1.0;   //  default c_0
00182   }
00183 
00184   // read the coefficients
00185   for ( int iNR=0; iNR < nLC; ++iNR )
00186   {
00187     double next_coef;
00188     int iR = iNR % 6;  //There are 6 numbers per line
00189     if ( iR == 0 ) getline( inFile, linebuff); //Read in new line
00190     if( !*(done) )
00191     {
00192       strbuff = linebuff.substr(iR*11, 11);
00193       read_d( &strbuff, &next_coef );
00194       this_link->coef.at( iNR + 1 ) = next_coef;
00195     }
00196   }
00197 
00198   // is this incident energy above our maximum?
00199   if( ( this_link->E_in() > ENDL.Max_E_in ) && !(*done) )
00200   {
00201     set_interp( );
00202     chop_highE( ENDL.Max_E_in );
00203     *done = true;
00204   }
00205   else if( !(*done) )
00206   {
00207     // expand the 1-d model
00208     this_link->expand();
00209     // we may be done
00210     double dE = ENDL_EPSILON( ENDL.Max_E_in );
00211     if( this_link->E_in() > ENDL.Max_E_in - dE )
00212     {
00213       *done = true;
00214     }
00215   }
00216 }
00217 
00218 // ----------- two_d_Legendre::expand_interp -----------------
00219 void two_d_Legendre::expand_interp()
00220 // expand possible dependence of the coefficients on the
00221 // logarithm of the incident energy
00222 {
00223   if( INT[0] == -7 )
00224   {
00225     SevereError("two_d_Legendre::expand_interp","expand_interp called twice");
00226   }
00227 
00228   // record the types of interpolation between 1-d lists
00229   set_interp();
00230 
00231   // construct the equiprobable bins
00232   for( two_d_Legendre::iterator this_link = begin();
00233     this_link != end(); ++this_link )
00234   {
00235     this_link->get_bins();
00236   }
00237   // fill in to get good linear interpolation
00238   thicken();
00239 
00240   // flag to ensure that we don't do this twice on the same data
00241   INT[0] = -7;
00242 }
00243 
00244 // ********* for class mf4_table *************
00245 // ----------- mf4_table::master -----------------
00246 void mf4_table::master( mf4_file& inFile )
00247 {
00248   int NE;   // number of incident energy points
00249   int NR;   // number of interpolation regions
00250 
00251   // how much data
00252   inFile.read_line3( &NR, &NE );
00253   inFile.get_regions(NR, NBT, INT);
00254 
00255   read_data(inFile, NE ); //read in the data
00256 
00257   widen_jumps();
00258 
00259   // renormalize the probability distributions since, in the log-lin
00260   // to lin-lin interpolation, we may have lost accuracy
00261   renorm();
00262 
00263   if (ENDL.write_file) 
00264   {
00265     write_endl( 1 ); //write the ENDL file
00266     // do we have elastic scattering for a light target?
00267     if ( ( ENDL.T == 2 ) && ( ENDL.res_za <= 2004 ) )
00268     {
00269       ENDL.outgoing_particle = 10 + ENDL.za_to_yo( ENDL.res_za );
00270       mirror( );
00271       write_endl( 1 );
00272     }
00273   }
00274 }
00275 // ----------- mf4_table::read_data -----------------
00276 void mf4_table::read_data(mf4_file& inFile, int NE)
00277 // read in the ENDF/B-VI tabulated  data
00278 // NE is the number of incident energies
00279 {
00280   // handle each incident neutron energy
00281   for (int iNE=0; iNE < NE; iNE++ )
00282   {
00283     one_E_in(inFile);
00284   }
00285 }
00286 // ----------- mf4_table::one_E_in -----------------
00287 void mf4_table::one_E_in(mf4_file& inFile)
00288 //read in the tabulated ENDF/B-VI data at the current incident neutron energy
00289 {
00290   int iZERO;    // zero
00291   
00292   string linebuff;  // the input line
00293   string strbuff;   // a substring
00294 
00295   double T;     // temperature
00296   double E_1;   // incident neutron energy
00297   int LT;       // test for temperature dependence
00298   int NR;       // number of regions
00299   int NP;       // number of data points
00300       
00301   getline( inFile, linebuff ); //read next line
00302   read_ddiiii(&linebuff, &T,    // temperature
00303           &E_1,             // incident energy
00304           &LT,              // test for temperature dependence
00305           &iZERO,           // zero
00306           &NR ,             // number of regions
00307           &NP);             // number of data points
00308   
00309   if( T != 0.0)
00310   {
00311     SevereError("mf4_table::one_E_in",
00312       pastenum("Non-zero temperature for tabulated data ",T));
00313   }
00314   if( NR != 1 )
00315   {
00316     SevereError("mf4_table::one_E_in",
00317       "Unwritten code!  Expected single region ");
00318   }
00319   if( NP < 1 )
00320   {
00321     SevereError("mf4_table::one_E_in",
00322       pastenum("Negative number of data points ",NP));
00323   }
00324 
00325   // read the interpolation information for this E_in
00326   inFile.get_regions(NR, NBT, INT);
00327 
00328   // make a new link for this incident energy
00329   one_d_table new_link;
00330 
00331   // insert the 1-d list as a link
00332   insert(end(), new_link);
00333   mf4_table::iterator this_link = end();
00334   --this_link;
00335 
00336   // change to MeV
00337   this_link->E_in() = E_1 * ENDL.eV2MeV;
00338 
00339   // read the data for this E_in
00340   for( int iNP=0; iNP < NP; iNP++ ) //Loop over NP data pairs
00341   { 
00342     int iP=iNP % 3;  //There are 3 pairs per line
00343     if ( iP == 0 ) getline( inFile, linebuff); //Read in new line
00344     for( int i=0+iP*22; i<22+iP*22; i=i+22 ) //Grab the right pair
00345     strbuff = linebuff.substr(iP*22, 22); //Grab the right pair
00346     double X,Y; //Real variables we will put the data pair
00347     read_dd(&strbuff, &X, &Y );
00348     if ( X==-999. || Y==-999. ) //read_PAIR sends -999. if problem
00349     {
00350       SevereError("mf4_table::one_E_in","read_PAIR fucked up!");
00351     }
00352     else
00353     {
00354       dd_link XYdata(X, Y);
00355       this_link->insert(this_link->end(), XYdata);
00356     }
00357   }
00358   
00359 }
00360 
00361 // ********* for class mixed_mf4 *************
00362 // ----------- mixed_mf4::master -----------------
00363 void mixed_mf4::master( mf4_file& inFile )
00364 // Handle the Legendre data at low incident energies and tables at high
00365 {
00366   int NE;  // number of incident energies
00367   int NR;  // number of interpolation regions
00368 
00369   // read the interpolation regions for Legendre data
00370   inFile.read_line3( &NR, &NE ); 
00371   inFile.get_regions( NR, NBT, INT );
00372 
00373   // Legendre data
00374   expand_data( inFile, NE, ENDL.F ); //read/expand data to pointwise
00375 
00376   // read the interpolation regions for the table
00377   inFile.read_line3( &NR, &NE );
00378   inFile.get_regions(NR, table_data.NBT, table_data.INT);
00379 
00380   table_data.read_data( inFile, NE ); //read in the tabular data
00381 
00382   //the last Legendre incident energy may be the same as the first tabular one
00383   mixed_mf4::iterator last_Legendre = end( );
00384   --last_Legendre;
00385   double last_L_Ein = last_Legendre->E_in( );
00386   
00387   mf4_table::iterator first_table = table_data.begin( );
00388   double first_T_Ein = first_table->E_in( );
00389 
00390   // get the local energy epsilon (smallest dE can see in output file)
00391   double local_eps = ENDL_EPSILON( last_L_Ein );
00392 
00393   if( first_T_Ein < last_L_Ein + local_eps )
00394   {
00395     // how close is the previous Legendre E_in?
00396     mixed_mf4::iterator prev_link = last_Legendre;
00397     --prev_link;
00398     if( prev_link->E_in( ) <= last_L_Ein - 2*local_eps )
00399     {
00400       last_Legendre->E_in( ) -= local_eps;
00401     }
00402     else
00403     {
00404       // just get rid of this link
00405       erase( last_Legendre );
00406     }
00407 
00408     // how close is the next tabular E_in?
00409     mf4_table::iterator next_link = first_table;
00410     ++next_link;
00411     if( next_link->E_in( ) >= first_T_Ein + 2*local_eps )
00412     {
00413       first_table->E_in( ) += local_eps;
00414     }
00415     else
00416     {
00417       // just get rid of this link
00418       table_data.erase( first_table );
00419     }
00420   }
00421   
00422   unique();
00423   widen_jumps();
00424   table_data.widen_jumps();
00425   
00426   // renormalize the probability distributions since, in the log-lin
00427   // to lin-lin interpolation, we may have lost accuracy
00428   table_data.renorm();
00429 
00430   if ( ENDL.write_file )
00431   {
00432     fstream endl_file;
00433     // set up and print header for the ENDL file
00434     set_up_endl( 1, endl_file );
00435 
00436     // print the Legendre data
00437     out_data( 1, endl_file, 0.0 );
00438 
00439     // print the table
00440     table_data.out_data( 1, endl_file, 0.0 );
00441 
00442     // end the file and close it
00443     close_file( endl_file );
00444 
00445     // do we have elastic scattering for a light target?
00446     if ( ( ENDL.T == 2 ) && ( ENDL.res_za <= 2004 ) )
00447     {
00448       Unimplemented("mixed_mf4::master", " mixed_mf4 data for light targets");
00449     }
00450   }
00451 }
00452 
00453 // ********* for class gen_mf4 *************
00454 // ----------- gen_mf4::master -----------------
00455 void gen_mf4::master( mf6_file& inFile )
00456 // interpret the ENDF/B-VI data
00457 {
00458   int NR;  // number of interpolation regions
00459   int NE;  // number of incident energies
00460   inFile.mf4_line1(&NR, &NE);
00461   inFile.get_regions(NR, NBT, INT);
00462   if ( (NR > 1) || (INT[0] != 2) )
00463   {
00464     Unimplemented("gen_mf4::master",
00465         "Implement interpolation between incident energies for gen_mf4");
00466   }
00467 
00468   // loop over the incident energies
00469   int LANG;  // type of data
00470   int NW;    // number of data entries
00471   int NL;    // Legendre order or number of cosines
00472   double e_in; // incident energy
00473   for ( int count = 0; count < NE; ++count)
00474   {
00475     inFile.mf4_line2(&e_in, &LANG, &NW, &NL);
00476     if ( LANG == 0 )
00477     {
00478       // Legendre data
00479       one_legendre( inFile, e_in, NL );
00480     }
00481     else if ( LANG == 12 )
00482     {
00483       // linear-linear tabular data
00484       one_table( inFile, e_in, NL );
00485     }
00486     else if ( LANG == 14 )
00487     {
00488       // linear-log tabular data
00489       one_table( inFile, e_in, NL );
00490 
00491       // construct NBT and INT vectors for lin-log interpolation
00492       gen_mf4::iterator this_link = end();
00493       --this_link;
00494       this_link->NBT.push_back( NL );
00495       this_link->INT.push_back( 4 );
00496       this_link->expand_interp( ENDL.Max_E_out );
00497     }
00498     else
00499     {
00500     Unimplemented("gen_mf4::master",pastenum(" Implement LANG = ",LANG));
00501     }
00502   }
00503   write_endl(1);
00504 }
00505 // ----------- gen_mf4::one_legendre -----------------
00506 void gen_mf4::one_legendre( mf6_file& inFile, double e_in, int NL )
00507 // interpret Legendre data for 1 incident energy
00508 {
00509   // make a 1-d Legendre list
00510   one_d_Legendre Legendre;
00511 
00512   // set the Legendre coefficients
00513   string linebuff;  // the input line
00514   string strbuff;   // a substring
00515   Legendre.coef.get_space( NL + 1 );
00516   Legendre.coef.at( 0 ) = 1.0;
00517   for ( int iNR=0; iNR < NL; ++iNR )
00518   {
00519     double next_coef;
00520     int iR = iNR % 6;  //There are 6 numbers per line
00521     if ( iR == 0 ) getline( inFile, linebuff); //Read in new line
00522     strbuff = linebuff.substr(iR*11, 11);
00523     read_d( &strbuff, &next_coef );
00524     Legendre.coef.at( iNR + 1 ) = next_coef;
00525   }
00526   // expand the model
00527   Legendre.expand();
00528 
00529   // *** copy the Legendre list into a table ***
00530   // make a new link for this incident energy
00531   one_d_table new_link;
00532 
00533   // insert the 1-d list as a link
00534   insert(end(), new_link);
00535   gen_mf4::iterator this_link = end();
00536   --this_link;
00537 
00538   // change to MeV
00539   this_link->E_in() = e_in * ENDL.eV2MeV;
00540 
00541   // go through the Legendre list
00542   dd_link XYdata;
00543   for( one_d_Legendre::iterator from_link = Legendre.begin();
00544     from_link != Legendre.end(); ++from_link )
00545   {
00546     XYdata.x = from_link->x;
00547     XYdata.y = from_link->y;
00548     this_link->insert(this_link->end(), XYdata);
00549   }
00550 }
00551 // ----------- gen_mf4::one_table -----------------
00552 void gen_mf4::one_table( mf6_file& inFile, double e_in, int NL )
00553 // copy a table for 1 incident energy
00554 {
00555   // make a new link for this incident energy
00556   one_d_table new_link;
00557 
00558   // insert the 1-d list as a link
00559   insert(end(), new_link);
00560   gen_mf4::iterator this_link = end();
00561   --this_link;
00562 
00563   // change to MeV
00564   this_link->E_in() = e_in * ENDL.eV2MeV;
00565 
00566   // go through the data
00567   string linebuff;  // the input line
00568   string strbuff;   // a substring
00569   dd_link XYdata;
00570   for( int count = 0; count < NL; ++count )
00571   {
00572     int iP=count % 3;  //There are 3 pairs per line
00573     if ( iP == 0 ) getline( inFile, linebuff); //Read in new line
00574     strbuff = linebuff.substr(iP*22, 22); //Grab the right pair
00575     read_dd(&strbuff, &XYdata.x, &XYdata.y);
00576     this_link->insert(this_link->end(), XYdata);
00577   }
00578 }

Generated on Thu Sep 7 10:30:10 2006 for fete -- From ENDFB6 To ENDL by doxygen 1.3.4