tstConcentrations.cpp

./Core/dc/tests/tstConcentrations.cpp

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include "Nemesis/gtest/nemesis_gtest.hh"
#include "Origen/Core/config.h"
#include "Standard/Interface/SerialStream.h"
using std::vector;
using std::pair;
using namespace Origen;
TEST( tstConcentrations, Basic )
{
// set 3 nuclides in 3 different sublibs and use internal sorting option
{
bool sort = true;
NuclideSet nuc_set( {10001001, 30002002, 20002002}, sort );
concs.set_nuclide_set( nuc_set );
}
// get the nuclide set and check that ids were reordered correctly
const NuclideSet& nuc_set = concs.nuclide_set();
EXPECT_VEC_EQ( Vec_Int( {10001001, 20002002, 30002002} ), nuc_set.ids() );
// set values that correspond to the actual order
concs.set_vals( {1.0, 0.5, 0.25} );
EXPECT_VEC_EQ( Vec_Dbl( {1.0, 0.5, 0.25} ), concs.vals() );
// check vals_at
EXPECT_EQ( 1.00, concs.vals_at( 0 ) );
EXPECT_EQ( 0.50, concs.vals_at( 1 ) );
EXPECT_EQ( 0.25, concs.vals_at( 2 ) );
// new concentrations from copy
Concentrations concs2( concs );
EXPECT_TRUE( concs.match( concs2 ) );
EXPECT_EQ( concs, concs2 );
// make sure still matches but values are new
concs2.set_vals( 0.0 );
EXPECT_VEC_EQ( Vec_Dbl( {0.0, 0.0, 0.0} ), concs2.vals() );
EXPECT_TRUE( concs.match( concs2 ) );
EXPECT_FALSE( concs == concs2 );
EXPECT_VEC_EQ( Vec_Dbl( {1.0, 0.5, 0.25} ), concs.vals() );
// attempt to add a nuclide that we should find
bool all_found;
all_found = concs.accumulate_concs( {30002002}, {5.3} );
EXPECT_TRUE( all_found );
EXPECT_FLOAT_EQ( 5.3 + 0.25, concs.vals_at( 2 ) );
// attempt to add two where one is found and one not
all_found = concs.accumulate_concs( {30002002, 30003003}, {2.1, 2.1} );
EXPECT_FALSE( all_found );
EXPECT_FLOAT_EQ( 5.3 + 0.25 + 2.1, concs.vals_at( 2 ) );
// attempt to add without sublib and should find match for 30002002
// and not 20002002
double prev = concs.vals_at( 1 );
all_found = concs.accumulate_concs( {2002}, {1.6} );
EXPECT_TRUE( all_found );
EXPECT_FLOAT_EQ( 5.3 + 0.25 + 2.1 + 1.6, concs.vals_at( 2 ) );
EXPECT_FLOAT_EQ( prev, concs.vals_at( 1 ) );
}
TEST( tstConcentrations, NuclideSetManagement )
{
// many variants of a nuclide like depletion would have
{
NuclideSet nuc_set;
nuc_set.set_ids(
{10001003, 10027058, 20001003, 30001002, 30027058, 40001003} );
depl.set_nuclide_set( nuc_set );
}
depl.set_vals( 1.0 );
// single variant of a nuclide like transport would have
{
NuclideSet nuc_set;
nuc_set.set_ids( {1003, 27058} );
tran.set_nuclide_set( nuc_set );
}
tran.set_vals( 0.5 );
EXPECT_FALSE( tran.nuclide_set().has_sublibs() );
bool found;
// Setting the izzzaaa onto a Concentrations with sizzzaaa,
found = depl.accumulate_concs( {1003, 27058}, {0.5, 1.2} );
// find in SUBLIB_1LT because Z<26
EXPECT_EQ( 10001003, depl.nuclide_set().ids_at( 0 ) );
EXPECT_FLOAT_EQ( 1.5, depl.vals_at( 0 ) );
EXPECT_FLOAT_EQ( 1.5, depl.lookup_val( 10001003 ) );
// find ins SUBLIB_3FP because first moving backwards
EXPECT_EQ( 30027058, depl.nuclide_set().ids_at( 4 ) );
EXPECT_FLOAT_EQ( 2.2, depl.vals_at( 4 ) );
EXPECT_FLOAT_EQ( 2.2, depl.lookup_val( 30027058 ) );
EXPECT_TRUE( found );
// Tricky part is getting the transport set with izzzaaa to update
// from the depletion set with sizzzaaa.
found = tran.accumulate_concs(
{10001003, 10027058, 20001003, 30001002, 30027058, 40001003},
{0.1, 0.2, 0.3, 0.4, 0.5, 0.6} );
EXPECT_TRUE( found );
EXPECT_FLOAT_EQ( 0.1 + 0.3 + 0.6 + 0.5, tran.lookup_val( 1003 ) );
EXPECT_FLOAT_EQ( 0.2 + 0.5 + 0.5, tran.lookup_val( 27058 ) );
EXPECT_EQ( BAD_DOUBLE, tran.lookup_val( 1002 ) );
EXPECT_FLOAT_EQ( 0, tran.lookup_val( 1002, 0.0 ) );
// std::cout << depl.to_string() << std::endl;
// std::cout << tran.to_string() << std::endl;
}
TEST( tstConcentrations, Serialization1 )
{
// many variants of a nuclide like depletion would have
{
NuclideSet nuc_set;
nuc_set.set_ids( {10001003, 20001003, 30001002, 40001003} );
obj1.set_nuclide_set( nuc_set );
}
obj1.set_vals( 1.0 );
obj1.set_volume( 3.0 );
// serialize
SerialStream ss;
int return_code = obj1.serialize( &ss );
EXPECT_EQ( 0, return_code );
// deserialize
return_code = obj2.deserialize( &ss );
EXPECT_EQ( 0, return_code );
// compare
EXPECT_EQ( obj1, obj2 );
EXPECT_NE( &obj1, &obj2 );
}
TEST( tstConcentrations, Serialization2 )
{
// create a nuclide set
Vec_Int ids;
NuclideSet nuc_set;
nuc_set.set_ids( ids );
// re-use buffer to get numden
Vec_Dbl numden;
// set up concentrations
obj1.set_nuclide_set( nuc_set );
obj1.set_volume( 3.0 );
obj1.set_concs( ids, numden );
// std::cout << obj1.to_string() << std::endl;
// serialize
SerialStream ss;
int return_code = obj1.serialize( &ss );
EXPECT_EQ( 0, return_code );
// deserialize
return_code = obj2.deserialize( &ss );
EXPECT_EQ( 0, return_code );
// compare
EXPECT_EQ( obj1, obj2 );
EXPECT_NE( &obj1, &obj2 );
}
TEST( tstConcentrations, UnitConversion )
{
auto nr = std::make_shared<NuclideResource>();
// check that masses are close (but not quite) the mass number
double u5 = nr->mass( 92235 );
EXPECT_EQ( 235, int( u5 ) );
EXPECT_NE( 235.0, u5 );
// check that masses are close (but not quite) the mass number
double u8 = nr->mass( 92238 );
EXPECT_EQ( 238, int( u8 ) );
EXPECT_NE( 238.0, u8 );
// get a library and extract the nuclide set
const NuclideSet& nuc_set = lib->definition().nuclide_set();
// create Concentrations with the same nuclide set and nuclide resource
Concentrations concs( nuc_set );
concs.set_nuclide_resource( nr );
// test out moles-->grams first
concs.set_units( MOLES );
concs.set_concs( {92238, 92235}, {2.0, 1.0} );
// switch to grams, check values
concs.set_units( GRAMS );
EXPECT_FLOAT_EQ( 2.0 * u8, concs.lookup_val( 20092238 ) );
EXPECT_FLOAT_EQ( 1.0 * u5, concs.lookup_val( 20092235 ) );
// spot check other values are zero
EXPECT_EQ( 0.0, concs.vals_at( 0 ) );
EXPECT_EQ( 0.0, concs.vals_at( 9 ) );
// normalize to 1 (wt frac)
size_t iu5 = concs.nuclide_set().lookup_index_guess( 20092235 );
auto x1 = concs.scp_vals();
concs.normalize();
auto x2 = concs.scp_vals();
// make sure x1 still has old values
EXPECT_EQ( 1.0 * u5, x1->at( iu5 ) );
// x2 has new values
EXPECT_GT( 1.0, x2->at( iu5 ) );
// output at any time to check contents
//std::cout << concs.to_string() << std::endl;
// test atoms/barn-cm --> wt frac
concs.set_units( ATOMS_B_CM );
concs.set_concs( {92238, 92235}, {2.0e-3, 1.0e-3} );
concs.set_units( GRAMS );
concs.normalize();
auto x3 = concs.scp_vals();
for( size_t i = 0; i < x3->size(); ++i )
{
EXPECT_FLOAT_EQ( ( *x2 )[i], ( *x3 )[i] );
}
// make sure we can go back to atoms/b-cm
concs.set_units( ATOMS_B_CM );
EXPECT_FLOAT_EQ( 1.0e-3, concs.lookup_val( 20092235 ) );
EXPECT_FLOAT_EQ( 2.0e-3, concs.lookup_val( 20092238 ) );
// output at any time to check contents
// std::cout << concs.to_string() << std::endl;
}
//! Here we test going from a
TEST( Concentration, UnitConversion2 )
{
// Get the default nuclide resource, based on the current version of
// the InMemoryStdCompLib.
auto nr = std::make_shared<NuclideResource>();
// Create two Concentrations. The origen_concs will contain concentrations
// with a nuclide set that has sublibs, i.e. lite=1, actinide=2, fp=3, and
// units of mass in grams. The stdcomp_concs represent what you would
// get out a SCALE number density calculation, number density by nuclide
// without sublib.
Concentrations origen_concs;
origen_concs.set_nuclide_resource( nr );
Concentrations stdcomp_concs = origen_concs;
// Initialize stdcomp_concs with numden. Note that stdcomps do not have
// a sublib, it is just a IZA.
NuclideSet stdcomp_nuc_set( {8016, 92235, 1092235, 92238, 60148} );
stdcomp_concs.set_nuclide_set( stdcomp_nuc_set );
stdcomp_concs.set_units( ATOMS_B_CM );
stdcomp_concs.set_vals( {4.0e-3, 1.0e-3, 1.0e-8, 2.0e-3, 1.0e-11} );
// std::cout << stdcomp_concs.to_string() << std::endl;
// Now, initialize origen_concs with traditional sublib-based nuclide set.
// Note that we have placed two versions of 60148: one in the activation
// product/lite sublib=1, and one in the fission product sublib=3.
NuclideSet origen_nuc_set(
{10008016, 10060148, 21092235, 20092235, 20092238, 30060148} );
origen_concs.set_nuclide_set( origen_nuc_set );
origen_concs.set_units( ATOMS_B_CM );
bool conserved = origen_concs.set_concs( stdcomp_concs );
EXPECT_TRUE( conserved );
// std::cout << origen_concs.to_string() << std::endl;
// first make sure we know where everything went
EXPECT_FLOAT_EQ( 4.0e-03, origen_concs.vals_at( 0 ) );
EXPECT_FLOAT_EQ( 0.0e+00, origen_concs.vals_at( 1 ) );
EXPECT_FLOAT_EQ( 1.0e-08, origen_concs.vals_at( 2 ) );
EXPECT_FLOAT_EQ( 1.0e-03, origen_concs.vals_at( 3 ) );
EXPECT_FLOAT_EQ( 2.0e-03, origen_concs.vals_at( 4 ) );
EXPECT_FLOAT_EQ( 1.0e-11, origen_concs.vals_at( 5 ) );
// Now change units to grams.
origen_concs.set_units( GRAMS );
// Normalize to 1 gram so now have weight fraction.
origen_concs.normalize();
EXPECT_FLOAT_EQ( 1.0, origen_concs.sum() );
// Alternatively can normalize to an amount of heavy metal (1MTHM here).
origen_concs.normalize_hm( 1e6 );
EXPECT_FLOAT_EQ( 1e6, origen_concs.sum_hm() );
EXPECT_LT( 1e6, origen_concs.sum() );
// std::cout << origen_concs.to_string() << std::endl;
}
TEST( tstConcentrations, accumulate )
{
// these could be any 3 numbers
const double a( 1.0 );
const double b( 2.0 );
const double c( 3.0 );
// check we can accumulate on two nuclides
NuclideSet nuc_set1( {1001, 1002} );
Concentrations conc1( nuc_set1 );
conc1.accumulate( {a, b} );
EXPECT_FLOAT_EQ( a, conc1.lookup_val( 1001, 0 ) );
EXPECT_FLOAT_EQ( b, conc1.lookup_val( 1002, 0 ) );
EXPECT_FLOAT_EQ( 0, conc1.lookup_val( 1003, 0 ) );
// check that we can accumulate on three nuclides
NuclideSet nuc_set2( {1001, 1002, 1003} );
Concentrations conc2( nuc_set2 );
conc2.accumulate( {0, c, c} );
EXPECT_FLOAT_EQ( 0, conc2.lookup_val( 1001, 0 ) );
EXPECT_FLOAT_EQ( c, conc2.lookup_val( 1002, 0 ) );
EXPECT_FLOAT_EQ( c, conc2.lookup_val( 1003, 0 ) );
// check that we can accumulate the first into the second
conc2.accumulate_concs( conc1 );
EXPECT_FLOAT_EQ( a, conc2.lookup_val( 1001, 0 ) );
EXPECT_FLOAT_EQ( b + c, conc2.lookup_val( 1002, 0 ) );
EXPECT_FLOAT_EQ( c, conc2.lookup_val( 1003, 0 ) );
}