tstinterp.cpp

./Core/fn/tests/tstinterp.cpp

#include "Nemesis/gtest/nemesis_gtest.hh"
using namespace Origen;
// Testing the Library Selection algorithm
TEST( Interp, LibSelect )
{
// Simulate the tagManagers from a 2D field of Libraries to sort.
std::vector<TagManager> tagManList;
for( int i = 0; i < 5; ++i )
{
for( int j = 0; j < 7; ++j )
{
TagManager fakeTags;
fakeTags.setIdTag( "Fuel Type",
"Uranium" ); // All 35 libraries have this tag.
// Compare against "Fuel Type=MOX".
if( i == 0 && j < 7 )
fakeTags.setIdTag(
"Assembly Type",
"w17x17" ); // 7 libs in libGrid[i=0][j=0-6] have this tag.
if( i == 1 && j < 6 )
fakeTags.setIdTag( "Assembly Type",
"w17x17_ofa" ); // 6 libs in
// libGrid[i=1][j=0-5] have
// this tag.
if( i == 2 && j < 5 )
fakeTags.setIdTag(
"Assembly Type",
"ge8x8" ); // 5 libs in libGrid[i=2][j=0-4] have this tag.
if( i == 3 && j < 4 )
fakeTags.setIdTag(
"Assembly Type",
"agr" ); // 4 libs in libGrid[i=3][j=0-3] have this tag.
if( i == 4 && j < 3 )
fakeTags.setIdTag( "Assembly Type", "candu37" ); // 3 libs in
// libGrid[i=4][j=0-2] have
// this tag.
if( j == 0 )
fakeTags.setIdTag(
"Cross section library",
"endf7" ); // 5 libs in libGrid[i=0-4][j=0] have this tag.
if( j == 1 && i < 2 )
fakeTags.setIdTag(
"Cross section library",
"endf6" ); // 2 libs in libGrid[i=0-1][j=1] have this tag.
if( j == 6 && i == 4 )
fakeTags.setIdTag(
"Cross section library",
"jendl" ); // 1 lib in libGrid[i=4][j=6] has this tag.
tagManList.push_back( fakeTags );
}
}
TagManager refTags;
// Testing against a single tag that no library should have.
refTags.setIdTag( "Fuel Type", "mox" );
EXPECT_TRUE( ( selectLibraries( tagManList, refTags ) ).size() == 0 );
// Testing against one that all libraries should have but two that don't
// overlap (i.e. - should return none).
refTags.setIdTag( "Fuel Type", "Uranium" );
refTags.setIdTag( "Assembly Type", "candu37" );
refTags.setIdTag( "Cross section library", "jendl" );
EXPECT_TRUE( ( selectLibraries( tagManList, refTags ) ).size() == 0 );
// Testing without the Cross section library tag, should return 3.
refTags.deleteTag( "Cross section library" );
EXPECT_TRUE( ( selectLibraries( tagManList, refTags ) ).size() == 3 );
// Testing without the Assembly Type tag, but with the Cross section library
// tag "jendl". Should return 1.
refTags.deleteTag( "Assembly Type" );
refTags.setIdTag( "Cross section library", "jendl" );
EXPECT_TRUE( ( selectLibraries( tagManList, refTags ) ).size() == 1 );
// Testing with 2 tags that should result in 5 returned library.
refTags.setIdTag( "Cross section library", "endf7" );
EXPECT_TRUE( ( selectLibraries( tagManList, refTags ) ).size() == 5 );
// Testing with 3 tags that should return 1.
refTags.setIdTag( "Assembly Type", "w17x17_ofa" );
EXPECT_TRUE( ( selectLibraries( tagManList, refTags ) ).size() == 1 );
// Removing Cross section library tag. Should return 6.
refTags.deleteTag( "Cross section library" );
EXPECT_TRUE( ( selectLibraries( tagManList, refTags ) ).size() == 6 );
}
// Test the interpolation functionality of ND Library interpolation
TEST( Interp, Library_InterpND_InMemory )
{
std::vector<float> bu_list = {0.0, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0};
refTC->set_burnup( bu_list[0] );
Library refLib;
refLib.add_transition_coeff( *refTC );
FakeFactory::Library_linear1D( refLib, bu_list, 2.5 );
TagManager refTags;
refTags.setIdTag( "Assembly Type", "FakeFactory" );
refTags.setIdTag( "Fuel Type", "Interpolate" );
refTags.setInterpTag( "Enrichment", 0 );
refTags.setInterpTag( "Moderator Density", 0 );
refTags.setInterpTag( "Fuel Temperature", 0 );
refLib.set_tag_manager( refTags );
std::vector<std::vector<std::vector<SP_Library>>> libGrid;
// sets enrichment tags ranging from 1.5 to 6.0
float enrich = 1.5;
float modden = 0.2;
float fueltmp = 565.;
for( int i = 0; i < 10; ++i )
{
// for each iteration through the enrichment range, the Transition
// Coefficient will be scaled by i+1 (1-10)
std::vector<std::vector<SP_Library>> tmpLibList2;
// sets moderator density tags from 0.2 to 0.8
for( int j = 0; j < 7; ++j )
{
// For each iteration through the moderator densities, the
// Transition Coefficient will be scaled by 100*(j+1)=(100-700).
std::vector<SP_Library> tmpLibList1;
// sets fuel temperature tags from 565 to 635
for( int k = 0; k < 15; ++k )
{
// For each iteration through the fuel temperatures, the
// Transition Coefficient will be scaled by (k+1*10,000)
// (10,000-150,000). At this point, the Transition Coefficient
// will be scaled by TC*(i+1)*((j+1)*100)*((k+1)*10,000) or
// range from 1,000,000 to 10*700*150,000=105,000,000.
unsigned int scale_TC =
( i + 1 ) * ( ( j + 1 ) * 100 ) * ( ( k + 1 ) * 10000 );
// must scale the TransitionCoeff properly and then create
// tmpLib.
refTags.setInterpTag( "Enrichment", enrich + ( i * 0.5 ) );
refTags.setInterpTag( "Moderator Density",
modden + ( j * 0.1 ) );
refTags.setInterpTag( "Fuel Temperature",
fueltmp + ( k * 5. ) );
SP_Library tmpLib = refLib.clone();
SP_TagManager tmpTags = refTags.clone();
tmpLib->set_tag_manager( *tmpTags );
size_t z = 0;
for( auto& bu : bu_list )
{
EXPECT_TRUE( scale_TC > 0 );
TransitionCoeff tmpCoeff = refLib.transition_coeff_at( z );
tmpCoeff.scale( scale_TC * 1.0 );
tmpCoeff.set_burnup( bu );
tmpLib->set_transition_coeff_at( tmpCoeff, z );
z++;
}
tmpLibList1.push_back( tmpLib );
}
tmpLibList2.push_back( tmpLibList1 );
}
libGrid.push_back( tmpLibList2 );
}
std::vector<SCP_Library> fullLibList;
for( auto& one : libGrid )
{
for( auto& two : one )
{
for( auto& three : two )
{
fullLibList.push_back( three );
}
}
}
TagManager testTags;
testTags.setIdTag( "Assembly Type", "FakeFactory" );
testTags.setIdTag( "Fuel Type", "Interpolate" );
testTags.setInterpTag( "Enrichment", 2.25 ); // Scale value of 2.5.
testTags.setInterpTag( "Moderator Density", 0.45 ); // Scale value of 350.
std::vector<SCP_Library> newLibList =
selectLibraries( fullLibList, testTags );
EXPECT_TRUE( testTags.hasTag( "Assembly Type" ) );
EXPECT_TRUE( testTags.getIdTag( "Assembly Type" ) == "FakeFactory" );
EXPECT_TRUE( testTags.hasTag( "Fuel Type" ) );
EXPECT_TRUE( testTags.getIdTag( "Fuel Type" ) == "Interpolate" );
EXPECT_TRUE( testTags.hasTag( "Enrichment" ) );
EXPECT_FLOAT_EQ( testTags.getInterpTag( "Enrichment" ), 2.25 );
EXPECT_TRUE( testTags.hasTag( "Moderator Density" ) );
EXPECT_FLOAT_EQ( testTags.getInterpTag( "Moderator Density" ), 0.45 );
EXPECT_FALSE( testTags.hasTag( "Fuel Temperature" ) );
SP_Library finalLib = interpLibraryND( newLibList, testTags );
TagManager finalTags = finalLib->tag_manager();
EXPECT_TRUE( finalTags.hasTag( "Assembly Type" ) );
EXPECT_TRUE( finalTags.getIdTag( "Assembly Type" ) == "FakeFactory" );
EXPECT_TRUE( finalTags.hasTag( "Fuel Type" ) );
EXPECT_TRUE( finalTags.getIdTag( "Fuel Type" ) == "Interpolate" );
EXPECT_TRUE( finalTags.hasTag( "Enrichment" ) );
EXPECT_FLOAT_EQ( finalTags.getInterpTag( "Enrichment" ), 2.25 );
EXPECT_TRUE( finalTags.hasTag( "Moderator Density" ) );
EXPECT_FLOAT_EQ( finalTags.getInterpTag( "Moderator Density" ), 0.45 );
EXPECT_TRUE( finalTags.hasTag( "Fuel Temperature" ) );
/*
* The following is calculated as the average of all of the fuel temperature
* values for which there are libraries. As it was not specified in
* testTags,
* the available values are averaged and that is used. There should also be
* a warning sent to cout notifying the user of this. Incidentally, this
* will
* scale the transition coefficients by 80,000.
*/
EXPECT_FLOAT_EQ( finalTags.getInterpTag( "Fuel Temperature" ), 600. );
/*
* Based on all of the scaling values up to this point, the Transition
* Coefficients of finalLib should be scaled by 2.5*350*80,000=70,000,000.
*/
EXPECT_EQ( refLib.transition_coeff_size(),
finalLib->transition_coeff_size() );
for( size_t i = 0; i != refLib.transition_coeff_size(); ++i )
{
SP_TransitionCoeff tcNew = finalLib->transition_coeff_at( i ).clone();
EXPECT_FLOAT_EQ( tcRef->burnup(), tcNew->burnup() )
<< "Burnups mismatched for Library " << i + 1 << " / "
<< refLib.transition_coeff_size() << std::endl;
tcRef->scale( 70000000. );
tcRef->set_burnup( tcNew->burnup() );
EXPECT_TRUE( tcRef->approx_eq( *tcNew ) )
<< "Library " << i + 1 << " / " << refLib.transition_coeff_size()
<< " does not match expected Library" << std::endl;
}
}
// Test the interpolation functionality of ND Library interpolation
TEST( Library, Library_InterpND_OnDisk )
{
std::vector<float> bu_list = {
0.0, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0}; // Burnups for test Libraries.
*refTC ); // Random TransitionCoeff generated by FakeFactory.
refTC->set_burnup( bu_list[0] );
Library refLib;
refLib.add_transition_coeff( *refTC );
bu_list,
2.5 ); // Linear scaling of original
// transition coefficient for the
// other burnups.
TagManager refTags;
// Setting the tags that will label all fake libraries.
refTags.setIdTag( "Assembly Type", "FakeFactory" );
refTags.setIdTag( "Fuel Type", "Interpolate" );
// Initializing interpolation tags to be filled later.
refTags.setInterpTag( "Enrichment", 0 );
refTags.setInterpTag( "Moderator Density", 0 );
refTags.setInterpTag( "Fuel Temperature", 0 );
refLib.set_tag_manager( refTags );
// 3D array of libraries to be populated.
std::vector<std::vector<std::vector<SP_Library>>> libGrid;
// Fills the 3 dimensions with libraries of varying enrichment, moderator
// density,
// and fuel temperature. Transition coefficients are scaled based on their
// position
// in each dimension so that it can be determined with relative certainty
// that the
// interpolation has worked by scaling the reference library by the same
// amount and
// comparing the two.
// sets enrichment tags ranging from 1.5 to 2.5
float enrich = 1.5;
float modden = 0.2;
float fueltmp = 565.;
for( int i = 0; i < 3; ++i )
{
// for each iteration through the enrichment range, the Transition
// Coefficient will be scaled by i+1 (1-3)
std::vector<std::vector<SP_Library>> tmpLibList2;
// sets moderator density tags from 0.2 to 0.3
for( int j = 0; j < 2; ++j )
{
// For each iteration through the moderator densities, the
// Transition Coefficient will be scaled by 100*(j+1)=(100-200).
std::vector<SP_Library> tmpLibList1;
// sets fuel temperature tags from 565 to 580
for( int k = 0; k < 4; ++k )
{
// For each iteration through the fuel temperatures, the
// Transition Coefficient will be scaled by ((k+1)*10,000)
// (10,000-40,000). At this point, the Transition Coefficient
// will be scaled by TC*(i+1)*((j+1)*100)*((k+1)*10,000) or
// range from 1,000,000 to 3*200*40,000=24,000,000.
unsigned int scale_TC =
( i + 1 ) * ( ( j + 1 ) * 100 ) * ( ( k + 1 ) * 10000 );
// must scale the TransitionCoeff properly and then create
// tmpLib.
refTags.setInterpTag( "Enrichment", enrich + ( i * 0.5 ) );
refTags.setInterpTag( "Moderator Density",
modden + ( j * 0.1 ) );
refTags.setInterpTag( "Fuel Temperature",
fueltmp + ( k * 5. ) );
SP_Library tmpLib = refLib.clone();
tmpLib->set_tag_manager( refTags );
size_t z = 0;
for( auto& bu : bu_list )
{
EXPECT_TRUE( scale_TC > 0 );
TransitionCoeff tmpCoeff = refLib.transition_coeff_at( z );
tmpCoeff.scale( scale_TC * 1.0 );
tmpCoeff.set_burnup( bu );
tmpLib->set_transition_coeff_at( tmpCoeff, z );
z++;
}
tmpLibList1.push_back( tmpLib );
}
tmpLibList2.push_back( tmpLibList1 );
}
libGrid.push_back( tmpLibList2 );
}
// Organizing the libraries into a single vector to feed to
// selectLibraries and interpLibND.
std::vector<SP_Library> fullLibList;
for( auto& one : libGrid )
{
for( auto& two : one )
{
for( auto& three : two )
{
fullLibList.push_back( three );
}
}
}
// Tags that will be given to selectLibraries and interpLibraryND.
// Fuel temperature is intentionally left out. interpLibraryND
// should be able to notice this and deal with it.
TagManager testTags;
testTags.setIdTag( "Assembly Type", "FakeFactory" );
testTags.setIdTag( "Fuel Type", "Interpolate" );
testTags.setInterpTag( "Enrichment", 2.25 ); // Scale value of 2.5.
testTags.setInterpTag( "Moderator Density", 0.275 ); // Scale value of 175.
// No Fuel Temperature value leads to the use of the average, which in this
// case is 572.5. This will have a scale value of 25,000.
// This results in a total scaling of 2.5*175*25,000=10,937,500.
// Set the library filenames based on the interp tags and save them
// to the current working directory.
ScaleUtils::IO::DB opts;
opts.set( "targetDirectory", "." );
std::vector<std::string> nameList;
std::vector<TagManager> tagManList;
for( auto& lib : fullLibList )
{
std::string fileName = "test";
for( auto& tag : lib->tag_manager().listInterpTags() )
{
fileName.append(
"_" +
std::to_string( lib->tag_manager().getInterpTag( tag ) ) );
}
fileName.append( ".bof" );
nameList.push_back( fileName );
TagManager tmpTM;
lib->get_tag_manager( tmpTM );
tmpTM.setIdTag( "Filename", fileName );
lib->set_tag_manager( tmpTM );
tagManList.push_back( lib->tag_manager() );
bool pass = saveLibrary( *lib, fileName, opts );
if( !pass )
std::cerr << "Library " << fileName << " did not save properly."
<< std::endl;
EXPECT_TRUE( pass );
}
// selectLibraries that should collect all libraries created.
// selectLibraries is tested elsewhere in this unit test.
std::vector<SCP_Library> constFullLibList;
for( auto& lib : fullLibList )
{
constFullLibList.push_back( lib );
}
std::vector<SCP_Library> newLibList =
selectLibraries( constFullLibList, testTags );
EXPECT_TRUE( testTags.hasTag( "Assembly Type" ) );
EXPECT_TRUE( testTags.getIdTag( "Assembly Type" ) == "FakeFactory" );
EXPECT_TRUE( testTags.hasTag( "Fuel Type" ) );
EXPECT_TRUE( testTags.getIdTag( "Fuel Type" ) == "Interpolate" );
EXPECT_TRUE( testTags.hasTag( "Enrichment" ) );
EXPECT_FLOAT_EQ( testTags.getInterpTag( "Enrichment" ), 2.25 );
EXPECT_TRUE( testTags.hasTag( "Moderator Density" ) );
EXPECT_FLOAT_EQ( testTags.getInterpTag( "Moderator Density" ), 0.275 );
EXPECT_FALSE( testTags.hasTag( "Fuel Temperature" ) );
// Interpolation to the target values. Function should be
// able to realize that the function space is underdefined,
// determine the average value for the unspecified dimensions
// and interpolate to those positions while throwing a warning.
SP_Library finalLib = interpLibraryND( newLibList, testTags );
SCP_TagManager finalTags = finalLib->scp_tag_manager();
EXPECT_TRUE( finalTags->hasTag( "Assembly Type" ) );
EXPECT_TRUE( finalTags->getIdTag( "Assembly Type" ) == "FakeFactory" );
EXPECT_TRUE( finalTags->hasTag( "Fuel Type" ) );
EXPECT_TRUE( finalTags->getIdTag( "Fuel Type" ) == "Interpolate" );
EXPECT_TRUE( finalTags->hasTag( "Enrichment" ) );
EXPECT_FLOAT_EQ( finalTags->getInterpTag( "Enrichment" ), 2.25 );
EXPECT_TRUE( finalTags->hasTag( "Moderator Density" ) );
EXPECT_FLOAT_EQ( finalTags->getInterpTag( "Moderator Density" ), 0.275 );
EXPECT_TRUE( finalTags->hasTag( "Fuel Temperature" ) );
/*
* The following is calculated as the average of all of the fuel temperature
* values for which there are libraries. As it was not specified in
* testTags,
* the available values are averaged and that is used. There should also be
* a warning sent to cout notifying the user of this. Incidentally, this
* will
* scale the transition coefficients by 80,000.
*/
EXPECT_FLOAT_EQ( finalTags->getInterpTag( "Fuel Temperature" ), 572.5 );
/*
* Based on all of the scaling values up to this point, the Transition
* Coefficients of finalLib should be scaled by 2.5*175*25,000=10,937,500.
*/
// Ensure that the interpolation has scaled transition coefficients by the
// correct scaling factor.
EXPECT_EQ( refLib.transition_coeff_size(),
finalLib->transition_coeff_size() );
EXPECT_EQ( refLib.transition_coeff_at( 0 ).burnup(),
finalLib->transition_coeff_at( 0 ).burnup() );
for( size_t i = 0; i != refLib.transition_coeff_size(); ++i )
{
SP_TransitionCoeff tcNew = finalLib->transition_coeff_at( i ).clone();
EXPECT_FLOAT_EQ( tcRef->burnup(), tcNew->burnup() )
<< "Burnups mismatched for Library " << i + 1 << " / "
<< refLib.transition_coeff_size() << std::endl;
tcRef->scale( 10937500. ); // 4.375e+06);
tcRef->set_burnup( tcNew->burnup() );
EXPECT_TRUE( tcRef->approx_eq( *tcNew ) )
<< "Library " << i + 1 << " / " << refLib.transition_coeff_size()
<< " does not match expected Library" << std::endl;
}
}