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

mf14classes.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: 1892 $
00029  * $Date: 2006-09-07 10:29:17 -0700 (Thu, 07 Sep 2006) $
00030  * $Author: dbrown $
00031  * $Id: mf14classes.cpp 1892 2006-09-07 17:29:17Z dbrown $
00032  * 
00033  * ******** fete: From ENDF To ENDL *********
00034  */
00035 
00036 // implementation of the classes for translating the MF=14 data
00037 
00038 #include "endl_formats.hpp"
00039 #include "mf4classes.hpp"
00040 #include "mf14classes.hpp"
00041 #include "global_params.hpp"
00042 #include "messaging.hpp"
00043 #include "endl_precision.hpp"
00044 
00045 extern ENDLClass ENDL;
00046 extern GlobalParameterClass Global;
00047 
00048 using namespace std;
00049 
00050 // ********* for class MF14_list *************
00051 // ----------- MF14_list constructor ----------------
00052 MF14_list::MF14_list( int NI, int NK, int order, mf12_file *InFile,
00053     mf14_file *Angle_File )
00054 {
00055   inFile = InFile;  // the mf12 file
00056   angle_file = Angle_File; // the mf14 file
00057 
00058   mf14_NI = NI; // number of isotropic distributions
00059   mf14_NK = NK; // total number of gamma distributions
00060   num_aniso = NK - NI;  // number of anisotropic gammas
00061   aniso_count = 0;  // numer of anisotropic gammas read
00062 
00063   // set the Legendre order
00064   order_ = order;
00065   coefs_.reserve( order + 1 );
00066   coefs_.resize( order + 1 );
00067   coefs_[0].inFile = inFile;
00068 }
00069 // ----------- MF14_list destructor ----------------
00070 MF14_list::~MF14_list()
00071 {
00072 }
00073 // ----------- MF14_list::master -----------------
00074 void MF14_list::master( int mf12_nk )
00075 // Read the data from the mf12 multiplicity file and the mf14
00076 // anisotropy file and print the results if ENDL i=4 format.
00077 // mf12_NK is the number of lines in the mf12 file---it may
00078 // be 1 more than mf14_NK (for the continuum).
00079 {
00080   int ZA;
00081   int mf14_LI, mf14_LTT;
00082 
00083   mf12_NK = mf12_nk;
00084 
00085   // reread the first line or the mf14 file
00086   angle_file->first_line(
00087        &ZA,             // target Z & A 
00088        &AWR,            // target mass
00089         &mf14_LI,        // isotropy flag
00090         &mf14_LTT,       // Legendre flag
00091         &mf14_NK,        // number of discreet photons (inc continuum)
00092         &mf14_NI         // number of isotropic photon dists
00093   );       
00094   // skip the isotropic lines
00095   angle_file->skip_iso( mf14_NI );
00096 
00097   // is there an mf15 file?
00098   contin_file.open( 15, ENDL.T );
00099   with_mf15 = ( contin_file )? true : false;
00100 
00101   if(mf14_NK > 1)
00102   {
00103     // The first block is the total multiplicity of discrete gammas.
00104     // Use the MF12_base read_mult routine.
00105     coefs_[0].read_mult( multiple );
00106 
00107     // set up the 2-d lists for the higher Legendre coefficients
00108     for( int L_count = 0; L_count <= order_; ++L_count )
00109     {
00110       dd_list::iterator mult_ptr = multiple.begin();
00111       for( int count = 0; count < multiple.size();
00112         ++count, ++mult_ptr )
00113       {
00114         one_d_table new_link;
00115         new_link.E_in() = mult_ptr->E_in();
00116         coefs_[ L_count ].insert( coefs_[ L_count ].end(), new_link );
00117       }
00118     }
00119 
00120     // get the discrete lines and continuum
00121     read_data( );
00122 
00123     // If there is continuum data, add it to the discrete lines
00124     if( with_mf15 )
00125     {
00126       add_lists( );
00127     }
00128     else
00129     {
00130       // just widen the delta functions
00131       widen_delta();
00132     }
00133     
00134     // strip any incident energy points that have 0 multiplicity from 
00135     // both the mulitplicity and outgoing angular distributions
00136     strip_zero_multiplicity( );
00137 
00138     // write the i = 4 file
00139     ENDL.set_yo(7);
00140     write_endl( );
00141 
00142     // print the multiplicities
00143     ENDL.set_yo(7);
00144     if ( ENDL.C == 55 )
00145     {
00146       if ( ENDL.T == 12 )
00147       {
00148         // read the cross section and multiply to get photon production
00149         multiple.scale_by_xs();
00150       }
00151       ENDL.set_yo(0);
00152       multiple.write_endl(0);
00153     }
00154     else
00155     {
00156       if ( ENDL.T == 13 )
00157       {
00158         // read the cross section and divide to get the gamma multiplicity
00159         multiple.divide_by_xs();
00160       }
00161       multiple.write_endl(9);
00162     }
00163   }
00164 }
00165 // ----------- MF14_list::read_data -----------------
00166 void MF14_list::read_data( )
00167 // This routine is used to read in ENDF/B-VI probabilities
00168 // of discrete and continuum gammas and their Legendre expansions,
00169 {
00170   // read the first anisotropic gamma energy
00171   angle_file->read_EG( &mf14_EG, &mf14_NR, &mf14_NE );
00172   mf14_EG *= ENDL.eV2MeV;  // in Mev
00173   if( mf14_EG == 0.0 )
00174   {
00175     SevereError("MF14_list::read_data",
00176         "Implement Legendre expansion of the continuum");
00177   }
00178   ++aniso_count; // one anisotropic gamma energy read
00179 
00180   double EG;  // gamma energy
00181   double ES;  // nucleus excitation level
00182   int LP;   // 2 Doppler shift the photon energy
00183             // 0, 1: do not Doppler shift
00184   int LF;   // 2 for discrete; 1 for continuum (in MF15 file)
00185   int NR;   // number of interpolation regions
00186   int NP;   // number of incident energies
00187   bool do_shift;  // true if we Doppler shift the gamma energy
00188   double prev_E_in;
00189 
00190   // read the mf12 file
00191   for(int count = 0; count < mf12_NK; ++count)
00192   {
00193     // initialize the test for duplicate incident energies
00194     prev_E_in = -1.0;
00195 
00196     inFile->gamma_line1(&EG,     //  gamma energy
00197               &ES,     //  excitation level
00198           &LP,     // do a Doppler shift?
00199           &LF,     // discrete-continuum flag
00200           &NR,     // number of interpolation regions
00201           &NP);    // number of (E, multiplicity) pairs
00202 
00203     // change to MeV
00204     EG *= ENDL.eV2MeV;
00205     if(LP == 2)
00206     {
00207       // do a Doppler shift
00208       do_shift = true;
00209     }
00210     else
00211     {
00212       do_shift = false;
00213     }
00214 
00215     if(LF == 1)
00216     {
00217       // this data is for the continuum, read the mf15 file
00218       continuum( NR, NP );
00219     }
00220     else
00221     {
00222       one_line( EG, &prev_E_in, NR, NP, do_shift );
00223     }
00224   }
00225 
00226   // we want probability density, not multiplicity
00227   if ( with_mf15 )
00228   {
00229     for( int L_count = 0; L_count <= order_; ++L_count )
00230     {
00231       for( MF12_base::iterator e_in_link = coefs_[ L_count ].begin( );
00232        e_in_link != coefs_[ L_count ].end( ); ++e_in_link )
00233       {
00234         double E_in = e_in_link->E_in( );
00235         double scale_by = multiple.evaluate( E_in );
00236         (*e_in_link) *= 1.0/scale_by;
00237       }
00238     }
00239   }
00240 }
00241 // ----------- MF14_list::one_line -----------------
00242 void MF14_list::one_line( double EG, double *prev_E_in, int NR,
00243   int NP, bool do_shift )
00244 // read in data for one discrete line
00245 {
00246   MF12_base::iterator e_in_link;
00247   dd_link XYdata;
00248   dd_link prev_XY;  // save for interpolation
00249   one_d_table new_link;
00250   string linebuff;
00251   string strbuff;
00252   double E_in;
00253   double use_E_in;
00254   double how_many;
00255   int L_count;  // count the Legendre order
00256   const double EPS = Global.Value( "mf5_tol" );  // tolerance for mf5 data
00257   double *coef_buff; // buffer for each E_in and its Legendre coefficients
00258   double **Coef_ptrs; // where in coef_buff for each E_in
00259   bool alloc_coef = false;  // no buffer allocated yet
00260   bool done = false;  // E_in is still below ENDL.Max_E_in
00261   double dE = ENDL_EPSILON( ENDL.Max_E_in );
00262 
00263   // read the interpolation regions
00264   inFile->get_regions(NR, coefs_[0].NBT, coefs_[0].INT);
00265   if( (NR > 1) || ( (coefs_[0].INT[0] != 1) && (coefs_[0].INT[0] != 2) ) )
00266   {
00267     Unimplemented("MF14_list::one_line","Implement interpolation");
00268   }
00269 
00270   // is this one of the anisotropic lines?
00271   if( abs( EG - mf14_EG ) <= EPS * EG )
00272   {
00273     // allocate space for the Legendre coefficients
00274     coef_buff = new double[ mf14_NE * ( order_ + 1 ) ];
00275     Coef_ptrs = new double* [ mf14_NE ];
00276     alloc_coef = true;
00277     read_Legendre( coef_buff, Coef_ptrs );
00278   }
00279 
00280   // read the data for this line
00281   for( int iNP=0; iNP < NP; iNP++ ) //Loop over NP data pairs
00282   { 
00283     int iP=iNP % 3;  //There are 3 pairs per line
00284     if ( iP == 0 )
00285     {
00286       getline( *inFile, linebuff ); //Read in new line
00287     }
00288     strbuff = linebuff.substr( iP*22, 22 );
00289     read_dd( &strbuff, &E_in, &how_many );
00290     if ( E_in==-999.0 || how_many==-999.0 ) //read_dd sends -999.0 if problem
00291     {
00292       SevereError( "MF14_list::one_line", "read_dd failed!" );
00293     }
00294     E_in *= ENDL.eV2MeV;
00295 
00296     // did we exceed the maximum E_in?
00297     if( done )
00298     {
00299       e_in_link = coefs_[ 0 ].end();
00300     }
00301     else if( E_in <= ENDL.Max_E_in )
00302     {
00303       use_E_in = E_in;
00304       if(mf12_NK > 1)
00305       {
00306         // Find the 1-d list with this incident energy
00307         e_in_link = coefs_[ 0 ].find_link( E_in, EG );
00308       }
00309       else
00310       {
00311         // make a new list
00312         new_link.E_in() = E_in;
00313         coefs_[ 0 ].insert(coefs_[ 0 ].end(), new_link);
00314         e_in_link = coefs_[ 0 ].end();
00315         --e_in_link;
00316       }
00317     }
00318     else
00319     {
00320       // E_in > ENDL.Max_E_in and we need to interpolate
00321       use_E_in = ENDL.Max_E_in;
00322       if(mf12_NK > 1)
00323       {
00324         // use ENDL.Max_E_in as the incident energy
00325         e_in_link = coefs_[ 0 ].find_link( use_E_in, EG );
00326       }
00327     }
00328 
00329     //  do we store this data?
00330     if( e_in_link != coefs_[ 0 ].end() )
00331     {
00332       if( do_shift )
00333       {
00334         XYdata.x = EG + AWR*E_in/(AWR + 1);
00335       }
00336       else
00337       {
00338         XYdata.x = EG;
00339       }
00340       XYdata.y = how_many;
00341       // we may have to interpolate
00342       if( E_in > ENDL.Max_E_in ) 
00343       {
00344         double E_diff = E_in - prev_XY.x;
00345         if( ( E_diff <= 0.0 ) || ( iNP == 0 ) )
00346         {
00347           SevereError( "MF14_list::one_line", "energies out of order" );
00348         }
00349         XYdata.y = prev_XY.y +
00350           ( ENDL.Max_E_in - prev_XY.x ) *
00351           ( XYdata.y - prev_XY.y ) / dE;
00352       }
00353 
00354       // save it if this is less than the maximum gamma energy
00355       if( XYdata.x < ENDL.Max_E_out + dE )
00356       {
00357         insert_pair( XYdata, e_in_link );
00358         // is this one of the anisotropic lines?
00359         if( alloc_coef )
00360         {
00361           insert_Legendre( use_E_in, XYdata, *prev_E_in, Coef_ptrs );
00362         }
00363         else
00364         {
00365           XYdata.y = 0.0;
00366           for( L_count = 1; L_count <= order_; ++L_count )
00367           {
00368             if(mf14_NK > 1)
00369             {
00370               // Find the 1-d list with this incident energy
00371               e_in_link = coefs_[ L_count ].find_link( use_E_in, EG );
00372             }
00373             else
00374             {
00375               // make a new list
00376               new_link.E_in() = use_E_in;
00377               coefs_[ L_count ].insert(coefs_[ L_count ].end(), new_link);
00378               e_in_link = coefs_[ L_count ].end();
00379               --e_in_link;
00380             }
00381             insert_pair( XYdata, e_in_link );
00382           }
00383         }
00384       }
00385     }
00386     // Save for the next data set
00387     *prev_E_in = use_E_in;
00388     prev_XY.x = XYdata.x;
00389     prev_XY.y = XYdata.y;
00390 
00391     // is this the last data to store?
00392     if( E_in > ENDL.Max_E_in - dE )
00393     {
00394       done = true;
00395     }
00396   }
00397 
00398   // delete storage if necessary
00399   if( alloc_coef )
00400   {
00401     delete [] coef_buff;
00402     delete [] Coef_ptrs;
00403   }
00404 }
00405 // ----------- MF14_list::insert_pair -----------------
00406 void MF14_list::insert_pair( dd_link& XYdata,
00407   MF12_base::iterator e_in_link )
00408 // Insert an (EG, probability) pair into a list
00409 {
00410   // The gamma energies are usually in descending order
00411   // but the Doppler shift may introduce inversions
00412   one_d_table::iterator next_xy;
00413   if( e_in_link->empty() )
00414   {
00415     next_xy = e_in_link->end();
00416   }
00417   else
00418   {
00419     // find the first bigger gamma energy
00420     for( next_xy = e_in_link->begin();
00421       next_xy != e_in_link->end();
00422         ++next_xy )
00423     {
00424       if ( next_xy->x >= XYdata.x )
00425       {
00426         break;
00427       }
00428     }
00429   }
00430   e_in_link->insert( next_xy, XYdata );
00431 }
00432 // ----------- MF14_list::read_Legendre -----------------
00433 void MF14_list::read_Legendre( double *coef_buff, double **Coef_ptrs )
00434 // Read Legendre data for one gamma from an mf14 file
00435 {
00436   double e_in;
00437   double *this_ptr = coef_buff;
00438   string linebuff;
00439   string strbuff;
00440   int NL;
00441 
00442   // read the interpolation regions
00443   angle_file->get_regions( mf14_NR, coefs_[1].NBT, coefs_[1].INT );
00444   if( (mf14_NR > 1) || ( (coefs_[1].INT[0] != 1) && (coefs_[1].INT[0] != 2) ) )
00445   {
00446     SevereError("MF14_list::read_Legendre","Implement interpolation");
00447   }
00448 
00449   // loop over the mf14 incident energies
00450   for( int count = 0; count < mf14_NE; ++count )
00451   {
00452     // read the incident neutron energy and the number of coefficients
00453     angle_file->Leg_head( &e_in, &NL );
00454     e_in *= ENDL.eV2MeV;  // in Mev
00455     *this_ptr = e_in;     // save the incident energy
00456     Coef_ptrs[ count ] = this_ptr;  // where to find this incident energy
00457     ++this_ptr;
00458 
00459     // read the Legendre coefficients for this incident energy
00460     int iNL;
00461     for( iNL = 0; iNL < NL; ++iNL, ++this_ptr )
00462     { 
00463       int iL=iNL % 6;  //There are 6 entries per line
00464       if ( iL == 0 )
00465       {
00466         getline( *angle_file, linebuff); //Read in new line
00467       }
00468       strbuff = linebuff.substr( iL*11, 11 );
00469       read_d( &strbuff, this_ptr );
00470     }
00471     // fill with zeros
00472     for( ; iNL < order_; ++iNL, ++this_ptr )
00473     {
00474       *this_ptr = 0.0;
00475     }
00476   }
00477 
00478   // is there more mf14 data?
00479   if( aniso_count < num_aniso )
00480   {
00481     // read the next anisotropic gamma energy
00482     angle_file->read_EG( &mf14_EG, &mf14_NR, &mf14_NE );
00483     mf14_EG *= ENDL.eV2MeV;  // in Mev
00484     if( mf14_EG == 0.0 )
00485     {
00486       Unimplemented("MF14_list::read_Legendre",
00487         "Implement Legendre expansion of the continuum");
00488     }
00489     ++aniso_count; // one more anisotropic gamma energy read
00490   }
00491   else
00492   {
00493     // make sure that mf14_EG is nonphysical
00494     mf14_EG = -1.0;
00495   }
00496 }
00497 // ----------- MF14_list::insert_Legendre -----------------
00498 void MF14_list::insert_Legendre( double e_in, dd_link& XYdata,
00499   double prev_E_in, double **Coef_ptrs )
00500 // Insert the Legendre data for one gamma from an mf14 file into our lists
00501 // Coef_ptrs[ j ] points to the j-th m14 incident energy, and this is
00502 // followed by order_ Legendre coefficients
00503 {
00504   MF12_base::iterator e_in_link;
00505   double scale = XYdata.y;  // The ENDF mf14 file assumes c_0 = 1
00506   int L_count;              // count the Legendre order
00507   dd_link new_data;         // for new 1-d links
00508   one_d_table new_link;     // for new 1-d lists
00509   double *prev_coef_ptr;
00510   double *next_coef_ptr;
00511 
00512   new_data.x = XYdata.x;  // this gamma energy
00513 
00514   // first find the mf14 data for this incident energy
00515   int j;
00516   for( j = 0; ( ( j < mf14_NE ) && ( *Coef_ptrs[ j ] < e_in ) ); ++j )
00517   {
00518   }
00519   if( j >= mf14_NE )
00520   {
00521     string msg( pastenum("Incident energy ",e_in)+" not found" + pastenum(" for gamma ", XYdata.x) );
00522     SevereError("MF14_list::insert_Legendre",msg);
00523   }
00524 
00525   // there is no interpolation at the first incident energy
00526   if( j == 0 )
00527   {
00528     next_coef_ptr = Coef_ptrs[ 0 ];
00529     ++next_coef_ptr;
00530     for( L_count = 1; L_count <= order_; ++L_count, ++next_coef_ptr )
00531     {
00532       if(mf14_NK > 1)
00533       {
00534         // Find the 1-d list with this incident energy
00535         e_in_link = coefs_[ L_count ].find_link( e_in, mf14_EG );
00536         if ( e_in_link == coefs_[ L_count ].end() ) 
00537             SevereError("MF14_list::insert_Legendre","Cannot find link");
00538       }
00539       else
00540       {
00541         // make a new list
00542         new_link.E_in() = e_in;
00543         coefs_[ L_count ].insert(coefs_[ L_count ].end(), new_link);
00544         e_in_link = coefs_[ L_count ].end();
00545         --e_in_link;
00546       }
00547       XYdata.y = scale * (*next_coef_ptr);
00548       insert_pair( XYdata, e_in_link );
00549     }
00550   }
00551   else
00552   {
00553     prev_coef_ptr = Coef_ptrs[ j - 1 ];  // previous incident energy
00554     next_coef_ptr = Coef_ptrs[ j ];      // next incident energy
00555     double alpha = ( e_in - *prev_coef_ptr ) / 
00556         ( *next_coef_ptr - *prev_coef_ptr );
00557     for( L_count = 1; L_count <= order_; ++L_count )
00558     {
00559       if(mf14_NK > 1)
00560       {
00561         // Find the 1-d list with this incident energy
00562         e_in_link = coefs_[ L_count ].find_link( e_in, mf14_EG );
00563         if ( e_in_link == coefs_[ L_count ].end() ) 
00564             SevereError("MF14_list::insert_Legendre","Cannot find link");
00565       }
00566       else
00567       {
00568         // make a new list
00569         new_link.E_in() = e_in;
00570         coefs_[ L_count ].insert(coefs_[ L_count ].end(), new_link);
00571         e_in_link = coefs_[ L_count ].end();
00572         --e_in_link;
00573       }
00574       // point to the next Legendre coefficients
00575       ++next_coef_ptr;
00576       ++prev_coef_ptr;
00577       XYdata.y = scale * ( alpha * (*next_coef_ptr) + 
00578         ( 1.0 - alpha) * (*prev_coef_ptr) );
00579       insert_pair( XYdata, e_in_link );
00580     }
00581   }
00582 }
00583 // ----------- MF14_list::widen_delta -----------------
00584 void MF14_list::widen_delta( )
00585 // widen the delta functions for the discrete spectrum
00586 {
00587   MF12_base::iterator e_in_link[ order_ + 1 ];  // Legendre coefficients
00588   int L_count;        // to count the Legendre order
00589 
00590   // point to the first incident energy for each Legendre order
00591   for( L_count = 0; L_count <= order_; ++L_count )
00592   {
00593     e_in_link[ L_count ] = coefs_[ L_count ].begin();
00594   }
00595 
00596   // pointers to links in a (gamma energy, probability) list
00597   dd_list::iterator this_link[ order_ + 1 ];
00598   dd_list::iterator next_link[ order_ + 1 ];
00599   dd_list::iterator prev_link;
00600 
00601   // loop through the incident energies
00602   bool quit = false;
00603   for( ; !quit; )
00604   {
00605     // start at the lowest gamma energy for each Legendre order
00606     for( L_count = 0; L_count <= order_; ++L_count )
00607     {
00608       this_link[ L_count ] = e_in_link[ L_count ]->begin();
00609       next_link[ L_count ] = e_in_link[ L_count ]->begin();
00610       ++next_link[ L_count ];
00611     }
00612     // loop through the discrete lines
00613     for( ; ; )
00614     {
00615       prev_link = this_link[ 0 ];
00616       --prev_link;
00617 
00618       // what is the separation between states?
00619       double dE_L = (this_link[ 0 ] == e_in_link[ 0 ]->begin()) ?
00620         this_link[ 0 ]->E_out() :
00621         this_link[ 0 ]->E_out() - prev_link->E_out();
00622       double dE_R = (next_link[ 0 ] == e_in_link[ 0 ]->end()) ?
00623         this_link[ 0 ]->E_out() :
00624         next_link[ 0 ]->E_out() - this_link[ 0 ]->E_out();
00625       double dE = (dE_L < dE_R) ? dE_L : dE_R;
00626 
00627       // set width of delta function (basically 5* smallest dE we
00628       // can see in output file)
00629       dE = ENDL_JUMP_WIDTH( this_link[ 0 ]->E_out() );
00630 
00631       dd_link new_link = dd_link(this_link[ 0 ]->E_out() - dE, 0.0);
00632       for( L_count = 0; L_count <= order_; ++L_count )
00633       {
00634         // scale the line
00635         this_link[ L_count ]->y /= dE;
00636 
00637         // insert the base of the triangle at each Legendre order
00638         e_in_link[ L_count ]->insert( this_link[ L_count ], new_link );
00639       }
00640       new_link = dd_link(this_link[ 0 ]->E_out() + dE, 0.0);
00641       for( L_count = 0; L_count <= order_; ++L_count )
00642       {
00643         e_in_link[ L_count ]->insert( next_link[ L_count ], new_link );
00644         this_link[ L_count ] = next_link[ L_count ];
00645         ++next_link[ L_count ];
00646       }
00647       if( this_link[ 0 ] == e_in_link[ 0 ]->end() )
00648       {
00649         break;
00650       }
00651     }
00652     // go to the next incident energy for each Legendre order
00653     for( L_count = 0; L_count <= order_; ++L_count )
00654     {
00655       ++e_in_link[ L_count ];
00656       if( e_in_link[ L_count ] == coefs_[ L_count ].end() )
00657       {
00658         quit = true;
00659         break;
00660       }
00661     }
00662   }
00663 }
00664 // ----------- MF14_list::thinit -----------------
00665 void MF14_list::thinit( )
00666 // remove redundant data points
00667 {
00668   // this routine is based on the list_1d version
00669   // declare pointers to the test links
00670   MF12_base::iterator e_in_list[ order_ + 1 ];
00671   dd_list::iterator left_link[ order_ + 1 ];
00672   dd_list::iterator mid_link[ order_ + 1 ];
00673   dd_list::iterator right_link[ order_ + 1 ];
00674   dd_list::iterator all_done;
00675   bool thin_ok;  // for test on 1 link
00676   bool do_thin;  // thin OK at this level
00677   bool prev_thin;  // thin OK at the previous level
00678   const double cut_off = Global.Value("cut_off_1d"); // don't impose accuracy below this value
00679   const double tol_1d = Global.Value("tol_1d");  // accuracy of linear interpolation
00680   int L_order;  // the Legendre order
00681 
00682   // initialize the pointers to the lists of Legendre coefficients
00683   for( L_order = 0; L_order <= order_; ++L_order )
00684   {
00685     e_in_list[ L_order ] = coefs_[ L_order ].begin( );
00686   }
00687 
00688   // loop over the incident energies
00689   for( ; ;  )
00690   {
00691 
00692     //  quit at the last valid link
00693     all_done = e_in_list[ 0 ]->end( );
00694     --all_done;
00695 
00696     // set the noise level
00697     double noise = 0.0;
00698 
00699     // initialize the pointers to the Legendre coefficients
00700     for( L_order = 0; L_order <= order_; ++L_order )
00701     {
00702       left_link[ L_order ] = e_in_list[ L_order ]->begin( );
00703     }
00704     // loop through the list of left-hand anchors
00705     for( ; left_link[ 0 ] != all_done; ++left_link[ 0 ])
00706     {
00707       // make sure that we have data to check
00708       for( L_order = 0; L_order <= order_; ++L_order )
00709       {
00710         mid_link[ L_order ] = left_link[ L_order ];
00711         ++mid_link[ L_order ];
00712         right_link[ L_order ] = mid_link[ L_order ];
00713         ++right_link[ L_order ];
00714         if( ( mid_link[ L_order ] == e_in_list[ L_order ]->end() ) ||
00715             ( right_link[ L_order ] == e_in_list[ L_order ]->end() ) )
00716         {
00717           break;  // no more data for this incident energy
00718         }
00719       }
00720 
00721       // the default is no thinning
00722       prev_thin = false;
00723 
00724       // how long a span may we delete?
00725       for( ; right_link[ 0 ] != e_in_list[ 0 ]->end(); ++right_link[ 0 ] )
00726       {
00727         // the default is don't delete links at this level
00728         do_thin = false;
00729 
00730         // check all of the intermediate links at all orders
00731         for( L_order = 0; L_order <= order_; ++L_order )
00732         {
00733           mid_link[ L_order ] = left_link[ L_order ];
00734           ++mid_link[ L_order ];
00735         }
00736         for( ; mid_link[ 0 ] != right_link[ 0 ]; ++mid_link[ 0 ] )
00737         {
00738           for( L_order = 0; L_order <= order_; ++L_order )
00739           {
00740             thin_ok = e_in_list[ L_order ]->check_interp(
00741               left_link[ L_order ], mid_link[ L_order ],
00742               right_link[ L_order ], tol_1d, noise );
00743 
00744             if(thin_ok)
00745             {
00746               // at least one deletion is possible
00747               do_thin = true;
00748             }
00749             else
00750             {
00751               // this section fails
00752               do_thin = false;
00753               break;
00754             }
00755           }
00756           if( !do_thin )
00757           {
00758             break;
00759           }
00760           for( L_order = 1; L_order <= order_; ++L_order )
00761           {
00762             ++mid_link[ L_order ];
00763           }
00764         }
00765 
00766         // did they all pass?
00767         if(do_thin)
00768         {
00769           prev_thin = true;
00770           // move the right links
00771           for( L_order = 1; L_order <= order_; ++L_order )
00772           {
00773             ++right_link[ L_order ];
00774           }
00775         }
00776         else
00777         {
00778           break;
00779         }
00780       }
00781 
00782       // do the deletions
00783       dd_list::iterator left_next;
00784       dd_list::iterator right_prev;
00785 
00786       if((prev_thin) && (!do_thin))
00787       {
00788         // deletion is not allowed here but it is OK at the previous level
00789         for( L_order = 0; L_order <= order_; ++L_order )
00790         {
00791           left_next = left_link[ L_order ];
00792           ++left_next;
00793           right_prev = right_link[ L_order ];
00794           --right_prev;
00795           e_in_list[ L_order ]->erase(left_next, right_prev);
00796         }
00797       }
00798       else if( (do_thin) && (right_link[ 0 ] == e_in_list[ 0 ]->end() ) &&
00799         ( mid_link[ 0 ] == all_done) )
00800       {
00801         // we are at the end and all links passed
00802         for( L_order = 0; L_order <= order_; ++L_order )
00803         {
00804           left_next = left_link[ L_order ];
00805           ++left_next;
00806           e_in_list[ L_order ]->erase( left_next, mid_link[ L_order ] );
00807         }
00808       }
00809 
00810       // increment the pointers to the higher Legendre coefficients
00811       for( L_order = 1; L_order <= order_; ++L_order )
00812       {
00813         ++left_link[ L_order ];
00814       }
00815     }
00816     // go to the list for the next incident energy
00817     for( L_order = 0; L_order <= order_; ++L_order )
00818     {
00819       ++e_in_list[ L_order ];
00820       if( e_in_list[ L_order ] == coefs_[ L_order ].end( ) )
00821       {
00822         return;  // there is no more data
00823       }
00824     }
00825   }
00826 }
00827 // ----------- MF14_list::set_norms -----------------
00828 void MF14_list::set_norms( )
00829 // set the norms of the discrete and continuous spectra according
00830 // to the given multiplicities
00831 {
00832   // first get the probability of a continuum gamma
00833   continuum_dist.multiple /= multiple;
00834   double scale_by;
00835   
00836   // pointers to the data
00837   MF12_base::iterator disc_ptr[ order_ + 1 ];
00838   MF15_list::iterator contin_ptr = continuum_dist.begin( );
00839   int L_order;
00840   for( L_order = 0; L_order <= order_; ++L_order )
00841   {
00842     disc_ptr[ L_order ] = coefs_[ L_order ].begin();
00843   }
00844 
00845   // go through the lists
00846   for( ; contin_ptr != continuum_dist.end( ); ++contin_ptr )
00847   {
00848     double cont_wgt =  continuum_dist.multiple.evaluate( contin_ptr->E_in( ) );
00849     if( ( cont_wgt < 0.0 ) || ( cont_wgt > 1.0 ) )
00850     {
00851       SevereError("MF14_list::set_norms",pastenum("Bad weight =",cont_wgt));
00852     }
00853     double norm_now = contin_ptr->get_norm( );
00854     if( norm_now <= 0.0 )
00855     {
00856       Warning("MF14_list::set_norms","Zero norm");
00857     }
00858     else 
00859     {
00860       scale_by = cont_wgt / norm_now;
00861       *(contin_ptr) *= scale_by;
00862     }
00863     
00864     norm_now = disc_ptr[ 0 ]->get_norm( );
00865     if( norm_now <= 0.0 )
00866     {
00867       disc_ptr[ 0 ]->print();
00868       Warning("MF14_list::set_norms","Zero norm");
00869     }
00870     else
00871     {
00872       scale_by = ( 1.0 - cont_wgt ) / norm_now;
00873       for( int L_order = 0; L_order <= order_; ++L_order )
00874       {
00875         *(disc_ptr[ L_order ]) *= scale_by;
00876         ++disc_ptr[ L_order ];
00877       }
00878     }
00879   }
00880 }
00881 
00882 // ----------- MF14_list::strip_zero_multiplicity -----------
00883 void MF14_list::strip_zero_multiplicity( )
00884 {
00885     multiplicity::iterator multPtr = multiple.begin();
00886     while ( multPtr != multiple.end() )
00887     {
00888         if ( multPtr->y == 0.0 ) {
00889             double bad_Ein = multPtr->x;
00890             Info( "MF14_list::strip_zero_multiplicity", pastenum( "Erasing outgoing energy ", multPtr->x ) + pastenum( " because M(E) = ", multPtr->y ) );
00891             multPtr = multiple.erase( multPtr );
00892             for( int L_count = 0; L_count <= order_; ++L_count )
00893             {
00894                 MF12_base::iterator list_ptr = coefs_[ L_count ].begin();
00895                 while ( list_ptr != coefs_[ L_count ].end() )
00896                 {
00897                      if ( abs( bad_Ein - list_ptr->E_in( ) ) < 1e-10 ) list_ptr = coefs_[ L_count ].erase( list_ptr );
00898                      else ++list_ptr;
00899                 }
00900             }
00901         }
00902         else 
00903         {
00904             ++multPtr;
00905         }
00906     }
00907 }
00908 
00909 // ----------- MF14_list::renorm -----------------
00910 void MF14_list::renorm( )
00911 // normalize the probabilities to 1
00912 {
00913   MF12_base::iterator e_in_link[ order_ + 1 ];  // Legendre coefficients
00914   int L_count;        // to count the Legendre order
00915 
00916   // point to the first incident energy for each Legendre order
00917   for( L_count = 0; L_count <= order_; ++L_count )
00918   {
00919     e_in_link[ L_count ] = coefs_[ L_count ].begin();
00920   }
00921 
00922   // loop through the incident energies
00923   for( ; ; )
00924   {
00925     // get the norm of the 0-order Legendre term
00926     double norm = e_in_link[ 0 ]->get_norm( );
00927     if( norm == 0.0 )
00928     {
00929       Warning("MF14_list::renorm",
00930         pastenum("No spectrum for E_in= ",e_in_link[ 0 ]->E_in( )));
00931     }
00932     else
00933     {
00934       // scale all Legendre orders
00935       for( L_count = 0; L_count <= order_; ++L_count )
00936       {
00937         *e_in_link[ L_count ] *= 1.0/norm;
00938       }
00939     }
00940 
00941     // go to the next incident energy for each Legendre order
00942     for( L_count = 0; L_count <= order_; ++L_count )
00943     {
00944       ++e_in_link[ L_count ];
00945       if( e_in_link[ L_count ] == coefs_[ L_count ].end() )
00946       {
00947         return;  // we did them all
00948       }
00949     }
00950   }
00951 }
00952 // ----------- MF14_list::add_lists -----------------
00953 void MF14_list::add_lists( )
00954 // combine the continuous spectrum with the discrete lines
00955 {
00956   // ensure that we have continuum data for all discrete incident energies
00957   list< double > E_incident;
00958   coefs_[ 0 ].collect_Ein( E_incident );
00959   continuum_dist.collect_Ein( E_incident );
00960   E_incident.sort( );
00961   E_incident.unique( );
00962   continuum_dist.fill_in_list( E_incident );
00963 
00964   // delete any extra continuum incident energies
00965   extra_contin( );
00966 
00967   // then widen the delta functions
00968   widen_delta( );
00969 
00970   // set the weights of the continuum and discrete spectra
00971   set_norms( );
00972 
00973   // now do the addition
00974   MF12_base::iterator disc_ptr[ order_ + 1 ];
00975   int L_order;
00976   for( L_order = 0; L_order <= order_; ++L_order )
00977   {
00978     disc_ptr[ L_order ] = coefs_[ L_order ].begin();
00979   }
00980   for( MF15_list::iterator contin_ptr = continuum_dist.begin( );
00981     contin_ptr != continuum_dist.end(); ++contin_ptr )
00982   {
00983     // make the gamma energies match
00984     fill_in_lists( *contin_ptr, *(disc_ptr[ 0 ]) );
00985     for( L_order = 1; L_order <= order_; ++L_order )
00986     {
00987       fill_in_lists( *(disc_ptr[ 0 ]), *(disc_ptr[ L_order ]) );
00988     }
00989     // add the zero-order terms
00990     *disc_ptr[ 0 ] += *contin_ptr;
00991     // next Legendre terms
00992     for( L_order = 0; L_order <= order_; ++L_order )
00993     {
00994       ++disc_ptr[ L_order ];
00995     }
00996   }
00997   check_Legendre( false );  // ensure same E_gamma for all Legendre orders
00998   thinit( );
00999   renorm( );
01000 }
01001 // ----------- MF14_list::extra_contin -----------------
01002 void MF14_list::extra_contin( )
01003 // Delete any extra continuum incident energies.
01004 // We do this because there is no safe way to interpolate between
01005 // lists of discrete lines.  (Data are not always given for all lines.)
01006 {
01007   // pointer to the discrete data
01008   MF12_base::iterator disc_ptr = coefs_[ 0 ].begin();
01009 
01010   // pointers to the continuum data
01011   MF15_list::iterator contin_ptr = continuum_dist.begin( );
01012   MF15_list::iterator next_contin = contin_ptr;
01013   ++next_contin;
01014 
01015   const double EPS = Global.Value( "mf5_tol" );  // tolerance for mf5 data
01016   if( abs( disc_ptr->E_in( ) - contin_ptr->E_in( ) ) >
01017     EPS*contin_ptr->E_in( ) )
01018   {
01019     SevereError("MF14_list::extra_contin",
01020         "mf14 discrete and continuum lists should start together");
01021   }
01022 
01023   // go through the incident energies for the discrete data
01024   for(  ; disc_ptr != coefs_[ 0 ].end( ); )
01025   {
01026     if( disc_ptr->E_in( ) < ( 1.0 - EPS )*contin_ptr->E_in( ) )
01027     {
01028       // We have discrete data but no continuum data for this E_in
01029       SevereError("MF14_list::extra_contin",
01030         "For mf14 first expand the continuum data");
01031     }
01032     else if( disc_ptr->E_in( ) > ( 1.0 + EPS )*contin_ptr->E_in( ) )
01033     {
01034       // We have continuum data but no discrete data for this E_in
01035       continuum_dist.erase( contin_ptr );
01036       contin_ptr = next_contin;
01037       ++next_contin;
01038     }
01039     else
01040     {
01041       // E_in is the same for both discrete and continuum data
01042       contin_ptr = next_contin;
01043       ++next_contin;
01044       ++disc_ptr; 
01045     }
01046   }
01047 }
01048 // ----------- MF14_list::widen_jumps -----------------
01049 void MF14_list::widen_jumps( )
01050 // widen the jump discontinuities
01051 {
01052     Unimplemented("MF14_list::widen_jumps", "Write this code!");
01053 }
01054 // ----------- MF14_list::continuum -----------------
01055 void MF14_list::continuum( int NR, int NP )
01056 // read the mf15 file on continuum energy distributions
01057 {
01058   if( !with_mf15 )
01059   {
01060     SevereError("MF14_list::continuum","no mf15 file!");
01061   }
01062 
01063   // read the interpolation regions
01064   inFile->get_regions( NR, continuum_dist.multiple.NBT,
01065     continuum_dist.multiple.INT );
01066 
01067   if( (NR > 1) || (continuum_dist.multiple.INT[0] != 2) )
01068   {
01069     Unimplemented("MF14_list::continuum","Implement interpolation in mf14 continuum");
01070   }
01071   continuum_dist.multiple.read_data( NP, *inFile );
01072 
01073   // read the mf15 file
01074   continuum_dist.read_data( contin_file );
01075   continuum_dist.set_interp();  // set the interpolation rules
01076   {
01077     Info("MF14_list::continuum","Closing file "+endf_file_name( 15, ENDL.T )+"...");
01078   }
01079   contin_file.close( );
01080 }
01081 // ----------- MF14_list::check_Legendre -----------------
01082 void MF14_list::check_Legendre( bool halt_on_error )
01083 // ensure that we have the same E_gamma values for all Legendre
01084 // orders.
01085 {
01086   MF12_base::iterator E_in_ptr[ order_ + 1 ];
01087   int L_order;
01088   bool two_d_done = false;
01089   // start at the first incident energy for each Legendre order
01090   for( L_order = 0; L_order <= order_; ++L_order )
01091   {
01092     E_in_ptr[ L_order ] = coefs_[ L_order ].begin();
01093   }
01094   // loop through the lists by incident energy
01095   for( ; ; )
01096   {
01097     // first check the incident energies
01098     double e_in = E_in_ptr[ 0 ]->E_in( );
01099     for( L_order = 1; L_order <= order_; ++L_order )
01100     {
01101       if( E_in_ptr[ L_order ]->E_in( ) != e_in )
01102       {
01103         string msg("Incompatible E_in\n"+
01104             pastenum("  For order 0, E_in = ",e_in)+
01105             pastenum("  for order ",L_order)+
01106             pastenum(" E_in = ",E_in_ptr[ L_order ]->E_in( )));
01107         if (halt_on_error) SevereError("MF14_list::check_Legendre",msg);
01108         else Warning("MF14_list::check_Legendre",msg);
01109       }
01110     }
01111     // start at the begining of each list
01112     bool one_d_done = false;
01113     dd_list::iterator L_ptr[ order_ + 1 ];
01114     for( L_order = 0; L_order <= order_; ++L_order )
01115     {
01116       L_ptr[ L_order ] = E_in_ptr[ L_order ]->begin( );
01117     }
01118     // now scan the lists
01119     for( ; ; )
01120     {
01121       for( L_order = 1; L_order <= order_; ++L_order )
01122       {
01123         double close_enough = ENDL_EPSILON( L_ptr[ 0 ]->x );
01124         if( abs(L_ptr[ L_order ]->x != L_ptr[ 0 ]->x) > close_enough )
01125         {
01126           string msg(
01127             pastenum("Incompatible gamma energy for E_in: ",e_in)+         
01128             pastenum("\n  For order 0, E_gamma = ",L_ptr[ 0 ]->x)+
01129             pastenum("  for order ",L_order)+
01130             pastenum(" E_gamma = ",L_ptr[ L_order ]->x));
01131           if (halt_on_error) SevereError("MF14_list::check_Legendre",msg);
01132           else Warning("MF14_list::check_Legendre",msg);
01133         }
01134       }
01135       // go to the next (E_gamma, probability) pair
01136       for( L_order = 0; L_order <= order_; ++L_order )
01137       {
01138         ++L_ptr[ L_order ];
01139         if( L_ptr[ L_order ] == E_in_ptr[ L_order ]->end( ) )
01140         {
01141           one_d_done = true;  // there is no more data
01142         }
01143       }
01144       if( one_d_done )
01145       {
01146         break;
01147       }
01148     }
01149     // did the lists finish for all Legendre orders?
01150     for( L_order = 0; L_order <= order_; ++L_order )
01151     {
01152       if( L_ptr[ L_order ] != E_in_ptr[ L_order ]->end( ) )
01153       {
01154         string msg(
01155             pastenum("For E_in: ",e_in)+
01156             pastenum(" extra link E_gamma: ",L_ptr[ L_order ]->x)+
01157             pastenum(" for order: ",L_order));
01158         if (halt_on_error) SevereError("MF14_list::check_Legendre",msg);
01159         else Warning("MF14_list::check_Legendre",msg);
01160       }
01161     }
01162     // go to the list for the next incident energy
01163     for( L_order = 0; L_order <= order_; ++L_order )
01164     {
01165       ++E_in_ptr[ L_order ];
01166       if( E_in_ptr[ L_order ] == coefs_[ L_order ].end( ) )
01167       {
01168         two_d_done = true;  // there is no more data
01169       }
01170     }
01171     if( two_d_done )
01172     {
01173       break;
01174     }
01175   }
01176   // did the lists finish for all Legendre orders?
01177   for( L_order = 0; L_order <= order_; ++L_order )
01178   {
01179     if( E_in_ptr[ L_order ] != coefs_[ L_order ].end( ) )
01180     {
01181         string msg(
01182             pastenum("\n  Extra list E_in: ",E_in_ptr[ L_order ]->E_in( ))+
01183             pastenum(" for order: ",L_order));
01184         if (halt_on_error) SevereError("MF14_list::check_Legendre",msg);
01185         else Warning("MF14_list::check_Legendre",msg);
01186     }
01187   }
01188 }
01189 // ----------- MF14_list::print -----------------
01190 void MF14_list::print( )
01191 // print the lists for debugging purposes
01192 {
01193   for( int L_order = 0; L_order <= order_; ++L_order )
01194   {
01195     cout << "Legendre order: " << L_order << endl;
01196     coefs_[ L_order ].print( );
01197   }
01198 }
01199 // ----------- MF14_list::write_endl -----------------
01200 void MF14_list::write_endl( )
01201 // write an ENDL i=4 file.
01202 {
01203   ENDL.set_I_number( 4 );
01204 
01205   fstream endl_file;
01206   string file_name = ENDL.file_name;
01207 
01208   if ( ENDL.new_file() )
01209   {
01210     endl_file.open(file_name.c_str(),ios::out);
01211     Info("MF14_list::write_endl","Opening ENDL file "+file_name);
01212   }
01213   else
01214   {
01215     endl_file.open(file_name.c_str(),ios::out|ios::app);
01216     Info("MF14_list::write_endl","Appending ENDL file "+file_name);
01217   }
01218 
01219   //Shove the header info in
01220   endl_file << ENDL.header_line_1 << endl;
01221   endl_file << ENDL.header_line_2 << endl;
01222   endl_file.setf(ios::scientific,ios::floatfield);
01223 
01224   // print the data
01225   for( int L_count = 0; L_count <= order_; ++L_count )
01226   {
01227     coefs_[ L_count ].out_data( 4, endl_file, 1.0*L_count );
01228   }
01229 
01230   //Put on end of file/section line into output file
01231   endl_file << ENDL.eof_line << endl;
01232 
01233   //Finally, we close the output file
01234   Info("MF14_list::write_endl","Closing ENDL file "+file_name);
01235   endl_file.close();
01236 }
01237 
01238 // ********* for class MF14_split ****************
01239 // ----------- MF14_split::master -----------------
01240 void MF14_split::master( double awr, int NK, mf12_file *InFile,
01241   mf14_file *angle_file )
01242 // handle an mf12 multiplicity file (LO = 1) in the isotropic case
01243 {
01244   // save the input data
01245   movers.AWR = awr;
01246   mf12_NK = NK;
01247 
01248   Warning("MF14_split::master", "Printing only the isotropic component");
01249 
01250   // Use InFile for all of the mf12 input
01251   inFile = InFile;
01252   statics.inFile = InFile;
01253   raw_move.inFile = InFile;
01254   raw_static.inFile = InFile;
01255 
01256   // initialize the Booleans
01257   with_move = false;
01258   with_static = false;
01259   with_mf15 = false;
01260 
01261   // get the energy distributions
01262   read_data( );
01263   // brach according to the type of data
01264   if( NK == 1 )
01265   {
01266     //Here, there is a single gamma in from the reaction (except continuum)
01267     //The i=9 file is created in the write_xxxx routines with a 
01268     //multiplicity of one (or a ratio of cross sections).
01269     if( with_mf15 )
01270     {
01271       // there are only continuum distributions
01272       Info("MF14_split::master","mf14 continuum only");
01273       write_continuum( );
01274     }
01275     else if( with_static )
01276     {
01277       // there is just 1 line (static)
01278       Info("MF14_split::master","mf14 1 static line");
01279       write_static( );
01280     }
01281     else
01282     {
01283       // there is just 1 line (moving)
01284       Info("MF14_split::master","mf14 1 moving line");
01285       write_mover( );
01286     }
01287   }
01288   else
01289   {
01290     if( with_mf15 )
01291     {
01292       if( with_move )
01293       {
01294         Info("MF14_split::master", "mf14 continuum plus moving lines");
01295         move_w_contin( );
01296       }
01297       else
01298       {
01299         // static lines plus continuum
01300         Info("MF14_split::master","mf14 static lines plus continuum");
01301         plus_contin( );
01302       }
01303     }
01304     else if( with_move )
01305     {
01306       // continuum represented by moving lines
01307       Info("MF14_split::master","mf14 static lines plus movers");
01308       do_movers( );
01309     }
01310     else
01311     {
01312       // only static lines
01313       Info("MF14_split::master","mf14 static lines only");
01314       just_statics( );
01315     }
01316   }
01317 }
01318 // ********* for class MF14_c55_list *************
01319 // ----------- MF14_c55_list constructor ----------------
01320 MF14_c55_list::MF14_c55_list()
01321 {
01322 }
01323 // ----------- MF14_c55_list destructor ----------------
01324 MF14_c55_list::~MF14_c55_list()
01325 {
01326 }
01327 // ----------- MF14_c55_list::master -----------------
01328 void MF14_c55_list::master( mf14_file& inFile, int LTT, int NK, int NI )
01329 // Handle an anisotropic mf14 file; make a c55 file
01330 // LTT: Legendre flag
01331 // NK: number of anisotropic lines
01332 // NI: total number of lines
01333 {
01334   int num_to_do = NK - NI;
01335   double EG[ num_to_do ]; // the gamma energies
01336   int count;
01337   int start_at;
01338 
01339   ENDL.set_c_number(55);
01340   ENDL.set_yo(7);
01341   ENDL.set_x0(0.0);  // ENDL convention for Q of c55 gammas
01342 
01343   // skip the isotropic lines
01344   for( count = 0; count < NI; ++count )
01345   {
01346     double eg;
01347     inFile.discrete( &eg );
01348   }
01349 
01350   // the anisotropic data
01351   if( LTT == 1 )
01352   {
01353     Info("MF14_c55_list::master"," Doing mf14 Legendre for c55");
01354     // we have NK sets of Legendre data
01355     two_d_Legendre Legendre[ num_to_do ];
01356     for( count = 0; count < num_to_do; ++count )
01357     {
01358       EG[count] = make_Legendre( inFile,  Legendre[count] );
01359     }
01360 
01361     // write the data in order of increasing gamma energy
01362     start_at = num_to_do - 1;
01363     if ( EG[ start_at ] == 0.0 )
01364     {
01365       // this is continuum data
01366       ENDL.set_x1(0.0);
01367       ENDL.set_s_number(0);
01368       Legendre[ start_at ].write_endl(1);
01369       --start_at;
01370     }
01371     // write the discrete data
01372     ENDL.set_s_number(3);
01373     for( count = start_at; count >= 0; --count )
01374     {
01375       ENDL.set_x1( EG[ count ] );
01376       Legendre[ count ].write_endl(1); 
01377       ENDL.append = true;
01378     }     
01379   }
01380   else if( LTT == 2 )
01381   {
01382     // we have num_to_do sets of tabular data
01383     mf4_table tables[ num_to_do ];
01384     for( count = 0; count < num_to_do; ++count )
01385     {
01386       EG[count] = make_table( inFile, tables[count] );
01387     }
01388 
01389     // write the data in order of increasing gamma energy
01390     start_at = num_to_do - 1;
01391     if ( EG[ start_at ] == 0.0 )
01392     {
01393       // this is continuum data
01394       ENDL.set_x1(0.0);
01395       ENDL.set_s_number(0);
01396       tables[ start_at ].write_endl(1);
01397       --start_at;
01398     }
01399     // write the discrete data
01400     ENDL.set_s_number(3);
01401     for( count = start_at; count >= 0; --count )
01402     {
01403       ENDL.set_x1( EG[ count ] );
01404       tables[ count ].write_endl(1); 
01405       ENDL.append = true;
01406     }     
01407   }
01408   else
01409   {
01410     SevereError("MF14_list::master",pastenum("Bad LTT value ",LTT));
01411   }
01412 }
01413 // ----------- MF14_c55_list::make_Legendre -----------------
01414 double MF14_c55_list::make_Legendre( mf14_file& inFile,
01415   two_d_Legendre& Legendre )
01416 // make a Legendre list for one gamma.  Return the gamma energy
01417 {
01418   double EG; // the gamma energy
01419   int NR;    // number of interpolation regions
01420   int NE;    // number of incident energies
01421 
01422   inFile.read_EG( &EG, &NR, &NE );
01423   inFile.get_regions( NR, Legendre.NBT, Legendre.INT );
01424   Legendre.expand_data( inFile, NE, 4 ); //read/expand mf4 data
01425 
01426   // change to MeV
01427   return EG * ENDL.eV2MeV;
01428 }
01429 
01430 // ----------- MF14_c55_list::make_table -----------------
01431 double MF14_c55_list::make_table( mf14_file& inFile,
01432   mf4_table& table )
01433 // make a table list for one gamma.  Return the gamma energy
01434 {
01435   double EG; // the gamma energy
01436   int NR;    // number of interpolation regions
01437   int NE;    // number of incident energies
01438 
01439   inFile.read_EG( &EG, &NR, &NE );
01440   inFile.get_regions( NR, table.NBT, table.INT );
01441   table.read_data( inFile, NE ); //read data
01442 
01443   // change to MeV
01444   return EG * ENDL.eV2MeV;
01445 }
01446 

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