Skip to content

Commit

Permalink
Adding the multiplicites subrecord
Browse files Browse the repository at this point in the history
  • Loading branch information
whaeck committed May 22, 2024
1 parent 58b3070 commit 0160275
Show file tree
Hide file tree
Showing 7 changed files with 346 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/NDItk/depletion/Multiplicities.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#ifndef NJOY_NDITK_DEPLETION_MULTIPLICITIES
#define NJOY_NDITK_DEPLETION_MULTIPLICITIES

// system includes
#include <sstream>
#include <iomanip>

// other includes
#include "tools/std23/views.hpp"
#include "NDItk/base/SubListRecord.hpp"

namespace njoy {
namespace NDItk {
namespace depletion {

/**
* @brief A reaction product multiplicity subrecord for depletion data
*/
class Multiplicities : protected base::SubListRecord< Multiplicities, int > {

friend class base::SubListRecord< Multiplicities, int >;
using Parent = base::SubListRecord< Multiplicities, int >;

/* auxiliary functions */

#include "NDItk/depletion/Multiplicities/src/verify.hpp"
#include "NDItk/depletion/Multiplicities/src/generateData.hpp"
#include "NDItk/depletion/Multiplicities/src/write.hpp"

public:

/* constructor */

#include "NDItk/depletion/Multiplicities/src/ctor.hpp"

/* methods */

/**
* @brief Return the reaction identifier
*/
int identifier() const { return this->value( 0 ); }

/**
* @brief Return the number of reaction products
*/
int numberReactionProducts() const { return this->value( 1 ); }

/**
* @brief Return the reaction product identifiers
*/
auto reactionProducts() const {

using namespace njoy::tools;
return this->values( 2, this->numberReactionProducts() )
| std23::views::stride( 2 );
}

/**
* @brief Return the reaction product multiplicities
*/
auto multiplicities() const {

using namespace njoy::tools;
return this->values( 3, this->numberReactionProducts() )
| std23::views::stride( 2 );
}

using Parent::values;
using Parent::size;
using Parent::empty;
using Parent::begin;
using Parent::end;
using Parent::print;
};

} // depletion namespace
} // NDItk namespace
} // njoy namespace

#endif
25 changes: 25 additions & 0 deletions src/NDItk/depletion/Multiplicities/src/ctor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @brief Constructor
*
* @param[in] reaction the reaction number
* @param[in] products the reaction product identifiers
* @param[in] multiplicities the multiplicity values
*/
Multiplicities( int reaction, std::vector< int > products,
std::vector< int > multiplicities ) :
Parent( generateData( reaction, std::move( products ), std::move( multiplicities ) ) ) {

verify( this->values() );
}

/**
* @brief Constructor
*
* @param[in] begin the begin iterator of the cross section
* @param[in] end the end iterator of the cross section
*/
Multiplicities( Iterator begin, Iterator end ) :
Parent( begin, end ) {

verify( this->values() );
}
28 changes: 28 additions & 0 deletions src/NDItk/depletion/Multiplicities/src/generateData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @brief Generate the subrecord's data vector
*
* @param[in] reaction the reaction number
* @param[in] products the reaction product identifiers
* @param[in] multiplicities the multiplicity values
*/
static std::vector< int >
generateData( int reaction, std::vector< int > products,
std::vector< int > multiplicities ) {

auto size = products.size();
if ( multiplicities.size() != size ) {

Log::error( "The number of reaction product identifiers and multiplicities "
"is inconsistent" );
Log::info( "Found {} reaction product identifiers", products.size() );
Log::info( "Found {} multiplicity values", multiplicities.size() );
throw std::exception();
}
std::vector< int > data = { reaction, static_cast< int >( size ) };
for ( unsigned int i = 0; i < size; ++i ) {

data.push_back( products[i] );
data.push_back( multiplicities[i] );
}
return data;
}
39 changes: 39 additions & 0 deletions src/NDItk/depletion/Multiplicities/src/verify.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @brief Verify the cross section data values
*
* The following verification tests are performed:
* - there are at least three values
* - the reaction identifier looks to be an integer
*
* @param[in] data the data values in the cross section subrecord
*/
template < typename Range >
static void verify( const Range& data ) {

if ( data.size() < 3 ) {

Log::error( "Expected at least 4 data values consisting of a reaction identifier,\n"
"the number of reaction products (in this case equal to 1) followed\n"
"by a reaction product identifier and multiplicity value" );
Log::info( "Found {} data values", data.size() );
throw std::exception();
}

if ( data[1] <= 0 ) {

Log::error( "The number of reaction products cannot be equal to or less than zero" );
Log::info( "Found {} as the number of reaction products", data[1] );
throw std::exception();
}


if ( data.size() != 2 + 2 * data[1] ) {

Log::error( "Expected at least {} data values consisting of a reaction identifier,\n"
"the number of reaction products (in this case equal to {}) followed\n"
"by {} reaction product identifier and multiplicity value pairs",
2 + 2 * data[1], data[1], data[1] );
Log::info( "Found {} data values", data.size() );
throw std::exception();
}
}
27 changes: 27 additions & 0 deletions src/NDItk/depletion/Multiplicities/src/write.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @brief Write the record data
*
* This assumes that the record is not empty.
*
* @param[in] iter the current position in the output
*/
template< typename OutputIterator >
void write( OutputIterator& iter ) const {

std::ostringstream buffer;

auto x = this->begin();
buffer << " " << x[0] << '\n'
<< " " << x[1] << '\n';
x += 2;

auto lines = this->numberReactionProducts();

while ( lines-- ) {

buffer << " " << x[0] << ' ' << x[1] << '\n';
x += 2;
}

for ( auto c : buffer.str() ) { *iter++ = c; }
};
1 change: 1 addition & 0 deletions src/NDItk/depletion/Multiplicities/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_cpp_test( depletion.Multiplicities Multiplicities.test.cpp )
146 changes: 146 additions & 0 deletions src/NDItk/depletion/Multiplicities/test/Multiplicities.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// include Catch2
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_floating_point.hpp>
using Catch::Matchers::WithinRel;

