diff --git a/python/src/MultigroupTable.python.cpp b/python/src/MultigroupTable.python.cpp index 7858a9c..ab22a11 100644 --- a/python/src/MultigroupTable.python.cpp +++ b/python/src/MultigroupTable.python.cpp @@ -22,6 +22,7 @@ void wrapMultigroupTable( python::module& module, python::module& ) { using ReactionCrossSections = njoy::NDItk::multigroup::ReactionCrossSections; using AverageFissionEnergyRelease = njoy::NDItk::multigroup::AverageFissionEnergyRelease; using OutgoingParticleTypes = njoy::NDItk::multigroup::OutgoingParticleTypes; + using OutgoingParticleTransportData = njoy::NDItk::multigroup::OutgoingParticleTransportData; using HeatingNumbers = njoy::NDItk::multigroup::HeatingNumbers; using Kerma = njoy::NDItk::multigroup::Kerma; @@ -51,6 +52,7 @@ void wrapMultigroupTable( python::module& module, python::module& ) { std::optional< TotalCrossSection >, std::optional< AverageFissionEnergyRelease >, std::optional< OutgoingParticleTypes >, + std::optional< OutgoingParticleTransportData >, std::optional< HeatingNumbers >, std::vector< HeatingNumbers >, std::optional< Kerma >, @@ -66,6 +68,7 @@ void wrapMultigroupTable( python::module& module, python::module& ) { python::arg( "total" ) = std::nullopt, python::arg( "release" ) = std::nullopt, python::arg( "types" ) = std::nullopt, + python::arg( "transport" ) = std::nullopt, python::arg( "primary_heating" ) = std::nullopt, python::arg( "outgoing_heating" ) = std::vector< HeatingNumbers >{}, python::arg( "primary_kerma" ) = std::nullopt, @@ -90,6 +93,7 @@ void wrapMultigroupTable( python::module& module, python::module& ) { " total the total cross section (optional)\n" " release the average fission energy release data (optional)\n" " types the outgoing particle types (optional)\n" + " transport the outgoing particle transport data (optional)\n" " primary_heating the primary heating numbers (optional)\n" " outgoing_heating the outgoing particle heating numbers (optional)\n" " primary_kerma the primary kerma (optional)\n" @@ -107,16 +111,6 @@ void wrapMultigroupTable( python::module& module, python::module& ) { &Table::primaryGroupBoundaries, "The primary group structure record" ) - .def( - - "outgoing_group_boundaries", - &Table::outgoingGroupBoundaries, - python::arg( "particle" ), - "The group structure record for an outgoing particle\n\n" - "Arguments:\n" - " self the table\n" - " particle the outgoing particle identifier" - ) .def_property_readonly( "velocities", @@ -147,6 +141,18 @@ void wrapMultigroupTable( python::module& module, python::module& ) { &Table::averageFissionEnergyRelease, "The average fission energy release record" ) + .def_property_readonly( + + "primary_heating_numbers", + &Table::primaryHeatingNumbers, + "The primary heating numbers record" + ) + .def_property_readonly( + + "primary_kerma", + &Table::primaryKerma, + "The primary kerma record" + ) .def_property_readonly( "outgoing_particle_types", @@ -155,9 +161,19 @@ void wrapMultigroupTable( python::module& module, python::module& ) { ) .def_property_readonly( - "primary_heating_numbers", - &Table::primaryHeatingNumbers, - "The primary heating numbers record" + "outgoing_particle_transport_data", + &Table::outgoingParticleTransportData, + "The outgoing particle transport data record" + ) + .def( + + "outgoing_group_boundaries", + &Table::outgoingGroupBoundaries, + python::arg( "particle" ), + "The group structure record for an outgoing particle\n\n" + "Arguments:\n" + " self the table\n" + " particle the outgoing particle identifier" ) .def( @@ -169,12 +185,6 @@ void wrapMultigroupTable( python::module& module, python::module& ) { " self the table\n" " particle the outgoing particle identifier" ) - .def_property_readonly( - - "primary_kerma", - &Table::primaryKerma, - "The primary kerma record" - ) .def( "outgoing_kerma", diff --git a/python/test/Test_NDItk_MultigroupTable.py b/python/test/Test_NDItk_MultigroupTable.py index de19ba5..a2c7963 100644 --- a/python/test/Test_NDItk_MultigroupTable.py +++ b/python/test/Test_NDItk_MultigroupTable.py @@ -14,6 +14,8 @@ from NDItk.multigroup import Velocities from NDItk.multigroup import HeatingNumbers from NDItk.multigroup import Kerma +from NDItk.multigroup import OutgoingParticleTypes +from NDItk.multigroup import OutgoingParticleTransportData class Test_NDItk_MultigroupTable( unittest.TestCase ) : """Unit test for the MultigroupTable class.""" @@ -49,21 +51,6 @@ def verify_chunk( self, chunk ) : self.assertAlmostEqual( 1, structure.values[6] ) self.assertAlmostEqual( 1e-11, structure.values[7] ) - # verify content - outgoing energy boundaries: 0 - structure = chunk.outgoing_group_boundaries( 0 ) - self.assertEqual( 3, structure.number_groups ) - self.assertAlmostEqual( 20, structure.values[0] ) - self.assertAlmostEqual( 10, structure.values[1] ) - self.assertAlmostEqual( 5, structure.values[2] ) - self.assertAlmostEqual( 1e-11, structure.values[3] ) - - # verify content - outgoing energy boundaries: 1001 - structure = chunk.outgoing_group_boundaries( 1001 ) - self.assertEqual( 2, structure.number_groups ) - self.assertAlmostEqual( 20, structure.values[0] ) - self.assertAlmostEqual( 10, structure.values[1] ) - self.assertAlmostEqual( 1e-11, structure.values[2] ) - # verify content - velocities velocities = chunk.velocities self.assertEqual( 7, velocities.number_groups ) @@ -166,18 +153,17 @@ def verify_chunk( self, chunk ) : self.assertAlmostEqual( 66, heating.values[5] ) self.assertAlmostEqual( 77, heating.values[6] ) - # verify content - outgoing heating numbers: 0 - heating = chunk.outgoing_heating_numbers( 0 ) - self.assertEqual( 3, heating.number_groups ) - self.assertAlmostEqual( 21 , heating.values[0] ) - self.assertAlmostEqual( 11 , heating.values[1] ) - self.assertAlmostEqual( 5.1, heating.values[2] ) + # verify content - outgoing particle types + types = chunk.outgoing_particle_types + self.assertEqual( 2, types.number_outgoing_particles ) + self.assertEqual( 0, types.values[0] ) + self.assertEqual( 1001, types.values[1] ) - # verify content - outgoing energy boundaries: 1001 - heating = chunk.outgoing_heating_numbers( 1001 ) - self.assertEqual( 2, heating.number_groups ) - self.assertAlmostEqual( 25, heating.values[0] ) - self.assertAlmostEqual( 15, heating.values[1] ) + # verify content - outgoing particle transport data + transport = chunk.outgoing_particle_transport_data + self.assertEqual( 2, transport.number_outgoing_particles ) + self.assertEqual( '92000', transport.values[0] ) + self.assertEqual( '92235.proton', transport.values[1] ) # verify content - primary kerma kerma = chunk.primary_kerma @@ -190,6 +176,34 @@ def verify_chunk( self, chunk ) : self.assertAlmostEqual( 660, kerma.values[5] ) self.assertAlmostEqual( 770, kerma.values[6] ) + # verify content - outgoing energy boundaries: 0 + structure = chunk.outgoing_group_boundaries( 0 ) + self.assertEqual( 3, structure.number_groups ) + self.assertAlmostEqual( 20, structure.values[0] ) + self.assertAlmostEqual( 10, structure.values[1] ) + self.assertAlmostEqual( 5, structure.values[2] ) + self.assertAlmostEqual( 1e-11, structure.values[3] ) + + # verify content - outgoing energy boundaries: 1001 + structure = chunk.outgoing_group_boundaries( 1001 ) + self.assertEqual( 2, structure.number_groups ) + self.assertAlmostEqual( 20, structure.values[0] ) + self.assertAlmostEqual( 10, structure.values[1] ) + self.assertAlmostEqual( 1e-11, structure.values[2] ) + + # verify content - outgoing heating numbers: 0 + heating = chunk.outgoing_heating_numbers( 0 ) + self.assertEqual( 3, heating.number_groups ) + self.assertAlmostEqual( 21 , heating.values[0] ) + self.assertAlmostEqual( 11 , heating.values[1] ) + self.assertAlmostEqual( 5.1, heating.values[2] ) + + # verify content - outgoing heating numbers: 1001 + heating = chunk.outgoing_heating_numbers( 1001 ) + self.assertEqual( 2, heating.number_groups ) + self.assertAlmostEqual( 25, heating.values[0] ) + self.assertAlmostEqual( 15, heating.values[1] ) + # verify content - outgoing kerma: 0 kerma = chunk.outgoing_kerma( 0 ) self.assertEqual( 3, kerma.number_groups ) @@ -208,8 +222,6 @@ 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.123456789, 16.0000000000001, 14., 10., 5, 1, 1e-11 ] ), - outgoing = [ EnergyGroupStructure( 0, [ 20., 10., 5, 1e-11 ] ), - EnergyGroupStructure( 1001, [ 20., 10., 1e-11 ] ) ], velocities = Velocities( [ 2.1, 2.2, 2.25, 2.05, 2.15, 2.04, 2.06 ] ), flux = FluxWeights( [ 0.1, 0.2, 0.25, 0.05, 0.15, 0.04, 0.06 ] ), total = TotalCrossSection( [ 1.1, 1.2, 1.25, 1.05, 1.15, 1.04, 1.06 ] ), @@ -219,9 +231,13 @@ def verify_chunk( self, chunk ) : release = AverageFissionEnergyRelease( 202.827, 181.238898, 4.827645, 7.281253, 6.5, 169.13 ), primary_heating = HeatingNumbers( [ 11., 22., 33., 44., 55., 66., 77. ] ), + primary_kerma = Kerma( [ 110., 220., 330., 440., 550., 660., 770. ] ), + types = OutgoingParticleTypes( [ 0, 1001 ] ), + transport = OutgoingParticleTransportData( [ "92000", "92235.proton" ] ), + outgoing = [ EnergyGroupStructure( 0, [ 20., 10., 5, 1e-11 ] ), + EnergyGroupStructure( 1001, [ 20., 10., 1e-11 ] ) ], outgoing_heating = [ HeatingNumbers( 0, [ 21., 11., 5.1 ] ), HeatingNumbers( 1001, [ 25., 15. ] ) ], - primary_kerma = Kerma( [ 110., 220., 330., 440., 550., 660., 770. ] ), outgoing_kerma = [ Kerma( 0, [ 210., 110., 51. ] ), Kerma( 1001, [ 250., 150. ] ) ] ) diff --git a/src/NDItk/MultigroupTable.hpp b/src/NDItk/MultigroupTable.hpp index dfe0127..57f9b8d 100644 --- a/src/NDItk/MultigroupTable.hpp +++ b/src/NDItk/MultigroupTable.hpp @@ -13,6 +13,7 @@ #include "NDItk/multigroup/TotalCrossSection.hpp" #include "NDItk/multigroup/AverageFissionEnergyRelease.hpp" #include "NDItk/multigroup/OutgoingParticleTypes.hpp" +#include "NDItk/multigroup/OutgoingParticleTransportData.hpp" #include "NDItk/multigroup/HeatingNumbers.hpp" #include "NDItk/multigroup/Kerma.hpp" @@ -36,6 +37,7 @@ class MultigroupTable { multigroup::HeatingNumbers primary_heating_; multigroup::Kerma primary_kerma_; multigroup::OutgoingParticleTypes outgoing_particles_; + multigroup::OutgoingParticleTransportData outgoing_zaids_; std::vector< multigroup::EnergyGroupStructure > outgoing_structure_; std::vector< multigroup::HeatingNumbers > outgoing_heating_; std::vector< multigroup::Kerma > outgoing_kerma_; @@ -134,6 +136,15 @@ class MultigroupTable { return this->outgoing_particles_; } + /** + * @brief Return the outgoing particle transport data record + */ + const multigroup::OutgoingParticleTransportData& + outgoingParticleTransportData() const { + + return this->outgoing_zaids_; + } + /** * @brief Return the group structure record for an outgoing particle */ @@ -228,6 +239,7 @@ class MultigroupTable { this->primary_heating_.print( iter ); this->primary_kerma_.print( iter ); this->outgoing_particles_.print( iter ); + this->outgoing_zaids_.print( iter ); for ( const auto& entry : this->outgoing_structure_ ) { entry.print( iter ); } for ( const auto& entry : this->outgoing_heating_ ) { entry.print( iter ); } for ( const auto& entry : this->outgoing_kerma_ ) { entry.print( iter ); } diff --git a/src/NDItk/MultigroupTable/src/ctor.hpp b/src/NDItk/MultigroupTable/src/ctor.hpp index 3e3e107..126ee71 100644 --- a/src/NDItk/MultigroupTable/src/ctor.hpp +++ b/src/NDItk/MultigroupTable/src/ctor.hpp @@ -28,6 +28,7 @@ MultigroupTable() : * @param[in] weight the atomic weight of the target (optional) * @param[in] release the average fission energy release data (optional) * @param[in] types the outgoing particle types (optional) + * @param[in] transport the outgoing particle transport data (optional) * @param[in] primaryHeating the primary particle heating numbers (optional) * @param[in] outgoingHeating the outgoing particles' heating numbers (optional) * @param[in] primaryKerma the primary particle kerma (optional) @@ -46,6 +47,7 @@ MultigroupTable( std::string zaid, std::string libname, std::optional< multigroup::TotalCrossSection > total = std::nullopt, std::optional< multigroup::AverageFissionEnergyRelease > release = std::nullopt, std::optional< multigroup::OutgoingParticleTypes > types = std::nullopt, + std::optional< multigroup::OutgoingParticleTransportData > transport = std::nullopt, std::optional< multigroup::HeatingNumbers > primaryHeating = std::nullopt, std::vector< multigroup::HeatingNumbers > outgoingHeating = {}, std::optional< multigroup::Kerma > primaryKerma = std::nullopt, @@ -80,5 +82,9 @@ MultigroupTable( std::string zaid, std::string libname, this->outgoing_particles_ = std::move( types.value() ); } + if ( transport.has_value() ) { + + this->outgoing_zaids_ = std::move( transport.value() ); + } this->verify(); } \ No newline at end of file diff --git a/src/NDItk/MultigroupTable/src/read.hpp b/src/NDItk/MultigroupTable/src/read.hpp index 9f2c107..ede8fcf 100644 --- a/src/NDItk/MultigroupTable/src/read.hpp +++ b/src/NDItk/MultigroupTable/src/read.hpp @@ -130,7 +130,21 @@ void read( Iterator& iter, const Iterator& 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" ); + Log::info( "Required metadata is missing: number of outgoing particle types" ); + throw std::exception(); + } + } + // outgoing particle transport data + else if ( keyword == this->outgoing_zaids_.keyword() ) { + + if ( this->metadata_.numberOutgoingParticles().has_value() ) { + + readRecord( this->outgoing_zaids_, iter, end, this->metadata_.numberOutgoingParticles().value() ); + } + else { + + Log::error( "Metadata required for the \'\' record was not found", keyword ); + Log::info( "Required metadata is missing: number of outgoing particle types" ); throw std::exception(); } } diff --git a/src/NDItk/MultigroupTable/test/MultigroupTable.test.cpp b/src/NDItk/MultigroupTable/test/MultigroupTable.test.cpp index 1bd5c35..b9b2bbf 100644 --- a/src/NDItk/MultigroupTable/test/MultigroupTable.test.cpp +++ b/src/NDItk/MultigroupTable/test/MultigroupTable.test.cpp @@ -46,6 +46,7 @@ SCENARIO( "MultigroupTable" ) { 7.281253, 6.5, 169.13 ); multigroup::HeatingNumbers primaryHeating( { 11., 22., 33., 44., 55., 66., 77. } ); multigroup::OutgoingParticleTypes types( { 0, 1001 } ); + multigroup::OutgoingParticleTransportData transport( { "92000", "92235.proton" } ); std::vector< multigroup::HeatingNumbers > outgoingHeating = { { 0, { 21., 11., 5.1 } }, { 1001, { 25., 15. } } @@ -62,7 +63,7 @@ SCENARIO( "MultigroupTable" ) { std::move( velocities ), std::move( weights ), std::move( xs ), std::move( source ), weight, std::move( total ), std::move( release ), - std::move( types ), + std::move( types ), std::move( transport ), std::move( primaryHeating ), std::move( outgoingHeating ), std::move( primaryKerma ), std::move( outgoingKerma ) ); @@ -142,6 +143,7 @@ SCENARIO( "MultigroupTable" ) { multigroup::AverageFissionEnergyRelease release( 202.827, 181.238898, 4.827645, 7.281253, 6.5, 169.13 ); multigroup::OutgoingParticleTypes types( { 0, 1001 } ); + multigroup::OutgoingParticleTransportData transport( { "92000", "92235.proton" } ); multigroup::HeatingNumbers primaryHeating( { 11., 22., 33., 44., 55., 66., 77. } ); std::vector< multigroup::HeatingNumbers > outgoingHeating = { { 0, { 21., 11., 5.1 } }, @@ -161,7 +163,7 @@ SCENARIO( "MultigroupTable" ) { std::move( weights ), std::move( xs ), std::move( source ), weight, std::move( total ), std::move( release ), - std::move( types ), + std::move( types ), std::move( transport ), std::move( primaryHeating ), std::move( outgoingHeating ), std::move( primaryKerma ), std::move( outgoingKerma ) ) ); } // THEN @@ -227,6 +229,8 @@ std::string chunk() { " 660 770\n" "sec_part_types\n" " 0 1001\n" + "sec_part_zaids\n" + " 92000 92235.proton\n" "e_bounds_0\n" " 20 10 5 1e-11\n" "e_bounds_1001\n" @@ -430,6 +434,16 @@ void verifyChunk( const MultigroupTable& chunk ) { CHECK( 0 == types.values()[0] ); CHECK( 1001 == types.values()[1] ); + // outgoing particle transport data + auto transport = chunk.outgoingParticleTransportData(); + CHECK( "sec_part_zaids" == transport.keyword() ); + CHECK( false == transport.empty() ); + CHECK( 2 == transport.size() ); + CHECK( 2 == transport.values().size() ); + CHECK( 2 == transport.numberOutgoingParticles() ); + CHECK( "92000" == transport.values()[0] ); + CHECK( "92235.proton" == transport.values()[1] ); + // outgoing group structure: 0 structure = chunk.outgoingGroupBoundaries( 0 ); CHECK( "e_bounds_0" == structure.keyword() );