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

mf12classes.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: 1887 $
00029  * $Date: 2006-08-23 11:34:44 -0700 (Wed, 23 Aug 2006) $
00030  * $Author: dbrown $
00031  * $Id: mf12classes.cpp 1887 2006-08-23 18:34:44Z dbrown $
00032  * 
00033  * ******** fete: From ENDF To ENDL *********
00034  */
00035 
00036 // implementation of the mf12 class for 2-d linked lists
00037 
00038 #include <cmath>
00039 #include <map>
00040 
00041 #include "mf12classes.hpp"
00042 #include "endl_formats.hpp"
00043 #include "mf15classes.hpp"
00044 
00045 extern ENDLClass ENDL;
00046 extern GlobalParameterClass Global;
00047 extern map< int, cascade > cascade_gammas;
00048 
00049 // ********* for class MF12_base *************
00050 // ----------- MF12_base::read_mult -----------------
00051 //! handle the total gamma multiplicity
00052 void MF12_base::read_mult( multiplicity& multiple )
00053 {
00054   int NR, NP;
00055 
00056   inFile->read_line2(
00057     &NR, // number of interpolation regions
00058     &NP  // number of data points
00059   );          
00060 
00061   // read the interpolation information
00062   inFile->get_regions( NR, multiple.NBT, multiple.INT );
00063 
00064   //The first data is the total multiplicity
00065   multiple.read_data( NP, *inFile );
00066 }
00067 
00068 // ----------- MF12_base::find_link -----------------
00069 //! Find the 1-d list with incident energy E_in.
00070 MF12_base::iterator MF12_base::find_link(double E_in,
00071   double EG)
00072 {
00073   MF12_base::iterator e_in_link = begin();
00074 
00075   while( e_in_link->E_in() < E_in )
00076   {
00077     ++e_in_link;
00078 
00079     if(e_in_link == end())
00080     {
00081       SevereError("MF12_base::find_link",
00082         pastenum("mf12 incident energy ",E_in)+" not found");
00083     }
00084   }
00085   // check for data omission in the total multiplicity
00086   if( e_in_link->E_in() > E_in )
00087   {
00088     Warning("MF12_base::find_link",pastenum("for discrete gamma: ",EG)+
00089         pastenum(" there is an extra mf12 incident energy: " ,E_in));
00090     e_in_link = end();
00091   }
00092   return e_in_link;
00093 }
00094 
00095 // ----------- MF12_base::shift_gammas -----------------
00096 //! Shift the gamma energies according to the atomic weight
00097 void MF12_base::shift_gammas( )
00098 {
00099   for( MF12_base::iterator e_in_link = begin();
00100     e_in_link != end( ); ++e_in_link )
00101   {
00102     // add this to each gamma energy
00103     double increment = ( AWR / ( AWR + 1 ) ) * e_in_link->E_in();
00104     dd_list::iterator next_ptr = e_in_link->begin( );
00105     ++next_ptr;
00106     for( dd_list::iterator link_ptr = e_in_link->begin( );
00107       link_ptr != e_in_link->end( ); link_ptr = next_ptr, ++next_ptr )
00108     {
00109       link_ptr->x += increment;
00110       if( link_ptr->x > ENDL.Max_E_out )
00111       {
00112         e_in_link->erase( link_ptr );
00113       }
00114     }
00115   }
00116 }
00117 
00118 // ----------- MF12_base::set_weights -----------------
00119 //! set the weights for the discrete spectra
00120 void MF12_base::set_weights( multiplicity& multiple )
00121 {
00122   double e_in;
00123   double num;
00124   double denom;
00125   double fract;
00126 
00127   for( MF12_base::iterator list_ptr = begin( );
00128        list_ptr != end( ); ++list_ptr )
00129   {
00130     e_in = list_ptr->E_in( );
00131     // get the multiplicity of the lines
00132     num = list_ptr->line_multiple( );
00133     // get the total gamma multiplicity
00134     denom = multiple.evaluate( e_in );
00135     if( denom == 0.0 )
00136     {
00137       fract = 0.0;
00138     }
00139     else
00140     {
00141       fract = num/denom;
00142     }
00143     if( fract < 0.0 )
00144     {
00145       SevereError("MF12_base::set_weights",pastenum("bad weight: ",fract));
00146     }
00147     else if( fract > 1.0 )
00148     {
00149       Info("MF12_base::set_weights",
00150         pastenum("line multiplicity too big: ",fract)+", setting to 1.0");
00151       fract = 1.0;
00152     }
00153     list_ptr->weight = fract;
00154   }
00155 }
00156 
00157 // ----------- MF12_base::weight_mult -----------------
00158 //! set the weights for the discrete spectra and save their multiplicities
00159 void MF12_base::weight_mult( multiplicity& multiple, multiplicity& line_mult )
00160 {
00161   double e_in;
00162   double num;
00163   double denom;
00164   double fract;
00165   dd_link XYdata;  // for adding links to line_mult
00166 
00167   for( MF12_base::iterator list_ptr = begin( );
00168        list_ptr != end( ); ++list_ptr )
00169   {
00170     e_in = list_ptr->E_in( );
00171     // get the multiplicity of the lines
00172     num = list_ptr->line_multiple( );
00173 
00174     // save this multiplicity
00175     XYdata.x = e_in;
00176     XYdata.y = num;
00177     line_mult.insert( line_mult.end( ), XYdata );
00178 
00179     // get the total gamma multiplicity
00180     denom = multiple.evaluate( e_in );
00181     if( denom == 0.0 )
00182     {
00183       fract = 0.0;
00184     }
00185     else
00186     {
00187       fract = num/denom;
00188     }
00189     if( ( fract < 0.0 ) || ( fract > 1.0 ) )
00190     {
00191       SevereError("MF12_base::weight_mult",pastenum("bad weight: ",fract));
00192     }
00193     list_ptr->weight = fract;
00194   }
00195 }
00196 
00197 // ----------- MF12_base::widen_deltas -----------------
00198 //! Widen all of the delta-functions.
00199 //! if clean_up is true, delete 1-d lists with zero norm
00200 void MF12_base::widen_deltas( bool clean_up )
00201 {
00202   MF12_base::iterator e_in_link = begin();
00203   MF12_base::iterator next_link = e_in_link;
00204   ++next_link;
00205 
00206   for( ; e_in_link != end( ); e_in_link = next_link, ++next_link )
00207   {
00208     e_in_link->widen_delta( );
00209     double Norm = e_in_link->get_norm( );
00210 
00211     // do we separate continuum from discrete gammas?
00212     if( Global.Value( "split_gammas" ) > 0 )
00213     {
00214       // for the multiplicity list
00215       dd_link XYdata;
00216       XYdata.x = e_in_link->E_in();
00217       XYdata.y = Norm;
00218       multiple.insert( multiple.end(), XYdata );
00219     }
00220 
00221     if( Norm > 0.0 )
00222     {
00223       e_in_link->renorm( Norm );
00224     }
00225     else if( clean_up )
00226     {
00227       erase( e_in_link );
00228     }
00229   }
00230 }
00231 
00232 // ----------- MF12_base::init_list -----------------
00233 //! initialize the ENDL list from raw_list
00234 void MF12_base::init_list( MF12_raw& raw_list )
00235 {
00236   // initialize the 2-d lists of energy distributions using
00237   // the incident neutron energies from raw_list
00238   MF12_raw::iterator first_raw = raw_list.begin( );
00239   for( dd_list::iterator raw_ptr = first_raw->begin( );
00240     raw_ptr != first_raw->end( ); ++raw_ptr )
00241   {
00242     one_d_table new_link;
00243     new_link.E_in( ) = raw_ptr->E_in( );
00244     insert( end( ), new_link );
00245   }
00246 }
00247 
00248 // ----------- MF12_base::join_lines -----------------
00249 //! If two adjacent lines have the same frequency, this routine adds their intensities.
00250 void MF12_base::join_lines( )
00251 {
00252   // loop over the gamma energies
00253   for( MF12_base::iterator E_gam_ptr = begin( );
00254        E_gam_ptr != end( ); ++E_gam_ptr )
00255   {
00256     E_gam_ptr->join_lines( );
00257   }
00258 }
00259 
00260 // ********* for class MF12_raw *************
00261 // ----------- MF12_raw::one_line -----------------
00262 void MF12_raw::one_line( double EG, int NR, int NP )
00263 // Read the data for one gamma with energy EG
00264 {
00265   dd_link XYdata;
00266   string linebuff;
00267   string strbuff;
00268 
00269   MF12_raw::iterator e_in_link;
00270   double E_in;
00271   double Prob;
00272 
00273   // keep the line if EG <= Max_g_energy (max outgoing energy for gammas)
00274   bool keepit = ( EG <= Global.Value( "Max_g_energy" ) );
00275 
00276   // compare with the maximum incident energy
00277   bool big_E_in = false;
00278   double dE = ENDL_EPSILON( ENDL.Max_E_in );
00279 
00280   // The gamma energies are in descending order
00281   multiplicity new_EG;
00282   MF12_raw::iterator new_EG_ptr;
00283 
00284   new_EG.E_gamma( ) = EG;
00285   if( keepit )
00286   {
00287     insert( begin( ), new_EG );
00288     // point to the new list
00289     new_EG_ptr = begin( );
00290     // read the interpolation regions
00291     inFile->get_regions( NR, new_EG_ptr->NBT, new_EG_ptr->INT );
00292   }
00293   else
00294   {
00295     Warning("MF12_raw::one_line",pastenum("Line above Max_g_energy, check that line not cut off.  EG = ",EG));
00296     // read and discard the interpolation regions
00297     inFile->get_regions( NR, new_EG.NBT, new_EG.INT );
00298   }
00299 
00300   // read the data for this line
00301   for( int iNP=0; iNP < NP; iNP++ ) //Loop over NP data pairs
00302   { 
00303     int iP=iNP % 3;  //There are 3 pairs per line
00304     if ( iP == 0 )
00305     {
00306       getline( *inFile, linebuff ); //Read in new line
00307     }
00308     strbuff = linebuff.substr(iP*22, 22);
00309     read_dd(&strbuff, &E_in, &Prob );
00310     if ( E_in==-999.0 || Prob==-999.0 ) //read_PAIR sends -999.0 if problem
00311     {
00312       SevereError("MF12_raw::one_line","read_PAIR fucked up!");
00313     }
00314     if( keepit && !big_E_in )
00315     {
00316       E_in *= ENDL.eV2MeV;
00317       XYdata.x = E_in;
00318       XYdata.y = Prob;
00319       new_EG_ptr->insert( new_EG_ptr->end( ), XYdata );
00320       // is this incident energy too big?
00321       if( E_in > ENDL.Max_E_in - dE )
00322       {
00323         new_EG_ptr->expand_interp( ENDL.Max_E_in );
00324         big_E_in = true;
00325         new_EG_ptr->chop( ENDL.Max_E_in );
00326       }
00327     }
00328   }
00329   if( keepit )
00330   {
00331     // expand histogram data
00332     new_EG_ptr->expand_interp( ENDL.Max_E_in );
00333     // the data may have jumps
00334     new_EG_ptr->widen_jumps( );
00335   }
00336 }
00337 
00338 // ----------- MF12_raw::fill_raw_lists -----------------
00339 void MF12_raw::fill_raw_lists( )
00340 // make sure that if any gamma energy has a
00341 // ( E_in, multiplicity ) pair for some E_in, then all of
00342 // the lists contain this E_in.
00343 {
00344   // first widen the jumps
00345   widen_jumps( );
00346 
00347   // Build a list of incident energies by combining the incident energies of all the gammas
00348   list< double > E_incident;
00349   for (MF12_raw::iterator gamma_ptr = begin( ); gamma_ptr != end( ); ++gamma_ptr )
00350   {
00351     for (multiplicity::iterator itr=gamma_ptr->begin();itr!=gamma_ptr->end(); ++itr) 
00352       E_incident.push_back(itr->x);
00353   }
00354   E_incident.unique();
00355   E_incident.sort();
00356 
00357   // now ensure common E_in values in all of the gamma lists
00358   for( MF12_raw::iterator gamma_ptr = begin( );
00359       gamma_ptr != end( ); ++gamma_ptr )
00360   {
00361     for (list<double>::iterator Eitr=E_incident.begin(); Eitr!=E_incident.end();
00362     ++Eitr)
00363     {
00364       dd_list::iterator next_link = gamma_ptr->find_next(*Eitr);
00365       if ((next_link==gamma_ptr->end()) || (next_link->x != *Eitr))
00366         gamma_ptr->insert(next_link,dd_link(*Eitr,gamma_ptr->evaluate(*Eitr)));
00367     }
00368   }
00369 }
00370 
00371 // ----------- MF12_raw::fill_raw_lists -----------------
00372 void MF12_raw::fill_raw_lists( MF15_list& cont_data )
00373 // make sure that the ( E_in, multiplicity ) pairs in the
00374 // ENDF raw list have E_in values matching the E_in tags
00375 // in cont_data.
00376 {
00377   list<double>::iterator Eitr;
00378   
00379   // Build a list of incident energies by combining the incident energies of all the gammas and continuum
00380   list< double > E_incident;
00381   cont_data.collect_Ein(E_incident);
00382   for (MF12_raw::iterator gamma_ptr = begin( ); gamma_ptr != end( ); ++gamma_ptr )
00383   {
00384     for (multiplicity::iterator itr=gamma_ptr->begin();itr!=gamma_ptr->end(); ++itr) 
00385       E_incident.push_back(itr->x);
00386   }
00387   E_incident.unique();
00388   E_incident.sort();
00389 
00390   // now ensure common E_in values in all of the gamma lists
00391   for( MF12_raw::iterator gamma_ptr = begin( );
00392       gamma_ptr != end( ); ++gamma_ptr )
00393   {
00394     for (Eitr=E_incident.begin(); Eitr!=E_incident.end(); ++Eitr)
00395     {
00396       dd_list::iterator next_link = gamma_ptr->find_next(*Eitr);
00397       if ((next_link==gamma_ptr->end()) || (next_link->x != *Eitr))
00398         gamma_ptr->insert(next_link,dd_link(*Eitr,gamma_ptr->evaluate(*Eitr)));
00399     }
00400   }
00401 
00402   E_incident.unique(); // somehow need to redo it??
00403 
00404   // now ensure common E_in values in are also in the continuum data, contin_data
00405   Eitr = E_incident.begin( );
00406   for(MF15_list::iterator cont_ptr = cont_data.begin( );
00407        ( cont_ptr != cont_data.end( ) ) &&
00408        ( Eitr != E_incident.end( ) ); )
00409   {
00410     if( cont_ptr->E_in( ) < *Eitr )
00411     {
00412       // go to the next
00413       ++cont_ptr;
00414     }
00415     else if( cont_ptr->E_in( ) == *Eitr )
00416     {
00417       // just go to the next links
00418       ++cont_ptr;
00419       ++Eitr;
00420     }
00421     else //  cont_ptr->E_in( ) > *Eitr
00422     {
00423       // insert an intermediate list
00424       one_d_table new_continuum;
00425       cont_data.insert( cont_ptr, new_continuum );
00426       MF15_list::iterator insert_ptr = cont_ptr;
00427       --insert_ptr;  // now points to the new link
00428       insert_ptr->E_in( ) = *Eitr;
00429       MF15_list::iterator prev_ptr = insert_ptr;
00430       --prev_ptr;
00431       insert_ptr->list_interp( *Eitr, *prev_ptr, *cont_ptr );
00432       ++Eitr;
00433     }
00434   }
00435 }
00436 
00437 // ----------- MF12_raw::insert_cross -----------------
00438 void MF12_raw::insert_cross( list< double >& crossings )
00439 // insert ( E_in, multiplicity ) pairs for each of the crossings
00440 // neutron energies
00441 {
00442   // loop over the gamma energies
00443   for( MF12_raw::iterator E_gam_ptr = begin( );
00444     E_gam_ptr != end( ); ++E_gam_ptr )
00445   {
00446     list< double >::iterator cross_ptr = crossings.begin( );
00447     dd_list::iterator prev_ptr = E_gam_ptr->begin( );
00448     dd_list::iterator next_ptr = prev_ptr;
00449     ++next_ptr;
00450 
00451     double E_prev = prev_ptr->x;
00452     double E_next = next_ptr->x;
00453     double E_cross = *cross_ptr;
00454     // scan the lists
00455     for( ; ; )
00456     {
00457       if( E_cross < (1 - EPS)*E_prev )
00458       {
00459         ++cross_ptr;
00460         E_cross = *cross_ptr;
00461       }
00462       else if( E_cross < (1 + EPS)*E_prev )
00463       {
00464     // we essentially have equality
00465         ++cross_ptr;
00466         E_cross = *cross_ptr;
00467       }
00468       else if( E_cross < (1 - EPS)*E_next )
00469       {
00470     // are between 2 neutron energies
00471     // insert a new link
00472         dd_link XYdata;
00473         XYdata.x = E_cross;
00474         XYdata.y = E_gam_ptr->interp( E_cross, *prev_ptr, *next_ptr,
00475           E_gam_ptr->INT[ 0 ] );
00476         E_gam_ptr->insert( next_ptr, XYdata );
00477         E_prev = E_cross;
00478         ++prev_ptr;
00479         ++cross_ptr;
00480         E_cross = *cross_ptr;
00481       }
00482       else if( E_cross < (1 + EPS)*E_next )
00483       {
00484     // we essentially have equality
00485         ++cross_ptr;
00486         E_cross = *cross_ptr;
00487         prev_ptr = next_ptr;
00488         ++next_ptr;
00489         E_prev = E_next;
00490         E_next = next_ptr->x;
00491       }
00492       else
00493       {
00494     // E_cross > E_next
00495         prev_ptr = next_ptr;
00496         ++next_ptr;
00497         E_prev = E_next;
00498         E_next = next_ptr->x;
00499       }
00500       // are we done?
00501       if( ( cross_ptr == crossings.end( ) ) ||
00502           ( next_ptr == E_gam_ptr->end( ) ) )
00503       {
00504         break;
00505       }
00506     }
00507   }
00508 }
00509 // ----------- MF12_raw::duplicate_E -----------------
00510 void MF12_raw::duplicate_E( )
00511 // ENDF/B-VI sometimes has duplicate gamma lines from
00512 // different cascades.  We combine them
00513 {
00514   MF12_raw::iterator this_link = begin();
00515   MF12_raw::iterator next_link = this_link;
00516   ++next_link;
00517 
00518   // go through the list
00519   for( ; next_link != end( ); )
00520   {
00521     if( next_link->E_gamma( ) == this_link->E_gamma( ) )
00522     {
00523       // combine these lists
00524       (*this_link) += (*next_link);
00525       erase( next_link );
00526     }
00527     else
00528     {
00529       // test the next one
00530       ++this_link;
00531     }
00532     // update the next link
00533     next_link = this_link;
00534     ++next_link;
00535   }
00536 }
00537 
00538 // ********* for class MF12_list *************
00539 // ----------- MF12_list::master -----------------
00540 void MF12_list::master( double awr, int NK, mf12_file *InFile )
00541 // handle an mf12 multiplicity file (LO = 1) in the isotropic case
00542 {
00543   // save the input data
00544   movers.AWR = awr;
00545   mf12_NK = NK;
00546 
00547   // Use InFile for all of the mf12 input
00548   inFile = InFile;
00549   statics.inFile = InFile;
00550   raw_move.inFile = InFile;
00551   raw_static.inFile = InFile;
00552 
00553   // initialize the Booleans
00554   with_move = false;
00555   with_static = false;
00556   with_mf15 = false;
00557 
00558   // get the energy distributions
00559   read_data( );
00560 
00561   // proceed according to the type of data
00562   if( NK == 1 )
00563   {
00564     //Here, there is a single gamma from the reaction (except continuum)
00565     //The i=9 file is created in the write_xxxx routines with a 
00566     //multiplicity of one (or a ratio of cross sections).
00567     if( with_mf15 )
00568     {
00569       // there are only continuum distributions
00570       Info("MF12_list::master","mf12 continuum only");
00571       write_continuum( );
00572     }
00573     else if( with_static )
00574     {
00575       // there is just 1 line (static)
00576       Info("MF12_list::master","mf12 1 static line");
00577       write_static( );
00578     }
00579     else
00580     {
00581       // there is just 1 line (moving)
00582       Info("MF12_list::master","mf12 1 moving line");
00583       write_mover( );
00584     }
00585   }
00586   else
00587   {
00588     if( with_mf15 )
00589     {
00590       if( with_move )
00591       {
00592         // moving lines plus continuum
00593         Info("MF12_list::master","mf12 moving lines plus continuum");
00594         move_w_contin( );
00595       }
00596       else
00597       {
00598         // static lines plus continuum
00599         Info("MF12_list::master","mf12 static lines plus continuum");
00600         plus_contin( );
00601       }
00602     }
00603     else if( with_move )
00604     {
00605       // continuum represented by moving lines
00606       Info("MF12_list::master","mf12 static lines plus movers");
00607       do_movers( );
00608     }
00609     else
00610     {
00611       // only static lines
00612       Info("MF12_list::master","mf12 static lines only");
00613       just_statics( );
00614     }
00615   }
00616 }
00617 // ----------- MF12_list::read_data -----------------
00618 void MF12_list::read_data( )
00619 // This routine is used to read in ENDF/B-VI probabilities
00620 // of discrete gammas,
00621 // mf12_NK is the number of data sets, discrete gammas + continuum
00622 {
00623   double EG; // gamma energy
00624   double ES; // nucleus excitation level
00625   int LP;    // 2: put into the raw_move list
00626              // 0, 1: stationary gamma
00627   int LF;    // 2 for discrete; 1 for continuum (in MF15 file)
00628   int NR;    // number of interpolation regions
00629   int NP;    // number of incident energies
00630 
00631   if( mf12_NK > 1 )
00632   {
00633     // the first block is the total multiplicity
00634     read_mult( multiple );
00635 
00636     if( ENDL.F == 13 )  //Need to convert cross section to multiplicity
00637     {
00638       multiple.divide_by_xs();
00639     }
00640   }
00641   
00642   for(int count = 0; count < mf12_NK; ++count)
00643   {
00644     inFile->gamma_line1(
00645       &EG,     // gamma energy
00646       &ES,     // excitation level
00647       &LP,     // energy-dependent gamma?
00648       &LF,     // discrete-continuum flag
00649       &NR,     // number of interpolation regions
00650       &NP      // number of (E, multiplicity) pairs
00651     );
00652 
00653     // change to MeV
00654     EG *= ENDL.eV2MeV;
00655     if(LF == 1)
00656     {
00657       // this data is for the continuum, read the mf15 file
00658       with_mf15 = true;
00659       continuum( NR, NP );
00660       break; // we should be done
00661     }
00662     else if( LP == 2 )
00663     {
00664       // a gamma to shift
00665       with_move = true;
00666       raw_move.one_line( EG, NR, NP );
00667     }
00668     else
00669     {
00670       // a fixed gamma
00671       with_static = true;
00672       raw_static.one_line( EG, NR, NP );
00673     }
00674   }
00675 }
00676 // ----------- MF12_list::clean_multiple -----------------
00677 void MF12_list::clean_multiple( MF12_base& statics )
00678 // make sure that the multiplicity is 0 if there is no distribution
00679 {
00680   multiplicity::iterator this_ptr = multiple.begin( );
00681   double first_E = statics.begin( )->E_in( );
00682 
00683   if( this_ptr->x < first_E )
00684   {
00685     for( ; this_ptr->x < first_E; ++this_ptr )
00686     {
00687       if( this_ptr == multiple.end( ) )
00688       {
00689         SevereError("MF12_list::clean_multiple","Unexplained failure");
00690       }
00691       this_ptr->x = first_E;
00692       this_ptr->y = 0.0;
00693     }
00694   }
00695 }
00696 // ----------- MF12_list::write_continuum -----------------
00697 void MF12_list::write_continuum( )
00698 // write only the continuum data
00699 {
00700   if( ENDL.F == 13 )
00701   {
00702     // convert from photon production cross section to multiplicity
00703     cont_data.multiple.divide_by_xs();
00704   }
00705   cont_data.multiple.widen_jumps();
00706   ENDL.set_yo( 7 );
00707   cont_data.multiple.write_endl( 9 );
00708   cont_data.widen_jumps();
00709   cont_data.renorm();
00710   cont_data.write_endl( 4 );
00711 }
00712 // ----------- MF12_list::write_statics -----------------
00713 void MF12_list::write_statics( )
00714 // write the static lines
00715 {
00716   ENDL.set_yo( 7 );
00717   ENDL.set_s_number( 3 );
00718   ENDL.set_I_number( 9 );
00719 
00720   fstream endl_file;
00721   string file_name = ENDL.file_name;
00722 
00723   // combine duplicate lines
00724   raw_static.duplicate_E( );
00725 
00726   //Now loop over the raw static lines
00727   for( MF12_raw::iterator link = raw_static.begin();
00728      link != raw_static.end(); ++link)
00729   {
00730     // reset the header lines
00731     ENDL.set_x1( link->E_gamma() );
00732 
00733     if( ENDL.F == 13 )  //Need to convert cross section to multiplicity
00734     {
00735       link->divide_by_xs();
00736     }
00737 
00738     // print the multiplicity
00739     link->write_endl( 9 );
00740 
00741     // append the rest of the data
00742     ENDL.append = true;
00743   }
00744   //Reset "append"
00745   ENDL.append = false;
00746 
00747 }
00748 // ----------- MF12_list::write_static -----------------
00749 void MF12_list::write_static( )
00750 // write the one static line
00751 {
00752   statics.init_list( raw_static ); // initialize the ENDL list
00753   // copy the mf12 data into ENDL order
00754   ENDL_order( raw_static, statics );
00755   statics.join_lines( );    // join any repeated lines
00756   statics.widen_deltas( true );  // widen the delta-functions
00757 
00758   ENDL.set_yo( 7 );
00759   // clean up and write out
00760   statics.widen_jumps();
00761   statics.renorm();
00762   statics.write_endl( 4 );
00763 
00764   //Since this routine only gets called when there is a single gamma...
00765   if( !multiple.empty( ) )
00766   {
00767     SevereError("MF12_list::write_static",
00768         " there should be no total multiplicity" );
00769   }
00770 
00771   // raw_static has just 1 multiplicity list
00772   MF12_raw::iterator mult_list = raw_static.begin( );
00773   mult_list->widen_jumps( );
00774   if( ENDL.F == 13 )  //Need to convert cross section to multiplicity
00775   {
00776     mult_list->divide_by_xs( );
00777   }
00778 
00779   mult_list->check_count( );   // Is multiplicity <= 1?
00780   mult_list->write_endl( 9 );  //Write the ENDL file
00781 }
00782 // ----------- MF12_list::write_mover -----------------
00783 void MF12_list::write_mover( )
00784 // write the one moving line
00785 {
00786   movers.init_list( raw_move ); // initialize the ENDL list
00787   // copy the mf12 data into ENDL order
00788   ENDL_order( raw_move, movers );
00789   movers.join_lines( );    // join any repeated lines
00790   movers.widen_deltas( true );  // widen the delta-functions
00791 
00792   // move the moving line
00793   movers.shift_gammas( );
00794   
00795   // clean up and write out
00796   ENDL.set_yo( 7 );
00797   movers.widen_jumps();
00798   movers.renorm();
00799   movers.write_endl( 4 );
00800 
00801   //Since this routine only gets called when there is a single gamma...
00802   MF12_raw::iterator mult_list = raw_move.begin( );
00803   mult_list->widen_jumps( );
00804   if( ENDL.F == 13 )  //Need to convert cross section to multiplicity
00805   {
00806     mult_list->divide_by_xs( );
00807   }
00808 
00809   mult_list->write_endl( 9 );  //Write the ENDL file
00810 }
00811 // ----------- MF12_list::plus_contin -----------------
00812 void MF12_list::plus_contin( )
00813 // there is mf15 continuum plus static lines
00814 {
00815   if( Global.Value( "split_gammas" ) > 0 )
00816   {
00817     // s=3 is used when there are separate discrete gammas
00818     ENDL.set_s_number( 3 );
00819 
00820     // write the continuum
00821     write_continuum( );
00822 
00823     // write the static lines
00824     ENDL.append = true;
00825     write_statics( );
00826   }
00827   else
00828   {
00829     // ensure that we have 2-d links for all energies
00830     raw_static.fill_raw_lists( cont_data );
00831 
00832     statics.init_list( raw_static ); // initialize the ENDL lists
00833 
00834     // copy the mf12 data into ENDL order
00835     ENDL_order( raw_static, statics );
00836     statics.join_lines( );    // join any repeated lines
00837 
00838     // set the weights for the discrete lines
00839     statics.set_weights( multiple );
00840 
00841     // widen the delta-functions
00842     // keep the ones with zero norm---they may have continuum data
00843     statics.widen_deltas( false );
00844 
00845 //    // make sure that the mf15 data has all of the statics energies
00846 //    list< double > E_incident;
00847 //    statics.collect_Ein( E_incident );
00848 //    cont_data.collect_Ein( E_incident );
00849 //    E_incident.sort( );
00850 //    E_incident.unique( );
00851 //    cont_data.fill_in_list( E_incident );
00852 
00853     // set the weights for continuum
00854     set_mf15_wt( );
00855 
00856     // weight the statics
00857     statics.use_weight( );
00858 
00859     // do the weighted sum
00860     sum_lists( statics, cont_data ); 
00861 
00862     // data clean up and final output
00863     statics.widen_jumps( );
00864     statics.renorm();
00865     ENDL.set_yo( 7 );
00866     statics.write_endl( 4 );
00867 
00868     // make sure that the multiplicity is 0 if there is no distribution
00869     clean_multiple( statics );
00870 
00871     // print the multiplicities
00872     multiple.widen_jumps( );
00873     multiple.write_endl( 9 );
00874   }
00875 }
00876 // ----------- MF12_list::join_move_static -----------------
00877 void MF12_list::join_move_static( )
00878 // join the moving lines with the static ones
00879 {
00880   // ensure that we have 2-d links for all energies
00881   raw_static.fill_raw_lists( );
00882   raw_move.fill_raw_lists( );
00883 
00884   find_crossings( );  // where moving and static energies coincide
00885   statics.init_list( raw_static ); // initialize the ENDL lists
00886   movers.init_list( raw_static ); // initialize the ENDL lists
00887 
00888   // copy the mf12 data into ENDL order
00889   ENDL_order( raw_static, statics );
00890   ENDL_order( raw_move, movers );
00891 
00892   // move the moving lines
00893   movers.shift_gammas( );
00894 
00895   // weight the statics
00896   statics.use_weight( );
00897   // form the line sum
00898   sum_lines( statics, movers );
00899   statics.join_lines( );    // join any repeated lines
00900 }
00901 // ----------- MF12_list::move_w_contin -----------------
00902 void MF12_list::move_w_contin( )
00903 // there is mf15 continuum plus moving lines plus maybe static lines
00904 {
00905   if( ( Global.Value( "split_gammas" ) > 0 ) || !with_static )
00906   {
00907     // a list for the multiplicity of the movers
00908     multiplicity move_mult;
00909 
00910     // combine the moving discrete gammas with the continuum
00911     // ensure that we have 2-d links for all energies
00912     raw_move.fill_raw_lists( cont_data );
00913 
00914     movers.init_list( raw_move ); // initialize the ENDL lists
00915 
00916     // copy the mf12 data into ENDL order
00917     ENDL_order( raw_move, movers );
00918 
00919     // set the weights of the movers and save their multiplicities
00920     movers.weight_mult( multiple, move_mult );
00921 
00922     // move the moving lines
00923     movers.shift_gammas( );
00924 
00925     // widen the delta-functions
00926     // keep the ones with zero norm---they may have continuum data
00927     movers.widen_deltas( false );
00928 
00929     set_mf15_wt( );   // set the weights for the continuum
00930 
00931 //    // make sure that the mf15 data has all of the movers energies
00932 //    list< double > E_incident;
00933 //    movers.collect_Ein( E_incident );
00934 //    cont_data.collect_Ein( E_incident );
00935 //    E_incident.sort( );
00936 //    E_incident.unique( );
00937 //    cont_data.fill_in_list( E_incident );
00938 
00939     // weight the movers
00940     movers.use_weight( );
00941     
00942     // do the weighted sum
00943     sum_lists( movers, cont_data ); 
00944 
00945     // write the continuum
00946     ENDL.set_yo( 7 );
00947     if( with_static )
00948     {
00949       // s=3 is used when there are separate discrete gammas
00950       ENDL.set_s_number( 3 );
00951     }
00952 
00953     // data clean up and final output
00954     movers.widen_jumps( );
00955     movers.renorm( );
00956     movers.write_endl( 4 );
00957 
00958     // get the multiplicity
00959     move_mult += cont_data.multiple;
00960 
00961     if( ENDL.F == 13 )
00962     {
00963       // convert from photon production cross section to multiplicity
00964       move_mult.divide_by_xs();
00965     }
00966     move_mult.widen_jumps();
00967 
00968     ENDL.set_yo( 7 );
00969     move_mult.write_endl( 9 );
00970 
00971     // write the static lines
00972     if( with_static )
00973     {
00974       ENDL.append = true;
00975       write_statics( );
00976     }
00977   }
00978   else
00979   {
00980     // make sure that one line has all of the energies from the continuum
00981     list< double > E_contin;
00982     cont_data.collect_Ein( E_contin );
00983     raw_static.begin( )->collect_E_in( E_contin );
00984     E_contin.sort( );
00985     E_contin.unique( );
00986 
00987     raw_static.begin( )->fill_with( E_contin );
00988 
00989     // combine the static lines with the moving ones
00990     join_move_static( );
00991 
00992     // set the weights for continuum and discrete lines
00993     set_mf15_wt( );
00994 
00995     statics.widen_deltas( false );  // widen the delta-functions
00996 
00997     // make sure that the mf15 data has all of the energies from the lines
00998     list< double > E_incident;
00999     statics.collect_Ein( E_incident );
01000     cont_data.collect_Ein( E_incident );
01001     E_incident.sort( );
01002     E_incident.unique( );
01003     cont_data.fill_in_list( E_incident );
01004 
01005     // weight the lines
01006     statics.use_weight( );
01007     sum_lists( statics, cont_data ); // do the weighted sum
01008 
01009     // data clean up and final output
01010     ENDL.set_yo( 7 );
01011     statics.renorm( );
01012     statics.write_endl( 4 );
01013 
01014     // make sure that the multiplicity is 0 if there is no distribution
01015     clean_multiple( statics );
01016 
01017     // print the multiplicities
01018     multiple.widen_jumps( );
01019     multiple.write_endl( 9 );
01020   }
01021 }
01022 // ----------- MF12_list::do_movers -----------------
01023 void MF12_list::do_movers( )
01024 // there are moving lines
01025 {
01026   if( Global.Value( "split_gammas" ) > 0 )
01027   {
01028     // separate the discrete gammas from the continuum
01029 
01030     // ensure that we have 2-d links for all energies
01031     raw_move.fill_raw_lists( );
01032 
01033     movers.init_list( raw_move ); // initialize the ENDL lists
01034 
01035     // copy the mf12 data into ENDL order
01036     ENDL_order( raw_move, movers );
01037 
01038     // move the moving lines
01039     movers.shift_gammas( );
01040     
01041     // join any repeated lines
01042     movers.join_lines( );    
01043 
01044     // widen the delta-functions and sum the multiplicities
01045     movers.widen_deltas( true );  
01046 
01047     // clean up and output
01048     ENDL.set_yo( 7 );
01049     ENDL.set_s_number( 3 );
01050     movers.widen_jumps(  );  
01051     movers.renorm();
01052     movers.write_endl( 4 );
01053     // print the multiplicities of movers
01054     if( ENDL.F == 13 )  //Need to convert cross section to multiplicity
01055     {
01056       movers.multiple.divide_by_xs();
01057     }
01058     movers.multiple.widen_jumps( );
01059     movers.multiple.write_endl( 9 );
01060 
01061     // append the static lines
01062     ENDL.append = true;
01063     write_statics( );
01064   }
01065   else
01066   {
01067     // first combine the static lines with the moving ones
01068     join_move_static( );
01069     statics.widen_deltas( true );  // widen the delta-functions
01070 
01071     // clean up and output
01072     ENDL.set_yo( 7 );
01073     statics.widen_jumps();
01074     statics.renorm();
01075     statics.write_endl( 4 );
01076 
01077     // make sure that the multiplicity is 0 if there is no distribution
01078     clean_multiple( statics );
01079 
01080     // print the multiplicities
01081     multiple.widen_jumps( );
01082     multiple.write_endl( 9 );
01083   }
01084 }
01085 // ----------- MF12_list::just_statics -----------------
01086 void MF12_list::just_statics( )
01087 // write the static lines
01088 {
01089   if( Global.Value( "split_gammas" ) > 0 )
01090   {
01091     // write the static lines
01092     write_statics( );
01093   }
01094   else
01095   {
01096     // ensure that we have 2-d links for all energies
01097     raw_static.fill_raw_lists( );
01098     statics.init_list( raw_static ); // initialize the ENDL lists
01099 
01100     // copy the mf12 data into ENDL order
01101     ENDL_order( raw_static, statics );
01102     statics.join_lines( );    // join any repeated lines
01103     statics.widen_deltas( true );  // widen the delta-functions
01104 
01105     // clean up and output
01106     ENDL.set_yo( 7 );
01107     statics.widen_jumps();
01108     statics.renorm();
01109     statics.write_endl( 4 );
01110 
01111     // make sure that the multiplicity is 0 if there is no distribution
01112     clean_multiple( statics );
01113 
01114     // print the multiplicities
01115     multiple.widen_jumps( );
01116     multiple.write_endl( 9 );
01117   }
01118 }
01119 // ----------- MF12_list::find_crossings -----------------
01120 void MF12_list::find_crossings( )
01121 // Find the neutron energies at which an energy-dependent
01122 // gamma coincides with a stationary gamma
01123 {
01124   const double EPS = Global.Value( "mf5_tol" );  // tolerance for mf5 data
01125 
01126   list< double > crossings;  // the coincident energies
01127   double E_n;  // neutron energy for a gamma coincidence
01128 
01129   // go through the static gammas
01130   for( MF12_raw::iterator stat_ptr = raw_static.begin( );
01131     stat_ptr != raw_static.end( ); ++stat_ptr )
01132   {
01133     // go through the moving gammas
01134     for( MF12_raw::iterator move_ptr = raw_move.begin( );
01135       move_ptr != raw_move.end( ); ++move_ptr )
01136     {
01137       if( move_ptr->E_gamma( ) > ( 1 - EPS )*stat_ptr->E_gamma( ) )
01138       {
01139         break;
01140       }
01141       else
01142       {
01143         E_n = ( ( movers.AWR + 1 ) / movers.AWR ) *
01144           ( stat_ptr->E_gamma( ) - move_ptr->E_gamma( ) );
01145     // insert this energy in the list
01146         crossings.insert( crossings.end( ), E_n );
01147       }
01148     }
01149   }
01150 
01151   // put the crossing energies in increasing order
01152   crossings.sort( );
01153 
01154   // remove duplicates
01155   list< double >::iterator cross_ptr = crossings.begin( );
01156   list< double >::iterator next_ptr = cross_ptr;
01157   ++next_ptr;
01158   double prev_E_n = -1.0;
01159   
01160   for( ; cross_ptr !=  crossings.end( ); cross_ptr = next_ptr, ++next_ptr )
01161   {
01162     E_n = *cross_ptr;
01163     if( abs( E_n - prev_E_n ) < EPS*E_n )
01164     {
01165       crossings.erase( cross_ptr );
01166     }
01167     else
01168     {
01169       prev_E_n = E_n;
01170     }
01171   }
01172   
01173   // insert ( neutron energy, multiplicity ) pairs at each crossing energy
01174   raw_move.insert_cross( crossings );
01175   raw_static.insert_cross( crossings );
01176 }
01177 // ----------- MF12_list::set_mf15_wt -----------------
01178 void MF12_list::set_mf15_wt( )
01179 // set the weights for the continuum
01180 {
01181   double num;
01182   double denom;
01183   double fract;  // num/denom, the weight
01184   double e_in;
01185 
01186   // set the weights in cont_data
01187   for( MF15_list::iterator cont_ptr = cont_data.begin( );
01188        cont_ptr != cont_data.end( ); ++cont_ptr )
01189   {
01190     e_in = cont_ptr->E_in( );
01191     num = cont_data.multiple.evaluate( e_in );
01192     denom = multiple.evaluate( e_in );
01193     if( denom == 0.0 )
01194     {
01195       fract = 0.0;
01196     }
01197     else
01198     {
01199       fract = num/denom;
01200     }
01201     if( ( fract < 0.0 ) || ( fract > 1.0 ) )
01202     {
01203       SevereError("MF12_list::set_mf15_wt",pastenum("bad weight: ",fract));
01204     }
01205     cont_ptr->weight = fract;
01206   }
01207 }
01208 // ----------- MF12_list::ENDL_order -----------------
01209 void MF12_list::ENDL_order( MF12_raw& mf12_data, MF12_base& ENDL_data )
01210 // copy the mf12_data to ENDL_data
01211 {
01212   const double EPS = Global.Value( "mf5_tol" );  // tolerance for mf5 data
01213 
01214   dd_link XYdata;
01215   MF12_base::iterator e_in_link;
01216   double E_in;
01217   double EG;  // gamma energy
01218   dd_list::iterator data_ptr;
01219 
01220   // loop through the gammas
01221   for( MF12_raw::iterator raw_ptr = mf12_data.begin( );
01222     raw_ptr != mf12_data.end( ); ++raw_ptr )
01223   {
01224     EG = raw_ptr->E_gamma( ); // the gamma energy
01225 
01226     // loop over the (E_in, multiplicity) pairs
01227     for( data_ptr = raw_ptr->begin( ); data_ptr != raw_ptr->end( );
01228       ++data_ptr )
01229     {
01230       // form an (E_in, multiplicity) pair
01231       XYdata.x = EG;
01232       XYdata.y = data_ptr->y;
01233       E_in = data_ptr->x;
01234 
01235       // Find the 1-d list with this incident energy
01236       e_in_link = ENDL_data.find_link( E_in, EG );
01237 
01238       if( e_in_link != ENDL_data.end( ) )
01239       {
01240         // The gamma energies are now in ascending order
01241         e_in_link->insert( e_in_link->end( ), XYdata );
01242       }
01243     }
01244   }
01245 }
01246 // ----------- MF12_list::continuum -----------------
01247 //! handle multiplicity and energy distributions for the continuum
01248 //! The multiplicity for the continuum is at the end of the mf12 file
01249 //! and we use it only if mf12_NK = 1
01250 void MF12_list::continuum( int NR, int NP )
01251 {
01252   // read the interpolation regions
01253   inFile->get_regions( NR, cont_data.multiple.NBT, cont_data.multiple.INT );
01254 
01255   cont_data.multiple.read_data( NP, *inFile );
01256 
01257   contin_file.open( 15, ENDL.T );  // open the mf15 file
01258   cont_data.read_data( contin_file );
01259   Info("MF12_list::continuum","Closing file "+endf_file_name(15,ENDL.T)+"...");
01260   contin_file.close( );
01261 }
01262 
01263 // ********* for class MF12_deexcite *************
01264 // ----------- MF12_deexcite::master -----------------
01265 //! handle an mf12 transition probability file (LO = 2)
01266 //! For LG = 1 the data is pairs; for LG = 2 it is triplets.
01267 void MF12_deexcite::master( double AWR, int LG, mf12_file& inFile )
01268 {
01269   //  int NR,NP;
01270   //  double EG,ES;
01271   //  int LP,LF;
01272 
01273   double Max_energy = ENDL.Max_E_in;
01274 
01275   // get the threshold energy
01276   double e_in = ENDL.threshold;
01277   if( e_in > Max_energy )
01278   {
01279     // skip this data
01280     return;
01281   }
01282 
01283   // make a new list at the threshold energy
01284   one_d_table new_link;
01285   new_link.E_in() = e_in;
01286   insert(end(), new_link);
01287   MF12_deexcite::iterator e_in_link = end();
01288   --e_in_link;
01289 
01290   // get the discrete gammas
01291   read_data( AWR, LG, inFile );
01292 
01293   // stick it in the MF12_deexcite object
01294   stick_it( e_in_link );
01295   
01296   // Copy this link to another at Max_energy
01297   new_link.E_in() = Max_energy;
01298   insert(end(), new_link);
01299   MF12_deexcite::iterator new_link_ptr = end();
01300   --new_link_ptr;
01301   for(dd_list::iterator list_ptr = e_in_link->begin();
01302     list_ptr != e_in_link->end(); ++list_ptr)
01303   {
01304     dd_link XYdata(list_ptr->x, list_ptr->y);
01305     new_link_ptr->insert(new_link_ptr->end(), XYdata);
01306   }
01307 
01308   ENDL.set_yo(7);
01309   renorm();
01310   write_endl( 4 );
01311 }
01312 
01313 // ----------- MF12_deexcite::read_data -----------------
01314 //! This routine is used to read in transition probabilities
01315 void MF12_deexcite::read_data( double AWR, int LG, mf12_file& inFile )
01316 {
01317   //  double ES;  // excitation level of the original nucleus
01318   double zero;
01319   int LP;
01320   int NT;  // the number of transitions in the file
01321   int dummy;
01322   double ES_i; // excitation level after gamma emission
01323   double prev_ESi;  // previous level
01324   dd_link XYdata;
01325   dd_link EPdata;
01326   string linebuff;
01327   string strbuff;
01328   double Prob, GammaConditionalProb;
01329   double cum_prob = 0.0;  // is the total probability 1?
01330   bool found_level;
01331 
01332   if (LG==2)
01333     Warning("MF12_deexcite::read_data","Ignoring internal conversion.  All energy from a transition goes to gamma production.");
01334 
01335   inFile.gamma_line1(
01336     &ES,     //  level energy
01337     &zero,
01338     &LP,     // do a Doppler shift?
01339     &dummy,  // zero
01340     &dummy,  // count of excitation levels
01341     &NT      // number of (ES_i, probability) pairs
01342   );
01343   
01344   if( LP == 2 )
01345   {
01346     if( ( ENDL.T > 50 ) && ( ENDL.T < 91 ) )
01347     {
01348       Warning("MF12_deexcite::read_data",
01349               "Typo: shifted gamma cascade makes no sense");
01350     }
01351     else
01352     {
01353       SevereError("MF12_deexcite::read_data",
01354                   "Implement shift for gamma cascade");
01355     }
01356   }
01357   ES *= ENDL.eV2MeV;  // Convert level energy to MeV
01358   cascade new_cascade;
01359   cascade_gammas.insert(make_pair(ENDL.T,new_cascade));
01360   cascade_gammas[ENDL.T].Level_Energy = ES;
01361 
01362   for(int count = 0; count < NT; ++count)
01363   {
01364     int iP;
01365     if(LG == 1)
01366     {
01367       iP = count % 3;  //There are 3 pairs per line
01368       if ( iP == 0 )
01369       {
01370         getline( inFile, linebuff); //Read in new line
01371       }
01372       strbuff = linebuff.substr(iP*22, 22);
01373       read_dd(&strbuff, &ES_i, &Prob );
01374       GammaConditionalProb = 1.0;
01375       if ( Prob > 1.0 ) 
01376         Warning( "MF12_deexcite::read_data", pastenum( "Prob = ", Prob ) + "> 1.0" );
01377     }
01378     else if(LG == 2)
01379     {
01380       iP = count % 2;  //There are 2 triples per line
01381       if ( iP == 0 )
01382       {
01383         getline( inFile, linebuff); //Read in new line
01384       }
01385       strbuff = linebuff.substr(iP*33, 33);
01386       read_ddd(&strbuff, &ES_i, &Prob, &GammaConditionalProb );
01387       // Note: we're throwing away the conditional gamma emission probability 
01388       // (GammaConditionalProb) and assuming a transition goes completely to the gamma
01389       // channel.  Really if GammaConditionalProb < 1, we should send some strength to 
01390       // internal conversion electrons.
01391       if ( Prob > 1.0 ) 
01392         Warning( "MF12_deexcite::read_data", pastenum( "Prob = ", Prob ) + "> 1.0" );
01393       if ( GammaConditionalProb > 1.0 ) 
01394         Warning( "MF12_deexcite::read_data", pastenum( "GammaConditionalProb = ", GammaConditionalProb ) + "> 1.0" );
01395     }
01396     else
01397     {
01398       SevereError("MF12_deexcite::read_data",pastenum("Bad value of LG: ",LG));
01399     }
01400     if ( ES_i==-999.0 || Prob==-999.0 ) //read_PAIR sends -999.0 if problem
01401     {
01402       SevereError("MF12_deexcite::read_data","read_PAIR messed up!");
01403     }
01404     ES_i *= ENDL.eV2MeV;
01405     EPdata.x = ES - ES_i;
01406     EPdata.y = Prob;
01407     cum_prob += Prob;
01408 
01409     // check for levels out of order
01410     if( ( count > 0 ) && ( ES_i >= prev_ESi ) )
01411     {
01412       SevereError( "MF12_deexcite::read_data",
01413            pastenum( "levels out of order: ", ES_i ) );
01414     }
01415     prev_ESi = ES_i;
01416     
01417     //Insert the data into the appropriate list
01418     cascade_gammas[ENDL.T].insert(cascade_gammas[ENDL.T].end(),EPdata);
01419     
01420     double levelMatchTol = 0.00001; // 10 eV
01421     //Need to propagate the cascade if it didn't decay to ground state
01422     if ( ES_i > 0.0 )  
01423     { 
01424      found_level = false;  //flag to insure all level searches are successful
01425       for( int level = ENDL.T; level >= ENDL.T-40; --level ) //Loop down thru MT's
01426       { 
01427         if( abs(cascade_gammas[level].Level_Energy - ES_i ) < levelMatchTol ) //Match is found
01428         {
01429           found_level = true;
01430           cascade these = cascade_gammas[level];  // local copy
01431           these *= Prob;                          // scale by initiating probability
01432           cascade_gammas[ENDL.T].line_sum( these , .00001 ); // add them to list
01433           break;
01434         }
01435       }
01436       if( !found_level ) //Better let somebody know 
01437       {
01438         SevereError("MF12_deexcite::read_data",
01439           pastenum( "Could not find matching level ", ES_i) +
01440           " in cascade data!");
01441       }
01442     }
01443 
01444   }
01445 
01446 
01447   // Check total probability.
01448   if( abs( cum_prob - 1.0 ) > ENDL_EPSILON( 1.0 ) )
01449   {
01450     Info( "MF12_deexcite::read_data",
01451            pastenum( "total probability: ", cum_prob )+", so rescaling" );
01452     for ( int level = ENDL.T; level >= ENDL.T-40; --level ) 
01453     {
01454       cascade_gammas[ENDL.T] *= 1.0/cum_prob;
01455     }
01456   }
01457 
01458   //Each time we complete a level, we write out to an i=9 file
01459   cascade_gammas[ENDL.T].write_endl( );
01460 
01461 }
01462 
01463 
01464 
01465 // ----------- MF12_deexcite::stick_it -----------------
01466 void MF12_deexcite::stick_it( MF12_deexcite::iterator e_in_link )
01467 // Routine to stick the cascade gammas into the deexcite object
01468 {
01469   dd_link XYdata;
01470 
01471 //Loop through the EP pairs and stick them into the deexcite object...
01472   for( cascade::iterator link = cascade_gammas[ENDL.T].begin(); 
01473      link != cascade_gammas[ENDL.T].end();
01474      ++link)
01475     {
01476       XYdata.x = link->x;
01477       XYdata.y = link->y;
01478   
01479       one_d_table::iterator next_xy;
01480       if(e_in_link->empty())
01481     {
01482       next_xy = e_in_link->end();
01483     }
01484       else
01485     {
01486       // find the first bigger gamma energy
01487       for(next_xy = e_in_link->begin();
01488           next_xy != e_in_link->end();
01489           ++next_xy)
01490         {
01491           if (next_xy->x >= XYdata.x)
01492         {
01493           break;
01494         }
01495         }
01496     }
01497       // is there positive gamma emission?
01498       if( XYdata.x <= 0.0 )
01499       {
01500         Warning( "MF12_deexcite::stick_it", "line with no energy" );
01501       }
01502       else
01503       {
01504         //Insert the data into the table
01505         e_in_link->insert(next_xy, XYdata);
01506       }
01507     }    
01508   // now widen the delta functions and renormalize
01509   e_in_link->widen_delta();
01510   e_in_link->renorm();
01511 }
01512 
01513 // ----------- cascade::print -----------------
01514 void cascade::print()
01515 {
01516   cout<<"Energy of this level = "<<Level_Energy<<endl;
01517   for(dd_list::iterator link = begin(); link != end();
01518       ++link)
01519     {
01520       cout << ENDL.data( link->x, link->y ) << endl;
01521     }
01522   cout<< "........................." <<endl;
01523 }
01524       
01525 // ----------- cascade::write_endl -----------------
01526 void cascade::write_endl()
01527 {
01528   ENDL.set_I_number(9);
01529   fstream endl_file;
01530   string file_name = ENDL.file_name;
01531   
01532   if(empty())
01533   {
01534     Warning("cascade::write_endl","The file "+file_name+" is empty.");
01535     return;
01536   }
01537   
01538   if ( ENDL.new_file() )
01539   {
01540     endl_file.open(file_name.c_str(),ios::out);
01541     Info("cascade::write_endl","Opening ENDL file "+file_name);
01542   }
01543   else
01544   {
01545     endl_file.open(file_name.c_str(),ios::out|ios::app);
01546     Info("cascade::write_endl","Appending ENDL file "+file_name);
01547   }
01548       
01549   //Write out the header information
01550   endl_file<<ENDL.header_line_1<<endl;
01551   endl_file<<ENDL.header_line_2<<endl;
01552   endl_file.setf(ios::scientific,ios::floatfield);
01553   
01554   //Loop through the data and determine the average number of gammas
01555   double mean = 0.0;
01556   for(dd_list::iterator link = begin(); link != end(); ++link)
01557   {
01558     mean += link->y ;
01559   }
01560   
01561   endl_file<<ENDL.data( ENDL.threshold, mean )<<endl;
01562   endl_file<<ENDL.data( ENDL.Max_E_in, mean )<<endl;
01563   
01564   //Put on end of file/section line into output file
01565   endl_file<<ENDL.eof_line<<endl;
01566   
01567   //Finally, we close the output file
01568       Info("cascade::write_endl","Closing ENDL file "+file_name);
01569   endl_file.close();
01570   
01571 }

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