tstLibraryIO.cpp

./Core/io/tests/tstLibraryIO.cpp

#include <sstream>
#include "Origen/Core/TestPaths.h"
#include "Origen/Core/config.h"
#include "ScaleSTL/Functions.h"
#include "ScaleUtils/IO/EndianUtils.h"
#include "Nemesis/gtest/nemesis_gtest.hh"
using namespace Origen;
using ScaleUtils::IO::DB;
class LibraryIOTester : public ::testing::TestWithParam<const char*>
{
protected:
void SetUp() { Origen::FakeFactory::Library_scale_pwr( lib ); }
void TearDown() { Origen::printTimingReport( std::cout ); }
};
// copy over stuff that didn't exist in the SCALE 6.1 library format
void scale61_fixup( const Library& lib, Library& new_lib )
{
// modify num_neutron_energy_groups
LibraryHeader hdr = new_lib.definition();
new_lib.set_definition( hdr );
// modify transition_ids
new_lib.set_transition_structure( tstruct );
// modify burnup/flux
TransitionCoeff tcoeff = new_lib.transition_coeff_at( 0 );
tcoeff.set_burnup( lib.transition_coeff_at( 0 ).burnup() );
tcoeff.set_flux( lib.transition_coeff_at( 0 ).flux() );
new_lib.set_transition_coeff_at( tcoeff, 0 );
}
// returns the expected endianness for the files on this system
std::string expected_endian( const std::string& fmt )
{
std::string endian =
ScaleUtils::IO::EndianUtils::system_is_big_endian() ? "big" : "little";
// SCALE 6.1 requires ORIGEN libraries in big endian format
#ifdef USE_IO_DETAIL_F90
if( fmt == "s61" )
{
endian = "big";
}
#endif
return endian;
}
TEST_P( LibraryIOTester, RoundTrip )
{
ScaleUtils::IO::DB opts;
std::string fmt = std::string( GetParam() );
std::string endian = expected_endian( fmt );
// save the data
opts.set( "fileFormat", GetParam() );
std::string path = "roundtrip." + fmt + ".f33";
ASSERT_TRUE( io.save( lib, path, opts ) );
// do some endian testing after we write
EXPECT_TRUE( opts.has<std::string>( "wroteFileEndian" ) );
auto wroteFileEndian =
opts.get<std::string>( "wroteFileEndian", "UNKNOWN" );
EXPECT_EQ( endian, wroteFileEndian );
// now load the data by trial
opts.set( "fileFormat", "" ); // use trial and error to get format
Origen::Library new_lib;
// need to do this so old formats that don't have masses look the same as
// new ones
opts.set<bool>( "legacyMass", true );
ASSERT_TRUE( io.load( new_lib, path, opts ) );
EXPECT_EQ( GetParam(), opts.get<std::string>( "loadedFileFormat" ) );
// do some endian testing after we read
EXPECT_TRUE( opts.has<std::string>( "readFileEndian" ) );
auto readFileEndian = opts.get<std::string>( "readFileEndian", "UNKNOWN" );
EXPECT_EQ( endian, readFileEndian );
// need to fixup extra info that may not exist in one format before we
// compare
if( fmt == "s61" )
{
scale61_fixup( lib, new_lib );
}
//
// Don't be deceived! This is a sophisticated, deep comparison of these
// objects.
//
EXPECT_EQ( lib, new_lib );
}
INSTANTIATE_TEST_CASE_P( LibraryIOTesterFormats,
::testing::Values( "bof", "s62b", "s61" ) );
TEST_F( LibraryIOTester, AppendFile )
{
ScaleUtils::IO::DB opts;
// add additional states
for( size_t i = 0; i < 10; ++i )
{
tc.set_burnup( ( i + 1 ) * 1000.0 );
}
ASSERT_EQ( 11, lib.transition_coeff_size() );
// save the original with copies
{
SCOPED_TIMER( "single write" );
opts.set( "fileFormat", "bof" );
bool pass = saveLibrary( lib, "testOriginal.bof.f33", opts );
EXPECT_TRUE( pass );
}
// save it in two steps with append
{
SCOPED_TIMER( "using append" );
opts.set( "fileFormat", "bof" );
bool pass = saveLibrary( lib, "testAppend.bof.f33", opts );
EXPECT_TRUE( pass );
// write an extra piece
{
SCOPED_TIMER( "append time only" );
opts.set( "appendExisting", true );
pass = saveLibrary( lib2, "testAppend.bof.f33", opts );
EXPECT_TRUE( pass );
}
}
// clear all opts
opts.clear();
Origen::SP_Library appended_lib;
{
SCOPED_TIMER( "load time" );
// load appended library written to disk
appended_lib = Origen::SP_Library(
Origen::loadLibrary( "testAppend.bof.f33", opts ) );
ASSERT_FALSE( appended_lib == nullptr );
ASSERT_EQ( 12, appended_lib->transition_coeff_size() );
}
// now states should be equal
ASSERT_EQ( 12, lib.transition_coeff_size() );
// compare for equality
EXPECT_TRUE( lib == *appended_lib ); //<<lib.to_string();
{
std::ofstream ofs( "appended_lib.txt" );
ofs << appended_lib->to_string() << std::endl;
}
{
std::ofstream ofs( "lib.txt" );
ofs << lib.to_string() << std::endl;
}
}