Skip to content

Commit

Permalink
Adding outgoing group structures
Browse files Browse the repository at this point in the history
  • Loading branch information
whaeck committed May 9, 2024
1 parent 70b5c60 commit 3314b62
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 24 deletions.
10 changes: 10 additions & 0 deletions python/src/MultigroupTable.python.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ void wrapMultigroupTable( python::module& module, python::module& ) {
&Table::structure,
"The primary group structure record"
)
.def(

"outgoing_structure",
&Table::outgoingStructure,
python::arg( "particle" ),
"The group structure record for an outgoing particle\n\n"
"Arguments:\n"
" self the metadata\n"
" particle the outgoing particle identifier"
)
.def_property_readonly(

"flux",
Expand Down
12 changes: 11 additions & 1 deletion python/src/multigroup/EnergyGroupStructure.python.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ void wrapEnergyGroupStructure( python::module& module, python::module& ) {
" self the table\n"
" boundaries the group structure boundaries"
)
.def(

python::init< unsigned int, std::vector< double > >(),
python::arg( "particle" ), python::arg( "boundaries" ),
"Initialise the record\n\n"
"Arguments:\n"
" self the table\n"
" particle the secondary particle identifier\n"
" boundaries the group structure boundaries"
)
.def_property_readonly(

"boundaries",
Expand All @@ -56,7 +66,7 @@ void wrapEnergyGroupStructure( python::module& module, python::module& ) {

"from_string",
[] ( const std::string& string, std::size_t number ) -> Record
{ return read< Record >( string, number ); },
{ return readWithSubtype< Record >( string, number ); },
python::arg( "string" ), python::arg( "number" ),
"Read the record from a string\n\n"
"An exception is raised if something goes wrong while reading the\n"
Expand Down
45 changes: 40 additions & 5 deletions python/src/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@
#include "tools/disco/FreeFormatCharacter.hpp"

/**
* @brief Read a record from a string
* @brief Read a record from a string (no subtype record)
*
* @param[in] string the string to read from
*/
template < typename Record, typename... Arguments >
Record read( const std::string& string, Arguments... arguments ) {

using namespace njoy::tools;
using namespace njoy::NDItk;

Record record;
auto iter = string.begin();
auto end = string.end();

std::string key = disco::FreeFormatCharacter::read< std::string >( iter, end );
if ( record.keyword() == key ) {
base::Keyword key( disco::FreeFormatCharacter::read< std::string >( iter, end ) );
if ( record.keyword() == key.keyword() ) {

//! @todo take into account _0 style keys
record.read( iter, end, arguments... );

//! @todo verify the string is now empty
Expand All @@ -35,9 +35,44 @@ Record read( const std::string& string, Arguments... arguments ) {

Log::error( "The record keyword is not the one expected" );
Log::info( "Expected: \'{}\'", record.keyword() );
Log::info( "Found: \'{}\'", key );
Log::info( "Found: \'{}\'", key.keyword() );
throw std::exception();
}
}

/**
* @brief Read a record from a string (subtype record)
*
* @param[in] string the string to read from
*/
template < typename Record, typename... Arguments >
Record readWithSubtype( const std::string& string, Arguments... arguments ) {

using namespace njoy::tools;
using namespace njoy::NDItk;

Record record;
auto iter = string.begin();
auto end = string.end();

base::Keyword key( disco::FreeFormatCharacter::read< std::string >( iter, end ) );
if ( key.keyword().find( record.keyword() ) == 0 ) {

if ( key.particle().has_value() ) {

record = Record( key.particle().value() );
}
record.read( iter, end, arguments... );

//! @todo verify the string is now empty
return record;
}
else {

Log::error( "The record keyword is not the one expected" );
Log::info( "Expected: \'{}\'", record.keyword() );
Log::info( "Found: \'{}\'", key.keyword() );
throw std::exception();
}
}
#endif
22 changes: 20 additions & 2 deletions python/test/Test_NDItk_MultigroupTable.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ def verify_chunk( self, chunk ) :
self.assertAlmostEqual( 2.53e-8, metadata.temperature )
self.assertAlmostEqual( 1e+10, metadata.dilution )
self.assertEqual( 7, metadata.number_groups )
self.assertEqual( 3, metadata.number_outgoing_groups( 0 ) )
self.assertEqual( 2, metadata.number_outgoing_groups( 1001 ) )
self.assertEqual( 2, metadata.number_reactions )

# verify content - energy boundaries
# verify content - primary energy boundaries
structure = chunk.structure
self.assertEqual( 7, structure.number_groups )
self.assertAlmostEqual( 20, structure.boundaries[0] )
Expand All @@ -43,6 +45,21 @@ def verify_chunk( self, chunk ) :
self.assertAlmostEqual( 1, structure.boundaries[6] )
self.assertAlmostEqual( 1e-11, structure.boundaries[7] )

# verify content - outgoing energy boundaries: 0
structure = chunk.outgoing_structure( 0 )
self.assertEqual( 3, structure.number_groups )
self.assertAlmostEqual( 20, structure.boundaries[0] )
self.assertAlmostEqual( 10, structure.boundaries[1] )
self.assertAlmostEqual( 5, structure.boundaries[2] )
self.assertAlmostEqual( 1e-11, structure.boundaries[3] )

# verify content - outgoing energy boundaries: 1001
structure = chunk.outgoing_structure( 1001 )
self.assertEqual( 2, structure.number_groups )
self.assertAlmostEqual( 20, structure.boundaries[0] )
self.assertAlmostEqual( 10, structure.boundaries[1] )
self.assertAlmostEqual( 1e-11, structure.boundaries[2] )

# verify content - flux weights
flux = chunk.flux
self.assertEqual( 7, flux.number_groups )
Expand Down Expand Up @@ -117,7 +134,8 @@ def verify_chunk( self, chunk ) :
process = '08/07/2013', awr = 233.0248, weight = 235.043937521619,
temperature = 2.53e-8, dilution = 1e+10,
structure = EnergyGroupStructure( [ 20., 18., 16., 14., 10., 5, 1, 1e-11 ] ),
outgoing = [],
outgoing = [ EnergyGroupStructure( 0, [ 20., 10., 5, 1e-11 ] ),
EnergyGroupStructure( 1001, [ 20., 10., 1e-11 ] )],
flux = FluxWeights( [ 0.1, 0.2, 0.25, 0.05, 0.15, 0.04, 0.06 ] ),
xs = ReactionCrossSections(
xs = [ CrossSection( 2, 0., [ 10., 20., 30., 40., 50., 60., 70. ] ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class Test_NDItk_multigroup_EnergyGroupStructure( unittest.TestCase ) :
' 20 18 16 14 10\n'
' 5 1 1e-11\n' )

chunk_outgoing_values = [ 20, 10, 1e-11 ]
chunk_outgoing_string = ( 'e_bounds_1001\n'
' 20 10 1e-11\n' )

def test_component( self ) :

def verify_chunk( self, chunk ) :
Expand Down Expand Up @@ -41,6 +45,26 @@ def verify_chunk( self, chunk ) :

self.assertAlmostEqual( self.chunk_values[index], values[index] )

def verify_outgoing_chunk( self, chunk ) :

# verify content
self.assertEqual( 2, chunk.number_groups )
self.assertAlmostEqual( 20, chunk.boundaries[0] )
self.assertAlmostEqual( 10, chunk.boundaries[1] )
self.assertAlmostEqual( 1e-11, chunk.boundaries[2] )

self.assertEqual( self.chunk_outgoing_string, chunk.to_string() )

# verify the record
self.assertEqual( 'e_bounds_1001', chunk.keyword )
self.assertEqual( False, chunk.empty )
self.assertEqual( 3, chunk.size )

values = chunk.values
for index in range( chunk.size ) :

self.assertAlmostEqual( self.chunk_outgoing_values[index], values[index] )

# the data is given explicitly
chunk = EnergyGroupStructure( boundaries = [ 20., 18., 16., 14., 10., 5, 1, 1e-11 ] )

Expand All @@ -51,6 +75,16 @@ def verify_chunk( self, chunk ) :

verify_chunk( self, chunk )

# the data is given explicitly for an outgoing particle
chunk = EnergyGroupStructure( particle = 1001, boundaries = [ 20., 10., 1e-11 ] )

verify_outgoing_chunk( self, chunk )

# the data is read from a string for an outgoing particle
chunk = EnergyGroupStructure.from_string( self.chunk_outgoing_string, 3 )

verify_outgoing_chunk( self, chunk )

if __name__ == '__main__' :

unittest.main()
32 changes: 28 additions & 4 deletions src/NDItk/MultigroupTable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ class MultigroupTable {

/* auxiliary functions */

#include "NDItk/MultigroupTable/src/generateOutgoingStructureMetadata.hpp"
#include "NDItk/MultigroupTable/src/readRecord.hpp"
#include "NDItk/MultigroupTable/src/readPrimaryStructure.hpp"
#include "NDItk/MultigroupTable/src/readOutgoingStructure.hpp"
#include "NDItk/MultigroupTable/src/verify.hpp"

public:
Expand All @@ -51,6 +54,29 @@ class MultigroupTable {
*/
const multigroup::EnergyGroupStructure& structure() const { return this->primary_structure_; }

/**
* @brief Return the group structure record for an outgoing particle
*/
const multigroup::EnergyGroupStructure& outgoingStructure( unsigned int particle ) const {

auto pos = std::lower_bound( this->outgoing_structure_.begin(),
this->outgoing_structure_.end(),
particle,
[] ( auto&& left, auto&& right ) {

return left.particle() < right;
} );
if ( pos != this->outgoing_structure_.end() ) {

if ( pos->particle() == particle ) {

return *pos;
}
}
Log::error( "The requested outgoing particle \'{}\' has no outgoing group structure", particle );
throw std::exception();
}

/**
* @brief Return the flux weight record
*/
Expand Down Expand Up @@ -85,13 +111,11 @@ class MultigroupTable {

this->metadata_.print( iter );
this->primary_structure_.print( iter );
for ( const auto& entry : this->outgoing_structure_ ) { entry.print( iter ); }
this->weights_.print( iter );
this->xs_.print( iter );
this->release_.print( iter );
*iter++ = 'e';
*iter++ = 'n';
*iter++ = 'd';
*iter++ = '\n';
base::Keyword( "end" ).print( iter );
};
};

Expand Down
3 changes: 2 additions & 1 deletion src/NDItk/MultigroupTable/src/ctor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ MultigroupTable( std::string zaid, std::string libname, std::string source,
std::optional< multigroup::AverageFissionEnergyRelease > release = std::nullopt ) :
metadata_( std::move( zaid ), std::move( libname ), std::move( source ),
std::move( process ), awr, weight, temperature, dilution,
xs.numberGroups(), {}, xs.numberReactions() ),
structure.numberGroups(), generateOutgoingStructureMetadata( outgoing ),
xs.numberReactions() ),
primary_structure_( std::move( structure ) ),
outgoing_structure_( std::move( outgoing ) ),
weights_( std::move( weigths ) ),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
static std::map< unsigned int, unsigned int >
generateOutgoingStructureMetadata( const std::vector< multigroup::EnergyGroupStructure >& outgoing ) {

std::map< unsigned int, unsigned int > metadata;
for ( const auto& entry : outgoing ) {

unsigned int particle = entry.particle().value();
if ( metadata.find( particle ) != metadata.end() ) {

Log::error( "Found duplicate outgoing group structure for particle \'{}\'", particle );
throw std::exception();
}
metadata[ particle ] = entry.numberGroups();
}
return metadata;
}
11 changes: 4 additions & 7 deletions src/NDItk/MultigroupTable/src/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@ void read( Iterator& iter, const Iterator& end ) {

this->metadata_.read( keyword, iter, end );
}
else if ( keyword == this->primary_structure_.keyword() ) {
else if ( keyword.find( this->primary_structure_.keyword() ) == 0 ) {

if ( this->metadata_.numberGroups().has_value() ) {
if ( keyword == this->primary_structure_.keyword() ) {

readRecord( this->primary_structure_, iter, end,
this->metadata_.numberGroups().value() + 1 );
readPrimaryStructure( iter, end );
}
else {

Log::error( "Metadata required for the \'\' record was not found", keyword );
Log::info( "Required metadata is missing: number of groups in the primary group structure" );
throw std::exception();
readOutgoingStructure( keyword, iter, end );
}
}
else if ( keyword == this->weights_.keyword() ) {
Expand Down
32 changes: 32 additions & 0 deletions src/NDItk/MultigroupTable/src/readOutgoingStructure.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
template< typename Iterator >
void readOutgoingStructure( const std::string& key, Iterator& iter, const Iterator& end ) {

base::Keyword secondary( key );
unsigned int particle = secondary.particle().value();
if ( this->metadata_.numberOutgoingGroups( particle ).has_value() ) {

auto pos = std::lower_bound( this->outgoing_structure_.begin(),
this->outgoing_structure_.end(),
particle,
[] ( auto&& left, auto&& right ) {

return left.particle() < right;
} );
if ( pos != this->outgoing_structure_.end() ) {

if ( pos->particle() == particle ) {

Log::error( "Duplicate keyword found: \'{}\'", secondary.keyword() );
throw std::exception();
}
}
pos = this->outgoing_structure_.insert( pos, multigroup::EnergyGroupStructure( particle ) );
readRecord( *pos, iter, end, this->metadata_.numberOutgoingGroups( particle ).value() + 1 );
}
else {

Log::error( "Metadata required for the \'\' record was not found", secondary.keyword() );
Log::info( "Required metadata is missing: number of groups in the outgoing group structure" );
throw std::exception();
}
}
15 changes: 15 additions & 0 deletions src/NDItk/MultigroupTable/src/readPrimaryStructure.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
template< typename Iterator >
void readPrimaryStructure( Iterator& iter, const Iterator& end ) {

if ( this->metadata_.numberGroups().has_value() ) {

readRecord( this->primary_structure_, iter, end,
this->metadata_.numberGroups().value() + 1 );
}
else {

Log::error( "Metadata required for the \'\' record was not found", this->primary_structure_.keyword() );
Log::info( "Required metadata is missing: number of groups in the primary group structure" );
throw std::exception();
}
}
Loading

0 comments on commit 3314b62

Please sign in to comment.