// what we are testing
#include "NDItk/depletion/Multiplicities.hpp"

// other includes

// convenience typedefs
using namespace njoy::NDItk;
using Multiplicities = depletion::Multiplicities;

std::string chunk();
std::vector< int > data();
void verifyChunk( const Multiplicities& );
std::vector< int > dataWithInsufficientLength();

SCENARIO( "Multiplicities" ) {

GIVEN( "valid data for a Multiplicities instance" ) {

std::string record = chunk();

WHEN( "the data is given explicitly" ) {

int reaction = 16;
std::vector< int > products = { 1, 92234 };
std::vector< int > multiplicities = { 2, 1 };

Multiplicities chunk( reaction, std::move( products ), std::move( multiplicities ) );

THEN( "a Multiplicities can be constructed and members can "
"be tested" ) {

verifyChunk( chunk );
} // THEN

THEN( "the record can be printed" ) {

std::string buffer;
auto output = std::back_inserter( buffer );
chunk.print( output );

CHECK( buffer == record );
} // THEN
} // WHEN

WHEN( "the data is defined using iterators" ) {

std::vector< int > values = data();
auto begin = values.begin();
auto end = values.end();

Multiplicities chunk( begin, end );

THEN( "a Multiplicities can be constructed and members can "
"be tested" ) {

verifyChunk( chunk );
} // THEN

THEN( "the record can be printed" ) {

std::string buffer;
auto output = std::back_inserter( buffer );
chunk.print( output );

CHECK( buffer == record );
} // THEN
} // WHEN
} // GIVEN

GIVEN( "invalid data for a Multiplicities instance" ) {

WHEN( "the number of reaction products is insufficient" ) {

THEN( "an exception is thrown" ) {

CHECK_THROWS( Multiplicities( 16, {}, {} ) );
} // THEN
} // WHEN

WHEN( "the number of reaction products and multiplcities is insufficient" ) {

THEN( "an exception is thrown" ) {

CHECK_THROWS( Multiplicities( 16, { 1, 92233 }, { 1 } ) );
} // THEN
} // WHEN

WHEN( "using iterators and the number of cross section values is "
"insufficient" ) {

std::vector< int > values = dataWithInsufficientLength();
auto begin = values.begin();
auto end = values.end();

THEN( "an exception is thrown" ) {

CHECK_THROWS( Multiplicities( begin, end ) );
} // THEN
} // WHEN
} // GIVEN
} // SCENARIO

std::string chunk() {

return " 16\n"
" 2\n"
" 1 2\n"
" 92234 1\n";
}

std::vector< int > data() {

return { 16,
2,
1, 2, 92234, 1 };
}

void verifyChunk( const Multiplicities& chunk ) {

CHECK( 16 == chunk.values()[0] );
CHECK( 2 == chunk.values()[1] );
CHECK( 1 == chunk.values()[2] );
CHECK( 2 == chunk.values()[3] );
CHECK( 92234 == chunk.values()[4] );
CHECK( 1 == chunk.values()[5] );

CHECK( false == chunk.empty() );
CHECK( 6 == chunk.size() );

CHECK( 2 == chunk.numberReactionProducts() );
CHECK( 16 == chunk.identifier() );
CHECK( 1 == chunk.reactionProducts()[0] );
CHECK( 92234 == chunk.reactionProducts()[1] );
CHECK( 2 == chunk.multiplicities()[0] );
CHECK( 1 == chunk.multiplicities()[1] );
}

std::vector< int > dataWithInsufficientLength() {

return { 16, 0 };
}

0 comments on commit 0160275

Please sign in to comment.