00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <vector>
00039 using namespace std;
00040 #include "mf6classes.hpp"
00041 #include "record_types.hpp"
00042 #include "global_params.hpp"
00043 #include "endl_precision.hpp"
00044
00045 extern ENDLClass ENDL;
00046 extern GlobalParameterClass Global;
00047
00048
00049
00050
00051 mf6_one_d::mf6_one_d( )
00052 {
00053 }
00054
00055
00056 void mf6_one_d::one_E_row( double min_E, double max_E )
00057
00058
00059 {
00060 double E_out;
00061 double Prob;
00062 dd_link e_out_link;
00063 const int Num = 2;
00064
00065
00066 double first_E = min_E*1.00001;
00067 double dE = (max_E*0.99999 - first_E)/Num;
00068
00069 for(int count = 0; count <= Num; ++count)
00070 {
00071 E_out = first_E + count*dE;
00072 Prob = f( E_out );
00073 e_out_link = dd_link( E_out, Prob );
00074 insert( end( ), e_out_link );
00075 }
00076
00077
00078 thicken();
00079
00080
00081
00082 if(bin_interp)
00083 {
00084 get_bins();
00085 }
00086 }
00087
00088
00089
00090 double one_d_phase::f( double E )
00091
00092 {
00093 Pair lab_Emu;
00094 Pair cm_Emu;
00095 double Prob;
00096
00097 lab_Emu.mu = mu( );
00098 lab_Emu.E = E;
00099
00100
00101 cm_Emu = map_->lab_to_cm( lab_Emu );
00102
00103 double E_diff = Ei_max - cm_Emu.E;
00104
00105 if ( E_diff <= 0.0 )
00106 {
00107 Warning("one_d_phase::f",
00108 pastenum("attempt to take logarithm of ",E_diff));
00109 return 0.0;
00110 }
00111
00112
00113 Prob = sqrt( lab_Emu.E )*exp( exponent * log( E_diff ) );
00114
00115 return Prob;
00116 }
00117
00118
00119
00120 two_d_phase::iterator two_d_phase::new_one_d( two_d_phase::iterator where )
00121 {
00122 one_d_phase new_link;
00123 insert( where, new_link );
00124
00125
00126 two_d_phase::iterator link_ptr = where;
00127 --link_ptr;
00128
00129
00130 link_ptr->Ei_max = Ei_max_;
00131 link_ptr->exponent = exponent_;
00132 link_ptr->copy_map( &map );
00133
00134 return link_ptr;
00135 }
00136
00137
00138
00139 phase_space::phase_space( int projectile, int target, int ZAP )
00140 {
00141 a.set( projectile );
00142 A.set( target );
00143 b.set( ZAP );
00144 C.set( projectile + target );
00145 Q = ENDL.QI;
00146 }
00147
00148
00149 void phase_space::expand_data( mf6_file& inFile, multiplicity& multiple)
00150 {
00151 double dE;
00152 double e_in;
00153 int count;
00154
00155
00156 if( ( multiple.INT.size() > 1 ) || ( multiple.INT[0] > 2 ) )
00157 {
00158 SevereError("phase_space::expand_data","Strange multiplicity for phase_space class");
00159 }
00160
00161
00162 double APSX;
00163 int NPSX;
00164 inFile.phase_space( &APSX, &NPSX );
00165 mass_ratio = ( APSX - b.AWR ) / APSX;
00166 exponent__ = 1.5 * NPSX - 4;
00167
00168
00169 double Max_energy = ENDL.Max_E_in;
00170 if( ENDL.threshold >= Max_energy )
00171 {
00172 ENDL.write_file = false;
00173 return;
00174 }
00175
00176
00177 double E_transition = find_E_trans( );
00178
00179 int Num_E_in = static_cast<int>( Global.Value( "num_E_in_3d" ) );
00180 if( ( E_transition <= 0.0 ) || ( E_transition >= Max_energy ) )
00181 {
00182 dE = ( Max_energy - ENDL.threshold ) / Num_E_in;
00183 for ( count = 0; count <= Num_E_in; ++ count )
00184 {
00185 e_in = ENDL.threshold + count * dE;
00186 one_E_in( e_in );
00187 }
00188 }
00189 else
00190 {
00191 double local_eps = ENDL_EPSILON( E_transition );
00192 dE = ( E_transition - local_eps - ENDL.threshold ) / Num_E_in;
00193 for ( count = 0; count <= Num_E_in; ++ count )
00194 {
00195 e_in = ENDL.threshold + count * dE;
00196 one_E_in( e_in );
00197 }
00198 dE = ( Max_energy - E_transition - local_eps ) / Num_E_in;
00199 for ( count = 0; count <= Num_E_in; ++ count )
00200 {
00201 e_in = E_transition + local_eps + count * dE;
00202 one_E_in( e_in );
00203 }
00204 }
00205 }
00206
00207
00208 void phase_space::one_E_in( double e_in )
00209 {
00210 two_d_phase e_in_link;
00211
00212 e_in_link.E_in() = e_in;
00213 insert( end(), e_in_link );
00214
00215
00216 phase_space::iterator this_link = end();
00217 --this_link;
00218
00219
00220 expand_E_in( this_link );
00221
00222
00223 one_d_table new_cos;
00224 cosines.insert( cosines.end(), new_cos );
00225
00226
00227 two_d_list<one_d_table>::iterator cos_ptr = cosines.end();
00228 --cos_ptr;
00229 this_link->make_cos_link( this_link->E_in(), cos_ptr );
00230 }
00231
00232
00233 void phase_space::expand_E_in( phase_space::iterator e_in_link )
00234 {
00235
00236 e_in_link->Ei_max_ = mass_ratio *
00237 ( Q + e_in_link->E_in()*( A.AWR/(A.AWR + a.AWR) ) );
00238 if( e_in_link->Ei_max_ <= 0.0 )
00239 {
00240 Warning("phase_space::expand_E_in",
00241 pastenum(" negative Ei_max_: ",e_in_link->Ei_max_)+
00242 pastenum(" for E_in: ", e_in_link->E_in()));
00243
00244 double EPSILON = Global.Value( "mf5_shift" );
00245 e_in_link->E_in() = -Q * ( 1 + EPSILON ) * (A.AWR + a.AWR) / A.AWR;
00246 e_in_link->Ei_max_ = mass_ratio *
00247 ( Q + e_in_link->E_in()*( A.AWR/(A.AWR + a.AWR) ) );
00248 }
00249
00250
00251 e_in_link->map.set_map( &A, &a, &b, e_in_link->E_in() );
00252 e_in_link->exponent_ = exponent__;
00253
00254
00255
00256
00257 e_in_link->get_geom( 0.0, e_in_link->Ei_max_ );
00258 if( e_in_link->geom_.fastest == Both_ways )
00259 {
00260 e_in_link->full_range( e_in_link->Ei_max_ );
00261 }
00262 else if( e_in_link->geom_.fastest == Transition )
00263 {
00264 e_in_link->full_trans( e_in_link->Ei_max_ );
00265 }
00266 else if( e_in_link->geom_.fastest == Forward )
00267 {
00268 e_in_link->full_forward( 0.0, e_in_link->Ei_max_ );
00269 }
00270 else
00271 {
00272 SevereError("phase_space::expand_E_in","Strange geometry");
00273 }
00274 }
00275
00276 double phase_space::find_E_trans( )
00277 {
00278
00279
00280 double numerator = mass_ratio*Q;
00281 double denominator =
00282 ( (a.AWR*b.AWR) / (A.AWR + a.AWR) - mass_ratio*A.AWR ) /
00283 (A.AWR + a.AWR);
00284
00285 double E_transition = numerator / denominator;
00286 return E_transition;
00287 }
00288
00289
00290
00291 two_d_ENDL_table::iterator
00292 two_d_ENDL_table::new_one_d( two_d_ENDL_table::iterator where )
00293 {
00294 one_d_table new_link;
00295 insert( where, new_link );
00296
00297
00298 two_d_ENDL_table::iterator link_ptr = where;
00299 --link_ptr;
00300
00301 return link_ptr;
00302 }
00303
00304
00305
00306 ENDL_table::ENDL_table( )
00307
00308 {
00309 }
00310
00311
00312 void ENDL_table::read_data( mf6_file& inFile, int ZAP,
00313 multiplicity& multiple )
00314
00315 {
00316
00317 if( ( multiple.INT.size() > 1 ) || ( multiple.INT[0] > 2 ) )
00318 {
00319 SevereError("ENDL_table::read_data","Strange multiplicity for ENDL_table class");
00320 }
00321
00322
00323 int NR;
00324 int NE;
00325 inFile.ENDL( &NR, &NE );
00326 inFile.get_regions( NR, NBT, INT );
00327
00328 for ( int count = 0; count < NE; ++count)
00329 {
00330 one_E_in( inFile );
00331 }
00332 }
00333
00334
00335 void ENDL_table::one_E_in( mf6_file& inFile )
00336
00337 {
00338 string linebuff;
00339 string strbuff;
00340
00341
00342 double e_in;
00343 int NR;
00344 int NMU;
00345 inFile.ENDL_head( &e_in, &NR, &NMU );
00346 two_d_ENDL_table new_e_in_link;
00347 insert( end(), new_e_in_link );
00348
00349 ENDL_table::iterator e_in_link = end();
00350 --e_in_link;
00351 e_in_link->E_in() = e_in*ENDL.eV2MeV;
00352
00353 inFile.get_regions( NR, e_in_link->NBT, e_in_link->INT );
00354
00355 for ( int count = 0; count < NMU; ++count )
00356 {
00357
00358 double this_mu;
00359 int NEP;
00360 inFile.ENDL_head( &this_mu, &NR, &NEP );
00361 two_d_ENDL_table::iterator mu_ptr =
00362 e_in_link->new_one_d( e_in_link->end( ) );
00363 mu_ptr->mu( ) = this_mu;
00364 inFile.get_regions( NR, mu_ptr->NBT, mu_ptr->INT );
00365
00366
00367 for( int iNP=0; iNP < NEP; ++iNP )
00368 {
00369 int iP=iNP % 3;
00370 if ( iP == 0 )
00371 {
00372 getline( inFile, linebuff);
00373 }
00374 strbuff = linebuff.substr( iP*22, 22 );
00375 double X, Y;
00376 read_dd(&strbuff, &X, &Y );
00377 if ( X==-999. || Y==-999. )
00378 {
00379 SevereError("ENDL_table::one_E_in","read_PAIR fucked up!");
00380 }
00381 else
00382 {
00383 dd_link XYdata( X*ENDL.eV2MeV, Y );
00384 mu_ptr->insert( mu_ptr->end(), XYdata );
00385 }
00386 }
00387 }
00388
00389 one_d_table new_cos;
00390 cosines.insert( cosines.end(), new_cos );
00391
00392
00393 two_d_list<one_d_table>::iterator cos_ptr = cosines.end();
00394 --cos_ptr;
00395 e_in_link->make_cos_link( e_in_link->E_in(), cos_ptr );
00396 }
00397
00398
00399
00400 Legendre_item::Legendre_item( )
00401 {
00402
00403 }
00404
00405 void Legendre_item::read_coefs( int i_start, string& linebuff, int order,
00406 mf6_file& inFile, bool *E_out_done )
00407
00408
00409
00410 {
00411 if( !(*E_out_done) )
00412 {
00413
00414 coefs.get_space( order + 1 );
00415 }
00416
00417 string strbuff;
00418
00419
00420 if( i_start == 0 )
00421 {
00422 getline( inFile, linebuff );
00423 }
00424 strbuff = linebuff.substr( 11*i_start, 11 );
00425 read_d( &strbuff, &E_out );
00426 E_out *= ENDL.eV2MeV;
00427
00428
00429 int count = 0;
00430 for( ; count <= order; ++count )
00431 {
00432
00433 int iP = ( i_start + count + 1 ) % 6;
00434 if ( iP == 0 )
00435 {
00436 getline( inFile, linebuff);
00437 }
00438 if( !(*E_out_done) )
00439 {
00440
00441 strbuff = linebuff.substr( 11*iP, 11 );
00442 read_d( &strbuff, &coefs[ count ] );
00443 }
00444 }
00445 double dE = ENDL_EPSILON( ENDL.Max_E_out );
00446 if( E_out > ENDL.Max_E_out - dE )
00447 {
00448 *E_out_done = true;
00449 }
00450 }
00451
00452 void Legendre_item::copy_coef( Legendre_item& copy_from )
00453
00454 {
00455
00456 int num_coef = copy_from.coefs.size( );
00457 coefs.get_space( num_coef );
00458
00459 for( int count = 0; count < num_coef; ++count )
00460 {
00461 coefs[ count ] = copy_from.coefs[ count ];
00462 }
00463 }
00464
00465 void Legendre_item::interpolate( Legendre_item& prev_link,
00466 Legendre_item& next_link )
00467
00468 {
00469 double E_diff = next_link.E_out - prev_link.E_out;
00470
00471
00472 if(E_diff == 0.0)
00473 {
00474 SevereError("Legendre_item::interpolate","division by 0");
00475 }
00476
00477 double alpha = (E_out - prev_link.E_out)/E_diff;
00478
00479
00480 if((alpha < 0.0) || (alpha > 1.0))
00481 {
00482 SevereError("Legendre_item::interpolate", "attempt to extrapolate");
00483 }
00484
00485 for( int j = 0; j < coefs.size( ); ++j )
00486 {
00487 coefs[ j ] += alpha*next_link.coefs[ j ] +
00488 (1.0 - alpha)*prev_link.coefs[ j ];
00489 }
00490 }
00491
00492
00493
00494 void Legendre_list::read_data( int LEP, mf6_file& inFile, bool *done )
00495
00496
00497 {
00498
00499 one_d_table gamma_lines;
00500
00501 int num_E_out;
00502 int ND;
00503
00504 inFile.Legendre_E_in( &E_in, &ND, &order, &num_E_out );
00505
00506 E_in *= ENDL.eV2MeV;
00507
00508
00509 string linebuff;
00510 string strbuff;
00511
00512
00513 for( int count = 0; count < ND; ++count )
00514 {
00515 int iP = count % 3;
00516 if ( iP == 0 )
00517 {
00518 getline( inFile, linebuff );
00519 }
00520 strbuff = linebuff.substr( iP*22, 22 );
00521 double X, Y;
00522 read_dd(&strbuff, &X, &Y );
00523
00524 X *= ENDL.eV2MeV;
00525 dd_link XYdata( X, Y );
00526
00527
00528 double dE = ENDL_EPSILON( ENDL.Max_E_out );
00529 if( ( Y > 0.0 ) && ( X <= ENDL.Max_E_out + dE ) )
00530 {
00531
00532 one_d_table::iterator next_line = gamma_lines.find_next( X );
00533 gamma_lines.insert( next_line, XYdata );
00534 }
00535 }
00536
00537
00538 int i_start = 2*ND % 6;
00539 bool E_out_done = false;
00540 for( int count = 0; count < num_E_out - ND; ++count )
00541 {
00542 Legendre_item new_E_out;
00543 if( !(*done) )
00544 {
00545 insert( end( ), new_E_out );
00546 Legendre_list::iterator E_out_data = end( );
00547 --E_out_data;
00548 E_out_data->read_coefs( i_start, linebuff, order, inFile,
00549 &E_out_done );
00550 }
00551 else
00552 {
00553 new_E_out.read_coefs( i_start, linebuff, order, inFile,
00554 &E_out_done );
00555 }
00556 i_start += order + 2;
00557 i_start = i_start % 6;
00558 }
00559
00560
00561 expand_interp( LEP );
00562
00563
00564 if( gamma_lines.size( ) > 0 )
00565 {
00566 gamma_lines.widen_delta( );
00567
00568
00569 if( empty( ) )
00570 {
00571
00572 only_lines( gamma_lines );
00573 }
00574 else
00575 {
00576
00577 add_lines( gamma_lines );
00578 }
00579 }
00580
00581 double dE = ENDL_EPSILON( ENDL.Max_E_in );
00582 if( E_in > ENDL.Max_E_in - dE )
00583 {
00584 *done = true;
00585 }
00586 }
00587
00588 void Legendre_list::only_lines( one_d_table& gamma_lines )
00589
00590 {
00591 for( one_d_table::iterator line_ptr = gamma_lines.begin( );
00592 line_ptr != gamma_lines.end( ); ++line_ptr )
00593 {
00594 Legendre_item new_E_out;
00595 insert( end( ), new_E_out );
00596 Legendre_list::iterator E_out_data = end( );
00597 --E_out_data;
00598 E_out_data->E_out = line_ptr->x;
00599 E_out_data->coefs.get_space( 1 );
00600 E_out_data->coefs[ 0 ] = line_ptr->y;
00601 }
00602 }
00603
00604 void Legendre_list::add_lines( one_d_table& gamma_lines )
00605
00606 {
00607
00608 one_d_table::iterator line_ptr = gamma_lines.begin( );
00609 Legendre_list::iterator continuum = begin( );
00610
00611 double Eout_line = line_ptr->x;
00612 double Eout_continuum = continuum->E_out;
00613
00614 if( Eout_line < Eout_continuum )
00615 {
00616 pad_head( Eout_line );
00617 }
00618 else if( Eout_continuum < Eout_line )
00619 {
00620 gamma_lines.pad_head( Eout_continuum );
00621 }
00622
00623
00624 line_ptr = gamma_lines.end( );
00625 continuum = end( );
00626 --line_ptr;
00627 --continuum;
00628
00629 Eout_line = line_ptr->x;
00630 Eout_continuum = continuum->E_out;
00631
00632 if( Eout_line > Eout_continuum )
00633 {
00634 pad_tail( Eout_line );
00635 }
00636 else if( Eout_continuum > Eout_line )
00637 {
00638 gamma_lines.pad_tail( Eout_continuum );
00639 }
00640
00641
00642 list< double > E_out_list;
00643 gamma_lines.collect_E_in( E_out_list );
00644
00645 for( Legendre_list::iterator continuum = begin( );
00646 continuum != end( ); ++continuum )
00647 {
00648 double E_cont = continuum->E_out;
00649 E_out_list.push_back( E_cont );
00650 }
00651
00652 E_out_list.sort( );
00653 E_out_list.unique( );
00654
00655 gamma_lines.fill_with( E_out_list );
00656
00657
00658 fill_with( E_out_list );
00659
00660
00661 for( line_ptr = gamma_lines.begin( ), continuum = begin( );
00662 ( line_ptr != gamma_lines.end( ) ) && ( continuum != end( ) );
00663 ++line_ptr, ++continuum )
00664 {
00665 double E_gamma = line_ptr->x;
00666 double E_cont = continuum->E_out;
00667
00668 if( E_gamma != E_cont )
00669 {
00670 SevereError( "Legendre_list::add_lines",
00671 "energies don't match" );
00672 }
00673
00674 continuum->coefs[ 0 ] += line_ptr->y;
00675 }
00676 }
00677
00678 void Legendre_list::pad_head( double E0 )
00679
00680 {
00681 Legendre_item new_link;
00682 Legendre_list::iterator E_out_data;
00683
00684 double first_E = begin( )->E_out;
00685
00686 double dE = ENDL_EPSILON( first_E );
00687
00688
00689 if( first_E - E0 > dE )
00690 {
00691 bool non_zero = false;
00692 for( int j = 0; j <= order; ++j )
00693 {
00694 if( begin( )->coefs[ j ] != 0.0 )
00695 {
00696 non_zero = true;
00697 break;
00698 }
00699 }
00700 if( non_zero )
00701 {
00702 new_link.E_out = first_E - dE;
00703 push_front( new_link );
00704 E_out_data = begin( );
00705 E_out_data->coefs.get_space( order + 1 );
00706 E_out_data->coefs.set_zero( );
00707 }
00708 }
00709
00710
00711 new_link.E_out = E0;
00712 push_front( new_link );
00713 E_out_data = begin( );
00714 E_out_data->coefs.get_space( order + 1 );
00715 E_out_data->coefs.set_zero( );
00716 }
00717
00718 void Legendre_list::pad_tail( double E0 )
00719
00720 {
00721 Legendre_item new_link;
00722
00723 Legendre_list::iterator E_out_data = end( );
00724 --E_out_data;
00725 double last_E = E_out_data->E_out;
00726
00727 double dE = ENDL_EPSILON( last_E );
00728
00729
00730 if( E0 - last_E > dE )
00731 {
00732 bool non_zero = false;
00733 for( int j = 0; j <= order; ++j )
00734 {
00735 if( E_out_data->coefs[ j ] != 0.0 )
00736 {
00737 non_zero = true;
00738 break;
00739 }
00740 }
00741 if( non_zero )
00742 {
00743 new_link.E_out = last_E + dE;
00744 push_back( new_link );
00745 E_out_data = end( );
00746 --E_out_data;
00747 E_out_data->coefs.get_space( order + 1 );
00748 E_out_data->coefs.set_zero( );
00749 }
00750 }
00751
00752
00753 new_link.E_out = E0;
00754 push_back( new_link );
00755 E_out_data = end( );
00756 --E_out_data;
00757 E_out_data->coefs.get_space( order + 1 );
00758 E_out_data->coefs.set_zero( );
00759 }
00760
00761 void Legendre_list::fill_with( list< double >& E_out_list )
00762
00763 {
00764 Legendre_list::iterator this_link = begin( );
00765
00766
00767 for( list< double >::iterator E_out_ptr = E_out_list.begin( );
00768 E_out_ptr != E_out_list.end( ); ++E_out_ptr )
00769 {
00770 double E_out = *E_out_ptr;
00771
00772
00773 if( this_link->E_out == E_out )
00774 {
00775 ++this_link;
00776 }
00777 else
00778 {
00779
00780 Legendre_item new_link;
00781 new_link.E_out = E_out;
00782 Legendre_list::iterator prev_link = this_link;
00783 --prev_link;
00784 insert( this_link, new_link );
00785 Legendre_list::iterator new_ptr = this_link;
00786 --new_ptr;
00787 new_ptr->coefs.get_space( order + 1 );
00788 new_ptr->interpolate( *prev_link, *this_link );
00789 }
00790 }
00791 }
00792
00793
00794 double Legendre_list::get_norm( )
00795
00796 {
00797
00798 Legendre_list::iterator data_ptr = begin( );
00799
00800 if (size()==0) SevereError("Legendre_list::get_norm","Empty list!");
00801
00802 double prev_E_out = data_ptr->E_out;
00803 double prev_P = data_ptr->coefs.at( 0 );
00804 ++data_ptr;
00805 double sum = 0.0;
00806
00807
00808 for( ; data_ptr != end( ); ++data_ptr )
00809 {
00810 double next_E_out = data_ptr->E_out;
00811 double next_P = data_ptr->coefs.at( 0 );
00812
00813
00814 sum += 0.5*( next_P + prev_P )*( next_E_out - prev_E_out );
00815
00816 prev_E_out = next_E_out;
00817 prev_P = next_P;
00818 }
00819 return sum;
00820 }
00821
00822 void Legendre_list::renorm( )
00823
00824 {
00825 double norm = get_norm( );
00826
00827 Legendre_list::iterator data_ptr = begin( );
00828
00829
00830 if( norm == 0.0 )
00831 {
00832 if (size()==0) SevereError("Legendre_list::renorm","Empty list!");
00833 Warning("Legendre_list::renorm",
00834 pastenum("zero norm in Legendre_list::renorm routine for E_in: ",E_in));
00835
00836 data_ptr->coefs[ 0 ] = 1.0;
00837 }
00838 else
00839 {
00840
00841 for( ; data_ptr != end( ); ++data_ptr )
00842 {
00843 for( int i_coef = 0; i_coef < data_ptr->coefs.size( );
00844 ++i_coef )
00845 {
00846 data_ptr->coefs[ i_coef ] /= norm;
00847 }
00848 }
00849 }
00850 }
00851
00852
00853
00854 void Legendre_list::widen_jumps( )
00855 {
00856
00857
00858 double local_eps, jump_width;
00859
00860 typedef Legendre_list::iterator list_iterator;
00861
00862
00863 list_iterator cluster_start = begin();
00864 list_iterator cluster_end = begin();
00865 int cluster_size=1;
00866
00867 for( list_iterator this_link = begin(); this_link != end( ); ++this_link )
00868 {
00869
00870 local_eps = ENDL_EPSILON( this_link->E_out );
00871 jump_width = ENDL_JUMP_WIDTH( this_link->E_out );
00872
00873
00874 if( abs( this_link->E_out - cluster_end->E_out ) <= local_eps )
00875 {
00876 cluster_end = this_link;
00877 ++cluster_size;
00878 }
00879
00880 else
00881 {
00882 if ( cluster_size > 1 )
00883 widen_cluster( cluster_start, cluster_end, cluster_size, jump_width );
00884
00885 cluster_start = ++cluster_end;
00886 cluster_size = 1;
00887 }
00888 }
00889
00890 if ( cluster_size > 1 )
00891 widen_cluster( cluster_start, cluster_end, cluster_size, jump_width );
00892 }
00893
00894
00895
00896 void Legendre_list::widen_cluster( Legendre_list::iterator cluster_start,
00897 Legendre_list::iterator cluster_end, int cluster_size, double jump_width )
00898 {
00899 if( ( cluster_size == 1 ) || ( cluster_start==cluster_end ) ) return;
00900 if ( cluster_size>4 )
00901 {
00902 Warning("Legendre_list::widen_cluster",pastenum("Found ",cluster_size)+
00903 pastenum(" links in a cluster, check ENDL_EPSILON and ENDL_JUMP_WIDTH values or the data is broken at E_out=",
00904 cluster_start->E_out));
00905 }
00906
00907 if ( cluster_start->E_out <= jump_width )
00908 {
00909 Legendre_list::iterator cluster_middle = cluster_start;
00910 for (int ijump = 1; ijump<=cluster_size; ++ijump)
00911 {
00912 ++cluster_middle;
00913 cluster_middle->E_out += static_cast<double>(ijump)*jump_width;
00914 }
00915 }
00916 else
00917 {
00918 switch (cluster_size)
00919 {
00920 case 2:
00921 cluster_start->E_out -= 0.5*jump_width;
00922 cluster_end->E_out += 0.5*jump_width;
00923 break;
00924 case 3:
00925 cluster_start->E_out -= jump_width;
00926 cluster_end->E_out += jump_width;
00927 break;
00928 case 4:
00929 {
00930 Legendre_list::iterator cluster_left = cluster_start;
00931 Legendre_list::iterator cluster_right = cluster_end;
00932 ++cluster_left;--cluster_right;
00933 cluster_start->E_out -= 1.5*jump_width;
00934 cluster_left->E_out -= 0.5*jump_width;
00935 cluster_right->E_out += 0.5*jump_width;
00936 cluster_end->E_out += 1.5*jump_width;
00937 }
00938 break;
00939 default:
00940 Warning("Legendre_list::widen_cluster",pastenum("Found ",cluster_size)+
00941 pastenum(" links in a cluster, check ENDL_EPSILON and ENDL_JUMP_WIDTH values or the data is broken at E_out=",
00942 cluster_start->E_out));
00943 return;
00944 }
00945 }
00946 }
00947
00948
00949 void Legendre_list::expand_interp( int LEP )
00950
00951
00952 {
00953
00954 if ( LEP == 2 )
00955 {
00956 }
00957 else if ( LEP == 1 )
00958 {
00959 Legendre_list::iterator data_ptr = begin( );
00960
00961
00962 if( data_ptr == end( ) )
00963 {
00964 return;
00965 }
00966
00967
00968 Legendre_list::iterator prev_ptr = begin( );
00969 ++data_ptr;
00970 Legendre_list::iterator next_ptr = data_ptr;
00971 ++next_ptr;
00972
00973 for( ; data_ptr != end( );
00974 prev_ptr = data_ptr, data_ptr = next_ptr, ++next_ptr )
00975 {
00976 Legendre_item new_link;
00977 insert( data_ptr, new_link );
00978 Legendre_list::iterator new_ptr = data_ptr;
00979 --new_ptr;
00980
00981
00982 double dE_L = data_ptr->E_out - prev_ptr->E_out;
00983 double dE_R = ( next_ptr == end( ) ) ? data_ptr->E_out :
00984 next_ptr->E_out - data_ptr->E_out;
00985 double dE = (dE_L < dE_R) ? dE_L : dE_R;
00986
00987 if(dE <= 0.0)
00988 {
00989 SevereError("Legendre_list::expand_interp", "bad histogram data");
00990 }
00991
00992
00993 dE = ENDL_EPSILON( data_ptr->E_out );
00994
00995 new_ptr->E_out = data_ptr->E_out - dE;
00996 data_ptr->E_out += dE;
00997 new_ptr->copy_coef( *prev_ptr );
00998 }
00999 }
01000 else
01001 {
01002 SevereError("Legendre_list::expand_interp",
01003 pastenum("Implement interpolation type: ",LEP));
01004 }
01005 }
01006
01007 void Legendre_list::unit_base( )
01008
01009 {
01010 least_E = begin( )->E_out;
01011 Legendre_list::iterator list_ptr = end( );
01012 --list_ptr;
01013 most_E = list_ptr->E_out;
01014 double scale = most_E - least_E;
01015 if( scale <= 0.0 )
01016 {
01017 SevereError( "Legendre_list::unit_base",
01018 "invalid scale factor");
01019 }
01020
01021 for( list_ptr = begin( ); list_ptr != end( ); ++list_ptr )
01022 {
01023 list_ptr->E_out = ( list_ptr->E_out - least_E )/scale;
01024 list_ptr->coefs *= scale;
01025 }
01026 }
01027
01028 void Legendre_list::rescale( )
01029
01030 {
01031 double scale = most_E - least_E;
01032 if( scale <= 0.0 )
01033 {
01034 SevereError( "Legendre_list::rescale",
01035 "invalid scale factor");
01036 }
01037
01038 for( Legendre_list::iterator list_ptr = begin( );
01039 list_ptr != end( ); ++list_ptr )
01040 {
01041 list_ptr->E_out = least_E + scale*list_ptr->E_out;
01042 list_ptr->coefs *= 1.0/scale;
01043 }
01044 }
01045
01046 void Legendre_list::copy( Legendre_list& to_copy )
01047
01048 {
01049 order = to_copy.order;
01050 interp_type = to_copy.interp_type;
01051 Legendre_item new_link;
01052
01053 for( Legendre_list::iterator copy_ptr = to_copy.begin( );
01054 copy_ptr != to_copy.end( ); ++copy_ptr )
01055 {
01056 insert( end( ), new_link );
01057 Legendre_list::iterator list_ptr = end( );
01058 --list_ptr;
01059
01060 list_ptr->E_out = copy_ptr->E_out;
01061 list_ptr->copy_coef( *copy_ptr );
01062 }
01063 }
01064
01065 Legendre_list& Legendre_list::operator*=( double alpha )
01066
01067 {
01068 for( Legendre_list::iterator list_ptr = begin( );
01069 list_ptr != end( ); ++list_ptr )
01070 {
01071 list_ptr->coefs *= alpha;
01072 }
01073 return *this;
01074 }
01075
01076 Legendre_list& Legendre_list::operator+=( Legendre_list& to_add )
01077
01078 {
01079 Legendre_list::iterator add_ptr = to_add.begin( );
01080 for( Legendre_list::iterator list_ptr = begin( );
01081 list_ptr != end( ); ++list_ptr, ++add_ptr )
01082 {
01083 if( ( list_ptr->E_out != add_ptr->E_out ) ||
01084 (add_ptr == to_add.end( ) ) )
01085 {
01086 SevereError( "Legendre_list::operator+=",
01087 "summands don't agree" );
01088 }
01089 list_ptr->coefs += add_ptr->coefs;
01090 }
01091 return *this;
01092 }
01093
01094 void Legendre_list::chop_E_out( double max_E_out )
01095
01096 {
01097
01098 double dE = ENDL_EPSILON( max_E_out );
01099 if( begin( )->E_out > max_E_out + dE )
01100 {
01101 Warning( "Legendre_list::chop_E_out",
01102 "all outgoing energies are too big" );
01103 }
01104
01105 Legendre_list::iterator last_ptr = end( );
01106 --last_ptr;
01107 if( last_ptr->E_out > max_E_out + dE )
01108 {
01109
01110 for( Legendre_list::iterator list_ptr = begin( );
01111 list_ptr != end( ); ++list_ptr )
01112 {
01113 if( list_ptr->E_out > max_E_out + dE )
01114 {
01115
01116 Legendre_list::iterator prev_ptr = list_ptr;
01117 --prev_ptr;
01118 if( prev_ptr->E_out > max_E_out - dE )
01119 {
01120
01121 Legendre_list::iterator prev_prev_ptr = prev_ptr;
01122 --prev_prev_ptr;
01123 for( ; prev_prev_ptr->E_out > max_E_out - dE; --prev_prev_ptr )
01124 {
01125 list_ptr = prev_ptr;
01126 prev_ptr = prev_prev_ptr;
01127 }
01128 prev_ptr->E_out = max_E_out;
01129 erase( list_ptr, end( ) );
01130 }
01131 else
01132 {
01133
01134 Legendre_item new_link;
01135 insert( list_ptr, new_link );
01136 Legendre_list::iterator new_ptr = list_ptr;
01137 --new_ptr;
01138 new_ptr->E_out = max_E_out;
01139 new_ptr->coefs.get_space( order + 1 );
01140 new_ptr->interpolate( *prev_ptr, *list_ptr );
01141 erase( list_ptr, end( ) );
01142 }
01143 break;
01144 }
01145 }
01146 }
01147 }
01148
01149 void Legendre_list::print( )
01150
01151 {
01152 cout.setf(ios::scientific,ios::floatfield);
01153 for( Legendre_list::iterator list_ptr = begin( );
01154 list_ptr != end( ); ++list_ptr )
01155 {
01156 cout << ENDL.data( list_ptr->E_out ) << ": ";
01157 list_ptr->coefs.print( );
01158 }
01159 }
01160
01161
01162
01163 void mf6_Legendre_raw::read_data( int NR, int num_E_in,
01164 int LEP, mf6_file& inFile )
01165
01166 {
01167 bool done = false;
01168
01169
01170 inFile.get_regions( NR, NBT, INT );
01171
01172
01173 for( int count = 0; count < num_E_in; ++count )
01174 {
01175 Legendre_list one_E_in;
01176 if( !done )
01177 {
01178 insert( end( ), one_E_in );
01179 mf6_Legendre_raw::iterator new_ptr = end( );
01180 --new_ptr;
01181 new_ptr->read_data( LEP, inFile, &done );
01182 }
01183 else
01184 {
01185 one_E_in.read_data( LEP, inFile, &done );
01186 }
01187 }
01188 }
01189
01190 int mf6_Legendre_raw::get_max_order( )
01191
01192 {
01193 int max_order = -1;
01194
01195 for( mf6_Legendre_raw::iterator list_ptr = begin( );
01196 list_ptr != end( ); ++list_ptr )
01197 {
01198 if( list_ptr->order > max_order )
01199 {
01200 max_order = list_ptr->order;
01201 }
01202 }
01203 return max_order;
01204 }
01205
01206 void mf6_Legendre_raw::expand_interp( )
01207
01208 {
01209
01210 int count = 0;
01211 int INT_index = 0;
01212 if( INT[ INT_index ] == 12 )
01213 {
01214 Info("mf6_Legendre_raw::expand_interp", "type 12 interpolation used");
01215 }
01216 else if( ( INT[ INT_index ] != 2 ) && ( INT[ INT_index ] != 22 ) )
01217 {
01218 Unimplemented("mf6_Legendre_raw::expand_interp",
01219 pastenum("Write code to expand interpolation ",INT[ INT_index ]));
01220 }
01221
01222
01223 for( mf6_Legendre_raw::iterator this_link = begin( );
01224 this_link != end( ); ++this_link, ++count )
01225 {
01226
01227 if ( count >= NBT[ INT_index ] )
01228 {
01229 ++INT_index;
01230 if ( INT_index >= INT.size( ) )
01231 {
01232 SevereError("mf6_Legendre_raw::expand_interp","INT_index overflow");
01233 }
01234 if( ( INT[ INT_index ] != 2 ) && ( INT[ INT_index ] != 22 ) )
01235 {
01236 Unimplemented("mf6_Legendre_raw::expand_interp",
01237 pastenum("write code to expand interpolation ",INT[ INT_index ]));
01238 }
01239 }
01240 this_link->interp_type = INT[ INT_index ];
01241 }
01242
01243
01244
01245 }
01246
01247
01248
01249 void mf6_Legendre_raw::widen_jumps( )
01250 {
01251
01252 for( mf6_Legendre_raw::iterator list_ptr = begin( );
01253 list_ptr != end( ); ++list_ptr )
01254 {
01255 list_ptr->widen_jumps( );
01256 }
01257 }
01258
01259
01260
01261 void mf6_Legendre_raw::renorm( )
01262
01263 {
01264
01265 for( mf6_Legendre_raw::iterator list_ptr = begin( );
01266 list_ptr != end( ); ++list_ptr )
01267 {
01268 list_ptr->renorm( );
01269 }
01270 }
01271
01272 void mf6_Legendre_raw::chop_E_in( double max_E_in )
01273
01274 {
01275 double dE = ENDL_EPSILON( max_E_in );
01276
01277 if( begin( )->E_in > max_E_in + dE )
01278 {
01279 ENDL.write_file = false;
01280 return;
01281 }
01282
01283 mf6_Legendre_raw::iterator last_ptr = end( );
01284 --last_ptr;
01285 if( last_ptr->E_in > max_E_in + dE )
01286 {
01287 mf6_Legendre_raw::iterator prev_ptr = last_ptr;
01288 --prev_ptr;
01289 interpolate( max_E_in, prev_ptr, last_ptr );
01290 erase( last_ptr );
01291 }
01292 }
01293
01294 void mf6_Legendre_raw::interpolate( double E_in,
01295 mf6_Legendre_raw::iterator prev_ptr,
01296 mf6_Legendre_raw::iterator next_ptr )
01297
01298 {
01299 Legendre_list new_list;
01300 insert( next_ptr, new_list );
01301 mf6_Legendre_raw::iterator new_ptr = next_ptr;
01302 --new_ptr;
01303
01304
01305 new_ptr->copy( *prev_ptr );
01306 new_ptr->E_in = E_in;
01307
01308 new_ptr->unit_base( );
01309 next_ptr->unit_base( );
01310
01311
01312 list< double > E_outgoing;
01313 Legendre_list::iterator list_ptr;
01314 for( list_ptr = new_ptr->begin( );
01315 list_ptr != new_ptr->end( ); ++list_ptr )
01316 {
01317 E_outgoing.push_back( list_ptr->E_out );
01318 }
01319 for( list_ptr = next_ptr->begin( );
01320 list_ptr != next_ptr->end( ); ++list_ptr )
01321 {
01322 E_outgoing.push_back( list_ptr->E_out );
01323 }
01324
01325 E_outgoing.sort( );
01326 E_outgoing.unique( );
01327
01328 new_ptr->fill_with( E_outgoing );
01329 next_ptr->fill_with( E_outgoing );
01330
01331
01332 double alpha = ( E_in - prev_ptr->E_in ) /
01333 ( next_ptr->E_in - prev_ptr->E_in );
01334 *new_ptr *= 1.0 - alpha;
01335 *next_ptr *= alpha;
01336 *new_ptr += *next_ptr;
01337 new_ptr->least_E = ( 1.0 - alpha )*new_ptr->least_E +
01338 alpha*next_ptr->least_E;
01339 new_ptr->most_E = ( 1.0 - alpha )*new_ptr->most_E +
01340 alpha*next_ptr->most_E;
01341
01342 new_ptr->rescale( );
01343 }
01344
01345 void mf6_Legendre_raw::chop_E_out( double max_E_out )
01346
01347 {
01348 for( mf6_Legendre_raw::iterator list_ptr = begin( );
01349 list_ptr != end( ); ++list_ptr )
01350 {
01351 list_ptr->chop_E_out( max_E_out );
01352 }
01353 }
01354
01355 void mf6_Legendre_raw::print( )
01356
01357 {
01358 for( mf6_Legendre_raw::iterator list_ptr = begin( );
01359 list_ptr != end( ); ++list_ptr )
01360 {
01361 cout << ENDL.data( list_ptr->E_in ) << ":\n";
01362 list_ptr->print( );
01363 }
01364 }
01365
01366
01367 bool mf6_one_order::null_coefs( )
01368
01369 {
01370 for( mf6_one_order::iterator this_list = begin( );
01371 this_list != end( ); ++this_list)
01372 {
01373 double Norm = this_list->get_norm( );
01374 if( Norm != 0.0 )
01375 {
01376 return false;
01377 }
01378 }
01379
01380 return true;
01381 }
01382
01383
01384
01385 void mf6_Legendre::master( mf6_file& inFile, int LEP,
01386 int NR, int NE, bool res_copy )
01387
01388 {
01389
01390 ENDF_data.read_data( NR, NE, LEP, inFile );
01391
01392 ENDF_data.chop_E_in( ENDL.Max_E_in );
01393
01394 ENDF_data.chop_E_out( ENDL.Max_E_out );
01395
01396 order = -1;
01397 if( !ENDL.write_file )
01398 {
01399 return;
01400 }
01401 order = ENDF_data.get_max_order( );
01402
01403
01404 ENDF_data.expand_interp( );
01405 ENDF_data.widen_jumps( );
01406 ENDF_data.renorm( );
01407
01408
01409 reformat( );
01410
01411
01412 reduce_order( );
01413
01414
01415 write_endl( );
01416
01417
01418 if( res_copy )
01419 {
01420 ENDL.outgoing_particle += 10;
01421 write_endl( );
01422 }
01423 }
01424
01425 void mf6_Legendre::reformat( )
01426
01427 {
01428 mf6_Legendre_raw::iterator ENDF_ptr;
01429
01430
01431 mf6_one_order::iterator ENDL_E_in[ order + 1 ];
01432
01433
01434 ENDL_data.resize( order + 1 );
01435
01436
01437 for( mf6_Legendre_raw::iterator ENDF_ptr = ENDF_data.begin( );
01438 ENDF_ptr != ENDF_data.end( ); ++ENDF_ptr )
01439 {
01440
01441 for( int count = 0; count <= order; ++count )
01442 {
01443 one_d_table new_E_out;
01444 ENDL_data[ count ].insert( ENDL_data[ count ].end( ),
01445 new_E_out );
01446 ENDL_E_in[ count ] = ENDL_data[ count ].end( );
01447 --ENDL_E_in[ count ];
01448 ENDL_E_in[ count ]->E_in( ) = ENDF_ptr->E_in;
01449 }
01450
01451
01452 for( Legendre_list::iterator ENDF_Eout_ptr = ENDF_ptr->begin( );
01453 ENDF_Eout_ptr != ENDF_ptr->end( ); ++ENDF_Eout_ptr )
01454 {
01455 dd_link XYdata;
01456 XYdata.x = ENDF_Eout_ptr->E_out;
01457
01458 for( int ord_count = 0; ord_count <= ENDF_ptr->order;
01459 ++ord_count )
01460 {
01461 XYdata.y = ENDF_Eout_ptr->coefs[ ord_count ];
01462 ENDL_E_in[ ord_count ]->insert( ENDL_E_in[ ord_count ]->end( ),
01463 XYdata );
01464 }
01465
01466 XYdata.y = 0.0;
01467 for( int ord_count = ENDF_ptr->order + 1; ord_count <= order;
01468 ++ord_count )
01469 {
01470 ENDL_E_in[ ord_count ]->insert( ENDL_E_in[ ord_count ]->end( ),
01471 XYdata );
01472 }
01473 }
01474 }
01475 }
01476
01477 void mf6_Legendre::reduce_order( )
01478
01479 {
01480 int L_count;
01481
01482
01483 for( L_count = order; L_count > 0; --L_count )
01484 {
01485 if( !ENDL_data[ L_count ].null_coefs( ) )
01486 {
01487
01488 break;
01489 }
01490 }
01491
01492 order = L_count;
01493 }
01494
01495 void mf6_Legendre::write_endl( )
01496
01497 {
01498 ENDL.set_I_number( 4 );
01499
01500 fstream endl_file;
01501 string file_name = ENDL.file_name;
01502
01503 if ( ENDL.new_file() )
01504 {
01505 endl_file.open(file_name.c_str(),ios::out);
01506 Info("mf6_Legendre::write_endl","Opening ENDL file "+file_name);
01507 }
01508 else
01509 {
01510 endl_file.open(file_name.c_str(),ios::out|ios::app);
01511 Info("mf6_Legendre::write_endl","Appending ENDL file "+file_name);
01512 }
01513
01514
01515 endl_file << ENDL.header_line_1 << endl;
01516 endl_file << ENDL.header_line_2 << endl;
01517 endl_file.setf(ios::scientific,ios::floatfield);
01518
01519
01520 for( int L_count = 0; L_count <= order; ++L_count )
01521 {
01522 ENDL_data[ L_count ].out_data( 4, endl_file, 1.0*L_count );
01523 }
01524
01525
01526 endl_file << ENDL.eof_line << endl;
01527
01528
01529 Info("mf6_Legendre::write_endl","Closing ENDL file "+file_name);
01530 endl_file.close();
01531 }