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 "Origen/Core/dc/Concentrations.h"
#include "Origen/Core/dc/FakeFactory.h"
#include "Origen/Core/re/defaultNuclideResource.h"
#include "Standard/Interface/SerialStream.h"
using std::vector;
using std::pair;
using namespace Origen;
TEST( tstConcentrations, Basic )
{
    Concentrations concs;
    // 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
    // set values that correspond to the actual order
    concs.set_vals( {1.0, 0.5, 0.25} );
    // 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 );
    // 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
    Concentrations depl;
    {
        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
    Concentrations tran;
    {
        NuclideSet nuc_set;
        nuc_set.set_ids( {1003, 27058} );
        tran.set_nuclide_set( nuc_set );
    }
    tran.set_vals( 0.5 );
    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_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_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
    Concentrations obj1;
    {
        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;
    EXPECT_EQ( 0, return_code );
    // deserialize
    Concentrations obj2;
    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;
    FakeFactory::nuclide_set_addnux4( ids );
    NuclideSet nuc_set;
    nuc_set.set_ids( ids );
    // re-use buffer to get numden
    Vec_Dbl numden;
    FakeFactory::vera_uox_e310( ids, numden );
    // set up concentrations
    Concentrations obj1;
    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
    Concentrations obj2;
    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>();
    defaultNuclideResource( &*nr );
    // 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>();
    defaultNuclideResource( &*nr );
    // 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.
    // 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 ) );
}
 
          
          
 1.8.10
 1.8.10