diff --git a/CMakeLists.txt b/CMakeLists.txt index b6a8a7236..96f23a432 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -771,7 +771,7 @@ target_sources( ENDFtk INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk/syntaxTree/File/src/parse.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk/syntaxTree/Section/src/ctor.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk/syntaxTree/Section/src/findEnd.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk/syntaxTree/Section/src/parse.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk/syntaxTree/Section/src/parse-endf.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk/syntaxTree/Tape/src/createMap.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk/syntaxTree/Tape/src/materialNumber.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/ENDFtk/syntaxTree/Tape/src/ctor.hpp" @@ -926,10 +926,15 @@ if( NOT is_subproject ) add_subdirectory( src/ENDFtk/section/8/457/DiscreteSpectrum/test ) add_subdirectory( src/ENDFtk/section/Base/test ) add_subdirectory( src/ENDFtk/section/BaseWithoutMT/test ) + add_subdirectory( src/ENDFtk/section/GendfBase/test ) + add_subdirectory( src/ENDFtk/section/Gendf3/test ) + add_subdirectory( src/ENDFtk/section/Gendf6/test ) add_subdirectory( src/ENDFtk/syntaxTree/File/test ) add_subdirectory( src/ENDFtk/syntaxTree/Material/test ) + add_subdirectory( src/ENDFtk/syntaxTree/GendfMaterial/test ) add_subdirectory( src/ENDFtk/syntaxTree/Section/test ) add_subdirectory( src/ENDFtk/syntaxTree/Tape/test ) + add_subdirectory( src/ENDFtk/GendfDataRecord/test ) endif() endif() @@ -949,4 +954,4 @@ install( DIRECTORY src// DESTINATION include FILES_MATCHING REGEX ".*\.h[+][+]$|.*\.hxx$|.*\.hpp$|.*\.hh$|.*\.h$" ) INCLUDE(CPack) - \ No newline at end of file + diff --git a/src/ENDFtk.hpp b/src/ENDFtk.hpp index 2cfd2f9e3..d44734020 100644 --- a/src/ENDFtk.hpp +++ b/src/ENDFtk.hpp @@ -72,6 +72,8 @@ using TAB1 = TabulationRecord; #include "ENDFtk/InterpolationSequenceRecord.hpp" +#include "ENDFtk/GendfDataRecord.hpp" + #include "ENDFtk/resonanceParameters.hpp" #include "ENDFtk/section.hpp" diff --git a/src/ENDFtk/GendfDataRecord.hpp b/src/ENDFtk/GendfDataRecord.hpp new file mode 100644 index 000000000..82b9d69e9 --- /dev/null +++ b/src/ENDFtk/GendfDataRecord.hpp @@ -0,0 +1,46 @@ +class GendfDataRecord : protected ListRecord { + +protected: + + int num_legendre_; + int num_sigma0_; + +public: + + /* constructor */ + #include "ENDFtk/GendfDataRecord/src/ctor.hpp" + + /* getters */ + double temperature() const { return this->C1(); }; + int NG2() const { return this->L1(); } + int numSecondaryPositions() const { return NG2(); } + int IG2LO() const { return this->L2(); } + int lowestGroup() const { return IG2LO(); }; + int IG() const { return this->N2(); } + int group() const { return IG(); } + + /* + * @brief Return the flux values. + * @note All GENDF data records (aside from MFD 1&5) include a + * matrix of the flux computed by NJOY for the group, + * given in an NLxNZ matrix. This results in a large degree + * of redundancy. + */ + auto flux() const { + return this->list() + | ranges::view::take_exactly( num_legendre_ * num_sigma0_ ); + } + + /* + * @brief Return the non-flux values. + * @note Included in the values is one of: + * - vector cross sections (NLxNZ) + * - ratio and cross sections (both NLxNZ) + * - matrix elements (NLxNZxNG) + */ + auto values() const { + return this->list() + | ranges::view::drop_exactly( num_legendre_ * num_sigma0_ ); + } + +}; diff --git a/src/ENDFtk/GendfDataRecord/src/ctor.hpp b/src/ENDFtk/GendfDataRecord/src/ctor.hpp new file mode 100644 index 000000000..287bef82d --- /dev/null +++ b/src/ENDFtk/GendfDataRecord/src/ctor.hpp @@ -0,0 +1,12 @@ +template< typename Iterator > +GendfDataRecord( Iterator& it, + const Iterator& end, + long& lineNumber, + int num_legendre, + int num_sigma0, + int MAT, + int MF, + int MT ) + : ListRecord( it, end, lineNumber, MAT, MF, MT ), + num_legendre_( num_legendre ), + num_sigma0_( num_sigma0 ) {} diff --git a/src/ENDFtk/GendfDataRecord/test/CMakeLists.txt b/src/ENDFtk/GendfDataRecord/test/CMakeLists.txt new file mode 100644 index 000000000..cf5419617 --- /dev/null +++ b/src/ENDFtk/GendfDataRecord/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.GendfDataRecord.test GendfDataRecord.test.cpp ) +target_compile_options( ENDFtk.GendfDataRecord.test PRIVATE ${${PREFIX}_common_flags} +$<$:${${PREFIX}_strict_flags}>$<$: +${${PREFIX}_DEBUG_flags} +$<$:${${PREFIX}_coverage_flags}>> +$<$: +${${PREFIX}_RELEASE_flags} +$<$:${${PREFIX}_link_time_optimization_flags}> +$<$:${${PREFIX}_nonportable_optimization_flags}>> + +${CXX_appended_flags} ${ENDFtk_appended_flags} ) +target_link_libraries( ENDFtk.GendfDataRecord.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.GendfDataRecord COMMAND ENDFtk.GendfDataRecord.test ) diff --git a/src/ENDFtk/GendfDataRecord/test/GendfDataRecord.test.cpp b/src/ENDFtk/GendfDataRecord/test/GendfDataRecord.test.cpp new file mode 100644 index 000000000..aef173f4f --- /dev/null +++ b/src/ENDFtk/GendfDataRecord/test/GendfDataRecord.test.cpp @@ -0,0 +1,46 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk.hpp" + +using namespace njoy::ENDFtk; + + +std::string getMFD3Record(); + + +SCENARIO( "reading a GendfDataRecord" ) { + GIVEN( "a string representation" ) { + WHEN( "a valid record is given" ) { + + std::string buffer = getMFD3Record(); + + auto begin = buffer.begin(); + auto end = buffer.end(); + long int lineNo = 2; + + THEN( "the object can be created" ) { + GendfDataRecord record( begin, end, lineNo, 1, 1, 9228, 3, 2 ); + + // check data + CHECK( record.temperature() == Approx(293.6) ); + CHECK( record.NG2() == 2 ); + CHECK( record.numSecondaryPositions() == 2 ); + CHECK( record.IG2LO() == 1 ); + CHECK( record.lowestGroup() == 1 ); + CHECK( record.IG() == 1 ); + CHECK( record.group() == 1); + CHECK( record.flux()[0] == Approx(8.86484e+4) ); + CHECK( record.values()[0] == Approx(14.69141) ); + } + } + } +} + + +std::string getMFD3Record() { + return + " 2.936000+2 0.000000+0 2 1 2 19228 3 2 2\n" + " 8.864840+4 1.469141+1 9228 3 2 3\n"; +} + diff --git a/src/ENDFtk/section.hpp b/src/ENDFtk/section.hpp index 64c14a4e7..23d734876 100644 --- a/src/ENDFtk/section.hpp +++ b/src/ENDFtk/section.hpp @@ -16,4 +16,13 @@ class Type; #include "ENDFtk/section/8.hpp" #include "ENDFtk/section/12.hpp" #include "ENDFtk/section/13.hpp" + +#include "ENDFtk/section/GendfBase.hpp" + +template< int MF, int... OptionalMT > +class GendfType; + +#include "ENDFtk/section/Gendf3.hpp" +#include "ENDFtk/section/Gendf6.hpp" + } diff --git a/src/ENDFtk/section/3.hpp b/src/ENDFtk/section/3.hpp old mode 100755 new mode 100644 diff --git a/src/ENDFtk/section/Base.hpp b/src/ENDFtk/section/Base.hpp old mode 100755 new mode 100644 diff --git a/src/ENDFtk/section/Gendf3.hpp b/src/ENDFtk/section/Gendf3.hpp new file mode 100644 index 000000000..7bebfe4cd --- /dev/null +++ b/src/ENDFtk/section/Gendf3.hpp @@ -0,0 +1,29 @@ +template<> +class GendfType< 3 > : protected GendfBase { + +protected: + + +public: + + /* constructor */ + #include "ENDFtk/section/Gendf3/src/ctor.hpp" + + /* methods */ + #include "ENDFtk/section/Gendf3/src/getCrossSection.hpp" + + /* getters inherited from GendfBase */ + using GendfBase::legendreOrder; + using GendfBase::numLegendre; + using GendfBase::numSigma0; + using GendfBase::breakupFlag; + using GendfBase::numGroups; + using GendfBase::temperature; + + /* getters inherited from Base */ + using GendfBase::MT; + using GendfBase::ZA; + using GendfBase::AWR; + using GendfBase::atomicWeightRatio; + +}; diff --git a/src/ENDFtk/section/Gendf3/src/ctor.hpp b/src/ENDFtk/section/Gendf3/src/ctor.hpp new file mode 100644 index 000000000..045e67f9f --- /dev/null +++ b/src/ENDFtk/section/Gendf3/src/ctor.hpp @@ -0,0 +1,15 @@ +template< typename BufferIterator > +GendfType( HeadRecord& head, + BufferIterator& begin, + const BufferIterator& end, + long& lineNumber, + int MAT ) + : GendfBase( head, begin, end, lineNumber, MAT ) { + + // TODO: Add support for ratio quantities + if( data_.at(num_groups_).NG2() == 3 ) { + Log::info( "ENDFtk does not yet support ratio quantities." ); + throw std::exception(); + } + +} diff --git a/src/ENDFtk/section/Gendf3/src/getCrossSection.hpp b/src/ENDFtk/section/Gendf3/src/getCrossSection.hpp new file mode 100644 index 000000000..088cdda25 --- /dev/null +++ b/src/ENDFtk/section/Gendf3/src/getCrossSection.hpp @@ -0,0 +1,44 @@ +/* + * @brief Return cross section value. + * @param group GENDF group index (1-based, low group = low energy) + * @param order Legendre order + * @param idil Index of dilution (0-based) + */ +double getCrossSection( int group, + int order, + int idil ) { + + // error checking + if( order > legendreOrder() ) { + Log::info( "{} is greater than Legendre order of dataset ({})", + order, legendreOrder() ); + throw std::exception(); + } + else if( idil >= num_sigma0_ ) { + Log::info( "Index {} exceeds number of dilutions in dataset ({})", + idil, num_sigma0_ ); + throw std::exception(); + } + else if( group <= 0 or group > num_groups_ ) { + Log::info( "Group {} is invalid with {} groups", + group, num_groups_ ); + throw std::exception(); + } + + // group not in dataset + if( data_.count( group ) == 0 ) + return 0.0; + + // select dilution and legendre order from dataset + auto data = data_.at(group).values(); + return data[numLegendre()*idil + order]; + +} + +/* + * @brief Return cross section value. Assume l=0, idil=0. + * @param group GENDF group index (1-based, low group = low energy) + */ +double getCrossSection( int group ) { + return getCrossSection( group, 0, 0 ); +} diff --git a/src/ENDFtk/section/Gendf3/test/CMakeLists.txt b/src/ENDFtk/section/Gendf3/test/CMakeLists.txt new file mode 100644 index 000000000..bb10e5ca0 --- /dev/null +++ b/src/ENDFtk/section/Gendf3/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.Gendf3.test Gendf3.test.cpp ) +target_compile_options( ENDFtk.section.Gendf3.test PRIVATE ${${PREFIX}_common_flags} +$<$:${${PREFIX}_strict_flags}>$<$: +${${PREFIX}_DEBUG_flags} +$<$:${${PREFIX}_coverage_flags}>> +$<$: +${${PREFIX}_RELEASE_flags} +$<$:${${PREFIX}_link_time_optimization_flags}> +$<$:${${PREFIX}_nonportable_optimization_flags}>> + +${CXX_appended_flags} ${ENDFtk_appended_flags} ) +target_link_libraries( ENDFtk.section.Gendf3.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.Gendf3 COMMAND ENDFtk.section.Gendf3.test ) diff --git a/src/ENDFtk/section/Gendf3/test/Gendf3.test.cpp b/src/ENDFtk/section/Gendf3/test/Gendf3.test.cpp new file mode 100644 index 000000000..be38132a2 --- /dev/null +++ b/src/ENDFtk/section/Gendf3/test/Gendf3.test.cpp @@ -0,0 +1,84 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk.hpp" + +using namespace njoy::ENDFtk; + + +std::string getSection(); + + +SCENARIO( "creating a GendfBase object" ) { + GIVEN( "a string representation of a GendfSection" ) { + WHEN( "a valid section is given" ) { + + std::string buffer = getSection(); + + auto begin = buffer.begin(); + auto end = buffer.end(); + long lineNo = 0; + int MAT = 9237; + HeadRecord head(begin, end, lineNo); + + THEN( "the object can be created" ) { + section::GendfType<3> chunk(head, begin, end, lineNo, MAT ); + + // head record parameter getters + CHECK( chunk.legendreOrder() == 1 ); + CHECK( chunk.numLegendre() == 2 ); + CHECK( chunk.numSigma0() == 2 ); + CHECK( chunk.breakupFlag() == 0 ); + CHECK( chunk.numGroups() == 10 ); + + // check temperature + CHECK( chunk.temperature() == Approx(293.6) ); + + // check data + CHECK( chunk.getCrossSection(1) == 0.0 ); + CHECK( chunk.getCrossSection(10) == Approx(10.46994) ); + CHECK( chunk.getCrossSection(2, 1, 0) == Approx(15.18365) ); + CHECK( chunk.getCrossSection(2, 0, 1) == Approx(15.17064) ); + CHECK_THROWS( chunk.getCrossSection(1, 3, 0) ); + CHECK_THROWS( chunk.getCrossSection(1, 0, 3) ); + CHECK_THROWS( chunk.getCrossSection(0) ); + + } + } + } +} + + +std::string getSection() { + return + " 9.223800+4 0.000000+0 2 2 0 109237 3 1 1\n" + " 2.936000+2 0.000000+0 2 1 8 29237 3 1 5\n" + " 4.076628+5 4.076628+5 2.707485+5 1.798684+5 1.518365+1 1.518365+19237 3 1 6\n" + " 1.517064+1 1.515778+1 9237 3 1 7\n" + " 2.936000+2 0.000000+0 2 1 8 39237 3 1 8\n" + " 3.325475+5 3.325475+5 2.276034+5 1.557802+5 1.383334+1 1.383334+19237 3 1 9\n" + " 1.383249+1 1.383164+1 9237 3 1 10\n" + " 2.936000+2 0.000000+0 2 1 8 49237 3 1 11\n" + " 2.704187+6 2.704187+6 1.908900+6 1.347643+6 1.250311+1 1.250311+19237 3 1 12\n" + " 1.249862+1 1.249418+1 9237 3 1 13\n" + " 2.936000+2 0.000000+0 2 1 8 59237 3 1 14\n" + " 9.182484+5 9.182484+5 6.589042+5 4.728086+5 1.180808+1 1.180808+19237 3 1 15\n" + " 1.180798+1 1.180788+1 9237 3 1 16\n" + " 2.936000+2 0.000000+0 2 1 8 69237 3 1 17\n" + " 1.831983+6 1.831983+6 1.323545+6 9.562210+5 1.152468+1 1.152468+19237 3 1 18\n" + " 1.152446+1 1.152423+1 9237 3 1 19\n" + " 2.936000+2 0.000000+0 2 1 8 79237 3 1 20\n" + " 1.611270+6 1.611270+6 1.171801+6 8.521988+5 1.125120+1 1.125120+19237 3 1 21\n" + " 1.125110+1 1.125099+1 9237 3 1 22\n" + " 2.936000+2 0.000000+0 2 1 8 89237 3 1 23\n" + " 2.150370+6 2.150370+6 1.573657+6 1.151619+6 1.099457+1 1.099457+19237 3 1 24\n" + " 1.099439+1 1.099421+1 9237 3 1 25\n" + " 2.936000+2 0.000000+0 2 1 8 99237 3 1 26\n" + " 1.677811+6 1.677811+6 1.236346+6 9.110428+5 1.071231+1 1.071231+19237 3 1 27\n" + " 1.071217+1 1.071202+1 9237 3 1 28\n" + " 2.936000+2 0.000000+0 2 1 8 109237 3 1 29\n" + " 9.702869+5 9.702869+5 7.192670+5 5.331894+5 1.046994+1 1.046994+19237 3 1 30\n" + " 1.046982+1 1.046969+1 9237 3 1 31\n" + " 9237 3 099999\n"; + +} diff --git a/src/ENDFtk/section/Gendf6.hpp b/src/ENDFtk/section/Gendf6.hpp new file mode 100644 index 000000000..82402b162 --- /dev/null +++ b/src/ENDFtk/section/Gendf6.hpp @@ -0,0 +1,29 @@ +template<> +class GendfType< 6 > : protected GendfBase { + +protected: + + +public: + + /* constructor */ + #include "ENDFtk/section/Gendf6/src/ctor.hpp" + + /* methods */ + #include "ENDFtk/section/Gendf6/src/getMatrixElement.hpp" + + /* getters inherited from GendfBase */ + using GendfBase::legendreOrder; + using GendfBase::numLegendre; + using GendfBase::numSigma0; + using GendfBase::breakupFlag; + using GendfBase::numGroups; + using GendfBase::temperature; + + /* getters inherited from Base */ + using GendfBase::MT; + using GendfBase::ZA; + using GendfBase::AWR; + using GendfBase::atomicWeightRatio; + +}; diff --git a/src/ENDFtk/section/Gendf6/src/ctor.hpp b/src/ENDFtk/section/Gendf6/src/ctor.hpp new file mode 100644 index 000000000..e5247878d --- /dev/null +++ b/src/ENDFtk/section/Gendf6/src/ctor.hpp @@ -0,0 +1,16 @@ +template< typename BufferIterator > +GendfType( HeadRecord& head, + BufferIterator& begin, + const BufferIterator& end, + long& lineNumber, + int MAT ) + : GendfBase( head, begin, end, lineNumber, MAT ) { + + // TODO: Add support for compressed fission format + if( data_.count(0) ) { + Log::info( "ENDFtk does not yet have support " + "for compressed fission format. " ); + throw std::exception(); + } + +} diff --git a/src/ENDFtk/section/Gendf6/src/getMatrixElement.hpp b/src/ENDFtk/section/Gendf6/src/getMatrixElement.hpp new file mode 100644 index 000000000..868135c7f --- /dev/null +++ b/src/ENDFtk/section/Gendf6/src/getMatrixElement.hpp @@ -0,0 +1,66 @@ +/* + * @brief Return matrix element from transfer matrix. + * @param in_group Incoming energy group (GENDF ordering) + * @param out_group Outgoing energy group (GENDF ordering) + * @param order Legendre order + * @param idil Index of dilution (0-based) + */ +double getMatrixElement( int in_group, + int out_group, + int order, + int idil ) { + + // error checking + if( order > legendreOrder() ) { + Log::info( "{} is greater than Legendre order of dataset ({})", + order, legendreOrder() ); + throw std::exception(); + } + else if( idil >= num_sigma0_ ) { + Log::info( "Index {} exceeds number of dilutions in dataset ({})", + idil, num_sigma0_ ); + throw std::exception(); + } + else if( in_group <= 0 or in_group > num_groups_ ) { + Log::info( "In-group {} is invalid with {} groups", + in_group, num_groups_ ); + throw std::exception(); + } + else if( out_group <= 0 or out_group > num_groups_ ) { + Log::info( "Out-group {} is invalid with {} groups", + out_group, num_groups_ ); + throw std::exception(); + } + + // in_group not in dataset + if( data_.count( in_group ) == 0 ) + return 0.0; + + // retrieve stored data + auto record = data_.at(in_group); + auto data = record.values(); + int lowest = record.lowestGroup(); + int npos = record.numSecondaryPositions() - 1; + + // find index + int idx = out_group - lowest; + + // out_group not in dataset + if( idx >= npos or idx < 0 ) + return 0.0; + + // return value from dataset + return data[ numLegendre()*numSigma0()*idx + numLegendre()*idil + order ]; + +} + + +/* + * @brief Return matrix element from transfer matrix. + Assume l=0, idil=0. + * @param in_group Incoming energy group (GENDF ordering) + * @param out_group Outgoing energy group (GENDF ordering) + */ +double getMatrixElement( int in_group, int out_group ) { + return getMatrixElement( in_group, out_group, 0, 0 ); +} diff --git a/src/ENDFtk/section/Gendf6/test/CMakeLists.txt b/src/ENDFtk/section/Gendf6/test/CMakeLists.txt new file mode 100644 index 000000000..decede554 --- /dev/null +++ b/src/ENDFtk/section/Gendf6/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.Gendf6.test Gendf6.test.cpp ) +target_compile_options( ENDFtk.section.Gendf6.test PRIVATE ${${PREFIX}_common_flags} +$<$:${${PREFIX}_strict_flags}>$<$: +${${PREFIX}_DEBUG_flags} +$<$:${${PREFIX}_coverage_flags}>> +$<$: +${${PREFIX}_RELEASE_flags} +$<$:${${PREFIX}_link_time_optimization_flags}> +$<$:${${PREFIX}_nonportable_optimization_flags}>> + +${CXX_appended_flags} ${ENDFtk_appended_flags} ) +target_link_libraries( ENDFtk.section.Gendf6.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.Gendf6 COMMAND ENDFtk.section.Gendf6.test ) diff --git a/src/ENDFtk/section/Gendf6/test/Gendf6.test.cpp b/src/ENDFtk/section/Gendf6/test/Gendf6.test.cpp new file mode 100644 index 000000000..b7c3a0210 --- /dev/null +++ b/src/ENDFtk/section/Gendf6/test/Gendf6.test.cpp @@ -0,0 +1,168 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk.hpp" + +using namespace njoy::ENDFtk; + + +std::string singleDilutionSingleLegendre(); +std::string multipleDilutionSingleLegendre(); +std::string multipleDilutionMultipleLegendre(); + + +SCENARIO( "creating a GendfBase object" ) { + GIVEN( "a string representation of a GendfSection" ) { + WHEN( "a valid section is given with single dilution/Legendre" ) { + + std::string buffer = singleDilutionSingleLegendre(); + + auto begin = buffer.begin(); + auto end = buffer.end(); + long lineNo = 0; + int MAT = 9231; + HeadRecord head(begin, end, lineNo); + + THEN( "the object can be created" ) { + section::GendfType<6> chunk(head, begin, end, lineNo, MAT ); + + // head record parameter getters + CHECK( chunk.legendreOrder() == 0 ); + CHECK( chunk.numLegendre() == 1 ); + CHECK( chunk.numSigma0() == 1 ); + CHECK( chunk.breakupFlag() == 0 ); + CHECK( chunk.numGroups() == 4 ); + + // check temperature + CHECK( chunk.temperature() == Approx(293.6) ); + + // check data + CHECK( chunk.getMatrixElement(1, 1) == 0.0 ); + CHECK( chunk.getMatrixElement(4, 4) == Approx(0.5641136) ); + CHECK( chunk.getMatrixElement(4, 3) == Approx(0.001889547) ); + CHECK( chunk.getMatrixElement(4, 1, 0, 0) == 0.0 ); + CHECK_THROWS( chunk.getMatrixElement(1, 1, 3, 0) ); + CHECK_THROWS( chunk.getMatrixElement(1, 1, 0, 3) ); + CHECK_THROWS( chunk.getMatrixElement(1, 0, 0, 0) ); + CHECK_THROWS( chunk.getMatrixElement(0, 1, 0, 0) ); + } + } + + WHEN( "the section has multiple dilutions/single Legendre" ) { + + std::string buffer = multipleDilutionSingleLegendre(); + + auto begin = buffer.begin(); + auto end = buffer.end(); + long lineNo = 0; + int MAT = 9231; + HeadRecord head(begin, end, lineNo); + + THEN( "the object can be created" ) { + section::GendfType<6> chunk(head, begin, end, lineNo, MAT ); + + // head record parameter getters + CHECK( chunk.legendreOrder() == 0 ); + CHECK( chunk.numLegendre() == 1 ); + CHECK( chunk.numSigma0() == 2 ); + CHECK( chunk.breakupFlag() == 0 ); + CHECK( chunk.numGroups() == 4 ); + + // check temperature + CHECK( chunk.temperature() == Approx(293.6) ); + + // check data + CHECK( chunk.getMatrixElement(1, 1) == Approx(13.08591) ); + CHECK( chunk.getMatrixElement(4, 4, 0, 1) == Approx(6.795481) ); + CHECK( chunk.getMatrixElement(4, 3) == Approx(0.01691256) ); + CHECK( chunk.getMatrixElement(4, 1, 0, 0) == 0.0 ); + CHECK_THROWS( chunk.getMatrixElement(1, 1, 3, 0) ); + CHECK_THROWS( chunk.getMatrixElement(1, 1, 0, 3) ); + CHECK_THROWS( chunk.getMatrixElement(1, 0, 0, 0) ); + CHECK_THROWS( chunk.getMatrixElement(0, 1, 0, 0) ); + } + } + + WHEN( "the section has multiple dilutions/Legendres" ) { + + std::string buffer = multipleDilutionMultipleLegendre(); + + auto begin = buffer.begin(); + auto pos = begin; + auto end = buffer.end(); + long lineNo = 0; + int MAT = 9231; + HeadRecord head(pos, end, lineNo); + + THEN( "the object can be created from a syntaxTree" ) { + syntaxTree::GendfSection< std::string::iterator > + tree(head, begin, pos, end, lineNo); + auto chunk = tree.parse<6>(); + + // head record parameter getters + CHECK( chunk.legendreOrder() == 2 ); + CHECK( chunk.numLegendre() == 3 ); + CHECK( chunk.numSigma0() == 2 ); + CHECK( chunk.breakupFlag() == 0 ); + CHECK( chunk.numGroups() == 4 ); + + // check temperature + CHECK( chunk.temperature() == Approx(293.6) ); + + // check data + CHECK( chunk.getMatrixElement(1, 1) == Approx(13.08591) ); + CHECK( chunk.getMatrixElement(4, 4, 0, 1) == Approx(6.795481) ); + CHECK( chunk.getMatrixElement(4, 3, 2, 1) == Approx(-1.461486e-6) ); + CHECK( chunk.getMatrixElement(4, 1, 0, 0) == 0.0 ); + CHECK_THROWS( chunk.getMatrixElement(1, 1, 3, 0) ); + CHECK_THROWS( chunk.getMatrixElement(1, 1, 0, 3) ); + CHECK_THROWS( chunk.getMatrixElement(1, 0, 0, 0) ); + CHECK_THROWS( chunk.getMatrixElement(0, 1, 0, 0) ); + } + } + } +} + + +std::string multipleDilutionSingleLegendre() { + return + " 9.223600+4 0.000000+0 1 2 0 49231 6 2 1\n" + " 2.936000+2 0.000000+0 2 1 4 19231 6 2 2\n" + " 7.836093+0 2.066847-1 1.308591+1 9.964397+0 9231 6 2 3\n" + " 2.936000+2 0.000000+0 3 1 6 29231 6 2 4\n" + " 5.063323+0 4.380571-1 1.488054-2 1.146178-2 8.538194+0 8.513820+09231 6 2 5\n" + " 2.936000+2 0.000000+0 3 2 6 39231 6 2 6\n" + " 7.824099+0 5.997011-1 6.905855-3 8.003645-3 2.515695+1 1.074624+19231 6 2 7\n" + " 2.936000+2 0.000000+0 3 3 6 49231 6 2 8\n" + " 7.601016+0 7.489501-1 1.691256-2 1.003045-2 8.111733+0 6.795481+09231 6 2 9\n" + " 9231 6 099999\n"; +} + +std::string multipleDilutionMultipleLegendre() { + return + " 9.223600+4 0.000000+0 3 2 0 49231 6 2 1\n" + " 2.936000+2 0.000000+0 2 1 12 19231 6 2 2\n" + " 7.836093+0 7.836093+0 7.836093+0 2.066847-1 8.373871-3 4.064310-49231 6 2 3\n" + " 1.308591+1 3.727915-2 4.841787-5 9.964397+0 2.603868-2 3.313675-59231 6 2 4\n" + " 2.936000+2 0.000000+0 3 1 18 29231 6 2 5\n" + " 5.063323+0 5.063323+0 5.063323+0 4.380571-1 3.832580-2 3.387609-39231 6 2 6\n" + " 1.488054-2-4.932024-3-1.692182-5 1.146178-2-2.896314-3-5.591585-69231 6 2 7\n" + " 8.538194+0 2.929976-2 4.856660-5 8.513820+0 2.710764-2 3.693604-59231 6 2 8\n" + " 2.936000+2 0.000000+0 3 2 18 39231 6 2 9\n" + " 7.824099+0 7.824099+0 7.824099+0 5.997011-1 5.604142-2 6.268131-39231 6 2 10\n" + " 6.905855-3-2.280570-3-1.283959-5 8.003645-3-2.497460-3-2.209360-59231 6 2 11\n" + " 2.515695+1 8.592875-2 4.188720-3 1.074624+1 3.278044-2 8.844580-49231 6 2 12\n" + " 2.936000+2 0.000000+0 3 3 18 49231 6 2 13\n" + " 7.601016+0 7.601016+0 7.601016+0 7.489501-1 8.041605-2 9.253031-39231 6 2 14\n" + " 1.691252-2-5.565639-3-1.212732-5 1.003043-2-1.797672-3-1.461486-69231 6 2 15\n" + " 8.111733+0 1.767513+0 1.134979+0 6.795481+0 2.207837+0 1.721833+09231 6 2 16\n" + " 9231 6 099999\n"; +} + +std::string singleDilutionSingleLegendre() { + return + " 9.223600+4 0.000000+0 1 1 0 49231 6 51 1\n" + " 2.936000+2 0.000000+0 4 2 4 49231 6 51 2\n" + " 7.601016+0 3.96073-10 1.889547-3 5.641136-1 9231 6 51 3\n" + " 9231 6 099999\n"; +} diff --git a/src/ENDFtk/section/GendfBase.hpp b/src/ENDFtk/section/GendfBase.hpp new file mode 100644 index 000000000..2a98e5420 --- /dev/null +++ b/src/ENDFtk/section/GendfBase.hpp @@ -0,0 +1,34 @@ +class GendfBase : protected Base { + +protected: + /* fields */ + std::map< int, GendfDataRecord > data_; + int num_legendre_; + int num_sigma0_; + int lrflag_; + int num_groups_; + double temperature_; + + /* methods */ + #include "ENDFtk/section/GendfBase/src/populateData.hpp" + +public: + /* constructor */ + #include "ENDFtk/section/GendfBase/src/ctor.hpp" + + /* getters */ + int legendreOrder() const { return num_legendre_-1; } + int numLegendre() const { return num_legendre_; } + int numSigma0() const { return num_sigma0_; } + int breakupFlag() const { return lrflag_; } + int numGroups() const { return num_groups_; } + double temperature() const { return temperature_; } + const auto& dataRecords() const { return data_; } + + /* getters inherited from Base */ + using Base::MT; + using Base::ZA; + using Base::AWR; + using Base::atomicWeightRatio; + +}; diff --git a/src/ENDFtk/section/GendfBase/src/ctor.hpp b/src/ENDFtk/section/GendfBase/src/ctor.hpp new file mode 100644 index 000000000..e88fcce78 --- /dev/null +++ b/src/ENDFtk/section/GendfBase/src/ctor.hpp @@ -0,0 +1,30 @@ +template< typename BufferIterator > +GendfBase( HeadRecord& head, + BufferIterator& begin, + const BufferIterator& end, + long& lineNumber, + int MAT ) + : Base( head, MAT, head.MF() ), + num_legendre_( head.L1() ), + num_sigma0_( head.L2() ), + lrflag_( head.N1() ), + num_groups_( head.N2() ) { + + // populate data records + data_ = populateData(head, begin, end, lineNumber, MAT); + + // find temperature and check all temperatures are consistent + bool temp_set = false; + for( const auto& [group, record] : data_ ) { + if( not temp_set ) { + temperature_ = record.temperature(); + temp_set = true; + } + else if( record.temperature() != temperature_ ) { + Log::info( "Inconsistent temperature in MFD/MT {}/{}: {} != {}", + head.MF(), head.MT(), temperature_, record.temperature() ); + throw std::exception(); + } + } + +} diff --git a/src/ENDFtk/section/GendfBase/src/populateData.hpp b/src/ENDFtk/section/GendfBase/src/populateData.hpp new file mode 100644 index 000000000..852124241 --- /dev/null +++ b/src/ENDFtk/section/GendfBase/src/populateData.hpp @@ -0,0 +1,43 @@ +template< typename BufferIterator > +auto populateData(HeadRecord& head, + BufferIterator& begin, + const BufferIterator& end, + long& lineNumber, + int MAT ) { + + // initialize + std::map< int, GendfDataRecord > data_records; + + // first list record + auto next_record = GendfDataRecord( begin, end, lineNumber, + num_legendre_, num_sigma0_, + MAT, head.MF(), head.MT() ); + int group = next_record.group(); + data_records.emplace( group, next_record ); + + // loop until final group is recorded + while( group < head.N2() ) { + + // create next record + next_record = GendfDataRecord( begin, end, lineNumber, + num_legendre_, num_sigma0_, + MAT, head.MF(), head.MT() ); + group = next_record.group(); + + // check if group was already seen + if (data_records.count( group ) > 0) { + Log::info( "Group {} appears multiple times in MFD/MT {}/{}", + group, head.MF(), head.MT() ); + throw std::exception(); + } + + data_records.emplace( group, next_record ); + + } + + // read SEND card + readSEND(begin, end, lineNumber, MAT, head.MF()); + + return data_records; + +} diff --git a/src/ENDFtk/section/GendfBase/test/CMakeLists.txt b/src/ENDFtk/section/GendfBase/test/CMakeLists.txt new file mode 100644 index 000000000..c02801777 --- /dev/null +++ b/src/ENDFtk/section/GendfBase/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.GendfBase.test GendfBase.test.cpp ) +target_compile_options( ENDFtk.section.GendfBase.test PRIVATE ${${PREFIX}_common_flags} +$<$:${${PREFIX}_strict_flags}>$<$: +${${PREFIX}_DEBUG_flags} +$<$:${${PREFIX}_coverage_flags}>> +$<$: +${${PREFIX}_RELEASE_flags} +$<$:${${PREFIX}_link_time_optimization_flags}> +$<$:${${PREFIX}_nonportable_optimization_flags}>> + +${CXX_appended_flags} ${ENDFtk_appended_flags} ) +target_link_libraries( ENDFtk.section.GendfBase.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.GendfBase COMMAND ENDFtk.section.GendfBase.test ) diff --git a/src/ENDFtk/section/GendfBase/test/GendfBase.test.cpp b/src/ENDFtk/section/GendfBase/test/GendfBase.test.cpp new file mode 100644 index 000000000..7267cd83b --- /dev/null +++ b/src/ENDFtk/section/GendfBase/test/GendfBase.test.cpp @@ -0,0 +1,162 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk.hpp" + +using namespace njoy::ENDFtk; + + +std::string validFEND(); +std::string mfd3mt2(); +std::string validSEND(); +std::string invalidSEND(); + + +SCENARIO( "creating a GendfBase object" ) { + GIVEN( "a string representation of a GendfSection" ) { + WHEN( "a valid section is given" ) { + + // MFD3, one temp, one sig0, one Legendre + std::string buffer = mfd3mt2(); + + auto begin = buffer.begin(); + auto end = buffer.end(); + long lineNo = 0; + int MAT = 9228; + HeadRecord head(begin, end, lineNo); + + THEN( "the object can be created" ) { + section::GendfBase chunk(head, begin, end, lineNo, MAT ); + + // head record parameter getters + CHECK( chunk.legendreOrder() == 0 ); + CHECK( chunk.numLegendre() == 1 ); + CHECK( chunk.numSigma0() == 1 ); + CHECK( chunk.breakupFlag() == 0 ); + CHECK( chunk.numGroups() == 44 ); + + // check temperature + CHECK( chunk.temperature() == Approx(293.6) ); + + // check lists + CHECK( chunk.dataRecords().at(1).group() == 1 ); + CHECK( chunk.dataRecords().at(44).group() == 44 ); + CHECK( chunk.dataRecords().at(2).flux().at(0) == + Approx(4.076628e+5) ); + + } + } + } +} + + +std::string validFEND() { + return + " 9228 0 0 0\n"; +} + +std::string mfd3mt2() { + return + " 9.223500+4 0.000000+0 1 1 0 449228 3 2 1\n" + " 2.936000+2 0.000000+0 2 1 2 19228 3 2 2\n" + " 8.864840+4 1.469141+1 9228 3 2 3\n" + " 2.936000+2 0.000000+0 2 1 2 29228 3 2 4\n" + " 4.076628+5 1.430320+1 9228 3 2 5\n" + " 2.936000+2 0.000000+0 2 1 2 39228 3 2 6\n" + " 3.325475+5 1.422934+1 9228 3 2 7\n" + " 2.936000+2 0.000000+0 2 1 2 49228 3 2 8\n" + " 2.704187+6 1.415084+1 9228 3 2 9\n" + " 2.936000+2 0.000000+0 2 1 2 59228 3 2 10\n" + " 9.182484+5 1.409805+1 9228 3 2 11\n" + " 2.936000+2 0.000000+0 2 1 2 69228 3 2 12\n" + " 1.831983+6 1.406694+1 9228 3 2 13\n" + " 2.936000+2 0.000000+0 2 1 2 79228 3 2 14\n" + " 1.611269+6 1.402843+1 9228 3 2 15\n" + " 2.936000+2 0.000000+0 2 1 2 89228 3 2 16\n" + " 2.150369+6 1.397806+1 9228 3 2 17\n" + " 2.936000+2 0.000000+0 2 1 2 99228 3 2 18\n" + " 1.677811+6 1.389651+1 9228 3 2 19\n" + " 2.936000+2 0.000000+0 2 1 2 109228 3 2 20\n" + " 9.702871+5 1.378522+1 9228 3 2 21\n" + " 2.936000+2 0.000000+0 2 1 2 119228 3 2 22\n" + " 3.285728+5 1.362093+1 9228 3 2 23\n" + " 2.936000+2 0.000000+0 2 1 2 129228 3 2 24\n" + " 1.348773+5 1.352095+1 9228 3 2 25\n" + " 2.936000+2 0.000000+0 2 1 2 139228 3 2 26\n" + " 1.208261+5 1.348035+1 9228 3 2 27\n" + " 2.936000+2 0.000000+0 2 1 2 149228 3 2 28\n" + " 1.094424+5 1.347708+1 9228 3 2 29\n" + " 2.936000+2 0.000000+0 2 1 2 159228 3 2 30\n" + " 1.921488+5 1.352816+1 9228 3 2 31\n" + " 2.936000+2 0.000000+0 2 1 2 169228 3 2 32\n" + " 8.537350+4 1.355762+1 9228 3 2 33\n" + " 2.936000+2 0.000000+0 2 1 2 179228 3 2 34\n" + " 7.955453+4 1.353933+1 9228 3 2 35\n" + " 2.936000+2 0.000000+0 2 1 2 189228 3 2 36\n" + " 7.448245+4 1.350431+1 9228 3 2 37\n" + " 2.936000+2 0.000000+0 2 1 2 199228 3 2 38\n" + " 5.152778+5 1.330950+1 9228 3 2 39\n" + " 2.936000+2 0.000000+0 2 1 2 209228 3 2 40\n" + " 5.421450+5 1.289614+1 9228 3 2 41\n" + " 2.936000+2 0.000000+0 2 1 2 219228 3 2 42\n" + " 6.582378+5 1.263968+1 9228 3 2 43\n" + " 2.936000+2 0.000000+0 2 1 2 229228 3 2 44\n" + " 6.085370+5 1.195173+1 9228 3 2 45\n" + " 2.936000+2 0.000000+0 2 1 2 239228 3 2 46\n" + " 5.304027+5 1.137018+1 9228 3 2 47\n" + " 2.936000+2 0.000000+0 2 1 2 249228 3 2 48\n" + " 2.698745+5 1.075633+1 9228 3 2 49\n" + " 2.936000+2 0.000000+0 2 1 2 259228 3 2 50\n" + " 3.469132+5 1.070006+1 9228 3 2 51\n" + " 2.936000+2 0.000000+0 2 1 2 269228 3 2 52\n" + " 2.436662+5 1.161760+1 9228 3 2 53\n" + " 2.936000+2 0.000000+0 2 1 2 279228 3 2 54\n" + " 1.269261+6 1.149129+1 9228 3 2 55\n" + " 2.936000+2 0.000000+0 2 1 2 289228 3 2 56\n" + " 1.389867+6 1.140790+1 9228 3 2 57\n" + " 2.936000+2 0.000000+0 2 1 2 299228 3 2 58\n" + " 1.966742+6 1.152955+1 9228 3 2 59\n" + " 2.936000+2 0.000000+0 2 1 2 309228 3 2 60\n" + " 1.958830+6 1.215428+1 9228 3 2 61\n" + " 2.936000+2 0.000000+0 2 1 2 319228 3 2 62\n" + " 2.003216+6 1.195243+1 9228 3 2 63\n" + " 2.936000+2 0.000000+0 2 1 2 329228 3 2 64\n" + " 4.448512+5 1.144792+1 9228 3 2 65\n" + " 2.936000+2 0.000000+0 2 1 2 339228 3 2 66\n" + " 1.600971+6 1.069586+1 9228 3 2 67\n" + " 2.936000+2 0.000000+0 2 1 2 349228 3 2 68\n" + " 1.653127+6 8.151080+0 9228 3 2 69\n" + " 2.936000+2 0.000000+0 2 1 2 359228 3 2 70\n" + " 1.607887+6 5.004643+0 9228 3 2 71\n" + " 2.936000+2 0.000000+0 2 1 2 369228 3 2 72\n" + " 1.044185+6 3.748074+0 9228 3 2 73\n" + " 2.936000+2 0.000000+0 2 1 2 379228 3 2 74\n" + " 5.807999+5 3.589833+0 9228 3 2 75\n" + " 2.936000+2 0.000000+0 2 1 2 389228 3 2 76\n" + " 4.118760+5 3.848525+0 9228 3 2 77\n" + " 2.936000+2 0.000000+0 2 1 2 399228 3 2 78\n" + " 7.543025+4 4.091297+0 9228 3 2 79\n" + " 2.936000+2 0.000000+0 2 1 2 409228 3 2 80\n" + " 2.347697+5 4.284081+0 9228 3 2 81\n" + " 2.936000+2 0.000000+0 2 1 2 419228 3 2 82\n" + " 3.334087+5 4.525173+0 9228 3 2 83\n" + " 2.936000+2 0.000000+0 2 1 2 429228 3 2 84\n" + " 8.667041+4 4.115439+0 9228 3 2 85\n" + " 2.936000+2 0.000000+0 2 1 2 439228 3 2 86\n" + " 3.704342+4 3.442857+0 9228 3 2 87\n" + " 2.936000+2 0.000000+0 2 1 2 449228 3 2 88\n" + " 1.292703+5 2.786681+0 9228 3 2 89\n" + " 9228 3 099999\n"; +} + +std::string validSEND() { + return + " 9228 1 0 0\n"; +} + +std::string invalidSEND() { + return + " 9228 1451 0\n"; +} + + diff --git a/src/ENDFtk/syntaxTree.hpp b/src/ENDFtk/syntaxTree.hpp index d6a612347..c714f509d 100644 --- a/src/ENDFtk/syntaxTree.hpp +++ b/src/ENDFtk/syntaxTree.hpp @@ -1,8 +1,13 @@ namespace syntaxTree { +/* tag structs */ +struct ENDFTag {}; +struct GENDFTag {}; + #include "ENDFtk/syntaxTree/Section.hpp" #include "ENDFtk/syntaxTree/File.hpp" #include "ENDFtk/syntaxTree/Material.hpp" +#include "ENDFtk/syntaxTree/GendfMaterial.hpp" #include "ENDFtk/syntaxTree/Tape.hpp" #include "ENDFtk/syntaxTree/src/makeTape.hpp" diff --git a/src/ENDFtk/syntaxTree/GendfMaterial.hpp b/src/ENDFtk/syntaxTree/GendfMaterial.hpp new file mode 100644 index 000000000..d4e1cfaf0 --- /dev/null +++ b/src/ENDFtk/syntaxTree/GendfMaterial.hpp @@ -0,0 +1,71 @@ +/* Template specialization for GendfMaterial */ +template< typename BufferIterator > +class Material< BufferIterator, GENDFTag > { + +public: + /* convenience typedefs */ + using Section_t = GendfSection< BufferIterator >; + using MFMT = std::pair< int, int >; + +protected: + /* fields */ + int materialNo; + std::map< MFMT, Section_t > sections_; + std::pair< BufferIterator, BufferIterator > bufferLimits; + + /* methods */ + #include "ENDFtk/syntaxTree/GendfMaterial/src/createMap.hpp" + +public: + /* constructor */ + #include "ENDFtk/syntaxTree/GendfMaterial/src/ctor.hpp" + + /* methods */ + + #include "ENDFtk/syntaxTree/GendfMaterial/src/section.hpp" + + /* + * @brief Return whether material includes given section. + * @param MF The MFD value of the section. + * @param MT The MT value of the section. + */ + bool hasSection( int MF, int MT ) const { + return sections_.count( MFMT(MF, MT) ); + } + + /* + * @brief Define begin, end to make object iterable. + */ + auto begin() { return (sections_ | ranges::view::values).begin(); } + auto end() { return (sections_ | ranges::view::values).end(); } + + auto begin() const { return (sections_ | ranges::view::values).begin(); } + auto end() const { return (sections_ | ranges::view::values).end(); } + + + /* + * @brief Return the number of Sections contained in the Material. + */ + std::size_t size() const { return sections_.size(); } + + /* + * @brief Return the MAT number. + */ + int MAT() const { return materialNo; } + int materialNumber() const { return MAT(); } + + /* + * @brief Create a reference to the buffer. + * TODO: Update make_iterator_range to newer syntax + */ + auto buffer() const { + return ranges::make_iterator_range( bufferLimits.first, + bufferLimits.second ); + } + +}; + + +/* convenience alias */ +template< typename BufferIterator > +using GendfMaterial = Material< BufferIterator, GENDFTag >; diff --git a/src/ENDFtk/syntaxTree/GendfMaterial/src/createMap.hpp b/src/ENDFtk/syntaxTree/GendfMaterial/src/createMap.hpp new file mode 100644 index 000000000..a6288c8fe --- /dev/null +++ b/src/ENDFtk/syntaxTree/GendfMaterial/src/createMap.hpp @@ -0,0 +1,63 @@ +/* + * @brief Utility routine for use in constructor to create map of Sections. + */ +static std::map< MFMT, Section_t > createMap( + const HeadRecord& head, + BufferIterator begin, + BufferIterator& position, + const BufferIterator& end, + long& lineNumber ) { + + std::map< MFMT, Section_t > sections; + + // emplace first section + auto idx = MFMT( head.MF(), head.MT() ); + sections.emplace( idx, + Section_t(head, begin, position, end, lineNumber) ); + + // read next card + begin = position; + auto division = StructureDivision( position, end, lineNumber ); + + // loop until MEND is found + while( division.isHead() ){ + + // map index + idx = MFMT( division.tail.MF(), division.tail.MT() ); + + // read section + Section_t new_section( asHead(division), begin, + position, end, lineNumber ); + + // map index already present + if ( sections.count(idx) ) { + Log::info("Warning: MFD{}, MT{} is already present in GENDF file. " + "Skipping redundant section.", + division.tail.MF(), division.tail.MT() ); + } + + // emplace next section + else { + sections.emplace(idx, new_section); + } + + // read next card + if( position >= end ){ + Log::error( "Material encountered end of stream before reading " + "MEND record" ); + throw std::exception(); + } + begin = position; + division = StructureDivision( position, end, lineNumber ); + + } + + if( not division.isMend() ){ + Log::error( "MEND record is misformatted" ); + utility::echoErroneousLine(begin, begin, end, lineNumber ); + throw std::exception(); + } + + return sections; + +} diff --git a/src/ENDFtk/syntaxTree/GendfMaterial/src/ctor.hpp b/src/ENDFtk/syntaxTree/GendfMaterial/src/ctor.hpp new file mode 100644 index 000000000..2565dbf47 --- /dev/null +++ b/src/ENDFtk/syntaxTree/GendfMaterial/src/ctor.hpp @@ -0,0 +1,15 @@ +/** + * @brief Constructor for GendfMaterial + */ +Material( const HeadRecord& head, + BufferIterator begin, + BufferIterator& position, + const BufferIterator& end, + long& lineNumber ) +try: materialNo( head.MAT() ), + sections_( createMap(head, begin, position, end, lineNumber) ), + bufferLimits( {begin, position} ) {} +catch( std::exception& e ) { + Log::info("Trouble while constructing GendfMaterial." ); + throw e; +} diff --git a/src/ENDFtk/syntaxTree/GendfMaterial/src/section.hpp b/src/ENDFtk/syntaxTree/GendfMaterial/src/section.hpp new file mode 100644 index 000000000..3c679c09f --- /dev/null +++ b/src/ENDFtk/syntaxTree/GendfMaterial/src/section.hpp @@ -0,0 +1,13 @@ +const Section_t& section( int MF, int MT ) const { + try{ + return this->files_.at( MFMT(MF, MT) ); + } catch( std::out_of_range& o ){ + Log::error + ( "Requested MF/MT does not " + "correspond to a stored section in the syntax tree" ); + Log::info( "Requested MF/MT: {}/{}", MF, MT ); + Log::info( "Material number of queried material syntax tree: {}", + this->materialNumber() ); + throw o; + } +} diff --git a/src/ENDFtk/syntaxTree/GendfMaterial/test/CMakeLists.txt b/src/ENDFtk/syntaxTree/GendfMaterial/test/CMakeLists.txt new file mode 100644 index 000000000..0c4740ffc --- /dev/null +++ b/src/ENDFtk/syntaxTree/GendfMaterial/test/CMakeLists.txt @@ -0,0 +1,18 @@ + +add_executable( ENDFtk.syntaxTree.GendfMaterial.test GendfMaterial.test.cpp ) +target_compile_options( ENDFtk.syntaxTree.GendfMaterial.test PRIVATE ${${PREFIX}_common_flags} +$<$:${${PREFIX}_strict_flags}>$<$: +${${PREFIX}_DEBUG_flags} +$<$:${${PREFIX}_coverage_flags}>> +$<$: +${${PREFIX}_RELEASE_flags} +$<$:${${PREFIX}_link_time_optimization_flags}> +$<$:${${PREFIX}_nonportable_optimization_flags}>> + +${CXX_appended_flags} ${ENDFtk_appended_flags} ) +target_link_libraries( ENDFtk.syntaxTree.GendfMaterial.test PUBLIC ENDFtk ) +file( GLOB resources "resources/*" ) +foreach( resource ${resources}) + file( COPY "${resource}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" ) +endforeach() +add_test( NAME ENDFtk.syntaxTree.GendfMaterial COMMAND ENDFtk.syntaxTree.GendfMaterial.test ) diff --git a/src/ENDFtk/syntaxTree/GendfMaterial/test/GendfMaterial.test.cpp b/src/ENDFtk/syntaxTree/GendfMaterial/test/GendfMaterial.test.cpp new file mode 100644 index 000000000..a994fe251 --- /dev/null +++ b/src/ENDFtk/syntaxTree/GendfMaterial/test/GendfMaterial.test.cpp @@ -0,0 +1,88 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk.hpp" + +using namespace njoy::ENDFtk; + + +std::string sampleSection(); +std::string validMEND(); +std::string validFEND(); +std::string validSEND(); +std::string invalidSEND(); + + +SCENARIO( "testing creation of GENDF material object" ) { + GIVEN( "a string representation of a GendfMaterial" ) { + WHEN( "a valid material is given" ){ + + // MFD1, MT451 uses FEND rather than SEND + std::string buffer = sampleSection() + validFEND() + validMEND(); + + auto begin = buffer.begin(); + auto position = begin; + auto end = buffer.end(); + long lineNo = 0; + + // construct object + HeadRecord head( position, end, lineNo ); + syntaxTree::GendfMaterial< std::string::iterator > + matl( head, begin, position, end, lineNo ); + + THEN( "the whole stream is read" ) { + CHECK( lineNo == 14 ); + } + AND_THEN( "one section is found" ) { + CHECK( matl.size() == 1 ); + CHECK( matl.hasSection(1, 451) ); + CHECK( not matl.hasSection(3, 1) ); + CHECK( matl.MAT() == 9228 ); + CHECK( matl.materialNumber() == 9228 ); + } + AND_THEN( "the object is iterable" ) { + for ( auto& section : matl ) + CHECK( section.MT() == 451 ); + } + + } + } +} + +std::string sampleSection() { + return + " 9.223500+4 2.330248+2 0 1 -1 19228 1451 1\n" + " 2.936000+2 0.000000+0 44 12 60 09228 1451 2\n" + " 0.000000+0 1.00000+10 1.000000-5 3.000000-3 7.500000-3 1.000000-29228 1451 3\n" + " 2.530000-2 3.000000-2 4.000000-2 5.000000-2 7.000000-2 1.000000-19228 1451 4\n" + " 1.500000-1 2.000000-1 2.250000-1 2.500000-1 2.750000-1 3.250000-19228 1451 5\n" + " 3.500000-1 3.750000-1 4.000000-1 6.250000-1 1.000000+0 1.770000+09228 1451 6\n" + " 3.000000+0 4.750000+0 6.000000+0 8.100000+0 1.000000+1 3.000000+19228 1451 7\n" + " 1.000000+2 5.500000+2 3.000000+3 1.700000+4 2.500000+4 1.000000+59228 1451 8\n" + " 4.000000+5 9.000000+5 1.400000+6 1.850000+6 2.354000+6 2.479000+69228 1451 9\n" + " 3.000000+6 4.800000+6 6.434000+6 8.187300+6 2.000000+7 1.000000+49228 1451 10\n" + " 1.000000+5 5.000000+5 1.000000+6 2.000000+6 3.000000+6 4.000000+69228 1451 11\n" + " 5.000000+6 6.000000+6 7.000000+6 8.000000+6 9.000000+6 2.000000+79228 1451 12\n"; +} + +std::string validMEND() { + return + " 0 0 0 0\n"; +} + +std::string validFEND() { + return + " 9228 0 0 0\n"; +} + +std::string validSEND() { + return + " 9228 1 0 0\n"; +} + +std::string invalidSEND() { + return + " 9228 1451 0\n"; +} + + diff --git a/src/ENDFtk/syntaxTree/Material.hpp b/src/ENDFtk/syntaxTree/Material.hpp index 4a386f22e..0eab930c4 100644 --- a/src/ENDFtk/syntaxTree/Material.hpp +++ b/src/ENDFtk/syntaxTree/Material.hpp @@ -1,5 +1,11 @@ +/* Forward class declaration */ +template< typename BufferIterator, typename Tag = ENDFTag > +class Material; + + +/* Template specialization */ template< typename BufferIterator > -class Material { +class Material< BufferIterator, ENDFTag > { public: /* convenience typedefs */ using File_t = File< BufferIterator >; diff --git a/src/ENDFtk/syntaxTree/Section.hpp b/src/ENDFtk/syntaxTree/Section.hpp index f71fe940d..698729e0d 100644 --- a/src/ENDFtk/syntaxTree/Section.hpp +++ b/src/ENDFtk/syntaxTree/Section.hpp @@ -1,15 +1,17 @@ template< typename BufferIterator > -class Section { -public: +class SectionBase { +protected: /* fields */ int sectionNo; int fileNo; std::pair< BufferIterator, BufferIterator > bufferLimits; /* methods */ -#include "ENDFtk/syntaxTree/Section/src/ctor.hpp" -#include "ENDFtk/syntaxTree/Section/src/findEnd.hpp" -#include "ENDFtk/syntaxTree/Section/src/parse.hpp" + #include "ENDFtk/syntaxTree/Section/src/findEnd.hpp" + +public: + /* methods */ + #include "ENDFtk/syntaxTree/Section/src/ctor.hpp" /* methods */ int MT() const { return this->sectionNo; } @@ -21,3 +23,54 @@ class Section { this->bufferLimits.second ); } }; + +template< typename BufferIterator, typename Tag = ENDFTag > +class Section : protected SectionBase< BufferIterator > { + +public: + + /* ctor */ + using Base = SectionBase< BufferIterator >; + using Base::SectionBase; + + /* methods */ + + // this file implements the parse() function + #include "ENDFtk/syntaxTree/Section/src/parse-endf.hpp" + + using Base::MT; + using Base::sectionNumber; + using Base::MF; + using Base::fileNumber; + using Base::buffer; + +}; + + +template< typename BufferIterator > +class Section< BufferIterator, GENDFTag > + : protected SectionBase< BufferIterator > { +public: + + /* ctor */ + using Base = SectionBase< BufferIterator >; + using Base::SectionBase; + + /* methods */ + + // this file implements the parse() function + #include "ENDFtk/syntaxTree/Section/src/parse-gendf.hpp" + + using Base::MT; + using Base::sectionNumber; + using Base::MF; + using Base::fileNumber; + using Base::buffer; + +}; + + +/* Convenience alias */ +template< typename BufferIterator > +using GendfSection = Section< BufferIterator, GENDFTag >; + diff --git a/src/ENDFtk/syntaxTree/Section/src/ctor.hpp b/src/ENDFtk/syntaxTree/Section/src/ctor.hpp index ef90d18af..35ab53246 100644 --- a/src/ENDFtk/syntaxTree/Section/src/ctor.hpp +++ b/src/ENDFtk/syntaxTree/Section/src/ctor.hpp @@ -1,6 +1,6 @@ -Section( const HEAD& head, BufferIterator begin, - BufferIterator& position, const BufferIterator& end, - long& lineNumber ) +SectionBase( const HEAD& head, BufferIterator begin, + BufferIterator& position, const BufferIterator& end, + long& lineNumber ) try: sectionNo( head.MT() ), fileNo( head.MF() ), diff --git a/src/ENDFtk/syntaxTree/Section/src/parse.hpp b/src/ENDFtk/syntaxTree/Section/src/parse-endf.hpp similarity index 100% rename from src/ENDFtk/syntaxTree/Section/src/parse.hpp rename to src/ENDFtk/syntaxTree/Section/src/parse-endf.hpp diff --git a/src/ENDFtk/syntaxTree/Section/src/parse-gendf.hpp b/src/ENDFtk/syntaxTree/Section/src/parse-gendf.hpp new file mode 100644 index 000000000..2f16c918d --- /dev/null +++ b/src/ENDFtk/syntaxTree/Section/src/parse-gendf.hpp @@ -0,0 +1,32 @@ +template< int MF, int... OptionalMT > +section::GendfType< MF, OptionalMT... > parse( long& lineNumber ) const { + auto position = this->buffer().begin(); + auto end = this->buffer().end(); + + HeadRecord head( position, end, lineNumber ); + return { head, position, end, lineNumber, head.MAT() }; +} + +template< int MF, int... OptionalMT > +section::GendfType< MF, OptionalMT... > parse() const { + long lineNumber = 1; + return this->parse< MF, OptionalMT... >( lineNumber ); +} + +template< long long MF, long long... OptionalMT> +auto parse( hana::llong, hana::llong... ) const { + + return parse< MF, OptionalMT... >(); +} + +template< long long MF> +auto parse( hana::llong, long& lineNumber ) const { + + return parse< MF >( lineNumber ); +} + +template< long long MF, long long MT> +auto parse( hana::llong, hana::llong, long& lineNumber ) const { + + return parse< MF, MT >( lineNumber ); +} diff --git a/src/ENDFtk/syntaxTree/Section/test/CMakeLists.txt b/src/ENDFtk/syntaxTree/Section/test/CMakeLists.txt index deab0f3b6..64e596269 100644 --- a/src/ENDFtk/syntaxTree/Section/test/CMakeLists.txt +++ b/src/ENDFtk/syntaxTree/Section/test/CMakeLists.txt @@ -8,7 +8,19 @@ $<$: ${${PREFIX}_RELEASE_flags} $<$:${${PREFIX}_link_time_optimization_flags}> $<$:${${PREFIX}_nonportable_optimization_flags}>> - ${CXX_appended_flags} ${ENDFtk_appended_flags} ) target_link_libraries( ENDFtk.syntaxTree.Section.test PUBLIC ENDFtk ) -add_test( NAME ENDFtk.syntaxTree.Section COMMAND ENDFtk.syntaxTree.Section.test ) \ No newline at end of file +add_test( NAME ENDFtk.syntaxTree.Section COMMAND ENDFtk.syntaxTree.Section.test ) + +add_executable( ENDFtk.syntaxTree.GendfSection.test GendfSection.test.cpp ) +target_compile_options( ENDFtk.syntaxTree.GendfSection.test PRIVATE ${${PREFIX}_common_flags} +$<$:${${PREFIX}_strict_flags}>$<$: +${${PREFIX}_DEBUG_flags} +$<$:${${PREFIX}_coverage_flags}>> +$<$: +${${PREFIX}_RELEASE_flags} +$<$:${${PREFIX}_link_time_optimization_flags}> +$<$:${${PREFIX}_nonportable_optimization_flags}>> +${CXX_appended_flags} ${ENDFtk_appended_flags} ) +target_link_libraries( ENDFtk.syntaxTree.GendfSection.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.syntaxTree.GendfSection COMMAND ENDFtk.syntaxTree.GendfSection.test ) diff --git a/src/ENDFtk/syntaxTree/Section/test/GendfSection.test.cpp b/src/ENDFtk/syntaxTree/Section/test/GendfSection.test.cpp new file mode 100755 index 000000000..cef6ea53b --- /dev/null +++ b/src/ENDFtk/syntaxTree/Section/test/GendfSection.test.cpp @@ -0,0 +1,201 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk.hpp" + +std::string mfd3mt2(); +std::string validSEND(); +std::string invalidSEND(); + +using namespace njoy::ENDFtk; + +SCENARIO( "Creating a syntax tree of a GENDF Section" ){ + GIVEN( "A string representation of a Section" ){ + WHEN( "a valid SEND record ends the Section" ){ + std::string sectionString = mfd3mt2() + validSEND(); + auto position = sectionString.begin(); + auto start = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 0; + + HeadRecord head( position, end, lineNumber ); + syntaxTree::GendfSection< std::string::iterator > + sectionTree( head, start, position, end, lineNumber ); + + const auto& csectionTree = sectionTree; + + THEN( "the entire stream is read" ){ + REQUIRE( 90 == lineNumber ); + } + + AND_THEN( "the buffer iterators are populated correctly "){ + REQUIRE( sectionString.begin() == sectionTree.buffer().begin() ); + REQUIRE( end == sectionTree.buffer().end() ); + REQUIRE( sectionString.begin() == csectionTree.buffer().begin() ); + REQUIRE( end == csectionTree.buffer().end() ); + } + + AND_THEN( "the file/section number or MF/MT is populated correctly" ){ + REQUIRE( 3 == sectionTree.MF() ); + REQUIRE( 3 == sectionTree.fileNumber() ); + REQUIRE( 2 == sectionTree.MT() ); + REQUIRE( 2 == sectionTree.sectionNumber() ); + REQUIRE( 2 == csectionTree.MT() ); + REQUIRE( 2 == csectionTree.sectionNumber() ); + } + + AND_THEN( "the first record of the section is a head record" ){ + auto start = sectionTree.buffer().begin(); + auto end = sectionTree.buffer().end(); + long lineNumber = 0; + + HeadRecord head( start, end, lineNumber ); + REQUIRE( head.ZA() == 9.2235E4 ); + REQUIRE( head.AWR() == 0.0 ); + REQUIRE( head.L1() == 1 ); + REQUIRE( head.L2() == 1 ); + REQUIRE( head.N1() == 0 ); + REQUIRE( head.N2() == 44 ); + } + + AND_THEN( "the section can be parsed" ){ + auto parsec = sectionTree.parse<3>(); + REQUIRE( parsec.numGroups() == 44 ); + REQUIRE( parsec.getCrossSection(1) == Approx(14.69141) ); + } + + + } // WHEN + + WHEN( "an invalid (MT!=0) SEND record ends the Section" ){ + std::string sectionString = mfd3mt2() + invalidSEND(); + THEN( "an exception is thrown" ){ + auto begin = sectionString.begin(); + auto start = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 0; + + HeadRecord head( begin, end, lineNumber ); + REQUIRE_THROWS( syntaxTree::Section< std::string::iterator >( + head, start, begin, end, lineNumber ) ); + } + } // WHEN + + WHEN( "a Section that is too short (no SEND record)" ){ + THEN( "an exception is thrown" ){ + std::string sectionString = mfd3mt2(); + auto begin = sectionString.begin(); + auto start = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 0; + HeadRecord head( begin, end, lineNumber ); + REQUIRE_THROWS( syntaxTree::Section< std::string::iterator >( + head, start, begin, end, lineNumber ) ); + } + } + } // GIVEN +} // SCENARIO + + +std::string mfd3mt2() { + return + " 9.223500+4 0.000000+0 1 1 0 449228 3 2 1\n" + " 2.936000+2 0.000000+0 2 1 2 19228 3 2 2\n" + " 8.864840+4 1.469141+1 9228 3 2 3\n" + " 2.936000+2 0.000000+0 2 1 2 29228 3 2 4\n" + " 4.076628+5 1.430320+1 9228 3 2 5\n" + " 2.936000+2 0.000000+0 2 1 2 39228 3 2 6\n" + " 3.325475+5 1.422934+1 9228 3 2 7\n" + " 2.936000+2 0.000000+0 2 1 2 49228 3 2 8\n" + " 2.704187+6 1.415084+1 9228 3 2 9\n" + " 2.936000+2 0.000000+0 2 1 2 59228 3 2 10\n" + " 9.182484+5 1.409805+1 9228 3 2 11\n" + " 2.936000+2 0.000000+0 2 1 2 69228 3 2 12\n" + " 1.831983+6 1.406694+1 9228 3 2 13\n" + " 2.936000+2 0.000000+0 2 1 2 79228 3 2 14\n" + " 1.611269+6 1.402843+1 9228 3 2 15\n" + " 2.936000+2 0.000000+0 2 1 2 89228 3 2 16\n" + " 2.150369+6 1.397806+1 9228 3 2 17\n" + " 2.936000+2 0.000000+0 2 1 2 99228 3 2 18\n" + " 1.677811+6 1.389651+1 9228 3 2 19\n" + " 2.936000+2 0.000000+0 2 1 2 109228 3 2 20\n" + " 9.702871+5 1.378522+1 9228 3 2 21\n" + " 2.936000+2 0.000000+0 2 1 2 119228 3 2 22\n" + " 3.285728+5 1.362093+1 9228 3 2 23\n" + " 2.936000+2 0.000000+0 2 1 2 129228 3 2 24\n" + " 1.348773+5 1.352095+1 9228 3 2 25\n" + " 2.936000+2 0.000000+0 2 1 2 139228 3 2 26\n" + " 1.208261+5 1.348035+1 9228 3 2 27\n" + " 2.936000+2 0.000000+0 2 1 2 149228 3 2 28\n" + " 1.094424+5 1.347708+1 9228 3 2 29\n" + " 2.936000+2 0.000000+0 2 1 2 159228 3 2 30\n" + " 1.921488+5 1.352816+1 9228 3 2 31\n" + " 2.936000+2 0.000000+0 2 1 2 169228 3 2 32\n" + " 8.537350+4 1.355762+1 9228 3 2 33\n" + " 2.936000+2 0.000000+0 2 1 2 179228 3 2 34\n" + " 7.955453+4 1.353933+1 9228 3 2 35\n" + " 2.936000+2 0.000000+0 2 1 2 189228 3 2 36\n" + " 7.448245+4 1.350431+1 9228 3 2 37\n" + " 2.936000+2 0.000000+0 2 1 2 199228 3 2 38\n" + " 5.152778+5 1.330950+1 9228 3 2 39\n" + " 2.936000+2 0.000000+0 2 1 2 209228 3 2 40\n" + " 5.421450+5 1.289614+1 9228 3 2 41\n" + " 2.936000+2 0.000000+0 2 1 2 219228 3 2 42\n" + " 6.582378+5 1.263968+1 9228 3 2 43\n" + " 2.936000+2 0.000000+0 2 1 2 229228 3 2 44\n" + " 6.085370+5 1.195173+1 9228 3 2 45\n" + " 2.936000+2 0.000000+0 2 1 2 239228 3 2 46\n" + " 5.304027+5 1.137018+1 9228 3 2 47\n" + " 2.936000+2 0.000000+0 2 1 2 249228 3 2 48\n" + " 2.698745+5 1.075633+1 9228 3 2 49\n" + " 2.936000+2 0.000000+0 2 1 2 259228 3 2 50\n" + " 3.469132+5 1.070006+1 9228 3 2 51\n" + " 2.936000+2 0.000000+0 2 1 2 269228 3 2 52\n" + " 2.436662+5 1.161760+1 9228 3 2 53\n" + " 2.936000+2 0.000000+0 2 1 2 279228 3 2 54\n" + " 1.269261+6 1.149129+1 9228 3 2 55\n" + " 2.936000+2 0.000000+0 2 1 2 289228 3 2 56\n" + " 1.389867+6 1.140790+1 9228 3 2 57\n" + " 2.936000+2 0.000000+0 2 1 2 299228 3 2 58\n" + " 1.966742+6 1.152955+1 9228 3 2 59\n" + " 2.936000+2 0.000000+0 2 1 2 309228 3 2 60\n" + " 1.958830+6 1.215428+1 9228 3 2 61\n" + " 2.936000+2 0.000000+0 2 1 2 319228 3 2 62\n" + " 2.003216+6 1.195243+1 9228 3 2 63\n" + " 2.936000+2 0.000000+0 2 1 2 329228 3 2 64\n" + " 4.448512+5 1.144792+1 9228 3 2 65\n" + " 2.936000+2 0.000000+0 2 1 2 339228 3 2 66\n" + " 1.600971+6 1.069586+1 9228 3 2 67\n" + " 2.936000+2 0.000000+0 2 1 2 349228 3 2 68\n" + " 1.653127+6 8.151080+0 9228 3 2 69\n" + " 2.936000+2 0.000000+0 2 1 2 359228 3 2 70\n" + " 1.607887+6 5.004643+0 9228 3 2 71\n" + " 2.936000+2 0.000000+0 2 1 2 369228 3 2 72\n" + " 1.044185+6 3.748074+0 9228 3 2 73\n" + " 2.936000+2 0.000000+0 2 1 2 379228 3 2 74\n" + " 5.807999+5 3.589833+0 9228 3 2 75\n" + " 2.936000+2 0.000000+0 2 1 2 389228 3 2 76\n" + " 4.118760+5 3.848525+0 9228 3 2 77\n" + " 2.936000+2 0.000000+0 2 1 2 399228 3 2 78\n" + " 7.543025+4 4.091297+0 9228 3 2 79\n" + " 2.936000+2 0.000000+0 2 1 2 409228 3 2 80\n" + " 2.347697+5 4.284081+0 9228 3 2 81\n" + " 2.936000+2 0.000000+0 2 1 2 419228 3 2 82\n" + " 3.334087+5 4.525173+0 9228 3 2 83\n" + " 2.936000+2 0.000000+0 2 1 2 429228 3 2 84\n" + " 8.667041+4 4.115439+0 9228 3 2 85\n" + " 2.936000+2 0.000000+0 2 1 2 439228 3 2 86\n" + " 3.704342+4 3.442857+0 9228 3 2 87\n" + " 2.936000+2 0.000000+0 2 1 2 449228 3 2 88\n" + " 1.292703+5 2.786681+0 9228 3 2 89\n"; +} + +std::string validSEND(){ + return + " 9228 3 0\n"; +} + +std::string invalidSEND(){ + return + " 9228 3 1\n"; +} diff --git a/src/ENDFtk/syntaxTree/Tape.hpp b/src/ENDFtk/syntaxTree/Tape.hpp index a41143a03..6b17a28c4 100644 --- a/src/ENDFtk/syntaxTree/Tape.hpp +++ b/src/ENDFtk/syntaxTree/Tape.hpp @@ -1,9 +1,9 @@ -template< typename Buffer > +template< typename Buffer, typename Tag = ENDFTag > class Tape { using BufferIterator = ranges::iterator_t< const Buffer >; public: /* convenience typedefs */ - using Material_t = Material< BufferIterator >; + using Material_t = Material< BufferIterator, Tag >; protected: /* fields */ @@ -45,3 +45,8 @@ class Tape { const TapeIdentification& TPID() const { return *( this->tpid ); } }; + + +/* convenience alias */ +template< typename Buffer > +using GendfTape = Tape< Buffer, GENDFTag >; diff --git a/src/ENDFtk/syntaxTree/Tape/test/CMakeLists.txt b/src/ENDFtk/syntaxTree/Tape/test/CMakeLists.txt index 192a7806c..814798571 100644 --- a/src/ENDFtk/syntaxTree/Tape/test/CMakeLists.txt +++ b/src/ENDFtk/syntaxTree/Tape/test/CMakeLists.txt @@ -15,4 +15,22 @@ file( GLOB resources "resources/*" ) foreach( resource ${resources}) file( COPY "${resource}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" ) endforeach() -add_test( NAME ENDFtk.syntaxTree.Tape COMMAND ENDFtk.syntaxTree.Tape.test ) \ No newline at end of file +add_test( NAME ENDFtk.syntaxTree.Tape COMMAND ENDFtk.syntaxTree.Tape.test ) + +add_executable( ENDFtk.syntaxTree.GendfTape.test GendfTape.test.cpp ) +target_compile_options( ENDFtk.syntaxTree.GendfTape.test PRIVATE ${${PREFIX}_common_flags} +$<$:${${PREFIX}_strict_flags}>$<$: +${${PREFIX}_DEBUG_flags} +$<$:${${PREFIX}_coverage_flags}>> +$<$: +${${PREFIX}_RELEASE_flags} +$<$:${${PREFIX}_link_time_optimization_flags}> +$<$:${${PREFIX}_nonportable_optimization_flags}>> + +${CXX_appended_flags} ${ENDFtk_appended_flags} ) +target_link_libraries( ENDFtk.syntaxTree.GendfTape.test PUBLIC ENDFtk ) +file( GLOB resources "resources/*" ) +foreach( resource ${resources}) + file( COPY "${resource}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" ) +endforeach() +add_test( NAME ENDFtk.syntaxTree.GendfTape COMMAND ENDFtk.syntaxTree.GendfTape.test ) diff --git a/src/ENDFtk/syntaxTree/Tape/test/GendfTape.test.cpp b/src/ENDFtk/syntaxTree/Tape/test/GendfTape.test.cpp new file mode 100644 index 000000000..0ac8fe30f --- /dev/null +++ b/src/ENDFtk/syntaxTree/Tape/test/GendfTape.test.cpp @@ -0,0 +1,154 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk.hpp" + +using namespace njoy::ENDFtk; + + +std::string headerString(); +std::string mfd3mt2(); +std::string validMEND(); +std::string validTEND(); + + +SCENARIO( "testing GENDF tape read" ) { + GIVEN( "a string representation of a GendfTape" ) { + WHEN( "duplicate section is present" ){ + + std::string buffer = headerString() + mfd3mt2() + mfd3mt2() + + validMEND() + validTEND(); + + THEN( "the object can be constructed and queried." ) { + + syntaxTree::GendfTape< std::string > tape( buffer ); + CHECK(tape.size() == 1); + CHECK(tape.hasMaterialNumber(9228)); + + } + } + } +} + +std::string headerString() { + return + "ENDF, TENDF -> UNRESR, GROUPR -> GENDF 0 0 0 0\n" + " 9.223500+4 2.330248+2 0 1 -1 19228 1451 1\n" + " 2.936000+2 0.000000+0 44 12 60 09228 1451 2\n" + " 0.000000+0 1.00000+10 1.000000-5 3.000000-3 7.500000-3 1.000000-29228 1451 3\n" + " 2.530000-2 3.000000-2 4.000000-2 5.000000-2 7.000000-2 1.000000-19228 1451 4\n" + " 1.500000-1 2.000000-1 2.250000-1 2.500000-1 2.750000-1 3.250000-19228 1451 5\n" + " 3.500000-1 3.750000-1 4.000000-1 6.250000-1 1.000000+0 1.770000+09228 1451 6\n" + " 3.000000+0 4.750000+0 6.000000+0 8.100000+0 1.000000+1 3.000000+19228 1451 7\n" + " 1.000000+2 5.500000+2 3.000000+3 1.700000+4 2.500000+4 1.000000+59228 1451 8\n" + " 4.000000+5 9.000000+5 1.400000+6 1.850000+6 2.354000+6 2.479000+69228 1451 9\n" + " 3.000000+6 4.800000+6 6.434000+6 8.187300+6 2.000000+7 1.000000+49228 1451 10\n" + " 1.000000+5 5.000000+5 1.000000+6 2.000000+6 3.000000+6 4.000000+69228 1451 11\n" + " 5.000000+6 6.000000+6 7.000000+6 8.000000+6 9.000000+6 2.000000+79228 1451 12\n" + " 9228 0 0 0\n"; +} + +std::string mfd3mt2() { + return + " 9.223500+4 0.000000+0 1 1 0 449228 3 2 1\n" + " 2.936000+2 0.000000+0 2 1 2 19228 3 2 2\n" + " 8.864840+4 1.469141+1 9228 3 2 3\n" + " 2.936000+2 0.000000+0 2 1 2 29228 3 2 4\n" + " 4.076628+5 1.430320+1 9228 3 2 5\n" + " 2.936000+2 0.000000+0 2 1 2 39228 3 2 6\n" + " 3.325475+5 1.422934+1 9228 3 2 7\n" + " 2.936000+2 0.000000+0 2 1 2 49228 3 2 8\n" + " 2.704187+6 1.415084+1 9228 3 2 9\n" + " 2.936000+2 0.000000+0 2 1 2 59228 3 2 10\n" + " 9.182484+5 1.409805+1 9228 3 2 11\n" + " 2.936000+2 0.000000+0 2 1 2 69228 3 2 12\n" + " 1.831983+6 1.406694+1 9228 3 2 13\n" + " 2.936000+2 0.000000+0 2 1 2 79228 3 2 14\n" + " 1.611269+6 1.402843+1 9228 3 2 15\n" + " 2.936000+2 0.000000+0 2 1 2 89228 3 2 16\n" + " 2.150369+6 1.397806+1 9228 3 2 17\n" + " 2.936000+2 0.000000+0 2 1 2 99228 3 2 18\n" + " 1.677811+6 1.389651+1 9228 3 2 19\n" + " 2.936000+2 0.000000+0 2 1 2 109228 3 2 20\n" + " 9.702871+5 1.378522+1 9228 3 2 21\n" + " 2.936000+2 0.000000+0 2 1 2 119228 3 2 22\n" + " 3.285728+5 1.362093+1 9228 3 2 23\n" + " 2.936000+2 0.000000+0 2 1 2 129228 3 2 24\n" + " 1.348773+5 1.352095+1 9228 3 2 25\n" + " 2.936000+2 0.000000+0 2 1 2 139228 3 2 26\n" + " 1.208261+5 1.348035+1 9228 3 2 27\n" + " 2.936000+2 0.000000+0 2 1 2 149228 3 2 28\n" + " 1.094424+5 1.347708+1 9228 3 2 29\n" + " 2.936000+2 0.000000+0 2 1 2 159228 3 2 30\n" + " 1.921488+5 1.352816+1 9228 3 2 31\n" + " 2.936000+2 0.000000+0 2 1 2 169228 3 2 32\n" + " 8.537350+4 1.355762+1 9228 3 2 33\n" + " 2.936000+2 0.000000+0 2 1 2 179228 3 2 34\n" + " 7.955453+4 1.353933+1 9228 3 2 35\n" + " 2.936000+2 0.000000+0 2 1 2 189228 3 2 36\n" + " 7.448245+4 1.350431+1 9228 3 2 37\n" + " 2.936000+2 0.000000+0 2 1 2 199228 3 2 38\n" + " 5.152778+5 1.330950+1 9228 3 2 39\n" + " 2.936000+2 0.000000+0 2 1 2 209228 3 2 40\n" + " 5.421450+5 1.289614+1 9228 3 2 41\n" + " 2.936000+2 0.000000+0 2 1 2 219228 3 2 42\n" + " 6.582378+5 1.263968+1 9228 3 2 43\n" + " 2.936000+2 0.000000+0 2 1 2 229228 3 2 44\n" + " 6.085370+5 1.195173+1 9228 3 2 45\n" + " 2.936000+2 0.000000+0 2 1 2 239228 3 2 46\n" + " 5.304027+5 1.137018+1 9228 3 2 47\n" + " 2.936000+2 0.000000+0 2 1 2 249228 3 2 48\n" + " 2.698745+5 1.075633+1 9228 3 2 49\n" + " 2.936000+2 0.000000+0 2 1 2 259228 3 2 50\n" + " 3.469132+5 1.070006+1 9228 3 2 51\n" + " 2.936000+2 0.000000+0 2 1 2 269228 3 2 52\n" + " 2.436662+5 1.161760+1 9228 3 2 53\n" + " 2.936000+2 0.000000+0 2 1 2 279228 3 2 54\n" + " 1.269261+6 1.149129+1 9228 3 2 55\n" + " 2.936000+2 0.000000+0 2 1 2 289228 3 2 56\n" + " 1.389867+6 1.140790+1 9228 3 2 57\n" + " 2.936000+2 0.000000+0 2 1 2 299228 3 2 58\n" + " 1.966742+6 1.152955+1 9228 3 2 59\n" + " 2.936000+2 0.000000+0 2 1 2 309228 3 2 60\n" + " 1.958830+6 1.215428+1 9228 3 2 61\n" + " 2.936000+2 0.000000+0 2 1 2 319228 3 2 62\n" + " 2.003216+6 1.195243+1 9228 3 2 63\n" + " 2.936000+2 0.000000+0 2 1 2 329228 3 2 64\n" + " 4.448512+5 1.144792+1 9228 3 2 65\n" + " 2.936000+2 0.000000+0 2 1 2 339228 3 2 66\n" + " 1.600971+6 1.069586+1 9228 3 2 67\n" + " 2.936000+2 0.000000+0 2 1 2 349228 3 2 68\n" + " 1.653127+6 8.151080+0 9228 3 2 69\n" + " 2.936000+2 0.000000+0 2 1 2 359228 3 2 70\n" + " 1.607887+6 5.004643+0 9228 3 2 71\n" + " 2.936000+2 0.000000+0 2 1 2 369228 3 2 72\n" + " 1.044185+6 3.748074+0 9228 3 2 73\n" + " 2.936000+2 0.000000+0 2 1 2 379228 3 2 74\n" + " 5.807999+5 3.589833+0 9228 3 2 75\n" + " 2.936000+2 0.000000+0 2 1 2 389228 3 2 76\n" + " 4.118760+5 3.848525+0 9228 3 2 77\n" + " 2.936000+2 0.000000+0 2 1 2 399228 3 2 78\n" + " 7.543025+4 4.091297+0 9228 3 2 79\n" + " 2.936000+2 0.000000+0 2 1 2 409228 3 2 80\n" + " 2.347697+5 4.284081+0 9228 3 2 81\n" + " 2.936000+2 0.000000+0 2 1 2 419228 3 2 82\n" + " 3.334087+5 4.525173+0 9228 3 2 83\n" + " 2.936000+2 0.000000+0 2 1 2 429228 3 2 84\n" + " 8.667041+4 4.115439+0 9228 3 2 85\n" + " 2.936000+2 0.000000+0 2 1 2 439228 3 2 86\n" + " 3.704342+4 3.442857+0 9228 3 2 87\n" + " 2.936000+2 0.000000+0 2 1 2 449228 3 2 88\n" + " 1.292703+5 2.786681+0 9228 3 2 89\n" + " 9228 3 099999\n"; +} + +std::string validMEND() { + return + " 0 0 0 0\n"; +} + +std::string validTEND() { + return + " -1 0 0 0\n"; +} +