diff --git a/.github/workflows/ContinuousIntegration.yml b/.github/workflows/ContinuousIntegration.yml index 78a486da5..bdf7ed600 100644 --- a/.github/workflows/ContinuousIntegration.yml +++ b/.github/workflows/ContinuousIntegration.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: os: [ ubuntu-18.04, macos-10.15 ] - cxx: [ clang++ ] + cxx: [ clang++, g++-9 ] build_type: [ Debug, Release ] steps: diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b689a931..d230f2371 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ set( REPOSITORIES "release" "Options for where to fetch repositories: develop, release, local" ) +message( STATUS "Using ${REPOSITORIES} repositories" ) + if( REPOSITORIES STREQUAL "develop" ) include( cmake/develop_dependencies.cmake ) @@ -67,7 +69,7 @@ target_link_libraries( ENDFtk INTERFACE disco INTERFACE hana-adapter INTERFACE header-utilities - INTERFACE range-v3-adapter + INTERFACE range-v3 ) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -182,6 +184,8 @@ pybind11_add_module( ENDFtk.python python/src/section/7/4/AnalyticalFunctions.python.cpp python/src/section/7/4/TabulatedFunctions.python.cpp python/src/section/7/4/ScatteringFunction.python.cpp + python/src/section/8/FissionYieldData.python.cpp + python/src/section/8/454.python.cpp python/src/section/8/457.python.cpp python/src/section/8/457/AverageDecayEnergies.python.cpp python/src/section/8/457/DecayMode.python.cpp @@ -189,6 +193,11 @@ pybind11_add_module( ENDFtk.python python/src/section/8/457/DiscreteSpectrum.python.cpp python/src/section/8/457/ContinuousSpectrum.python.cpp python/src/section/8/457/DecaySpectrum.python.cpp + python/src/section/8/459.python.cpp + python/src/section/9.python.cpp + python/src/section/9/ReactionProduct.python.cpp + python/src/section/10.python.cpp + python/src/section/10/ReactionProduct.python.cpp python/src/section/12.python.cpp python/src/section/12/TotalMultiplicity.python.cpp python/src/section/12/PartialMultiplicity.python.cpp @@ -197,6 +206,17 @@ pybind11_add_module( ENDFtk.python python/src/section/13.python.cpp python/src/section/13/TotalCrossSection.python.cpp python/src/section/13/PartialCrossSection.python.cpp + python/src/section/14.python.cpp + python/src/section/14/IsotropicDiscretePhoton.python.cpp + python/src/section/14/LegendreCoefficients.python.cpp + python/src/section/14/TabulatedDistribution.python.cpp + python/src/section/14/LegendreDistributions.python.cpp + python/src/section/14/TabulatedDistributions.python.cpp + python/src/section/15.python.cpp + python/src/section/15/OutgoingEnergyDistribution.python.cpp + python/src/section/15/TabulatedSpectrum.python.cpp + python/src/section/15/Probability.python.cpp + python/src/section/15/PartialDistribution.python.cpp python/src/file/1.python.cpp python/src/file/2.python.cpp python/src/file/3.python.cpp @@ -205,8 +225,12 @@ pybind11_add_module( ENDFtk.python python/src/file/6.python.cpp python/src/file/7.python.cpp python/src/file/8.python.cpp + python/src/file/9.python.cpp + python/src/file/10.python.cpp python/src/file/12.python.cpp python/src/file/13.python.cpp + python/src/file/14.python.cpp + python/src/file/15.python.cpp python/src/Material.python.cpp python/src/tree/Section.python.cpp python/src/tree/File.python.cpp diff --git a/cmake/develop_dependencies.cmake b/cmake/develop_dependencies.cmake index b3abbdc72..7f655ec6c 100644 --- a/cmake/develop_dependencies.cmake +++ b/cmake/develop_dependencies.cmake @@ -35,16 +35,14 @@ FetchContent_Declare( header-utilities GIT_SHALLOW TRUE ) -FetchContent_Declare( range-v3-adapter - GIT_REPOSITORY https://github.com/njoy/range-v3-adapter - GIT_TAG origin/master - GIT_SHALLOW TRUE +FetchContent_Declare( range-v3 + GIT_REPOSITORY https://github.com/ericniebler/range-v3 + GIT_TAG 0.11.0 ) FetchContent_Declare( pybind11 GIT_REPOSITORY https://github.com/pybind/pybind11 GIT_TAG v2.6.1 - GIT_SHALLOW TRUE ) ####################################################################### @@ -57,6 +55,6 @@ FetchContent_MakeAvailable( disco hana-adapter header-utilities - range-v3-adapter + range-v3 pybind11 ) diff --git a/cmake/release_dependencies.cmake b/cmake/release_dependencies.cmake index 2bc44944f..e33220f8a 100644 --- a/cmake/release_dependencies.cmake +++ b/cmake/release_dependencies.cmake @@ -35,9 +35,9 @@ FetchContent_Declare( pybind11 GIT_TAG f1abf5d9159b805674197f6bc443592e631c9130 # tag: v2.6.1 ) -FetchContent_Declare( range-v3-adapter - GIT_REPOSITORY https://github.com/njoy/range-v3-adapter - GIT_TAG 252679d4737c8f755d87c0e1eed6c37394a2ec59 +FetchContent_Declare( range-v3 + GIT_REPOSITORY https://github.com/ericniebler/range-v3 + GIT_TAG 4989f3e9ff2efee1852942bb9328ef121369ba02 # tag: 0.11.0 ) FetchContent_Declare( spdlog @@ -57,6 +57,6 @@ FetchContent_MakeAvailable( header-utilities Log pybind11 - range-v3-adapter + range-v3 spdlog ) diff --git a/cmake/unit_testing.cmake b/cmake/unit_testing.cmake index 26068311b..bd31dbca4 100644 --- a/cmake/unit_testing.cmake +++ b/cmake/unit_testing.cmake @@ -16,12 +16,12 @@ add_subdirectory( src/ENDFtk/HeadRecord/test ) add_subdirectory( src/ENDFtk/InterpolationRecord/test ) add_subdirectory( src/ENDFtk/InterpolationSequenceRecord/test ) add_subdirectory( src/ENDFtk/ListRecord/test ) +add_subdirectory( src/ENDFtk/Material/test ) add_subdirectory( src/ENDFtk/StructureDivision/test ) add_subdirectory( src/ENDFtk/TabulationRecord/test ) +add_subdirectory( src/ENDFtk/Tape/test ) add_subdirectory( src/ENDFtk/TapeIdentification/test ) add_subdirectory( src/ENDFtk/TextRecord/test ) -add_subdirectory( src/ENDFtk/Material/test ) -add_subdirectory( src/ENDFtk/Tape/test ) add_subdirectory( src/ENDFtk/file/1/test ) add_subdirectory( src/ENDFtk/file/2/test ) add_subdirectory( src/ENDFtk/file/7/test ) @@ -33,24 +33,26 @@ add_subdirectory( src/ENDFtk/record/Sequence/test ) add_subdirectory( src/ENDFtk/record/Tail/test ) add_subdirectory( src/ENDFtk/record/Zipper/test ) add_subdirectory( src/ENDFtk/record/test ) -add_subdirectory( src/ENDFtk/section/1/PolynomialMultiplicity/test ) -add_subdirectory( src/ENDFtk/section/1/TabulatedMultiplicity/test ) add_subdirectory( src/ENDFtk/section/1/451/test ) add_subdirectory( src/ENDFtk/section/1/452/test ) -add_subdirectory( src/ENDFtk/section/1/455/test ) add_subdirectory( src/ENDFtk/section/1/455/DecayConstants/test ) add_subdirectory( src/ENDFtk/section/1/455/EnergyDependentConstants/test ) add_subdirectory( src/ENDFtk/section/1/455/EnergyIndependentConstants/test ) +add_subdirectory( src/ENDFtk/section/1/455/test ) add_subdirectory( src/ENDFtk/section/1/456/test ) -add_subdirectory( src/ENDFtk/section/1/458/test ) add_subdirectory( src/ENDFtk/section/1/458/EnergyReleaseComponent/test ) add_subdirectory( src/ENDFtk/section/1/458/PolynomialComponents/test ) add_subdirectory( src/ENDFtk/section/1/458/TabulatedComponents/test ) add_subdirectory( src/ENDFtk/section/1/458/ThermalPointComponents/test ) -add_subdirectory( src/ENDFtk/section/1/460/test ) +add_subdirectory( src/ENDFtk/section/1/458/test ) add_subdirectory( src/ENDFtk/section/1/460/ContinuousPhotons/test ) -add_subdirectory( src/ENDFtk/section/1/460/DiscretePhotons/test ) add_subdirectory( src/ENDFtk/section/1/460/DiscretePhotonMultiplicity/test ) +add_subdirectory( src/ENDFtk/section/1/460/DiscretePhotons/test ) +add_subdirectory( src/ENDFtk/section/1/460/test ) +add_subdirectory( src/ENDFtk/section/1/PolynomialMultiplicity/test ) +add_subdirectory( src/ENDFtk/section/1/TabulatedMultiplicity/test ) +add_subdirectory( src/ENDFtk/section/10/ReactionProduct/test ) +add_subdirectory( src/ENDFtk/section/10/test ) add_subdirectory( src/ENDFtk/section/12/Multiplicities/test ) add_subdirectory( src/ENDFtk/section/12/PartialMultiplicity/test ) add_subdirectory( src/ENDFtk/section/12/TotalMultiplicity/test ) @@ -60,19 +62,30 @@ add_subdirectory( src/ENDFtk/section/12/test ) add_subdirectory( src/ENDFtk/section/13/PartialCrossSection/test ) add_subdirectory( src/ENDFtk/section/13/TotalCrossSection/test ) add_subdirectory( src/ENDFtk/section/13/test ) +add_subdirectory( src/ENDFtk/section/14/IsotropicDiscretePhoton/test ) +add_subdirectory( src/ENDFtk/section/14/LegendreCoefficients/test ) +add_subdirectory( src/ENDFtk/section/14/LegendreDistributions/test ) +add_subdirectory( src/ENDFtk/section/14/TabulatedDistribution/test ) +add_subdirectory( src/ENDFtk/section/14/TabulatedDistributions/test ) +add_subdirectory( src/ENDFtk/section/14/test ) +add_subdirectory( src/ENDFtk/section/15/PartialDistribution/test ) +add_subdirectory( src/ENDFtk/section/15/Probability/test ) +add_subdirectory( src/ENDFtk/section/15/TabulatedSpectrum/OutgoingEnergyDistribution/test ) +add_subdirectory( src/ENDFtk/section/15/TabulatedSpectrum/test ) +add_subdirectory( src/ENDFtk/section/15/test ) add_subdirectory( src/ENDFtk/section/2/151/BreitWignerLValue/Resonance/test ) add_subdirectory( src/ENDFtk/section/2/151/BreitWignerLValue/test ) add_subdirectory( src/ENDFtk/section/2/151/Isotope/test ) add_subdirectory( src/ENDFtk/section/2/151/MultiLevelBreitWigner/test ) +add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels/test ) +add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/FrohnerBackgroundRMatrix/test ) +add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/NoBackgroundRMatrix/test ) add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/ParticlePairs/test ) add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/ResonanceChannels/test ) add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/ResonanceParameters/test ) -add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/NoBackgroundRMatrix/test ) -add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/test ) add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/SammyBackgroundRMatrix/test ) -add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/FrohnerBackgroundRMatrix/test ) -add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels/test ) add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/SpinGroup/test ) +add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/test ) add_subdirectory( src/ENDFtk/section/2/151/RMatrixLimited/test ) add_subdirectory( src/ENDFtk/section/2/151/ReichMoore/test ) add_subdirectory( src/ENDFtk/section/2/151/ReichMooreLValue/Resonance/test ) @@ -106,8 +119,8 @@ add_subdirectory( src/ENDFtk/section/5/GeneralEvaporationSpectrum/test ) add_subdirectory( src/ENDFtk/section/5/MadlandNixSpectrum/test ) add_subdirectory( src/ENDFtk/section/5/MaxwellianFissionSpectrum/test ) add_subdirectory( src/ENDFtk/section/5/Parameter/test ) -add_subdirectory( src/ENDFtk/section/5/Probability/test ) add_subdirectory( src/ENDFtk/section/5/PartialDistribution/test ) +add_subdirectory( src/ENDFtk/section/5/Probability/test ) add_subdirectory( src/ENDFtk/section/5/TabulatedSpectrum/OutgoingEnergyDistribution/test ) add_subdirectory( src/ENDFtk/section/5/TabulatedSpectrum/test ) add_subdirectory( src/ENDFtk/section/5/WattSpectrum/test ) @@ -147,6 +160,7 @@ add_subdirectory( src/ENDFtk/section/7/4/ScatteringLawConstants/test ) add_subdirectory( src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction/test ) add_subdirectory( src/ENDFtk/section/7/4/TabulatedFunctions/test ) add_subdirectory( src/ENDFtk/section/7/4/test ) +add_subdirectory( src/ENDFtk/section/8/454/test ) add_subdirectory( src/ENDFtk/section/8/457/AverageDecayEnergies/test ) add_subdirectory( src/ENDFtk/section/8/457/ContinuousSpectrum/test ) add_subdirectory( src/ENDFtk/section/8/457/DecayMode/test ) @@ -154,6 +168,11 @@ add_subdirectory( src/ENDFtk/section/8/457/DecayModes/test ) add_subdirectory( src/ENDFtk/section/8/457/DecaySpectrum/test ) add_subdirectory( src/ENDFtk/section/8/457/DiscreteSpectrum/test ) add_subdirectory( src/ENDFtk/section/8/457/test ) +add_subdirectory( src/ENDFtk/section/8/459/test ) +add_subdirectory( src/ENDFtk/section/8/FissionYieldData/FissionProduct/test ) +add_subdirectory( src/ENDFtk/section/8/FissionYieldData/test ) +add_subdirectory( src/ENDFtk/section/9/ReactionProduct/test ) +add_subdirectory( src/ENDFtk/section/9/test ) add_subdirectory( src/ENDFtk/section/Base/test ) add_subdirectory( src/ENDFtk/section/BaseWithoutMT/test ) add_subdirectory( src/ENDFtk/test ) @@ -161,3 +180,6 @@ add_subdirectory( src/ENDFtk/tree/File/test ) add_subdirectory( src/ENDFtk/tree/Material/test ) add_subdirectory( src/ENDFtk/tree/Section/test ) add_subdirectory( src/ENDFtk/tree/Tape/test ) +add_subdirectory( src/ENDFtk/gendf/SectionBase/test ) +add_subdirectory( src/ENDFtk/gendf/DataRecord/test ) +add_subdirectory( src/ENDFtk/gendf/CrossSection/test ) diff --git a/python/src/ENDFtk.python.cpp b/python/src/ENDFtk.python.cpp index e098e4f4c..ffa754af1 100644 --- a/python/src/ENDFtk.python.cpp +++ b/python/src/ENDFtk.python.cpp @@ -22,8 +22,12 @@ void wrapFile_5( python::module&, python::module& ); void wrapFile_6( python::module&, python::module& ); void wrapFile_7( python::module&, python::module& ); void wrapFile_8( python::module&, python::module& ); +void wrapFile_9( python::module&, python::module& ); +void wrapFile_10( python::module&, python::module& ); void wrapFile_12( python::module&, python::module& ); void wrapFile_13( python::module&, python::module& ); +void wrapFile_14( python::module&, python::module& ); +void wrapFile_15( python::module&, python::module& ); // material and tape void wrapMaterial( python::module&, python::module& ); @@ -83,8 +87,12 @@ PYBIND11_MODULE( ENDFtk, module ) { wrapFile_6( module, viewmodule ); wrapFile_7( module, viewmodule ); wrapFile_8( module, viewmodule ); + wrapFile_9( module, viewmodule ); + wrapFile_10( module, viewmodule ); wrapFile_12( module, viewmodule ); wrapFile_13( module, viewmodule ); + wrapFile_14( module, viewmodule ); + wrapFile_15( module, viewmodule ); // wrap material and tape wrapMaterial( module, viewmodule ); diff --git a/python/src/Material.python.cpp b/python/src/Material.python.cpp index 6da5ca505..badb8ec1b 100644 --- a/python/src/Material.python.cpp +++ b/python/src/Material.python.cpp @@ -25,8 +25,12 @@ void wrapMaterial( python::module& module, python::module& ) { using MF6 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 6 > >; using MF7 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 7 > >; using MF8 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 8 > >; + using MF9 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 9 > >; + using MF10 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 10 > >; using MF12 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 12 > >; using MF13 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 13 > >; + using MF14 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 14 > >; + using MF15 = std::reference_wrapper< const njoy::ENDFtk::file::Type< 15 > >; // wrap views created by this section @@ -38,6 +42,33 @@ void wrapMaterial( python::module& module, python::module& ) { "Material - nuclear data for a single material" ); + // predefined lambda + auto getFile = [] ( const Material& self, int mf ) + -> std::variant< MF1, MF2, MF3, MF4, MF5, MF6, MF7, MF8, MF9, MF10, + MF12, MF13, MF14, MF15 > { + + switch ( mf ) { + + case 1 : return self.file( 1_c ); + case 2 : return self.file( 2_c ); + case 3 : return self.file( 3_c ); + case 4 : return self.file( 4_c ); + case 5 : return self.file( 5_c ); + case 6 : return self.file( 6_c ); + case 7 : return self.file( 7_c ); + case 8 : return self.file( 8_c ); + case 9 : return self.file( 9_c ); + case 10 : return self.file( 10_c ); + case 12 : return self.file( 12_c ); + case 13 : return self.file( 13_c ); + case 14 : return self.file( 14_c ); + case 15 : return self.file( 15_c ); + default: throw std::runtime_error( + "Requested file number (" + std::to_string( mf ) + + ") does not correspond to a stored file" ); + } + }; + // wrap the section material .def_property_readonly( @@ -75,26 +106,7 @@ void wrapMaterial( python::module& module, python::module& ) { .def( "MF", - [] ( const Material& self, int mf ) - -> std::variant< MF1, MF2, MF3, MF4, MF5, MF6, MF7, MF8, MF12, MF13 > { - - switch ( mf ) { - - case 1 : return self.file( 1_c ); - case 2 : return self.file( 2_c ); - case 3 : return self.file( 3_c ); - case 4 : return self.file( 4_c ); - case 5 : return self.file( 5_c ); - case 6 : return self.file( 6_c ); - case 7 : return self.file( 7_c ); - case 8 : return self.file( 8_c ); - case 12 : return self.file( 12_c ); - case 13 : return self.file( 13_c ); - default: throw std::runtime_error( - "Requested file number (" + std::to_string( mf ) + - ") does not correspond to a stored file" ); - } - }, + getFile, python::arg( "mf" ), "Return the file with the requested MF number\n\n" "Arguments:\n" @@ -105,26 +117,7 @@ void wrapMaterial( python::module& module, python::module& ) { .def( "file", - [] ( const Material& self, int mf ) - -> std::variant< MF1, MF2, MF3, MF4, MF5, MF6, MF7, MF8, MF12, MF13 > { - - switch ( mf ) { - - case 1 : return self.file( 1_c ); - case 2 : return self.file( 2_c ); - case 3 : return self.file( 3_c ); - case 4 : return self.file( 4_c ); - case 5 : return self.file( 5_c ); - case 6 : return self.file( 6_c ); - case 7 : return self.file( 7_c ); - case 8 : return self.file( 8_c ); - case 12 : return self.file( 12_c ); - case 13 : return self.file( 13_c ); - default: throw std::runtime_error( - "Requested file number (" + std::to_string( mf ) + - ") does not correspond to a stored file" ); - } - }, + getFile, python::arg( "mf" ), "Return the file with the requested MF number\n\n" "Arguments:\n" diff --git a/python/src/file/10.python.cpp b/python/src/file/10.python.cpp new file mode 100644 index 000000000..911366132 --- /dev/null +++ b/python/src/file/10.python.cpp @@ -0,0 +1,52 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/file/10.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +// declarations - sections +void wrapSection_10( python::module&, python::module& ); + +void wrapFile_10( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 10 >; + using File = njoy::ENDFtk::file::Type< 10 >; + using SectionRange = BidirectionalAnyView< Section >; + + // create the submodule + python::module submodule = module.def_submodule( + + "MF10", + "MF10 - production cross sections for radioactive nuclides" + ); + + // wrap sections + wrapSection_10( submodule, viewmodule ); + + // wrap views created by this file + // none of these are supposed to be created directly by the user + wrapBidirectionalAnyViewOf< Section >( + viewmodule, + "any_view< section::Type< 10 >, bidirectional >" ); + + // create the file + python::class_< File > file( + + submodule, + "File", + "MF10 file - production cross sections for radioactive nuclides" + ); + + // wrap the file + addStandardUnenumeratedFileDefinitions< File, Section, SectionRange >( file ); + + // add standard file definitions + addStandardFileDefinitions< File >( file ); +} diff --git a/python/src/file/14.python.cpp b/python/src/file/14.python.cpp new file mode 100644 index 000000000..314d8a767 --- /dev/null +++ b/python/src/file/14.python.cpp @@ -0,0 +1,52 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/file/14.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +// declarations - sections +void wrapSection_14( python::module&, python::module& ); + +void wrapFile_14( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 14 >; + using File = njoy::ENDFtk::file::Type< 14 >; + using SectionRange = BidirectionalAnyView< Section >; + + // create the submodule + python::module submodule = module.def_submodule( + + "MF14", + "MF14 - angular distributions of photons" + ); + + // wrap sections + wrapSection_14( submodule, viewmodule ); + + // wrap views created by this file + // none of these are supposed to be created directly by the user + wrapBidirectionalAnyViewOf< Section >( + viewmodule, + "any_view< section::Type< 14 >, bidirectional >" ); + + // create the file + python::class_< File > file( + + submodule, + "File", + "MF14 file - angular distributions of secondary photons" + ); + + // wrap the file + addStandardUnenumeratedFileDefinitions< File, Section, SectionRange >( file ); + + // add standard file definitions + addStandardFileDefinitions< File >( file ); +} diff --git a/python/src/file/15.python.cpp b/python/src/file/15.python.cpp new file mode 100644 index 000000000..b58f3afac --- /dev/null +++ b/python/src/file/15.python.cpp @@ -0,0 +1,52 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/file/15.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +// declarations - sections +void wrapSection_15( python::module&, python::module& ); + +void wrapFile_15( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 15 >; + using File = njoy::ENDFtk::file::Type< 15 >; + using SectionRange = BidirectionalAnyView< Section >; + + // create the submodule + python::module submodule = module.def_submodule( + + "MF15", + "MF15 - continuous photon energy spectra" + ); + + // wrap sections + wrapSection_15( submodule, viewmodule ); + + // wrap views created by this file + // none of these are supposed to be created directly by the user + wrapBidirectionalAnyViewOf< Section >( + viewmodule, + "any_view< section::Type< 15 >, bidirectional >" ); + + // create the file + python::class_< File > file( + + submodule, + "File", + "MF15 file - continuous photon energy spectra" + ); + + // wrap the file + addStandardUnenumeratedFileDefinitions< File, Section, SectionRange >( file ); + + // add standard file definitions + addStandardFileDefinitions< File >( file ); +} diff --git a/python/src/file/8.python.cpp b/python/src/file/8.python.cpp index 82decb0c3..4086ab71e 100644 --- a/python/src/file/8.python.cpp +++ b/python/src/file/8.python.cpp @@ -15,13 +15,18 @@ namespace hana = boost::hana; inline namespace literals { using namespace hana::literals; } // declarations - sections +void wrap_8_FissionYieldData( python::module&, python::module& ); +void wrapSection_8_454( python::module&, python::module& ); void wrapSection_8_457( python::module&, python::module& ); +void wrapSection_8_459( python::module&, python::module& ); void wrapFile_8( python::module& module, python::module& viewmodule ) { // type aliases using File = njoy::ENDFtk::file::Type< 8 >; + using MF8MT454 = std::reference_wrapper< const njoy::ENDFtk::section::Type< 8, 454 > >; using MF8MT457 = std::reference_wrapper< const njoy::ENDFtk::section::Type< 8, 457 > >; + using MF8MT459 = std::reference_wrapper< const njoy::ENDFtk::section::Type< 8, 459 > >; // wrap views created by this file @@ -33,7 +38,10 @@ void wrapFile_8( python::module& module, python::module& viewmodule ) { ); // wrap sections + wrap_8_FissionYieldData( submodule, viewmodule ); + wrapSection_8_454( submodule, viewmodule ); wrapSection_8_457( submodule, viewmodule ); + wrapSection_8_459( submodule, viewmodule ); // create the file python::class_< File > file( @@ -45,11 +53,14 @@ void wrapFile_8( python::module& module, python::module& viewmodule ) { // common lambda auto get_section = - [] ( const File& self, int mt ) -> std::variant< MF8MT457 > { + [] ( const File& self, int mt ) -> std::variant< MF8MT454, MF8MT457, + MF8MT459 > { switch ( mt ) { + case 454 : return self.section( 454_c ); case 457 : return self.section( 457_c ); + case 459 : return self.section( 459_c ); default: throw std::runtime_error( "Requested section number (" + std::to_string( mt ) + ") does not correspond to a stored section" ); diff --git a/python/src/file/9.python.cpp b/python/src/file/9.python.cpp new file mode 100644 index 000000000..08cb9199a --- /dev/null +++ b/python/src/file/9.python.cpp @@ -0,0 +1,52 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/file/9.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +// declarations - sections +void wrapSection_9( python::module&, python::module& ); + +void wrapFile_9( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 9 >; + using File = njoy::ENDFtk::file::Type< 9 >; + using SectionRange = BidirectionalAnyView< Section >; + + // create the submodule + python::module submodule = module.def_submodule( + + "MF9", + "MF9 - multiplicities for radioactive nuclide production" + ); + + // wrap sections + wrapSection_9( submodule, viewmodule ); + + // wrap views created by this file + // none of these are supposed to be created directly by the user + wrapBidirectionalAnyViewOf< Section >( + viewmodule, + "any_view< section::Type< 9 >, bidirectional >" ); + + // create the file + python::class_< File > file( + + submodule, + "File", + "MF9 file - multiplicities for radioactive nuclide production" + ); + + // wrap the file + addStandardUnenumeratedFileDefinitions< File, Section, SectionRange >( file ); + + // add standard file definitions + addStandardFileDefinitions< File >( file ); +} diff --git a/python/src/section/1/451.python.cpp b/python/src/section/1/451.python.cpp index f8adb4772..fda03780d 100644 --- a/python/src/section/1/451.python.cpp +++ b/python/src/section/1/451.python.cpp @@ -293,7 +293,7 @@ void wrapSection_1_451( python::module& module, python::module& viewmodule ) { "description", [] ( const Section& type ) -> std::string - { return type.description(); }, + { return ranges::to< std::string >( type.description() ); }, "The descriptive information" ) .def_property_readonly( diff --git a/python/src/section/10.python.cpp b/python/src/section/10.python.cpp new file mode 100644 index 000000000..3f7140bbb --- /dev/null +++ b/python/src/section/10.python.cpp @@ -0,0 +1,94 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/10.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf10 { + + // declarations - components + void wrapReactionProduct( python::module&, python::module& ); +} + +void wrapSection_10( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 10 >; + using ReactionProduct = Section::ReactionProduct; + using ReactionProductRange = RandomAccessAnyView< ReactionProduct >; + + // wrap components + mf10::wrapReactionProduct( module, viewmodule ); + + // wrap views created by this section + // none of these are supposed to be created directly by the user + wrapRandomAccessAnyViewOf< ReactionProduct >( + viewmodule, + "any_view< MF10::ReactionProduct, random_access >" ); + + // create the section + python::class_< Section > section( + + module, + "Section", + "MF10 section - cross sections for radioactive nuclide production" + ); + + // wrap the section + section + .def( + + python::init< int, double, double, long, + std::vector< ReactionProduct >&& >(), + python::arg( "mt" ), python::arg( "zaid" ), python::arg( "awr" ), + python::arg( "lis" ), python::arg( "products" ), + "Initialise the section\n\n" + "Arguments:\n" + " self the section\n" + " mt the MT number\n" + " zaid the ZA identifier\n" + " awr the atomic mass ratio\n" + " lis the target's excited level\n" + " products the multiplicities for every state" + ) + .def_property_readonly( + + "LIS", + &Section::LIS, + "The excited level number" + ) + .def_property_readonly( + + "excited_level", + &Section::excitedLevel, + "The excited level number" + ) + .def_property_readonly( + + "NS", + &Section::NS, + "The number of excited states for the reaction product" + ) + .def_property_readonly( + + "number_reaction_products", + &Section::numberReactionProducts, + "The number of excited states for the reaction product" + ) + .def_property_readonly( + + "reaction_products", + [] ( const Section& self ) -> ReactionProductRange + { return self.reactionProducts(); }, + "The reaction product data" + ); + + // add standard section definitions + addStandardSectionDefinitions< Section >( section ); +} diff --git a/python/src/section/10/ReactionProduct.python.cpp b/python/src/section/10/ReactionProduct.python.cpp new file mode 100644 index 000000000..a52f9edcb --- /dev/null +++ b/python/src/section/10/ReactionProduct.python.cpp @@ -0,0 +1,139 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/10.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf10 { + +void wrapReactionProduct( python::module& module, python::module& ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 10 >; + using Component = Section::ReactionProduct; + + // wrap views created by this section + + // create the component + python::class_< Component > component( + + module, + "ReactionProduct", + "MF10 section - production cross sections for a specific excited state of " + " the reaction product" + ); + + // wrap the section + component + .def( + + python::init< double, double, int, int, + std::vector< long >&&, std::vector< long >&&, + std::vector< double >&&, std::vector< double >&& >(), + python::arg( "qm" ), python::arg( "qi" ), + python::arg( "izap" ), python::arg( "lfs" ), + python::arg( "boundaries" ), python::arg( "interpolants" ), + python::arg( "energies" ), python::arg( "xs" ), + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " qm the mass difference Q value\n" + " qi the reaction Q value\n" + " izap the za identifier of the product\n" + " lfs the excited level number\n" + " boundaries the interpolation range boundaries\n" + " interpolants the interpolation types for each range\n" + " energies the energy values\n" + " xs the cross section values" + ) + .def_property_readonly( + + "QM", + &Component::QM, + "The mass difference Q value" + ) + .def_property_readonly( + + "mass_difference_qvalue", + &Component::massDifferenceQValue, + "The mass difference Q value" + ) + .def_property_readonly( + + "QI", + &Component::QI, + "The reaction Q value" + ) + .def_property_readonly( + + "reaction_qvalue", + &Component::reactionQValue, + "The mass difference Q value" + ) + .def_property_readonly( + + "IZAP", + &Component::IZAP, + "The ZA identifier of the reaction product" + ) + .def_property_readonly( + + "product_identifier", + &Component::productIdentifier, + "The ZA identifier of the reaction product" + ) + .def_property_readonly( + + "LFS", + &Component::LFS, + "The excited level number of the product" + ) + .def_property_readonly( + + "excited_level", + &Component::excitedLevel, + "The product modifier flag" + ) + .def_property_readonly( + + "E", + [] ( const Component& self ) -> DoubleRange + { return self.E(); }, + "The incident energy values" + ) + .def_property_readonly( + + "energies", + [] ( const Component& self ) -> DoubleRange + { return self.energies(); }, + "The incident energy values" + ) + .def_property_readonly( + + "XS", + [] ( const Component& self ) -> DoubleRange + { return self.XS(); }, + "The cross section values" + ) + .def_property_readonly( + + "cross_sections", + [] ( const Component& self ) -> DoubleRange + { return self.crossSections(); }, + "The cross section values" + ); + + // add standard tab1 definitions + addStandardTableDefinitions< Component >( component ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf6 diff --git a/python/src/section/12/Multiplicities.python.cpp b/python/src/section/12/Multiplicities.python.cpp index af43decd0..81627de53 100644 --- a/python/src/section/12/Multiplicities.python.cpp +++ b/python/src/section/12/Multiplicities.python.cpp @@ -77,13 +77,13 @@ void wrapMultiplicities( python::module& module, python::module& viewmodule ) { "NK", &Component::NK, - "The number of partial multiplicities (discrete photons and continuum)" + "The the number of photons (discrete and continuum) with partial multiplicities" ) .def_property_readonly( - "number_partials", - &Component::numberPartials, - "The number of partial multiplicities (discrete photons and continuum)" + "number_photons", + &Component::numberPhotons, + "The the number of photons (discrete and continuum) with partial multiplicities" ) .def_property_readonly( @@ -93,9 +93,9 @@ void wrapMultiplicities( python::module& module, python::module& viewmodule ) { ) .def_property_readonly( - "partial_multiplicities", + "photon_partial_multiplicities", [] ( const Component& self ) -> PartialMultiplicityRange - { return self.partialMultiplicities(); }, + { return self.photonPartialMultiplicities(); }, "The partial multiplicities" ) .def( diff --git a/python/src/section/13.python.cpp b/python/src/section/13.python.cpp index 6d1ba1689..761343e8e 100644 --- a/python/src/section/13.python.cpp +++ b/python/src/section/13.python.cpp @@ -83,13 +83,13 @@ void wrapSection_13( python::module& module, python::module& viewmodule ) { "NK", &Section::NK, - "The number of partial cross sections (discrete photons and continuum)" + "The number of photons (discrete and continuum) with partial cross sections" ) .def_property_readonly( - "number_partials", - &Section::numberPartials, - "The number of partial cross sections (discrete photons and continuum)" + "number_photons", + &Section::numberPhotons, + "The number of photons (discrete and continuum) with partial cross sections" ) .def_property_readonly( @@ -99,9 +99,9 @@ void wrapSection_13( python::module& module, python::module& viewmodule ) { ) .def_property_readonly( - "partial_cross_sections", + "photon_partial_cross_sections", [] ( const Section& self ) -> PartialCrossSectionRange - { return self.partialCrossSections(); }, + { return self.photonPartialCrossSections(); }, "The partial cross sections" ); diff --git a/python/src/section/14.python.cpp b/python/src/section/14.python.cpp new file mode 100644 index 000000000..52d7b6761 --- /dev/null +++ b/python/src/section/14.python.cpp @@ -0,0 +1,137 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/14.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +// declarations - components +namespace mf14 { + + void wrapIsotropicDiscretePhoton( python::module&, python::module& ); + void wrapLegendreCoefficients( python::module&, python::module& ); + void wrapTabulatedDistribution( python::module&, python::module& ); + void wrapLegendreDistributions( python::module&, python::module& ); + void wrapTabulatedDistributions( python::module&, python::module& ); +} + +void wrapSection_14( python::module& module, python::module& viewmodule ) { + + // type aliases + + // wrap components + mf14::wrapIsotropicDiscretePhoton( module, viewmodule ); + mf14::wrapLegendreCoefficients( module, viewmodule ); + mf14::wrapTabulatedDistribution( module, viewmodule ); + mf14::wrapLegendreDistributions( module, viewmodule ); + mf14::wrapTabulatedDistributions( module, viewmodule ); + + // wrap views created by this section + using Section = njoy::ENDFtk::section::Type< 14 >; + using PhotonDistribution = Section::PhotonDistribution; + using PhotonDistributionRange = RandomAccessAnyView< PhotonDistribution >; + + // wrap views created by this section + // none of these are supposed to be created directly by the user + wrapRandomAccessAnyViewOf< PhotonDistribution >( + viewmodule, + "any_view< PhotonDistribution, random_access >" ); + + // create the section + python::class_< Section > section( + + module, + "Section", + "MF14 section - angular distributions of secondary photons" + ); + + // wrap the section + section + .def( + + python::init< int, double, double >(), + python::arg( "mt" ), python::arg( "zaid" ), python::arg( "awr" ), + "Initialise the section for all isotropic photons\n\n" + "Arguments:\n" + " self the section\n" + " mt the MT number\n" + " zaid the ZA identifier\n" + " awr the atomic mass ratio" + ) + .def( + + python::init< int, double, double, + std::vector< PhotonDistribution >&& >(), + python::arg( "mt" ), python::arg( "zaid" ), python::arg( "awr" ), + python::arg( "photons" ), + "Initialise the section\n\n" + "Arguments:\n" + " self the section\n" + " mt the MT number\n" + " zaid the ZA identifier\n" + " awr the atomic mass ratio\n" + " photons the photon distribution data" + ) + .def_property_readonly( + + "NI", + &Section::NI, + "The number of photons with an isotropic angular distribution" + ) + .def_property_readonly( + + "number_isotropic_photons", + &Section::numberIsotropicPhotons, + "The number of photons with an isotropic angular distribution" + ) + .def_property_readonly( + + "NK", + &Section::NK, + "The number of photons (discrete and continuum) with angular distributions" + ) + .def_property_readonly( + + "number_photons", + &Section::numberPhotons, + "The number of photons (discrete and continuum) with angular distributions" + ) + .def_property_readonly( + + "LTT", + &Section::LTT, + "The distribution law" + ) + .def_property_readonly( + + "LAW", + &Section::LAW, + "The distribution law" + ) + .def_property_readonly( + + "LI", + &Section::LI, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "isotropic_angular_distributions", + &Section::isotropicAngularDistributions, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "photon_angular_distributions", + &Section::photonAngularDistributions, + "The secondary photons with their angular distribution" + ); + + // add standard section definitions + addStandardSectionDefinitions< Section >( section ); +} diff --git a/python/src/section/14/IsotropicDiscretePhoton.python.cpp b/python/src/section/14/IsotropicDiscretePhoton.python.cpp new file mode 100644 index 000000000..31831748c --- /dev/null +++ b/python/src/section/14/IsotropicDiscretePhoton.python.cpp @@ -0,0 +1,73 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/14.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf14 { + +void wrapIsotropicDiscretePhoton( python::module& module, python::module& ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 14 >; + using Component = Section::IsotropicDiscretePhoton; + + // wrap views created by this section + + // create the component + python::class_< Component > component( + + module, + "IsotropicDiscretePhoton", + "MF14 section - the angular distribution for a specific discrete photon \n" + " is isotropic" + ); + + // wrap the section + component + .def( + + python::init< double, double >(), + python::arg( "energy" ), python::arg( "level" ), + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " energy the photon energy\n" + " level the energy of the level from which the photon originates" + ) + .def_property_readonly( + + "ES", + &Component::ES, + "The energy of the level from which the photon originates" + ) + .def_property_readonly( + + "level_energy", + &Component::levelEnergy, + "The energy of the level from which the photon originates" + ) + .def_property_readonly( + + "EG", + &Component::EG, + "The photon energy" + ) + .def_property_readonly( + + "photon_energy", + &Component::photonEnergy, + "The photon energy or the binding energy" + ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf14 diff --git a/python/src/section/14/LegendreCoefficients.python.cpp b/python/src/section/14/LegendreCoefficients.python.cpp new file mode 100644 index 000000000..5d8723ff3 --- /dev/null +++ b/python/src/section/14/LegendreCoefficients.python.cpp @@ -0,0 +1,88 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/14.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf14 { + +void wrapLegendreCoefficients( python::module& module, python::module& ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 14 >; + using Component = Section::LegendreCoefficients; + + // wrap views created by this section + + // create the component + python::class_< Component > component( + + module, + "LegendreCoefficients", + "MF14 section - an angular distribution given as Legendre coefficients" + ); + + // wrap the section + component + .def( + + python::init< double, std::vector< double >&& >(), + python::arg( "energy" ), python::arg( "coefficients" ), + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " energy the incident energy\n" + " coefficients the Legendre coefficients" + ) + .def_property_readonly( + + "E", + &Component::E, + "The incident energy for which the angular distribution is given" + ) + .def_property_readonly( + + "incident_energy", + &Component::incidentEnergy, + "The incident energy for which the angular distribution is given" + ) + .def_property_readonly( + + "NL", + &Component::NL, + "The Legendre order for the angular distribution" + ) + .def_property_readonly( + + "legendre_order", + &Component::legendreOrder, + "The Legendre order for the angular distribution" + ) + .def_property_readonly( + + "A", + [] ( const Component& self ) -> DoubleRange + { return self.A(); }, + "The Legendre coefficients in the distribution (a0 is not present and\n" + "assumed to be equal to 1)" + ) + .def_property_readonly( + + "coefficients", + [] ( const Component& self ) -> DoubleRange + { return self.coefficients(); }, + "The Legendre coefficients in the distribution (a0 is not present and\n" + "assumed to be equal to 1)" + ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf14 diff --git a/python/src/section/14/LegendreDistributions.python.cpp b/python/src/section/14/LegendreDistributions.python.cpp new file mode 100644 index 000000000..b4e3d52c2 --- /dev/null +++ b/python/src/section/14/LegendreDistributions.python.cpp @@ -0,0 +1,135 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/14.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf14 { + +void wrapLegendreDistributions( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 14 >; + using Component = Section::LegendreDistributions; + using Distribution = Section::LegendreCoefficients; + using DistributionRange = RandomAccessAnyView< Distribution >; + + // wrap views created by this section + // none of these are supposed to be created directly by the user + wrapRandomAccessAnyViewOf< Distribution >( + viewmodule, + "any_view< MF14::LegendreCoefficients, random_access >" ); + + // create the component + python::class_< Component > component( + + module, + "LegendreDistributions", + "MF14 section - angular distributions as a function of incident energy\n" + " using Legendre coefficients (LTT=1) for a given discrete\n" + " photon" + ); + + // wrap the section + component + .def( + + python::init< double, double, std::vector< long >&&, std::vector< long >&&, + std::vector< Distribution >&& >(), + python::arg( "energy" ), python::arg( "level" ), + python::arg( "boundaries" ), python::arg( "interpolants" ), + python::arg( "distributions" ), + "Initialise the scattering radius\n\n" + "Arguments:\n" + " self the component\n" + " energy the photon energy\n" + " level the energy of the level from which the photon\n" + " originates\n" + " boundaries the interpolation range boundaries\n" + " interpolants the interpolation types for each range\n" + " distributions the sequence of angular distributions" + ) + .def_property_readonly( + + "ES", + &Component::ES, + "The energy of the level from which the photon originates" + ) + .def_property_readonly( + + "level_energy", + &Component::levelEnergy, + "The energy of the level from which the photon originates" + ) + .def_property_readonly( + + "EG", + &Component::EG, + "The photon energy" + ) + .def_property_readonly( + + "photon_energy", + &Component::photonEnergy, + "The photon energy" + ) + .def_property_readonly( + + "LI", + [] ( const Component& self ) { return self.LI(); }, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "isotropic_angular_distributions", + [] ( const Component& self ) { return self.isotropicAngularDistributions(); }, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "LTT", + [] ( const Component& self ) { return self.LTT(); }, + "The distribution law" + ) + .def_property_readonly( + + "LAW", + &Component::LAW, + "The distribution law" + ) + .def_property_readonly( + + "NE", + [] ( const Component& self ) { return self.NE(); }, + "The number of incident energy values for which angular distributions\n" + "are given" + ) + .def_property_readonly( + + "incident_energies", + [] ( const Component& self ) -> DoubleRange + { return self.incidentEnergies(); }, + "The incident energies" + ) + .def_property_readonly( + + "angular_distributions", + [] ( const Component& self ) -> DistributionRange + { return self.angularDistributions(); }, + "The angular distributions (one for each incident energy)" + ); + + // add standard tab2 definitions + addStandardInterpolationTableDefinitions< Component >( component ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf14 diff --git a/python/src/section/14/TabulatedDistribution.python.cpp b/python/src/section/14/TabulatedDistribution.python.cpp new file mode 100644 index 000000000..36da4d782 --- /dev/null +++ b/python/src/section/14/TabulatedDistribution.python.cpp @@ -0,0 +1,97 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/14.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf14 { + +void wrapTabulatedDistribution( python::module& module, python::module& ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 14 >; + using Component = Section::TabulatedDistribution; + + // wrap views created by this section + + // create the component + python::class_< Component > component( + + module, + "TabulatedDistribution", + "MF14 section - an angular distribution given as a tabulated function" + ); + + // wrap the section + component + .def( + + python::init< double, std::vector< long >&&, std::vector< long >&&, + std::vector< double >&&, std::vector< double >&& >(), + python::arg( "energy" ), python::arg( "boundaries" ), + python::arg( "interpolants" ), python::arg( "cosines" ), + python::arg( "probabilities" ), + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " incident the incident energy value\n" + " boundaries the interpolation range boundaries\n" + " interpolants the interpolation types for each range\n" + " cosines the cosine values\n" + " probabilities the probability values" + ) + .def_property_readonly( + + "E", + &Component::E, + "The incident energy for which the angular distribution is given" + ) + .def_property_readonly( + + "incident_energy", + &Component::incidentEnergy, + "The incident energy for which the angular distribution is given" + ) + .def_property_readonly( + + "MU", + [] ( const Component& self ) -> DoubleRange + { return self.MU(); }, + "The cosine values" + ) + .def_property_readonly( + + "cosines", + [] ( const Component& self ) -> DoubleRange + { return self.cosines(); }, + "The cosine values" + ) + .def_property_readonly( + + "F", + [] ( const Component& self ) -> DoubleRange + { return self.F(); }, + "The distribution probabilities" + ) + .def_property_readonly( + + "probabilities", + [] ( const Component& self ) -> DoubleRange + { return self.probabilities(); }, + "The distribution probabilities" + ); + + // add standard tab1 definitions + addStandardTableDefinitions< Component >( component ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf14 diff --git a/python/src/section/14/TabulatedDistributions.python.cpp b/python/src/section/14/TabulatedDistributions.python.cpp new file mode 100644 index 000000000..ce4884e05 --- /dev/null +++ b/python/src/section/14/TabulatedDistributions.python.cpp @@ -0,0 +1,134 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/14.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf14 { + +void wrapTabulatedDistributions( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 14 >; + using Component = Section::TabulatedDistributions; + using Distribution = Section::TabulatedDistribution; + using DistributionRange = RandomAccessAnyView< Distribution >; + + // wrap views created by this section + // none of these are supposed to be created directly by the user + wrapRandomAccessAnyViewOf< Distribution >( + viewmodule, + "any_view< MF14::TabulatedDistribution, random_access >" ); + + // create the component + python::class_< Component > component( + + module, + "TabulatedDistributions", + "MF4 section - angular distributions as a function of incident energy using\n" + " tabulated functions (LTT=2) for a given discrete photon" + ); + + // wrap the section + component + .def( + + python::init< double, double, std::vector< long >&&, std::vector< long >&&, + std::vector< Distribution >&& >(), + python::arg( "energy" ), python::arg( "level" ), + python::arg( "boundaries" ), python::arg( "interpolants" ), + python::arg( "distributions" ), + "Initialise the scattering radius\n\n" + "Arguments:\n" + " self the component\n" + " energy the photon energy\n" + " level the energy of the level from which the photon\n" + " originates\n" + " boundaries the interpolation range boundaries\n" + " interpolants the interpolation types for each range\n" + " distributions the sequence of angular distributions" + ) + .def_property_readonly( + + "ES", + &Component::ES, + "The energy of the level from which the photon originates" + ) + .def_property_readonly( + + "level_energy", + &Component::levelEnergy, + "The energy of the level from which the photon originates" + ) + .def_property_readonly( + + "EG", + &Component::EG, + "The photon energy" + ) + .def_property_readonly( + + "photon_energy", + &Component::photonEnergy, + "The photon energy" + ) + .def_property_readonly( + + "LI", + [] ( const Component& self ) { return self.LI(); }, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "isotropic_angular_distributions", + [] ( const Component& self ) { return self.isotropicAngularDistributions(); }, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "LTT", + [] ( const Component& self ) { return self.LTT(); }, + "The distribution law" + ) + .def_property_readonly( + + "LAW", + &Component::LAW, + "The distribution law" + ) + .def_property_readonly( + + "NE", + [] ( const Component& self ) { return self.NE(); }, + "The number of incident energy values for which angular distributions\n" + "are given" + ) + .def_property_readonly( + + "incident_energies", + [] ( const Component& self ) -> DoubleRange + { return self.incidentEnergies(); }, + "The incident energies" + ) + .def_property_readonly( + + "angular_distributions", + [] ( const Component& self ) -> DistributionRange + { return self.angularDistributions(); }, + "The angular distributions (one for each incident energy)" + ); + + // add standard tab2 definitions + addStandardInterpolationTableDefinitions< Component >( component ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf14 diff --git a/python/src/section/15.python.cpp b/python/src/section/15.python.cpp new file mode 100644 index 000000000..2da98217e --- /dev/null +++ b/python/src/section/15.python.cpp @@ -0,0 +1,86 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/15.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf15 { + + // declarations - components + void wrapOutgoingEnergyDistribution( python::module&, python::module& ); + void wrapTabulatedSpectrum( python::module&, python::module& ); + void wrapProbability( python::module&, python::module& ); + void wrapPartialDistribution( python::module&, python::module& ); +} + +void wrapSection_15( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 15 >; + using PartialDistribution = Section::PartialDistribution; + using PartialDistributionRange = RandomAccessAnyView< PartialDistribution >; + + // wrap components + mf15::wrapOutgoingEnergyDistribution( module, viewmodule ); + mf15::wrapTabulatedSpectrum( module, viewmodule ); + mf15::wrapProbability( module, viewmodule ); + mf15::wrapPartialDistribution( module, viewmodule ); + + // wrap views created by this section + // none of these are supposed to be created directly by the user + wrapRandomAccessAnyViewOf< PartialDistribution >( + module, + "any_view< MF15::PartialDistribution, random_access >" ); + + // create the section + python::class_< Section > section( + + module, + "Section", + "MF15 section - continuous photon energy spectra" + ); + + // wrap the section + section + .def( + + python::init< int, double, double, std::vector< PartialDistribution >&& >(), + python::arg( "mt" ), python::arg( "zaid" ), python::arg( "awr" ), + python::arg( "partials" ), + "Initialise the section\n\n" + "Arguments:\n" + " self the section\n" + " mt the MT number\n" + " zaid the ZA identifier\n" + " awr the atomic mass ratio\n" + " partials the partial distributions (at least 1)" + ) + .def_property_readonly( + + "NK", + &Section::NK, + "The number of subsections with partial distributions" + ) + .def_property_readonly( + + "number_partial_distributions", + &Section::numberPartialDistributions, + "The number of subsections with partial distributions" + ) + .def_property_readonly( + + "partial_distributions", + [] ( const Section& self ) -> PartialDistributionRange + { return self.partialDistributions(); }, + "The partial distributions defined in this section" + ); + + // add standard section definitions + addStandardSectionDefinitions< Section >( section ); +} diff --git a/python/src/section/15/OutgoingEnergyDistribution.python.cpp b/python/src/section/15/OutgoingEnergyDistribution.python.cpp new file mode 100644 index 000000000..25243bce1 --- /dev/null +++ b/python/src/section/15/OutgoingEnergyDistribution.python.cpp @@ -0,0 +1,97 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/15.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf15 { + +void wrapOutgoingEnergyDistribution( python::module& module, python::module& ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 15 >; + using Component = Section::TabulatedSpectrum::OutgoingEnergyDistribution; + + // wrap views created by this section + + // create the component + python::class_< Component > component( + + module, + "OutgoingEnergyDistribution", + "MF15 section - outgoing energy distribution for a fixed value of E" + ); + + // wrap the section + component + .def( + + python::init< double, std::vector< long >&&, std::vector< long >&&, + std::vector< double >&&, std::vector< double >&& >(), + python::arg( "incident" ), python::arg( "boundaries" ), + python::arg( "interpolants" ), python::arg( "energies" ), + python::arg( "probabilities" ), + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " incident the incident energy value\n" + " boundaries the interpolation range boundaries\n" + " interpolants the interpolation types for each range\n" + " energies the outgoing energy values\n" + " probabilities the probability values" + ) + .def_property_readonly( + + "E", + &Component::E, + "The incident energy value" + ) + .def_property_readonly( + + "incident_energy", + &Component::incidentEnergy, + "The incident energy value" + ) + .def_property_readonly( + + "EP", + [] ( const Component& self ) -> DoubleRange + { return self.EP(); }, + "The outgoing energy values" + ) + .def_property_readonly( + + "outgoing_energies", + [] ( const Component& self ) -> DoubleRange + { return self.outgoingEnergies(); }, + "The outgoing energy values" + ) + .def_property_readonly( + + "G", + [] ( const Component& self ) -> DoubleRange + { return self.G(); }, + "The distribution probabilities" + ) + .def_property_readonly( + + "probabilities", + [] ( const Component& self ) -> DoubleRange + { return self.probabilities(); }, + "The distribution probabilities" + ); + + // add standard tab1 definitions + addStandardTableDefinitions< Component >( component ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf15 diff --git a/python/src/section/15/PartialDistribution.python.cpp b/python/src/section/15/PartialDistribution.python.cpp new file mode 100644 index 000000000..9e4b4eb79 --- /dev/null +++ b/python/src/section/15/PartialDistribution.python.cpp @@ -0,0 +1,65 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/15.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf15 { + +void wrapPartialDistribution( python::module& module, python::module& ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 15 >; + using Component = Section::PartialDistribution; + using Probability = Section::Probability; + using Distribution = Section::Distribution; + + // wrap views created by this section + + // create the component + python::class_< Component > component( + + module, + "PartialDistribution", + "MF15 section - a distribution subsection of an MF15 section" + ); + + // wrap the section + component + .def( + + //! @todo pybind11 lambda move custom type workaround + python::init( [] ( Probability probability, Distribution distribution ) + { return Component( std::move( probability ), + std::move( distribution ) ); } ), + python::arg( "probability" ), python::arg( "spectrum" ), + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " probability the probability\n" + " spectrum the spectrum" + ) + .def_property_readonly( + + "probability", + &Component::probability, + "The probability" + ) + .def_property_readonly( + + "distribution", + &Component::distribution, + "The distribution" + ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf15 diff --git a/python/src/section/15/Probability.python.cpp b/python/src/section/15/Probability.python.cpp new file mode 100644 index 000000000..0d95ca315 --- /dev/null +++ b/python/src/section/15/Probability.python.cpp @@ -0,0 +1,98 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/15.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf15 { + +void wrapProbability( python::module& module, python::module& ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 15 >; + using Component = Section::Probability; + + // wrap views created by this section + + // create the component + python::class_< Component > component( + + module, + "Probability", + "MF15 section - probability for a given partial distribution" + ); + + // wrap the section + component + .def( + + python::init< long, std::vector< long >&&, std::vector< long >&&, + std::vector< double >&&, std::vector< double >&&, double >(), + python::arg( "lf" ), python::arg( "boundaries" ), + python::arg( "interpolants" ), python::arg( "energies" ), + python::arg( "probabilities" ), python::arg( "u" ) = 0.0, + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " lf the type of the underlying distribution\n" + " boundaries the interpolation range boundaries\n" + " interpolants the interpolation types for each range\n" + " energies the energy values\n" + " probabilities the probability values\n" + " u the energy limit constant U (default = 0.0)" + ) + .def_property_readonly( + + "LF", + [] ( const Component& self ) { return self.LF(); }, + "The distribution type (the LF flag)" + ) + .def_property_readonly( + + "LAW", + &Component::LAW, + "The distribution type (the LF flag)" + ) + .def_property_readonly( + + "E", + [] ( const Component& self ) -> DoubleRange + { return self.E(); }, + "The energy values" + ) + .def_property_readonly( + + "energies", + [] ( const Component& self ) -> DoubleRange + { return self.energies(); }, + "The energy values" + ) + .def_property_readonly( + + "P", + [] ( const Component& self ) -> DoubleRange + { return self.P(); }, + "The probability values" + ) + .def_property_readonly( + + "probabilities", + [] ( const Component& self ) -> DoubleRange + { return self.probabilities(); }, + "The probability values" + ); + + // add standard tab1 definitions + addStandardTableDefinitions< Component >( component ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf15 diff --git a/python/src/section/15/TabulatedSpectrum.python.cpp b/python/src/section/15/TabulatedSpectrum.python.cpp new file mode 100644 index 000000000..2c990485f --- /dev/null +++ b/python/src/section/15/TabulatedSpectrum.python.cpp @@ -0,0 +1,92 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/15.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf15 { + +void wrapTabulatedSpectrum( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 15 >; + using Component = Section::TabulatedSpectrum; + using Distribution = Section::TabulatedSpectrum::OutgoingEnergyDistribution; + using DistributionRange = RandomAccessAnyView< Distribution >; + + // wrap views created by this section + // none of these are supposed to be created directly by the user + wrapRandomAccessAnyViewOf< Distribution >( + viewmodule, + "any_view< MF15::OutgoingEnergyDistribution, random_access >" ); + + // create the component + python::class_< Component > component( + + module, + "TabulatedSpectrum", + "MF15 section - arbitrary tabulated energy distribution (LF=1)" + ); + + // wrap the section + component + .def( + + python::init< std::vector< long >&&, std::vector< long >&&, + std::vector< Distribution >&& >(), + python::arg( "boundaries" ), python::arg( "interpolants" ), + python::arg( "distributions" ), + "Initialise the scattering radius\n\n" + "Arguments:\n" + " self the component\n" + " boundaries the interpolation range boundaries\n" + " interpolants the interpolation types for each range\n" + " distributions the sequence of outgoing energy distributions" + ) + .def_property_readonly( + + "LF", + [] ( const Component& self ) { return self.LF(); }, + "The distribution type (the LF flag)" + ) + .def_property_readonly( + + "LAW", + &Component::LAW, + "The distribution type (the LF flag)" + ) + .def_property_readonly( + + "NE", + [] ( const Component& self ) { return self.NE(); }, + "The number of incident energy values" + ) + .def_property_readonly( + + "incident_energies", + [] ( const Component& self ) -> DoubleRange + { return self.incidentEnergies(); }, + "The incident energies" + ) + .def_property_readonly( + + "outgoing_distributions", + [] ( const Component& self ) -> DistributionRange + { return self.outgoingDistributions(); }, + "The outgoing energy distributions (one for each incident energy)" + ); + + // add standard tab2 definitions + addStandardInterpolationTableDefinitions< Component >( component ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf15 diff --git a/python/src/section/4.python.cpp b/python/src/section/4.python.cpp index 779b72853..dbe5ebda2 100644 --- a/python/src/section/4.python.cpp +++ b/python/src/section/4.python.cpp @@ -61,8 +61,8 @@ void wrapSection_4( python::module& module, python::module& viewmodule ) { " mt the MT number\n" " zaid the ZA identifier\n" " awr the atomic mass ratio\n" - " lct the reference frameo\n" - " distributions the distributionso" + " lct the reference frame\n" + " distributions the distributions" ) .def_property_readonly( diff --git a/python/src/section/4/Isotropic.python.cpp b/python/src/section/4/Isotropic.python.cpp index 909304d05..6528d711e 100644 --- a/python/src/section/4/Isotropic.python.cpp +++ b/python/src/section/4/Isotropic.python.cpp @@ -44,6 +44,18 @@ void wrapIsotropic( python::module& module, python::module& ) { " self the component\n" " component the component to be copied" ) + .def_property_readonly( + + "LI", + [] ( const Component& self ) { return self.LI(); }, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "isotropic_angular_distributions", + [] ( const Component& self ) { return self.isotropicAngularDistributions(); }, + "The isotropic angular distribution flag" + ) .def_property_readonly( "LTT", diff --git a/python/src/section/4/LegendreDistributions.python.cpp b/python/src/section/4/LegendreDistributions.python.cpp index 71ec5aec8..983093dfb 100644 --- a/python/src/section/4/LegendreDistributions.python.cpp +++ b/python/src/section/4/LegendreDistributions.python.cpp @@ -48,6 +48,18 @@ void wrapLegendreDistributions( python::module& module, python::module& viewmodu " interpolants the interpolation types for each range\n" " distributions the sequence of angular distributions" ) + .def_property_readonly( + + "LI", + [] ( const Component& self ) { return self.LI(); }, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "isotropic_angular_distributions", + [] ( const Component& self ) { return self.isotropicAngularDistributions(); }, + "The isotropic angular distribution flag" + ) .def_property_readonly( "LTT", diff --git a/python/src/section/4/MixedDistributions.python.cpp b/python/src/section/4/MixedDistributions.python.cpp index 1e6272cdf..6aa483aae 100644 --- a/python/src/section/4/MixedDistributions.python.cpp +++ b/python/src/section/4/MixedDistributions.python.cpp @@ -50,6 +50,18 @@ void wrapMixedDistributions( python::module& module, python::module& ) { " legendre the legendre distributions\n" " tabulated the tabulated distributions" ) + .def_property_readonly( + + "LI", + [] ( const Component& self ) { return self.LI(); }, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "isotropic_angular_distributions", + [] ( const Component& self ) { return self.isotropicAngularDistributions(); }, + "The isotropic angular distribution flag" + ) .def_property_readonly( "LTT", diff --git a/python/src/section/4/TabulatedDistributions.python.cpp b/python/src/section/4/TabulatedDistributions.python.cpp index d97f9c52f..039c32b86 100644 --- a/python/src/section/4/TabulatedDistributions.python.cpp +++ b/python/src/section/4/TabulatedDistributions.python.cpp @@ -48,6 +48,18 @@ void wrapTabulatedDistributions( python::module& module, python::module& viewmod " interpolants the interpolation types for each range\n" " distributions the sequence of angular distributions" ) + .def_property_readonly( + + "LI", + [] ( const Component& self ) { return self.LI(); }, + "The isotropic angular distribution flag" + ) + .def_property_readonly( + + "isotropic_angular_distributions", + [] ( const Component& self ) { return self.isotropicAngularDistributions(); }, + "The isotropic angular distribution flag" + ) .def_property_readonly( "LTT", diff --git a/python/src/section/8/454.python.cpp b/python/src/section/8/454.python.cpp new file mode 100644 index 000000000..217850b20 --- /dev/null +++ b/python/src/section/8/454.python.cpp @@ -0,0 +1,137 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/8/454.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +void wrapSection_8_454( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 8, 454 >; + using FissionYieldData = njoy::ENDFtk::section::FissionYieldData; + using FissionYieldDataRange = RandomAccessAnyView< FissionYieldData >; + + // create the submodule + python::module submodule = module.def_submodule( + + "MT454", + "MT454 - independent fission product yields" + ); + + // wrap components + + // wrap views created by this section + + // create the section + python::class_< Section > section( + + submodule, + "Section", + "MF8 MT454 section - independent fission product yields" + ); + + // wrap the section + section + .def( + + python::init< double, double, std::vector< FissionYieldData >&& >(), + python::arg( "zaid" ), python::arg( "awr" ), python::arg( "yields" ), + "Initialise the section with fission yield data\n\n" + "Arguments:\n" + " self the section\n" + " zaid the material ZAID value\n" + " awr the atomic weight ratio\n" + " yields the fission yield data" + ) + .def( + + python::init< double, double, + std::vector< unsigned int >&&, + std::vector< unsigned int >&&, + std::vector< std::array< double, 2 > >&& >(), + python::arg( "zaid" ), python::arg( "awr" ), + python::arg( "identifiers" ), python::arg( "states" ), + python::arg( "yields" ), + "Initialise the section with energy independent fission yields\n\n" + "Arguments:\n" + " self the section\n" + " zaid the material ZAID value\n" + " awr the atomic weight ratio\n" + " identifiers the fission product identifiers (NFP values)\n" + " states the isomeric states (NFP values)\n" + " yields the fission yield values and uncertainties\n" + " (NFP pairs)" + ) + .def( + + python::init< double, double, + std::vector< unsigned int >&&, + std::vector< unsigned int >&&, + std::vector< double >&&, + std::vector< unsigned int >&&, + std::vector< std::vector< std::array< double, 2 > > >&& >(), + python::arg( "zaid" ), python::arg( "awr" ), + python::arg( "identifiers" ), python::arg( "states" ), + python::arg( "energies" ), python::arg( "interpolants" ), + python::arg( "yields" ), + "Initialise the section with energy dependent fission yields\n\n" + "Arguments:\n" + " self the section\n" + " zaid the material ZAID value\n" + " awr the atomic weight ratio\n" + " identifiers the fission product identifiers (NFP values)\n" + " states the isomeric states (NFP values)\n" + " energies the incident neutron energies (NE values)\n" + " interpolants the interpolation types (NE-1 values)\n" + " yields the fission yield values and uncertainties\n" + " (NFP arrays of NE pairs)" + ) + .def_property_readonly( + + "LE", + &Section::LE, + "Whether or not the fission yield data is energy independent" + ) + .def_property_readonly( + + "is_energy_independent", + &Section::isEnergyIndependent, + "Whether or not the fission yield data is energy independent" + ) + .def_property_readonly( + + "NE", + &Section::NE, + "The number of incident energy values" + ) + .def_property_readonly( + + "E", + [] ( const Section& self ) -> DoubleRange + { return self.E(); }, + "The incident energy values" + ) + .def_property_readonly( + + "incident_energies", + [] ( const Section& self ) -> DoubleRange + { return self.incidentEnergies(); }, + "The incident energy values" + ) + .def_property_readonly( + + "yields", + [] ( const Section& self ) -> FissionYieldDataRange + { return self.yields(); }, + "The fission yield data, one for each incident energy" + ); + + // add standard section definitions + addStandardSectionDefinitions< Section >( section ); +} diff --git a/python/src/section/8/457/DecayModes.python.cpp b/python/src/section/8/457/DecayModes.python.cpp index d3e6c01fb..d7889b54b 100644 --- a/python/src/section/8/457/DecayModes.python.cpp +++ b/python/src/section/8/457/DecayModes.python.cpp @@ -95,7 +95,7 @@ void wrapDecayModes( python::module& module, python::module& ) { "decay_modes", [] ( const Component& self ) -> std::vector< DecayMode > - { return self.decayModes(); }, + { return ranges::to< std::vector< DecayMode > >( self.decayModes() ); }, "The decay mode information" ); diff --git a/python/src/section/8/459.python.cpp b/python/src/section/8/459.python.cpp new file mode 100644 index 000000000..dab3a583c --- /dev/null +++ b/python/src/section/8/459.python.cpp @@ -0,0 +1,137 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/8/459.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +void wrapSection_8_459( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 8, 459 >; + using FissionYieldData = njoy::ENDFtk::section::FissionYieldData; + using FissionYieldDataRange = RandomAccessAnyView< FissionYieldData >; + + // create the submodule + python::module submodule = module.def_submodule( + + "MT459", + "MT459 - cumulative fission product yields" + ); + + // wrap components + + // wrap views created by this section + + // create the section + python::class_< Section > section( + + submodule, + "Section", + "MF8 MT459 section - cumulative fission product yields" + ); + + // wrap the section + section + .def( + + python::init< double, double, std::vector< FissionYieldData >&& >(), + python::arg( "zaid" ), python::arg( "awr" ), python::arg( "yields" ), + "Initialise the section with fission yield data\n\n" + "Arguments:\n" + " self the section\n" + " zaid the material ZAID value\n" + " awr the atomic weight ratio\n" + " yields the fission yield data" + ) + .def( + + python::init< double, double, + std::vector< unsigned int >&&, + std::vector< unsigned int >&&, + std::vector< std::array< double, 2 > >&& >(), + python::arg( "zaid" ), python::arg( "awr" ), + python::arg( "identifiers" ), python::arg( "states" ), + python::arg( "yields" ), + "Initialise the section with energy cumulative fission yields\n\n" + "Arguments:\n" + " self the section\n" + " zaid the material ZAID value\n" + " awr the atomic weight ratio\n" + " identifiers the fission product identifiers (NFP values)\n" + " states the isomeric states (NFP values)\n" + " yields the fission yield values and uncertainties\n" + " (NFP pairs)" + ) + .def( + + python::init< double, double, + std::vector< unsigned int >&&, + std::vector< unsigned int >&&, + std::vector< double >&&, + std::vector< unsigned int >&&, + std::vector< std::vector< std::array< double, 2 > > >&& >(), + python::arg( "zaid" ), python::arg( "awr" ), + python::arg( "identifiers" ), python::arg( "states" ), + python::arg( "energies" ), python::arg( "interpolants" ), + python::arg( "yields" ), + "Initialise the section with energy dependent fission yields\n\n" + "Arguments:\n" + " self the section\n" + " zaid the material ZAID value\n" + " awr the atomic weight ratio\n" + " identifiers the fission product identifiers (NFP values)\n" + " states the isomeric states (NFP values)\n" + " energies the incident neutron energies (NE values)\n" + " interpolants the interpolation types (NE-1 values)\n" + " yields the fission yield values and uncertainties\n" + " (NFP arrays of NE pairs)" + ) + .def_property_readonly( + + "LE", + &Section::LE, + "Whether or not the fission yield data is energy independent" + ) + .def_property_readonly( + + "is_energy_independent", + &Section::isEnergyIndependent, + "Whether or not the fission yield data is energy independent" + ) + .def_property_readonly( + + "NE", + &Section::NE, + "The number of incident energy values" + ) + .def_property_readonly( + + "E", + [] ( const Section& self ) -> DoubleRange + { return self.E(); }, + "The incident energy values" + ) + .def_property_readonly( + + "incident_energies", + [] ( const Section& self ) -> DoubleRange + { return self.incidentEnergies(); }, + "The incident energy values" + ) + .def_property_readonly( + + "yields", + [] ( const Section& self ) -> FissionYieldDataRange + { return self.yields(); }, + "The fission yield data, one for each incident energy" + ); + + // add standard section definitions + addStandardSectionDefinitions< Section >( section ); +} diff --git a/python/src/section/8/FissionYieldData.python.cpp b/python/src/section/8/FissionYieldData.python.cpp new file mode 100644 index 000000000..74efca0f6 --- /dev/null +++ b/python/src/section/8/FissionYieldData.python.cpp @@ -0,0 +1,147 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/8/FissionYieldData.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +void wrap_8_FissionYieldData( python::module& module, python::module& viewmodule ) { + + // type aliases + using Component = njoy::ENDFtk::section::FissionYieldData; + + // wrap views of this component + // none of these are supposed to be created directly by the user + wrapRandomAccessAnyViewOf< Component >( + viewmodule, + "any_view< FissionYieldData, random_access >" ); + + // create the component + python::class_< Component > component( + + module, + "FissionYieldData", + "MF8 component - fission yield data for a specific incident energy (or \n" + " energy independent yields)" + ); + + // wrap the component + component + .def( + + python::init< std::vector< unsigned int >&&, std::vector< unsigned int >&&, + std::vector< std::array< double, 2 > >&&, + double, int >(), + python::arg( "identifiers" ), python::arg( "states" ), + python::arg( "yields" ), python::arg( "energy" ) = 0., + python::arg( "interpolation" ) = 0, + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " identifiers the fission product identifiers (ZA identifier)\n" + " states the isomeric state for each fission product\n" + " yields the fission yield values and uncertainties\n" + " energy the incident neutron energy (equal to zero for\n" + " energy independent yields)\n" + " interpolation the interpolation type (equal to zero for\n" + " energy independent yields)" + ) + .def_property_readonly( + + "LE", + &Component::LE, + "Whether or not the fission yield data is energy independent" + ) + .def_property_readonly( + + "is_energy_independent", + &Component::isEnergyIndependent, + "Whether or not the fission yield data is energy independent" + ) + .def_property_readonly( + + "I", + &Component::I, + "The interpolation type (or LE value)" + ) + .def_property_readonly( + + "interpolation_type", + &Component::interpolationType, + "The interpolation type (or LE value)" + ) + .def_property_readonly( + + "E", + &Component::E, + "The incident energy value" + ) + .def_property_readonly( + + "incident_energy", + &Component::incidentEnergy, + "The incident energy value" + ) + .def_property_readonly( + + "NFP", + &Component::NFP, + "The number of fission products" + ) + .def_property_readonly( + + "number_fission_products", + &Component::numberFissionProducts, + "The number of fission products" + ) + .def_property_readonly( + + "ZAFP", + [] ( const Component& self ) -> IntRange + { return self.ZAFP(); }, + "The fission product ZA identifiers" + ) + .def_property_readonly( + + "fission_product_identifiers", + [] ( const Component& self ) -> IntRange + { return self.fissionProductIdentifiers(); }, + "The fission product ZA identifiers" + ) + .def_property_readonly( + + "FPS", + [] ( const Component& self ) -> IntRange + { return self.FPS(); }, + "The fission product isomeric states" + ) + .def_property_readonly( + + "isomeric_states", + [] ( const Component& self ) -> IntRange + { return self.isomericStates(); }, + "The fission product isomeric states" + ) + .def_property_readonly( + + "Y", + [] ( const Component& self ) -> DoubleRange2D + { return self.Y(); }, + "The fission yield values and uncertainties" + ) + .def_property_readonly( + + "fission_yields", + [] ( const Component& self ) -> DoubleRange2D + { return self.fissionYields(); }, + "The fission yield values and uncertainties" + ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} diff --git a/python/src/section/9.python.cpp b/python/src/section/9.python.cpp new file mode 100644 index 000000000..7c2467a39 --- /dev/null +++ b/python/src/section/9.python.cpp @@ -0,0 +1,94 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/9.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf9 { + + // declarations - components + void wrapReactionProduct( python::module&, python::module& ); +} + +void wrapSection_9( python::module& module, python::module& viewmodule ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 9 >; + using ReactionProduct = Section::ReactionProduct; + using ReactionProductRange = RandomAccessAnyView< ReactionProduct >; + + // wrap components + mf9::wrapReactionProduct( module, viewmodule ); + + // wrap views created by this section + // none of these are supposed to be created directly by the user + wrapRandomAccessAnyViewOf< ReactionProduct >( + viewmodule, + "any_view< MF9::ReactionProduct, random_access >" ); + + // create the section + python::class_< Section > section( + + module, + "Section", + "MF9 section - multiplicities for radioactive nuclide production" + ); + + // wrap the section + section + .def( + + python::init< int, double, double, long, + std::vector< ReactionProduct >&& >(), + python::arg( "mt" ), python::arg( "zaid" ), python::arg( "awr" ), + python::arg( "lis" ), python::arg( "products" ), + "Initialise the section\n\n" + "Arguments:\n" + " self the section\n" + " mt the MT number\n" + " zaid the ZA identifier\n" + " awr the atomic mass ratio\n" + " lis the target's excited level\n" + " products the multiplicities for every state" + ) + .def_property_readonly( + + "LIS", + &Section::LIS, + "The excited level number of the target" + ) + .def_property_readonly( + + "excited_level", + &Section::excitedLevel, + "The excited level number of the target" + ) + .def_property_readonly( + + "NS", + &Section::NS, + "The number of excited states for the reaction product" + ) + .def_property_readonly( + + "number_reaction_products", + &Section::numberReactionProducts, + "The number of excited states for the reaction product" + ) + .def_property_readonly( + + "reaction_products", + [] ( const Section& self ) -> ReactionProductRange + { return self.reactionProducts(); }, + "The reaction product data" + ); + + // add standard section definitions + addStandardSectionDefinitions< Section >( section ); +} diff --git a/python/src/section/9/ReactionProduct.python.cpp b/python/src/section/9/ReactionProduct.python.cpp new file mode 100644 index 000000000..62a33e725 --- /dev/null +++ b/python/src/section/9/ReactionProduct.python.cpp @@ -0,0 +1,138 @@ +// system includes +#include +#include + +// local includes +#include "ENDFtk/section/9.hpp" +#include "definitions.hpp" +#include "views.hpp" + +// namespace aliases +namespace python = pybind11; + +namespace mf9 { + +void wrapReactionProduct( python::module& module, python::module& ) { + + // type aliases + using Section = njoy::ENDFtk::section::Type< 9 >; + using Component = Section::ReactionProduct; + + // wrap views created by this section + + // create the component + python::class_< Component > component( + + module, + "ReactionProduct", + "MF9 section - reaction product data: Q values and multiplicities" + ); + + // wrap the section + component + .def( + + python::init< double, double, int, int, + std::vector< long >&&, std::vector< long >&&, + std::vector< double >&&, std::vector< double >&& >(), + python::arg( "qm" ), python::arg( "qi" ), + python::arg( "izap" ), python::arg( "lfs" ), + python::arg( "boundaries" ), python::arg( "interpolants" ), + python::arg( "energies" ), python::arg( "multiplicities" ), + "Initialise the component\n\n" + "Arguments:\n" + " self the component\n" + " qm the mass difference Q value\n" + " qi the reaction Q value\n" + " izap the za identifier of the product\n" + " lfs the excited level number\n" + " boundaries the interpolation range boundaries\n" + " interpolants the interpolation types for each range\n" + " energies the energy values\n" + " multiplicities the multiplicity values" + ) + .def_property_readonly( + + "QM", + &Component::QM, + "The mass difference Q value" + ) + .def_property_readonly( + + "mass_difference_qvalue", + &Component::massDifferenceQValue, + "The mass difference Q value" + ) + .def_property_readonly( + + "QI", + &Component::QI, + "The reaction Q value" + ) + .def_property_readonly( + + "reaction_qvalue", + &Component::reactionQValue, + "The mass difference Q value" + ) + .def_property_readonly( + + "IZAP", + &Component::IZAP, + "The ZA identifier of the reaction product" + ) + .def_property_readonly( + + "product_identifier", + &Component::productIdentifier, + "The ZA identifier of the reaction product" + ) + .def_property_readonly( + + "LFS", + &Component::LFS, + "The excited level number of the product" + ) + .def_property_readonly( + + "excited_level", + &Component::excitedLevel, + "The product modifier flag" + ) + .def_property_readonly( + + "E", + [] ( const Component& self ) -> DoubleRange + { return self.E(); }, + "The incident energy values" + ) + .def_property_readonly( + + "energies", + [] ( const Component& self ) -> DoubleRange + { return self.energies(); }, + "The incident energy values" + ) + .def_property_readonly( + + "Y", + [] ( const Component& self ) -> DoubleRange + { return self.Y(); }, + "The multiplicity values" + ) + .def_property_readonly( + + "multiplicities", + [] ( const Component& self ) -> DoubleRange + { return self.multiplicities(); }, + "The multiplicity values" + ); + + // add standard tab1 definitions + addStandardTableDefinitions< Component >( component ); + + // add standard component definitions + addStandardComponentDefinitions< Component >( component ); +} + +} // namespace mf6 diff --git a/python/src/tree/File.python.cpp b/python/src/tree/File.python.cpp index f2ece773a..fc53c6da1 100644 --- a/python/src/tree/File.python.cpp +++ b/python/src/tree/File.python.cpp @@ -4,13 +4,7 @@ // local includes #include "ENDFtk/tree/Tape.hpp" -#include "ENDFtk/file/3.hpp" -#include "ENDFtk/file/4.hpp" -#include "ENDFtk/file/5.hpp" -#include "ENDFtk/file/6.hpp" -#include "ENDFtk/file/12.hpp" -#include "ENDFtk/file/13.hpp" -#include "range/v3/utility/iterator.hpp" +#include "range/v3/range/operations.hpp" #include "views.hpp" // namespace aliases @@ -32,8 +26,12 @@ void wrapTreeFile( python::module& module, python::module& viewmodule ) { using MF6 = njoy::ENDFtk::file::Type< 6 >; using MF7 = njoy::ENDFtk::file::Type< 7 >; using MF8 = njoy::ENDFtk::file::Type< 8 >; + using MF9 = njoy::ENDFtk::file::Type< 9 >; + using MF10 = njoy::ENDFtk::file::Type< 10 >; using MF12 = njoy::ENDFtk::file::Type< 12 >; using MF13 = njoy::ENDFtk::file::Type< 13 >; + using MF14 = njoy::ENDFtk::file::Type< 14 >; + using MF15 = njoy::ENDFtk::file::Type< 15 >; // wrap views created by this tree component // none of these are supposed to be created directly by the user @@ -107,7 +105,7 @@ void wrapTreeFile( python::module& module, python::module& viewmodule ) { "section_numbers", [] ( const File& self ) -> std::vector< int > - { return self.sectionNumbers(); }, + { return ranges::to< std::vector< int > >( self.sectionNumbers() ); }, "All section numbers in the file" ) .def_property_readonly( @@ -143,16 +141,25 @@ void wrapTreeFile( python::module& module, python::module& viewmodule ) { "parse", [] ( const File& self ) -> std::variant< MF1, MF2, MF3, MF4, MF5, MF6, - MF7, MF8, MF12, MF13 > { + MF7, MF8, MF9, MF10, MF12, MF13, + MF14, MF15 > { switch ( self.fileNumber() ) { + case 1 : return self.parse< 1 >(); + case 2 : return self.parse< 2 >(); case 3 : return self.parse< 3 >(); case 4 : return self.parse< 4 >(); case 5 : return self.parse< 5 >(); case 6 : return self.parse< 6 >(); + case 7 : return self.parse< 7 >(); + case 8 : return self.parse< 8 >(); + case 9 : return self.parse< 9 >(); + case 10 : return self.parse< 10 >(); case 12 : return self.parse< 12 >(); case 13 : return self.parse< 13 >(); + case 14 : return self.parse< 14 >(); + case 15 : return self.parse< 15 >(); } throw std::runtime_error( "File cannot be parsed yet" ); }, @@ -162,7 +169,7 @@ void wrapTreeFile( python::module& module, python::module& viewmodule ) { "content", [] ( const File& self ) -> std::string - { return self.buffer(); }, + { return ranges::to< std::string >( self.buffer() ); }, "The content of the file" ); } diff --git a/python/src/tree/Material.python.cpp b/python/src/tree/Material.python.cpp index f9a0a9efe..a86126b18 100644 --- a/python/src/tree/Material.python.cpp +++ b/python/src/tree/Material.python.cpp @@ -5,7 +5,7 @@ // local includes #include "ENDFtk/Material.hpp" #include "ENDFtk/tree/Tape.hpp" -#include "range/v3/utility/iterator.hpp" +#include "range/v3/range/operations.hpp" #include "views.hpp" // namespace aliases @@ -80,7 +80,7 @@ void wrapTreeMaterial( python::module& module, python::module& viewmodule ) { "file_numbers", [] ( const Material& self ) -> std::vector< int > - { return self.fileNumbers(); }, + { return ranges::to< std::vector< int > >( self.fileNumbers() ); }, "All file numbers in the material" ) .def_property_readonly( @@ -94,7 +94,7 @@ void wrapTreeMaterial( python::module& module, python::module& viewmodule ) { "content", [] ( const Material& self ) -> std::string - { return self.buffer(); }, + { return ranges::to< std::string >( self.buffer() ); }, "The content of the material" ) .def( diff --git a/python/src/tree/Section.python.cpp b/python/src/tree/Section.python.cpp index 312946af3..def0ad44a 100644 --- a/python/src/tree/Section.python.cpp +++ b/python/src/tree/Section.python.cpp @@ -4,17 +4,7 @@ // local includes #include "ENDFtk/tree/Tape.hpp" -#include "ENDFtk/section/1.hpp" -#include "ENDFtk/section/2.hpp" -#include "ENDFtk/section/3.hpp" -#include "ENDFtk/section/4.hpp" -#include "ENDFtk/section/5.hpp" -#include "ENDFtk/section/6.hpp" -#include "ENDFtk/section/7.hpp" -#include "ENDFtk/section/8.hpp" -#include "ENDFtk/section/12.hpp" -#include "ENDFtk/section/13.hpp" -#include "range/v3/utility/iterator.hpp" +#include "range/v3/range/operations.hpp" #include "views.hpp" // namespace aliases @@ -41,9 +31,15 @@ void wrapTreeSection( python::module& module, python::module& ) { using MF6MTxxx = njoy::ENDFtk::section::Type< 6 >; using MF7MT2 = njoy::ENDFtk::section::Type< 7, 2 >; using MF7MT4 = njoy::ENDFtk::section::Type< 7, 4 >; + using MF8MT454 = njoy::ENDFtk::section::Type< 8, 454 >; using MF8MT457 = njoy::ENDFtk::section::Type< 8, 457 >; + using MF8MT459 = njoy::ENDFtk::section::Type< 8, 459 >; + using MF9MTxxx = njoy::ENDFtk::section::Type< 9 >; + using MF10MTxxx = njoy::ENDFtk::section::Type< 10 >; using MF12MTxxx = njoy::ENDFtk::section::Type< 12 >; using MF13MTxxx = njoy::ENDFtk::section::Type< 13 >; + using MF14MTxxx = njoy::ENDFtk::section::Type< 14 >; + using MF15MTxxx = njoy::ENDFtk::section::Type< 15 >; // wrap views created by this component @@ -111,8 +107,10 @@ void wrapTreeSection( python::module& module, python::module& ) { MF2MT151, MF2MT152, MF3MTxxx, MF4MTxxx, MF5MTxxx, MF6MTxxx, MF7MT2, MF7MT4, - MF8MT457, - MF12MTxxx, MF13MTxxx > { + MF8MT454, MF8MT457, MF8MT459, + MF9MTxxx, MF10MTxxx, + MF12MTxxx, MF13MTxxx, + MF14MTxxx, MF15MTxxx > { int mf = self.fileNumber(); int mt = self.sectionNumber(); switch ( mf ) { @@ -169,20 +167,21 @@ void wrapTreeSection( python::module& module, python::module& ) { switch ( mt ) { + case 454 : return self.parse< 8, 454 >(); case 457 : return self.parse< 8, 457 >(); - case 454 : - case 459 : throw std::runtime_error( - "Section " + std::to_string( mt ) + " from file " + - std::to_string( mf ) + - " cannot be parsed yet" ); + case 459 : return self.parse< 8, 459 >(); default : throw std::runtime_error( "Section " + std::to_string( mt ) + " from file " + std::to_string( mf ) + " is not an official ENDF section" ); } } + case 9 : return self.parse< 9 >(); + case 10 : return self.parse< 10 >(); case 12 : return self.parse< 12 >(); case 13 : return self.parse< 13 >(); + case 14 : return self.parse< 14 >(); + case 15 : return self.parse< 15 >(); default: throw std::runtime_error( "Section from file " + std::to_string( mf ) + " cannot be parsed yet" ); @@ -194,7 +193,7 @@ void wrapTreeSection( python::module& module, python::module& ) { "content", [] ( const Section& self ) -> std::string - { return self.buffer(); }, + { return ranges::to< std::string >( self.buffer() ); }, "The content of the section" ); } diff --git a/python/src/tree/Tape.python.cpp b/python/src/tree/Tape.python.cpp index 048ab02a5..485c50597 100644 --- a/python/src/tree/Tape.python.cpp +++ b/python/src/tree/Tape.python.cpp @@ -6,6 +6,7 @@ #include "ENDFtk/tree/Tape.hpp" #include "ENDFtk/tree/makeTape.hpp" #include "ENDFtk/tree/fromFile.hpp" +#include "range/v3/range/operations.hpp" #include "views.hpp" // namespace aliases @@ -141,7 +142,7 @@ void wrapTreeTape( python::module& module, python::module& viewmodule ) { "content", [] ( const Tape& self ) -> std::string - { return self.buffer(); }, + { return ranges::to< std::string >( self.buffer() ); }, "The content of the tape" ) .def_static( diff --git a/python/src/views.hpp b/python/src/views.hpp index 1634fb418..1995c6d63 100644 --- a/python/src/views.hpp +++ b/python/src/views.hpp @@ -9,11 +9,8 @@ #include #include #include "range/v3/view/any_view.hpp" -#include "range/v3/distance.hpp" -#include "range/v3/index.hpp" -#include "range/v3/front.hpp" -#include "range/v3/utility/iterator.hpp" -#include "range/v3/to_container.hpp" +#include "range/v3/range/conversion.hpp" +#include "range/v3/range/operations.hpp" namespace python = pybind11; @@ -92,13 +89,13 @@ void wrapBasicBidirectionalAnyViewOf( python::module& module, const std::string& .def( "to_list", [] ( BasicBidirectionalAnyView< Element >& view ) -> std::vector< Element > - { return view; }, + { return ranges::to< std::vector< Element > >( view ); }, "Convert the sequence to a list (this is a deep copy for primitive\n" "types (like integer and floats) and a shallow copy for custom types" ) .def( "copy", [] ( BasicRandomAccessAnyView< Element >& view ) -> std::vector< CopyElement > - { return view; }, + { return ranges::to< std::vector< CopyElement > >( view ); }, "Copy the sequence to a list (this is a deep copy for both primitive\n" "types (like integer and floats) and custom types" ); } @@ -178,13 +175,13 @@ void wrapBasicRandomAccessAnyViewOf( python::module& module, const std::string& .def( "to_list", [] ( BasicRandomAccessAnyView< Element >& view ) -> std::vector< Element > - { return view; }, + { return ranges::to< std::vector< Element > >( view ); }, "Convert the sequence to a list (this is a deep copy for primitive\n" "types (like integer and floats) and a shallow copy for custom types" ) .def( "copy", [] ( BasicRandomAccessAnyView< Element >& view ) -> std::vector< CopyElement > - { return view; }, + { return ranges::to< std::vector< CopyElement > >( view ); }, "Copy the sequence to a list (this is a deep copy for both primitive\n" "types (like integer and floats) and custom types" ); } diff --git a/python/test/Test_ENDFtk_MF10_ReactionProduct.py b/python/test/Test_ENDFtk_MF10_ReactionProduct.py new file mode 100644 index 000000000..fcd85c954 --- /dev/null +++ b/python/test/Test_ENDFtk_MF10_ReactionProduct.py @@ -0,0 +1,96 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF10 import ReactionProduct + +class Test_ENDFtk_MF10_ReactionProduct( unittest.TestCase ) : + """Unit test for the ReactionProduct class.""" + + chunk = ( ' 2.224648+6 3.224648+6 95242 2 1 2953410102 \n' + ' 2 5 953410102 \n' + ' 1.000000+0 2.000000+0 3.000000+0 4.000000+0 953410102 \n' ) + + invalid = ( ' 2.224648+6 3.224648+6 95242 2 2 2953410102 \n' + ' 2 2 953410102 \n' + ' 1.000000-5 8.579050+0 3.000000+7 1.487778+1 953410102 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertAlmostEqual( 2.224648e+6, chunk.QM ) + self.assertAlmostEqual( 2.224648e+6, chunk.mass_difference_qvalue ) + self.assertAlmostEqual( 3.224648e+6, chunk.QI ) + self.assertAlmostEqual( 3.224648e+6, chunk.reaction_qvalue ) + self.assertEqual( 95242, chunk.IZAP ) + self.assertEqual( 95242, chunk.product_identifier ) + self.assertEqual( 2, chunk.LFS ) + self.assertEqual( 2, chunk.excited_level ) + + self.assertEqual( 2, chunk.NP ) + self.assertEqual( 1, chunk.NR ) + self.assertEqual( 1, len( chunk.interpolants ) ) + self.assertEqual( 1, len( chunk.boundaries ) ) + self.assertEqual( 5, chunk.interpolants[0] ) + self.assertEqual( 2, chunk.boundaries[0] ) + self.assertEqual( 2, len( chunk.E ) ) + self.assertEqual( 2, len( chunk.energies ) ) + self.assertEqual( 2, len( chunk.XS ) ) + self.assertEqual( 2, len( chunk.cross_sections ) ) + self.assertAlmostEqual( 1., chunk.E[0] ) + self.assertAlmostEqual( 3., chunk.E[1] ) + self.assertAlmostEqual( 1., chunk.energies[0] ) + self.assertAlmostEqual( 3., chunk.energies[1] ) + self.assertAlmostEqual( 2., chunk.XS[0] ) + self.assertAlmostEqual( 4., chunk.XS[1] ) + self.assertAlmostEqual( 2., chunk.cross_sections[0] ) + self.assertAlmostEqual( 4., chunk.cross_sections[1] ) + + self.assertEqual( 3, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9534, 10, 102 ) ) + + # the data is given explicitly + chunk = ReactionProduct( qm = 2.224648e+6, qi = 3.224648e+6, + izap = 95242, lfs = 2, + boundaries = [ 2 ], + interpolants = [ 5 ], + energies = [ 1., 3. ], + xs = [ 2., 4. ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = ReactionProduct.from_string( self.chunk, 9534, 10, 102 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = ReactionProduct( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # wrong boundaries + with self.assertRaises( Exception ) : + + chunk = ReactionProduct( qm = 2.224648e+6, qi = 3.224648e+6, + izap = 95242, lfs = 2, + boundaries = [ 2 ], interpolants = [ 5, 2 ], + energies = [ 1., 3. ], xs = [ 2., 4. ] ) + + with self.assertRaises( Exception ) : + + chunk = ReactionProduct.from_string( self.invalid, 9534, 10, 102 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF10_Section.py b/python/test/Test_ENDFtk_MF10_Section.py new file mode 100644 index 000000000..0b5bb4467 --- /dev/null +++ b/python/test/Test_ENDFtk_MF10_Section.py @@ -0,0 +1,146 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF10 import Section +from ENDFtk.MF10 import ReactionProduct +from ENDFtk.tree import Tape + +class Test_ENDFtk_MF10_Section( unittest.TestCase ) : + """Unit test for the Section class.""" + + chunk = ( ' 9.524100+4 2.389860+2 0 0 2 0954310102 \n' + ' 5.537755+6 5.537755+6 95242 0 1 2954310102 \n' + ' 2 3 954310102 \n' + ' 1.000000-5 9.000000-1 3.000000+7 5.200000-1 954310102 \n' + ' 5.537755+6 5.489125+6 95242 2 1 2954310102 \n' + ' 2 3 954310102 \n' + ' 1.000000-5 1.000000-1 3.000000+7 4.800000-1 954310102 \n' ) + + valid_TPID = 'Just a tape identifier \n' + valid_SEND = ' 954310 0 \n' + valid_FEND = ' 9543 0 0 \n' + valid_MEND = ' 0 0 0 \n' + valid_TEND = ' -1 0 0 \n' + invalid_SEND = ' 954310 1 \n' + + def test_section( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( 102, chunk.MT ) + self.assertEqual( 95241, chunk.ZA ) + self.assertAlmostEqual( 2.389860e+2, chunk.AWR ) + self.assertAlmostEqual( 2.389860e+2, chunk.atomic_weight_ratio ) + self.assertEqual( 0, chunk.LIS ) + self.assertEqual( 0, chunk.excited_level ) + self.assertEqual( 2, chunk.NS ) + self.assertEqual( 2, chunk.number_reaction_products ) + + self.assertEqual( 2, len( chunk.reaction_products ) ) + + product = chunk.reaction_products[0] + self.assertAlmostEqual( 5.537755e+6, product.QM ) + self.assertAlmostEqual( 5.537755e+6, product.mass_difference_qvalue ) + self.assertAlmostEqual( 5.537755e+6, product.QI ) + self.assertAlmostEqual( 5.537755e+6, product.reaction_qvalue ) + self.assertEqual( 95242, product.IZAP ) + self.assertEqual( 95242, product.product_identifier ) + self.assertEqual( 0, product.LFS ) + self.assertEqual( 0, product.excited_level ) + self.assertEqual( 2, product.NP ) + self.assertEqual( 1, product.NR ) + self.assertEqual( 1, len( product.interpolants ) ) + self.assertEqual( 1, len( product.boundaries ) ) + self.assertEqual( 3, product.interpolants[0] ) + self.assertEqual( 2, product.boundaries[0] ) + self.assertEqual( 2, len( product.E ) ) + self.assertEqual( 2, len( product.energies ) ) + self.assertEqual( 2, len( product.XS ) ) + self.assertEqual( 2, len( product.cross_sections ) ) + self.assertAlmostEqual( 1e-5, product.E[0] ) + self.assertAlmostEqual( 3e+7, product.E[1] ) + self.assertAlmostEqual( 1e-5, product.energies[0] ) + self.assertAlmostEqual( 3e+7, product.energies[1] ) + self.assertAlmostEqual( 0.9, product.XS[0] ) + self.assertAlmostEqual( 0.52, product.XS[1] ) + self.assertAlmostEqual( 0.9, product.cross_sections[0] ) + self.assertAlmostEqual( 0.52, product.cross_sections[1] ) + + product = chunk.reaction_products[1] + self.assertAlmostEqual( 5.537755e+6, product.QM ) + self.assertAlmostEqual( 5.537755e+6, product.mass_difference_qvalue ) + self.assertAlmostEqual( 5.489125e+6, product.QI ) + self.assertAlmostEqual( 5.489125e+6, product.reaction_qvalue ) + self.assertEqual( 95242, product.IZAP ) + self.assertEqual( 95242, product.product_identifier ) + self.assertEqual( 2, product.LFS ) + self.assertEqual( 2, product.excited_level ) + self.assertEqual( 2, product.NP ) + self.assertEqual( 1, product.NR ) + self.assertEqual( 1, len( product.interpolants ) ) + self.assertEqual( 1, len( product.boundaries ) ) + self.assertEqual( 3, product.interpolants[0] ) + self.assertEqual( 2, product.boundaries[0] ) + self.assertEqual( 2, len( product.E ) ) + self.assertEqual( 2, len( product.energies ) ) + self.assertEqual( 2, len( product.XS ) ) + self.assertEqual( 2, len( product.cross_sections ) ) + self.assertAlmostEqual( 1e-5, product.E[0] ) + self.assertAlmostEqual( 3e+7, product.E[1] ) + self.assertAlmostEqual( 1e-5, product.energies[0] ) + self.assertAlmostEqual( 3e+7, product.energies[1] ) + self.assertAlmostEqual( 0.1, product.XS[0] ) + self.assertAlmostEqual( 0.48, product.XS[1] ) + self.assertAlmostEqual( 0.1, product.cross_sections[0] ) + self.assertAlmostEqual( 0.48, product.cross_sections[1] ) + + self.assertEqual( 7, chunk.NC ) + + # verify string + self.assertEqual( self.chunk + self.valid_SEND, + chunk.to_string( 9543, 10 ) ) + + # the data is given explicitly + chunk = Section( mt = 102, zaid = 95241, lis = 0, awr = 2.389860e+2, + products = + [ ReactionProduct( 5.537755e+6, 5.537755e+6, 95242, 0, + [ 2 ], [ 3 ], [ 1e-5, 3e+7 ], [ 0.9, 0.52 ] ), + ReactionProduct( 5.537755e+6, 5.489125e+6, 95242, 2, + [ 2 ], [ 3 ], [ 1e-5, 3e+7 ], [ 0.1, 0.48 ] ) ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk + self.valid_SEND ) + + verify_chunk( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9543 ).file( 10 ).section( 102 ).parse() + + verify_chunk( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # illegal SEND + with self.assertRaises( Exception ) : + + chunk = Section.from_string( self.chunk + self.invalid_SEND ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF12_Multiplicities.py b/python/test/Test_ENDFtk_MF12_Multiplicities.py index 53bbf58c7..70ec9e077 100644 --- a/python/test/Test_ENDFtk_MF12_Multiplicities.py +++ b/python/test/Test_ENDFtk_MF12_Multiplicities.py @@ -35,14 +35,14 @@ def verify_chunk_partial( self, chunk ) : # verify content self.assertEqual( None, chunk.total_multiplicity ) - self.assertEqual( 1, len( chunk.partial_multiplicities ) ) + self.assertEqual( 1, len( chunk.photon_partial_multiplicities ) ) self.assertEqual( 1, chunk.NK ) - self.assertEqual( 1, chunk.number_partials ) + self.assertEqual( 1, chunk.number_photons ) self.assertEqual( 1, chunk.LO ) self.assertEqual( 1, chunk.representation ) - partial = chunk.partial_multiplicities[0] + partial = chunk.photon_partial_multiplicities[0] self.assertAlmostEqual( 0.0, partial.EG ) self.assertAlmostEqual( 0.0, partial.photon_or_binding_energy ) self.assertAlmostEqual( 0.0, partial.ES ) @@ -72,9 +72,9 @@ def verify_chunk_partial( self, chunk ) : def verify_chunk_partials( self, chunk ) : # verify content - self.assertEqual( 2, len( chunk.partial_multiplicities ) ) + self.assertEqual( 2, len( chunk.photon_partial_multiplicities ) ) self.assertEqual( 2, chunk.NK ) - self.assertEqual( 2, chunk.number_partials ) + self.assertEqual( 2, chunk.number_photons ) self.assertEqual( 1, chunk.LO ) self.assertEqual( 1, chunk.representation ) @@ -94,7 +94,7 @@ def verify_chunk_partials( self, chunk ) : self.assertEqual( 9, chunk.NC ) self.assertEqual( 3, chunk.total_multiplicity.NC ) - partial = chunk.partial_multiplicities[0] + partial = chunk.photon_partial_multiplicities[0] self.assertAlmostEqual( 0.0, partial.EG ) self.assertAlmostEqual( 0.0, partial.photon_or_binding_energy ) self.assertAlmostEqual( 0.0, partial.ES ) @@ -116,7 +116,7 @@ def verify_chunk_partials( self, chunk ) : self.assertAlmostEqual( 8.579050e+0, partial.multiplicities[0] ) self.assertAlmostEqual( 1.487778e+1, partial.multiplicities[1] ) - partial = chunk.partial_multiplicities[1] + partial = chunk.photon_partial_multiplicities[1] self.assertAlmostEqual( 0.0, partial.EG ) self.assertAlmostEqual( 0.0, partial.photon_or_binding_energy ) self.assertAlmostEqual( 0.0, partial.ES ) diff --git a/python/test/Test_ENDFtk_MF12_Section.py b/python/test/Test_ENDFtk_MF12_Section.py index 0ccab6ac9..7787a83b2 100644 --- a/python/test/Test_ENDFtk_MF12_Section.py +++ b/python/test/Test_ENDFtk_MF12_Section.py @@ -51,14 +51,14 @@ def verify_chunk_lo1( self, chunk ) : self.assertEqual( True, isinstance( data, Multiplicities ) ) self.assertEqual( None, data.total_multiplicity ) - self.assertEqual( 1, len( data.partial_multiplicities ) ) + self.assertEqual( 1, len( data.photon_partial_multiplicities ) ) self.assertEqual( 1, data.NK ) - self.assertEqual( 1, data.number_partials ) + self.assertEqual( 1, data.number_photons ) self.assertEqual( 1, data.LO ) self.assertEqual( 1, data.representation ) - partial = data.partial_multiplicities[0]; + partial = data.photon_partial_multiplicities[0]; self.assertAlmostEqual( 0.0, partial.EG ) self.assertAlmostEqual( 0.0, partial.photon_or_binding_energy ) self.assertAlmostEqual( 0.0, partial.ES ) diff --git a/python/test/Test_ENDFtk_MF13_Section.py b/python/test/Test_ENDFtk_MF13_Section.py index cc31bcbcc..3e9e81b68 100644 --- a/python/test/Test_ENDFtk_MF13_Section.py +++ b/python/test/Test_ENDFtk_MF13_Section.py @@ -36,12 +36,12 @@ def verify_chunk( self, chunk ) : self.assertAlmostEqual( 2.330250e+2, chunk.atomic_weight_ratio ) self.assertEqual( None, chunk.total_cross_section ) - self.assertEqual( 1, len( chunk.partial_cross_sections ) ) + self.assertEqual( 1, len( chunk.photon_partial_cross_sections ) ) self.assertEqual( 1, chunk.NK ) - self.assertEqual( 1, chunk.number_partials ) + self.assertEqual( 1, chunk.number_photons ) - partial = chunk.partial_cross_sections[0] + partial = chunk.photon_partial_cross_sections[0] self.assertAlmostEqual( 0.0, partial.EG ) self.assertAlmostEqual( 0.0, partial.photon_or_binding_energy ) self.assertAlmostEqual( 0.0, partial.ES ) diff --git a/python/test/Test_ENDFtk_MF14_IsotropicDiscretePhoton.py b/python/test/Test_ENDFtk_MF14_IsotropicDiscretePhoton.py new file mode 100644 index 000000000..782dc4658 --- /dev/null +++ b/python/test/Test_ENDFtk_MF14_IsotropicDiscretePhoton.py @@ -0,0 +1,46 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF14 import IsotropicDiscretePhoton + +class Test_ENDFtk_MF14_IsotropicDiscretePhoton( unittest.TestCase ) : + """Unit test for the IsotropicDiscretePhoton class.""" + + chunk = ' 1.000000+0 2.000000+0 0 0 0 0262514 2 \n' + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertAlmostEqual( 1., chunk.EG ) + self.assertAlmostEqual( 1., chunk.photon_energy ) + self.assertAlmostEqual( 2., chunk.ES ) + self.assertAlmostEqual( 2., chunk.level_energy ) + + self.assertEqual( 1, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 2625, 14, 2 ) ) + + # the data is given explicitly + chunk = IsotropicDiscretePhoton( energy = 1., level = 2. ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = IsotropicDiscretePhoton.from_string( self.chunk, 2625, 14, 2 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = IsotropicDiscretePhoton( chunk ) + + verify_chunk( self, copy ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF14_LegendreCoefficients.py b/python/test/Test_ENDFtk_MF14_LegendreCoefficients.py new file mode 100644 index 000000000..a582c7738 --- /dev/null +++ b/python/test/Test_ENDFtk_MF14_LegendreCoefficients.py @@ -0,0 +1,68 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF14 import LegendreCoefficients + +class Test_ENDFtk_MF14_LegendreCoefficients( unittest.TestCase ) : + """Unit test for the LegendreCoefficients class.""" + + chunk = ( ' 0.000000+0 1.000000-5 0 0 3 0922814 2 \n' + ' 7.392510-5 8.477139-9 1.17106-13 922814 2 \n' ) + + invalid = ( ' 0.000000+0 1.000000-5 0 0 2 0922814 2 \n' + ' 7.392510-5 8.477139-9 1.17106-13 922814 2 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertAlmostEqual( 1e-5, chunk.E ) + self.assertAlmostEqual( 1e-5, chunk.incident_energy ) + self.assertEqual( 3, chunk.NL ) + self.assertEqual( 3, chunk.legendre_order ) + self.assertEqual( 3, len( chunk.A ) ) + self.assertEqual( 3, len( chunk.coefficients ) ) + self.assertAlmostEqual( 7.392510e-5 , chunk.A[0] ) + self.assertAlmostEqual( 8.477139e-9, chunk.A[1] ) + self.assertAlmostEqual( 1.17106e-13, chunk.A[2] ) + self.assertAlmostEqual( 7.392510e-5 , chunk.coefficients[0] ) + self.assertAlmostEqual( 8.477139e-9, chunk.coefficients[1] ) + self.assertAlmostEqual( 1.17106e-13, chunk.coefficients[2] ) + + self.assertEqual( 2, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9228, 14, 2 ) ) + + # the data is given explicitly + chunk = LegendreCoefficients( energy = 1e-5, + coefficients = [ 7.392510e-5, 8.477139e-9, + 1.17106e-13 ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = LegendreCoefficients.from_string( self.chunk, 9228, 14, 2 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = LegendreCoefficients( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + with self.assertRaises( Exception ) : + + chunk = LegendreCoefficients.from_string( self.invalid, 9228, 14, 2 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF14_LegendreDistributions.py b/python/test/Test_ENDFtk_MF14_LegendreDistributions.py new file mode 100644 index 000000000..9cada6689 --- /dev/null +++ b/python/test/Test_ENDFtk_MF14_LegendreDistributions.py @@ -0,0 +1,133 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF14 import LegendreCoefficients +from ENDFtk.MF14 import LegendreDistributions + +class Test_ENDFtk_MF14_LegendreDistributions( unittest.TestCase ) : + """Unit test for the LegendreDistributions class.""" + + chunk = ( ' 1.000000+0 2.000000+0 0 0 1 2922814 2 \n' + ' 2 1 922814 2 \n' + ' 0.000000+0 1.000000-5 0 0 3 0922814 2 \n' + ' 7.392510-5 8.477139-9 1.17106-13 922814 2 \n' + ' 0.000000+0 2.000000+7 0 0 2 0922814 2 \n' + ' 2.874390-2 3.19645-11 922814 2 \n' ) + + invalid = ( ' 1.000000+0 2.000000+0 0 0 3 2922814 2 \n' + ' 2 1 922814 2 \n' + ' 0.000000+0 1.000000-5 0 0 3 0922814 2 \n' + ' 7.392510-5 8.477139-9 1.17106-13 922814 2 \n' + ' 0.000000+0 2.000000+7 0 0 2 0922814 2 \n' + ' 2.874390-2 3.19645-11 922814 2 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( False, chunk.LI ) + self.assertEqual( False, chunk.isotropic_angular_distributions ) + self.assertEqual( 1, chunk.LTT ) + self.assertEqual( 1, chunk.LAW ) + + self.assertAlmostEqual( 1., chunk.EG ) + self.assertAlmostEqual( 1., chunk.photon_energy ) + self.assertAlmostEqual( 2., chunk.ES ) + self.assertAlmostEqual( 2., chunk.level_energy ) + + self.assertEqual( 2, chunk.NE ) + self.assertEqual( 1, chunk.NR ) + self.assertEqual( 1, len( chunk.interpolants ) ) + self.assertEqual( 1, len( chunk.boundaries ) ) + self.assertEqual( 1, chunk.interpolants[0] ); + self.assertEqual( 2, chunk.boundaries[0] ); + + self.assertEqual( 2, len( chunk.incident_energies ) ) + self.assertEqual( 2, len( chunk.angular_distributions ) ) + + self.assertAlmostEqual( 1e-5, chunk.incident_energies[0] ) + self.assertAlmostEqual( 2e+7, chunk.incident_energies[1] ) + + distributions = chunk.angular_distributions + + d = distributions[0]; + self.assertAlmostEqual( 1e-5, d.E ) + self.assertAlmostEqual( 1e-5, d.incident_energy ) + self.assertEqual( 3, d.NL ) + self.assertEqual( 3, d.legendre_order ) + self.assertEqual( 3, len( d.coefficients ) ) + self.assertAlmostEqual( 7.392510e-5 , d.coefficients[0] ) + self.assertAlmostEqual( 8.477139e-9, d.coefficients[1] ) + self.assertAlmostEqual( 1.17106e-13, d.coefficients[2] ) + + d = distributions[1]; + self.assertAlmostEqual( 2e+7, d.E ) + self.assertAlmostEqual( 2e+7, d.incident_energy ) + self.assertEqual( 2, d.NL ) + self.assertEqual( 2, d.legendre_order ) + self.assertEqual( 2, len( d.coefficients ) ) + self.assertAlmostEqual( 2.874390e-2 , d.coefficients[0] ) + self.assertAlmostEqual( 3.19645e-11, d.coefficients[1] ) + + self.assertEqual( 6, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9228, 14, 2 ) ) + + # the data is given explicitly + chunk = LegendreDistributions( + energy = 1.0, level = 2.0, + boundaries = [ 2 ], interpolants = [ 1 ], + distributions = [ LegendreCoefficients( 1e-5, [ 7.392510e-5, 8.477139e-9, 1.17106e-13 ] ), + LegendreCoefficients( 2e+7, [ 2.874390e-2, 3.19645e-11 ] ) ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = LegendreDistributions.from_string( self.chunk, 9228, 14, 2 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = LegendreDistributions( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + with self.assertRaises( Exception ) : + + chunk = LegendreDistributions( + energy = 1.0, level = 2.0, + boundaries = [ 2, 4 ], interpolants = [ 1 ], + distributions = [ LegendreCoefficients( 1e-5, [ 7.392510e-5, 8.477139e-9, 1.17106e-13 ] ), + LegendreCoefficients( 2e+7, [ 2.874390e-2, 3.19645e-11 ] ) ] ) + + with self.assertRaises( Exception ) : + + chunk = LegendreDistributions( + energy = 1.0, level = 2.0, + boundaries = [ 2 ], interpolants = [ 1, 2 ], + distributions = [ LegendreCoefficients( 1e-5, [ 7.392510e-5, 8.477139e-9, 1.17106e-13 ] ), + LegendreCoefficients( 2e+7, [ 2.874390e-2, 3.19645e-11 ] ) ] ) + + with self.assertRaises( Exception ) : + + chunk = LegendreDistributions( + energy = 1.0, level = 2.0, + boundaries = [ 2 ], interpolants = [ 1 ], + distributions = [ LegendreCoefficients( 1e-5, [ 7.392510e-5, 8.477139e-9, 1.17106e-13 ] ) ] ) + + with self.assertRaises( Exception ) : + + chunk = LegendreDistributions.from_string( self.invalid, 9228, 14, 2 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF14_Section.py b/python/test/Test_ENDFtk_MF14_Section.py new file mode 100644 index 000000000..5351eb968 --- /dev/null +++ b/python/test/Test_ENDFtk_MF14_Section.py @@ -0,0 +1,214 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF14 import LegendreCoefficients +from ENDFtk.MF14 import TabulatedDistribution +from ENDFtk.MF14 import LegendreDistributions +from ENDFtk.MF14 import TabulatedDistributions +from ENDFtk.MF14 import Section +from ENDFtk.tree import Tape + +class Test_ENDFtk_MF14_Section( unittest.TestCase ) : + """Unit test for the Section class.""" + + chunk_LTT0 = ( ' 9.223500+4 2.330248+2 1 0 0 0922814 2 \n' ) + + chunk_LTT1 = ( ' 9.223500+4 2.330248+2 0 1 1 0922814 2 \n' + ' 4.438900+6 4.438900+6 0 0 1 2922814 2 \n' + ' 2 3 922814 2 \n' + ' 0.000000+0 4.812998+6 0 0 2 0922814 2 \n' + ' 0.000000+0 4.076000-2 922814 2 \n' + ' 0.000000+0 1.500000+8 0 0 2 0922814 2 \n' + ' 0.000000+0 0.000000+0 922814 2 \n' ) + + invalid = ( ' 9.223500+4 2.330250+2 0 4 1 0922814 2 \n' ) + + valid_TPID = 'Just a tape identifier \n' + valid_SEND = ' 922814 0 \n' + valid_FEND = ' 9228 0 0 \n' + valid_MEND = ' 0 0 0 \n' + valid_TEND = ' -1 0 0 \n' + invalid_SEND = ' 9228 3 1 \n' + + def test_section( self ) : + + def verify_chunk_LTT0( self, chunk ) : + + # verify content + self.assertEqual( 2, chunk.MT ) + self.assertEqual( 2, chunk.section_number ) + + self.assertAlmostEqual( 92235., chunk.ZA ) + self.assertAlmostEqual( 2.330248e+2, chunk.AWR ) + self.assertAlmostEqual( 2.330248e+2, chunk.atomic_weight_ratio ) + + self.assertEqual( 0, chunk.NI ) + self.assertEqual( 0, chunk.number_isotropic_photons ) + self.assertEqual( 0, chunk.NK ) + self.assertEqual( 0, chunk.number_photons ) + + self.assertEqual( 0, chunk.LTT ) + self.assertEqual( 0, chunk.LAW ) + self.assertEqual( True, chunk.LI ) + self.assertEqual( True, chunk.isotropic_angular_distributions ) + + self.assertEqual( 0, len( chunk.photon_angular_distributions ) ) + + self.assertEqual( 1, chunk.NC ) + + # verify string + self.assertEqual( self.chunk_LTT0 + self.valid_SEND, + chunk.to_string( 9228, 14 ) ) + + def verify_chunk_LTT1( self, chunk ) : + + # verify content + self.assertEqual( 2, chunk.MT ) + self.assertEqual( 2, chunk.section_number ) + + self.assertAlmostEqual( 92235., chunk.ZA ) + self.assertAlmostEqual( 2.330248e+2, chunk.AWR ) + self.assertAlmostEqual( 2.330248e+2, chunk.atomic_weight_ratio ) + + self.assertEqual( 0, chunk.NI ) + self.assertEqual( 0, chunk.number_isotropic_photons ) + self.assertEqual( 1, chunk.NK ) + self.assertEqual( 1, chunk.number_photons ) + + self.assertEqual( 1, chunk.LTT ) + self.assertEqual( 1, chunk.LAW ) + self.assertEqual( False, chunk.LI ) + self.assertEqual( False, chunk.isotropic_angular_distributions ) + + self.assertEqual( 1, len( chunk.photon_angular_distributions ) ) + + photon = chunk.photon_angular_distributions[0] + self.assertEqual( True, isinstance( photon, LegendreDistributions ) ) + + self.assertEqual( False, photon.LI ) + self.assertEqual( False, photon.isotropic_angular_distributions ) + self.assertEqual( 1, photon.LTT ) + self.assertEqual( 1, photon.LAW ) + + self.assertEqual( 4.438900e+6, photon.EG ) + self.assertEqual( 4.438900e+6, photon.photon_energy ) + self.assertEqual( 4.438900e+6, photon.ES ) + self.assertEqual( 4.438900e+6, photon.level_energy ) + + self.assertEqual( 2, photon.NE ) + self.assertEqual( 1, photon.NR ) + self.assertEqual( 1, len( photon.interpolants ) ) + self.assertEqual( 1, len( photon.boundaries ) ) + self.assertEqual( 3, photon.interpolants[0] ) + self.assertEqual( 2, photon.boundaries[0] ) + + self.assertEqual( 2, len( photon.incident_energies ) ) + self.assertEqual( 2, len( photon.angular_distributions ) ) + + self.assertEqual( 4.812998e+6, photon.incident_energies[0] ) + self.assertEqual( 15e+7, photon.incident_energies[1] ) + + distributions = photon.angular_distributions + + d = distributions[0] + self.assertEqual( 4.812998e+6, d.E ) + self.assertEqual( 4.812998e+6, d.incident_energy ) + self.assertEqual( 2, d.NL ) + self.assertEqual( 2, d.legendre_order ) + self.assertEqual( 2, len( d.coefficients ) ) + self.assertEqual( 0. , d.coefficients[0] ) + self.assertEqual( 4.076000e-2, d.coefficients[1] ) + + d = distributions[1] + self.assertEqual( 15e+7, d.E ) + self.assertEqual( 15e+7, d.incident_energy ) + self.assertEqual( 2, d.NL ) + self.assertEqual( 2, d.legendre_order ) + self.assertEqual( 2, len( d.coefficients ) ) + self.assertEqual( 0., d.coefficients[0] ) + self.assertEqual( 0., d.coefficients[1] ) + + self.assertEqual( 7, chunk.NC ) + + # verify string + self.assertEqual( self.chunk_LTT1 + self.valid_SEND, + chunk.to_string( 9228, 14 ) ) + + # the data is given explicitly for LTT=0 + chunk = Section( mt = 2, zaid = 92235., awr = 2.330248e+2 ) + + verify_chunk_LTT0( self, chunk ) + + # the data is read from a string for LTT=0 + chunk = Section.from_string( self.chunk_LTT0 + self.valid_SEND ) + + verify_chunk_LTT0( self, chunk ) + + # the data is retrieved from a tree element and parsed for LTT=0 + tape = Tape.from_string( self.valid_TPID + self.chunk_LTT0 + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 14 ).section( 2 ).parse() + + verify_chunk_LTT0( self, chunk ) + + # the data is copied for LTT=0 + copy = Section( chunk ) + + verify_chunk_LTT0( self, copy ) + + # the data is given explicitly for LTT=1 + distributions = [ LegendreDistributions( + energy = 4.438900e+6, level = 4.438900e+6, + boundaries = [ 2 ], interpolants = [ 3 ], + distributions = [ LegendreCoefficients( 4.812998e+6, [ 0., 0.04076 ] ), + LegendreCoefficients( 15e+7, [ 0., 0. ] ) ] ) ] + + chunk = Section( mt = 2, zaid = 92235., awr = 2.330248e+2, + photons = distributions ) + + verify_chunk_LTT1( self, chunk ) + + # the data is read from a string for LTT=1 + chunk = Section.from_string( self.chunk_LTT1 + self.valid_SEND ) + + verify_chunk_LTT1( self, chunk ) + + # the data is retrieved from a tree element and parsed for LTT=1 + tape = Tape.from_string( self.valid_TPID + self.chunk_LTT1 + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 14 ).section( 2 ).parse() + + verify_chunk_LTT1( self, chunk ) + + # the data is copied for LTT=1 + copy = Section( chunk ) + + verify_chunk_LTT1( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # illegal SEND for LTT=0 + with self.assertRaises( Exception ) : + + chunk = Section.from_string( self.chunk_LTT0 + self.invalid_SEND ) + + # illegal SEND for LTT=1 + with self.assertRaises( Exception ) : + + chunk = Section.from_string( self.chunk_LTT1 + self.invalid_SEND ) + + # illegal LTT + with self.assertRaises( Exception ) : + + chunk = Section.from_string( self.invalid + self.valid_SEND ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF14_TabulatedDistribution.py b/python/test/Test_ENDFtk_MF14_TabulatedDistribution.py new file mode 100644 index 000000000..e71773854 --- /dev/null +++ b/python/test/Test_ENDFtk_MF14_TabulatedDistribution.py @@ -0,0 +1,88 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF14 import TabulatedDistribution + +class Test_ENDFtk_MF4_TabulatedDistribution( unittest.TestCase ) : + """Unit test for the TabulatedDistribution class.""" + + chunk = ( ' 0.000000+0 1.000000-5 0 0 1 3922814 2 \n' + ' 3 2 922814 2 \n' + '-1.000000+0 0.000000+0 0.000000+0 1.000000+0 1.000000+0 0.000000+0922814 2 \n' ) + + invalid = ( ' 0.000000+0 1.000000-5 0 0 2 3922814 2 \n' + ' 3 2 922814 2 \n' + '-1.000000+0 0.000000+0 0.000000+0 1.000000+0 1.000000+0 0.000000+0922814 2 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertAlmostEqual( 1e-5, chunk.E ) + self.assertAlmostEqual( 1e-5, chunk.incident_energy ) + self.assertEqual( 3, chunk.NP ) + self.assertEqual( 1, chunk.NR ) + self.assertEqual( 1, len( chunk.boundaries ) ) + self.assertEqual( 1, len( chunk.interpolants ) ) + self.assertEqual( 3, chunk.boundaries[0] ) + self.assertEqual( 2, chunk.interpolants[0] ) + self.assertEqual( 3, len( chunk.cosines ) ) + self.assertAlmostEqual( -1.0 , chunk.MU[0] ) + self.assertAlmostEqual( 0.0, chunk.MU[1] ) + self.assertAlmostEqual( 1.0, chunk.MU[2] ) + self.assertAlmostEqual( -1.0 , chunk.cosines[0] ) + self.assertAlmostEqual( 0.0, chunk.cosines[1] ) + self.assertAlmostEqual( 1.0, chunk.cosines[2] ) + self.assertEqual( 3, len( chunk.probabilities ) ) + self.assertAlmostEqual( 0.0 , chunk.F[0] ) + self.assertAlmostEqual( 1.0, chunk.F[1] ) + self.assertAlmostEqual( 0.0, chunk.F[2] ) + self.assertAlmostEqual( 0.0 , chunk.probabilities[0] ) + self.assertAlmostEqual( 1.0, chunk.probabilities[1] ) + self.assertAlmostEqual( 0.0, chunk.probabilities[2] ) + + self.assertEqual( 3, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9228, 14, 2 ) ) + + # the data is given explicitly + chunk = TabulatedDistribution( energy = 1e-5, + boundaries = [ 3 ], interpolants = [ 2 ], + cosines = [ -1.0, 0.0, 1.0 ], probabilities = [ 0.0, 1.0, 0.0 ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = TabulatedDistribution.from_string( self.chunk, 9228, 14, 2 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = TabulatedDistribution( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # wrong boundaries + with self.assertRaises( Exception ) : + + chunk = TabulatedDistribution( + energy = 1e-5, + boundaries = [ 4 ], interpolants = [ 2 ], + cosines = [ -1.0, 0.0, 1.0 ], probabilities = [ 0.0, 1.0, 0.0 ] ) + + with self.assertRaises( Exception ) : + + chunk = TabulatedDistribution.from_string( self.invalid, 9228, 14, 2 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF14_TabulatedDistributions.py b/python/test/Test_ENDFtk_MF14_TabulatedDistributions.py new file mode 100644 index 000000000..5ed52e5e8 --- /dev/null +++ b/python/test/Test_ENDFtk_MF14_TabulatedDistributions.py @@ -0,0 +1,152 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF14 import TabulatedDistribution +from ENDFtk.MF14 import TabulatedDistributions + +class Test_ENDFtk_MF14_TabulatedDistributions( unittest.TestCase ) : + """Unit test for the TabulatedDistributions class.""" + + chunk = ( ' 1.000000+0 2.000000+0 0 0 1 2922814 2 \n' + ' 2 1 922814 2 \n' + ' 0.000000+0 1.000000-5 0 0 1 2922814 2 \n' + ' 2 2 922814 2 \n' + '-1.000000+0 5.000000-1 1.000000+0 5.000000-1 922814 2 \n' + ' 0.000000+0 2.000000+7 0 0 1 3922814 2 \n' + ' 3 2 922814 2 \n' + '-1.000000+0 0.000000+0 0.000000+0 1.000000+0 1.000000+0 0.000000+0922814 2 \n' ) + + invalid = ( ' 1.000000+0 2.000000+0 0 0 2 2922814 2 \n' + ' 2 1 922814 2 \n' + ' 0.000000+0 1.000000-5 0 0 1 2922814 2 \n' + ' 2 2 922814 2 \n' + '-1.000000+0 5.000000-1 1.000000+0 5.000000-1 922814 2 \n' + ' 0.000000+0 2.000000+7 0 0 1 3922814 2 \n' + ' 3 2 922814 2 \n' + '-1.000000+0 0.000000+0 0.000000+0 1.000000+0 1.000000+0 0.000000+0922814 2 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( False, chunk.LI ) + self.assertEqual( False, chunk.isotropic_angular_distributions ) + self.assertEqual( 2, chunk.LTT ) + self.assertEqual( 2, chunk.LAW ) + + self.assertAlmostEqual( 1., chunk.EG ) + self.assertAlmostEqual( 1., chunk.photon_energy ) + self.assertAlmostEqual( 2., chunk.ES ) + self.assertAlmostEqual( 2., chunk.level_energy ) + + self.assertEqual( 2, chunk.NE ) + self.assertEqual( 1, chunk.NR ) + self.assertEqual( 1, len( chunk.interpolants ) ) + self.assertEqual( 1, len( chunk.boundaries ) ) + self.assertEqual( 1, chunk.interpolants[0] ) + self.assertEqual( 2, chunk.boundaries[0] ) + + self.assertEqual( 2, len( chunk.incident_energies ) ) + self.assertEqual( 2, len( chunk.angular_distributions ) ) + + self.assertAlmostEqual( 1e-5, chunk.incident_energies[0] ) + self.assertAlmostEqual( 2e+7, chunk.incident_energies[1] ) + + distributions = chunk.angular_distributions + + d = distributions[0] + self.assertAlmostEqual( 1e-5, d.E ) + self.assertAlmostEqual( 1e-5, d.incident_energy ) + self.assertEqual( 2, d.NP ) + self.assertEqual( 1, d.NR ) + self.assertEqual( 1, len( d.boundaries ) ) + self.assertEqual( 1, len( d.interpolants ) ) + self.assertEqual( 2, d.boundaries[0] ) + self.assertEqual( 2, d.interpolants[0] ) + self.assertEqual( 2, len( d.cosines ) ) + self.assertAlmostEqual( -1.0 , d.cosines[0] ) + self.assertAlmostEqual( 1.0, d.cosines[1] ) + self.assertEqual( 2, len( d.probabilities ) ) + self.assertAlmostEqual( 0.5 , d.probabilities[0] ) + self.assertAlmostEqual( 0.5, d.probabilities[1] ) + + d = distributions[1] + self.assertAlmostEqual( 2e+7, d.E ) + self.assertAlmostEqual( 2e+7, d.incident_energy ) + self.assertEqual( 3, d.NP ) + self.assertEqual( 1, d.NR ) + self.assertEqual( 1, len( d.boundaries ) ) + self.assertEqual( 1, len( d.interpolants ) ) + self.assertEqual( 3, d.boundaries[0] ) + self.assertEqual( 2, d.interpolants[0] ) + self.assertEqual( 3, len( d.cosines ) ) + self.assertAlmostEqual( -1.0 , d.cosines[0] ) + self.assertAlmostEqual( 0.0, d.cosines[1] ) + self.assertAlmostEqual( 1.0, d.cosines[2] ) + self.assertEqual( 3, len( d.probabilities ) ) + self.assertAlmostEqual( 0.0 , d.probabilities[0] ) + self.assertAlmostEqual( 1.0, d.probabilities[1] ) + self.assertAlmostEqual( 0.0, d.probabilities[2] ) + + self.assertEqual( 8, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9228, 14, 2 ) ) + + # the data is given explicitly + chunk = TabulatedDistributions( + energy = 1.0, level = 2.0, + boundaries = [ 2 ], interpolants = [ 1 ], + distributions = [ TabulatedDistribution( 1e-5, [ 2 ], [ 2 ], [ -1.0, 1.0 ], [ 0.5, 0.5 ] ), + TabulatedDistribution( 2e+7, [ 3 ], [ 2 ], [ -1.0, 0.0, 1.0 ], [ 0.0, 1.0, 0.0 ] ) ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = TabulatedDistributions.from_string( self.chunk, 9228, 14, 2 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = TabulatedDistributions( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + with self.assertRaises( Exception ) : + + chunk = TabulatedDistributions( + energy = 1.0, level = 2.0, + boundaries = [ 2, 4 ], interpolants = [ 1 ], + distributions = [ TabulatedDistribution( 1e-5, [ 2 ], [ 2 ], [ -1.0, 1.0 ], [ 0.5, 0.5 ] ), + TabulatedDistribution( 2e+7, [ 3 ], [ 2 ], [ -1.0, 0.0, 1.0 ], [ 0.0, 1.0, 0.0 ] ) ] ) + + with self.assertRaises( Exception ) : + + chunk = TabulatedDistributions( + energy = 1.0, level = 2.0, + boundaries = [ 2 ], interpolants = [ 1, 2 ], + distributions = [ TabulatedDistribution( 1e-5, [ 2 ], [ 2 ], [ -1.0, 1.0 ], [ 0.5, 0.5 ] ), + TabulatedDistribution( 2e+7, [ 3 ], [ 2 ], [ -1.0, 0.0, 1.0 ], [ 0.0, 1.0, 0.0 ] ) ] ) + + with self.assertRaises( Exception ) : + + chunk = TabulatedDistributions( + energy = 1.0, level = 2.0, + boundaries = [ 2 ], interpolants = [ 1 ], + distributions = [ TabulatedDistribution( 1e-5, [ 2 ], [ 2 ], [ -1.0, 1.0 ], [ 0.5, 0.5 ] ) ] ) + + with self.assertRaises( Exception ) : + + chunk = TabulatedDistributions.from_string( self.invalid, 9228, 14, 2 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF15_OutgoingEnergyDistribution.py b/python/test/Test_ENDFtk_MF15_OutgoingEnergyDistribution.py new file mode 100644 index 000000000..e3db568d1 --- /dev/null +++ b/python/test/Test_ENDFtk_MF15_OutgoingEnergyDistribution.py @@ -0,0 +1,92 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF15 import OutgoingEnergyDistribution + +class Test_ENDFtk_MF15_OutgoingEnergyDistribution( unittest.TestCase ) : + """Unit test for the OutgoingEnergyDistribution class.""" + + chunk = ( ' 0.000000+0 1.000000-5 0 0 1 3943715 18 \n' + ' 3 2 943715 18 \n' + ' 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n' ) + + invalid = ( ' 0.000000+0 1.000000-5 0 0 2 3943715 18 \n' + ' 3 2 943715 18 \n' + ' 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertAlmostEqual( 1e-5, chunk.E ) + self.assertAlmostEqual( 1e-5, chunk.incident_energy ) + + self.assertEqual( 3, chunk.NP ) + self.assertEqual( 1, chunk.NR ) + self.assertEqual( 1, len( chunk.interpolants ) ) + self.assertEqual( 1, len( chunk.boundaries ) ) + self.assertEqual( 2, chunk.interpolants[0] ) + self.assertEqual( 3, chunk.boundaries[0] ) + self.assertEqual( 3, len( chunk.EP ) ) + self.assertEqual( 3, len( chunk.outgoing_energies ) ) + self.assertEqual( 3, len( chunk.G ) ) + self.assertEqual( 3, len( chunk.probabilities ) ) + self.assertAlmostEqual( 0.0, chunk.EP[0] ) + self.assertAlmostEqual( 1e+5, chunk.EP[1] ) + self.assertAlmostEqual( 3e+7, chunk.EP[2] ) + self.assertAlmostEqual( 0.0, chunk.outgoing_energies[0] ) + self.assertAlmostEqual( 1e+5, chunk.outgoing_energies[1] ) + self.assertAlmostEqual( 3e+7, chunk.outgoing_energies[2] ) + self.assertAlmostEqual( 0., chunk.G[0] ) + self.assertAlmostEqual( 1.757570e-9, chunk.G[1] ) + self.assertAlmostEqual( 1.843350e-9, chunk.G[2] ) + self.assertAlmostEqual( 0., chunk.probabilities[0] ) + self.assertAlmostEqual( 1.757570e-9, chunk.probabilities[1] ) + self.assertAlmostEqual( 1.843350e-9, chunk.probabilities[2] ) + + self.assertEqual( 3, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9437, 15, 18 ) ) + + # the data is given explicitly + chunk = OutgoingEnergyDistribution( incident = 1e-5, + boundaries = [ 3 ], interpolants = [ 2 ], + energies = [ 0.0, 1e+5, 3e+7 ], + probabilities = [ 0.0, 1.757570e-9, 1.843350e-9 ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = OutgoingEnergyDistribution.from_string( self.chunk, 9437, 15, 18 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = OutgoingEnergyDistribution( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # wrong boundaries + with self.assertRaises( Exception ) : + + chunk = OutgoingEnergyDistribution( incident = 1e-5, + boundaries = [ 4 ], interpolants = [ 2 ], + energies = [ 0.0, 1e+5, 3e+7 ], + probabilities = [ 0.0, 1.757570e-9, 1.843350e-9 ] ) + + with self.assertRaises( Exception ) : + + chunk = OutgoingEnergyDistribution.from_string( self.invalid, 9437, 15, 18 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF15_Probability.py b/python/test/Test_ENDFtk_MF15_Probability.py new file mode 100644 index 000000000..d9887b206 --- /dev/null +++ b/python/test/Test_ENDFtk_MF15_Probability.py @@ -0,0 +1,86 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF15 import Probability + +class Test_ENDFtk_MF15_Probability( unittest.TestCase ) : + """Unit test for the Probability class.""" + + chunk = ( ' 0.000000+0 0.000000+0 0 1 1 2943715 18 \n' + ' 2 2 943715 18 \n' + ' 1.000000-5 1.000000+0 3.000000+7 1.000000+0 943715 18 \n' ) + + invalid = ( ' 0.000000+0 0.000000+0 0 1 2 2943715 18 \n' + ' 2 2 943715 18 \n' + ' 1.000000-5 1.000000+0 3.000000+7 1.000000+0 943715 18 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( 1, chunk.LF ) + self.assertEqual( 1, chunk.LAW ) + + self.assertEqual( 2, chunk.NP ) + self.assertEqual( 1, chunk.NR ) + self.assertEqual( 1, len( chunk.interpolants ) ) + self.assertEqual( 1, len( chunk.boundaries ) ) + self.assertEqual( 2, chunk.interpolants[0] ) + self.assertEqual( 2, chunk.boundaries[0] ) + self.assertEqual( 2, len( chunk.E ) ) + self.assertEqual( 2, len( chunk.energies ) ) + self.assertEqual( 2, len( chunk.P ) ) + self.assertEqual( 2, len( chunk.probabilities ) ) + self.assertAlmostEqual( 1e-5, chunk.E[0] ) + self.assertAlmostEqual( 3e+7, chunk.E[1] ) + self.assertAlmostEqual( 1e-5, chunk.energies[0] ) + self.assertAlmostEqual( 3e+7, chunk.energies[1] ) + self.assertAlmostEqual( 1., chunk.P[0] ) + self.assertAlmostEqual( 1., chunk.P[1] ) + self.assertAlmostEqual( 1., chunk.probabilities[0] ) + self.assertAlmostEqual( 1., chunk.probabilities[1] ) + + self.assertEqual( 3, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9437, 15, 18 ) ) + + # the data is given explicitly + chunk = Probability( lf = 1, + boundaries = [ 2 ], interpolants = [ 2 ], + energies = [ 1e-5, 3e+7 ], probabilities = [ 1., 1. ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = Probability.from_string( self.chunk, 9437, 15, 18 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = Probability( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # wrong boundaries + with self.assertRaises( Exception ) : + + chunk = Probability( lf = 1, + boundaries = [ 2,4 ], interpolants = [ 2 ], + energies = [ 1e-5, 3e+7 ], values = [ 1., 1. ] ) + + with self.assertRaises( Exception ) : + + chunk = Probability.from_string( self.invalid, 9437, 15, 18 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF15_Section.py b/python/test/Test_ENDFtk_MF15_Section.py new file mode 100644 index 000000000..d87b23225 --- /dev/null +++ b/python/test/Test_ENDFtk_MF15_Section.py @@ -0,0 +1,205 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF15 import Section +from ENDFtk.MF15 import Probability +from ENDFtk.MF15 import PartialDistribution +from ENDFtk.MF15 import OutgoingEnergyDistribution +from ENDFtk.MF15 import TabulatedSpectrum +from ENDFtk.tree import Tape + +class Test_ENDFtk_MF15_Section( unittest.TestCase ) : + """Unit test for the Section class.""" + + chunk = ( ' 9.223500+4 2.330250+2 0 0 1 0922815 18 \n' + ' 0.000000+0 0.000000+0 0 1 1 2922815 18 \n' + ' 2 2 922815 18 \n' + ' 1.000000-5 1.000000+0 3.000000+7 1.000000+0 922815 18 \n' + ' 0.000000+0 0.000000+0 0 0 1 2922815 18 \n' + ' 2 4 922815 18 \n' + ' 0.000000+0 1.000000-5 0 0 1 3922815 18 \n' + ' 3 2 922815 18 \n' + ' 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9922815 18 \n' + ' 0.000000+0 3.000000+7 0 0 1 4922815 18 \n' + ' 4 2 922815 18 \n' + ' 0.000000+0 0.000000+0 1.000000+1 1.733405-9 1.100000+1 1.818010-9922815 18 \n' + ' 3.000000+7 1.898849-9 922815 18 \n' ) + + valid_TPID = 'Just a tape identifier \n' + valid_SEND = ' 922815 0 \n' + valid_FEND = ' 9228 0 0 \n' + valid_MEND = ' 0 0 0 \n' + valid_TEND = ' -1 0 0 \n' + invalid_SEND = ' 9228 3 1 \n' + + def test_section( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( 18, chunk.MT ) + self.assertEqual( 18, chunk.section_number ) + + self.assertAlmostEqual( 92235., chunk.ZA ) + self.assertAlmostEqual( 2.330250e+2, chunk.AWR ) + self.assertAlmostEqual( 2.330250e+2, chunk.atomic_weight_ratio ) + self.assertEqual( 1, chunk.NK ) + self.assertEqual( 1, chunk.number_partial_distributions ) + + partial = chunk.partial_distributions[0] + + p = partial.probability + + self.assertEqual( 1, p.LF ) + self.assertEqual( 1, p.LAW ) + + self.assertEqual( 2, p.NP ) + self.assertEqual( 1, p.NR ) + self.assertEqual( 1, len( p.interpolants ) ) + self.assertEqual( 1, len( p.boundaries ) ) + self.assertEqual( 2, p.interpolants[0] ) + self.assertEqual( 2, p.boundaries[0] ) + self.assertEqual( 2, len( p.E ) ) + self.assertEqual( 2, len( p.energies ) ) + self.assertEqual( 2, len( p.P ) ) + self.assertEqual( 2, len( p.probabilities ) ) + self.assertAlmostEqual( 1e-5, p.E[0] ) + self.assertAlmostEqual( 3e+7, p.E[1] ) + self.assertAlmostEqual( 1e-5, p.energies[0] ) + self.assertAlmostEqual( 3e+7, p.energies[1] ) + self.assertAlmostEqual( 1., p.P[0] ) + self.assertAlmostEqual( 1., p.P[1] ) + self.assertAlmostEqual( 1., p.probabilities[0] ) + self.assertAlmostEqual( 1., p.probabilities[1] ) + + d = partial.distribution + + self.assertEqual( True, isinstance( d, TabulatedSpectrum ) ) + + self.assertEqual( 1, d.LF ) + self.assertEqual( 1, d.LAW ) + + self.assertEqual( 1, d.NR ) + self.assertEqual( 2, d.NE ) + self.assertEqual( 1, len( d.boundaries ) ) + self.assertEqual( 2, d.boundaries[0] ) + self.assertEqual( 1, len( d.interpolants ) ) + self.assertEqual( 4, d.interpolants[0] ) + + self.assertEqual( 2, len( d.incident_energies ) ) + self.assertAlmostEqual( 1e-5, d.incident_energies[0] ) + self.assertAlmostEqual( 3e+7, d.incident_energies[1] ) + + value = d.outgoing_distributions[0] + self.assertAlmostEqual( 1e-5, value.E ) + self.assertAlmostEqual( 1e-5, value.incident_energy ) + self.assertEqual( 3, value.NP ) + self.assertEqual( 1, value.NR ) + self.assertEqual( 1, len( value.interpolants ) ) + self.assertEqual( 1, len( value.boundaries ) ) + self.assertEqual( 2, value.interpolants[0] ) + self.assertEqual( 3, value.boundaries[0] ) + self.assertEqual( 3, len( value.EP ) ) + self.assertEqual( 3, len( value.outgoing_energies ) ) + self.assertEqual( 3, len( value.G ) ) + self.assertEqual( 3, len( value.probabilities ) ) + self.assertAlmostEqual( 0.0, value.EP[0] ) + self.assertAlmostEqual( 1e+5, value.EP[1] ) + self.assertAlmostEqual( 3e+7, value.EP[2] ) + self.assertAlmostEqual( 0.0, value.outgoing_energies[0] ) + self.assertAlmostEqual( 1e+5, value.outgoing_energies[1] ) + self.assertAlmostEqual( 3e+7, value.outgoing_energies[2] ) + self.assertAlmostEqual( 0., value.G[0] ) + self.assertAlmostEqual( 1.757570e-9, value.G[1] ) + self.assertAlmostEqual( 1.843350e-9, value.G[2] ) + self.assertAlmostEqual( 0., value.probabilities[0] ) + self.assertAlmostEqual( 1.757570e-9, value.probabilities[1] ) + self.assertAlmostEqual( 1.843350e-9, value.probabilities[2] ) + + value = d.outgoing_distributions[1] + self.assertAlmostEqual( 3e+7, value.E ) + self.assertAlmostEqual( 3e+7, value.incident_energy ) + self.assertEqual( 4, value.NP ) + self.assertEqual( 1, value.NR ) + self.assertEqual( 1, len( value.interpolants ) ) + self.assertEqual( 1, len( value.boundaries ) ) + self.assertEqual( 2, value.interpolants[0] ) + self.assertEqual( 4, value.boundaries[0] ) + self.assertEqual( 4, len( value.EP ) ) + self.assertEqual( 4, len( value.outgoing_energies ) ) + self.assertEqual( 4, len( value.G ) ) + self.assertEqual( 4, len( value.probabilities ) ) + self.assertAlmostEqual( 0.0, value.EP[0] ) + self.assertAlmostEqual( 10., value.EP[1] ) + self.assertAlmostEqual( 11., value.EP[2] ) + self.assertAlmostEqual( 3e+7, value.EP[3] ) + self.assertAlmostEqual( 0.0, value.outgoing_energies[0] ) + self.assertAlmostEqual( 10., value.outgoing_energies[1] ) + self.assertAlmostEqual( 11., value.outgoing_energies[2] ) + self.assertAlmostEqual( 3e+7, value.outgoing_energies[3] ) + self.assertAlmostEqual( 0., value.G[0] ) + self.assertAlmostEqual( 1.733405e-9, value.G[1] ) + self.assertAlmostEqual( 1.818010e-9, value.G[2] ) + self.assertAlmostEqual( 1.898849e-9, value.G[3] ) + self.assertAlmostEqual( 0., value.probabilities[0] ) + self.assertAlmostEqual( 1.733405e-9, value.probabilities[1] ) + self.assertAlmostEqual( 1.818010e-9, value.probabilities[2] ) + self.assertAlmostEqual( 1.898849e-9, value.probabilities[3] ) + + self.assertEqual( 13, chunk.NC ) + + # verify string + self.assertEqual( self.chunk + self.valid_SEND, + chunk.to_string( 9228, 15 ) ) + + # the data is given explicitly + chunk = Section( mt = 18, zaid = 92235., awr = 2.330250e+2, + partials = [ PartialDistribution( + Probability( 1, [ 2 ], [ 2 ], + [ 1e-5, 3e+7 ], [ 1., 1. ] ), + TabulatedSpectrum( [ 2 ], [ 4 ], + [ OutgoingEnergyDistribution( + 1e-5, [ 3 ], [ 2 ], + [ 0.0, 1e+5, 3e+7 ], + [ 0.0, 1.757570e-9, 1.843350e-9 ] ), + OutgoingEnergyDistribution( + 3e+7, [ 4 ], [ 2 ], + [ 0.0, 10., 11., 3e+7 ], + [ 0.0, 1.733405e-9, 1.818010e-9, + 1.898849e-9 ] ) ] ) ) ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk + self.valid_SEND ) + + verify_chunk( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 15 ).section( 18 ).parse() + + verify_chunk( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # illegal SEND + with self.assertRaises( Exception ) : + + chunk = Section.from_string( self.chunk + self.invalid_SEND ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF15_TabulatedSpectrum.py b/python/test/Test_ENDFtk_MF15_TabulatedSpectrum.py new file mode 100644 index 000000000..f749b1213 --- /dev/null +++ b/python/test/Test_ENDFtk_MF15_TabulatedSpectrum.py @@ -0,0 +1,158 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF15 import OutgoingEnergyDistribution +from ENDFtk.MF15 import TabulatedSpectrum + +class Test_ENDFtk_MF15_TabulatedSpectrum( unittest.TestCase ) : + """Unit test for the TabulatedSpectrum class.""" + + chunk = ( ' 0.000000+0 0.000000+0 0 0 1 2943715 18 \n' + ' 2 4 943715 18 \n' + ' 0.000000+0 1.000000-5 0 0 1 3943715 18 \n' + ' 3 2 943715 18 \n' + ' 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n' + ' 0.000000+0 3.000000+7 0 0 1 4943715 18 \n' + ' 4 2 943715 18 \n' + ' 0.000000+0 0.000000+0 1.000000+1 1.733405-9 1.100000+1 1.818010-9943715 18 \n' + ' 3.000000+7 1.898849-9 943715 18 \n' ) + + invalid = ( ' 0.000000+0 0.000000+0 0 0 2 2943715 18 \n' + ' 2 4 943715 18 \n' + ' 0.000000+0 1.000000-5 0 0 1 3943715 18 \n' + ' 3 2 943715 18 \n' + ' 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n' + ' 0.000000+0 3.000000+7 0 0 1 4943715 18 \n' + ' 4 2 943715 18 \n' + ' 0.000000+0 0.000000+0 1.000000+1 1.733405-9 1.100000+1 1.818010-9943715 18 \n' + ' 3.000000+7 1.898849-9 943715 18 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( 1, chunk.LF ) + self.assertEqual( 1, chunk.LAW ) + + self.assertEqual( 1, chunk.NR ) + self.assertEqual( 2, chunk.NE ) + self.assertEqual( 1, len( chunk.boundaries ) ) + self.assertEqual( 2, chunk.boundaries[0] ) + self.assertEqual( 1, len( chunk.interpolants ) ) + self.assertEqual( 4, chunk.interpolants[0] ) + + self.assertEqual( 2, len( chunk.incident_energies ) ) + self.assertAlmostEqual( 1e-5, chunk.incident_energies[0] ) + self.assertAlmostEqual( 3e+7, chunk.incident_energies[1] ) + + value = chunk.outgoing_distributions[0] + self.assertAlmostEqual( 1e-5, value.E ) + self.assertAlmostEqual( 1e-5, value.incident_energy ) + self.assertEqual( 3, value.NP ) + self.assertEqual( 1, value.NR ) + self.assertEqual( 1, len( value.interpolants ) ) + self.assertEqual( 1, len( value.boundaries ) ) + self.assertEqual( 2, value.interpolants[0] ) + self.assertEqual( 3, value.boundaries[0] ) + self.assertEqual( 3, len( value.EP ) ) + self.assertEqual( 3, len( value.outgoing_energies ) ) + self.assertEqual( 3, len( value.G ) ) + self.assertEqual( 3, len( value.probabilities ) ) + self.assertAlmostEqual( 0.0, value.EP[0] ) + self.assertAlmostEqual( 1e+5, value.EP[1] ) + self.assertAlmostEqual( 3e+7, value.EP[2] ) + self.assertAlmostEqual( 0.0, value.outgoing_energies[0] ) + self.assertAlmostEqual( 1e+5, value.outgoing_energies[1] ) + self.assertAlmostEqual( 3e+7, value.outgoing_energies[2] ) + self.assertAlmostEqual( 0., value.G[0] ) + self.assertAlmostEqual( 1.757570e-9, value.G[1] ) + self.assertAlmostEqual( 1.843350e-9, value.G[2] ) + self.assertAlmostEqual( 0., value.probabilities[0] ) + self.assertAlmostEqual( 1.757570e-9, value.probabilities[1] ) + self.assertAlmostEqual( 1.843350e-9, value.probabilities[2] ) + + value = chunk.outgoing_distributions[1] + self.assertAlmostEqual( 3e+7, value.E ) + self.assertAlmostEqual( 3e+7, value.incident_energy ) + self.assertEqual( 4, value.NP ) + self.assertEqual( 1, value.NR ) + self.assertEqual( 1, len( value.interpolants ) ) + self.assertEqual( 1, len( value.boundaries ) ) + self.assertEqual( 2, value.interpolants[0] ) + self.assertEqual( 4, value.boundaries[0] ) + self.assertEqual( 4, len( value.EP ) ) + self.assertEqual( 4, len( value.outgoing_energies ) ) + self.assertEqual( 4, len( value.G ) ) + self.assertEqual( 4, len( value.probabilities ) ) + self.assertAlmostEqual( 0.0, value.EP[0] ) + self.assertAlmostEqual( 10., value.EP[1] ) + self.assertAlmostEqual( 11., value.EP[2] ) + self.assertAlmostEqual( 3e+7, value.EP[3] ) + self.assertAlmostEqual( 0.0, value.outgoing_energies[0] ) + self.assertAlmostEqual( 10., value.outgoing_energies[1] ) + self.assertAlmostEqual( 11., value.outgoing_energies[2] ) + self.assertAlmostEqual( 3e+7, value.outgoing_energies[3] ) + self.assertAlmostEqual( 0., value.G[0] ) + self.assertAlmostEqual( 1.733405e-9, value.G[1] ) + self.assertAlmostEqual( 1.818010e-9, value.G[2] ) + self.assertAlmostEqual( 1.898849e-9, value.G[3] ) + self.assertAlmostEqual( 0., value.probabilities[0] ) + self.assertAlmostEqual( 1.733405e-9, value.probabilities[1] ) + self.assertAlmostEqual( 1.818010e-9, value.probabilities[2] ) + self.assertAlmostEqual( 1.898849e-9, value.probabilities[3] ) + + self.assertEqual( 9, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9437, 15, 18 ) ) + + # the data is given explicitly + chunk = TabulatedSpectrum( + boundaries = [ 2 ], interpolants = [ 4 ], + distributions = [ OutgoingEnergyDistribution( 1e-5, [ 3 ], [ 2 ], + [ 0.0, 1e+5, 3e+7 ], + [ 0.0, 1.757570e-9, 1.843350e-9 ] ), + OutgoingEnergyDistribution( 3e+7, [ 4 ], [ 2 ], + [ 0.0, 10., 11., 3e+7 ], + [ 0.0, 1.733405e-9, 1.818010e-9, + 1.898849e-9 ] ) ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = TabulatedSpectrum.from_string( self.chunk, 9437, 15, 18 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = TabulatedSpectrum( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + with self.assertRaises( Exception ) : + + chunk = TabulatedSpectrum( + boundaries = [ 2, 4 ], interpolants = [ 4 ], + distributions = [ OutgoingEnergyDistribution( 1e-5, [ 3 ], [ 2 ], + [ 0.0, 1e+5, 3e+7 ], + [ 0.0, 1.757570e-9, 1.843350e-9 ] ), + OutgoingEnergyDistribution( 3e+7, [ 4 ], [ 2 ], + [ 0.0, 10., 11., 3e+7 ], + [ 0.0, 1.733405e-9, 1.818010e-9, + 1.898849e-9 ] ) ] ) + + with self.assertRaises( Exception ) : + + chunk = TabulatedSpectrum.from_string( self.invalid, 9437, 15, 18 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF4_Isotropic.py b/python/test/Test_ENDFtk_MF4_Isotropic.py index 7f62c0744..970bda54a 100644 --- a/python/test/Test_ENDFtk_MF4_Isotropic.py +++ b/python/test/Test_ENDFtk_MF4_Isotropic.py @@ -14,6 +14,8 @@ def test_component( self ) : def verify_chunk( self, chunk ) : # verify content + self.assertEqual( True, chunk.LI ) + self.assertEqual( True, chunk.isotropic_angular_distributions ) self.assertEqual( 0, chunk.LTT ) self.assertEqual( 0, chunk.LAW ) diff --git a/python/test/Test_ENDFtk_MF4_LegendreCoefficients.py b/python/test/Test_ENDFtk_MF4_LegendreCoefficients.py index 13921715f..225ca3372 100644 --- a/python/test/Test_ENDFtk_MF4_LegendreCoefficients.py +++ b/python/test/Test_ENDFtk_MF4_LegendreCoefficients.py @@ -61,7 +61,7 @@ def test_failures( self ) : with self.assertRaises( Exception ) : - chunk = LegendreCoefficients.from_string( self.invalid, 9228, 2, 151 ) + chunk = LegendreCoefficients.from_string( self.invalid, 9228, 4, 2 ) if __name__ == '__main__' : diff --git a/python/test/Test_ENDFtk_MF4_LegendreDistributions.py b/python/test/Test_ENDFtk_MF4_LegendreDistributions.py index 62fc28afd..3fbce93fb 100644 --- a/python/test/Test_ENDFtk_MF4_LegendreDistributions.py +++ b/python/test/Test_ENDFtk_MF4_LegendreDistributions.py @@ -29,6 +29,8 @@ def test_component( self ) : def verify_chunk( self, chunk ) : # verify content + self.assertEqual( False, chunk.LI ) + self.assertEqual( False, chunk.isotropic_angular_distributions ) self.assertEqual( 1, chunk.LTT ) self.assertEqual( 1, chunk.LAW ) @@ -115,7 +117,7 @@ def test_failures( self ) : with self.assertRaises( Exception ) : - chunk = LegendreDistributions.from_string( self.invalid, 9228, 2, 151 ) + chunk = LegendreDistributions.from_string( self.invalid, 9228, 14, 2 ) if __name__ == '__main__' : diff --git a/python/test/Test_ENDFtk_MF4_MixedDistributions.py b/python/test/Test_ENDFtk_MF4_MixedDistributions.py index 295d23dfc..d0bdf6435 100644 --- a/python/test/Test_ENDFtk_MF4_MixedDistributions.py +++ b/python/test/Test_ENDFtk_MF4_MixedDistributions.py @@ -48,6 +48,8 @@ def test_component( self ) : def verify_chunk( self, chunk ) : # verify content + self.assertEqual( False, chunk.LI ) + self.assertEqual( False, chunk.isotropic_angular_distributions ) self.assertEqual( 3, chunk.LTT ) self.assertEqual( 3, chunk.LAW ) diff --git a/python/test/Test_ENDFtk_MF4_TabulatedDistribution.py b/python/test/Test_ENDFtk_MF4_TabulatedDistribution.py index ec7905bb6..f0fa0b589 100644 --- a/python/test/Test_ENDFtk_MF4_TabulatedDistribution.py +++ b/python/test/Test_ENDFtk_MF4_TabulatedDistribution.py @@ -81,7 +81,7 @@ def test_failures( self ) : with self.assertRaises( Exception ) : - chunk = TabulatedDistribution.from_string( self.invalid, 9228, 2, 151 ) + chunk = TabulatedDistribution.from_string( self.invalid, 9228, 4, 2 ) if __name__ == '__main__' : diff --git a/python/test/Test_ENDFtk_MF4_TabulatedDistributions.py b/python/test/Test_ENDFtk_MF4_TabulatedDistributions.py index 9eb5796c5..b3c47ddee 100644 --- a/python/test/Test_ENDFtk_MF4_TabulatedDistributions.py +++ b/python/test/Test_ENDFtk_MF4_TabulatedDistributions.py @@ -33,6 +33,8 @@ def test_component( self ) : def verify_chunk( self, chunk ) : # verify content + self.assertEqual( False, chunk.LI ) + self.assertEqual( False, chunk.isotropic_angular_distributions ) self.assertEqual( 2, chunk.LTT ) self.assertEqual( 2, chunk.LAW ) @@ -134,7 +136,7 @@ def test_failures( self ) : with self.assertRaises( Exception ) : - chunk = TabulatedDistributions.from_string( self.invalid, 9228, 2, 151 ) + chunk = TabulatedDistributions.from_string( self.invalid, 9228, 4, 2 ) if __name__ == '__main__' : diff --git a/python/test/Test_ENDFtk_MF8_FissionYieldData.py b/python/test/Test_ENDFtk_MF8_FissionYieldData.py new file mode 100644 index 000000000..6c8da04ae --- /dev/null +++ b/python/test/Test_ENDFtk_MF8_FissionYieldData.py @@ -0,0 +1,107 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF8 import FissionYieldData + +class Test_ENDFtk_MF8_FissionYieldData( unittest.TestCase ) : + """Unit test for the FissionYieldData class.""" + + chunk = ( ' 2.530000-2 0.000000+0 2 0 12 39228 8454 \n' + ' 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8454 \n' + ' 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n' ) + + invalid = ( ' 2.530000-2 0.000000+0 2 0 16 39228 8454 \n' + ' 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8454 \n' + ' 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( 2, chunk.I ) + self.assertEqual( 2, chunk.interpolation_type ) + self.assertEqual( False, chunk.LE ) + self.assertEqual( False, chunk.is_energy_independent ) + self.assertEqual( 3, chunk.NFP ) + self.assertEqual( 3, chunk.number_fission_products ) + self.assertEqual( 0.0253, chunk.E ) + self.assertEqual( 0.0253, chunk.incident_energy ) + + self.assertEqual( 3, len( chunk.ZAFP ) ) + self.assertEqual( 3, len( chunk.fission_product_identifiers ) ) + self.assertEqual( 3, len( chunk.FPS ) ) + self.assertEqual( 3, len( chunk.isomeric_states ) ) + self.assertEqual( 3, len( chunk.Y ) ) + self.assertEqual( 3, len( chunk.fission_yields ) ) + self.assertEqual( 23066, chunk.ZAFP[0] ) + self.assertEqual( 54135, chunk.ZAFP[1] ) + self.assertEqual( 72171, chunk.ZAFP[2] ) + self.assertEqual( 23066, chunk.fission_product_identifiers[0] ) + self.assertEqual( 54135, chunk.fission_product_identifiers[1] ) + self.assertEqual( 72171, chunk.fission_product_identifiers[2] ) + self.assertEqual( 0, chunk.FPS[0] ) + self.assertEqual( 0, chunk.FPS[1] ) + self.assertEqual( 0, chunk.FPS[2] ) + self.assertEqual( 0, chunk.isomeric_states[0] ) + self.assertEqual( 0, chunk.isomeric_states[1] ) + self.assertEqual( 0, chunk.isomeric_states[2] ) + self.assertEqual( 2, len( chunk.Y[0] ) ) + self.assertEqual( 2, len( chunk.Y[1] ) ) + self.assertEqual( 2, len( chunk.Y[2] ) ) + self.assertEqual( 2, len( chunk.fission_yields[0] ) ) + self.assertEqual( 2, len( chunk.fission_yields[1] ) ) + self.assertEqual( 2, len( chunk.fission_yields[2] ) ) + self.assertAlmostEqual( 2.05032e-19, chunk.Y[0][0] ) + self.assertAlmostEqual( 1.31220e-19, chunk.Y[0][1] ) + self.assertAlmostEqual( 7.851250e-4, chunk.Y[1][0] ) + self.assertAlmostEqual( 4.710750e-5, chunk.Y[1][1] ) + self.assertAlmostEqual( 0, chunk.Y[2][0] ) + self.assertAlmostEqual( 0, chunk.Y[2][1] ) + self.assertAlmostEqual( 2.05032e-19, chunk.fission_yields[0][0] ) + self.assertAlmostEqual( 1.31220e-19, chunk.fission_yields[0][1] ) + self.assertAlmostEqual( 7.851250e-4, chunk.fission_yields[1][0] ) + self.assertAlmostEqual( 4.710750e-5, chunk.fission_yields[1][1] ) + self.assertAlmostEqual( 0, chunk.fission_yields[2][0] ) + self.assertAlmostEqual( 0, chunk.fission_yields[2][1] ) + + self.assertEqual( 3, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9228, 8, 454 ) ) + + # the data is given explicitly + chunk = FissionYieldData( energy = 0.0253, + interpolation = 2, + identifiers = [ 23066, 54135, 72171 ], + states = [ 0, 0, 0 ], + yields = [ [ 2.05032e-19, 1.31220e-19 ], + [ 7.851250e-4, 4.710750e-5 ], + [ 0., 0. ] ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = FissionYieldData.from_string( self.chunk, 9228, 8, 454 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = FissionYieldData( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + with self.assertRaises( Exception ) : + + chunk = FissionYieldData.from_string( self.invalid, 9228, 8, 454 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF8_MT454_Section.py b/python/test/Test_ENDFtk_MF8_MT454_Section.py new file mode 100644 index 000000000..fc8254748 --- /dev/null +++ b/python/test/Test_ENDFtk_MF8_MT454_Section.py @@ -0,0 +1,333 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF8.MT454 import Section +from ENDFtk.MF8 import FissionYieldData +from ENDFtk.tree import Tape + +class Test_ENDFtk_MF8_MT457_Section( unittest.TestCase ) : + """Unit test for the Section class.""" + + chunk = ( ' 9.223500+4 2.330250+2 2 0 0 09228 8454 \n' + ' 2.530000-2 0.000000+0 1 0 12 39228 8454 \n' + ' 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8454 \n' + ' 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n' + ' 5.000000+5 0.000000+0 3 0 12 39228 8454 \n' + ' 2.306600+4 0.000000+0 4.48456-18 2.87012-18 5.413500+4 0.000000+09228 8454 \n' + ' 1.196100-3 2.751030-4 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n' ) + + chunk_energy_independent = ( ' 9.223500+4 2.330250+2 1 0 0 09228 8454 \n' + ' 0.000000+0 0.000000+0 0 0 12 39228 8454 \n' + ' 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8454 \n' + ' 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n' ) + + valid_TPID = 'Just a tape identifier \n' + valid_SEND = ' 9228 8 0 \n' + valid_FEND = ' 9228 0 0 \n' + valid_MEND = ' 0 0 0 \n' + valid_TEND = ' -1 0 0 \n' + invalid_SEND = ' 9228 8457 \n' + + def test_section( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( 454, chunk.MT ) + self.assertEqual( 454, chunk.section_number ) + + self.assertAlmostEqual( 92235., chunk.ZA ) + self.assertAlmostEqual( 233.0250, chunk.AWR ) + self.assertAlmostEqual( 233.0250, chunk.atomic_weight_ratio ) + + self.assertEqual( False, chunk.LE ) + self.assertEqual( False, chunk.is_energy_independent ) + + self.assertEqual( 2, chunk.NE ) + self.assertEqual( 2, len( chunk.E ) ) + self.assertEqual( 2, len( chunk.incident_energies ) ) + self.assertAlmostEqual( 0.0253, chunk.E[0] ) + self.assertAlmostEqual( 500e+3, chunk.E[1] ) + self.assertAlmostEqual( 0.0253, chunk.incident_energies[0] ) + self.assertAlmostEqual( 500e+3, chunk.incident_energies[1] ) + + self.assertEqual( 2, len( chunk.yields ) ) + + data = chunk.yields[0] + self.assertEqual( 1, data.I ) + self.assertEqual( 1, data.interpolation_type ) + self.assertEqual( False, data.LE ) + self.assertEqual( False, data.is_energy_independent ) + self.assertEqual( 3, data.NFP ) + self.assertEqual( 3, data.number_fission_products ) + self.assertAlmostEqual( 0.0253, data.E ) + self.assertAlmostEqual( 0.0253, data.incident_energy ) + + self.assertEqual( 3, len( data.ZAFP ) ) + self.assertEqual( 3, len( data.fission_product_identifiers ) ) + self.assertEqual( 3, len( data.FPS ) ) + self.assertEqual( 3, len( data.isomeric_states ) ) + self.assertEqual( 3, len( data.Y ) ) + self.assertEqual( 3, len( data.fission_yields ) ) + self.assertEqual( 23066, data.ZAFP[0] ); + self.assertEqual( 54135, data.ZAFP[1] ); + self.assertEqual( 72171, data.ZAFP[2] ); + self.assertEqual( 23066, data.fission_product_identifiers[0] ); + self.assertEqual( 54135, data.fission_product_identifiers[1] ); + self.assertEqual( 72171, data.fission_product_identifiers[2] ); + self.assertEqual( 0, data.FPS[0] ); + self.assertEqual( 0, data.FPS[1] ); + self.assertEqual( 0, data.FPS[2] ); + self.assertEqual( 0, data.isomeric_states[0] ); + self.assertEqual( 0, data.isomeric_states[1] ); + self.assertEqual( 0, data.isomeric_states[2] ); + self.assertEqual( 2, len( data.Y[0] ) ) + self.assertEqual( 2, len( data.Y[1] ) ) + self.assertEqual( 2, len( data.Y[2] ) ) + self.assertEqual( 2, len( data.fission_yields[0] ) ) + self.assertEqual( 2, len( data.fission_yields[1] ) ) + self.assertEqual( 2, len( data.fission_yields[2] ) ) + self.assertAlmostEqual( 2.05032e-19, data.Y[0][0] ) + self.assertAlmostEqual( 1.31220e-19, data.Y[0][1] ) + self.assertAlmostEqual( 7.851250e-4, data.Y[1][0] ) + self.assertAlmostEqual( 4.710750e-5, data.Y[1][1] ) + self.assertAlmostEqual( 0, data.Y[2][0] ) + self.assertAlmostEqual( 0, data.Y[2][1] ) + self.assertAlmostEqual( 2.05032e-19, data.fission_yields[0][0] ) + self.assertAlmostEqual( 1.31220e-19, data.fission_yields[0][1] ) + self.assertAlmostEqual( 7.851250e-4, data.fission_yields[1][0] ) + self.assertAlmostEqual( 4.710750e-5, data.fission_yields[1][1] ) + self.assertAlmostEqual( 0, data.fission_yields[2][0] ) + self.assertAlmostEqual( 0, data.fission_yields[2][1] ) + + data = chunk.yields[1] + self.assertEqual( 3, data.I ) + self.assertEqual( 3, data.interpolation_type ) + self.assertEqual( False, data.LE ) + self.assertEqual( False, data.is_energy_independent ) + self.assertEqual( 3, data.NFP ) + self.assertEqual( 3, data.number_fission_products ) + self.assertAlmostEqual( 500e+3, data.E ) + self.assertAlmostEqual( 500e+3, data.incident_energy ) + + self.assertEqual( 3, len( data.ZAFP ) ) + self.assertEqual( 3, len( data.fission_product_identifiers ) ) + self.assertEqual( 3, len( data.FPS ) ) + self.assertEqual( 3, len( data.isomeric_states ) ) + self.assertEqual( 3, len( data.Y ) ) + self.assertEqual( 3, len( data.fission_yields ) ) + self.assertEqual( 23066, data.ZAFP[0] ); + self.assertEqual( 54135, data.ZAFP[1] ); + self.assertEqual( 72171, data.ZAFP[2] ); + self.assertEqual( 23066, data.fission_product_identifiers[0] ); + self.assertEqual( 54135, data.fission_product_identifiers[1] ); + self.assertEqual( 72171, data.fission_product_identifiers[2] ); + self.assertEqual( 0, data.FPS[0] ); + self.assertEqual( 0, data.FPS[1] ); + self.assertEqual( 0, data.FPS[2] ); + self.assertEqual( 0, data.isomeric_states[0] ); + self.assertEqual( 0, data.isomeric_states[1] ); + self.assertEqual( 0, data.isomeric_states[2] ); + self.assertEqual( 2, len( data.Y[0] ) ) + self.assertEqual( 2, len( data.Y[1] ) ) + self.assertEqual( 2, len( data.Y[2] ) ) + self.assertEqual( 2, len( data.fission_yields[0] ) ) + self.assertEqual( 2, len( data.fission_yields[1] ) ) + self.assertEqual( 2, len( data.fission_yields[2] ) ) + self.assertAlmostEqual( 4.48456e-18, data.Y[0][0] ) + self.assertAlmostEqual( 2.87012e-18, data.Y[0][1] ) + self.assertAlmostEqual( 1.196100e-3, data.Y[1][0] ) + self.assertAlmostEqual( 2.751030e-4, data.Y[1][1] ) + self.assertAlmostEqual( 0, data.Y[2][0] ) + self.assertAlmostEqual( 0, data.Y[2][1] ) + self.assertAlmostEqual( 4.48456e-18, data.fission_yields[0][0] ) + self.assertAlmostEqual( 2.87012e-18, data.fission_yields[0][1] ) + self.assertAlmostEqual( 1.196100e-3, data.fission_yields[1][0] ) + self.assertAlmostEqual( 2.751030e-4, data.fission_yields[1][1] ) + self.assertAlmostEqual( 0, data.fission_yields[2][0] ) + self.assertAlmostEqual( 0, data.fission_yields[2][1] ) + + self.assertEqual( 7, chunk.NC ) + + # verify string + self.assertEqual( self.chunk + self.valid_SEND, + chunk.to_string( 9228, 8 ) ) + + def verify_chunk_energy_independent( self, chunk ) : + + self.assertEqual( 454, chunk.MT ) + self.assertEqual( 454, chunk.section_number ) + + self.assertAlmostEqual( 92235., chunk.ZA ) + self.assertAlmostEqual( 233.0250, chunk.AWR ) + self.assertAlmostEqual( 233.0250, chunk.atomic_weight_ratio ) + + self.assertEqual( True, chunk.LE ) + self.assertEqual( True, chunk.is_energy_independent ) + + self.assertEqual( 1, len( chunk.E ) ) + self.assertEqual( 1, len( chunk.incident_energies ) ) + self.assertAlmostEqual( 0., chunk.E[0] ) + self.assertAlmostEqual( 0., chunk.incident_energies[0] ) + + self.assertEqual( 1, len( chunk.yields ) ) + + data = chunk.yields[0] + self.assertEqual( 0, data.I ) + self.assertEqual( 0, data.interpolation_type ) + self.assertEqual( True, data.LE ) + self.assertEqual( True, data.is_energy_independent ) + self.assertEqual( 3, data.NFP ) + self.assertEqual( 3, data.number_fission_products ) + self.assertEqual( 0., data.E ) + self.assertEqual( 0., data.incident_energy ) + + self.assertEqual( 3, len( data.ZAFP ) ) + self.assertEqual( 3, len( data.fission_product_identifiers ) ) + self.assertEqual( 3, len( data.FPS ) ) + self.assertEqual( 3, len( data.isomeric_states ) ) + self.assertEqual( 3, len( data.Y ) ) + self.assertEqual( 3, len( data.fission_yields ) ) + self.assertEqual( 23066, data.ZAFP[0] ); + self.assertEqual( 54135, data.ZAFP[1] ); + self.assertEqual( 72171, data.ZAFP[2] ); + self.assertEqual( 23066, data.fission_product_identifiers[0] ); + self.assertEqual( 54135, data.fission_product_identifiers[1] ); + self.assertEqual( 72171, data.fission_product_identifiers[2] ); + self.assertEqual( 0, data.FPS[0] ); + self.assertEqual( 0, data.FPS[1] ); + self.assertEqual( 0, data.FPS[2] ); + self.assertEqual( 0, data.isomeric_states[0] ); + self.assertEqual( 0, data.isomeric_states[1] ); + self.assertEqual( 0, data.isomeric_states[2] ); + self.assertEqual( 2, len( data.Y[0] ) ) + self.assertEqual( 2, len( data.Y[1] ) ) + self.assertEqual( 2, len( data.Y[2] ) ) + self.assertEqual( 2, len( data.fission_yields[0] ) ) + self.assertEqual( 2, len( data.fission_yields[1] ) ) + self.assertEqual( 2, len( data.fission_yields[2] ) ) + self.assertAlmostEqual( 2.05032e-19, data.Y[0][0] ) + self.assertAlmostEqual( 1.31220e-19, data.Y[0][1] ) + self.assertAlmostEqual( 7.851250e-4, data.Y[1][0] ) + self.assertAlmostEqual( 4.710750e-5, data.Y[1][1] ) + self.assertAlmostEqual( 0, data.Y[2][0] ) + self.assertAlmostEqual( 0, data.Y[2][1] ) + self.assertAlmostEqual( 2.05032e-19, data.fission_yields[0][0] ) + self.assertAlmostEqual( 1.31220e-19, data.fission_yields[0][1] ) + self.assertAlmostEqual( 7.851250e-4, data.fission_yields[1][0] ) + self.assertAlmostEqual( 4.710750e-5, data.fission_yields[1][1] ) + self.assertAlmostEqual( 0, data.fission_yields[2][0] ) + self.assertAlmostEqual( 0, data.fission_yields[2][1] ) + + self.assertEqual( 4, chunk.NC ) + + # verify string + self.assertEqual( self.chunk_energy_independent + self.valid_SEND, + chunk.to_string( 9228, 8 ) ) + + # the data is given explicitly + chunk = Section( zaid = 92235., awr = 233.0250, + identifiers = [ 23066, 54135, 72171 ], + states = [ 0, 0, 0 ], + energies = [ 0.0253, 500e+3 ], + interpolants = [ 3 ], + yields = [ [ [ 2.05032e-19, 1.31220e-19 ], [ 4.48456e-18, 2.87012e-18 ] ], + [ [ 7.851250e-4, 4.710750e-5 ], [ 1.196100e-3, 2.751030e-4 ] ], + [ [ 0, 0 ], [ 0, 0 ] ] ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk + self.valid_SEND ) + + verify_chunk( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 8 ).section( 454 ).parse() + + verify_chunk( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk( self, copy ) + + # the data is given explicitly as a FissionYieldData array + chunk = Section( zaid = 92235., awr = 233.0250, + yields = [ FissionYieldData( [ 23066, 54135, 72171 ], [ 0, 0, 0 ], + [ [ 2.05032e-19, 1.31220e-19 ], + [ 7.851250e-4, 4.710750e-5 ], + [ 0, 0 ] ], + 0.0253, 1 ), + FissionYieldData( [ 23066, 54135, 72171 ], [ 0, 0, 0 ], + [ [ 4.48456e-18, 2.87012e-18 ], + [ 1.196100e-3, 2.751030e-4 ], + [ 0, 0 ] ], + 500e+3, 3 ) ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk + self.valid_SEND ) + + verify_chunk( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 8 ).section( 454 ).parse() + + verify_chunk( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk( self, copy ) + + # the data is given explicitly for energy independent yields + chunk = Section( zaid = 92235., awr = 233.0250, + identifiers = [ 23066, 54135, 72171 ], + states = [ 0, 0, 0 ], + yields = [ [ 2.05032e-19, 1.31220e-19 ], + [ 7.851250e-4, 4.710750e-5 ], + [ 0, 0 ] ] ) + + verify_chunk_energy_independent( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk_energy_independent + self.valid_SEND ) + + verify_chunk_energy_independent( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk_energy_independent + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 8 ).section( 454 ).parse() + + verify_chunk_energy_independent( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk_energy_independent( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # illegal SEND + with self.assertRaises( Exception ) : + + chunk = Section.from_string( self.chunk + self.invalid_SEND ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF8_MT459_Section.py b/python/test/Test_ENDFtk_MF8_MT459_Section.py new file mode 100644 index 000000000..ae8bd5fdd --- /dev/null +++ b/python/test/Test_ENDFtk_MF8_MT459_Section.py @@ -0,0 +1,333 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF8.MT459 import Section +from ENDFtk.MF8 import FissionYieldData +from ENDFtk.tree import Tape + +class Test_ENDFtk_MF8_MT457_Section( unittest.TestCase ) : + """Unit test for the Section class.""" + + chunk = ( ' 9.223500+4 2.330250+2 2 0 0 09228 8459 \n' + ' 2.530000-2 0.000000+0 1 0 12 39228 8459 \n' + ' 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8459 \n' + ' 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8459 \n' + ' 5.000000+5 0.000000+0 3 0 12 39228 8459 \n' + ' 2.306600+4 0.000000+0 4.48456-18 2.87012-18 5.413500+4 0.000000+09228 8459 \n' + ' 1.196100-3 2.751030-4 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8459 \n' ) + + chunk_energy_independent = ( ' 9.223500+4 2.330250+2 1 0 0 09228 8459 \n' + ' 0.000000+0 0.000000+0 0 0 12 39228 8459 \n' + ' 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8459 \n' + ' 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8459 \n' ) + + valid_TPID = 'Just a tape identifier \n' + valid_SEND = ' 9228 8 0 \n' + valid_FEND = ' 9228 0 0 \n' + valid_MEND = ' 0 0 0 \n' + valid_TEND = ' -1 0 0 \n' + invalid_SEND = ' 9228 8457 \n' + + def test_section( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( 459, chunk.MT ) + self.assertEqual( 459, chunk.section_number ) + + self.assertAlmostEqual( 92235., chunk.ZA ) + self.assertAlmostEqual( 233.0250, chunk.AWR ) + self.assertAlmostEqual( 233.0250, chunk.atomic_weight_ratio ) + + self.assertEqual( False, chunk.LE ) + self.assertEqual( False, chunk.is_energy_independent ) + + self.assertEqual( 2, chunk.NE ) + self.assertEqual( 2, len( chunk.E ) ) + self.assertEqual( 2, len( chunk.incident_energies ) ) + self.assertAlmostEqual( 0.0253, chunk.E[0] ) + self.assertAlmostEqual( 500e+3, chunk.E[1] ) + self.assertAlmostEqual( 0.0253, chunk.incident_energies[0] ) + self.assertAlmostEqual( 500e+3, chunk.incident_energies[1] ) + + self.assertEqual( 2, len( chunk.yields ) ) + + data = chunk.yields[0] + self.assertEqual( 1, data.I ) + self.assertEqual( 1, data.interpolation_type ) + self.assertEqual( False, data.LE ) + self.assertEqual( False, data.is_energy_independent ) + self.assertEqual( 3, data.NFP ) + self.assertEqual( 3, data.number_fission_products ) + self.assertAlmostEqual( 0.0253, data.E ) + self.assertAlmostEqual( 0.0253, data.incident_energy ) + + self.assertEqual( 3, len( data.ZAFP ) ) + self.assertEqual( 3, len( data.fission_product_identifiers ) ) + self.assertEqual( 3, len( data.FPS ) ) + self.assertEqual( 3, len( data.isomeric_states ) ) + self.assertEqual( 3, len( data.Y ) ) + self.assertEqual( 3, len( data.fission_yields ) ) + self.assertEqual( 23066, data.ZAFP[0] ); + self.assertEqual( 54135, data.ZAFP[1] ); + self.assertEqual( 72171, data.ZAFP[2] ); + self.assertEqual( 23066, data.fission_product_identifiers[0] ); + self.assertEqual( 54135, data.fission_product_identifiers[1] ); + self.assertEqual( 72171, data.fission_product_identifiers[2] ); + self.assertEqual( 0, data.FPS[0] ); + self.assertEqual( 0, data.FPS[1] ); + self.assertEqual( 0, data.FPS[2] ); + self.assertEqual( 0, data.isomeric_states[0] ); + self.assertEqual( 0, data.isomeric_states[1] ); + self.assertEqual( 0, data.isomeric_states[2] ); + self.assertEqual( 2, len( data.Y[0] ) ) + self.assertEqual( 2, len( data.Y[1] ) ) + self.assertEqual( 2, len( data.Y[2] ) ) + self.assertEqual( 2, len( data.fission_yields[0] ) ) + self.assertEqual( 2, len( data.fission_yields[1] ) ) + self.assertEqual( 2, len( data.fission_yields[2] ) ) + self.assertAlmostEqual( 2.05032e-19, data.Y[0][0] ) + self.assertAlmostEqual( 1.31220e-19, data.Y[0][1] ) + self.assertAlmostEqual( 7.851250e-4, data.Y[1][0] ) + self.assertAlmostEqual( 4.710750e-5, data.Y[1][1] ) + self.assertAlmostEqual( 0, data.Y[2][0] ) + self.assertAlmostEqual( 0, data.Y[2][1] ) + self.assertAlmostEqual( 2.05032e-19, data.fission_yields[0][0] ) + self.assertAlmostEqual( 1.31220e-19, data.fission_yields[0][1] ) + self.assertAlmostEqual( 7.851250e-4, data.fission_yields[1][0] ) + self.assertAlmostEqual( 4.710750e-5, data.fission_yields[1][1] ) + self.assertAlmostEqual( 0, data.fission_yields[2][0] ) + self.assertAlmostEqual( 0, data.fission_yields[2][1] ) + + data = chunk.yields[1] + self.assertEqual( 3, data.I ) + self.assertEqual( 3, data.interpolation_type ) + self.assertEqual( False, data.LE ) + self.assertEqual( False, data.is_energy_independent ) + self.assertEqual( 3, data.NFP ) + self.assertEqual( 3, data.number_fission_products ) + self.assertAlmostEqual( 500e+3, data.E ) + self.assertAlmostEqual( 500e+3, data.incident_energy ) + + self.assertEqual( 3, len( data.ZAFP ) ) + self.assertEqual( 3, len( data.fission_product_identifiers ) ) + self.assertEqual( 3, len( data.FPS ) ) + self.assertEqual( 3, len( data.isomeric_states ) ) + self.assertEqual( 3, len( data.Y ) ) + self.assertEqual( 3, len( data.fission_yields ) ) + self.assertEqual( 23066, data.ZAFP[0] ); + self.assertEqual( 54135, data.ZAFP[1] ); + self.assertEqual( 72171, data.ZAFP[2] ); + self.assertEqual( 23066, data.fission_product_identifiers[0] ); + self.assertEqual( 54135, data.fission_product_identifiers[1] ); + self.assertEqual( 72171, data.fission_product_identifiers[2] ); + self.assertEqual( 0, data.FPS[0] ); + self.assertEqual( 0, data.FPS[1] ); + self.assertEqual( 0, data.FPS[2] ); + self.assertEqual( 0, data.isomeric_states[0] ); + self.assertEqual( 0, data.isomeric_states[1] ); + self.assertEqual( 0, data.isomeric_states[2] ); + self.assertEqual( 2, len( data.Y[0] ) ) + self.assertEqual( 2, len( data.Y[1] ) ) + self.assertEqual( 2, len( data.Y[2] ) ) + self.assertEqual( 2, len( data.fission_yields[0] ) ) + self.assertEqual( 2, len( data.fission_yields[1] ) ) + self.assertEqual( 2, len( data.fission_yields[2] ) ) + self.assertAlmostEqual( 4.48456e-18, data.Y[0][0] ) + self.assertAlmostEqual( 2.87012e-18, data.Y[0][1] ) + self.assertAlmostEqual( 1.196100e-3, data.Y[1][0] ) + self.assertAlmostEqual( 2.751030e-4, data.Y[1][1] ) + self.assertAlmostEqual( 0, data.Y[2][0] ) + self.assertAlmostEqual( 0, data.Y[2][1] ) + self.assertAlmostEqual( 4.48456e-18, data.fission_yields[0][0] ) + self.assertAlmostEqual( 2.87012e-18, data.fission_yields[0][1] ) + self.assertAlmostEqual( 1.196100e-3, data.fission_yields[1][0] ) + self.assertAlmostEqual( 2.751030e-4, data.fission_yields[1][1] ) + self.assertAlmostEqual( 0, data.fission_yields[2][0] ) + self.assertAlmostEqual( 0, data.fission_yields[2][1] ) + + self.assertEqual( 7, chunk.NC ) + + # verify string + self.assertEqual( self.chunk + self.valid_SEND, + chunk.to_string( 9228, 8 ) ) + + def verify_chunk_energy_independent( self, chunk ) : + + self.assertEqual( 459, chunk.MT ) + self.assertEqual( 459, chunk.section_number ) + + self.assertAlmostEqual( 92235., chunk.ZA ) + self.assertAlmostEqual( 233.0250, chunk.AWR ) + self.assertAlmostEqual( 233.0250, chunk.atomic_weight_ratio ) + + self.assertEqual( True, chunk.LE ) + self.assertEqual( True, chunk.is_energy_independent ) + + self.assertEqual( 1, len( chunk.E ) ) + self.assertEqual( 1, len( chunk.incident_energies ) ) + self.assertAlmostEqual( 0., chunk.E[0] ) + self.assertAlmostEqual( 0., chunk.incident_energies[0] ) + + self.assertEqual( 1, len( chunk.yields ) ) + + data = chunk.yields[0] + self.assertEqual( 0, data.I ) + self.assertEqual( 0, data.interpolation_type ) + self.assertEqual( True, data.LE ) + self.assertEqual( True, data.is_energy_independent ) + self.assertEqual( 3, data.NFP ) + self.assertEqual( 3, data.number_fission_products ) + self.assertEqual( 0., data.E ) + self.assertEqual( 0., data.incident_energy ) + + self.assertEqual( 3, len( data.ZAFP ) ) + self.assertEqual( 3, len( data.fission_product_identifiers ) ) + self.assertEqual( 3, len( data.FPS ) ) + self.assertEqual( 3, len( data.isomeric_states ) ) + self.assertEqual( 3, len( data.Y ) ) + self.assertEqual( 3, len( data.fission_yields ) ) + self.assertEqual( 23066, data.ZAFP[0] ); + self.assertEqual( 54135, data.ZAFP[1] ); + self.assertEqual( 72171, data.ZAFP[2] ); + self.assertEqual( 23066, data.fission_product_identifiers[0] ); + self.assertEqual( 54135, data.fission_product_identifiers[1] ); + self.assertEqual( 72171, data.fission_product_identifiers[2] ); + self.assertEqual( 0, data.FPS[0] ); + self.assertEqual( 0, data.FPS[1] ); + self.assertEqual( 0, data.FPS[2] ); + self.assertEqual( 0, data.isomeric_states[0] ); + self.assertEqual( 0, data.isomeric_states[1] ); + self.assertEqual( 0, data.isomeric_states[2] ); + self.assertEqual( 2, len( data.Y[0] ) ) + self.assertEqual( 2, len( data.Y[1] ) ) + self.assertEqual( 2, len( data.Y[2] ) ) + self.assertEqual( 2, len( data.fission_yields[0] ) ) + self.assertEqual( 2, len( data.fission_yields[1] ) ) + self.assertEqual( 2, len( data.fission_yields[2] ) ) + self.assertAlmostEqual( 2.05032e-19, data.Y[0][0] ) + self.assertAlmostEqual( 1.31220e-19, data.Y[0][1] ) + self.assertAlmostEqual( 7.851250e-4, data.Y[1][0] ) + self.assertAlmostEqual( 4.710750e-5, data.Y[1][1] ) + self.assertAlmostEqual( 0, data.Y[2][0] ) + self.assertAlmostEqual( 0, data.Y[2][1] ) + self.assertAlmostEqual( 2.05032e-19, data.fission_yields[0][0] ) + self.assertAlmostEqual( 1.31220e-19, data.fission_yields[0][1] ) + self.assertAlmostEqual( 7.851250e-4, data.fission_yields[1][0] ) + self.assertAlmostEqual( 4.710750e-5, data.fission_yields[1][1] ) + self.assertAlmostEqual( 0, data.fission_yields[2][0] ) + self.assertAlmostEqual( 0, data.fission_yields[2][1] ) + + self.assertEqual( 4, chunk.NC ) + + # verify string + self.assertEqual( self.chunk_energy_independent + self.valid_SEND, + chunk.to_string( 9228, 8 ) ) + + # the data is given explicitly + chunk = Section( zaid = 92235., awr = 233.0250, + identifiers = [ 23066, 54135, 72171 ], + states = [ 0, 0, 0 ], + energies = [ 0.0253, 500e+3 ], + interpolants = [ 3 ], + yields = [ [ [ 2.05032e-19, 1.31220e-19 ], [ 4.48456e-18, 2.87012e-18 ] ], + [ [ 7.851250e-4, 4.710750e-5 ], [ 1.196100e-3, 2.751030e-4 ] ], + [ [ 0, 0 ], [ 0, 0 ] ] ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk + self.valid_SEND ) + + verify_chunk( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 8 ).section( 459 ).parse() + + verify_chunk( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk( self, copy ) + + # the data is given explicitly as a FissionYieldData array + chunk = Section( zaid = 92235., awr = 233.0250, + yields = [ FissionYieldData( [ 23066, 54135, 72171 ], [ 0, 0, 0 ], + [ [ 2.05032e-19, 1.31220e-19 ], + [ 7.851250e-4, 4.710750e-5 ], + [ 0, 0 ] ], + 0.0253, 1 ), + FissionYieldData( [ 23066, 54135, 72171 ], [ 0, 0, 0 ], + [ [ 4.48456e-18, 2.87012e-18 ], + [ 1.196100e-3, 2.751030e-4 ], + [ 0, 0 ] ], + 500e+3, 3 ) ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk + self.valid_SEND ) + + verify_chunk( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 8 ).section( 459 ).parse() + + verify_chunk( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk( self, copy ) + + # the data is given explicitly for energy independent yields + chunk = Section( zaid = 92235., awr = 233.0250, + identifiers = [ 23066, 54135, 72171 ], + states = [ 0, 0, 0 ], + yields = [ [ 2.05032e-19, 1.31220e-19 ], + [ 7.851250e-4, 4.710750e-5 ], + [ 0, 0 ] ] ) + + verify_chunk_energy_independent( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk_energy_independent + self.valid_SEND ) + + verify_chunk_energy_independent( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk_energy_independent + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9228 ).file( 8 ).section( 459 ).parse() + + verify_chunk_energy_independent( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk_energy_independent( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # illegal SEND + with self.assertRaises( Exception ) : + + chunk = Section.from_string( self.chunk + self.invalid_SEND ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF9_ReactionProduct.py b/python/test/Test_ENDFtk_MF9_ReactionProduct.py new file mode 100644 index 000000000..f6648bdef --- /dev/null +++ b/python/test/Test_ENDFtk_MF9_ReactionProduct.py @@ -0,0 +1,96 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF9 import ReactionProduct + +class Test_ENDFtk_MF9_ReactionProduct( unittest.TestCase ) : + """Unit test for the ReactionProduct class.""" + + chunk = ( ' 2.224648+6 3.224648+6 95242 2 1 29534 9102 \n' + ' 2 5 9534 9102 \n' + ' 1.000000+0 2.000000+0 3.000000+0 4.000000+0 9534 9102 \n' ) + + invalid = ( ' 2.224648+6 3.224648+6 95242 2 2 29534 9102 \n' + ' 2 2 9534 9102 \n' + ' 1.000000-5 8.579050+0 3.000000+7 1.487778+1 9534 9102 \n' ) + + def test_component( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertAlmostEqual( 2.224648e+6, chunk.QM ) + self.assertAlmostEqual( 2.224648e+6, chunk.mass_difference_qvalue ) + self.assertAlmostEqual( 3.224648e+6, chunk.QI ) + self.assertAlmostEqual( 3.224648e+6, chunk.reaction_qvalue ) + self.assertEqual( 95242, chunk.IZAP ) + self.assertEqual( 95242, chunk.product_identifier ) + self.assertEqual( 2, chunk.LFS ) + self.assertEqual( 2, chunk.excited_level ) + + self.assertEqual( 2, chunk.NP ) + self.assertEqual( 1, chunk.NR ) + self.assertEqual( 1, len( chunk.interpolants ) ) + self.assertEqual( 1, len( chunk.boundaries ) ) + self.assertEqual( 5, chunk.interpolants[0] ) + self.assertEqual( 2, chunk.boundaries[0] ) + self.assertEqual( 2, len( chunk.E ) ) + self.assertEqual( 2, len( chunk.energies ) ) + self.assertEqual( 2, len( chunk.Y ) ) + self.assertEqual( 2, len( chunk.multiplicities ) ) + self.assertAlmostEqual( 1., chunk.E[0] ) + self.assertAlmostEqual( 3., chunk.E[1] ) + self.assertAlmostEqual( 1., chunk.energies[0] ) + self.assertAlmostEqual( 3., chunk.energies[1] ) + self.assertAlmostEqual( 2., chunk.Y[0] ) + self.assertAlmostEqual( 4., chunk.Y[1] ) + self.assertAlmostEqual( 2., chunk.multiplicities[0] ) + self.assertAlmostEqual( 4., chunk.multiplicities[1] ) + + self.assertEqual( 3, chunk.NC ) + + # verify string + self.assertEqual( self.chunk, chunk.to_string( 9534, 9, 102 ) ) + + # the data is given explicitly + chunk = ReactionProduct( qm = 2.224648e+6, qi = 3.224648e+6, + izap = 95242, lfs = 2, + boundaries = [ 2 ], + interpolants = [ 5 ], + energies = [ 1., 3. ], + multiplicities = [ 2., 4. ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = ReactionProduct.from_string( self.chunk, 9534, 9, 102 ) + + verify_chunk( self, chunk ) + + # the data is copied + copy = ReactionProduct( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # wrong boundaries + with self.assertRaises( Exception ) : + + chunk = ReactionProduct( qm = 2.224648e+6, qi = 3.224648e+6, + izap = 95242, lfs = 2, + boundaries = [ 2 ], interpolants = [ 5, 2 ], + energies = [ 1., 3. ], multiplicities = [ 2., 4. ] ) + + with self.assertRaises( Exception ) : + + chunk = ReactionProduct.from_string( self.invalid, 9534, 9, 102 ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/python/test/Test_ENDFtk_MF9_Section.py b/python/test/Test_ENDFtk_MF9_Section.py new file mode 100644 index 000000000..2e53997c4 --- /dev/null +++ b/python/test/Test_ENDFtk_MF9_Section.py @@ -0,0 +1,146 @@ +# standard imports +import unittest + +# third party imports + +# local imports +from ENDFtk.MF9 import Section +from ENDFtk.MF9 import ReactionProduct +from ENDFtk.tree import Tape + +class Test_ENDFtk_MF9_Section( unittest.TestCase ) : + """Unit test for the Section class.""" + + chunk = ( ' 9.524100+4 2.389860+2 0 0 2 09543 9102 \n' + ' 5.537755+6 5.537755+6 95242 0 1 29543 9102 \n' + ' 2 3 9543 9102 \n' + ' 1.000000-5 9.000000-1 3.000000+7 5.200000-1 9543 9102 \n' + ' 5.537755+6 5.489125+6 95242 2 1 29543 9102 \n' + ' 2 3 9543 9102 \n' + ' 1.000000-5 1.000000-1 3.000000+7 4.800000-1 9543 9102 \n' ) + + valid_TPID = 'Just a tape identifier \n' + valid_SEND = ' 9543 9 0 \n' + valid_FEND = ' 9543 0 0 \n' + valid_MEND = ' 0 0 0 \n' + valid_TEND = ' -1 0 0 \n' + invalid_SEND = ' 9543 9 1 \n' + + def test_section( self ) : + + def verify_chunk( self, chunk ) : + + # verify content + self.assertEqual( 102, chunk.MT ) + self.assertEqual( 95241, chunk.ZA ) + self.assertAlmostEqual( 2.389860e+2, chunk.AWR ) + self.assertAlmostEqual( 2.389860e+2, chunk.atomic_weight_ratio ) + self.assertEqual( 0, chunk.LIS ) + self.assertEqual( 0, chunk.excited_level ) + self.assertEqual( 2, chunk.NS ) + self.assertEqual( 2, chunk.number_reaction_products ) + + self.assertEqual( 2, len( chunk.reaction_products ) ) + + product = chunk.reaction_products[0] + self.assertAlmostEqual( 5.537755e+6, product.QM ) + self.assertAlmostEqual( 5.537755e+6, product.mass_difference_qvalue ) + self.assertAlmostEqual( 5.537755e+6, product.QI ) + self.assertAlmostEqual( 5.537755e+6, product.reaction_qvalue ) + self.assertEqual( 95242, product.IZAP ) + self.assertEqual( 95242, product.product_identifier ) + self.assertEqual( 0, product.LFS ) + self.assertEqual( 0, product.excited_level ) + self.assertEqual( 2, product.NP ) + self.assertEqual( 1, product.NR ) + self.assertEqual( 1, len( product.interpolants ) ) + self.assertEqual( 1, len( product.boundaries ) ) + self.assertEqual( 3, product.interpolants[0] ) + self.assertEqual( 2, product.boundaries[0] ) + self.assertEqual( 2, len( product.E ) ) + self.assertEqual( 2, len( product.energies ) ) + self.assertEqual( 2, len( product.Y ) ) + self.assertEqual( 2, len( product.multiplicities ) ) + self.assertAlmostEqual( 1e-5, product.E[0] ) + self.assertAlmostEqual( 3e+7, product.E[1] ) + self.assertAlmostEqual( 1e-5, product.energies[0] ) + self.assertAlmostEqual( 3e+7, product.energies[1] ) + self.assertAlmostEqual( 0.9, product.Y[0] ) + self.assertAlmostEqual( 0.52, product.Y[1] ) + self.assertAlmostEqual( 0.9, product.multiplicities[0] ) + self.assertAlmostEqual( 0.52, product.multiplicities[1] ) + + product = chunk.reaction_products[1] + self.assertAlmostEqual( 5.537755e+6, product.QM ) + self.assertAlmostEqual( 5.537755e+6, product.mass_difference_qvalue ) + self.assertAlmostEqual( 5.489125e+6, product.QI ) + self.assertAlmostEqual( 5.489125e+6, product.reaction_qvalue ) + self.assertEqual( 95242, product.IZAP ) + self.assertEqual( 95242, product.product_identifier ) + self.assertEqual( 2, product.LFS ) + self.assertEqual( 2, product.excited_level ) + self.assertEqual( 2, product.NP ) + self.assertEqual( 1, product.NR ) + self.assertEqual( 1, len( product.interpolants ) ) + self.assertEqual( 1, len( product.boundaries ) ) + self.assertEqual( 3, product.interpolants[0] ) + self.assertEqual( 2, product.boundaries[0] ) + self.assertEqual( 2, len( product.E ) ) + self.assertEqual( 2, len( product.energies ) ) + self.assertEqual( 2, len( product.Y ) ) + self.assertEqual( 2, len( product.multiplicities ) ) + self.assertAlmostEqual( 1e-5, product.E[0] ) + self.assertAlmostEqual( 3e+7, product.E[1] ) + self.assertAlmostEqual( 1e-5, product.energies[0] ) + self.assertAlmostEqual( 3e+7, product.energies[1] ) + self.assertAlmostEqual( 0.1, product.Y[0] ) + self.assertAlmostEqual( 0.48, product.Y[1] ) + self.assertAlmostEqual( 0.1, product.multiplicities[0] ) + self.assertAlmostEqual( 0.48, product.multiplicities[1] ) + + self.assertEqual( 7, chunk.NC ) + + # verify string + self.assertEqual( self.chunk + self.valid_SEND, + chunk.to_string( 9543, 9 ) ) + + # the data is given explicitly + chunk = Section( mt = 102, zaid = 95241, lis = 0, awr = 2.389860e+2, + products = [ + ReactionProduct( 5.537755e+6, 5.537755e+6, 95242, 0, + [ 2 ], [ 3 ], [ 1e-5, 3e+7 ], [ 0.9, 0.52 ] ), + ReactionProduct( 5.537755e+6, 5.489125e+6, 95242, 2, + [ 2 ], [ 3 ], [ 1e-5, 3e+7 ], [ 0.1, 0.48 ] ) ] ) + + verify_chunk( self, chunk ) + + # the data is read from a string + chunk = Section.from_string( self.chunk + self.valid_SEND ) + + verify_chunk( self, chunk ) + + # the data is retrieved from a tree element and parsed + tape = Tape.from_string( self.valid_TPID + self.chunk + + self.valid_SEND + self.valid_FEND + + self.valid_MEND + self.valid_TEND ) + chunk = tape.material( 9543 ).file( 9 ).section( 102 ).parse() + + verify_chunk( self, chunk ) + + # the data is copied + copy = Section( chunk ) + + verify_chunk( self, copy ) + + def test_failures( self ) : + + print( '\n' ) + + # illegal SEND + with self.assertRaises( Exception ) : + + chunk = Section.from_string( self.chunk + self.invalid_SEND ) + +if __name__ == '__main__' : + + unittest.main() diff --git a/src/ENDFtk/InterpolationRecord/test/InterpolationRecord.test.cpp b/src/ENDFtk/InterpolationRecord/test/InterpolationRecord.test.cpp index 10b473899..636227c49 100644 --- a/src/ENDFtk/InterpolationRecord/test/InterpolationRecord.test.cpp +++ b/src/ENDFtk/InterpolationRecord/test/InterpolationRecord.test.cpp @@ -4,7 +4,7 @@ #include "ENDFtk/InterpolationRecord.hpp" // other includes -#include "range/v3/at.hpp" +#include "range/v3/range/operations.hpp" #include "header-utilities/copy.hpp" // convenience typedefs diff --git a/src/ENDFtk/InterpolationSequenceRecord.hpp b/src/ENDFtk/InterpolationSequenceRecord.hpp index db51bb86c..e93de5dcd 100644 --- a/src/ENDFtk/InterpolationSequenceRecord.hpp +++ b/src/ENDFtk/InterpolationSequenceRecord.hpp @@ -129,7 +129,7 @@ namespace ENDFtk { */ AllRange< Component > records() const { - return ranges::view::all( this->sequence_ ); + return ranges::cpp20::views::all( this->sequence_ ); } #include "ENDFtk/InterpolationSequenceRecord/src/NC.hpp" diff --git a/src/ENDFtk/ListRecord.hpp b/src/ENDFtk/ListRecord.hpp index 3595a56c8..92993f6bb 100644 --- a/src/ENDFtk/ListRecord.hpp +++ b/src/ENDFtk/ListRecord.hpp @@ -120,12 +120,15 @@ namespace ENDFtk { /** * @brief Return the list of values */ - DoubleRange list() const { return ranges::view::all( this->data ); } + AllRange< double > list() const { + + return ranges::cpp20::views::all( this->data ); + } /** * @brief Return the list of values */ - DoubleRange B() const { return this->list(); } + AllRange< double > B() const { return this->list(); } /** * @brief Equality operator diff --git a/src/ENDFtk/Material.hpp b/src/ENDFtk/Material.hpp index b3448ccf6..0d70f4664 100644 --- a/src/ENDFtk/Material.hpp +++ b/src/ENDFtk/Material.hpp @@ -43,12 +43,12 @@ namespace ENDFtk { // all other files are optional static constexpr auto optionalFiles() RANGES_DECLTYPE_AUTO_RETURN( hana::make_tuple( 2_c, 3_c, 4_c, 5_c, 6_c, - 7_c, 8_c, 12_c, 13_c ) ) + 7_c, 8_c, 9_c, 10_c, + 12_c, 13_c, 14_c, 15_c ) ) // the following files are currently unimplemented static constexpr auto unimplementedFiles() - RANGES_DECLTYPE_AUTO_RETURN( hana::make_tuple( 9_c, 10_c, 14_c, 15_c, - 23_c, 26_c, 27_c, 28_c, + RANGES_DECLTYPE_AUTO_RETURN( hana::make_tuple( 23_c, 26_c, 27_c, 28_c, 30_c, 31_c, 32_c, 33_c, 34_c, 35_c, 40_c ) ) diff --git a/src/ENDFtk/TabulationRecord.hpp b/src/ENDFtk/TabulationRecord.hpp index 62b9e3015..cd96db67c 100644 --- a/src/ENDFtk/TabulationRecord.hpp +++ b/src/ENDFtk/TabulationRecord.hpp @@ -7,6 +7,7 @@ // other includes #include "range/v3/view/all.hpp" #include "range/v3/view/iota.hpp" +#include "range/v3/view/subrange.hpp" #include "range/v3/view/transform.hpp" #include "range/v3/view/zip.hpp" #include "ENDFtk/types.hpp" @@ -43,10 +44,10 @@ namespace ENDFtk { const auto left = index ? this->boundaries()[ index - 1 ] - 1 : 0; const auto right = this->boundaries()[ index ]; return - std::make_pair( ranges::make_iterator_range + std::make_pair( ranges::make_subrange ( this->xValues.begin() + left, this->xValues.begin() + right ), - ranges::make_iterator_range + ranges::make_subrange ( this->yValues.begin() + left, this->yValues.begin() + right ) ); } @@ -72,19 +73,25 @@ namespace ENDFtk { /** * @brief Return the x values in the table */ - DoubleRange x() const { return ranges::view::all( this->xValues ); } + AllRange< double > x() const { + + return ranges::cpp20::views::all( this->xValues ); + } /** * @brief Return the y values in the table */ - DoubleRange y() const { return ranges::view::all( this->yValues ); } + AllRange< double > y() const { + + return ranges::cpp20::views::all( this->yValues ); + } /** * @brief Return the x,y pairs in the table */ auto pairs() const { - return ranges::view::zip( this->xValues, this->yValues ); + return ranges::views::zip( this->xValues, this->yValues ); } using InterpolationBase::interpolants; @@ -96,8 +103,9 @@ namespace ENDFtk { auto regions() const { return - ranges::view::iota( 0ul, this->boundaries().size() ) - | ranges::view::transform( [this ]( int i ){ return this->regions(i); } ); + ranges::views::iota( 0ul, this->boundaries().size() ) + | ranges::cpp20::views::transform( + [this ]( int i ){ return this->regions(i); } ); } /** diff --git a/src/ENDFtk/TabulationRecord/test/TabulationRecord.test.cpp b/src/ENDFtk/TabulationRecord/test/TabulationRecord.test.cpp index 0e87b6156..6fbcf8a42 100644 --- a/src/ENDFtk/TabulationRecord/test/TabulationRecord.test.cpp +++ b/src/ENDFtk/TabulationRecord/test/TabulationRecord.test.cpp @@ -4,8 +4,8 @@ #include "ENDFtk/TabulationRecord.hpp" // other includes -#include "range/v3/at.hpp" #include "range/v3/algorithm/equal.hpp" +#include "range/v3/range/operations.hpp" #include "header-utilities/copy.hpp" // convenience typedefs diff --git a/src/ENDFtk/TabulationRecord/test/pairs.test.hpp b/src/ENDFtk/TabulationRecord/test/pairs.test.hpp index 844146943..4e91fa258 100644 --- a/src/ENDFtk/TabulationRecord/test/pairs.test.hpp +++ b/src/ENDFtk/TabulationRecord/test/pairs.test.hpp @@ -34,11 +34,11 @@ SCENARIO( "TabulationRecord pairs", auto pairs = tab1.pairs(); // this zipped view is a bit expensive (5 doubles), but lives on the stack - REQUIRE( sizeof( pairs ) == 40 ); + REQUIRE( sizeof( pairs ) == 24 ); // so copying them isn't the end of the world auto pairs2 = pairs; - REQUIRE( ranges::equal( pairs2, pairs ) ); + REQUIRE( ranges::cpp20::equal( pairs2, pairs ) ); } } } diff --git a/src/ENDFtk/TabulationRecord/test/regions.test.hpp b/src/ENDFtk/TabulationRecord/test/regions.test.hpp index 184ed58c6..964ba4394 100644 --- a/src/ENDFtk/TabulationRecord/test/regions.test.hpp +++ b/src/ENDFtk/TabulationRecord/test/regions.test.hpp @@ -14,17 +14,17 @@ SCENARIO( "TabulationRecord regions", "[ENDFtk], [TabulationRecord]" ){ // regions are iterable int index = 0; for ( auto region : tab1.regions() ){ - ranges::equal( region.first, xValues[index] ); - ranges::equal( region.second, yValues[index++] ); + ranges::cpp20::equal( region.first, xValues[index] ); + ranges::cpp20::equal( region.second, yValues[index++] ); } // regions are indexible, with and without bound checking auto regions = tab1.regions(); for ( size_t index = 0; index < size_t(tab1.NR()); ++index ){ - ranges::equal( regions.at(index).first, xValues[index] ); - ranges::equal( regions[index].first, xValues[index] ); - ranges::equal( regions.at(index).second, yValues[index] ); - ranges::equal( regions[index].second, yValues[index] ); + ranges::cpp20::equal( regions.at(index).first, xValues[index] ); + ranges::cpp20::equal( regions[index].first, xValues[index] ); + ranges::cpp20::equal( regions.at(index).second, yValues[index] ); + ranges::cpp20::equal( regions[index].second, yValues[index] ); } REQUIRE_THROWS( tab1.regions().at( -1 ) ); REQUIRE_THROWS( tab1.regions().at( tab1.NR() ) ); @@ -35,6 +35,6 @@ SCENARIO( "TabulationRecord regions", "[ENDFtk], [TabulationRecord]" ){ // + doesn't require a heap allocation // + and is only modestly sized (the same as an array of 6 doubles). - REQUIRE( sizeof( tab1.regions() ) == 48 ); + REQUIRE( sizeof( tab1.regions() ) == 40 ); } diff --git a/src/ENDFtk/TabulationRecord/test/x.test.hpp b/src/ENDFtk/TabulationRecord/test/x.test.hpp index e048ae17a..e7cae82d0 100644 --- a/src/ENDFtk/TabulationRecord/test/x.test.hpp +++ b/src/ENDFtk/TabulationRecord/test/x.test.hpp @@ -33,11 +33,11 @@ SCENARIO( "TabulationRecord x command", auto xs = tab1.x(); // because they don't own data, views are small and live on the stack - REQUIRE( sizeof( xs ) == 16 ); + REQUIRE( sizeof( xs ) == 8 ); // so we can copy them willy-nilly auto xs2 = xs; - REQUIRE( ranges::equal( xs2, xs ) ); + REQUIRE( ranges::cpp20::equal( xs2, xs ) ); // no more worrying about accidentally copying large vectors! } diff --git a/src/ENDFtk/TabulationRecord/test/y.test.hpp b/src/ENDFtk/TabulationRecord/test/y.test.hpp index a045e90cc..70f36d281 100644 --- a/src/ENDFtk/TabulationRecord/test/y.test.hpp +++ b/src/ENDFtk/TabulationRecord/test/y.test.hpp @@ -32,11 +32,11 @@ SCENARIO( "TabulationRecord yValue", auto ys = tab1.y(); // because they don't own data, views are small and live on the stack - REQUIRE( sizeof( ys ) == 16 ); + REQUIRE( sizeof( ys ) == 8 ); // so we can copy them willy-nilly auto ys2 = ys; - REQUIRE( ranges::equal( ys2, ys ) ); + REQUIRE( ranges::cpp20::equal( ys2, ys ) ); // no more worrying about accidentally copying large vectors! } diff --git a/src/ENDFtk/Tape.hpp b/src/ENDFtk/Tape.hpp index cbe7f42a5..be64eddf7 100644 --- a/src/ENDFtk/Tape.hpp +++ b/src/ENDFtk/Tape.hpp @@ -6,7 +6,7 @@ // other includes #include "range/v3/view/all.hpp" #include "range/v3/view/filter.hpp" -#include "range/v3/distance.hpp" +#include "range/v3/iterator/operations.hpp" #include "ENDFtk/TapeIdentification.hpp" #include "ENDFtk/Material.hpp" @@ -42,12 +42,15 @@ namespace ENDFtk { /** * @brief Return the materials stored in this file */ - auto materials() { return ranges::view::all( this->materials_ ); } + auto materials() { return ranges::cpp20::views::all( this->materials_ ); } /** * @brief Return the materials stored in this file */ - auto materials() const { return ranges::view::all( this->materials_ ); } + auto materials() const { + + return ranges::cpp20::views::all( this->materials_ ); + } /** * @brief Return an iterator to the start of the materials @@ -77,7 +80,7 @@ namespace ENDFtk { auto MAT( int mat ) const { return this->materials_ - | ranges::view::filter( + | ranges::cpp20::views::filter( [mat] ( const auto& material ) { return material.MAT() == mat; } ); } @@ -97,7 +100,7 @@ namespace ENDFtk { */ bool hasMAT( int mat ) const { - return ranges::distance( this->material( mat ) ) > 0; + return ranges::cpp20::distance( this->material( mat ) ) > 0; } /** diff --git a/src/ENDFtk/file/1/test/1.test.cpp b/src/ENDFtk/file/1/test/1.test.cpp index b46c34e1d..a81e9846f 100644 --- a/src/ENDFtk/file/1/test/1.test.cpp +++ b/src/ENDFtk/file/1/test/1.test.cpp @@ -48,7 +48,7 @@ SCENARIO( "Testing special case of file 1" ) { "-----INCIDENT NEUTRON DATA \n" "------ENDF-6 FORMAT \n" "*************************************************** \n"; - int nc = 4 + ranges::count( description, '\n' ) + 2; + int nc = 4 + ranges::cpp20::count( description, '\n' ) + 2; WHEN( "a file::Type< 1 > is constructed using only mt451" ) { diff --git a/src/ENDFtk/file/10.hpp b/src/ENDFtk/file/10.hpp index 7bb26c276..baebbc861 100644 --- a/src/ENDFtk/file/10.hpp +++ b/src/ENDFtk/file/10.hpp @@ -1,41 +1,2 @@ -#ifndef NJOY_ENDFTK_FILE_10 -#define NJOY_ENDFTK_FILE_10 - -// system includes - -// other includes -#include "ENDFtk/file/NotImplementedYet.hpp" - -namespace njoy { -namespace ENDFtk { -namespace file { - - template<> - class Type< 10 > : public NotImplementedYet< Type< 10 > > { - - friend NotImplementedYet< Type< 10 > >; - - public: - - Type() : NotImplementedYet() {} - template< typename BufferIterator > - Type( StructureDivision& division, - BufferIterator& begin, const BufferIterator& end, - long& lineNumber ) : - NotImplementedYet( division, begin, end, - lineNumber ) {} - - /** - * @brief Return the MF number of the section - */ - static constexpr int fileNumber() { return 10; } - - using NotImplementedYet::MF; - using NotImplementedYet::print; - }; - -} // file namespace -} // ENDFtk namespace -} // njoy namespace - -#endif +#include "ENDFtk/section/10.hpp" +#include "ENDFtk/file/Type.hpp" diff --git a/src/ENDFtk/file/14.hpp b/src/ENDFtk/file/14.hpp index e1a8a6b5e..fa62fd670 100644 --- a/src/ENDFtk/file/14.hpp +++ b/src/ENDFtk/file/14.hpp @@ -1,41 +1,2 @@ -#ifndef NJOY_ENDFTK_FILE_14 -#define NJOY_ENDFTK_FILE_14 - -// system includes - -// other includes -#include "ENDFtk/file/NotImplementedYet.hpp" - -namespace njoy { -namespace ENDFtk { -namespace file { - - template<> - class Type< 14 > : public NotImplementedYet< Type< 14 > > { - - friend NotImplementedYet< Type< 14 > >; - - public: - - Type() : NotImplementedYet() {} - template< typename BufferIterator > - Type( StructureDivision& division, - BufferIterator& begin, const BufferIterator& end, - long& lineNumber ) : - NotImplementedYet( division, begin, end, - lineNumber ) {} - - /** - * @brief Return the MF number of the section - */ - static constexpr int fileNumber() { return 14; } - - using NotImplementedYet::MF; - using NotImplementedYet::print; - }; - -} // file namespace -} // ENDFtk namespace -} // njoy namespace - -#endif +#include "ENDFtk/section/14.hpp" +#include "ENDFtk/file/Type.hpp" diff --git a/src/ENDFtk/file/15.hpp b/src/ENDFtk/file/15.hpp index f3cbd0035..3091de1f4 100644 --- a/src/ENDFtk/file/15.hpp +++ b/src/ENDFtk/file/15.hpp @@ -1,41 +1,2 @@ -#ifndef NJOY_ENDFTK_FILE_15 -#define NJOY_ENDFTK_FILE_15 - -// system includes - -// other includes -#include "ENDFtk/file/NotImplementedYet.hpp" - -namespace njoy { -namespace ENDFtk { -namespace file { - - template<> - class Type< 15 > : public NotImplementedYet< Type< 15 > > { - - friend NotImplementedYet< Type< 15 > >; - - public: - - Type() : NotImplementedYet() {} - template< typename BufferIterator > - Type( StructureDivision& division, - BufferIterator& begin, const BufferIterator& end, - long& lineNumber ) : - NotImplementedYet( division, begin, end, - lineNumber ) {} - - /** - * @brief Return the MF number of the section - */ - static constexpr int fileNumber() { return 15; } - - using NotImplementedYet::MF; - using NotImplementedYet::print; - }; - -} // file namespace -} // ENDFtk namespace -} // njoy namespace - -#endif +#include "ENDFtk/section/15.hpp" +#include "ENDFtk/file/Type.hpp" diff --git a/src/ENDFtk/file/8.hpp b/src/ENDFtk/file/8.hpp index 1b52492ed..a50432847 100644 --- a/src/ENDFtk/file/8.hpp +++ b/src/ENDFtk/file/8.hpp @@ -28,18 +28,17 @@ namespace file { // MT454, MT457 and MT459 are optional static constexpr auto optionalSections() - RANGES_DECLTYPE_AUTO_RETURN( hana::make_tuple( 457_c ) ) + RANGES_DECLTYPE_AUTO_RETURN( hana::make_tuple( 454_c, 457_c, 459_c ) ) // the following sections are currently unimplemented static constexpr auto unimplementedSections() - RANGES_DECLTYPE_AUTO_RETURN( hana::make_tuple( 454_c, 459_c ) ) + RANGES_DECLTYPE_AUTO_RETURN( hana::make_tuple() ) using Map = typename decltype( details::deduceMapType( 8_c, requiredSections(), - hana::concat( optionalSections(), - unimplementedSections() ) ) )::type; + optionalSections() ) )::type; /* fields */ Map sectionMap; diff --git a/src/ENDFtk/file/9.hpp b/src/ENDFtk/file/9.hpp index d2f8d0800..cd2309227 100644 --- a/src/ENDFtk/file/9.hpp +++ b/src/ENDFtk/file/9.hpp @@ -1,41 +1,2 @@ -#ifndef NJOY_ENDFTK_FILE_9 -#define NJOY_ENDFTK_FILE_9 - -// system includes - -// other includes -#include "ENDFtk/file/NotImplementedYet.hpp" - -namespace njoy { -namespace ENDFtk { -namespace file { - - template<> - class Type< 9 > : public NotImplementedYet< Type< 9 > > { - - friend NotImplementedYet< Type< 9 > >; - - public: - - Type() : NotImplementedYet() {} - template< typename BufferIterator > - Type( StructureDivision& division, - BufferIterator& begin, const BufferIterator& end, - long& lineNumber ) : - NotImplementedYet( division, begin, end, - lineNumber ) {} - - /** - * @brief Return the MF number of the section - */ - static constexpr int fileNumber() { return 9; } - - using NotImplementedYet::MF; - using NotImplementedYet::print; - }; - -} // file namespace -} // ENDFtk namespace -} // njoy namespace - -#endif +#include "ENDFtk/section/9.hpp" +#include "ENDFtk/file/Type.hpp" diff --git a/src/ENDFtk/file/Type.hpp b/src/ENDFtk/file/Type.hpp index 31a2512c7..e2c40d980 100644 --- a/src/ENDFtk/file/Type.hpp +++ b/src/ENDFtk/file/Type.hpp @@ -5,7 +5,6 @@ #include // other includes -#include "range/v3/front.hpp" #include "range/v3/view/map.hpp" #include "ENDFtk/section.hpp" #include "ENDFtk/file/Base.hpp" @@ -46,12 +45,18 @@ namespace file { /** * @brief Return the sections stored in this file */ - auto sections() { return this->sectionMap | ranges::view::values; } + auto sections() { + + return this->sectionMap | ranges::cpp20::views::values; + } /** * @brief Return the sections stored in this file */ - auto sections() const { return this->sectionMap | ranges::view::values; } + auto sections() const { + + return this->sectionMap | ranges::cpp20::views::values; + } /** * @brief Return an iterator to the start of the sections diff --git a/src/ENDFtk/file/Type/test/Type.test.cpp b/src/ENDFtk/file/Type/test/Type.test.cpp index 5a0348461..5ed6b4fbf 100755 --- a/src/ENDFtk/file/Type/test/Type.test.cpp +++ b/src/ENDFtk/file/Type/test/Type.test.cpp @@ -5,7 +5,7 @@ #include "ENDFtk/file/Type.hpp" // other includes -#include "range/v3/to_container.hpp" +#include "range/v3/range/conversion.hpp" #include "range/v3/view/reverse.hpp" #include "ENDFtk/tree/File.hpp" @@ -30,7 +30,7 @@ SCENARIO( "Testing generic case using file 3" ) { { 2l }, { 2l }, { 1e-5, 2e+7 }, { 20.43634, 0.4827462 } }, { 102, 1001., 0.9991673, 2.224631e+6, 2.224631e+6, 0, { 2l }, { 5l }, { 1e-5, 2e+7 }, { 16.69994, 2.722354e-5 } } }; - auto unsorted = sorted | ranges::view::reverse | ranges::to_vector; + auto unsorted = sorted | ranges::cpp20::views::reverse | ranges::to_vector; WHEN( "a file::Type<3> is constructed from a sorted vector" ) { diff --git a/src/ENDFtk/gendf/CrossSection.hpp b/src/ENDFtk/gendf/CrossSection.hpp new file mode 100644 index 000000000..37c350b50 --- /dev/null +++ b/src/ENDFtk/gendf/CrossSection.hpp @@ -0,0 +1,166 @@ +#ifndef NJOY_ENDFTK_GENDF_CROSSSECTION +#define NJOY_ENDFTK_GENDF_CROSSSECTION + +// system includes + +// other includes +#include "ENDFtk/gendf/SectionBase.hpp" +// #include "range/v3/action.hpp" + +namespace njoy { +namespace ENDFtk { +namespace gendf { + + class CrossSection : protected SectionBase { + + protected: + + /* constructor */ + #include "ENDFtk/gendf/CrossSection/src/ctor.hpp" + + public: + + /* convenience functions */ + + # include "ENDFtk/gendf/CrossSection/src/makeDataRecord.hpp" + + /** + * @brief Return a list of fluxes for each group. + * + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + auto fluxes( unsigned int order, unsigned int dilution ) const { + + checkBounds( order, dilution ); + return ranges::view::iota( 1, this->num_groups_+1 ) + | ranges::view::transform( + [=] ( unsigned int group ) -> double + { return getValue( 0, group, order, dilution ); } ); + } + + /** + * @brief Return a list of fluxes for each group. + * + * @note Assumes order=0. Most CrossSections in a GENDF have NL=1. + * + * @param[in] dilution the index of the dilution + */ + auto fluxes( unsigned int dilution ) const { return fluxes( 0, dilution ); } + + /** + * @brief Return the flux for a given energy group. + * + * @param[in] group the energy group index + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + double flux( unsigned int group, unsigned int order, + unsigned int dilution ) const { + + checkBounds( group, order, dilution ); + return this->getValue( 0, group, order, dilution ); + } + + /** + * @brief Return the flux for a given energy group. + * + * @param[in] group the energy group index + * @param[in] dilution the index of the dilution + */ + double flux( unsigned int group, unsigned int dilution ) const { + return flux( group, 0, dilution ); + } + + /** + * @brief Return the flux for a given energy group. + * + * @param[in] group the energy group index + */ + double flux( unsigned int group ) const { return flux( group, 0, 0 ); } + + /** + * @brief Return a list of cross sections for each group. + * + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + auto crossSections( unsigned int order, unsigned int dilution ) const { + + checkBounds( order, dilution ); + return ranges::view::iota( 1, this->num_groups_+1 ) + | ranges::view::transform( + [=] ( unsigned int group ) -> double + { return this->getValue( 1, group, order, dilution ); } ); + } + + /** + * @brief Return a list of cross sections for each group. + * + * @note Assumes order=0. Most CrossSections in a GENDF have NL=1. + * + * @param[in] dilution the index of the dilution + */ + auto crossSections( unsigned int dilution ) const { + return crossSections( 0, dilution ); + } + + /** + * @brief Return the cross section for a given energy group. + * + * @param[in] group the energy group index + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + double crossSection( unsigned int group, unsigned int order, + unsigned int dilution ) const { + + checkBounds( group, order, dilution ); + return this->getValue( 1, group, order, dilution ); + } + + /** + * @brief Return the cross section for a given energy group. + * + * @param[in] group the energy group index + * @param[in] dilution the index of the dilution + */ + double crossSection( unsigned int group, unsigned int dilution ) const { + return crossSection( group, 0, dilution ); + } + + /** + * @brief Return the cross section for a given energy group. + * + * @param[in] group the energy group index + */ + double crossSection( unsigned int group ) const { + return crossSection( group, 0, 0 ); + } + + // from gendf::SectionBase + using SectionBase::NL; + using SectionBase::numberLegendreMoments; + using SectionBase::legendreOrder; + using SectionBase::NZ; + using SectionBase::numberDilutions; + using SectionBase::numberSigmaZeros; + using SectionBase::NGN; + using SectionBase::numberGroups; + using SectionBase::LR; + using SectionBase::complexBreakUp; + + // from section::Base + using SectionBase::MT; + using SectionBase::sectionNumber; + using SectionBase::ZA; + using SectionBase::AWR; + using SectionBase::atomicWeightRatio; + + }; + +} +} +} + +#endif diff --git a/src/ENDFtk/gendf/CrossSection/src/ctor.hpp b/src/ENDFtk/gendf/CrossSection/src/ctor.hpp new file mode 100644 index 000000000..bfda7d771 --- /dev/null +++ b/src/ENDFtk/gendf/CrossSection/src/ctor.hpp @@ -0,0 +1,33 @@ +public: + + CrossSection( double za, double awr, int mt, + int nl, int nz, int lr, int ng, + std::vector< DataRecord >&& records) : + SectionBase( za, awr, mt, nl, nz, lr, ng, + std::move( records ) ) {} + + CrossSection( double za, double awr, int mt, + int nl, int nz, int lr, int ng, + std::map< unsigned int, DataRecord >&& records) : + SectionBase( za, awr, mt, nl, nz, lr, ng, + std::move( records ) ) {} + + + /** + * @brief Constructor from buffer + * + * @tparam Iterator a buffer iterator + * + * @param[in] head the head record of the section + * @param[in] begin the iterator for begin + * @param[in] end the iterator for end + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + */ + template< typename Iterator > + CrossSection( const HEAD& head, + Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT ) : + SectionBase( head, begin, end, lineNumber, MAT ) {} diff --git a/src/ENDFtk/gendf/CrossSection/src/makeDataRecord.hpp b/src/ENDFtk/gendf/CrossSection/src/makeDataRecord.hpp new file mode 100644 index 000000000..f8a00841b --- /dev/null +++ b/src/ENDFtk/gendf/CrossSection/src/makeDataRecord.hpp @@ -0,0 +1,11 @@ +static DataRecord makeDataRecord( + double temperature, unsigned int group, + const std::vector< double >& fluxes, + const std::vector< double >& cross_sections ) { + + std::vector< double > list; + list.insert( list.end(), fluxes.begin(), fluxes.end() ); + list.insert( list.end(), cross_sections.begin(), cross_sections.end() ); + + return { temperature, 2, 1, group, std::move( list ) }; +} diff --git a/src/ENDFtk/gendf/CrossSection/test/CMakeLists.txt b/src/ENDFtk/gendf/CrossSection/test/CMakeLists.txt new file mode 100644 index 000000000..727966f8f --- /dev/null +++ b/src/ENDFtk/gendf/CrossSection/test/CMakeLists.txt @@ -0,0 +1,13 @@ +add_executable( ENDFtk.gendf.CrossSection.test CrossSection.test.cpp ) +target_compile_options( ENDFtk.gendf.CrossSection.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.gendf.CrossSection.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.gendf.CrossSection COMMAND ENDFtk.gendf.CrossSection.test ) diff --git a/src/ENDFtk/gendf/CrossSection/test/CrossSection.test.cpp b/src/ENDFtk/gendf/CrossSection/test/CrossSection.test.cpp new file mode 100644 index 000000000..689fc8b35 --- /dev/null +++ b/src/ENDFtk/gendf/CrossSection/test/CrossSection.test.cpp @@ -0,0 +1,139 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/gendf/CrossSection.hpp" +#include + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using namespace njoy::ENDFtk::gendf; + +// forward declarations +std::string chunk(); +void verifySection( const CrossSection& ); + +// helper function +template< typename Range1, typename Range2 > +void compareRanges( const Range1& r1, const Range2& r2 ) { + + CHECK( r1.size() == r2.size() ); + for( std::size_t i=0; i fluxes1 = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 }; + std::vector< double > xs1 = { 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 }; + std::vector< double > fluxes2 = { 1.1, 2.1, 3.1, 4.1, 5.1, 6.1 }; + std::vector< double > xs2 = { 7.1, 8.1, 9.1, 10.1, 11.1, 12.1 }; + + THEN( "the section can be constructed" ) { + + + // std::vector< DataRecord > records = { + // CrossSection::makeDataRecord( 293.6, 2, fluxes1, xs1 ), + // CrossSection::makeDataRecord( 293.6, 2, fluxes2, xs2 ) }; + // CrossSection section( 92235., 0.0, 1, 2, 3, 0, 3, + // std::move( records ) ); + // verifySection( section ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk(){ + + return + " 9.223500+4 0.000000+0 2 3 0 39228 3 1 \n" + " 2.936000+2 0.000000+0 2 1 12 19228 3 1 \n" + " 0.0 0.0 0.0 0.0 0.0 0.09228 3 1 \n" + " 0.0 0.0 0.0 0.0 0.0 0.09228 3 1 \n" + " 2.936000+2 0.000000+0 2 1 12 29228 3 1 \n" + " 1.0 2.0 3.0 4.0 5.0 6.09228 3 1 \n" + " 7.0 8.0 9.0 10.0 11.0 12.09228 3 1 \n" + " 2.936000+2 0.000000+0 2 1 12 39228 3 1 \n" + " 1.1 2.1 3.1 4.1 5.1 6.19228 3 1 \n" + " 7.1 8.1 9.1 10.1 11.1 12.19228 3 1 \n" + " 9228 3 0 \n"; +} + +void verifySection( const CrossSection& section ) { + + // header information + CHECK( 1 == section.MT() ); + CHECK( 1 == section.sectionNumber() ); + CHECK( 92235 == section.ZA() ); + CHECK( 0.0 == section.atomicWeightRatio() ); + CHECK( 0.0 == section.AWR() ); + CHECK( 2 == section.NL() ); + CHECK( 2 == section.numberLegendreMoments() ); + CHECK( 1 == section.legendreOrder() ); + CHECK( 3 == section.NZ() ); + CHECK( 3 == section.numberDilutions() ); + CHECK( 0 == section.LR() ); + CHECK( 0 == section.complexBreakUp() ); + CHECK( 3 == section.NGN() ); + CHECK( 3 == section.numberGroups() ); + + // group not provided + CHECK( 0.0 == Approx( section.flux(1) ) ); + CHECK( 0.0 == Approx( section.flux(1, 1, 1) ) ); + CHECK( 0.0 == Approx( section.crossSection(1) ) ); + CHECK( 0.0 == Approx( section.crossSection(1, 0, 0) ) ); + + // group provided -- flux + CHECK( 1.0 == Approx( section.flux(2) ) ); + CHECK( 1.0 == Approx( section.flux(2, 0, 0) ) ); + CHECK( 2.0 == Approx( section.flux(2, 1, 0) ) ); + CHECK( 3.0 == Approx( section.flux(2, 0, 1) ) ); + CHECK( 3.0 == Approx( section.flux(2, 1) ) ); + CHECK( 4.0 == Approx( section.flux(2, 1, 1) ) ); + CHECK( 5.0 == Approx( section.flux(2, 0, 2) ) ); + CHECK( 6.0 == Approx( section.flux(2, 1, 2) ) ); + + // group provided -- cross_section + CHECK( 7.1 == Approx( section.crossSection(3) ) ); + CHECK( 7.1 == Approx( section.crossSection(3, 0, 0) ) ); + CHECK( 8.1 == Approx( section.crossSection(3, 1, 0) ) ); + CHECK( 9.1 == Approx( section.crossSection(3, 0, 1) ) ); + CHECK( 10.1 == Approx( section.crossSection(3, 1, 1) ) ); + CHECK( 11.1 == Approx( section.crossSection(3, 0, 2) ) ); + CHECK( 11.1 == Approx( section.crossSection(3, 2) ) ); + CHECK( 12.1 == Approx( section.crossSection(3, 1, 2) ) ); + + // vectors + compareRanges( std::vector< double >( {0.0, 1.0, 1.1} ), + section.fluxes(0) ); + compareRanges( std::vector< double >( {0.0, 2.0, 2.1} ), + section.fluxes(1, 0) ); + compareRanges( std::vector< double >( {0.0, 7.0, 7.1} ), + section.crossSections(0) ); + compareRanges( std::vector< double >( {0.0, 10.0, 10.1} ), + section.crossSections(1, 1) ); + +} diff --git a/src/ENDFtk/gendf/DataRecord.hpp b/src/ENDFtk/gendf/DataRecord.hpp new file mode 100644 index 000000000..e0b5c5e2f --- /dev/null +++ b/src/ENDFtk/gendf/DataRecord.hpp @@ -0,0 +1,124 @@ +#ifndef NJOY_ENDFTK_GENDF_DATARECORD +#define NJOY_ENDFTK_GENDF_DATARECORD + +// system includes + +// other includes +#include "ENDFtk/ListRecord.hpp" +#include "range/v3/view.hpp" + +namespace njoy { +namespace ENDFtk { +namespace gendf { + + class DataRecord : protected ListRecord { + + public: + + /** + * @brief Constructor from parameters + * + * @param[in] temp the temperature + * @param[in] ng2 the number of secondary positions + * @param[in] ig2lo the index to lowest position + * @param[in] ig the group index + * @param[in] list the data contained + */ + DataRecord( double temp, long ng2, long ig2lo, long ig, + std::vector< double >&& list ) : + ListRecord( temp, 0., ng2, ig2lo, ig, + std::move( list ) ) {} + + /** + * @brief Constructor from buffer + * + * @tparam Iterator a buffer iterator + * + * @param[in] it the iterator for begin + * @param[in] end the iterator for end + * @param[in] lineNumber the line number + * @param[in] MAT the expected material number + * @param[in] MF the expected file number + * @param[in] MT the expected section number + */ + template< typename Iterator > + DataRecord( Iterator& it, const Iterator& end, long& lineNumber, + long MAT, long MF, long MT ) : + ListRecord( it, end, lineNumber, MAT, MF, MT ) {} + + /* getter methods */ + + /** + * @brief The temperature + */ + double TEMP() const { return this->C1(); } + + /** + * @brief The temperature + */ + double temperature() const { return this->TEMP(); } + + + /** + * @brief The number of secondary positions + */ + long NG2() const { return this->L1(); } + + /** + * @brief The number of secondary positions + */ + long numberSecondaryPositions() const { return this->NG2(); } + + /** + * @brief The index to the lowest position + */ + long IG2LO() const { return this->L2(); } + + /** + * @brief The index to the lowest position + */ + long lowestPosition() const { return this->IG2LO(); } + + + /** + * @brief The number of words in the list + */ + long NW() const { return this->NPL(); } + + /** + * @brief The number of words in the list + */ + long numberWords() const { return this->NW(); } + + /** + * @brief The group index + */ + long IG() const { return this->N2(); } + + /** + * @brief The group index + */ + long groupIndex() const { return this->IG(); } + + /** + * @brief A block of data from the record + * + * @param[in] position the requested block + */ + auto data( unsigned int block ) const { + + std::size_t size = this->NW() / this->NG2(); + return this->list() + | ranges::view::drop_exactly( block * size ) + | ranges::view::take_exactly( size ); + } + + using ListRecord::list; + + }; + +} +} +} + +#endif diff --git a/src/ENDFtk/gendf/DataRecord/test/CMakeLists.txt b/src/ENDFtk/gendf/DataRecord/test/CMakeLists.txt new file mode 100644 index 000000000..f54a4f987 --- /dev/null +++ b/src/ENDFtk/gendf/DataRecord/test/CMakeLists.txt @@ -0,0 +1,13 @@ +add_executable( ENDFtk.gendf.DataRecord.test DataRecord.test.cpp ) +target_compile_options( ENDFtk.gendf.DataRecord.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.gendf.DataRecord.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.gendf.DataRecord COMMAND ENDFtk.gendf.DataRecord.test ) diff --git a/src/ENDFtk/gendf/DataRecord/test/DataRecord.test.cpp b/src/ENDFtk/gendf/DataRecord/test/DataRecord.test.cpp new file mode 100644 index 000000000..e93703f40 --- /dev/null +++ b/src/ENDFtk/gendf/DataRecord/test/DataRecord.test.cpp @@ -0,0 +1,74 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/gendf/DataRecord.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk::gendf; + +// forward declarations +std::string chunk(); +void verifyRecord( DataRecord ); + +// tests +SCENARIO( "DataRecord tests") { + + GIVEN( "valid data for the DataRecord" ) { + + WHEN( "the data is given as a string" ) { + + std::string data = chunk(); + auto begin = data.begin(); + auto end = data.end(); + long lineNumber = 10; + + THEN( "the record can be constructed" ) { + + DataRecord record( begin, end, lineNumber, 9228, 3, 1 ); + verifyRecord( record ); + + } // THEN + } // WHEN + + WHEN( "the data is given explicitly" ) { + + std::vector data = { 1.0, 2.0, 3.0, 4.0 }; + + THEN( "the record can be constructed" ) { + + DataRecord record( 293.6, 2, 1, 5, std::move( data ) ); + verifyRecord( record ); + + } // THEN + } // WHEN + } // GIVEN + +} // SCENARIO + +std::string chunk(){ + + return + " 2.936000+2 0.000000+0 2 1 4 59228 3 1 10\n" + " 1.000000+0 2.000000+0 3.000000+0 4.000000+0 9228 3 1 11\n"; + +} + +void verifyRecord( DataRecord record ) { + CHECK( 293.6 == Approx( record.TEMP() ) ); + CHECK( 293.6 == Approx( record.temperature() ) ); + CHECK( 2 == record.NG2() ); + CHECK( 2 == record.numberSecondaryPositions() ); + CHECK( 1 == record.IG2LO() ); + CHECK( 1 == record.lowestPosition() ); + CHECK( 4 == record.NW() ); + CHECK( 4 == record.numberWords() ); + CHECK( 5 == record.IG() ); + CHECK( 5 == record.groupIndex() ); + CHECK( 1.0 == Approx( record.list()[0] ) ); + CHECK( 2.0 == Approx( record.list()[1] ) ); + CHECK( 2.0 == Approx( record.data(0)[1] ) ); + CHECK( 4.0 == Approx( record.data(1)[1] ) ); + +} diff --git a/src/ENDFtk/gendf/Matrix.hpp b/src/ENDFtk/gendf/Matrix.hpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/ENDFtk/gendf/Ratio.hpp b/src/ENDFtk/gendf/Ratio.hpp new file mode 100644 index 000000000..7ee6f93f8 --- /dev/null +++ b/src/ENDFtk/gendf/Ratio.hpp @@ -0,0 +1,223 @@ +#ifndef NJOY_ENDFTK_GENDF_RATIO +#define NJOY_ENDFTK_GENDF_RATIO + +// system includes + +// other includes +#include "ENDFtk/gendf/SectionBase.hpp" + +namespace njoy { +namespace ENDFtk { +namespace gendf { + + class Ratio : protected SectionBase { + + protected: + + /* constructor */ + #include "ENDFtk/gendf/Ratio/src/ctor.hpp" + + public: + + + /* convenience functions */ + + /** + * @brief Return a list of fluxes for each group. + * + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + auto fluxes( unsigned int order, unsigned int dilution ) { + + checkBounds( order, dilution ); + return ranges::view::iota( 1, this->num_groups_+1 ) + | ranges::view::transform( + [&] ( unsigned int group ) -> double + { return getValue( 0, group, order, dilution ); } ); + } + + /** + * @brief Return a list of fluxes for each group. + * + * @note Assumes order=0. Most CrossSections in a GENDF have NL=1. + * + * @param[in] dilution the index of the dilution + */ + auto fluxes( unsigned int dilution ) { return fluxes( 0, dilution ); } + + /** + * @brief Return the flux for a given energy group. + * + * @param[in] group the energy group index + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + double flux( unsigned int group, unsigned int order, + unsigned int dilution ) { + + checkBounds( group, order, dilution ); + return getValue( 0, group, order, dilution ); + } + + /** + * @brief Return the flux for a given energy group. + * + * @param[in] group the energy group index + * @param[in] dilution the index of the dilution + */ + double flux( unsigned int group, unsigned int dilution ) { + return flux( group, 0, dilution ); + } + + /** + * @brief Return the flux for a given energy group. + * + * @param[in] group the energy group index + */ + double flux( unsigned int group ) { return flux( group, 0, 0 ); } + + /** + * @brief Return a list of ratios for each group. + * + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + auto ratios( unsigned int order, unsigned int dilution ) { + + checkBounds( order, dilution ); + return ranges::view::iota( 1, this->num_groups_+1 ) + | ranges::view::transform( + [&] ( unsigned int group ) -> double + { return getValue( 1, group, order, dilution ); } ); + } + + /** + * @brief Return a list of ratios for each group. + * + * @note Assumes order=0. Most Ratios in a GENDF have NL=1. + * + * @param[in] dilution the index of the dilution + */ + auto ratios( unsigned int dilution ) { + return ratios( 0, dilution ); + } + + /** + * @brief Return the ratio for a given energy group. + * + * @param[in] group the energy group index + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + double ratio( unsigned int group, unsigned int order, + unsigned int dilution ) { + + checkBounds( group, order, dilution ); + return getValue( 1, group, order, dilution ); + } + + /** + * @brief Return the ratio for a given energy group. + * + * @param[in] group the energy group index + * @param[in] dilution the index of the dilution + */ + double ratio( unsigned int group, unsigned int dilution ) { + return ratio( group, 0, dilution ); + } + + /** + * @brief Return the ratio for a given energy group. + * + * @param[in] group the energy group index + */ + double ratio( unsigned int group ) { + return ratio( group, 0, 0 ); + } + + /** + * @brief Return a list of cross sections for each group. + * + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + auto crossSections( unsigned int order, unsigned int dilution ) { + + checkBounds( order, dilution ); + return ranges::view::iota( 1, this->num_groups_+1 ) + | ranges::view::transform( + [&] ( unsigned int group ) -> double + { return getValue( 2, group, order, dilution ); } ); + } + + /** + * @brief Return a list of cross sections for each group. + * + * @note Assumes order=0. Most CrossSections in a GENDF have NL=1. + * + * @param[in] dilution the index of the dilution + */ + auto crossSections( unsigned int dilution ) { + return crossSections( 0, dilution ); + } + + /** + * @brief Return the cross section for a given energy group. + * + * @param[in] group the energy group index + * @param[in] order the Legendre order + * @param[in] dilution the index of the dilution + */ + double crossSection( unsigned int group, unsigned int order, + unsigned int dilution ) { + + checkBounds( group, order, dilution ); + return getValue( 2, group, order, dilution ); + } + + /** + * @brief Return the cross section for a given energy group. + * + * @param[in] group the energy group index + * @param[in] dilution the index of the dilution + */ + double crossSection( unsigned int group, unsigned int dilution ) { + return crossSection( group, 0, dilution ); + } + + /** + * @brief Return the cross section for a given energy group. + * + * @param[in] group the energy group index + */ + double crossSection( unsigned int group ) { + return crossSection( group, 0, 0 ); + } + + // from gendf::SectionBase + using SectionBase::NL; + using SectionBase::numberLegendreMoments; + using SectionBase::legendreOrder; + using SectionBase::NZ; + using SectionBase::numberDilutions; + using SectionBase::numberSigmaZeros; + using SectionBase::NGN; + using SectionBase::numberGroups; + using SectionBase::LR; + using SectionBase::complexBreakUp; + + // from section::Base + using SectionBase::MT; + using SectionBase::sectionNumber; + using SectionBase::ZA; + using SectionBase::AWR; + using SectionBase::atomicWeightRatio; + + }; + +} +} +} + +#endif diff --git a/src/ENDFtk/gendf/SectionBase.hpp b/src/ENDFtk/gendf/SectionBase.hpp new file mode 100644 index 000000000..53f5991cb --- /dev/null +++ b/src/ENDFtk/gendf/SectionBase.hpp @@ -0,0 +1,148 @@ +#ifndef NJOY_ENDFTK_GENDF_SECTIONBASE +#define NJOY_ENDFTK_GENDF_SECTIONBASE + +// system includes + +// other includes +#include "ENDFtk/section/Base.hpp" +#include "ENDFtk/gendf/DataRecord.hpp" +#include "range/v3/view.hpp" + +namespace njoy { +namespace ENDFtk { +namespace gendf { + + class SectionBase : protected section::Base { + + protected: + + /* fields */ + int num_legendre_; + int num_dilutions_; + int breakup_; + int num_groups_; + std::map< unsigned int, DataRecord > records_; + + /* constructor */ + #include "ENDFtk/gendf/SectionBase/src/readRecords.hpp" + #include "ENDFtk/gendf/SectionBase/src/mapRecords.hpp" + #include "ENDFtk/gendf/SectionBase/src/verifyRecords.hpp" + #include "ENDFtk/gendf/SectionBase/src/ctor.hpp" + + public: + + /* get methods */ + + /** + * @brief The number of Legendre moments + */ + unsigned int NL() const { return this->num_legendre_; } + + /** + * @brief The number of Legendre moments + */ + unsigned int numberLegendreMoments() const { return this->NL(); } + + /** + * @brief The Legendre order + */ + unsigned int legendreOrder() const { return this->NL()-1; } + + /** + * @brief The number of dilutions + */ + unsigned int NZ() const { return this->num_dilutions_; } + + /** + * @brief The number of dilutions + */ + unsigned int numberDilutions() const { return this->NZ(); } + + /** + * @brief The number of dilutions + */ + unsigned int numberSigmaZeros() const { return this->NZ(); } + + /** + * @brief The number of groups + */ + unsigned int NGN() const { return this->num_groups_; } + + /** + * @brief The number of groups + */ + unsigned int numberGroups() const { return this->NGN(); } + + /** + * @brief The complex breakup flag + */ + int LR() const { return this->breakup_; } + + /** + * @brief The complex breakup flag + */ + int complexBreakUp() const { return this->LR(); } + + + /* convenience functions for accessing data */ + + /** + * @brief View of the record data. + */ + auto records() const { return ranges::view::values( this->records_ ); } + + /** + * @brief Return a DataRecord by group + * + * @param[in] group the group index + */ + const auto& record( unsigned int group ) const { + return this->records_.at( group ); + } + + /** + * @brief Check if group has a DataRecord + * + * @param[in] group the group index + */ + bool hasRecord( unsigned int group ) const { + return this->records_.find( group ) != this->records_ .end(); + } + + #include "ENDFtk/gendf/SectionBase/src/checkBounds.hpp" + + /** + * @brief Convenience function for extracting a value from + * a block of a DataRecord + * + * @param[in] block the block index + * @param[in] group the group index + * @param[in] order the Legendre order + * @param[in] dilution the dilution index + */ + double getValue( unsigned int block, unsigned int group, + unsigned int order, unsigned int dilution ) const { + + // default value + if ( !this->hasRecord(group) ) { + return 0.0; + } + + // from list + const auto& values = this->record( group ).data( block ); + return values[ this->num_legendre_ * dilution + order ]; + } + + using Base::MT; + using Base::sectionNumber; + using Base::ZA; + using Base::AWR; + using Base::atomicWeightRatio; + + }; + +} // gendf namespace +} // ENDFtk namespace +} // njoy namespace + +#endif diff --git a/src/ENDFtk/gendf/SectionBase/src/checkBounds.hpp b/src/ENDFtk/gendf/SectionBase/src/checkBounds.hpp new file mode 100644 index 000000000..a89b372a5 --- /dev/null +++ b/src/ENDFtk/gendf/SectionBase/src/checkBounds.hpp @@ -0,0 +1,42 @@ +/** + * @brief Ensure requested indices are valid. + * + * @param[in] group the group index + * @param[in] order the Legendre order + * @param[in] dilution the dilution index + */ +void checkBounds( unsigned int group, unsigned int order, + unsigned int dilution ) const { + + // check group + if ( group == 0 || group > this->num_groups_ ) { + Log::error( "Group index {} is invalid with {} groups.", + group, this->num_groups_ ); + throw std::exception(); + } + + checkBounds( order, dilution ); +} + +/** + * @brief Ensure requested indices are valid. + * + * @param[in] order the Legendre order + * @param[in] dilution the dilution index + */ +void checkBounds( unsigned int order, unsigned int dilution ) const { + + // check order + if ( order >= this->num_legendre_ ) { + Log::error( "Legendre order {} is invalid with {} NL.", + order, this->num_legendre_ ); + throw std::exception(); + } + + // check dilution + if ( dilution >= this->num_dilutions_ ) { + Log::error( "Dilution index {} is invalid with {} dilutions.", + dilution, this->num_dilutions_ ); + throw std::exception(); + } +} diff --git a/src/ENDFtk/gendf/SectionBase/src/ctor.hpp b/src/ENDFtk/gendf/SectionBase/src/ctor.hpp new file mode 100644 index 000000000..9adb1fbbc --- /dev/null +++ b/src/ENDFtk/gendf/SectionBase/src/ctor.hpp @@ -0,0 +1,65 @@ +protected: + + SectionBase( double za, double awr, int mt, + int nl, int nz, int lr, int ng, + std::map< unsigned int, DataRecord >&& records ) : + Base( za, awr, mt ), + num_legendre_(nl), + num_dilutions_(nz), + breakup_(lr), + num_groups_(ng), + records_(records) { + + verifyRecords(); +} + +public: + + /** + * @brief Constructor from parameters + * + * @param[in] za the ZAID identifier + * @param[in] awr the atomic weight ratio + * @param[in] mt the section number + * @param[in] nl the number of Legendre moments (order+1) + * @param[in] nz the number of dilutions (sigma-zeros) + * @param[in] lr the complex breakup flag + * @param[in] ng the number of groups + * @param[in] records the data records + */ + SectionBase( double za, double awr, int mt, + int nl, int nz, int lr, int ng, + std::vector< DataRecord >&& records ) : + SectionBase( za, awr, mt, nl, nz, lr, ng, + std::move( mapRecords( std::move( records ) ) ) ) {} + + /** + * @brief Constructor from buffer + * + * @tparam Iterator a buffer iterator + * + * @param[in] head the head record of the section + * @param[in] begin the iterator for begin + * @param[in] end the iterator for end + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + */ + template< typename Iterator > + SectionBase( const HEAD& head, + Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT ) + try: SectionBase( head.ZA(), head.atomicWeightRatio(), head.MT(), + head.L1(), head.L2(), head.N1(), head.N2(), + readRecords( begin, end, MAT, head.MF(), + head.MT(), head.N2() ) ) { + + this->readSEND( begin, end, lineNumber, head.MAT(), head.MF() ); + } + catch( std::exception& e ) { + Log::info( "Encountered error while reading section {} of file {} of " + "material {} in GENDF file.", + head.MT(), head.MF(), head.MAT() ); + throw e; + } diff --git a/src/ENDFtk/gendf/SectionBase/src/mapRecords.hpp b/src/ENDFtk/gendf/SectionBase/src/mapRecords.hpp new file mode 100644 index 000000000..6d291254e --- /dev/null +++ b/src/ENDFtk/gendf/SectionBase/src/mapRecords.hpp @@ -0,0 +1,9 @@ +static auto mapRecords( std::vector< DataRecord >&& records ) { + + std::map< unsigned int, DataRecord > result; + for( auto& record : records ) { + result.emplace( record.IG(), std::move( record ) ); + } + + return result; +} diff --git a/src/ENDFtk/gendf/SectionBase/src/readRecords.hpp b/src/ENDFtk/gendf/SectionBase/src/readRecords.hpp new file mode 100644 index 000000000..f0a183758 --- /dev/null +++ b/src/ENDFtk/gendf/SectionBase/src/readRecords.hpp @@ -0,0 +1,17 @@ +template< typename Iterator > +static auto readRecords( + Iterator& it, const Iterator& end, long MAT, + long MF, long MT, unsigned int NGN ) { + + std::map< unsigned int, DataRecord > result; + + do { + + long lineNumber = 0; + auto record = DataRecord( it, end, lineNumber, MAT, MF, MT ); + result.emplace( record.IG(), record ); + + } while( result.rbegin()->first < NGN ); + + return result; +} diff --git a/src/ENDFtk/gendf/SectionBase/src/verifyRecords.hpp b/src/ENDFtk/gendf/SectionBase/src/verifyRecords.hpp new file mode 100644 index 000000000..65abe5e4e --- /dev/null +++ b/src/ENDFtk/gendf/SectionBase/src/verifyRecords.hpp @@ -0,0 +1,11 @@ +void verifyRecords() { + + // test if last record's index matches number of groups + unsigned int ig = records_.rbegin()->first; + if ( ig != this->num_groups_ ) { + Log::error( "Final DataRecord in GENDF section {} has IG {} which " + "does not match NGN {}.", + this->MT(), ig, this->NGN() ); + throw; + } +} diff --git a/src/ENDFtk/gendf/SectionBase/test/CMakeLists.txt b/src/ENDFtk/gendf/SectionBase/test/CMakeLists.txt new file mode 100644 index 000000000..644f8d93e --- /dev/null +++ b/src/ENDFtk/gendf/SectionBase/test/CMakeLists.txt @@ -0,0 +1,13 @@ +add_executable( ENDFtk.gendf.SectionBase.test SectionBase.test.cpp ) +target_compile_options( ENDFtk.gendf.SectionBase.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.gendf.SectionBase.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.gendf.SectionBase COMMAND ENDFtk.gendf.SectionBase.test ) diff --git a/src/ENDFtk/gendf/SectionBase/test/SectionBase.test.cpp b/src/ENDFtk/gendf/SectionBase/test/SectionBase.test.cpp new file mode 100644 index 000000000..63a03e315 --- /dev/null +++ b/src/ENDFtk/gendf/SectionBase/test/SectionBase.test.cpp @@ -0,0 +1,111 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/gendf/SectionBase.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using namespace njoy::ENDFtk::gendf; + +// trivial class to access protected constructors +class TestBase : public SectionBase { +public: + TestBase( double ZA, double AWR, int MT, + int NL, int NZ, int LRFLAG, int NGN, + std::vector< DataRecord >&& lists ) : + SectionBase( ZA, AWR, MT, NL, NZ, LRFLAG, NGN, std::move( lists ) ) {}; + template< typename Iterator > + TestBase( const HEAD& head, Iterator& begin, const Iterator& end, + long& lineNumber, int MAT ) : + SectionBase( head, begin, end, lineNumber, MAT ) {}; +}; + +// forward declarations +std::string chunk(); +void verifySection( TestBase ); + +// tests +SCENARIO( "BaseSection tests") { + + GIVEN( "valid data for the section" ) { + + WHEN( "the data is given as a string" ) { + + std::string line = chunk(); + auto begin = line.begin(); + auto end = line.end(); + long lineNumber = 0; + auto head = StructureDivision( begin, end, lineNumber ); + + THEN( "the section can be constructed" ) { + + TestBase section( asHead(head), begin, end, lineNumber, 9228 ); + verifySection( section ); + } // THEN + } // WHEN + + WHEN( "the data is given explicitly" ) { + + std::vector< DataRecord > lists; + std::vector data1 = { 7.705020e-4, 1.023642e+3 }; + lists.emplace_back( 293.6, 2, 1, 2, std::move( data1 ) ); + std::vector data2 = { 9.306457e-3, 2.031301e+2 }; + lists.emplace_back( 293.6, 2, 1, 3, std::move( data2 ) ); + + THEN( "the section can be constructed" ) { + + TestBase section( 92235., 0.0, 1, 1, 1, 0, 3, std::move( lists ) ); + verifySection( section ); + } // THEN + } // WHEN + } // GIVEN + +} // SCENARIO + +std::string chunk(){ + + return + " 9.223500+4 0.000000+0 1 1 0 39228 3 1 1\n" + " 2.936000+2 0.000000+0 2 1 2 29228 3 1 2\n" + " 7.705020-4 1.023642+3 9228 3 1 3\n" + " 2.936000+2 0.000000+0 2 1 2 39228 3 1 4\n" + " 9.306457-3 2.031301+2 9228 3 1 5\n" + " 9228 3 099999\n"; +} + +void verifySection( TestBase section ) { + + // header information + CHECK( 1 == section.MT() ); + CHECK( 1 == section.sectionNumber() ); + CHECK( 92235 == section.ZA() ); + CHECK( 0.0 == section.atomicWeightRatio() ); + CHECK( 0.0 == section.AWR() ); + CHECK( 1 == section.NL() ); + CHECK( 1 == section.numberLegendreMoments() ); + CHECK( 0 == section.legendreOrder() ); + CHECK( 1 == section.NZ() ); + CHECK( 1 == section.numberDilutions() ); + CHECK( 0 == section.LR() ); + CHECK( 0 == section.complexBreakUp() ); + CHECK( 3 == section.NGN() ); + CHECK( 3 == section.numberGroups() ); + + // access lists + CHECK( 2 == section.records().size() ); + CHECK( 9.306457e-3 == Approx( section.record(3).list()[0] ) ); + CHECK( section.hasRecord(2) ); + CHECK( !section.hasRecord(1) ); + CHECK( !section.hasRecord(4) ); + + // convenience functions + CHECK_THROWS( section.checkBounds( 1, 1 ) ); + CHECK_THROWS( section.checkBounds( 0, 2 ) ); + CHECK_THROWS( section.checkBounds( 0, 0, 0 ) ); + CHECK_THROWS( section.checkBounds( 4, 0, 0 ) ); + CHECK_NOTHROW( section.checkBounds( 3, 0, 0 ) ); + CHECK( 7.705020e-4 == Approx( section.getValue( 0, 2, 0, 0) ) ); + CHECK( 2.031301e+2 == Approx( section.getValue( 1, 3, 0, 0) ) ); +} diff --git a/src/ENDFtk/record/InterpolationBase.hpp b/src/ENDFtk/record/InterpolationBase.hpp index 3f2dbaacc..830235020 100644 --- a/src/ENDFtk/record/InterpolationBase.hpp +++ b/src/ENDFtk/record/InterpolationBase.hpp @@ -74,12 +74,14 @@ namespace record { long NR() const { return this->boundaryIndices.size(); } long N2() const { return this->boundaryIndices.back(); } - LongRange interpolants() const { - return ranges::view::all( this->interpolationSchemeIndices ); + AllRange< long > interpolants() const { + + return ranges::cpp20::views::all( this->interpolationSchemeIndices ); } - LongRange boundaries() const { - return ranges::view::all( this->boundaryIndices ); + AllRange< long > boundaries() const { + + return ranges::cpp20::views::all( this->boundaryIndices ); } bool operator==( const InterpolationBase& rhs ) const { diff --git a/src/ENDFtk/record/InterpolationBase/test/InterpolationBase.test.cpp b/src/ENDFtk/record/InterpolationBase/test/InterpolationBase.test.cpp index 68adee1b1..eb1ee506a 100644 --- a/src/ENDFtk/record/InterpolationBase/test/InterpolationBase.test.cpp +++ b/src/ENDFtk/record/InterpolationBase/test/InterpolationBase.test.cpp @@ -4,7 +4,7 @@ #include "ENDFtk/record/InterpolationBase.hpp" // other includes -#include "range/v3/at.hpp" +#include "range/v3/range/operations.hpp" #include "header-utilities/copy.hpp" // convenience typedefs diff --git a/src/ENDFtk/section/1/451.hpp b/src/ENDFtk/section/1/451.hpp index 834359c28..2386b9bbd 100644 --- a/src/ENDFtk/section/1/451.hpp +++ b/src/ENDFtk/section/1/451.hpp @@ -4,7 +4,8 @@ // system includes // other includes -#include "range/v3/distance.hpp" +#include "range/v3/iterator/operations.hpp" +#include "range/v3/range/conversion.hpp" #include "range/v3/view/all.hpp" #include "range/v3/view/concat.hpp" #include "range/v3/view/join.hpp" @@ -240,7 +241,7 @@ namespace section { */ AllRange< DirectoryRecord > index() const { - return ranges::view::all( this->index_ ); + return ranges::cpp20::views::all( this->index_ ); } /** diff --git a/src/ENDFtk/section/1/451/src/ctor.hpp b/src/ENDFtk/section/1/451/src/ctor.hpp index 95b57be46..37666dbb4 100644 --- a/src/ENDFtk/section/1/451/src/ctor.hpp +++ b/src/ENDFtk/section/1/451/src/ctor.hpp @@ -50,8 +50,8 @@ Type( double zaid, double awr, int lrp, int lfi, int nlib, int nmod, parameters_( makeParameters( elis, sta, lis, liso, nfor, awi, emax, lrel, nsub, nver, temp, rtol, ldrv, - ranges::distance( - ranges::view::split( description, '\n' ) ), + ranges::cpp20::distance( + ranges::cpp20::views::split( description, '\n' ) ), index.size() ) ), description_( makeDescription( description ) ), index_( std::move( index ) ) {} diff --git a/src/ENDFtk/section/1/451/src/description.hpp b/src/ENDFtk/section/1/451/src/description.hpp index 987a5dd91..e10526628 100644 --- a/src/ENDFtk/section/1/451/src/description.hpp +++ b/src/ENDFtk/section/1/451/src/description.hpp @@ -4,11 +4,11 @@ auto description() const { return - ranges::view::concat + ranges::views::concat ( this->description_ - | ranges::view::transform + | ranges::cpp20::views::transform ( []( const auto& textRecord )->decltype(auto) { return textRecord.text(); } ) - | ranges::view::join( '\n' ), - ranges::view::single( '\n' ) ); + | ranges::views::join( '\n' ), + ranges::cpp20::views::single( '\n' ) ); } diff --git a/src/ENDFtk/section/1/451/src/makeDescription.hpp b/src/ENDFtk/section/1/451/src/makeDescription.hpp index f043d3bc6..568b30d61 100644 --- a/src/ENDFtk/section/1/451/src/makeDescription.hpp +++ b/src/ENDFtk/section/1/451/src/makeDescription.hpp @@ -2,7 +2,10 @@ static std::vector< TextRecord > makeDescription( const std::string& description ) { - return ranges::view::split( description, '\n' ) - | ranges::view::transform( [] ( const auto& line ) - { return TextRecord( line ); } ); + return ranges::to< std::vector< TextRecord > >( + ranges::cpp20::views::split( description, '\n' ) + | ranges::cpp20::views::transform( + [] ( const auto& line ) + { std::string string = ranges::to< std::string >( line ); + return TextRecord( std::move( string ) ); } ) ); } diff --git a/src/ENDFtk/section/1/451/test/451.test.cpp b/src/ENDFtk/section/1/451/test/451.test.cpp index 06c3fa447..cb3a43292 100644 --- a/src/ENDFtk/section/1/451/test/451.test.cpp +++ b/src/ENDFtk/section/1/451/test/451.test.cpp @@ -246,7 +246,7 @@ void verifyChunk( const section::Type< 1, 451 >& chunk ) { CHECK( 21 == chunk.LDRV() ); CHECK( 21 == chunk.derivedMaterial() ); CHECK( 9 == chunk.NWD() ); - CHECK( ranges::equal( description(), chunk.description() ) ); + CHECK( ranges::cpp20::equal( description(), chunk.description() ) ); auto entries = index(); CHECK( entries.size() == chunk.NXC() ); diff --git a/src/ENDFtk/section/1/455.hpp b/src/ENDFtk/section/1/455.hpp index 86e4f3884..ea57535ce 100644 --- a/src/ENDFtk/section/1/455.hpp +++ b/src/ENDFtk/section/1/455.hpp @@ -11,6 +11,7 @@ #include "ENDFtk/HeadRecord.hpp" #include "ENDFtk/ControlRecord.hpp" #include "ENDFtk/section.hpp" +#include "ENDFtk/types.hpp" #include "range/v3/view/stride.hpp" #include "range/v3/view/drop_exactly.hpp" diff --git a/src/ENDFtk/section/1/455/DecayConstants.hpp b/src/ENDFtk/section/1/455/DecayConstants.hpp index 2ba5b4bf2..743ca4570 100644 --- a/src/ENDFtk/section/1/455/DecayConstants.hpp +++ b/src/ENDFtk/section/1/455/DecayConstants.hpp @@ -41,29 +41,35 @@ class DecayConstants : protected ListRecord { /** * @brief Return the decay constants */ - auto lambdas() const { + StrideRange< AllRange< double > > lambdas() const { - return ListRecord::list() | ranges::view::stride( 2 ); + return ListRecord::list() | ranges::views::stride( 2 ); } /** * @brief Return the decay constants */ - auto decayConstants() const { return this->lambdas(); } + StrideRange< AllRange< double > > decayConstants() const { + + return this->lambdas(); + } /** * @brief Return the abundance values */ - auto alphas() const { + StrideRange< DropRange< AllRange< double > > > alphas() const { - return ListRecord::list() | ranges::view::drop_exactly( 1 ) - | ranges::view::stride( 2 ); + return ListRecord::list() | ranges::views::drop_exactly( 1 ) + | ranges::views::stride( 2 ); } /** * @brief Return the abundance values */ - auto abundances() const { return this->alphas(); } + StrideRange< DropRange< AllRange< double > > > abundances() const { + + return this->alphas(); + } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/1/455/EnergyDependentConstants.hpp b/src/ENDFtk/section/1/455/EnergyDependentConstants.hpp index 122474e9b..7e5431d0d 100644 --- a/src/ENDFtk/section/1/455/EnergyDependentConstants.hpp +++ b/src/ENDFtk/section/1/455/EnergyDependentConstants.hpp @@ -51,18 +51,24 @@ class EnergyDependentConstants : /** * @brief Return the interpolants for the incident energy axis */ - auto interpolants() const { return InterpolationSequenceRecord::tab2().interpolants(); } + AllRange< long > interpolants() const { + + return InterpolationSequenceRecord::tab2().interpolants(); + } /** * @brief Return the interpolation region boundaries for the incident * energy axis */ - auto boundaries() const { return InterpolationSequenceRecord::tab2().boundaries(); } + AllRange< long > boundaries() const { + + return InterpolationSequenceRecord::tab2().boundaries(); + } /** * @brief Return the decay contants */ - auto constants() const { + AllRange< DecayConstants > constants() const { return this->records(); } @@ -73,7 +79,7 @@ class EnergyDependentConstants : auto E() const { return this->constants() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( const auto& record ) { return record.incidentEnergy(); } ); } diff --git a/src/ENDFtk/section/1/455/EnergyIndependentConstants.hpp b/src/ENDFtk/section/1/455/EnergyIndependentConstants.hpp index 3e6861f98..2a9ea3d48 100644 --- a/src/ENDFtk/section/1/455/EnergyIndependentConstants.hpp +++ b/src/ENDFtk/section/1/455/EnergyIndependentConstants.hpp @@ -37,12 +37,12 @@ class EnergyIndependentConstants : protected ListRecord { /** * @brief Return the decay constants */ - auto lambdas() const { return ListRecord::list(); } + AllRange< double > lambdas() const { return ListRecord::list(); } /** * @brief Return the decay constants */ - auto decayConstants() const { return this->lambdas(); } + AllRange< double > decayConstants() const { return this->lambdas(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/1/458/EnergyReleaseComponent.hpp b/src/ENDFtk/section/1/458/EnergyReleaseComponent.hpp index e9d52b1e8..df7123070 100644 --- a/src/ENDFtk/section/1/458/EnergyReleaseComponent.hpp +++ b/src/ENDFtk/section/1/458/EnergyReleaseComponent.hpp @@ -39,22 +39,22 @@ class EnergyReleaseComponent : protected TabulationRecord { /** * @brief Return the incident energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the incident energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the fission energy release values */ - auto EIFC() const { return TabulationRecord::y(); } + AllRange< double > EIFC() const { return TabulationRecord::y(); } /** * @brief Return the fission energy release values */ - auto qValues() const { return this->EIFC(); } + AllRange< double > qValues() const { return this->EIFC(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/1/458/PolynomialComponents.hpp b/src/ENDFtk/section/1/458/PolynomialComponents.hpp index 8a58eed49..8260503c9 100644 --- a/src/ENDFtk/section/1/458/PolynomialComponents.hpp +++ b/src/ENDFtk/section/1/458/PolynomialComponents.hpp @@ -9,6 +9,13 @@ */ class PolynomialComponents : protected ListRecord { +public: + + /* type aliases */ + using Piece = StrideRange< DropRange< ChunkRange< AllRange< double > > > >; + +private: + /* auxiliary functions */ #include "ENDFtk/section/1/458/PolynomialComponents/src/verify.hpp" #include "ENDFtk/section/1/458/PolynomialComponents/src/generateList.hpp" @@ -59,8 +66,8 @@ class PolynomialComponents : protected ListRecord { */ auto E() const { - return ranges::view::iota( 0, 9 ) - | ranges::view::transform( + return ranges::cpp20::views::iota( 0, 9 ) + | ranges::cpp20::views::transform( [&] ( unsigned int index ) { return this->createRangeFromIndex( index ); } ); } @@ -77,99 +84,99 @@ class PolynomialComponents : protected ListRecord { * @brief Return the kinetic energy of the fission fragments and its * uncertainty */ - auto EFR() const { return this->createRangeFromIndex( 0 ); } + Piece EFR() const { return this->createRangeFromIndex( 0 ); } /** * @brief Return the kinetic energy of the fission fragments and its * uncertainty */ - auto fissionFragments() const { return this->EFR(); } + Piece fissionFragments() const { return this->EFR(); } /** * @brief Return the kinetic energy of the prompt fission neutrons and its * uncertainty */ - auto ENP() const { return this->createRangeFromIndex( 1 ); } + Piece ENP() const { return this->createRangeFromIndex( 1 ); } /** * @brief Return the kinetic energy of the prompt fission neutrons and its * uncertainty */ - auto promptNeutrons() const { return this->ENP(); } + Piece promptNeutrons() const { return this->ENP(); } /** * @brief Return the kinetic energy of the delayed fission neutrons and its * uncertainty */ - auto END() const { return this->createRangeFromIndex( 2 ); } + Piece END() const { return this->createRangeFromIndex( 2 ); } /** * @brief Return the kinetic energy of the delayed fission neutrons and its * uncertainty */ - auto delayedNeutrons() const { return this->END(); } + Piece delayedNeutrons() const { return this->END(); } /** * @brief Return the energy release by prompt gammas and its uncertainty */ - auto EGP() const { return this->createRangeFromIndex( 3 ); } + Piece EGP() const { return this->createRangeFromIndex( 3 ); } /** * @brief Return the energy release by prompt gammas and its uncertainty */ - auto promptGammas() const { return this->EGP(); } + Piece promptGammas() const { return this->EGP(); } /** * @brief Return the energy release by delayed gammas and its uncertainty */ - auto EGD() const { return this->createRangeFromIndex( 4 ); } + Piece EGD() const { return this->createRangeFromIndex( 4 ); } /** * @brief Return the energy release by delayed gammas and its uncertainty */ - auto delayedGammas() const { return this->EGD(); } + Piece delayedGammas() const { return this->EGD(); } /** * @brief Return the energy release by delayed betas and its uncertainty */ - auto EB() const { return this->createRangeFromIndex( 5 ); } + Piece EB() const { return this->createRangeFromIndex( 5 ); } /** * @brief Return the energy release by delayed betas and its uncertainty */ - auto delayedBetas() const { return this->EB(); } + Piece delayedBetas() const { return this->EB(); } /** * @brief Return the energy release by neutrinos and its uncertainty */ - auto ENU() const { return this->createRangeFromIndex( 6 ); } + Piece ENU() const { return this->createRangeFromIndex( 6 ); } /** * @brief Return the energy release by neutrinos and its uncertainty */ - auto neutrinos() const { return this->ENU(); } + Piece neutrinos() const { return this->ENU(); } /** * @brief Return the total energy release minus the neutrino energy and its * uncertainty */ - auto ER() const { return this->createRangeFromIndex( 7 ); } + Piece ER() const { return this->createRangeFromIndex( 7 ); } /** * @brief Return the total energy release minus the neutrino energy and its * uncertainty */ - auto totalMinusNeutrinos() const { return this->ER(); } + Piece totalMinusNeutrinos() const { return this->ER(); } /** * @brief Return the total energy release and its uncertainty */ - auto ET() const { return this->createRangeFromIndex( 8 ); } + Piece ET() const { return this->createRangeFromIndex( 8 ); } /** * @brief Return the total energy release and its uncertainty */ - auto total() const { return this->ET(); } + Piece total() const { return this->ET(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/1/458/PolynomialComponents/src/createRangeFromIndex.hpp b/src/ENDFtk/section/1/458/PolynomialComponents/src/createRangeFromIndex.hpp index 623252fe5..952249deb 100644 --- a/src/ENDFtk/section/1/458/PolynomialComponents/src/createRangeFromIndex.hpp +++ b/src/ENDFtk/section/1/458/PolynomialComponents/src/createRangeFromIndex.hpp @@ -1,7 +1,7 @@ -auto createRangeFromIndex( unsigned int i ) const { +Piece createRangeFromIndex( unsigned int i ) const { return ListRecord::list() - | ranges::view::chunk( 2 ) - | ranges::view::drop_exactly( i ) - | ranges::view::stride( 9 ); + | ranges::views::chunk( 2 ) + | ranges::views::drop_exactly( i ) + | ranges::views::stride( 9 ); } diff --git a/src/ENDFtk/section/1/458/TabulatedComponents.hpp b/src/ENDFtk/section/1/458/TabulatedComponents.hpp index 47dbb1912..0b4a76b2a 100644 --- a/src/ENDFtk/section/1/458/TabulatedComponents.hpp +++ b/src/ENDFtk/section/1/458/TabulatedComponents.hpp @@ -10,10 +10,17 @@ */ class TabulatedComponents { +public: + + /* type aliases */ + using OptionalEnergyReleaseComponent = std::optional< EnergyReleaseComponent >; + +private: + /* fields */ int nfc_; ThermalPointComponents values_; - std::array< std::optional< EnergyReleaseComponent >, 9 > components_; + std::array< OptionalEnergyReleaseComponent, 9 > components_; /* auxiliary functions */ #include "ENDFtk/section/1/458/TabulatedComponents/src/generateTables.hpp" @@ -67,12 +74,15 @@ class TabulatedComponents { /** * @brief Return the tabulated kinetic energy of the fission fragments */ - const auto& tabulated() const { return this->components_; } + const std::array< OptionalEnergyReleaseComponent, 9 >& tabulated() const { + + return this->components_; + } /** * @brief Return the tabulated kinetic energy of the fission fragments */ - const auto& tabulatedEFR() const { + const OptionalEnergyReleaseComponent& tabulatedEFR() const { return std::get< 0 >( this->components_ ); } @@ -80,12 +90,15 @@ class TabulatedComponents { /** * @brief Return the tabulated kinetic energy of the fission fragments */ - const auto& tabulatedFissionFragments() const { return this->tabulatedEFR(); } + const OptionalEnergyReleaseComponent& tabulatedFissionFragments() const { + + return this->tabulatedEFR(); + } /** * @brief Return the tabulated kinetic energy of the prompt fission neutrons */ - const auto& tabulatedENP() const { + const OptionalEnergyReleaseComponent& tabulatedENP() const { return std::get< 1 >( this->components_ ); } @@ -93,12 +106,15 @@ class TabulatedComponents { /** * @brief Return the tabulated kinetic energy of the prompt fission neutrons */ - const auto& tabulatedPromptNeutrons() const { return this->tabulatedENP(); } + const OptionalEnergyReleaseComponent& tabulatedPromptNeutrons() const { + + return this->tabulatedENP(); + } /** * @brief Return the tabulated kinetic energy of the delayed fission neutrons */ - const auto& tabulatedEND() const { + const OptionalEnergyReleaseComponent& tabulatedEND() const { return std::get< 2 >( this->components_ ); } @@ -106,12 +122,15 @@ class TabulatedComponents { /** * @brief Return the tabulated kinetic energy of the delayed fission neutrons */ - const auto& tabulatedDelayedNeutrons() const { return this->tabulatedEND(); } + const OptionalEnergyReleaseComponent& tabulatedDelayedNeutrons() const { + + return this->tabulatedEND(); + } /** * @brief Return the tabulated energy release by prompt gammas */ - const auto& tabulatedEGP() const { + const OptionalEnergyReleaseComponent& tabulatedEGP() const { return std::get< 3 >( this->components_ ); } @@ -119,12 +138,15 @@ class TabulatedComponents { /** * @brief Return the tabulated energy release by prompt gammas */ - const auto& tabulatedPromptGammas() const { return this->tabulatedEGP(); } + const OptionalEnergyReleaseComponent& tabulatedPromptGammas() const { + + return this->tabulatedEGP(); + } /** * @brief Return the tabulated energy release by delayed gammas */ - const auto& tabulatedEGD() const { + const OptionalEnergyReleaseComponent& tabulatedEGD() const { return std::get< 4 >( this->components_ ); } @@ -132,12 +154,15 @@ class TabulatedComponents { /** * @brief Return the tabulated energy release by delayed gammas */ - const auto& tabulatedDelayedGammas() const { return this->tabulatedEGD(); } + const OptionalEnergyReleaseComponent& tabulatedDelayedGammas() const { + + return this->tabulatedEGD(); + } /** * @brief Return the tabulated energy release by delayed betas */ - const auto& tabulatedEB() const { + const OptionalEnergyReleaseComponent& tabulatedEB() const { return std::get< 5 >( this->components_ ); } @@ -145,12 +170,15 @@ class TabulatedComponents { /** * @brief Return the tabulated energy release by delayed betas */ - const auto& tabulatedDelayedBetas() const { return this->tabulatedEB(); } + const OptionalEnergyReleaseComponent& tabulatedDelayedBetas() const { + + return this->tabulatedEB(); + } /** * @brief Return the tabulated energy release by neutrinos */ - const auto& tabulatedENU() const { + const OptionalEnergyReleaseComponent& tabulatedENU() const { return std::get< 6 >( this->components_ ); } @@ -158,12 +186,15 @@ class TabulatedComponents { /** * @brief Return the tabulated energy release by neutrinos */ - const auto& tabulatedNeutrinos() const { return this->tabulatedENU(); } + const OptionalEnergyReleaseComponent& tabulatedNeutrinos() const { + + return this->tabulatedENU(); + } /** * @brief Return the tabulated total energy release minus the neutrino energy */ - const auto& tabulatedER() const { + const OptionalEnergyReleaseComponent& tabulatedER() const { return std::get< 7 >( this->components_ ); } @@ -171,7 +202,7 @@ class TabulatedComponents { /** * @brief Return the tabulated total energy release minus the neutrino energy */ - const auto& tabulatedTotalMinusNeutrinos() const { + const OptionalEnergyReleaseComponent& tabulatedTotalMinusNeutrinos() const { return this->tabulatedER(); } @@ -179,7 +210,7 @@ class TabulatedComponents { /** * @brief Return the tabulated total energy release */ - const auto& tabulatedET() const { + const OptionalEnergyReleaseComponent& tabulatedET() const { return std::get< 8 >( this->components_ ); } @@ -187,7 +218,10 @@ class TabulatedComponents { /** * @brief Return the tabulated total energy release */ - const auto& tabulatedTotal() const { return this->tabulatedET(); } + const OptionalEnergyReleaseComponent& tabulatedTotal() const { + + return this->tabulatedET(); + } #include "ENDFtk/section/1/458/TabulatedComponents/src/NC.hpp" #include "ENDFtk/section/1/458/TabulatedComponents/src/print.hpp" diff --git a/src/ENDFtk/section/1/458/ThermalPointComponents.hpp b/src/ENDFtk/section/1/458/ThermalPointComponents.hpp index 6e71f6bd0..f7577f0a9 100644 --- a/src/ENDFtk/section/1/458/ThermalPointComponents.hpp +++ b/src/ENDFtk/section/1/458/ThermalPointComponents.hpp @@ -55,9 +55,9 @@ class ThermalPointComponents : protected ListRecord { * This returns a range of pairs (the energy release value and its * uncertainty) */ - auto E() const { + ChunkRange< AllRange< double > > E() const { - return ListRecord::list() | ranges::view::chunk( 2 ); + return ListRecord::list() | ranges::views::chunk( 2 ); } /** @@ -66,105 +66,105 @@ class ThermalPointComponents : protected ListRecord { * This returns a range of pairs (the energy release value and its * uncertainty) */ - auto energyRelease() const { return this->E(); } + ChunkRange< AllRange< double > > energyRelease() const { return this->E(); } /** * @brief Return the kinetic energy of the fission fragments and its * uncertainty */ - auto EFR() const { return this->E()[0]; } + Chunk< AllRange< double > > EFR() const { return this->E()[0]; } /** * @brief Return the kinetic energy of the fission fragments and its * uncertainty */ - auto fissionFragments() const { return this->EFR(); } + Chunk< AllRange< double > > fissionFragments() const { return this->EFR(); } /** * @brief Return the kinetic energy of the prompt fission neutrons and its * uncertainty */ - auto ENP() const { return this->E()[1]; } + Chunk< AllRange< double > > ENP() const { return this->E()[1]; } /** * @brief Return the kinetic energy of the prompt fission neutrons and its * uncertainty */ - auto promptNeutrons() const { return this->ENP(); } + Chunk< AllRange< double > > promptNeutrons() const { return this->ENP(); } /** * @brief Return the kinetic energy of the delayed fission neutrons and its * uncertainty */ - auto END() const { return this->E()[2]; } + Chunk< AllRange< double > > END() const { return this->E()[2]; } /** * @brief Return the kinetic energy of the delayed fission neutrons and its * uncertainty */ - auto delayedNeutrons() const { return this->END(); } + Chunk< AllRange< double > > delayedNeutrons() const { return this->END(); } /** * @brief Return the energy release by prompt gammas and its uncertainty */ - auto EGP() const { return this->E()[3]; } + Chunk< AllRange< double > > EGP() const { return this->E()[3]; } /** * @brief Return the energy release by prompt gammas and its uncertainty */ - auto promptGammas() const { return this->EGP(); } + Chunk< AllRange< double > > promptGammas() const { return this->EGP(); } /** * @brief Return the energy release by delayed gammas and its uncertainty */ - auto EGD() const { return this->E()[4]; } + Chunk< AllRange< double > > EGD() const { return this->E()[4]; } /** * @brief Return the energy release by delayed gammas and its uncertainty */ - auto delayedGammas() const { return this->EGD(); } + Chunk< AllRange< double > > delayedGammas() const { return this->EGD(); } /** * @brief Return the energy release by delayed betas and its uncertainty */ - auto EB() const { return this->E()[5]; } + Chunk< AllRange< double > > EB() const { return this->E()[5]; } /** * @brief Return the energy release by delayed betas and its uncertainty */ - auto delayedBetas() const { return this->EB(); } + Chunk< AllRange< double > > delayedBetas() const { return this->EB(); } /** * @brief Return the energy release by neutrinos and its uncertainty */ - auto ENU() const { return this->E()[6]; } + Chunk< AllRange< double > > ENU() const { return this->E()[6]; } /** * @brief Return the energy release by neutrinos and its uncertainty */ - auto neutrinos() const { return this->ENU(); } + Chunk< AllRange< double > > neutrinos() const { return this->ENU(); } /** * @brief Return the total energy release minus the neutrino energy and its * uncertainty */ - auto ER() const { return this->E()[7]; } + Chunk< AllRange< double > > ER() const { return this->E()[7]; } /** * @brief Return the total energy release minus the neutrino energy and its * uncertainty */ - auto totalMinusNeutrinos() const { return this->ER(); } + Chunk< AllRange< double > > totalMinusNeutrinos() const { return this->ER(); } /** * @brief Return the total energy release and its uncertainty */ - auto ET() const { return this->E()[8]; } + Chunk< AllRange< double > > ET() const { return this->E()[8]; } /** * @brief Return the total energy release and its uncertainty */ - auto total() const { return this->ET(); } + Chunk< AllRange< double > > total() const { return this->ET(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/1/460/ContinuousPhotons.hpp b/src/ENDFtk/section/1/460/ContinuousPhotons.hpp index 531f0c78b..7d19e7fe0 100644 --- a/src/ENDFtk/section/1/460/ContinuousPhotons.hpp +++ b/src/ENDFtk/section/1/460/ContinuousPhotons.hpp @@ -49,12 +49,12 @@ class ContinuousPhotons : protected ListRecord { /** * @brief Return the decay constants for all precursor families */ - auto lambdas() const { return ListRecord::list(); } + AllRange< double > lambdas() const { return ListRecord::list(); } /** * @brief Return the decay constants for all precursor families */ - auto decayConstants() const { return this->lambdas(); } + AllRange< double > decayConstants() const { return this->lambdas(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/1/460/DiscretePhotonMultiplicity.hpp b/src/ENDFtk/section/1/460/DiscretePhotonMultiplicity.hpp index 9dc49f4ca..667357317 100644 --- a/src/ENDFtk/section/1/460/DiscretePhotonMultiplicity.hpp +++ b/src/ENDFtk/section/1/460/DiscretePhotonMultiplicity.hpp @@ -36,12 +36,12 @@ class DiscretePhotonMultiplicity : protected TabulationRecord { /** * @brief Return the time values */ - auto time() const { return TabulationRecord::x(); } + AllRange< double > time() const { return TabulationRecord::x(); } /** * @brief Return the time dependent multiplicity values (in units of 1/s) */ - auto multiplicities() const { return TabulationRecord::y(); } + AllRange< double > multiplicities() const { return TabulationRecord::y(); } using TabulationRecord::x; using TabulationRecord::y; diff --git a/src/ENDFtk/section/1/460/DiscretePhotons.hpp b/src/ENDFtk/section/1/460/DiscretePhotons.hpp index be4da363a..5556f6022 100644 --- a/src/ENDFtk/section/1/460/DiscretePhotons.hpp +++ b/src/ENDFtk/section/1/460/DiscretePhotons.hpp @@ -42,7 +42,10 @@ class DiscretePhotons { /** * @brief Return the discrete photon data */ - auto photons() const { return ranges::view::all( this->photons_ ); } + AllRange< DiscretePhotonMultiplicity > photons() const { + + return ranges::cpp20::views::all( this->photons_ ); + } #include "ENDFtk/section/1/460/DiscretePhotons/src/NC.hpp" #include "ENDFtk/section/1/460/DiscretePhotons/src/print.hpp" diff --git a/src/ENDFtk/section/1/PolynomialMultiplicity.hpp b/src/ENDFtk/section/1/PolynomialMultiplicity.hpp index 05f070472..2efa10d7e 100644 --- a/src/ENDFtk/section/1/PolynomialMultiplicity.hpp +++ b/src/ENDFtk/section/1/PolynomialMultiplicity.hpp @@ -51,12 +51,12 @@ namespace section{ /** * @brief Return the coefficients */ - auto C() const { return ListRecord::list(); } + AllRange< double > C() const { return ListRecord::list(); } /** * @brief Return the coefficients */ - auto coefficients() const { return this->C(); } + AllRange< double > coefficients() const { return this->C(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/1/PolynomialMultiplicity/test/CMakeLists.txt b/src/ENDFtk/section/1/PolynomialMultiplicity/test/CMakeLists.txt index 0fa5f1096..201726c9c 100644 --- a/src/ENDFtk/section/1/PolynomialMultiplicity/test/CMakeLists.txt +++ b/src/ENDFtk/section/1/PolynomialMultiplicity/test/CMakeLists.txt @@ -1,6 +1,6 @@ -add_executable( ENDFtk.section.1.Polynomial.test PolynomialMultiplicity.test.cpp ) -target_compile_options( ENDFtk.section.1.Polynomial.test PRIVATE ${${PREFIX}_common_flags} +add_executable( ENDFtk.section.1.PolynomialMultiplicity.test PolynomialMultiplicity.test.cpp ) +target_compile_options( ENDFtk.section.1.PolynomialMultiplicity.test PRIVATE ${${PREFIX}_common_flags} $<$:${${PREFIX}_strict_flags}>$<$: ${${PREFIX}_DEBUG_flags} $<$:${${PREFIX}_coverage_flags}>> @@ -10,5 +10,5 @@ $<$:${${PREFIX}_link_time_optimization_flags}> $<$:${${PREFIX}_nonportable_optimization_flags}>> ${CXX_appended_flags} ${ENDFtk_appended_flags} ) -target_link_libraries( ENDFtk.section.1.Polynomial.test PUBLIC ENDFtk ) -add_test( NAME ENDFtk.section.1.Polynomial COMMAND ENDFtk.section.1.Polynomial.test ) +target_link_libraries( ENDFtk.section.1.PolynomialMultiplicity.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.1.PolynomialMultiplicity COMMAND ENDFtk.section.1.PolynomialMultiplicity.test ) diff --git a/src/ENDFtk/section/1/TabulatedMultiplicity.hpp b/src/ENDFtk/section/1/TabulatedMultiplicity.hpp index 355d9c1af..ef9bb11d9 100644 --- a/src/ENDFtk/section/1/TabulatedMultiplicity.hpp +++ b/src/ENDFtk/section/1/TabulatedMultiplicity.hpp @@ -41,22 +41,22 @@ namespace section{ /** * @brief Return the incident energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the incident energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the fission multiplicity values */ - auto NU() const { return TabulationRecord::y(); } + AllRange< double > NU() const { return TabulationRecord::y(); } /** * @brief Return the fission multiplicity values */ - auto multiplicities() const { return this->NU(); } + AllRange< double > multiplicities() const { return this->NU(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/10.hpp b/src/ENDFtk/section/10.hpp new file mode 100644 index 000000000..de1907367 --- /dev/null +++ b/src/ENDFtk/section/10.hpp @@ -0,0 +1,84 @@ +#ifndef NJOY_ENDFTK_SECTION_10 +#define NJOY_ENDFTK_SECTION_10 + +// system includes + +// other includes +#include "ENDFtk/ControlRecord.hpp" +#include "ENDFtk/TabulationRecord.hpp" +#include "ENDFtk/readSequence.hpp" +#include "ENDFtk/section.hpp" + +namespace njoy { +namespace ENDFtk { +namespace section{ + + /** + * @class + * @brief MF10 - cross sections for radioactive nuclide production + * + * See ENDF102, section 10.2 for more information. + */ + template<> + class Type< 10 > : protected Base { + + public: + + #include "ENDFtk/section/10/ReactionProduct.hpp" + + private: + + /* fields */ + int lis_; + std::vector< ReactionProduct > products_; + + public: + + /* constructor */ + #include "ENDFtk/section/10/src/ctor.hpp" + + /* methods */ + + /** + * @brief Return the excited level number of the target + */ + int LIS() const { return this->lis_; } + + /** + * @brief Return the excited level number of the target + */ + int excitedLevel() const { return this->LIS(); } + + /** + * @brief Return the number of excited states for the reaction product + */ + int NS() const { return this->products_.size(); } + + /** + * @brief Return the number of excited states for the reaction product + */ + int numberReactionProducts() const { return this->NS(); } + + /** + * @brief Return the reaction product data + */ + AllRange< ReactionProduct > reactionProducts() const { + + return ranges::cpp20::views::all( this->products_ ); + } + + #include "ENDFtk/section/10/src/NC.hpp" + #include "ENDFtk/section/10/src/print.hpp" + + using Base::MT; + using Base::sectionNumber; + using Base::ZA; + using Base::atomicWeightRatio; + using Base::AWR; + }; + +} // section namespace +} // ENDFtk namespace +} // njoy namespace + +#endif diff --git a/src/ENDFtk/section/10/ReactionProduct.hpp b/src/ENDFtk/section/10/ReactionProduct.hpp new file mode 100644 index 000000000..251e9e1dd --- /dev/null +++ b/src/ENDFtk/section/10/ReactionProduct.hpp @@ -0,0 +1,87 @@ +/** + * @class + * @brief The reaction product data : Q values and multiplicities + * + * See ENDF102, section 10.2 for more information. + */ +class ReactionProduct : protected TabulationRecord { + + /* auxiliary functions */ + +public: + + /* constructor */ + #include "ENDFtk/section/10/ReactionProduct/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return the mass difference Q value + */ + double QM() const { return TabulationRecord::C1(); } + + /** + * @brief Return the mass difference Q value + */ + double massDifferenceQValue() const { return this->QM(); } + + /** + * @brief Return the reaction Q value + */ + double QI() const { return TabulationRecord::C2(); } + + /** + * @brief Return the reaction Q value + */ + double reactionQValue() const { return this->QI(); } + + /** + * @brief Return the ZA identifier for the product nucleus + */ + int IZAP() const { return TabulationRecord::L1(); } + + /** + * @brief Return the ZA identifier for the product nucleus + */ + int productIdentifier() const { return this->IZAP(); } + + /** + * @brief Return the excited level number of the product + */ + int LFS() const { return TabulationRecord::L2(); } + + /** + * @brief Return the excited level number of the product + */ + int excitedLevel() const { return this->LFS(); } + + /** + * @brief Return the incident energy values + */ + AllRange< double > E() const { return TabulationRecord::x(); } + + /** + * @brief Return the incident energy values + */ + AllRange< double > energies() const { return this->E(); } + + /** + * @brief Return the multiplicity values + */ + AllRange< double > XS() const { return TabulationRecord::y(); } + + /** + * @brief Return the multiplicity values + */ + AllRange< double > crossSections() const { return this->XS(); } + + using TabulationRecord::NR; + using TabulationRecord::NP; + using TabulationRecord::interpolants; + using TabulationRecord::boundaries; + using TabulationRecord::x; + using TabulationRecord::y; + using TabulationRecord::regions; + using TabulationRecord::NC; + using TabulationRecord::print; +}; diff --git a/src/ENDFtk/section/10/ReactionProduct/src/ctor.hpp b/src/ENDFtk/section/10/ReactionProduct/src/ctor.hpp new file mode 100644 index 000000000..c4d8fc566 --- /dev/null +++ b/src/ENDFtk/section/10/ReactionProduct/src/ctor.hpp @@ -0,0 +1,51 @@ +/** + * @brief Constructor + * + * @param[in] qm the mass difference Q value + * @param[in] qi the reaction Q value + * @param[in] izap the za identifier of the product + * @param[in] lfs the excited level number + * @param[in] boundaries the interpolation range boundaries + * @param[in] interpolants the interpolation types for each range + * @param[in] energies the energy values + * @param[in] xs the cross section values + */ +ReactionProduct( double qm, double qi, long izap, long lfs, + std::vector< long >&& boundaries, + std::vector< long >&& interpolants, + std::vector< double >&& energies, + std::vector< double >&& xs ) + try : TabulationRecord( qm, qi, izap, lfs, + std::move( boundaries ), + std::move( interpolants ), + std::move( energies ), + std::move( xs ) ) {} + catch ( std::exception& e ) { + + Log::info( "Encountered error while constructing a radioactive reaction " + "product" ); + throw; + } + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + * @param[in] MF the expected MF number + * @param[in] MT the expected MT number + */ +template< typename Iterator > +ReactionProduct( Iterator& begin, const Iterator& end, + long& lineNumber, int MAT, int MF, int MT ) + try : TabulationRecord( begin, end, lineNumber, MAT, MF, MT ) {} + catch ( std::exception& e ) { + + Log::info( "Encountered error while constructing a radioactive reaction " + "product" ); + throw; + } diff --git a/src/ENDFtk/section/10/ReactionProduct/test/CMakeLists.txt b/src/ENDFtk/section/10/ReactionProduct/test/CMakeLists.txt new file mode 100644 index 000000000..5a6dc3aeb --- /dev/null +++ b/src/ENDFtk/section/10/ReactionProduct/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.10.ReactionProduct.test ReactionProduct.test.cpp ) +target_compile_options( ENDFtk.section.10.ReactionProduct.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.10.ReactionProduct.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.10.ReactionProduct COMMAND ENDFtk.section.10.ReactionProduct.test ) diff --git a/src/ENDFtk/section/10/ReactionProduct/test/ReactionProduct.test.cpp b/src/ENDFtk/section/10/ReactionProduct/test/ReactionProduct.test.cpp new file mode 100644 index 000000000..2ce22d6d0 --- /dev/null +++ b/src/ENDFtk/section/10/ReactionProduct/test/ReactionProduct.test.cpp @@ -0,0 +1,174 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/10.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using ReactionProduct = section::Type< 10 >::ReactionProduct; + +std::string chunk(); +void verifyChunk( const ReactionProduct& ); +std::string invalidChunk(); + +SCENARIO( "ReactionProduct" ) { + + GIVEN( "valid data for a ReactionProduct" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double qm = 2.224648e+6; + double qi = 3.224648e+6; + long za = 95242; + long lfs = 2; + std::vector< long > boundaries = { 2 }; + std::vector< long > interpolants = { 5 }; + std::vector< double > x = { 1., 3. }; + std::vector< double > y = { 2., 4. }; + + ReactionProduct chunk( qm, qi, za, lfs, + std::move( boundaries ), + std::move( interpolants ), + std::move( x ), + std::move( y ) ); + + THEN( "a ReactionProduct can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9534, 10, 102 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + ReactionProduct chunk( begin, end, lineNumber, 9534, 10, 102 ); + + THEN( "a ReactionProduct can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9534, 10, 102 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a ReactionProduct" ) { + + WHEN( "inconsistent data is used" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + double qm = 2.224648e+6; + double qi = 3.224648e+6; + long za = 95242; + long lfs = 2; + std::vector< long > boundaries = { 2 }; + std::vector< long > wrongInterpolants = { 5, 2 }; + std::vector< double > x = { 1., 3. }; + std::vector< double > y = { 2., 4. }; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( ReactionProduct( qm, qi, za, lfs, + std::move( boundaries ), + std::move( wrongInterpolants ), + std::move( x ), + std::move( y ) ) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( ReactionProduct( begin, end, lineNumber, + 9534, 10, 102 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 2.224648+6 3.224648+6 95242 2 1 2953410102 \n" + " 2 5 953410102 \n" + " 1.000000+0 2.000000+0 3.000000+0 4.000000+0 953410102 \n"; +} + +void verifyChunk( const ReactionProduct& chunk ) { + + CHECK( 2.224648e+6 == Approx( chunk.QM() ) ); + CHECK( 2.224648e+6 == Approx( chunk.massDifferenceQValue() ) ); + CHECK( 3.224648e+6 == Approx( chunk.QI() ) ); + CHECK( 3.224648e+6 == Approx( chunk.reactionQValue() ) ); + CHECK( 95242 == chunk.IZAP() ); + CHECK( 95242 == chunk.productIdentifier() ); + CHECK( 2 == chunk.LFS() ); + CHECK( 2 == chunk.excitedLevel() ); + + CHECK( 2 == chunk.NP() ); + CHECK( 1 == chunk.NR() ); + CHECK( 1 == chunk.interpolants().size() ); + CHECK( 1 == chunk.boundaries().size() ); + CHECK( 5 == chunk.interpolants()[0] ); + CHECK( 2 == chunk.boundaries()[0] ); + CHECK( 2 == chunk.E().size() ); + CHECK( 2 == chunk.energies().size() ); + CHECK( 2 == chunk.x().size() ); + CHECK( 2 == chunk.XS().size() ); + CHECK( 2 == chunk.crossSections().size() ); + CHECK( 2 == chunk.y().size() ); + CHECK( 1. == Approx( chunk.E()[0] ) ); + CHECK( 3. == Approx( chunk.E()[1] ) ); + CHECK( 1. == Approx( chunk.energies()[0] ) ); + CHECK( 3. == Approx( chunk.energies()[1] ) ); + CHECK( 1. == Approx( chunk.x()[0] ) ); + CHECK( 3. == Approx( chunk.x()[1] ) ); + CHECK( 2. == Approx( chunk.XS()[0] ) ); + CHECK( 4. == Approx( chunk.XS()[1] ) ); + CHECK( 2. == Approx( chunk.crossSections()[0] ) ); + CHECK( 4. == Approx( chunk.crossSections()[1] ) ); + CHECK( 2. == Approx( chunk.y()[0] ) ); + CHECK( 4. == Approx( chunk.y()[1] ) ); + + CHECK( 3 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 2.224648+6 3.224648+6 95242 2 2 2953410102 \n" + " 2 2 953410102 \n" + " 1.000000-5 8.579050+0 3.000000+7 1.487778+1 953410102 \n"; +} diff --git a/src/ENDFtk/section/10/src/NC.hpp b/src/ENDFtk/section/10/src/NC.hpp new file mode 100644 index 000000000..ca8eeeb7a --- /dev/null +++ b/src/ENDFtk/section/10/src/NC.hpp @@ -0,0 +1,12 @@ +/** + * @brief Return the number of lines in this MF10 component + */ +long NC() const { + + long NC = 1; + for ( const auto& entry : this->products_ ) { + + NC += entry.NC(); + } + return NC; +}; diff --git a/src/ENDFtk/section/10/src/ctor.hpp b/src/ENDFtk/section/10/src/ctor.hpp new file mode 100644 index 000000000..9f278573b --- /dev/null +++ b/src/ENDFtk/section/10/src/ctor.hpp @@ -0,0 +1,44 @@ +/** + * @brief Constructor + * + * @param[in] mt the MT number + * @param[in] zaid the ZA identifier + * @param[in] awr the atomic mass ratio + * @param[in] lis the target's excited level + * @param[in] products the reaction products (at least 1) + */ +Type( int mt, double zaid, double awr, long lis, + std::vector< ReactionProduct >&& products ) : + Base( zaid, awr, mt ), lis_( lis ), products_( std::move( products ) ) {} + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] head the head record of the section + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + */ +template< typename Iterator > +Type ( HEAD& head, + Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT ) + try: Type( head.MT(), head.ZA(), head.AWR(), head.L1(), + readSequence< ReactionProduct >( begin, end, lineNumber, + MAT, 10, head.MT(), + head.N1() ) ) { + + readSEND(begin, end, lineNumber, MAT, 10 ); + } + catch( std::exception& e ) { + + Log::info + ( "Encountered error while reading section {} of file 10 of material {}", + head.MT(), MAT ); + throw e; + } diff --git a/src/ENDFtk/section/10/src/print.hpp b/src/ENDFtk/section/10/src/print.hpp new file mode 100644 index 000000000..234683ce7 --- /dev/null +++ b/src/ENDFtk/section/10/src/print.hpp @@ -0,0 +1,22 @@ +/** + * @brief Print this MF10 component + * + * @tparam OutputIterator an output iterator + * + * @param[in] it the current position in the output + * @param[in] MAT the MAT number + * @param[in] MF the MF number + */ +template< typename OutputIterator > +void print( OutputIterator& it, int MAT, int MF ) const { + + int MT = this->MT(); + ControlRecord( this->ZA(), this->AWR(), + this->LIS(), 0, + this->products_.size(), 0 ).print( it, MAT, MF, MT ); + for ( const auto& entry : this->products_ ) { + + entry.print( it, MAT, MF, MT ); + } + SEND( MAT, MF ).print( it ); +} diff --git a/src/ENDFtk/section/10/test/10.test.cpp b/src/ENDFtk/section/10/test/10.test.cpp new file mode 100644 index 000000000..8f307ad54 --- /dev/null +++ b/src/ENDFtk/section/10/test/10.test.cpp @@ -0,0 +1,242 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/10.hpp" + +// other includes +#include "ENDFtk/tree/Section.hpp" + +// convenience typedefs +using namespace njoy::ENDFtk; +using ReactionProduct = section::Type< 10 >::ReactionProduct; + +std::string chunk(); +void verifyChunk( const section::Type< 10 >& ); +std::string validSEND(); +std::string invalidSEND(); + +SCENARIO( "section::Type< 10 >" ) { + + GIVEN( "valid data for a section::Type< 10 >" ) { + + std::string sectionString = chunk() + validSEND(); + + WHEN( "the data is given explicitly" ) { + + int mt = 102; + int zaid = 95241; + int lis = 0; + double awr = 2.389860e+2; + + std::vector< ReactionProduct > products = { + + ReactionProduct( 5.537755e+6, 5.537755e+6, 95242, 0, + { 2 }, { 3 }, { 1e-5, 3e+7 }, { 0.9, 0.52 } ), + ReactionProduct( 5.537755e+6, 5.489125e+6, 95242, 2, + { 2 }, { 3 }, { 1e-5, 3e+7 }, { 0.1, 0.48 } ) }; + + section::Type< 10 > chunk( mt, zaid, awr, lis, + std::move( products ) ); + + THEN( "a section::Type< 10 > can be constructed and " + "members can be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9543, 10 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 0; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 10 > chunk( head, begin, end, lineNumber, 9543 ); + + THEN( "a section::Type< 10 > can be constructed and " + "members can be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9543, 10 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "there is a tree::Section" ) { + + std::string sectionString = chunk() + validSEND(); + auto begin = sectionString.begin(); + auto position = begin; + auto end = sectionString.end(); + long lineNumber = 0; + auto head = HEAD( position, end, lineNumber ); + tree::Section< std::string::iterator > + section( head, begin, position, end, lineNumber ); + + section::Type< 10 > chunk = section.parse< 10 >(); + section::Type< 10 > chunk2 = section.parse< 10 >( lineNumber ); + section::Type< 10 > chunk3 = section.parse( 10_c ); + section::Type< 10 > chunk4 = section.parse( 10_c, lineNumber ); + + THEN( "a section::Type< 10 > can be constructed and " + "members can be tested" ) { + + verifyChunk( chunk ); + verifyChunk( chunk2 ); + verifyChunk( chunk3 ); + verifyChunk( chunk4 ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + std::string buffer2; + std::string buffer3; + std::string buffer4; + auto output = std::back_inserter( buffer ); + auto output2 = std::back_inserter( buffer2 ); + auto output3 = std::back_inserter( buffer3 ); + auto output4 = std::back_inserter( buffer4 ); + chunk.print( output, 9543, 10 ); + chunk2.print( output2, 9543, 10 ); + chunk3.print( output3, 9543, 10 ); + chunk4.print( output4, 9543, 10 ); + + CHECK( buffer == sectionString ); + CHECK( buffer2 == sectionString ); + CHECK( buffer3 == sectionString ); + CHECK( buffer4 == sectionString ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a section::Type< 10 >" ) { + + WHEN( "a string representation of a section::Type< 10 > with " + "an invalid SEND" ) { + + std::string sectionString = chunk() + invalidSEND(); + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + THEN( "an exception is thrown" ){ + + CHECK_THROWS( section::Type< 10 >( head, begin, end, + lineNumber, 9543 ) ); + } // THEN + } // WHEN + } // THEN +} // SCENARIO + +std::string chunk() { + + return + " 9.524100+4 2.389860+2 0 0 2 0954310102 \n" + " 5.537755+6 5.537755+6 95242 0 1 2954310102 \n" + " 2 3 954310102 \n" + " 1.000000-5 9.000000-1 3.000000+7 5.200000-1 954310102 \n" + " 5.537755+6 5.489125+6 95242 2 1 2954310102 \n" + " 2 3 954310102 \n" + " 1.000000-5 1.000000-1 3.000000+7 4.800000-1 954310102 \n"; +} + +void verifyChunk( const section::Type< 10 >& chunk ) { + + CHECK( 102 == chunk.MT() ); + CHECK( 95241 == chunk.ZA() ); + CHECK( 2.389860e+2 == Approx( chunk.AWR() ) ); + CHECK( 2.389860e+2 == Approx( chunk.atomicWeightRatio() ) ); + CHECK( 0 == chunk.LIS() ); + CHECK( 0 == chunk.excitedLevel() ); + CHECK( 2 == chunk.NS() ); + CHECK( 2 == chunk.numberReactionProducts() ); + + CHECK( 2 == chunk.reactionProducts().size() ); + + auto product = chunk.reactionProducts()[0]; + CHECK( 5.537755e+6 == Approx( product.QM() ) ); + CHECK( 5.537755e+6 == Approx( product.massDifferenceQValue() ) ); + CHECK( 5.537755e+6 == Approx( product.QI() ) ); + CHECK( 5.537755e+6 == Approx( product.reactionQValue() ) ); + CHECK( 95242 == product.IZAP() ); + CHECK( 95242 == product.productIdentifier() ); + CHECK( 0 == product.LFS() ); + CHECK( 0 == product.excitedLevel() ); + CHECK( 2 == product.NP() ); + CHECK( 1 == product.NR() ); + CHECK( 1 == product.interpolants().size() ); + CHECK( 1 == product.boundaries().size() ); + CHECK( 3 == product.interpolants()[0] ); + CHECK( 2 == product.boundaries()[0] ); + CHECK( 2 == product.E().size() ); + CHECK( 2 == product.energies().size() ); + CHECK( 2 == product.XS().size() ); + CHECK( 2 == product.crossSections().size() ); + CHECK( 1e-5 == Approx( product.E()[0] ) ); + CHECK( 3e+7 == Approx( product.E()[1] ) ); + CHECK( 1e-5 == Approx( product.energies()[0] ) ); + CHECK( 3e+7 == Approx( product.energies()[1] ) ); + CHECK( 0.9 == Approx( product.XS()[0] ) ); + CHECK( 0.52 == Approx( product.XS()[1] ) ); + CHECK( 0.9 == Approx( product.crossSections()[0] ) ); + CHECK( 0.52 == Approx( product.crossSections()[1] ) ); + + product = chunk.reactionProducts()[1]; + CHECK( 5.537755e+6 == Approx( product.QM() ) ); + CHECK( 5.537755e+6 == Approx( product.massDifferenceQValue() ) ); + CHECK( 5.489125e+6 == Approx( product.QI() ) ); + CHECK( 5.489125e+6 == Approx( product.reactionQValue() ) ); + CHECK( 95242 == product.IZAP() ); + CHECK( 95242 == product.productIdentifier() ); + CHECK( 2 == product.LFS() ); + CHECK( 2 == product.excitedLevel() ); + CHECK( 2 == product.NP() ); + CHECK( 1 == product.NR() ); + CHECK( 1 == product.interpolants().size() ); + CHECK( 1 == product.boundaries().size() ); + CHECK( 3 == product.interpolants()[0] ); + CHECK( 2 == product.boundaries()[0] ); + CHECK( 2 == product.E().size() ); + CHECK( 2 == product.energies().size() ); + CHECK( 2 == product.XS().size() ); + CHECK( 2 == product.crossSections().size() ); + CHECK( 1e-5 == Approx( product.E()[0] ) ); + CHECK( 3e+7 == Approx( product.E()[1] ) ); + CHECK( 1e-5 == Approx( product.energies()[0] ) ); + CHECK( 3e+7 == Approx( product.energies()[1] ) ); + CHECK( 0.1 == Approx( product.XS()[0] ) ); + CHECK( 0.48 == Approx( product.XS()[1] ) ); + CHECK( 0.1 == Approx( product.crossSections()[0] ) ); + CHECK( 0.48 == Approx( product.crossSections()[1] ) ); + + CHECK( 7 == chunk.NC() ); +} + +std::string validSEND(){ + return + " 954310 0 \n"; +} + +std::string invalidSEND(){ + return + " 954310 1 \n"; +} diff --git a/src/ENDFtk/section/10/test/CMakeLists.txt b/src/ENDFtk/section/10/test/CMakeLists.txt new file mode 100644 index 000000000..bb4b06af2 --- /dev/null +++ b/src/ENDFtk/section/10/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.10.test 10.test.cpp ) +target_compile_options( ENDFtk.section.10.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.10.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.10 COMMAND ENDFtk.section.10.test ) diff --git a/src/ENDFtk/section/12.hpp b/src/ENDFtk/section/12.hpp index fab58a89d..97442cea0 100644 --- a/src/ENDFtk/section/12.hpp +++ b/src/ENDFtk/section/12.hpp @@ -76,7 +76,7 @@ namespace section{ /** * @brief Return the photon production data */ - const auto& photonProduction() const { return this->photon_; } + const PhotonProduction& photonProduction() const { return this->photon_; } #include "ENDFtk/section/12/src/NC.hpp" #include "ENDFtk/section/12/src/print.hpp" diff --git a/src/ENDFtk/section/12/Multiplicities.hpp b/src/ENDFtk/section/12/Multiplicities.hpp index 2f01fa07d..9d82db836 100644 --- a/src/ENDFtk/section/12/Multiplicities.hpp +++ b/src/ENDFtk/section/12/Multiplicities.hpp @@ -12,6 +12,13 @@ */ class Multiplicities { +public: + + /* type aliases */ + using OptionalTotalMultiplicity = std::optional< TotalMultiplicity >; + +private: + /* fields */ std::optional< TotalMultiplicity > total_; std::vector< PartialMultiplicity > partials_; @@ -38,28 +45,31 @@ class Multiplicities { int representation() const { return this->LO(); } /** - * @brief Return the number of partial multiplicities (discrete photons - * and continuum) + * @brief Return the number of photons (discrete and continuum) with + * partial multiplicities */ int NK() const { return this->partials_.size(); } /** - * @brief Return the number of partial multiplicities (discrete photons - * and continuum) + * @brief Return the number of photons (discrete and continuum) with + * partial multiplicities */ - int numberPartials() const { return this->NK(); } + int numberPhotons() const { return this->NK(); } /** * @brief Return the total multiplicity (optional) */ - const auto& totalMultiplicity() const { return this->total_; } + const OptionalTotalMultiplicity& totalMultiplicity() const { + + return this->total_; + } /** * @brief Return the partial multiplicities */ - auto partialMultiplicities() const { + AllRange< PartialMultiplicity > photonPartialMultiplicities() const { - return ranges::view::all( this->partials_ ); + return ranges::cpp20::views::all( this->partials_ ); } #include "ENDFtk/section/12/Multiplicities/src/NC.hpp" diff --git a/src/ENDFtk/section/12/Multiplicities/src/NC.hpp b/src/ENDFtk/section/12/Multiplicities/src/NC.hpp index 5404f3437..8dfb063d8 100644 --- a/src/ENDFtk/section/12/Multiplicities/src/NC.hpp +++ b/src/ENDFtk/section/12/Multiplicities/src/NC.hpp @@ -9,4 +9,4 @@ long NC() const { NC += entry.NC(); } return NC; -}; +} diff --git a/src/ENDFtk/section/12/Multiplicities/test/Multiplicities.test.cpp b/src/ENDFtk/section/12/Multiplicities/test/Multiplicities.test.cpp index 5d0e53a28..65bbb1296 100644 --- a/src/ENDFtk/section/12/Multiplicities/test/Multiplicities.test.cpp +++ b/src/ENDFtk/section/12/Multiplicities/test/Multiplicities.test.cpp @@ -157,14 +157,14 @@ std::string chunkWithOnePartial() { void verifyChunkWithOnePartial( const Multiplicities& chunk ) { CHECK( std::nullopt == chunk.totalMultiplicity() ); - CHECK( 1 == chunk.partialMultiplicities().size() ); + CHECK( 1 == chunk.photonPartialMultiplicities().size() ); CHECK( 1 == chunk.NK() ); - CHECK( 1 == chunk.numberPartials() ); + CHECK( 1 == chunk.numberPhotons() ); CHECK( 1 == chunk.LO() ); CHECK( 1 == chunk.representation() ); - auto partial = chunk.partialMultiplicities()[0]; + auto partial = chunk.photonPartialMultiplicities()[0]; CHECK( 0.0 == Approx( partial.EG() ) ); CHECK( 0.0 == Approx( partial.photonOrBindingEnergy() ) ); CHECK( 0.0 == Approx( partial.ES() ) ); @@ -205,9 +205,9 @@ std::string chunkWithMultiplePartials() { void verifyChunkWithMultiplePartials( const Multiplicities& chunk ) { CHECK( std::nullopt != chunk.totalMultiplicity() ); - CHECK( 2 == chunk.partialMultiplicities().size() ); + CHECK( 2 == chunk.photonPartialMultiplicities().size() ); CHECK( 2 == chunk.NK() ); - CHECK( 2 == chunk.numberPartials() ); + CHECK( 2 == chunk.numberPhotons() ); CHECK( 1 == chunk.LO() ); CHECK( 1 == chunk.representation() ); @@ -225,7 +225,7 @@ void verifyChunkWithMultiplePartials( const Multiplicities& chunk ) { CHECK( 10. == Approx( total.multiplicities()[0] ) ); CHECK( 15. == Approx( total.multiplicities()[1] ) ); - auto partial = chunk.partialMultiplicities()[0]; + auto partial = chunk.photonPartialMultiplicities()[0]; CHECK( 0.0 == Approx( partial.EG() ) ); CHECK( 0.0 == Approx( partial.photonOrBindingEnergy() ) ); CHECK( 0.0 == Approx( partial.ES() ) ); @@ -247,7 +247,7 @@ void verifyChunkWithMultiplePartials( const Multiplicities& chunk ) { CHECK( 8.579050e+0 == Approx( partial.multiplicities()[0] ) ); CHECK( 1.487778e+1 == Approx( partial.multiplicities()[1] ) ); - partial = chunk.partialMultiplicities()[1]; + partial = chunk.photonPartialMultiplicities()[1]; CHECK( 0.0 == Approx( partial.EG() ) ); CHECK( 0.0 == Approx( partial.photonOrBindingEnergy() ) ); CHECK( 0.0 == Approx( partial.ES() ) ); diff --git a/src/ENDFtk/section/12/PartialMultiplicity.hpp b/src/ENDFtk/section/12/PartialMultiplicity.hpp index ac1878150..8d0407d08 100644 --- a/src/ENDFtk/section/12/PartialMultiplicity.hpp +++ b/src/ENDFtk/section/12/PartialMultiplicity.hpp @@ -58,22 +58,22 @@ class PartialMultiplicity : protected TabulationRecord { /** * @brief Return the incident energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the incident energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the multiplicity values */ - auto Y() const { return TabulationRecord::y(); } + AllRange< double > Y() const { return TabulationRecord::y(); } /** * @brief Return the multiplicity values */ - auto multiplicities() const { return this->Y(); } + AllRange< double > multiplicities() const { return this->Y(); } using TabulationRecord::NR; using TabulationRecord::NP; diff --git a/src/ENDFtk/section/12/TotalMultiplicity.hpp b/src/ENDFtk/section/12/TotalMultiplicity.hpp index 22c377127..dc9b6ee2f 100644 --- a/src/ENDFtk/section/12/TotalMultiplicity.hpp +++ b/src/ENDFtk/section/12/TotalMultiplicity.hpp @@ -18,22 +18,22 @@ class TotalMultiplicity : protected TabulationRecord { /** * @brief Return the incident energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the incident energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the multiplicity values */ - auto Y() const { return TabulationRecord::y(); } + AllRange< double > Y() const { return TabulationRecord::y(); } /** * @brief Return the multiplicity values */ - auto multiplicities() const { return this->Y(); } + AllRange< double > multiplicities() const { return this->Y(); } using TabulationRecord::NR; using TabulationRecord::NP; diff --git a/src/ENDFtk/section/12/TransitionProbabilities.hpp b/src/ENDFtk/section/12/TransitionProbabilities.hpp index b07c48225..73b039be6 100644 --- a/src/ENDFtk/section/12/TransitionProbabilities.hpp +++ b/src/ENDFtk/section/12/TransitionProbabilities.hpp @@ -75,9 +75,9 @@ class TransitionProbabilities : protected ListRecord { */ auto transitions() const { - auto chunked = ListRecord::list() | ranges::view::chunk( this->LG() + 1 ); + auto chunked = ListRecord::list() | ranges::views::chunk( this->LG() + 1 ); using Range = decltype( chunked[0] ); - return chunked | ranges::view::transform( + return chunked | ranges::cpp20::views::transform( [] ( Range&& chunk ) -> Transition< Range > { return { std::move( chunk ) }; } ); } @@ -88,8 +88,8 @@ class TransitionProbabilities : protected ListRecord { auto E() const { return this->transitions() - | ranges::view::transform( [] ( const auto& transition ) - { return transition.E(); } ); + | ranges::cpp20::views::transform( [] ( const auto& transition ) + { return transition.E(); } ); } /** @@ -103,8 +103,8 @@ class TransitionProbabilities : protected ListRecord { auto TP() const { return this->transitions() - | ranges::view::transform( [] ( const auto& transition ) - { return transition.TP(); } ); + | ranges::cpp20::views::transform( [] ( const auto& transition ) + { return transition.TP(); } ); } /** @@ -118,8 +118,8 @@ class TransitionProbabilities : protected ListRecord { auto GP() const { return this->transitions() - | ranges::view::transform( [] ( const auto& transition ) - { return transition.GP(); } ); + | ranges::cpp20::views::transform( [] ( const auto& transition ) + { return transition.GP(); } ); } /** diff --git a/src/ENDFtk/section/12/TransitionProbabilities/Transition.hpp b/src/ENDFtk/section/12/TransitionProbabilities/Transition.hpp index ab86961b3..e54b7eabc 100644 --- a/src/ENDFtk/section/12/TransitionProbabilities/Transition.hpp +++ b/src/ENDFtk/section/12/TransitionProbabilities/Transition.hpp @@ -22,30 +22,30 @@ class Transition { /** * @brief Return the energy of the transition. */ - auto E() const { return this->chunk[0]; } + double E() const { return this->chunk[0]; } /** * @brief Return the energy of the transition. */ - auto energy() const { return this->E(); } + double energy() const { return this->E(); } /** * @brief Return the transition probability. */ - auto TP() const { return this->chunk[1]; } + double TP() const { return this->chunk[1]; } /** * @brief Return the transiition probability. */ - auto transitionProbability() const { return this->TP(); } + double transitionProbability() const { return this->TP(); } /** * @brief Return the conditional probability. */ - auto GP() const { return this->chunk.size() == 3 ? this->chunk[2] : 1.0; } + double GP() const { return this->chunk.size() == 3 ? this->chunk[2] : 1.0; } /** * @brief Return the conditional probability. */ - auto conditionalProbability() const { return this->GP(); } + double conditionalProbability() const { return this->GP(); } }; diff --git a/src/ENDFtk/section/12/test/12.test.cpp b/src/ENDFtk/section/12/test/12.test.cpp index ad86d2066..daada3252 100644 --- a/src/ENDFtk/section/12/test/12.test.cpp +++ b/src/ENDFtk/section/12/test/12.test.cpp @@ -404,14 +404,14 @@ void verifyChunkWithLO1( const section::Type< 12 >& chunk ) { auto data = std::get< Multiplicities >( chunk.photonProduction() ); CHECK( std::nullopt == data.totalMultiplicity() ); - CHECK( 1 == data.partialMultiplicities().size() ); + CHECK( 1 == data.photonPartialMultiplicities().size() ); CHECK( 1 == data.NK() ); - CHECK( 1 == data.numberPartials() ); + CHECK( 1 == data.numberPhotons() ); CHECK( 1 == data.LO() ); CHECK( 1 == data.representation() ); - auto partial = data.partialMultiplicities()[0]; + auto partial = data.photonPartialMultiplicities()[0]; CHECK( 0.0 == Approx( partial.EG() ) ); CHECK( 0.0 == Approx( partial.photonOrBindingEnergy() ) ); CHECK( 0.0 == Approx( partial.ES() ) ); diff --git a/src/ENDFtk/section/13.hpp b/src/ENDFtk/section/13.hpp index c39c3ce0d..1f48af871 100644 --- a/src/ENDFtk/section/13.hpp +++ b/src/ENDFtk/section/13.hpp @@ -28,10 +28,12 @@ namespace section{ #include "ENDFtk/section/13/TotalCrossSection.hpp" #include "ENDFtk/section/13/PartialCrossSection.hpp" + using OptionalTotalCrossSection = std::optional< TotalCrossSection >; + private: /* fields */ - std::optional< TotalCrossSection > total_; + OptionalTotalCrossSection total_; std::vector< PartialCrossSection > partials_; /* auxiliary functions */ @@ -46,28 +48,31 @@ namespace section{ /* get methods */ /** - * @brief Return the number of partial cross sections (discrete photons - * and continuum) + * @brief Return the number of photons (discrete and continuum) with + * partial cross sections */ int NK() const { return this->partials_.size(); } /** - * @brief Return the number of partial multiplicities (discrete photons - * and continuum) + * @brief Return the number of photons (discrete and continuum) with + * partial cross sections */ - int numberPartials() const { return this->NK(); } + int numberPhotons() const { return this->NK(); } /** * @brief Return the total cross section (optional) */ - const auto& totalCrossSection() const { return this->total_; } + const OptionalTotalCrossSection& totalCrossSection() const { + + return this->total_; + } /** * @brief Return the partial cross sections */ - auto partialCrossSections() const { + AllRange< PartialCrossSection > photonPartialCrossSections() const { - return ranges::view::all( this->partials_ ); + return ranges::cpp20::views::all( this->partials_ ); } #include "ENDFtk/section/13/src/NC.hpp" diff --git a/src/ENDFtk/section/13/PartialCrossSection.hpp b/src/ENDFtk/section/13/PartialCrossSection.hpp index 34cbcfd22..49b999f03 100644 --- a/src/ENDFtk/section/13/PartialCrossSection.hpp +++ b/src/ENDFtk/section/13/PartialCrossSection.hpp @@ -58,22 +58,22 @@ class PartialCrossSection : protected TabulationRecord { /** * @brief Return the incident energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the incident energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the cross section values */ - auto XS() const { return TabulationRecord::y(); } + AllRange< double > XS() const { return TabulationRecord::y(); } /** * @brief Return the cross section values */ - auto crossSections() const { return this->XS(); } + AllRange< double > crossSections() const { return this->XS(); } using TabulationRecord::NR; using TabulationRecord::NP; diff --git a/src/ENDFtk/section/13/TotalCrossSection.hpp b/src/ENDFtk/section/13/TotalCrossSection.hpp index 2cc657438..006ee4850 100644 --- a/src/ENDFtk/section/13/TotalCrossSection.hpp +++ b/src/ENDFtk/section/13/TotalCrossSection.hpp @@ -18,22 +18,22 @@ class TotalCrossSection : protected TabulationRecord { /** * @brief Return the incident energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the incident energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the cross section values */ - auto XS() const { return TabulationRecord::y(); } + AllRange< double > XS() const { return TabulationRecord::y(); } /** * @brief Return the cross section values */ - auto crossSections() const { return this->XS(); } + AllRange< double > crossSections() const { return this->XS(); } using TabulationRecord::NR; using TabulationRecord::NP; diff --git a/src/ENDFtk/section/13/test/13.test.cpp b/src/ENDFtk/section/13/test/13.test.cpp index 5b051244d..2b048dd68 100644 --- a/src/ENDFtk/section/13/test/13.test.cpp +++ b/src/ENDFtk/section/13/test/13.test.cpp @@ -180,12 +180,12 @@ void verifyChunk( const section::Type< 13 >& chunk ) { CHECK( 2.330250e+2 == Approx( chunk.atomicWeightRatio() ) ); CHECK( std::nullopt == chunk.totalCrossSection() ); - CHECK( 1 == chunk.partialCrossSections().size() ); + CHECK( 1 == chunk.photonPartialCrossSections().size() ); CHECK( 1 == chunk.NK() ); - CHECK( 1 == chunk.numberPartials() ); + CHECK( 1 == chunk.numberPhotons() ); - auto partial = chunk.partialCrossSections()[0]; + auto partial = chunk.photonPartialCrossSections()[0]; CHECK( 0.0 == Approx( partial.EG() ) ); CHECK( 0.0 == Approx( partial.photonOrBindingEnergy() ) ); CHECK( 0.0 == Approx( partial.ES() ) ); diff --git a/src/ENDFtk/section/14.hpp b/src/ENDFtk/section/14.hpp new file mode 100644 index 000000000..1e70cc47e --- /dev/null +++ b/src/ENDFtk/section/14.hpp @@ -0,0 +1,142 @@ +#ifndef NJOY_ENDFTK_SECTION_14 +#define NJOY_ENDFTK_SECTION_14 + +// system includes +#include + +// other includes +#include "range/v3/algorithm/count_if.hpp" +#include "ENDFtk/ControlRecord.hpp" +#include "ENDFtk/ListRecord.hpp" +#include "ENDFtk/TabulationRecord.hpp" +#include "ENDFtk/InterpolationSequenceRecord.hpp" +#include "ENDFtk/section.hpp" + +namespace njoy { +namespace ENDFtk { +namespace section{ + + /** + * @class + * @brief MF14 - angular distributions of secondary photons + * + * See ENDF102, section 14.2 for more information. + */ + template<> + class Type< 14 > : protected Base { + + protected: + + #include "ENDFtk/section/4/AngularDistributions.hpp" // MF4 component taken over as is + + public: + + #include "ENDFtk/section/14/IsotropicDiscretePhoton.hpp" + #include "ENDFtk/section/4/LegendreCoefficients.hpp" // MF4 component taken over as is + #include "ENDFtk/section/4/TabulatedDistribution.hpp" // MF4 component taken over as is + #include "ENDFtk/section/14/LegendreDistributions.hpp" + #include "ENDFtk/section/14/TabulatedDistributions.hpp" + + /** @typedef PhotonDistribution + * @brief The angular distribution of a given discrete photon + * + * This distribution class is set up as a variant. + */ + using PhotonDistribution = std::variant< IsotropicDiscretePhoton, + LegendreDistributions, + TabulatedDistributions >; + + /* auxiliary functions */ + #include "ENDFtk/section/14/src/readPhotons.hpp" + + private: + + /* type aliases */ + + /* fields */ + std::vector< PhotonDistribution > photons_; + + /* auxiliary functions */ + + public: + + /* constructor */ + #include "ENDFtk/section/14/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return the number of photons with an isotropic angular + * distribution + */ + int NI() const { + + return ranges::count_if( this->photons_, + [] ( const auto& entry ) + { return entry.index() == 0; } ); + } + + /** + * @brief Return the number of photons with an isotropic angular + * distribution + */ + int numberIsotropicPhotons() const { return this->NI(); } + + /** + * @brief Return the number of photons (discrete and continuum) with + * angular distributions + */ + int NK() const { return this->photons_.size(); } + + /** + * @brief Return the number of photons (discrete and continuum) with + * angular distributions + */ + int numberPhotons() const { return this->NK(); } + + /** + * @brief Return the isotropic angular distribution flag + */ + bool LI() const { return this->photons_.size() == 0; } + + /** + * @brief Return the isotropic angular distribution flag + */ + bool isotropicAngularDistributions() const { return this->LI(); } + + /** + * @brief Return the distribution law + */ + int LTT() const { + + return this->LI() ? 0 + : std::visit( [] ( const auto& photon ) + { return photon.LTT(); }, + this->photons_.back() ); + } + + /** + * @brief Return the distribution law + */ + int LAW() const { return this->LTT(); } + + /** + * @brief Return the secondary photons with their angular distribution + */ + const auto& photonAngularDistributions() const { return this->photons_; } + + #include "ENDFtk/section/14/src/NC.hpp" + #include "ENDFtk/section/14/src/print.hpp" + + using Base::MT; + using Base::sectionNumber; + using Base::ZA; + using Base::atomicWeightRatio; + using Base::AWR; + }; + +} // section namespace +} // ENDFtk namespace +} // njoy namespace + +#endif diff --git a/src/ENDFtk/section/14/IsotropicDiscretePhoton.hpp b/src/ENDFtk/section/14/IsotropicDiscretePhoton.hpp new file mode 100644 index 000000000..f79ae7d2b --- /dev/null +++ b/src/ENDFtk/section/14/IsotropicDiscretePhoton.hpp @@ -0,0 +1,58 @@ +/** + * @class + * @brief The angular distribution for a specific discrete photon is isotropic + * + * See ENDF102, section 14.2.2 for more information. + */ +class IsotropicDiscretePhoton { + + /* fields */ + double eg_; + double es_; + + /* auxiliary functions */ + +public: + + /* constructor */ + #include "ENDFtk/section/14/IsotropicDiscretePhoton/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return the energy of the level from which the photon originates + */ + double ES() const { return this->es_; } + + /** + * @brief Return the energy of the level from which the photon originates + */ + double levelEnergy() const { return this->ES(); } + + /** + * @brief Return the photon energy or the binding energy + */ + double EG() const { return this->eg_; } + + /** + * @brief Return the photon energy or the binding energy + */ + double photonEnergy() const { return this->EG(); } + + /** + * @brief Return the distribution law + */ + static constexpr int LTT() { return 0; } + + /** + * @brief Return the distribution law + */ + int LAW() const { return this->LTT(); } + + /** + * @brief Return the number of lines in this MF12 component + */ + static constexpr long NC() { return 1; } + + #include "ENDFtk/section/14/IsotropicDiscretePhoton/src/print.hpp" +}; diff --git a/src/ENDFtk/section/14/IsotropicDiscretePhoton/src/ctor.hpp b/src/ENDFtk/section/14/IsotropicDiscretePhoton/src/ctor.hpp new file mode 100644 index 000000000..782472797 --- /dev/null +++ b/src/ENDFtk/section/14/IsotropicDiscretePhoton/src/ctor.hpp @@ -0,0 +1,50 @@ +//! @todo pybind11 variant needs default constructor workaround +#ifdef PYBIND11 +/** + * @brief Default constructor - only enabled for pybind11 + */ +IsotropicDiscretePhoton() = default; +#endif + +/** + * @brief Constructor + * + * @param[in] energy the photon energy + * @param[in] level the energy of the level from which the photon + * originates + */ +IsotropicDiscretePhoton( double energy, double level ) : + // no need for a try ... catch: nothing can go wrong here + eg_( energy ), es_( level ) {} + +private: +/** + * @brief Private intermediate constructor + */ +IsotropicDiscretePhoton( ControlRecord&& cont ) : + IsotropicDiscretePhoton( cont.C1(), cont.C2() ) {} + +public: +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + * @param[in] MF the expected MF number + * @param[in] MT the expected MT number + */ +template< typename Iterator > +IsotropicDiscretePhoton( Iterator& it, const Iterator& end, long& lineNumber, + int MAT, int MF, int MT ) + try : IsotropicDiscretePhoton( + ControlRecord( it, end, lineNumber, MAT, MF, MT ) ) {} + catch ( std::exception& e ) { + + Log::info( "Encountered error while constructing the isotropic angular " + "distribution for a discrete photon" ); + throw; + } diff --git a/src/ENDFtk/section/14/IsotropicDiscretePhoton/src/print.hpp b/src/ENDFtk/section/14/IsotropicDiscretePhoton/src/print.hpp new file mode 100644 index 000000000..ed0bfc1d3 --- /dev/null +++ b/src/ENDFtk/section/14/IsotropicDiscretePhoton/src/print.hpp @@ -0,0 +1,15 @@ +/** + * @brief Print this MF14 component + * + * @tparam OutputIterator an output iterator + * + * @param[in] it the current position in the output + * @param[in] MAT the MAT number + * @param[in] MF the MF number + * @param[in] MT the MT number + */ +template< typename OutputIterator > +void print( OutputIterator& it, int MAT, int MF, int MT ) const { + + ControlRecord( this->EG(), this->ES(), 0, 0, 0, 0 ).print( it, MAT, MF, MT ); +} diff --git a/src/ENDFtk/section/14/IsotropicDiscretePhoton/test/CMakeLists.txt b/src/ENDFtk/section/14/IsotropicDiscretePhoton/test/CMakeLists.txt new file mode 100644 index 000000000..6ddd1506a --- /dev/null +++ b/src/ENDFtk/section/14/IsotropicDiscretePhoton/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.14.IsotropicDiscretePhoton.test IsotropicDiscretePhoton.test.cpp ) +target_compile_options( ENDFtk.section.14.IsotropicDiscretePhoton.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.14.IsotropicDiscretePhoton.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.14.IsotropicDiscretePhoton COMMAND ENDFtk.section.14.IsotropicDiscretePhoton.test ) diff --git a/src/ENDFtk/section/14/IsotropicDiscretePhoton/test/IsotropicDiscretePhoton.test.cpp b/src/ENDFtk/section/14/IsotropicDiscretePhoton/test/IsotropicDiscretePhoton.test.cpp new file mode 100644 index 000000000..b9a59f5e5 --- /dev/null +++ b/src/ENDFtk/section/14/IsotropicDiscretePhoton/test/IsotropicDiscretePhoton.test.cpp @@ -0,0 +1,84 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/14.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using IsotropicDiscretePhoton = +section::Type< 14 >::IsotropicDiscretePhoton; + +std::string chunk(); +void verifyChunk( const IsotropicDiscretePhoton& ); + +SCENARIO( "IsotropicDiscretePhoton" ) { + + GIVEN( "valid data for an IsotropicDiscretePhoton" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double energy = 1.; + double level = 2.; + + IsotropicDiscretePhoton chunk( energy, level ); + + THEN( "an IsotropicDiscretePhoton can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 2625, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + IsotropicDiscretePhoton chunk( begin, end, lineNumber, 2625, 14, 2 ); + + THEN( "a IsotropicDiscretePhoton can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 2625, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 1.000000+0 2.000000+0 0 0 0 0262514 2 \n"; +} + +void verifyChunk( const IsotropicDiscretePhoton& chunk ) { + + CHECK( 1. == Approx( chunk.EG() ) ); + CHECK( 1. == Approx( chunk.photonEnergy() ) ); + CHECK( 2. == Approx( chunk.ES() ) ); + CHECK( 2. == Approx( chunk.levelEnergy() ) ); + + CHECK( 1 == chunk.NC() ); +} diff --git a/src/ENDFtk/section/14/LegendreCoefficients/test/CMakeLists.txt b/src/ENDFtk/section/14/LegendreCoefficients/test/CMakeLists.txt new file mode 100644 index 000000000..61f45e889 --- /dev/null +++ b/src/ENDFtk/section/14/LegendreCoefficients/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.14.LegendreCoefficients.test LegendreCoefficients.test.cpp ) +target_compile_options( ENDFtk.section.14.LegendreCoefficients.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.14.LegendreCoefficients.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.14.LegendreCoefficients COMMAND ENDFtk.section.14.LegendreCoefficients.test ) diff --git a/src/ENDFtk/section/14/LegendreCoefficients/test/LegendreCoefficients.test.cpp b/src/ENDFtk/section/14/LegendreCoefficients/test/LegendreCoefficients.test.cpp new file mode 100644 index 000000000..3b5b7d2d5 --- /dev/null +++ b/src/ENDFtk/section/14/LegendreCoefficients/test/LegendreCoefficients.test.cpp @@ -0,0 +1,119 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/14.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using LegendreCoefficients = section::Type< 14 >::LegendreCoefficients; + +std::string chunk(); +void verifyChunk( const LegendreCoefficients& ); +std::string invalidChunk(); + +SCENARIO( "LegendreCoefficients" ) { + + GIVEN( "valid data for a LegendreCoefficients" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double energy = 1e-5; + std::vector< double > coefficients = { 7.392510e-5, 8.477139e-9, + 1.17106e-13 }; + + LegendreCoefficients chunk( energy, std::move( coefficients ) ); + + THEN( "an LegendreCoefficients can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + LegendreCoefficients chunk( begin, end, lineNumber, 9228, 14, 2 ); + + THEN( "a LegendreCoefficients can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a LegendreCoefficients" ) { + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (LIST takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( LegendreCoefficients( begin, end, lineNumber, + 9228, 14, 2 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 0.000000+0 1.000000-5 0 0 3 0922814 2 \n" + " 7.392510-5 8.477139-9 1.17106-13 922814 2 \n"; +} + +void verifyChunk( const LegendreCoefficients& chunk ) { + + CHECK( 1e-5 == Approx( chunk.E() ) ); + CHECK( 1e-5 == Approx( chunk.incidentEnergy() ) ); + CHECK( 3 == chunk.NL() ); + CHECK( 3 == chunk.legendreOrder() ); + CHECK( 3 == chunk.coefficients().size() ); + CHECK( 3 == chunk.A().size() ); + CHECK( 7.392510e-5 == Approx( chunk.A()[0] ) ); + CHECK( 8.477139e-9 == Approx( chunk.A()[1] ) ); + CHECK( 1.17106e-13 == Approx( chunk.A()[2] ) ); + CHECK( 7.392510e-5 == Approx( chunk.coefficients()[0] ) ); + CHECK( 8.477139e-9 == Approx( chunk.coefficients()[1] ) ); + CHECK( 1.17106e-13 == Approx( chunk.coefficients()[2] ) ); + + CHECK( 2 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 0.000000+0 1.000000-5 0 0 2 0922814 2 \n" + " 7.392510-5 8.477139-9 1.17106-13 922814 2 \n"; +} diff --git a/src/ENDFtk/section/14/LegendreDistributions.hpp b/src/ENDFtk/section/14/LegendreDistributions.hpp new file mode 100644 index 000000000..0ba7eb71f --- /dev/null +++ b/src/ENDFtk/section/14/LegendreDistributions.hpp @@ -0,0 +1,76 @@ +/** + * @class + * @brief Angular distributions as a function of incident energy using + * Legendre coefficients (LTT=1) for a given discrete photon + * + * The LegendreDistributions class is used to represent the case in which + * the angular distributions in an MF14 section are given as Legendre + * coefficients. + * + * See ENDF102, section 14.2.2 for more information. + */ +class LegendreDistributions : + protected AngularDistributions< LegendreCoefficients > { + +public: + + /* constructor */ + #include "ENDFtk/section/14/LegendreDistributions/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return the energy of the level from which the photon originates + */ + double ES() const { + + return AngularDistributions< LegendreCoefficients >::C2(); } + + /** + * @brief Return the energy of the level from which the photon originates + */ + double levelEnergy() const { return this->ES(); } + + /** + * @brief Return the photon energy or the binding energy + */ + double EG() const { + + return AngularDistributions< LegendreCoefficients >::C1(); + } + + /** + * @brief Return the photon energy or the binding energy + */ + double photonEnergy() const { return this->EG(); } + + /** + * @brief Return the isotropic angular distribution flag + */ + static constexpr bool LI() { return false; } + + /** + * @brief Return the isotropic angular distribution flag + */ + bool isotropicAngularDistributions() const { return this->LI(); } + + /** + * @brief Return the distribution law + */ + static constexpr int LTT() { return 1; } + + /** + * @brief Return the distribution law + */ + int LAW() const { return this->LTT(); } + + using AngularDistributions< LegendreCoefficients >::NR; + using AngularDistributions< LegendreCoefficients >::NE; + using AngularDistributions< LegendreCoefficients >::interpolants; + using AngularDistributions< LegendreCoefficients >::boundaries; + using AngularDistributions< LegendreCoefficients >::incidentEnergies; + using AngularDistributions< LegendreCoefficients >::angularDistributions; + + using AngularDistributions< LegendreCoefficients >::NC; + using AngularDistributions< LegendreCoefficients >::print; +}; diff --git a/src/ENDFtk/section/14/LegendreDistributions/src/ctor.hpp b/src/ENDFtk/section/14/LegendreDistributions/src/ctor.hpp new file mode 100644 index 000000000..98882d872 --- /dev/null +++ b/src/ENDFtk/section/14/LegendreDistributions/src/ctor.hpp @@ -0,0 +1,45 @@ +//! @todo pybind11 variant needs default constructor workaround +#ifdef PYBIND11 +/** + * @brief Default constructor - only enabled for pybind11 + */ +LegendreDistributions() = default; +#endif + +/** + * @brief Constructor + * + * @param[in] energy the photon energy + * @param[in] level the energy of the level from which the photon + * originates + * @param[in] boundaries the interpolation range boundaries + * @param[in] interpolants the interpolation types for each range + * @param[in] distributions the sequence of angular distributions + */ +LegendreDistributions( double energy, double level, + std::vector< long >&& boundaries, + std::vector< long >&& interpolants, + std::vector< LegendreCoefficients >&& distributions ) : + AngularDistributions( std::move( interpolants ), std::move( boundaries ), + std::move( distributions ), energy, level ) {} + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + * @param[in] MF the expected MF number + * @param[in] MT the expected MT number + */ +template< typename Iterator > +LegendreDistributions( Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT, + int MF, + int MT ) : + AngularDistributions( begin, end, lineNumber, MAT, MF, MT ) {} diff --git a/src/ENDFtk/section/14/LegendreDistributions/test/CMakeLists.txt b/src/ENDFtk/section/14/LegendreDistributions/test/CMakeLists.txt new file mode 100644 index 000000000..dd639fd15 --- /dev/null +++ b/src/ENDFtk/section/14/LegendreDistributions/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.14.LegendreDistributions.test LegendreDistributions.test.cpp ) +target_compile_options( ENDFtk.section.14.LegendreDistributions.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.14.LegendreDistributions.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.14.LegendreDistributions COMMAND ENDFtk.section.14.LegendreDistributions.test ) diff --git a/src/ENDFtk/section/14/LegendreDistributions/test/LegendreDistributions.test.cpp b/src/ENDFtk/section/14/LegendreDistributions/test/LegendreDistributions.test.cpp new file mode 100644 index 000000000..180344440 --- /dev/null +++ b/src/ENDFtk/section/14/LegendreDistributions/test/LegendreDistributions.test.cpp @@ -0,0 +1,222 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/14.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using LegendreDistributions = section::Type< 14 >::LegendreDistributions; +using LegendreCoefficients = section::Type< 14 >::LegendreCoefficients; + +std::string chunk(); +void verifyChunk( const LegendreDistributions& ); +std::string invalidChunk(); + +SCENARIO( "LegendreDistributions" ) { + + GIVEN( "valid data for a LegendreDistributions" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double energy = 1.0; + double level = 2.0; + std::vector< long > boundaries = { 2 }; + std::vector< long > interpolants = { 1 }; + std::vector< LegendreCoefficients > sequence = + { { 1e-5, { 7.392510e-5, 8.477139e-9, 1.17106e-13 } }, + { 2e+7, { 2.874390e-2, 3.19645e-11 } } }; + + LegendreDistributions chunk( energy, level, + std::move( boundaries ), + std::move( interpolants ), + std::move( sequence ) ); + + THEN( "an LegendreDistributions can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + LegendreDistributions chunk( begin, end, lineNumber, 9228, 14, 2 ); + + THEN( "a LegendreDistributions can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a LegendreDistributions" ) { + + WHEN( "something is wrong with the interpolation sequence record" ) { + + THEN( "an exception is thrown upon construction when there is " + "something wrong with the boundaries" ) { + + double energy = 1.0; + double level = 2.0; + std::vector< long > wrongBoundaries = { 2, 4 }; + std::vector< long > interpolants = { 1 }; + std::vector< LegendreCoefficients > sequence = + { { 1e-5, { 7.392510e-5, 8.477139e-9, 1.17106e-13 } }, + { 2e+7, { 2.874390e-2, 3.19645e-11 } } }; + + CHECK_THROWS( + LegendreDistributions( energy, level, + std::move( wrongBoundaries ), + std::move( interpolants ), + std::move( sequence ) ) ); + } // THEN + + THEN( "an exception is thrown upon construction when there is " + "something wrong with the interpolants" ) { + + double energy = 1.0; + double level = 2.0; + std::vector< long > boundaries = { 2 }; + std::vector< long > wrongInterpolants = { 1, 2 }; + std::vector< LegendreCoefficients > sequence = + { { 1e-5, { 7.392510e-5, 8.477139e-9, 1.17106e-13 } }, + { 2e+7, { 2.874390e-2, 3.19645e-11 } } }; + + CHECK_THROWS( + LegendreDistributions( energy, level, + std::move( boundaries ), + std::move( wrongInterpolants ), + std::move( sequence ) ) ); + } // THEN + + THEN( "an exception is thrown upon construction when there is " + "something wrong with the sequence" ) { + + double energy = 1.0; + double level = 2.0; + std::vector< long > boundaries = { 2 }; + std::vector< long > interpolants = { 1 }; + std::vector< LegendreCoefficients > wrongSequence = + { { 1e-5, { 7.392510e-5, 8.477139e-9, 1.17106e-13 } } }; + + CHECK_THROWS( + LegendreDistributions( energy, level, + std::move( boundaries ), + std::move( interpolants ), + std::move( wrongSequence ) ) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (LIST takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( LegendreDistributions( begin, end, lineNumber, + 9228, 14, 2 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 1.000000+0 2.000000+0 0 0 1 2922814 2 \n" + " 2 1 922814 2 \n" + " 0.000000+0 1.000000-5 0 0 3 0922814 2 \n" + " 7.392510-5 8.477139-9 1.17106-13 922814 2 \n" + " 0.000000+0 2.000000+7 0 0 2 0922814 2 \n" + " 2.874390-2 3.19645-11 922814 2 \n"; +} + +void verifyChunk( const LegendreDistributions& chunk ) { + + CHECK( false == chunk.LI() ); + CHECK( false == chunk.isotropicAngularDistributions() ); + CHECK( 1 == chunk.LTT() ); + CHECK( 1 == chunk.LAW() ); + + CHECK( 1. == Approx( chunk.EG() ) ); + CHECK( 1. == Approx( chunk.photonEnergy() ) ); + CHECK( 2. == Approx( chunk.ES() ) ); + CHECK( 2. == Approx( chunk.levelEnergy() ) ); + + CHECK( 2 == chunk.NE() ); + CHECK( 1 == chunk.NR() ); + CHECK( 1 == chunk.interpolants().size() ); + CHECK( 1 == chunk.boundaries().size() ); + CHECK( 1 == chunk.interpolants()[0] ); + CHECK( 2 == chunk.boundaries()[0] ); + + CHECK( 2 == chunk.incidentEnergies().size() ); + CHECK( 2 == chunk.angularDistributions().size() ); + + CHECK( 1e-5 == Approx( chunk.incidentEnergies()[0] ) ); + CHECK( 2e+7 == Approx( chunk.incidentEnergies()[1] ) ); + + auto distributions = chunk.angularDistributions(); + + auto d = distributions[0]; + CHECK( 1e-5 == Approx( d.E() ) ); + CHECK( 1e-5 == Approx( d.incidentEnergy() ) ); + CHECK( 3 == d.NL() ); + CHECK( 3 == d.legendreOrder() ); + CHECK( 3 == d.coefficients().size() ); + CHECK( 7.392510e-5 == Approx( d.coefficients()[0] ) ); + CHECK( 8.477139e-9 == Approx( d.coefficients()[1] ) ); + CHECK( 1.17106e-13 == Approx( d.coefficients()[2] ) ); + + d = distributions[1]; + CHECK( 2e+7 == Approx( d.E() ) ); + CHECK( 2e+7 == Approx( d.incidentEnergy() ) ); + CHECK( 2 == d.NL() ); + CHECK( 2 == d.legendreOrder() ); + CHECK( 2 == d.coefficients().size() ); + CHECK( 2.874390e-2 == Approx( d.coefficients()[0] ) ); + CHECK( 3.19645e-11 == Approx( d.coefficients()[1] ) ); + + CHECK( 6 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 0.000000+0 0.000000+0 0 0 3 2922814 2 \n" + " 2 1 922814 2 \n" + " 0.000000+0 1.000000-5 0 0 3 0922814 2 \n" + " 7.392510-5 8.477139-9 1.17106-13 922814 2 \n" + " 0.000000+0 2.000000+7 0 0 2 0922814 2 \n" + " 2.874390-2 3.19645-11 922814 2 \n"; +} diff --git a/src/ENDFtk/section/14/TabulatedDistribution.hpp b/src/ENDFtk/section/14/TabulatedDistribution.hpp new file mode 100644 index 000000000..e57285e2a --- /dev/null +++ b/src/ENDFtk/section/14/TabulatedDistribution.hpp @@ -0,0 +1,60 @@ +/** + * @class + * @brief An angular distribution given as a tabulated function. + * + * The TabulatedDistribution class is used to represent the case in which the + * angular distribution for a secondary particle at a given incident energy is + * is given as a tabulated function. + * + * See ENDF102, section 4.2.2 for more information. + */ +class TabulatedDistribution : protected TabulationRecord { + + /* auxiliary functions */ + +public: + + /* constructor */ + #include "ENDFtk/section/4/TabulatedDistribution/src/ctor.hpp" + + /* methods */ + + /** + * @brief Return the incident energy for which the angular distribution + * is given + */ + double E() const { return TabulationRecord::C2(); } + + /** + * @brief Return the incident energy for which the angular distribution + * is given + */ + double incidentEnergy() const { return this->E(); } + + /** + * @brief Return the cosine values + */ + AllRange< double > MU() const { return TabulationRecord::x(); } + + /** + * @brief Return the cosine values + */ + AllRange< double > cosines() const { return this->MU(); } + + /** + * @brief Return the distribution probabilities + */ + AllRange< double > F() const { return TabulationRecord::y(); } + + /** + * @brief Return the distribution probabilities + */ + AllRange< double > probabilities() const { return this->F(); } + + using TabulationRecord::NR; + using TabulationRecord::NP; + using TabulationRecord::interpolants; + using TabulationRecord::boundaries; + using TabulationRecord::NC; + using TabulationRecord::print; +}; diff --git a/src/ENDFtk/section/14/TabulatedDistribution/test/CMakeLists.txt b/src/ENDFtk/section/14/TabulatedDistribution/test/CMakeLists.txt new file mode 100644 index 000000000..2a1e19665 --- /dev/null +++ b/src/ENDFtk/section/14/TabulatedDistribution/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.14.TabulatedDistribution.test TabulatedDistribution.test.cpp ) +target_compile_options( ENDFtk.section.14.TabulatedDistribution.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.14.TabulatedDistribution.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.14.TabulatedDistribution COMMAND ENDFtk.section.14.TabulatedDistribution.test ) diff --git a/src/ENDFtk/section/14/TabulatedDistribution/test/TabulatedDistribution.test.cpp b/src/ENDFtk/section/14/TabulatedDistribution/test/TabulatedDistribution.test.cpp new file mode 100644 index 000000000..1d4166c97 --- /dev/null +++ b/src/ENDFtk/section/14/TabulatedDistribution/test/TabulatedDistribution.test.cpp @@ -0,0 +1,155 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/14.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using TabulatedDistribution = section::Type< 14 >::TabulatedDistribution; + +std::string chunk(); +void verifyChunk( const TabulatedDistribution& ); +std::string invalidChunk(); + +SCENARIO( "TabulatedDistribution" ) { + + GIVEN( "valid data for a TabulatedDistribution" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double energy = 1e-5; + std::vector< long > boundaries = { 3 }; + std::vector< long > interpolants = { 2 }; + std::vector< double > cosines = { -1.0, 0.0, 1.0 }; + std::vector< double > probabilities = { 0.0, 1.0, 0.0 }; + + TabulatedDistribution chunk( energy, + std::move( boundaries ), + std::move( interpolants ), + std::move( cosines ), + std::move( probabilities ) ); + + THEN( "an TabulatedDistribution can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + TabulatedDistribution chunk( begin, end, lineNumber, 9228, 14, 2 ); + + THEN( "a TabulatedDistribution can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a TabulatedDistribution" ) { + + WHEN( "the data with an error is given" ) { + + double energy = 1e-5; + std::vector< long > wrongBoundaries = { 3, 4 }; + std::vector< long > interpolants = { 2 }; + std::vector< double > cosines = { -1.0, 0.0, 1.0 }; + std::vector< double > probabilities = { 0.0, 1.0, 0.0 }; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( TabulatedDistribution( energy, + std::move( wrongBoundaries ), + std::move( interpolants ), + std::move( cosines ), + std::move( probabilities ) ) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( TabulatedDistribution( begin, end, lineNumber, + 9228, 14, 2 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 0.000000+0 1.000000-5 0 0 1 3922814 2 \n" + " 3 2 922814 2 \n" + "-1.000000+0 0.000000+0 0.000000+0 1.000000+0 1.000000+0 0.000000+0922814 2 \n"; +} + +void verifyChunk( const TabulatedDistribution& chunk ) { + + CHECK( 1e-5 == Approx( chunk.E() ) ); + CHECK( 1e-5 == Approx( chunk.incidentEnergy() ) ); + CHECK( 3 == chunk.NP() ); + CHECK( 1 == chunk.NR() ); + CHECK( 1 == chunk.boundaries().size() ); + CHECK( 1 == chunk.interpolants().size() ); + CHECK( 3 == chunk.boundaries()[0] ); + CHECK( 2 == chunk.interpolants()[0] ); + CHECK( 3 == chunk.cosines().size() ); + CHECK( -1.0 == Approx( chunk.MU()[0] ) ); + CHECK( 0.0 == Approx( chunk.MU()[1] ) ); + CHECK( 1.0 == Approx( chunk.MU()[2] ) ); + CHECK( -1.0 == Approx( chunk.cosines()[0] ) ); + CHECK( 0.0 == Approx( chunk.cosines()[1] ) ); + CHECK( 1.0 == Approx( chunk.cosines()[2] ) ); + CHECK( 3 == chunk.probabilities().size() ); + CHECK( 0.0 == Approx( chunk.F()[0] ) ); + CHECK( 1.0 == Approx( chunk.F()[1] ) ); + CHECK( 0.0 == Approx( chunk.F()[2] ) ); + CHECK( 0.0 == Approx( chunk.probabilities()[0] ) ); + CHECK( 1.0 == Approx( chunk.probabilities()[1] ) ); + CHECK( 0.0 == Approx( chunk.probabilities()[2] ) ); + + CHECK( 3 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 0.000000+0 1.000000-5 0 0 2 3922814 2 \n" + " 3 2 922814 2 \n" + "-1.000000+0 0.000000+0 0.000000+0 1.000000+0 1.000000+0 0.000000+0922814 2 \n"; +} diff --git a/src/ENDFtk/section/14/TabulatedDistributions.hpp b/src/ENDFtk/section/14/TabulatedDistributions.hpp new file mode 100644 index 000000000..1b3d31a1d --- /dev/null +++ b/src/ENDFtk/section/14/TabulatedDistributions.hpp @@ -0,0 +1,76 @@ +/** + * @class + * @brief Angular distributions as a function of incident energy using + * tabulated functions (LTT=2) for a given discrete photon + * + * The LegendreDistributions class is used to represent the case in which + * the angular distributions in an MF4 section are given as tabulated + * functions. + * + * See ENDF102, section 14.2.3 for more information. + */ +class TabulatedDistributions : + protected AngularDistributions< TabulatedDistribution > { + +public: + + /* constructor */ + #include "ENDFtk/section/14/TabulatedDistributions/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return the energy of the level from which the photon originates + */ + double ES() const { + + return AngularDistributions< TabulatedDistribution >::C2(); } + + /** + * @brief Return the energy of the level from which the photon originates + */ + double levelEnergy() const { return this->ES(); } + + /** + * @brief Return the photon energy or the binding energy + */ + double EG() const { + + return AngularDistributions< TabulatedDistribution >::C1(); + } + + /** + * @brief Return the photon energy or the binding energy + */ + double photonEnergy() const { return this->EG(); } + + /** + * @brief Return the isotropic angular distribution flag + */ + static constexpr bool LI() { return false; } + + /** + * @brief Return the isotropic angular distribution flag + */ + bool isotropicAngularDistributions() const { return this->LI(); } + + /** + * @brief Return the distribution law + */ + static constexpr int LTT() { return 2; } + + /** + * @brief Return the distribution law + */ + int LAW() const { return this->LTT(); } + + using AngularDistributions< TabulatedDistribution >::NR; + using AngularDistributions< TabulatedDistribution >::NE; + using AngularDistributions< TabulatedDistribution >::interpolants; + using AngularDistributions< TabulatedDistribution >::boundaries; + using AngularDistributions< TabulatedDistribution >::incidentEnergies; + using AngularDistributions< TabulatedDistribution >::angularDistributions; + + using AngularDistributions< TabulatedDistribution >::NC; + using AngularDistributions< TabulatedDistribution >::print; +}; diff --git a/src/ENDFtk/section/14/TabulatedDistributions/src/ctor.hpp b/src/ENDFtk/section/14/TabulatedDistributions/src/ctor.hpp new file mode 100644 index 000000000..f29388573 --- /dev/null +++ b/src/ENDFtk/section/14/TabulatedDistributions/src/ctor.hpp @@ -0,0 +1,45 @@ +//! @todo pybind11 variant needs default constructor workaround +#ifdef PYBIND11 +/** + * @brief Default constructor - only enabled for pybind11 + */ +TabulatedDistributions() = default; +#endif + +/** + * @brief Constructor + * + * @param[in] energy the photon energy + * @param[in] level the energy of the level from which the photon + * originates + * @param[in] boundaries the interpolation range boundaries + * @param[in] interpolants the interpolation types for each range + * @param[in] distributions the sequence of angular distributions + */ +TabulatedDistributions( double energy, double level, + std::vector< long >&& boundaries, + std::vector< long >&& interpolants, + std::vector< TabulatedDistribution >&& distributions ) : + AngularDistributions( std::move( interpolants ), std::move( boundaries ), + std::move( distributions ), energy, level ) {} + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + * @param[in] MF the expected MF number + * @param[in] MT the expected MT number + */ +template< typename Iterator > +TabulatedDistributions( Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT, + int MF, + int MT ) : + AngularDistributions( begin, end, lineNumber, MAT, MF, MT ) {} diff --git a/src/ENDFtk/section/14/TabulatedDistributions/test/CMakeLists.txt b/src/ENDFtk/section/14/TabulatedDistributions/test/CMakeLists.txt new file mode 100644 index 000000000..bc6a5f60a --- /dev/null +++ b/src/ENDFtk/section/14/TabulatedDistributions/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.14.TabulatedDistributions.test TabulatedDistributions.test.cpp ) +target_compile_options( ENDFtk.section.14.TabulatedDistributions.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.14.TabulatedDistributions.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.14.TabulatedDistributions COMMAND ENDFtk.section.14.TabulatedDistributions.test ) diff --git a/src/ENDFtk/section/14/TabulatedDistributions/test/TabulatedDistributions.test.cpp b/src/ENDFtk/section/14/TabulatedDistributions/test/TabulatedDistributions.test.cpp new file mode 100644 index 000000000..098e7e41d --- /dev/null +++ b/src/ENDFtk/section/14/TabulatedDistributions/test/TabulatedDistributions.test.cpp @@ -0,0 +1,241 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/14.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using TabulatedDistributions = section::Type< 14 >::TabulatedDistributions; +using TabulatedDistribution = section::Type< 14 >::TabulatedDistribution; + +std::string chunk(); +void verifyChunk( const TabulatedDistributions& ); +std::string invalidChunk(); + +SCENARIO( "TabulatedDistributions" ) { + + GIVEN( "valid data for a TabulatedDistributions" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double energy = 1.0; + double level = 2.0; + std::vector< long > boundaries = { 2 }; + std::vector< long > interpolants = { 1 }; + std::vector< TabulatedDistribution > sequence = + { { 1e-5, { 2 }, { 2 }, { -1.0, 1.0 }, { 0.5, 0.5 } }, + { 2e+7, { 3 }, { 2 }, { -1.0, 0.0, 1.0 }, { 0.0, 1.0, 0.0 } } }; + + TabulatedDistributions chunk( energy, level, + std::move( boundaries ), + std::move( interpolants ), + std::move( sequence ) ); + + THEN( "a TabulatedDistributions can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + TabulatedDistributions chunk( begin, end, lineNumber, 9228, 14, 2 ); + + THEN( "a TabulatedDistributions can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14, 2 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a TabulatedDistributions" ) { + + WHEN( "something is wrong with the interpolation sequence record" ) { + + THEN( "an exception is thrown upon construction when there is " + "something wrong with the boundaries" ) { + + double energy = 1.0; + double level = 2.0; + std::vector< long > wrongBoundaries = { 2, 4 }; + std::vector< long > interpolants = { 1 }; + std::vector< TabulatedDistribution > sequence = + { { 1e-5, { 2 }, { 2 }, { -1.0, 1.0 }, { 0.5, 0.5 } }, + { 2e+7, { 3 }, { 2 }, { -1.0, 0.0, 1.0 }, { 0.0, 1.0, 0.0 } } }; + + CHECK_THROWS( + TabulatedDistributions( energy, level, + std::move( wrongBoundaries ), + std::move( interpolants ), + std::move( sequence ) ) ); + } // THEN + + THEN( "an exception is thrown upon construction when there is " + "something wrong with the interpolants" ) { + + double energy = 1.0; + double level = 2.0; + std::vector< long > boundaries = { 2 }; + std::vector< long > wrongInterpolants = { 1, 2 }; + std::vector< TabulatedDistribution > sequence = + { { 1e-5, { 2 }, { 2 }, { -1.0, 1.0 }, { 0.5, 0.5 } }, + { 2e+7, { 3 }, { 2 }, { -1.0, 0.5, 1.0 }, { 0.0, 0.5, 0.0 } } }; + + CHECK_THROWS( + TabulatedDistributions( energy, level, + std::move( boundaries ), + std::move( wrongInterpolants ), + std::move( sequence ) ) ); + } // THEN + + THEN( "an exception is thrown upon construction when there is " + "something wrong with the sequence" ) { + + double energy = 1.0; + double level = 2.0; + std::vector< long > boundaries = { 2 }; + std::vector< long > interpolants = { 1 }; + std::vector< TabulatedDistribution > wrongSequence = + { { 1e-5, { 2 }, { 2 }, { -1.0, 1.0 }, { 0.5, 0.5 } } }; + + CHECK_THROWS( + TabulatedDistributions( energy, level, + std::move( boundaries ), + std::move( interpolants ), + std::move( wrongSequence ) ) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (LIST takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( TabulatedDistributions( begin, end, lineNumber, + 9228, 14, 2 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 1.000000+0 2.000000+0 0 0 1 2922814 2 \n" + " 2 1 922814 2 \n" + " 0.000000+0 1.000000-5 0 0 1 2922814 2 \n" + " 2 2 922814 2 \n" + "-1.000000+0 5.000000-1 1.000000+0 5.000000-1 922814 2 \n" + " 0.000000+0 2.000000+7 0 0 1 3922814 2 \n" + " 3 2 922814 2 \n" + "-1.000000+0 0.000000+0 0.000000+0 1.000000+0 1.000000+0 0.000000+0922814 2 \n"; +} + +void verifyChunk( const TabulatedDistributions& chunk ) { + + CHECK( false == chunk.LI() ); + CHECK( false == chunk.isotropicAngularDistributions() ); + CHECK( 2 == chunk.LTT() ); + CHECK( 2 == chunk.LAW() ); + + CHECK( 1. == Approx( chunk.EG() ) ); + CHECK( 1. == Approx( chunk.photonEnergy() ) ); + CHECK( 2. == Approx( chunk.ES() ) ); + CHECK( 2. == Approx( chunk.levelEnergy() ) ); + + CHECK( 2 == chunk.NE() ); + CHECK( 1 == chunk.NR() ); + CHECK( 1 == chunk.interpolants().size() ); + CHECK( 1 == chunk.boundaries().size() ); + CHECK( 1 == chunk.interpolants()[0] ); + CHECK( 2 == chunk.boundaries()[0] ); + + CHECK( 2 == chunk.incidentEnergies().size() ); + CHECK( 2 == chunk.angularDistributions().size() ); + + CHECK( 1e-5 == Approx( chunk.incidentEnergies()[0] ) ); + CHECK( 2e+7 == Approx( chunk.incidentEnergies()[1] ) ); + + auto distributions = chunk.angularDistributions(); + + auto d = distributions[0]; + CHECK( 1e-5 == Approx( d.E() ) ); + CHECK( 1e-5 == Approx( d.incidentEnergy() ) ); + CHECK( 2 == d.NP() ); + CHECK( 1 == d.NR() ); + CHECK( 1 == d.boundaries().size() ); + CHECK( 1 == d.interpolants().size() ); + CHECK( 2 == d.boundaries()[0] ); + CHECK( 2 == d.interpolants()[0] ); + CHECK( 2 == d.cosines().size() ); + CHECK( -1.0 == Approx( d.cosines()[0] ) ); + CHECK( 1.0 == Approx( d.cosines()[1] ) ); + CHECK( 2 == d.probabilities().size() ); + CHECK( 0.5 == Approx( d.probabilities()[0] ) ); + CHECK( 0.5 == Approx( d.probabilities()[1] ) ); + + d = distributions[1]; + CHECK( 2e+7 == Approx( d.E() ) ); + CHECK( 2e+7 == Approx( d.incidentEnergy() ) ); + CHECK( 3 == d.NP() ); + CHECK( 1 == d.NR() ); + CHECK( 1 == d.boundaries().size() ); + CHECK( 1 == d.interpolants().size() ); + CHECK( 3 == d.boundaries()[0] ); + CHECK( 2 == d.interpolants()[0] ); + CHECK( 3 == d.cosines().size() ); + CHECK( -1.0 == Approx( d.cosines()[0] ) ); + CHECK( 0.0 == Approx( d.cosines()[1] ) ); + CHECK( 1.0 == Approx( d.cosines()[2] ) ); + CHECK( 3 == d.probabilities().size() ); + CHECK( 0.0 == Approx( d.probabilities()[0] ) ); + CHECK( 1.0 == Approx( d.probabilities()[1] ) ); + CHECK( 0.0 == Approx( d.probabilities()[2] ) ); + + CHECK( 8 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 1.000000+0 2.000000+0 0 0 2 2922814 2 \n" + " 2 1 922814 2 \n" + " 0.000000+0 1.000000-5 0 0 1 2922814 2 \n" + " 2 2 922814 2 \n" + "-1.000000+0 5.000000-1 1.000000+0 5.000000-1 922814 2 \n" + " 0.000000+0 2.000000+7 0 0 1 3922814 2 \n" + " 3 2 922814 2 \n" + "-1.000000+0 0.000000+0 0.000000+0 1.000000+0 1.000000+0 0.000000+0922814 2 \n"; +} diff --git a/src/ENDFtk/section/14/src/NC.hpp b/src/ENDFtk/section/14/src/NC.hpp new file mode 100644 index 000000000..eed3b06f0 --- /dev/null +++ b/src/ENDFtk/section/14/src/NC.hpp @@ -0,0 +1,12 @@ +/** + * @brief Return the number of lines in this MF14 section + */ +long NC() const { + + long NC = 1; + for ( const auto& entry : this->photons_ ) { + + NC += std::visit( [&] ( const auto& v ) { return v.NC(); }, entry ); + } + return NC; +}; diff --git a/src/ENDFtk/section/14/src/ctor.hpp b/src/ENDFtk/section/14/src/ctor.hpp new file mode 100644 index 000000000..791978b61 --- /dev/null +++ b/src/ENDFtk/section/14/src/ctor.hpp @@ -0,0 +1,53 @@ +/** + * @brief Constructor for isotropic photon distributions + * + * @param[in] mt the MT number for the section + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + */ +Type( int MT, double zaid, double awr ) : + Base( zaid, awr, MT ), + photons_() {} + +/** + * @brief Constructor + * + * @param[in] mt the MT number for the section + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] photons the photon distribution data + */ +Type( int MT, double zaid, double awr, + std::vector< PhotonDistribution >&& photons ) : + Base( zaid, awr, MT ), + photons_( std::move( photons ) ) {} + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] head the head record of the section + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + */ +template< typename Iterator > +Type ( HEAD& head, + Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT ) + try: Type( head.MT(), head.ZA(), head.AWR(), + readPhotons( begin, end, lineNumber, head.MAT(), 14, head.MT(), + head.L1(), head.N2(), head.N1(), head.L2() ) ) { + + readSEND(begin, end, lineNumber, MAT, 14 ); + } catch( std::exception& e ) { + + Log::info + ( "Encountered error while reading section {} of file 14 of material {}", + head.MT(), MAT ); + throw; + } diff --git a/src/ENDFtk/section/14/src/print.hpp b/src/ENDFtk/section/14/src/print.hpp new file mode 100644 index 000000000..fb8168f8b --- /dev/null +++ b/src/ENDFtk/section/14/src/print.hpp @@ -0,0 +1,23 @@ +/** + * @brief Print the MF14 section (includes SEND record) + * + * @tparam OutputIterator an output iterator + * + * @param[in] it the current position in the output + * @param[in] MAT the MAT number + * @param[in] MF the MF number + */ +template< typename OutputIterator > +void print( OutputIterator& it, int MAT, int MF ) const { + + int MT = this->MT(); + ControlRecord( this->ZA(), this->AWR(), this->LI(), this->LTT(), + this->NK(), this->NI() ).print( it, MAT, MF, MT ); + for ( const auto& entry : this->photons_ ) { + + std::visit( [&] ( const auto& v ) + { return v.print( it, MAT, MF, MT ); }, + entry ); + } + SEND( MAT, MF ).print( it ); +} diff --git a/src/ENDFtk/section/14/src/readPhotons.hpp b/src/ENDFtk/section/14/src/readPhotons.hpp new file mode 100644 index 000000000..8fc3b059c --- /dev/null +++ b/src/ENDFtk/section/14/src/readPhotons.hpp @@ -0,0 +1,54 @@ +template< typename Iterator > +static std::vector< PhotonDistribution > +readPhotons( Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT, + int MF, + int MT, + long LI, + long NI, + long NK, + long LTT) { + + std::vector< PhotonDistribution > sequence; + if ( LI != 1 ) { + + sequence.reserve( NK ); + + NK -= NI; + while ( NI-- ) { + + sequence.push_back( IsotropicDiscretePhoton( begin, end, lineNumber, + MAT, MF, MT ) ); + } + + while ( NK-- ) { + + switch ( LTT ) { + + case 1 : { + + sequence.push_back( LegendreDistributions( begin, end, lineNumber, + MAT, MF, MT ) ); + break; + } + case 2 : { + + sequence.push_back( TabulatedDistributions( begin, end, lineNumber, + MAT, MF, MT ) ); + break; + } + default : { + Log::error( "Encountered illegal LTT value" ); + Log::info( "LTT must be equal to 1 or 2" ); + Log::info( "LTT value: {}", LTT ); + Log::info( "Line number: {}", lineNumber - 2 ); + throw std::exception(); + } + } + } + } + + return sequence; +} diff --git a/src/ENDFtk/section/14/test/14.test.cpp b/src/ENDFtk/section/14/test/14.test.cpp new file mode 100644 index 000000000..727bd3e5c --- /dev/null +++ b/src/ENDFtk/section/14/test/14.test.cpp @@ -0,0 +1,298 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/14.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using PhotonDistribution = section::Type< 14 >::PhotonDistribution; +using LegendreDistributions = section::Type< 14 >::LegendreDistributions; +using LegendreCoefficients = section::Type< 14 >::LegendreCoefficients; +using TabulatedDistributions = section::Type< 14 >::TabulatedDistributions; +using TabulatedDistribution = section::Type< 14 >::TabulatedDistribution; + +std::string chunkWithLTT0(); +void verifyChunkWithLTT0( const section::Type< 14 >& ); +std::string chunkWithLTT1(); +void verifyChunkWithLTT1( const section::Type< 14 >& ); +std::string chunkWithInvalidLTT(); +std::string validSEND(); +std::string invalidSEND(); + +SCENARIO( "section::Type< 14 >" ) { + + GIVEN( "valid data for a section::Type< 14 > with LTT=0" ) { + + std::string sectionString = chunkWithLTT0() + validSEND(); + + WHEN( "the data is given explicitly" ) { + + int mt = 2; + double za = 92235.; + double awr = 2.330248e+2; + + section::Type< 14 > chunk( mt, za, awr ); + + THEN( "a section::Type< 14 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithLTT0( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 14 > chunk( head, begin, end, lineNumber, 9228 ); + + THEN( "a section::Type< 14 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithLTT0( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14 ); + + CHECK( buffer == sectionString ); + } // THEN + } //WHEN + } // GIVEN + + GIVEN( "valid data for a section::Type< 14 > with LTT=1" ) { + + std::string sectionString = chunkWithLTT1() + validSEND(); + + WHEN( "the data is given explicitly" ) { + + int mt = 2; + double za = 92235.; + double awr = 2.330248e+2; + + std::vector< PhotonDistribution > photons = + { LegendreDistributions( 4.438900e+6, 4.438900e+6, + { 2 }, { 3 }, + { { 4.812998e+6, { 0., 0.04076 } }, + { 15e+7, { 0., 0. } } } ) }; + + section::Type< 14 > chunk( mt, za, awr, std::move( photons ) ); + + THEN( "a section::Type< 14 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithLTT1( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 14 > chunk( head, begin, end, lineNumber, 9228 ); + + THEN( "a section::Type< 14 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithLTT1( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 14 ); + + CHECK( buffer == sectionString ); + } // THEN + } //WHEN + } // GIVEN + + GIVEN( "invalid data for a section::Type< 14 >" ) { + + WHEN( "a string representation of a section::Type< 14 > with an " + "invalid LTT" ) { + + std::string sectionString = chunkWithInvalidLTT() + validSEND(); + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( section::Type< 14 >( head, begin, end, + lineNumber, 9228 ) ); + } // THEN + } // WHEN + + WHEN( "a string representation of a valid section::Type< 14 > " + "with an invalid SEND" ) { + + std::string sectionString = chunkWithLTT0() + invalidSEND(); + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( section::Type< 14 >( head, begin, end, + lineNumber, 9228 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunkWithLTT0() { + return + " 9.223500+4 2.330248+2 1 0 0 0922814 2 \n"; +} + +void verifyChunkWithLTT0( const section::Type< 14 >& chunk ) { + + CHECK( 2 == chunk.MT() ); + CHECK( 2 == chunk.sectionNumber() ); + + CHECK( 92235. == Approx( chunk.ZA() ) ); + CHECK( 2.330248e+2 == Approx( chunk.AWR() ) ); + CHECK( 2.330248e+2 == Approx( chunk.atomicWeightRatio() ) ); + + CHECK( 0 == chunk.NI() ); + CHECK( 0 == chunk.numberIsotropicPhotons() ); + CHECK( 0 == chunk.NK() ); + CHECK( 0 == chunk.numberPhotons() ); + + CHECK( 0 == chunk.LTT() ); + CHECK( 0 == chunk.LAW() ); + CHECK( true == chunk.LI() ); + CHECK( true == chunk.isotropicAngularDistributions() ); + + CHECK( 0 == chunk.photonAngularDistributions().size() ); + + CHECK( 1 == chunk.NC() ); +} + +std::string chunkWithLTT1() { + return + " 9.223500+4 2.330248+2 0 1 1 0922814 2 \n" + " 4.438900+6 4.438900+6 0 0 1 2922814 2 \n" + " 2 3 922814 2 \n" + " 0.000000+0 4.812998+6 0 0 2 0922814 2 \n" + " 0.000000+0 4.076000-2 922814 2 \n" + " 0.000000+0 1.500000+8 0 0 2 0922814 2 \n" + " 0.000000+0 0.000000+0 922814 2 \n"; +} + +void verifyChunkWithLTT1( const section::Type< 14 >& chunk ) { + + CHECK( 2 == chunk.MT() ); + CHECK( 2 == chunk.sectionNumber() ); + + CHECK( 92235. == Approx( chunk.ZA() ) ); + CHECK( 2.330248e+2 == Approx( chunk.AWR() ) ); + CHECK( 2.330248e+2 == Approx( chunk.atomicWeightRatio() ) ); + + CHECK( 0 == chunk.NI() ); + CHECK( 0 == chunk.numberIsotropicPhotons() ); + CHECK( 1 == chunk.NK() ); + CHECK( 1 == chunk.numberPhotons() ); + + CHECK( 1 == chunk.LTT() ); + CHECK( 1 == chunk.LAW() ); + CHECK( false == chunk.LI() ); + CHECK( false == chunk.isotropicAngularDistributions() ); + + CHECK( 1 == chunk.photonAngularDistributions().size() ); + + auto photon = std::get< LegendreDistributions >( chunk.photonAngularDistributions()[0] ); + + CHECK( false == photon.LI() ); + CHECK( false == photon.isotropicAngularDistributions() ); + CHECK( 1 == photon.LTT() ); + CHECK( 1 == photon.LAW() ); + + CHECK( 4.438900e+6 == Approx( photon.EG() ) ); + CHECK( 4.438900e+6 == Approx( photon.photonEnergy() ) ); + CHECK( 4.438900e+6 == Approx( photon.ES() ) ); + CHECK( 4.438900e+6 == Approx( photon.levelEnergy() ) ); + + CHECK( 2 == photon.NE() ); + CHECK( 1 == photon.NR() ); + CHECK( 1 == photon.interpolants().size() ); + CHECK( 1 == photon.boundaries().size() ); + CHECK( 3 == photon.interpolants()[0] ); + CHECK( 2 == photon.boundaries()[0] ); + + CHECK( 2 == photon.incidentEnergies().size() ); + CHECK( 2 == photon.angularDistributions().size() ); + + CHECK( 4.812998e+6 == Approx( photon.incidentEnergies()[0] ) ); + CHECK( 15e+7 == Approx( photon.incidentEnergies()[1] ) ); + + auto distributions = photon.angularDistributions(); + + auto d = distributions[0]; + CHECK( 4.812998e+6 == Approx( d.E() ) ); + CHECK( 4.812998e+6 == Approx( d.incidentEnergy() ) ); + CHECK( 2 == d.NL() ); + CHECK( 2 == d.legendreOrder() ); + CHECK( 2 == d.coefficients().size() ); + CHECK( 0. == Approx( d.coefficients()[0] ) ); + CHECK( 4.076000e-2 == Approx( d.coefficients()[1] ) ); + + d = distributions[1]; + CHECK( 15e+7 == Approx( d.E() ) ); + CHECK( 15e+7 == Approx( d.incidentEnergy() ) ); + CHECK( 2 == d.NL() ); + CHECK( 2 == d.legendreOrder() ); + CHECK( 2 == d.coefficients().size() ); + CHECK( 0. == Approx( d.coefficients()[0] ) ); + CHECK( 0. == Approx( d.coefficients()[1] ) ); + + CHECK( 7 == chunk.NC() ); +} + +std::string chunkWithInvalidLTT() { + return + " 9.223500+4 2.330250+2 0 4 1 0922814 2 \n"; +} + +std::string validSEND() { + return + " 922814 0 \n"; +} + +std::string invalidSEND() { + return + " 922814 4 \n"; +} diff --git a/src/ENDFtk/section/14/test/CMakeLists.txt b/src/ENDFtk/section/14/test/CMakeLists.txt new file mode 100644 index 000000000..e3365cceb --- /dev/null +++ b/src/ENDFtk/section/14/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.14.test 14.test.cpp ) +target_compile_options( ENDFtk.section.14.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.14.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.14 COMMAND ENDFtk.section.14.test ) diff --git a/src/ENDFtk/section/15.hpp b/src/ENDFtk/section/15.hpp new file mode 100644 index 000000000..ef9eb13ba --- /dev/null +++ b/src/ENDFtk/section/15.hpp @@ -0,0 +1,84 @@ +#ifndef NJOY_ENDFTK_SECTION_15 +#define NJOY_ENDFTK_SECTION_15 + +// system includes +#include + +// other includes +#include "range/v3/view/all.hpp" +#include "range/v3/view/transform.hpp" +#include "ENDFtk/ControlRecord.hpp" +#include "ENDFtk/ListRecord.hpp" +#include "ENDFtk/TabulationRecord.hpp" +#include "ENDFtk/InterpolationSequenceRecord.hpp" +#include "ENDFtk/section.hpp" + +namespace njoy { +namespace ENDFtk { +namespace section{ + +template<> +class Type< 15 > : protected Base { + +public: + + #include "ENDFtk/section/5/TabulatedSpectrum.hpp" // LF=1, taken from MF5 + + using LF1 = TabulatedSpectrum; + + /** @typedef Distribution + * @brief A secondary particle energy distribution of MF15 + */ + using Distribution = TabulatedSpectrum; // LF=1 + + #include "ENDFtk/section/5/Probability.hpp" // taken from MF5 + #include "ENDFtk/section/15/PartialDistribution.hpp" + +private: + + /* fields */ + std::vector< PartialDistribution > partials_; + + /* auxiliary functions */ + #include "ENDFtk/section/5/src/verifyNK.hpp" // taken from MF5 + +public: + + /* constructor */ + #include "ENDFtk/section/15/src/ctor.hpp" + + /* methods */ + + /** + * @brief Return the number NK of subsections with partial distributions + */ + int NK() const { return this->partials_.size(); } + + /** + * @brief Return the number NK of subsections with partial distributions + */ + int numberPartialDistributions() const { return this->NK(); } + + /** + * @brief Return the partial distributions defined in this section + */ + AllRange< PartialDistribution > partialDistributions() const { + + return ranges::cpp20::views::all( this->partials_ ); + } + + #include "ENDFtk/section/5/src/NC.hpp" // taken from MF5 + #include "ENDFtk/section/5/src/print.hpp" // taken from MF5 + + using Base::MT; + using Base::sectionNumber; + using Base::ZA; + using Base::atomicWeightRatio; + using Base::AWR; +}; + +} // section namespace +} // ENDFtk namespace +} // njoy namespace + +#endif diff --git a/src/ENDFtk/section/15/PartialDistribution.hpp b/src/ENDFtk/section/15/PartialDistribution.hpp new file mode 100644 index 000000000..60b344932 --- /dev/null +++ b/src/ENDFtk/section/15/PartialDistribution.hpp @@ -0,0 +1,33 @@ +/** + * @class + * @brief A distribution subsection of an MF15 section + */ +class PartialDistribution { + + Probability probability_; + Distribution distribution_; + + /* auxiliary functions */ + #include "ENDFtk/section/15/PartialDistribution/src/verifyLF.hpp" + #include "ENDFtk/section/15/PartialDistribution/src/readPartialDistribution.hpp" + +public: + + /* constructor */ + #include "ENDFtk/section/15/PartialDistribution/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return the probability + */ + const Probability& probability() const { return this->probability_; } + + /** + * @brief Return the distribution + */ + const Distribution& distribution() const { return this->distribution_; } + + #include "ENDFtk/section/15/PartialDistribution/src/NC.hpp" + #include "ENDFtk/section/15/PartialDistribution/src/print.hpp" +}; diff --git a/src/ENDFtk/section/15/PartialDistribution/src/NC.hpp b/src/ENDFtk/section/15/PartialDistribution/src/NC.hpp new file mode 100644 index 000000000..1cca64fd4 --- /dev/null +++ b/src/ENDFtk/section/15/PartialDistribution/src/NC.hpp @@ -0,0 +1,4 @@ +/** + * @brief Return the number of lines in this MF15 component + */ +long NC() const { return this->probability_.NC() + this->distribution_.NC(); }; diff --git a/src/ENDFtk/section/15/PartialDistribution/src/ctor.hpp b/src/ENDFtk/section/15/PartialDistribution/src/ctor.hpp new file mode 100644 index 000000000..f6c329934 --- /dev/null +++ b/src/ENDFtk/section/15/PartialDistribution/src/ctor.hpp @@ -0,0 +1,36 @@ +/** + * @brief Constructor + * + * @param[in] probability the probability + * @param[in] spectrum the spectrum + */ +PartialDistribution( Probability&& probability, + Distribution&& spectrum ) : + probability_( std::move( probability ) ), + distribution_( std::move( spectrum ) ) { + + verifyLF( this->probability_.LF(), + this->distribution_.LF() ); +} + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] begin the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + * @param[in] MF the expected MF number + * @param[in] MT the expected MT number + */ +template< typename Iterator > +PartialDistribution( Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT, + int MF, + int MT ) : + PartialDistribution( readPartialDistribution( begin, end, lineNumber, + MAT, MF, MT ) ) {} diff --git a/src/ENDFtk/section/15/PartialDistribution/src/print.hpp b/src/ENDFtk/section/15/PartialDistribution/src/print.hpp new file mode 100644 index 000000000..b973ae897 --- /dev/null +++ b/src/ENDFtk/section/15/PartialDistribution/src/print.hpp @@ -0,0 +1,16 @@ +/** + * @brief Print this MF15 component + * + * @tparam OutputIterator an output iterator + * + * @param[in] it the current position in the output + * @param[in] MAT the MAT number + * @param[in] MF the MF number + * @param[in] MT the MT number + */ +template< typename OutputIterator > +void print( OutputIterator& it, int MAT, int MF, int MT ) const { + + this->probability_.print( it, MAT, MF, MT ); + this->distribution_.print( it, MAT, MF, MT ); +} diff --git a/src/ENDFtk/section/15/PartialDistribution/src/readPartialDistribution.hpp b/src/ENDFtk/section/15/PartialDistribution/src/readPartialDistribution.hpp new file mode 100644 index 000000000..6960e075c --- /dev/null +++ b/src/ENDFtk/section/15/PartialDistribution/src/readPartialDistribution.hpp @@ -0,0 +1,24 @@ +template< typename Iterator > +static PartialDistribution +readPartialDistribution( Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT, + int MF, + int MT ) { + + Probability probability( begin, end, lineNumber, MAT, MF, MT ); + switch ( probability.LF() ) { + case 1 : + return PartialDistribution + ( std::move( probability ), + TabulatedSpectrum( begin, end, lineNumber, MAT, MF, MT ) ); + default : { + Log::error( "Encountered illegal LF value" ); + Log::info( "LF must be equal to 1" ); + Log::info( "LF value: {}", probability.LF() ); + Log::info( "Line number: {}", lineNumber - probability.NC() ); + throw std::exception(); + } + } +} diff --git a/src/ENDFtk/section/15/PartialDistribution/src/verifyLF.hpp b/src/ENDFtk/section/15/PartialDistribution/src/verifyLF.hpp new file mode 100644 index 000000000..29158e82b --- /dev/null +++ b/src/ENDFtk/section/15/PartialDistribution/src/verifyLF.hpp @@ -0,0 +1,13 @@ +static void +verifyLF( int partialLF, int spectrumLF ) { + + if ( partialLF != spectrumLF ) { + + Log::error( "Inconsistent LF value between partial probability and " + "spectrum" ); + Log::info( "LF must be equal to 1" ); + Log::info( "Partial probability LF value: {}", partialLF ); + Log::info( "Spectrum LF value: {}", spectrumLF ); + throw std::exception(); + } +} diff --git a/src/ENDFtk/section/15/PartialDistribution/test/CMakeLists.txt b/src/ENDFtk/section/15/PartialDistribution/test/CMakeLists.txt new file mode 100644 index 000000000..6f4dc76dc --- /dev/null +++ b/src/ENDFtk/section/15/PartialDistribution/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.15.PartialDistribution.test PartialDistribution.test.cpp ) +target_compile_options( ENDFtk.section.15.PartialDistribution.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.15.PartialDistribution.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.15.PartialDistribution COMMAND ENDFtk.section.15.PartialDistribution.test ) diff --git a/src/ENDFtk/section/15/PartialDistribution/test/PartialDistribution.test.cpp b/src/ENDFtk/section/15/PartialDistribution/test/PartialDistribution.test.cpp new file mode 100644 index 000000000..7e6c3c331 --- /dev/null +++ b/src/ENDFtk/section/15/PartialDistribution/test/PartialDistribution.test.cpp @@ -0,0 +1,244 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/15.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using PartialDistribution = +section::Type< 15 >::PartialDistribution; +using Probability = +section::Type< 15 >::Probability; +using TabulatedSpectrum = +section::Type< 15 >::TabulatedSpectrum; + +std::string chunkLF1(); +void verifyChunkLF1( const PartialDistribution& ); +std::string invalidLF(); + +SCENARIO( "PartialDistribution" ) { + + GIVEN( "valid data for a PartialDistribution using TabulatedSpectrum (LF=1)" ) { + + std::string string = chunkLF1(); + + WHEN( "the data is given explicitly" ) { + + Probability probability( 1, { 2 }, { 2 }, + { 1e-5, 3e+7 }, + { 1.0, 1.0 } ); + TabulatedSpectrum spectrum( { 2 }, { 4 }, + { { 1e-5, { 3 }, { 2 }, + { 0.0, 1e+5, 3e+7 }, + { 0.0, 1.757570e-9, 1.843350e-9 } }, + { 3e+7, { 4 }, { 2 }, + { 0.0, 10., 11., 3e+7 }, + { 0.0, 1.733405e-9, + 1.818010e-9, 1.898849e-9 } } } ); + + PartialDistribution chunk( std::move( probability ), std::move( spectrum ) ); + + THEN( "a PartialDistribution can be constructed and members can be tested" ) { + + verifyChunkLF1( chunk ); + } + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9437, 15, 18 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + PartialDistribution chunk( begin, end, lineNumber, 9437, 15, 18 ); + + THEN( "a PartialDistribution can be constructed and members can be tested" ) { + + verifyChunkLF1( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9437, 15, 18 ); + + CHECK( buffer == string ); + } // THEN + } //WHEN + } // GIVEN + + GIVEN( "invalid data for a PartialDistribution" ) { + + WHEN( "an inconsistent LF between the partial probability and spectrum" ) { + + Probability probability( 2, { 2 }, { 2 }, // LF=2 + { 1e-5, 3e+7 }, + { 1.0, 1.0 } ); + TabulatedSpectrum spectrum( { 2 }, { 4 }, // LF=1 + { { 1e-5, { 3 }, { 2 }, + { 0.0, 1e+5, 3e+7 }, + { 0.0, 1.757570e-9, 1.843350e-9 } }, + { 3e+7, { 4 }, { 2 }, + { 0.0, 10., 11., 3e+7 }, + { 0.0, 1.733405e-9, + 1.818010e-9, 1.898849e-9 } } } ); + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( PartialDistribution( std::move( probability ), + std::move( spectrum )) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an invalid LF number" ) { + + std::string string = invalidLF(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( PartialDistribution(begin, end, lineNumber, 9222, 15, 18 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunkLF1() { + return + " 0.000000+0 0.000000+0 0 1 1 2943715 18 \n" + " 2 2 943715 18 \n" + " 1.000000-5 1.000000+0 3.000000+7 1.000000+0 943715 18 \n" + " 0.000000+0 0.000000+0 0 0 1 2943715 18 \n" + " 2 4 943715 18 \n" + " 0.000000+0 1.000000-5 0 0 1 3943715 18 \n" + " 3 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n" + " 0.000000+0 3.000000+7 0 0 1 4943715 18 \n" + " 4 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+1 1.733405-9 1.100000+1 1.818010-9943715 18 \n" + " 3.000000+7 1.898849-9 943715 18 \n"; +} + +void verifyChunkLF1( const PartialDistribution& chunk ) { + + auto p = chunk.probability(); + + CHECK( 1 == p.LF() ); + CHECK( 1 == p.LAW() ); + + CHECK( 2 == p.NP() ); + CHECK( 1 == p.NR() ); + CHECK( 1 == p.interpolants().size() ); + CHECK( 1 == p.boundaries().size() ); + CHECK( 2 == p.interpolants()[0] ); + CHECK( 2 == p.boundaries()[0] ); + CHECK( 2 == p.E().size() ); + CHECK( 2 == p.energies().size() ); + CHECK( 2 == p.P().size() ); + CHECK( 2 == p.probabilities().size() ); + CHECK( 1e-5 == Approx( p.E()[0] ) ); + CHECK( 3e+7 == Approx( p.E()[1] ) ); + CHECK( 1e-5 == Approx( p.energies()[0] ) ); + CHECK( 3e+7 == Approx( p.energies()[1] ) ); + CHECK( 1. == Approx( p.P()[0] ) ); + CHECK( 1. == Approx( p.P()[1] ) ); + CHECK( 1. == Approx( p.probabilities()[0] ) ); + CHECK( 1. == Approx( p.probabilities()[1] ) ); + + auto d = chunk.distribution(); + + CHECK( 1 == d.NR() ); + CHECK( 2 == d.NE() ); + CHECK( 1 == d.boundaries().size() ); + CHECK( 2 == d.boundaries()[0] ); + CHECK( 1 == d.interpolants().size() ); + CHECK( 4 == d.interpolants()[0] ); + + CHECK( 2 == d.incidentEnergies().size() ); + CHECK( 1e-5 == Approx( d.incidentEnergies()[0] ) ); + CHECK( 3e+7 == Approx( d.incidentEnergies()[1] ) ); + + auto value = d.outgoingDistributions()[0]; + CHECK( 1e-5 == Approx( value.incidentEnergy() ) ); + CHECK( 3 == value.NP() ); + CHECK( 1 == value.NR() ); + CHECK( 1 == value.interpolants().size() ); + CHECK( 1 == value.boundaries().size() ); + CHECK( 2 == value.interpolants()[0] ); + CHECK( 3 == value.boundaries()[0] ); + CHECK( 3 == value.EP().size() ); + CHECK( 3 == value.outgoingEnergies().size() ); + CHECK( 3 == value.G().size() ); + CHECK( 3 == value.probabilities().size() ); + CHECK( 0.0 == Approx( value.EP()[0] ) ); + CHECK( 1e+5 == Approx( value.EP()[1] ) ); + CHECK( 3e+7 == Approx( value.EP()[2] ) ); + CHECK( 0.0 == Approx( value.outgoingEnergies()[0] ) ); + CHECK( 1e+5 == Approx( value.outgoingEnergies()[1] ) ); + CHECK( 3e+7 == Approx( value.outgoingEnergies()[2] ) ); + CHECK( 0. == Approx( value.G()[0] ) ); + CHECK( 1.757570e-9 == Approx( value.G()[1] ) ); + CHECK( 1.843350e-9 == Approx( value.G()[2] ) ); + CHECK( 0. == Approx( value.probabilities()[0] ) ); + CHECK( 1.757570e-9 == Approx( value.probabilities()[1] ) ); + CHECK( 1.843350e-9 == Approx( value.probabilities()[2] ) ); + + value = d.outgoingDistributions()[1]; + CHECK( 3e+7 == Approx( value.incidentEnergy() ) ); + CHECK( 4 == value.NP() ); + CHECK( 1 == value.NR() ); + CHECK( 1 == value.interpolants().size() ); + CHECK( 1 == value.boundaries().size() ); + CHECK( 2 == value.interpolants()[0] ); + CHECK( 4 == value.boundaries()[0] ); + CHECK( 4 == value.EP().size() ); + CHECK( 4 == value.outgoingEnergies().size() ); + CHECK( 4 == value.G().size() ); + CHECK( 4 == value.probabilities().size() ); + CHECK( 0.0 == Approx( value.EP()[0] ) ); + CHECK( 10. == Approx( value.EP()[1] ) ); + CHECK( 11. == Approx( value.EP()[2] ) ); + CHECK( 3e+7 == Approx( value.EP()[3] ) ); + CHECK( 0.0 == Approx( value.outgoingEnergies()[0] ) ); + CHECK( 10. == Approx( value.outgoingEnergies()[1] ) ); + CHECK( 11. == Approx( value.outgoingEnergies()[2] ) ); + CHECK( 3e+7 == Approx( value.outgoingEnergies()[3] ) ); + CHECK( 0. == Approx( value.G()[0] ) ); + CHECK( 1.733405e-9 == Approx( value.G()[1] ) ); + CHECK( 1.818010e-9 == Approx( value.G()[2] ) ); + CHECK( 1.898849e-9 == Approx( value.G()[3] ) ); + CHECK( 0. == Approx( value.probabilities()[0] ) ); + CHECK( 1.733405e-9 == Approx( value.probabilities()[1] ) ); + CHECK( 1.818010e-9 == Approx( value.probabilities()[2] ) ); + CHECK( 1.898849e-9 == Approx( value.probabilities()[3] ) ); + + CHECK( 12 == chunk.NC() ); +} + +std::string invalidLF() { + return + " 0.000000+0 0.000000+0 0 2 1 2922215 18 \n" + " 2 2 922215 18 \n" + " 1.000000-5 1.000000+0 3.000000+7 1.000000+0 922215 18 \n" + " 0.000000+0 0.000000+0 0 0 1 3922215 18 \n" + " 3 2 922215 18 \n" + " 1.000000-5 9.770000+5 1.500000+6 1.000000+6 3.000000+7 1.060000+6922215 18 \n" + " 0.000000+0 0.000000+0 0 0 1 5922215 18 \n" + " 5 2 922215 18 \n" + " 1.000000-5 2.546000-6 1.500000+6 2.546000-6 1.000000+7 2.474000-6922215 18 \n" + " 1.220000+7 2.612000-6 3.000000+7 2.620000-6 922215 18 \n"; +} diff --git a/src/ENDFtk/section/15/Probability/test/CMakeLists.txt b/src/ENDFtk/section/15/Probability/test/CMakeLists.txt new file mode 100644 index 000000000..4394dba42 --- /dev/null +++ b/src/ENDFtk/section/15/Probability/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.15.Probability.test Probability.test.cpp ) +target_compile_options( ENDFtk.section.15.Probability.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.15.Probability.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.15.Probability COMMAND ENDFtk.section.15.Probability.test ) diff --git a/src/ENDFtk/section/15/Probability/test/Probability.test.cpp b/src/ENDFtk/section/15/Probability/test/Probability.test.cpp new file mode 100644 index 000000000..26d72aa9a --- /dev/null +++ b/src/ENDFtk/section/15/Probability/test/Probability.test.cpp @@ -0,0 +1,156 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/15.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using Probability = +section::Type< 15 >::Probability; + +std::string chunk(); +void verifyChunk( const Probability& ); +std::string invalidChunk(); + +SCENARIO( "Probability" ) { + + GIVEN( "valid data for a Probability" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + long lf = 1; + std::vector< long > boundaries = { 2 }; + std::vector< long > interpolants = { 2 }; + std::vector< double > energies = { 1e-5, 3e+7 }; + std::vector< double > probabilities = { 1., 1. }; + + Probability chunk( lf, + std::move( boundaries ), + std::move( interpolants ), + std::move( energies ), + std::move( probabilities ) ); + + THEN( "a Probability can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } //THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9437, 15, 18 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + Probability chunk( begin, end, lineNumber, 9437, 15, 18 ); + + THEN( "a Probability can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9437, 15, 18 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a Probability" ) { + + WHEN( "inconsistent data is used" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + long lf = 1; + std::vector< long > boundaries = { 2 }; + std::vector< long > wrongInterpolants = { 2, 4 }; + std::vector< double > energies = { 1e-5, 3e+7 }; + std::vector< double > probabilities = { 1., 1. }; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( Probability( lf, + std::move( boundaries ), + std::move( wrongInterpolants ), + std::move( energies ), + std::move( probabilities ) ) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( Probability( begin, end, lineNumber, 9437, 15, 18 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 0.000000+0 0.000000+0 0 1 1 2943715 18 \n" + " 2 2 943715 18 \n" + " 1.000000-5 1.000000+0 3.000000+7 1.000000+0 943715 18 \n"; +} + +void verifyChunk( const Probability& chunk ) { + + CHECK( 1 == chunk.LF() ); + CHECK( 1 == chunk.LAW() ); + + CHECK( 2 == chunk.NP() ); + CHECK( 1 == chunk.NR() ); + CHECK( 1 == chunk.interpolants().size() ); + CHECK( 1 == chunk.boundaries().size() ); + CHECK( 2 == chunk.interpolants()[0] ); + CHECK( 2 == chunk.boundaries()[0] ); + CHECK( 2 == chunk.E().size() ); + CHECK( 2 == chunk.energies().size() ); + CHECK( 2 == chunk.P().size() ); + CHECK( 2 == chunk.probabilities().size() ); + CHECK( 1e-5 == Approx( chunk.E()[0] ) ); + CHECK( 3e+7 == Approx( chunk.E()[1] ) ); + CHECK( 1e-5 == Approx( chunk.energies()[0] ) ); + CHECK( 3e+7 == Approx( chunk.energies()[1] ) ); + CHECK( 1. == Approx( chunk.P()[0] ) ); + CHECK( 1. == Approx( chunk.P()[1] ) ); + CHECK( 1. == Approx( chunk.probabilities()[0] ) ); + CHECK( 1. == Approx( chunk.probabilities()[1] ) ); + + CHECK( 3 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 0.000000+0 0.000000+0 0 1 2 29437 5 18 \n" + " 2 2 9437 5 18 \n" + " 1.000000-5 1.000000+0 3.000000+7 1.000000+0 9437 5 18 \n"; +} diff --git a/src/ENDFtk/section/15/TabulatedSpectrum/OutgoingEnergyDistribution/test/CMakeLists.txt b/src/ENDFtk/section/15/TabulatedSpectrum/OutgoingEnergyDistribution/test/CMakeLists.txt new file mode 100644 index 000000000..c76e2d832 --- /dev/null +++ b/src/ENDFtk/section/15/TabulatedSpectrum/OutgoingEnergyDistribution/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.15.TabulatedSpectrum.OutgoingEnergyDistribution.test OutgoingDistribution.test.cpp ) +target_compile_options( ENDFtk.section.15.TabulatedSpectrum.OutgoingEnergyDistribution.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.15.TabulatedSpectrum.OutgoingEnergyDistribution.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.15.TabulatedSpectrum.OutgoingEnergyDistribution COMMAND ENDFtk.section.15.TabulatedSpectrum.OutgoingEnergyDistribution.test ) diff --git a/src/ENDFtk/section/15/TabulatedSpectrum/OutgoingEnergyDistribution/test/OutgoingDistribution.test.cpp b/src/ENDFtk/section/15/TabulatedSpectrum/OutgoingEnergyDistribution/test/OutgoingDistribution.test.cpp new file mode 100644 index 000000000..93b41c090 --- /dev/null +++ b/src/ENDFtk/section/15/TabulatedSpectrum/OutgoingEnergyDistribution/test/OutgoingDistribution.test.cpp @@ -0,0 +1,162 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/15.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using OutgoingEnergyDistribution = +section::Type< 15 >::TabulatedSpectrum::OutgoingEnergyDistribution; + +std::string chunk(); +void verifyChunk( const OutgoingEnergyDistribution& ); +std::string invalidChunk(); + +SCENARIO( "OutgoingEnergyDistribution" ) { + + GIVEN( "valid data for an OutgoingEnergyDistribution" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double incident = 1e-5; + std::vector< long > boundaries = { 3 }; + std::vector< long > interpolants = { 2 }; + std::vector< double > energies = { 0.0, 1e+5, 3e+7 }; + std::vector< double > values = { 0.0, 1.757570e-9, 1.843350e-9 }; + + OutgoingEnergyDistribution chunk( incident, + std::move( boundaries ), + std::move( interpolants ), + std::move( energies ), + std::move( values ) ); + + THEN( "an OutgoingEnergyDistribution can be constructed and members can " + "be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9437, 15, 18 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + OutgoingEnergyDistribution chunk( begin, end, lineNumber, 9437, 15, 18 ); + + THEN( "an OutgoingEnergyDistribution can be constructed and members can " + "be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9437, 15, 18 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for an OutgoingEnergyDistribution" ) { + + WHEN( "inconsistent data is used" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + double incident = 1e-5; + std::vector< long > boundaries = { 3 }; + std::vector< long > wrongInterpolants = { 2, 4 }; + std::vector< double > energies = { 0.0, 1e+5, 3e+7 }; + std::vector< double > values = { 0.0, 1.757570e-9, 1.843350e-9 }; + + THEN( "an exception is thrown" ) { + + REQUIRE_THROWS( + OutgoingEnergyDistribution( incident, + std::move( boundaries ), + std::move( wrongInterpolants ), + std::move( energies ), + std::move( values ) ) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + REQUIRE_THROWS( OutgoingEnergyDistribution( begin, end, lineNumber, + 9437, 15, 18 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 0.000000+0 1.000000-5 0 0 1 3943715 18 \n" + " 3 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n"; +} + +void verifyChunk( const OutgoingEnergyDistribution& chunk ) { + + CHECK( 1e-5 == Approx( chunk.E() ) ); + CHECK( 1e-5 == Approx( chunk.incidentEnergy() ) ); + + CHECK( 3 == chunk.NP() ); + CHECK( 1 == chunk.NR() ); + CHECK( 1 == chunk.interpolants().size() ); + CHECK( 1 == chunk.boundaries().size() ); + CHECK( 2 == chunk.interpolants()[0] ); + CHECK( 3 == chunk.boundaries()[0] ); + CHECK( 3 == chunk.EP().size() ); + CHECK( 3 == chunk.outgoingEnergies().size() ); + CHECK( 3 == chunk.G().size() ); + CHECK( 3 == chunk.probabilities().size() ); + CHECK( 0.0 == Approx( chunk.EP()[0] ) ); + CHECK( 1e+5 == Approx( chunk.EP()[1] ) ); + CHECK( 3e+7 == Approx( chunk.EP()[2] ) ); + CHECK( 0.0 == Approx( chunk.outgoingEnergies()[0] ) ); + CHECK( 1e+5 == Approx( chunk.outgoingEnergies()[1] ) ); + CHECK( 3e+7 == Approx( chunk.outgoingEnergies()[2] ) ); + CHECK( 0. == Approx( chunk.G()[0] ) ); + CHECK( 1.757570e-9 == Approx( chunk.G()[1] ) ); + CHECK( 1.843350e-9 == Approx( chunk.G()[2] ) ); + CHECK( 0. == Approx( chunk.probabilities()[0] ) ); + CHECK( 1.757570e-9 == Approx( chunk.probabilities()[1] ) ); + CHECK( 1.843350e-9 == Approx( chunk.probabilities()[2] ) ); + + CHECK( 3 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 0.000000+0 1.000000-5 0 0 2 3943715 18 \n" + " 3 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n"; +} diff --git a/src/ENDFtk/section/15/TabulatedSpectrum/test/CMakeLists.txt b/src/ENDFtk/section/15/TabulatedSpectrum/test/CMakeLists.txt new file mode 100644 index 000000000..70dacbf84 --- /dev/null +++ b/src/ENDFtk/section/15/TabulatedSpectrum/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.15.TabulatedSpectrum.test TabulatedSpectrum.test.cpp ) +target_compile_options( ENDFtk.section.15.TabulatedSpectrum.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.15.TabulatedSpectrum.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.15.TabulatedSpectrum COMMAND ENDFtk.section.15.TabulatedSpectrum.test ) diff --git a/src/ENDFtk/section/15/TabulatedSpectrum/test/TabulatedSpectrum.test.cpp b/src/ENDFtk/section/15/TabulatedSpectrum/test/TabulatedSpectrum.test.cpp new file mode 100644 index 000000000..2bfa3e1e7 --- /dev/null +++ b/src/ENDFtk/section/15/TabulatedSpectrum/test/TabulatedSpectrum.test.cpp @@ -0,0 +1,223 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/15.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using TabulatedSpectrum = section::Type< 15 >::TabulatedSpectrum; +using OutgoingEnergyDistribution = +section::Type< 15 >::TabulatedSpectrum::OutgoingEnergyDistribution; + +std::string chunk(); +void verifyChunk( const TabulatedSpectrum& ); +std::string invalidChunk(); + +SCENARIO( "TabulatedSpectrum" ) { + + GIVEN( "valid data for a TabulatedSpectrum" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + std::vector< long > boundaries = { 2 }; + std::vector< long > interpolants = { 4 }; + std::vector< OutgoingEnergyDistribution > outgoing = { + OutgoingEnergyDistribution( 1e-5, { 3 }, { 2 }, + { 0.0, 1e+5, 3e+7 }, + { 0.0, 1.757570e-9, 1.843350e-9 } ), + OutgoingEnergyDistribution( 3e+7, { 4 }, { 2 }, + { 0.0, 10., 11., 3e+7 }, + { 0.0, 1.733405e-9, 1.818010e-9, + 1.898849e-9 } ) }; + + TabulatedSpectrum chunk( std::move( boundaries ), + std::move( interpolants ), + std::move( outgoing ) ); + + THEN( "a TabulatedSpectrum can be constructed" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9437, 15, 18 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + TabulatedSpectrum chunk( begin, end, lineNumber, 9437, 15, 18 ); + + THEN( "a TabulatedSpectrum can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9437, 15, 18 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a TabulatedSpectrum" ) { + + WHEN( "inconsistent data is used" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + std::vector< long > boundaries = { 2 }; + std::vector< long > wrongInterpolants = { 4, 2 }; + std::vector< OutgoingEnergyDistribution > outgoing = { + OutgoingEnergyDistribution( 1e-5, { 3 }, { 2 }, + { 0.0, 1e+5, 3e+7 }, + { 0.0, 1.757570e-9, 1.843350e-9 } ), + OutgoingEnergyDistribution( 3e+7, { 4 }, { 2 }, + { 0.0, 10., 11., 3e+7 }, + { 0.0, 1.733405e-9, 1.818010e-9, + 1.898849e-9 } ) }; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( TabulatedSpectrum( std::move( boundaries ), + std::move( wrongInterpolants ), + std::move( outgoing ) ) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( TabulatedSpectrum( begin, end, lineNumber, + 9437, 15, 18 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 0.000000+0 0.000000+0 0 0 1 2943715 18 \n" + " 2 4 943715 18 \n" + " 0.000000+0 1.000000-5 0 0 1 3943715 18 \n" + " 3 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n" + " 0.000000+0 3.000000+7 0 0 1 4943715 18 \n" + " 4 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+1 1.733405-9 1.100000+1 1.818010-9943715 18 \n" + " 3.000000+7 1.898849-9 943715 18 \n"; +} + +void verifyChunk( const TabulatedSpectrum& chunk ) { + + CHECK( 1 == chunk.LF() ); + CHECK( 1 == chunk.LAW() ); + + CHECK( 1 == chunk.NR() ); + CHECK( 2 == chunk.NE() ); + CHECK( 1 == chunk.boundaries().size() ); + CHECK( 2 == chunk.boundaries()[0] ); + CHECK( 1 == chunk.interpolants().size() ); + CHECK( 4 == chunk.interpolants()[0] ); + + CHECK( 2 == chunk.incidentEnergies().size() ); + CHECK( 1e-5 == Approx( chunk.incidentEnergies()[0] ) ); + CHECK( 3e+7 == Approx( chunk.incidentEnergies()[1] ) ); + + auto value = chunk.outgoingDistributions()[0]; + CHECK( 1e-5 == Approx( value.E() ) ); + CHECK( 1e-5 == Approx( value.incidentEnergy() ) ); + CHECK( 3 == value.NP() ); + CHECK( 1 == value.NR() ); + CHECK( 1 == value.interpolants().size() ); + CHECK( 1 == value.boundaries().size() ); + CHECK( 2 == value.interpolants()[0] ); + CHECK( 3 == value.boundaries()[0] ); + CHECK( 3 == value.EP().size() ); + CHECK( 3 == value.outgoingEnergies().size() ); + CHECK( 3 == value.G().size() ); + CHECK( 3 == value.probabilities().size() ); + CHECK( 0.0 == Approx( value.EP()[0] ) ); + CHECK( 1e+5 == Approx( value.EP()[1] ) ); + CHECK( 3e+7 == Approx( value.EP()[2] ) ); + CHECK( 0.0 == Approx( value.outgoingEnergies()[0] ) ); + CHECK( 1e+5 == Approx( value.outgoingEnergies()[1] ) ); + CHECK( 3e+7 == Approx( value.outgoingEnergies()[2] ) ); + CHECK( 0. == Approx( value.G()[0] ) ); + CHECK( 1.757570e-9 == Approx( value.G()[1] ) ); + CHECK( 1.843350e-9 == Approx( value.G()[2] ) ); + CHECK( 0. == Approx( value.probabilities()[0] ) ); + CHECK( 1.757570e-9 == Approx( value.probabilities()[1] ) ); + CHECK( 1.843350e-9 == Approx( value.probabilities()[2] ) ); + + value = chunk.outgoingDistributions()[1]; + CHECK( 3e+7 == Approx( value.E() ) ); + CHECK( 3e+7 == Approx( value.incidentEnergy() ) ); + CHECK( 4 == value.NP() ); + CHECK( 1 == value.NR() ); + CHECK( 1 == value.interpolants().size() ); + CHECK( 1 == value.boundaries().size() ); + CHECK( 2 == value.interpolants()[0] ); + CHECK( 4 == value.boundaries()[0] ); + CHECK( 4 == value.EP().size() ); + CHECK( 4 == value.outgoingEnergies().size() ); + CHECK( 4 == value.G().size() ); + CHECK( 4 == value.probabilities().size() ); + CHECK( 0.0 == Approx( value.EP()[0] ) ); + CHECK( 10. == Approx( value.EP()[1] ) ); + CHECK( 11. == Approx( value.EP()[2] ) ); + CHECK( 3e+7 == Approx( value.EP()[3] ) ); + CHECK( 0.0 == Approx( value.outgoingEnergies()[0] ) ); + CHECK( 10. == Approx( value.outgoingEnergies()[1] ) ); + CHECK( 11. == Approx( value.outgoingEnergies()[2] ) ); + CHECK( 3e+7 == Approx( value.outgoingEnergies()[3] ) ); + CHECK( 0. == Approx( value.G()[0] ) ); + CHECK( 1.733405e-9 == Approx( value.G()[1] ) ); + CHECK( 1.818010e-9 == Approx( value.G()[2] ) ); + CHECK( 1.898849e-9 == Approx( value.G()[3] ) ); + CHECK( 0. == Approx( value.probabilities()[0] ) ); + CHECK( 1.733405e-9 == Approx( value.probabilities()[1] ) ); + CHECK( 1.818010e-9 == Approx( value.probabilities()[2] ) ); + CHECK( 1.898849e-9 == Approx( value.probabilities()[3] ) ); + + CHECK( 9 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 0.000000+0 0.000000+0 0 0 2 2943715 18 \n" + " 2 4 943715 18 \n" + " 0.000000+0 1.000000-5 0 0 1 3943715 18 \n" + " 3 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n" + " 0.000000+0 3.000000+7 0 0 1 4943715 18 \n" + " 4 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+1 1.733405-9 1.100000+1 1.818010-9943715 18 \n" + " 3.000000+7 1.898849-9 943715 18 \n"; +} diff --git a/src/ENDFtk/section/15/src/ctor.hpp b/src/ENDFtk/section/15/src/ctor.hpp new file mode 100644 index 000000000..9126817ca --- /dev/null +++ b/src/ENDFtk/section/15/src/ctor.hpp @@ -0,0 +1,44 @@ +/** + * @brief Constructor + * + * @param[in] mt the MT number of the section + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] partials the partial distributions (at least 1) + */ +Type( int mt, double zaid, double awr, + std::vector< PartialDistribution >&& partials ) : + Base( zaid, awr, mt ), partials_( std::move( partials ) ) { + + verifyNK( this->NK() ); +} + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] head the head record of the section + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + */ +template< typename Iterator > +Type( HEAD& head, + Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT ) + try: + Base( head, MAT, 15 ), + partials_( readSequence< PartialDistribution >( + begin, end, lineNumber, + MAT, 15, head.MT(), head.N1() ) ) { + verifyNK( this->NK() ); + readSEND( begin, end, lineNumber, MAT, 15 ); + } catch( std::exception& e ) { + Log::info( "Trouble while reading section {} of File 15 of Material {}", + head.MT(), MAT ); + throw e; + } diff --git a/src/ENDFtk/section/15/test/15.test.cpp b/src/ENDFtk/section/15/test/15.test.cpp new file mode 100644 index 000000000..38f9f5769 --- /dev/null +++ b/src/ENDFtk/section/15/test/15.test.cpp @@ -0,0 +1,331 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/15.hpp" + +// other includes +#include "ENDFtk/tree/Section.hpp" + +// convenience typedefs +using namespace njoy::ENDFtk; +using PartialDistribution = section::Type< 15 >::PartialDistribution; +using Probability = section::Type< 15 >::Probability; +using TabulatedSpectrum = section::Type< 15 >::TabulatedSpectrum; +using OutgoingEnergyDistribution = +section::Type< 15 >::TabulatedSpectrum::OutgoingEnergyDistribution; + +std::string chunk(); +void verifyChunk( const section::Type< 15 >& ); +std::string chunkWithNK0(); +std::string validSEND(); +std::string invalidSEND(); + +SCENARIO( "section::Type< 15 >" ) { + + GIVEN( "valid data for a section::Type< 15 >" ) { + + std::string sectionString = chunk() + validSEND(); + + WHEN( "the data is given explicitly" ) { + + int mt = 18; + double za = 92235.; + double awr = 2.330250e+2; + + std::vector< PartialDistribution > partials = + { { Probability( 1, { 2 }, { 2 }, + { 1e-5, 3e+7 }, { 1., 1. } ), + TabulatedSpectrum( + { 2 }, { 4 }, + { OutgoingEnergyDistribution( + 1e-5, { 3 }, { 2 }, + { 0.0, 1e+5, 3e+7 }, + { 0.0, 1.757570e-9, 1.843350e-9 } ), + OutgoingEnergyDistribution( + 3e+7, { 4 }, { 2 }, + { 0.0, 10., 11., 3e+7 }, + { 0.0, 1.733405e-9, 1.818010e-9, 1.898849e-9 } ) } ) } }; + + section::Type< 15 > chunk( mt, za, awr, std::move( partials ) ); + + THEN( "a section::Type< 15 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 15 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 15 > chunk( head, begin, end, lineNumber, 9228 ); + + THEN( "a section::Type< 15 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 15 ); + + CHECK( buffer == sectionString ); + } // THEN + } //WHEN + + WHEN( "there is a tree::Section" ) { + + auto begin = sectionString.begin(); + auto position = begin; + auto end = sectionString.end(); + long lineNumber = 1; + auto head = HEAD( position, end, lineNumber ); + tree::Section< std::string::iterator > + section( head, begin, position, end, lineNumber ); + + section::Type< 15 > chunk1 = section.parse< 15 >(); + section::Type< 15 > chunk2 = section.parse< 15 >( lineNumber ); + section::Type< 15 > chunk3 = section.parse( 15_c ); + section::Type< 15 > chunk4 = section.parse( 15_c, lineNumber ); + + THEN( "a section::Type< 15 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk1 ); + verifyChunk( chunk2 ); + verifyChunk( chunk3 ); + verifyChunk( chunk4 ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer1; + auto output1 = std::back_inserter( buffer1 ); + chunk1.print( output1, 9228, 15 ); + + std::string buffer2; + auto output2 = std::back_inserter( buffer2 ); + chunk1.print( output2, 9228, 15 ); + + std::string buffer3; + auto output3 = std::back_inserter( buffer3 ); + chunk1.print( output3, 9228, 15 ); + + std::string buffer4; + auto output4 = std::back_inserter( buffer4 ); + chunk1.print( output4, 9228, 15 ); + + CHECK( buffer1 == sectionString ); + CHECK( buffer2 == sectionString ); + CHECK( buffer3 == sectionString ); + CHECK( buffer4 == sectionString ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a section::Type< 15 >" ) { + + WHEN( "a string representation of a section::Type< 15 > with NK=0" ) { + + std::string sectionString = chunkWithNK0() + validSEND(); + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( section::Type< 15 >( head, begin, end, + lineNumber, 9228 ) ); + } // THEN + } // WHEN + + WHEN( "a string representation of a valid section::Type< 15 > " + "with an invalid SEND" ) { + + std::string sectionString = chunk() + invalidSEND(); + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( section::Type< 15 >( head, begin, end, + lineNumber, 9228 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 9.223500+4 2.330250+2 0 0 1 0922815 18 \n" + " 0.000000+0 0.000000+0 0 1 1 2922815 18 \n" + " 2 2 922815 18 \n" + " 1.000000-5 1.000000+0 3.000000+7 1.000000+0 922815 18 \n" + " 0.000000+0 0.000000+0 0 0 1 2922815 18 \n" + " 2 4 922815 18 \n" + " 0.000000+0 1.000000-5 0 0 1 3922815 18 \n" + " 3 2 922815 18 \n" + " 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9922815 18 \n" + " 0.000000+0 3.000000+7 0 0 1 4922815 18 \n" + " 4 2 922815 18 \n" + " 0.000000+0 0.000000+0 1.000000+1 1.733405-9 1.100000+1 1.818010-9922815 18 \n" + " 3.000000+7 1.898849-9 922815 18 \n"; +} + +void verifyChunk( const section::Type< 15 >& chunk ) { + + CHECK( 18 == chunk.MT() ); + CHECK( 18 == chunk.sectionNumber() ); + + CHECK( 92235. == Approx( chunk.ZA() ) ); + CHECK( 2.330250e+2 == Approx( chunk.AWR() ) ); + CHECK( 2.330250e+2 == Approx( chunk.atomicWeightRatio() ) ); + CHECK( 1 == chunk.NK() ); + CHECK( 1 == chunk.numberPartialDistributions() ); + + const auto& partial = chunk.partialDistributions()[0]; + + const auto& p = partial.probability(); + + CHECK( 1 == p.LF() ); + CHECK( 1 == p.LAW() ); + + CHECK( 2 == p.NP() ); + CHECK( 1 == p.NR() ); + CHECK( 1 == p.interpolants().size() ); + CHECK( 1 == p.boundaries().size() ); + CHECK( 2 == p.interpolants()[0] ); + CHECK( 2 == p.boundaries()[0] ); + CHECK( 2 == p.E().size() ); + CHECK( 2 == p.energies().size() ); + CHECK( 2 == p.P().size() ); + CHECK( 2 == p.probabilities().size() ); + CHECK( 1e-5 == Approx( p.E()[0] ) ); + CHECK( 3e+7 == Approx( p.E()[1] ) ); + CHECK( 1e-5 == Approx( p.energies()[0] ) ); + CHECK( 3e+7 == Approx( p.energies()[1] ) ); + CHECK( 1. == Approx( p.P()[0] ) ); + CHECK( 1. == Approx( p.P()[1] ) ); + CHECK( 1. == Approx( p.probabilities()[0] ) ); + CHECK( 1. == Approx( p.probabilities()[1] ) ); + + auto d = partial.distribution(); + + CHECK( 1 == d.LF() ); + CHECK( 1 == d.LAW() ); + + CHECK( 1 == d.NR() ); + CHECK( 2 == d.NE() ); + CHECK( 1 == d.boundaries().size() ); + CHECK( 2 == d.boundaries()[0] ); + CHECK( 1 == d.interpolants().size() ); + CHECK( 4 == d.interpolants()[0] ); + + CHECK( 2 == d.incidentEnergies().size() ); + CHECK( 1e-5 == Approx( d.incidentEnergies()[0] ) ); + CHECK( 3e+7 == Approx( d.incidentEnergies()[1] ) ); + + auto value = d.outgoingDistributions()[0]; + CHECK( 1e-5 == Approx( value.E() ) ); + CHECK( 1e-5 == Approx( value.incidentEnergy() ) ); + CHECK( 3 == value.NP() ); + CHECK( 1 == value.NR() ); + CHECK( 1 == value.interpolants().size() ); + CHECK( 1 == value.boundaries().size() ); + CHECK( 2 == value.interpolants()[0] ); + CHECK( 3 == value.boundaries()[0] ); + CHECK( 3 == value.EP().size() ); + CHECK( 3 == value.outgoingEnergies().size() ); + CHECK( 3 == value.G().size() ); + CHECK( 3 == value.probabilities().size() ); + CHECK( 0.0 == Approx( value.EP()[0] ) ); + CHECK( 1e+5 == Approx( value.EP()[1] ) ); + CHECK( 3e+7 == Approx( value.EP()[2] ) ); + CHECK( 0.0 == Approx( value.outgoingEnergies()[0] ) ); + CHECK( 1e+5 == Approx( value.outgoingEnergies()[1] ) ); + CHECK( 3e+7 == Approx( value.outgoingEnergies()[2] ) ); + CHECK( 0. == Approx( value.G()[0] ) ); + CHECK( 1.757570e-9 == Approx( value.G()[1] ) ); + CHECK( 1.843350e-9 == Approx( value.G()[2] ) ); + CHECK( 0. == Approx( value.probabilities()[0] ) ); + CHECK( 1.757570e-9 == Approx( value.probabilities()[1] ) ); + CHECK( 1.843350e-9 == Approx( value.probabilities()[2] ) ); + + value = d.outgoingDistributions()[1]; + CHECK( 3e+7 == Approx( value.E() ) ); + CHECK( 3e+7 == Approx( value.incidentEnergy() ) ); + CHECK( 4 == value.NP() ); + CHECK( 1 == value.NR() ); + CHECK( 1 == value.interpolants().size() ); + CHECK( 1 == value.boundaries().size() ); + CHECK( 2 == value.interpolants()[0] ); + CHECK( 4 == value.boundaries()[0] ); + CHECK( 4 == value.EP().size() ); + CHECK( 4 == value.outgoingEnergies().size() ); + CHECK( 4 == value.G().size() ); + CHECK( 4 == value.probabilities().size() ); + CHECK( 0.0 == Approx( value.EP()[0] ) ); + CHECK( 10. == Approx( value.EP()[1] ) ); + CHECK( 11. == Approx( value.EP()[2] ) ); + CHECK( 3e+7 == Approx( value.EP()[3] ) ); + CHECK( 0.0 == Approx( value.outgoingEnergies()[0] ) ); + CHECK( 10. == Approx( value.outgoingEnergies()[1] ) ); + CHECK( 11. == Approx( value.outgoingEnergies()[2] ) ); + CHECK( 3e+7 == Approx( value.outgoingEnergies()[3] ) ); + CHECK( 0. == Approx( value.G()[0] ) ); + CHECK( 1.733405e-9 == Approx( value.G()[1] ) ); + CHECK( 1.818010e-9 == Approx( value.G()[2] ) ); + CHECK( 1.898849e-9 == Approx( value.G()[3] ) ); + CHECK( 0. == Approx( value.probabilities()[0] ) ); + CHECK( 1.733405e-9 == Approx( value.probabilities()[1] ) ); + CHECK( 1.818010e-9 == Approx( value.probabilities()[2] ) ); + CHECK( 1.898849e-9 == Approx( value.probabilities()[3] ) ); + + CHECK( 13 == chunk.NC() ); +} + +std::string chunkWithNK0() { + return + " 9.223500+4 2.330250+2 0 0 0 0922815 18 \n" + "-3.000000+7 0.000000+0 0 1 1 2922815 18 \n" + " 2 2 922815 18 \n" + " 1.000000-5 1.000000+0 3.000000+7 1.000000+0 922815 18 \n" + " 0.000000+0 0.000000+0 0 0 1 2943715 18 \n" + " 2 4 943715 18 \n" + " 0.000000+0 1.000000-5 0 0 1 3943715 18 \n" + " 3 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+5 1.757570-9 3.000000+7 1.843350-9943715 18 \n" + " 0.000000+0 3.000000+7 0 0 1 4943715 18 \n" + " 4 2 943715 18 \n" + " 0.000000+0 0.000000+0 1.000000+1 1.733405-9 1.100000+1 1.818010-9943715 18 \n" + " 3.000000+7 1.898849-9 943715 18 \n"; +} + +std::string validSEND() { + return + " 922815 0 \n"; +} + +std::string invalidSEND() { + return + " 922815 4 \n"; +} diff --git a/src/ENDFtk/section/15/test/CMakeLists.txt b/src/ENDFtk/section/15/test/CMakeLists.txt new file mode 100644 index 000000000..b9904c2cd --- /dev/null +++ b/src/ENDFtk/section/15/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.15.test 15.test.cpp ) +target_compile_options( ENDFtk.section.15.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.15.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.15 COMMAND ENDFtk.section.15.test ) diff --git a/src/ENDFtk/section/2/151.hpp b/src/ENDFtk/section/2/151.hpp index d9266c559..07e2e182f 100644 --- a/src/ENDFtk/section/2/151.hpp +++ b/src/ENDFtk/section/2/151.hpp @@ -8,6 +8,7 @@ // other includes #include "range/v3/algorithm/count.hpp" #include "range/v3/algorithm/find.hpp" +#include "range/v3/range/conversion.hpp" #include "range/v3/view/all.hpp" #include "range/v3/view/chunk.hpp" #include "range/v3/view/drop_exactly.hpp" @@ -105,7 +106,7 @@ namespace section { */ AllRange< Isotope > isotopes() const { - return ranges::view::all( this->isotopes_ ); + return ranges::cpp20::views::all( this->isotopes_ ); } using BaseWithoutMT::MT; diff --git a/src/ENDFtk/section/2/151/BreitWignerLValue.hpp b/src/ENDFtk/section/2/151/BreitWignerLValue.hpp index bbf869d43..3b80fc81c 100644 --- a/src/ENDFtk/section/2/151/BreitWignerLValue.hpp +++ b/src/ENDFtk/section/2/151/BreitWignerLValue.hpp @@ -9,6 +9,9 @@ class BreitWignerLValue : protected BreitWignerReichMooreLValueBase { public: + /* type aliases */ + using Column = BreitWignerReichMooreLValueBase::Column; + #include "ENDFtk/section/2/151/BreitWignerLValue/Resonance.hpp" /* constructor */ @@ -51,49 +54,49 @@ class BreitWignerLValue : protected BreitWignerReichMooreLValueBase { /** * @brief Return the total widths */ - auto GT() const { return BreitWignerReichMooreLValueBase::G1(); } + Column GT() const { return BreitWignerReichMooreLValueBase::G1(); } /** * @brief Return the total widths */ - auto totalWidths() const { return this->GT(); } + Column totalWidths() const { return this->GT(); } /** * @brief Return the neutron widths */ - auto GN() const { return BreitWignerReichMooreLValueBase::G2(); } + Column GN() const { return BreitWignerReichMooreLValueBase::G2(); } /** * @brief Return the neutron widths */ - auto neutronWidths() const { return this->GN(); } + Column neutronWidths() const { return this->GN(); } /** * @brief Return the gamma widths */ - auto GG() const { return BreitWignerReichMooreLValueBase::G3(); } + Column GG() const { return BreitWignerReichMooreLValueBase::G3(); } /** * @brief Return the gamma widths */ - auto gammaWidths() const { return this->GG(); } + Column gammaWidths() const { return this->GG(); } /** * @brief Return the fission widths */ - auto GF() const { return BreitWignerReichMooreLValueBase::G4(); } + Column GF() const { return BreitWignerReichMooreLValueBase::G4(); } /** * @brief Return the first fission widths */ - auto fissionWidths() const { return this->GF(); } + Column fissionWidths() const { return this->GF(); } /** * @brief Return the competitive widths */ auto GX() const { - return ranges::view::zip_with( + return ranges::views::zip_with( [] ( double gt, double gn, double gg, double gf ) { return gt - gn - gg - gf; }, this->GT(), this->GN(), this->GG(), this->GF() ); @@ -111,7 +114,7 @@ class BreitWignerLValue : protected BreitWignerReichMooreLValueBase { using Chunk = decltype( BreitWignerReichMooreLValueBase::resonances()[0] ); return BreitWignerReichMooreLValueBase::resonances() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( Chunk&& chunk ) -> Resonance< Chunk > { return { std::move( chunk ) }; } ); } diff --git a/src/ENDFtk/section/2/151/BreitWignerReichMooreBase.hpp b/src/ENDFtk/section/2/151/BreitWignerReichMooreBase.hpp index 3531842ea..f0f924fcc 100644 --- a/src/ENDFtk/section/2/151/BreitWignerReichMooreBase.hpp +++ b/src/ENDFtk/section/2/151/BreitWignerReichMooreBase.hpp @@ -35,7 +35,7 @@ class BreitWignerReichMooreBase { */ constexpr int LRU() const { - return static_cast< const Derived* >( this )->type(); + return static_cast< const Derived* >( this )->type(); } /** @@ -43,7 +43,7 @@ class BreitWignerReichMooreBase { */ constexpr int LRF() const { - return static_cast< const Derived* >( this )->representation(); + return static_cast< const Derived* >( this )->representation(); } /** @@ -114,7 +114,10 @@ class BreitWignerReichMooreBase { /** * @brief Return the l values and its resonance parameters */ - auto lValues() const { return ranges::view::all( this->lvalues_ ); } + AllRange< LValue > lValues() const { + + return ranges::cpp20::views::all( this->lvalues_ ); + } #include "ENDFtk/section/2/151/BreitWignerReichMooreBase/src/NC.hpp" #include "ENDFtk/section/2/151/BreitWignerReichMooreBase/src/print.hpp" diff --git a/src/ENDFtk/section/2/151/BreitWignerReichMooreLValueBase.hpp b/src/ENDFtk/section/2/151/BreitWignerReichMooreLValueBase.hpp index 042a33d5f..2cdbddf01 100644 --- a/src/ENDFtk/section/2/151/BreitWignerReichMooreLValueBase.hpp +++ b/src/ENDFtk/section/2/151/BreitWignerReichMooreLValueBase.hpp @@ -7,14 +7,20 @@ */ class BreitWignerReichMooreLValueBase : protected ListRecord { +public: + + using Column = StrideRange< DropRange< AllRange< double > > >; + +private: + /* auxiliary functions */ #include "ENDFtk/section/2/151/BreitWignerReichMooreLValueBase/src/verifySize.hpp" #include "ENDFtk/section/2/151/BreitWignerReichMooreLValueBase/src/generateList.hpp" - auto column( unsigned int i ) const { + Column column( unsigned int i ) const { - return ListRecord::list() | ranges::view::drop_exactly( i ) - | ranges::view::stride( 6 ); + return ListRecord::list() | ranges::views::drop_exactly( i ) + | ranges::views::stride( 6 ); } protected: @@ -25,29 +31,29 @@ class BreitWignerReichMooreLValueBase : protected ListRecord { /** * @brief Return the first width */ - auto G1() const { return BreitWignerReichMooreLValueBase::column( 2 ); } + Column G1() const { return BreitWignerReichMooreLValueBase::column( 2 ); } /** * @brief Return the second width */ - auto G2() const { return BreitWignerReichMooreLValueBase::column( 3 ); } + Column G2() const { return BreitWignerReichMooreLValueBase::column( 3 ); } /** * @brief Return the third width */ - auto G3() const { return BreitWignerReichMooreLValueBase::column( 4 ); } + Column G3() const { return BreitWignerReichMooreLValueBase::column( 4 ); } /** * @brief Return the fourth width */ - auto G4() const { return BreitWignerReichMooreLValueBase::column( 5 ); } + Column G4() const { return BreitWignerReichMooreLValueBase::column( 5 ); } /** * @brief Return the resonances */ - auto resonances() const { + ChunkRange< AllRange< double > > resonances() const { - return ListRecord::list() | ranges::view::chunk(6); + return ListRecord::list() | ranges::views::chunk(6); } public: @@ -93,22 +99,22 @@ class BreitWignerReichMooreLValueBase : protected ListRecord { /** * @brief Return the resonance energies */ - auto ER() const { return ListRecord::list() | ranges::view::stride( 6 ); } + Column ER() const { return BreitWignerReichMooreLValueBase::column( 0 ); } /** * @brief Return the resonance energies */ - auto resonanceEnergies() const { return this->ER(); } + Column resonanceEnergies() const { return this->ER(); } /** * @brief Return the spin values */ - auto AJ() const { return BreitWignerReichMooreLValueBase::column( 1 ); } + Column AJ() const { return BreitWignerReichMooreLValueBase::column( 1 ); } /** * @brief Return the spin values */ - auto spinValues() const { return this->AJ(); } + Column spinValues() const { return this->AJ(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/2/151/Isotope.hpp b/src/ENDFtk/section/2/151/Isotope.hpp index c2cb8b919..c99d1484a 100644 --- a/src/ENDFtk/section/2/151/Isotope.hpp +++ b/src/ENDFtk/section/2/151/Isotope.hpp @@ -65,9 +65,9 @@ class Isotope { /** * @brief Return the resonance ranges for this isotope */ - auto resonanceRanges() const { + AllRange< ResonanceRange > resonanceRanges() const { - return ranges::view::all( this->ranges_ ); + return ranges::cpp20::views::all( this->ranges_ ); } #include "ENDFtk/section/2/151/Isotope/src/print.hpp" diff --git a/src/ENDFtk/section/2/151/RMatrixLimited.hpp b/src/ENDFtk/section/2/151/RMatrixLimited.hpp index eb5ac7d97..1d1b4d855 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited.hpp @@ -96,12 +96,12 @@ class RMatrixLimited { /** * @brief Return the resonance formalism to be employed */ - auto KRM() const { return this->krm_; } + int KRM() const { return this->krm_; } /** * @brief Return the resonance formalism to be employed */ - auto formalism() const { return this->KRM(); } + int formalism() const { return this->KRM(); } /** * @brief Return the non relativistic kinematics flag @@ -121,17 +121,20 @@ class RMatrixLimited { /** * @brief Return the number of spin groups */ - auto numberSpinGroups() const { return this->NJS(); } + unsigned int numberSpinGroups() const { return this->NJS(); } /** * @brief Return the particle pair information */ - const auto& particlePairs() const { return this->particle_pairs_; } + const ParticlePairs& particlePairs() const { return this->particle_pairs_; } /** * @brief Return the spin groups */ - auto spinGroups() const { return ranges::view::all( this->spin_groups_ ); } + AllRange< SpinGroup > spinGroups() const { + + return ranges::cpp20::views::all( this->spin_groups_ ); + } #include "ENDFtk/section/2/151/RMatrixLimited/src/SPI.hpp" #include "ENDFtk/section/2/151/RMatrixLimited/src/AP.hpp" diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels.hpp index d6dea68a7..7ba0dc2fa 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels.hpp @@ -6,8 +6,15 @@ */ class BackgroundChannels { +public: + + /* type aliases */ + using OptionalBackgroundRMatrix = std::optional< BackgroundRMatrix >; + +private: + /* fields */ - std::vector< std::optional< BackgroundRMatrix > > channels_; + std::vector< OptionalBackgroundRMatrix > channels_; /* auxiliary functions */ #include "ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels/src/makeBackgroundMatrices.hpp" @@ -23,37 +30,37 @@ class BackgroundChannels { /** * @brief Return the number of channels */ - auto NCH() const { return this->channels_.size(); } + unsigned int NCH() const { return this->channels_.size(); } /** * @brief Return the number of channels */ - auto numberChannels() const { return this->NCH(); } + unsigned int numberChannels() const { return this->NCH(); } /** * @brief Return the background R-matrix values for all channels */ - auto backgroundRMatrices() const { + AllRange< OptionalBackgroundRMatrix > backgroundRMatrices() const { - return ranges::view::all( this->channels_ ); + return ranges::cpp20::views::all( this->channels_ ); } /** * @brief Return the number of channels with background R-matrix values */ - auto KBK() const { + unsigned int KBK() const { - return ranges::count( this->backgroundRMatrices() - | ranges::view::transform( - [] ( const auto& value ) - { return bool( value ); } ), - true ); + return ranges::cpp20::count( this->backgroundRMatrices() + | ranges::cpp20::views::transform( + [] ( const auto& value ) + { return bool( value ); } ), + true ); } /** * @brief Return the number of channels with background R-matrix values */ - auto numberBackgroundChannels() const { return this->KBK(); } + unsigned int numberBackgroundChannels() const { return this->KBK(); } #include "ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels/src/NC.hpp" #include "ENDFtk/section/2/151/RMatrixLimited/BackgroundChannels/src/print.hpp" diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/FrohnerBackgroundRMatrix/src/extract.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/FrohnerBackgroundRMatrix/src/extract.hpp index 6903681eb..6b120d30c 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/FrohnerBackgroundRMatrix/src/extract.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/FrohnerBackgroundRMatrix/src/extract.hpp @@ -13,7 +13,7 @@ extract( ListRecord&& record ) { auto list = record.list(); values[0] = record.C1(); values[1] = record.C2(); - std::copy_n( ranges::begin( list ), 3, values.begin() + 2 ); + std::copy_n( ranges::cpp20::begin( list ), 3, values.begin() + 2 ); return values; } diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/ParticlePairs.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/ParticlePairs.hpp index ebdd985eb..7d313da77 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/ParticlePairs.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/ParticlePairs.hpp @@ -10,18 +10,25 @@ */ class ParticlePairs : protected ListRecord { +public: + + using Column = StrideRange< DropRange< AllRange< double > > >; + +private: + /* auxiliary functions */ #include "ENDFtk/section/2/151/RMatrixLimited/ParticlePairs/src/generateList.hpp" #include "ENDFtk/section/2/151/RMatrixLimited/ParticlePairs/src/verifySize.hpp" - auto column( unsigned int i ) const { + Column column( unsigned int i ) const { return ListRecord::list() - | ranges::view::drop_exactly( i ) - | ranges::view::stride( 12 ); + | ranges::views::drop_exactly( i ) + | ranges::views::stride( 12 ); } public: + /* constructor */ #include "ENDFtk/section/2/151/RMatrixLimited/ParticlePairs/src/ctor.hpp" @@ -30,105 +37,105 @@ class ParticlePairs : protected ListRecord { /** * @brief Return the number of particle pairs */ - auto NPP() const { return ListRecord::NPL() / 12; } + unsigned int NPP() const { return ListRecord::NPL() / 12; } /** * @brief Return the number of particle pairs */ - auto numberParticlePairs() const { return this->NPP(); } + unsigned int numberParticlePairs() const { return this->NPP(); } /** * @brief Return the mass of the first particle in each particle pair */ - auto MA() const { return ListRecord::list() | ranges::view::stride( 12 ); } + Column MA() const { return ParticlePairs::column( 0 ); } /** * @brief Return the mass of the first particle in each particle pair */ - auto massParticleA() const { return this->MA(); } + Column massParticleA() const { return this->MA(); } /** * @brief Return the mass of the second particle in each particle pair */ - auto MB() const { return ParticlePairs::column( 1 ); } + Column MB() const { return ParticlePairs::column( 1 ); } /** * @brief Return the mass of the second particle in each particle pair */ - auto massParticleB() const { return this->MB(); } + Column massParticleB() const { return this->MB(); } /** * @brief Return the charge of the first particle in each particle pair */ - auto ZA() const { return ParticlePairs::column( 2 ); } + Column ZA() const { return ParticlePairs::column( 2 ); } /** * @brief Return the charge of the first particle in each particle pair */ - auto chargeParticleA() const { return this->ZA(); } + Column chargeParticleA() const { return this->ZA(); } /** * @brief Return the charge of the second particle in each particle pair */ - auto ZB() const { return ParticlePairs::column( 3 ); } + Column ZB() const { return ParticlePairs::column( 3 ); } /** * @brief Return the charge of the second particle in each particle pair */ - auto chargeParticleB() const { return this->ZB(); } + Column chargeParticleB() const { return this->ZB(); } /** * @brief Return the spin of the first particle in each particle pair */ - auto IA() const { return ParticlePairs::column( 4 ); } + Column IA() const { return ParticlePairs::column( 4 ); } /** * @brief Return the spin of the first particle in each particle pair */ - auto spinParticleA() const { return this->IA(); } + Column spinParticleA() const { return this->IA(); } /** * @brief Return the spin of the second particle in each particle pair */ - auto IB() const { return ParticlePairs::column( 5 ); } + Column IB() const { return ParticlePairs::column( 5 ); } /** * @brief Return the spin of the second particle in each particle pair */ - auto spinParticleB() const { return this->IB(); } + Column spinParticleB() const { return this->IB(); } /** * @brief Return the parity of the first particle in each particle pair */ - auto PA() const { return ParticlePairs::column( 10 ); } + Column PA() const { return ParticlePairs::column( 10 ); } /** * @brief Return the parity of the first particle in each particle pair */ - auto parityParticleA() const { return this->PA(); } + Column parityParticleA() const { return this->PA(); } /** * @brief Return the parity of the second particle in each particle pair */ - auto PB() const { return ParticlePairs::column( 11 ); } + Column PB() const { return ParticlePairs::column( 11 ); } /** * @brief Return the parity of the second particle in each particle pair */ - auto parityParticleB() const { return this->PB(); } + Column parityParticleB() const { return this->PB(); } /** * @brief Return the Q value for each particle pair */ - auto Q() const { return ParticlePairs::column( 6 ); } + Column Q() const { return ParticlePairs::column( 6 ); } /** * @brief Return the penetrability flag for each particle pair */ auto PNT() const { return ParticlePairs::column( 7 ) - | ranges::view::transform( [] ( auto pnt ) - { return int( pnt ); } ); } + | ranges::cpp20::views::transform( [] ( auto pnt ) + { return int( pnt ); } ); } /** * @brief Return the penetrability flag for each particle pair @@ -140,8 +147,8 @@ class ParticlePairs : protected ListRecord { */ auto SHF() const { return ParticlePairs::column( 8 ) - | ranges::view::transform( [] ( auto shf ) - { return int( shf ); } ); } + | ranges::cpp20::views::transform( [] ( auto shf ) + { return int( shf ); } ); } /** * @brief Return the shift factor flag for each particle pair @@ -153,8 +160,8 @@ class ParticlePairs : protected ListRecord { */ auto MT() const { return ParticlePairs::column( 9 ) - | ranges::view::transform( [] ( auto mt ) - { return int( mt ); } ); } + | ranges::cpp20::views::transform( [] ( auto mt ) + { return int( mt ); } ); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/ResonanceChannels.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/ResonanceChannels.hpp index 20062945a..49164af01 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/ResonanceChannels.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/ResonanceChannels.hpp @@ -11,15 +11,21 @@ */ class ResonanceChannels : protected ListRecord { +public: + + using Column = StrideRange< DropRange< AllRange< double > > >; + +private: + /* auxiliary functions */ #include "ENDFtk/section/2/151/RMatrixLimited/ResonanceChannels/src/generateList.hpp" #include "ENDFtk/section/2/151/RMatrixLimited/ResonanceChannels/src/verifySize.hpp" - auto column( unsigned int i ) const { + Column column( unsigned int i ) const { return ListRecord::list() - | ranges::view::drop_exactly( i ) - | ranges::view::stride( 6 ); + | ranges::views::drop_exactly( i ) + | ranges::views::stride( 6 ); } public: @@ -32,22 +38,22 @@ class ResonanceChannels : protected ListRecord { /** * @brief Return the spin J of the spin group */ - auto AJ() const { return ListRecord::C1(); } + double AJ() const { return ListRecord::C1(); } /** * @brief Return the LLN flag (either S or ln(S) is stored) */ - auto spin() const { return this->AJ(); } + double spin() const { return this->AJ(); } /** * @brief Return the parity of the spin J */ - auto PJ() const { return ListRecord::C2(); } + double PJ() const { return ListRecord::C2(); } /** * @brief Return the parity of the spin J */ - auto parity() const { return this->PJ(); } + double parity() const { return this->PJ(); } /** * @brief Return the number of channels with background R-matrix values @@ -72,21 +78,21 @@ class ResonanceChannels : protected ListRecord { /** * @brief Return the number of channels */ - auto NCH() const { return ListRecord::NPL() / 6; } + unsigned int NCH() const { return ListRecord::NPL() / 6; } /** * @brief Return the number of channels */ - long numberChannels() const { return this->NCH(); } + unsigned int numberChannels() const { return this->NCH(); } /** * @brief Return the particle pair numbers of each channel */ auto PPI() const { return ListRecord::list() - | ranges::view::stride( 6 ) - | ranges::view::transform( [] ( auto ppi ) - { return int( ppi ); } ); } + | ranges::views::stride( 6 ) + | ranges::cpp20::views::transform( [] ( auto ppi ) + { return int( ppi ); } ); } /** * @brief Return the particle pair numbers of each channel @@ -98,8 +104,8 @@ class ResonanceChannels : protected ListRecord { */ auto L() const { return ResonanceChannels::column( 1 ) - | ranges::view::transform( [] ( auto l ) - { return int( l ); } ); } + | ranges::cpp20::views::transform( [] ( auto l ) + { return int( l ); } ); } /** * @brief Return the orbital momentum values for all channels @@ -109,44 +115,46 @@ class ResonanceChannels : protected ListRecord { /** * @brief Return the channel spin values */ - auto SCH() const { return ResonanceChannels::column( 2 ); } - /** + Column SCH() const { return ResonanceChannels::column( 2 ); } + + /** * @brief Return the channel spin values */ - auto channelSpinValues() const { return this->SCH(); } + Column channelSpinValues() const { return this->SCH(); } /** * @brief Return the boundary condition values */ - auto BND() const { return ResonanceChannels::column( 3 ); } + Column BND() const { return ResonanceChannels::column( 3 ); } /** - * @brief Return the boundary condition values + * @brief Return the boundary condition values */ - auto boundaryConditionValues() const { return this->BND(); } + Column boundaryConditionValues() const { return this->BND(); } /** - * @brief Return the true channel radii (used in the calculation of the - * penetrability and shift factor) + * @brief Return the true channel radii (used in the calculation of the + * penetrability and shift factor) */ - auto APT() const { return ResonanceChannels::column( 5 ); } + Column APT() const { return ResonanceChannels::column( 5 ); } /** - * @brief Return the true channel radii (used in the calculation of the - * penetrability and shift factor) + * @brief Return the true channel radii (used in the calculation of the + * penetrability and shift factor) */ - auto trueChannelRadii() const { return this->APT(); } + Column trueChannelRadii() const { return this->APT(); } /** * @brief Return the effective channel radii (used in the calculation of the * phase shift) */ - auto APE() const { return ResonanceChannels::column( 4 ); } + Column APE() const { return ResonanceChannels::column( 4 ); } + /** * @brief Return the effective channel radii (used in the calculation of the * phase shift) */ - auto effectiveChannelRadii() const { return this->APE(); } + Column effectiveChannelRadii() const { return this->APE(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/ResonanceParameters.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/ResonanceParameters.hpp index 10f221097..5339f59a8 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/ResonanceParameters.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/ResonanceParameters.hpp @@ -42,24 +42,28 @@ class ResonanceParameters : protected ListRecord { /** * @brief Return the resonance energies */ - auto ER() const { + StrideRange< AllRange< double > > ER() const { + return ListRecord::list() - | ranges::view::stride( this->NX() / this->NRS() * 6 ); } + | ranges::views::stride( this->NX() / this->NRS() * 6 ); } /** * @brief Return the resonance energies */ - auto resonanceEnergies() const { return this->ER(); } + StrideRange< AllRange< double > > resonanceEnergies() const { + + return this->ER(); + } /** * @brief Return the resonance parameters */ auto GAM() const { return ListRecord::list() - | ranges::view::chunk( this->NX() / this->NRS() * 6 ) - | ranges::view::transform( + | ranges::views::chunk( this->NX() / this->NRS() * 6 ) + | ranges::cpp20::views::transform( [] ( auto chunk ) - { return chunk | ranges::view::drop_exactly( 1 ); } ); } + { return chunk | ranges::views::drop_exactly( 1 ); } ); } /** * @brief Return the resonance parameters diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/SammyBackgroundRMatrix/src/extract.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/SammyBackgroundRMatrix/src/extract.hpp index 7cf5172a2..d42f037be 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/SammyBackgroundRMatrix/src/extract.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/SammyBackgroundRMatrix/src/extract.hpp @@ -13,7 +13,7 @@ extract( ListRecord&& record ) { auto list = record.list(); values[0] = record.C1(); values[1] = record.C2(); - std::copy_n( ranges::begin( list ), 5, values.begin() + 2 ); + std::copy_n( ranges::cpp20::begin( list ), 5, values.begin() + 2 ); return values; } diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/SpinGroup.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/SpinGroup.hpp index 08a5cb0ac..bba7663a2 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/SpinGroup.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/SpinGroup.hpp @@ -27,22 +27,22 @@ class SpinGroup { /** * @brief Return the spin for this spin group */ - auto AJ() const { return this->channels_.AJ(); } + double AJ() const { return this->channels_.AJ(); } /** * @brief Return the spin for this spin group */ - auto spin() const { return this->AJ(); } + double spin() const { return this->AJ(); } /** * @brief Return the parity for this spin group */ - auto PJ() const { return this->channels_.PJ(); } + double PJ() const { return this->channels_.PJ(); } /** * @brief Return the parity for this spin group */ - auto parity() const { return this->PJ(); } + double parity() const { return this->PJ(); } /** * @brief Return the number of channels @@ -77,17 +77,17 @@ class SpinGroup { /** * @brief Return the channel information */ - const auto& channels() const { return this->channels_; } + const ResonanceChannels& channels() const { return this->channels_; } /** * @brief Return the resonance parameters for this spin group */ - const auto& parameters() const { return this->parameters_; } + const ResonanceParameters& parameters() const { return this->parameters_; } /** * @brief Return the background R-matrix values for the spin group channels */ - const auto& background() const { return this->background_; } + const BackgroundChannels& background() const { return this->background_; } /** * @brief Return the number of lines in this MF2 MT151 component diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix.hpp index f2f89e2ae..2238b7af8 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix.hpp @@ -36,59 +36,59 @@ class TabulatedBackgroundRMatrix : protected BaseBackgroundRMatrix< TabulatedBac /** * @brief Return the number of energy points. */ - auto NP() const { return this->real_.NP(); } + unsigned int NP() const { return this->real_.NP(); } /** * @brief Return the number of interpolation ranges */ - auto NR() const { return this->real_.NR(); } + unsigned int NR() const { return this->real_.NR(); } /** * @brief Return the interpolants */ - auto interpolants() const { return this->real_.interpolants(); } + AllRange< long > interpolants() const { return this->real_.interpolants(); } /** * @brief Return the interpolation range boundaries. */ - auto boundaries() const { return this->real_.boundaries(); } + AllRange< long > boundaries() const { return this->real_.boundaries(); } /** * @brief Return the energy values */ - auto E() const { return this->real_.x(); } + AllRange< double > E() const { return this->real_.x(); } /** * @brief Return the energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the real component of the R-matrix values */ - auto RBR() const { return this->real_.y(); } + AllRange< double > RBR() const { return this->real_.y(); } /** * @brief Return the real component of the R-matrix values */ - auto real() const { return this->RBR(); } + AllRange< double > real() const { return this->RBR(); } /** * @brief Return the imaginary component of the R-matrix values */ - auto RBI() const { return this->imaginary_.y(); } + AllRange< double > RBI() const { return this->imaginary_.y(); } /** * @brief Return the imaginary component of the R-matrix values */ - auto imaginary() const { return this->RBI(); } + AllRange< double > imaginary() const { return this->RBI(); } /** * @brief Return the complex R-matrix values */ auto RB() const { - return ranges::view::zip_with( + return ranges::views::zip_with( [] ( double real, double imag ) -> std::complex< double > { return { real, imag }; }, this->real_.y(), diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/src/extract.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/src/extract.hpp index 1769d40b8..796f28d69 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/src/extract.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/src/extract.hpp @@ -2,14 +2,18 @@ template < typename Range > static std::vector< double > extractReal( const Range& values ) { - return values | ranges::view::transform( [] ( const auto& complex ) - { return complex.real(); } ); + return ranges::to< std::vector< double > >( + values | ranges::cpp20::views::transform( + [] ( const auto& complex ) + { return complex.real(); } ) ); } template < typename Range > static std::vector< double > extractImaginary( const Range& values ) { - return values | ranges::view::transform( [] ( const auto& complex ) - { return complex.imag(); } ); + return ranges::to< std::vector< double > >( + values | ranges::cpp20::views::transform( + [] ( const auto& complex ) + { return complex.imag(); } ) ); } diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/src/verify.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/src/verify.hpp index b0b87df05..0087089ac 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/src/verify.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/TabulatedBackgroundRMatrix/src/verify.hpp @@ -1,10 +1,10 @@ template < typename Range > static bool compare( const Range& left, const Range& right ) { - return ranges::count( - ranges::view::zip_with( + return ranges::cpp20::count( + ranges::views::zip_with( [] ( double left, double right ) { return left == right; }, - left, right ), true ) == ranges::distance( left ); + left, right ), true ) == ranges::cpp20::distance( left ); } static void diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/src/AP.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/src/AP.hpp index 202976a7d..26df708c5 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/src/AP.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/src/AP.hpp @@ -9,12 +9,14 @@ double AP() const { auto mt = this->particlePairs().MT(); - unsigned int elastic = ranges::distance( ranges::begin( mt ), - ranges::find( mt, int( 2 ) ) ) + 1; + unsigned int elastic = ranges::cpp20::distance( + ranges::cpp20::begin( mt ), + ranges::cpp20::find( mt, int( 2 ) ) ) + 1; auto channels = this->spinGroups().front().channels(); auto ppi = channels.particlePairNumbers(); - unsigned int index = ranges::distance( ranges::begin( ppi ), - ranges::find( ppi, int( elastic ) ) ); + unsigned int index = ranges::cpp20::distance( + ranges::cpp20::begin( ppi ), + ranges::cpp20::find( ppi, int( elastic ) ) ); return channels.trueChannelRadii()[index]; }; diff --git a/src/ENDFtk/section/2/151/RMatrixLimited/src/SPI.hpp b/src/ENDFtk/section/2/151/RMatrixLimited/src/SPI.hpp index d8de8dcb6..191512dc5 100644 --- a/src/ENDFtk/section/2/151/RMatrixLimited/src/SPI.hpp +++ b/src/ENDFtk/section/2/151/RMatrixLimited/src/SPI.hpp @@ -4,7 +4,8 @@ double SPI() const { auto mt = this->particlePairs().MT(); - unsigned int index = ranges::distance( ranges::begin( mt ), - ranges::find( mt, int( 2 ) ) ); + unsigned int index = ranges::cpp20::distance( + ranges::cpp20::begin( mt ), + ranges::cpp20::find( mt, int( 2 ) ) ); return this->particlePairs().spinParticleB()[index]; }; diff --git a/src/ENDFtk/section/2/151/ReichMooreLValue.hpp b/src/ENDFtk/section/2/151/ReichMooreLValue.hpp index 9fd7b2e27..b98b818c6 100644 --- a/src/ENDFtk/section/2/151/ReichMooreLValue.hpp +++ b/src/ENDFtk/section/2/151/ReichMooreLValue.hpp @@ -9,6 +9,9 @@ class ReichMooreLValue : protected BreitWignerReichMooreLValueBase { public: + /* type aliases */ + using Column = BreitWignerReichMooreLValueBase::Column; + #include "ENDFtk/section/2/151/ReichMooreLValue/Resonance.hpp" /* constructor */ @@ -41,42 +44,42 @@ class ReichMooreLValue : protected BreitWignerReichMooreLValueBase { /** * @brief Return the neutron widths */ - auto GN() const { return BreitWignerReichMooreLValueBase::G1(); } + Column GN() const { return BreitWignerReichMooreLValueBase::G1(); } /** * @brief Return the neutron widths */ - auto neutronWidths() const { return this->GN(); } + Column neutronWidths() const { return this->GN(); } /** * @brief Return the gamma widths */ - auto GG() const { return BreitWignerReichMooreLValueBase::G2(); } + Column GG() const { return BreitWignerReichMooreLValueBase::G2(); } /** * @brief Return the gamma widths */ - auto gammaWidths() const { return this->GG(); } + Column gammaWidths() const { return this->GG(); } /** * @brief Return the first fission widths */ - auto GFA() const { return BreitWignerReichMooreLValueBase::G3(); } + Column GFA() const { return BreitWignerReichMooreLValueBase::G3(); } /** * @brief Return the first fission widths */ - auto firstFissionWidths() const { return this->GFA(); } + Column firstFissionWidths() const { return this->GFA(); } /** * @brief Return the second fission widths */ - auto GFB() const { return BreitWignerReichMooreLValueBase::G4(); } + Column GFB() const { return BreitWignerReichMooreLValueBase::G4(); } /** * @brief Return the second fission widths */ - auto secondFissionWidths() const { return this->GFB(); } + Column secondFissionWidths() const { return this->GFB(); } /** * @brief Return the resonances @@ -85,7 +88,7 @@ class ReichMooreLValue : protected BreitWignerReichMooreLValueBase { using Chunk = decltype( BreitWignerReichMooreLValueBase::resonances()[0] ); return BreitWignerReichMooreLValueBase::resonances() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( Chunk&& chunk ) -> Resonance< Chunk > { return { std::move( chunk ) }; } ); } diff --git a/src/ENDFtk/section/2/151/ResonanceRange.hpp b/src/ENDFtk/section/2/151/ResonanceRange.hpp index 52d1a85a2..c69aa29a4 100644 --- a/src/ENDFtk/section/2/151/ResonanceRange.hpp +++ b/src/ENDFtk/section/2/151/ResonanceRange.hpp @@ -11,6 +11,9 @@ class ResonanceRange { public: + /* type aliases */ + using OptionalScatteringRadius = std::optional< ScatteringRadius >; + using ResonanceParameters = std::variant< // LRU=0 @@ -33,7 +36,7 @@ class ResonanceRange { int naps_; ResonanceParameters parameters_; - std::optional< ScatteringRadius > scattering_radius_; + OptionalScatteringRadius scattering_radius_; /* auxiliary functions */ #include "ENDFtk/section/2/151/ResonanceRange/src/verifyOptions.hpp" @@ -48,22 +51,22 @@ class ResonanceRange { /** * @brief Return the lower energy boundary of the resonance region */ - auto EL() const { return this->el_; } + double EL() const { return this->el_; } /** * @brief Return the lower energy boundary of the resonance region */ - auto lowerEnergy() const { return this->EL(); } + double lowerEnergy() const { return this->EL(); } /** * @brief Return the upper energy boundary of the resonance region */ - auto EH() const { return this->eh_; } + double EH() const { return this->eh_; } /** * @brief Return the upper energy boundary of the resonance region */ - auto upperEnergy() const { return this->EH(); } + double upperEnergy() const { return this->EH(); } /** * @brief Return the resonance type (resolved or unresolved) @@ -124,12 +127,15 @@ class ResonanceRange { /** * @brief Return optional scattering radius */ - const auto& scatteringRadius() const { return this->scattering_radius_; } + const OptionalScatteringRadius& scatteringRadius() const { + + return this->scattering_radius_; + } /** * @brief Return the resonance parameters */ - const auto& parameters() const { return this->parameters_; } + const ResonanceParameters& parameters() const { return this->parameters_; } /** * @brief Return the number of lines in this MF2/MT151 component diff --git a/src/ENDFtk/section/2/151/ScatteringRadius.hpp b/src/ENDFtk/section/2/151/ScatteringRadius.hpp index e30357637..e71bfb70c 100644 --- a/src/ENDFtk/section/2/151/ScatteringRadius.hpp +++ b/src/ENDFtk/section/2/151/ScatteringRadius.hpp @@ -17,22 +17,22 @@ class ScatteringRadius : protected TabulationRecord { /** * @brief Return the energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the scatterin radius values */ - auto AP() const { return TabulationRecord::y(); } + AllRange< double > AP() const { return TabulationRecord::y(); } /** - * @brief Return the scattering radius values + * @brief Return the scattering radius values */ - auto radii() const { return this->AP(); } + AllRange< double > radii() const { return this->AP(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/2/151/UnresolvedBaseWithoutSpin.hpp b/src/ENDFtk/section/2/151/UnresolvedBaseWithoutSpin.hpp index 010233c60..5ddd75232 100644 --- a/src/ENDFtk/section/2/151/UnresolvedBaseWithoutSpin.hpp +++ b/src/ENDFtk/section/2/151/UnresolvedBaseWithoutSpin.hpp @@ -102,5 +102,8 @@ class UnresolvedBaseWithoutSpin { /** * @brief Return the l value data */ - auto lValues() const { return ranges::view::all( this->lvalues_ ); } + AllRange< LValue > lValues() const { + + return ranges::cpp20::views::all( this->lvalues_ ); + } }; diff --git a/src/ENDFtk/section/2/151/UnresolvedEnergyDependent/JValue.hpp b/src/ENDFtk/section/2/151/UnresolvedEnergyDependent/JValue.hpp index 2b845696d..5749f424a 100644 --- a/src/ENDFtk/section/2/151/UnresolvedEnergyDependent/JValue.hpp +++ b/src/ENDFtk/section/2/151/UnresolvedEnergyDependent/JValue.hpp @@ -8,15 +8,22 @@ */ class JValue : protected ListRecord { +public: + + using Column = StrideRange< DropRange< AllRange< double > > >; + +private: + /* auxiliary functions */ #include "ENDFtk/section/2/151/UnresolvedEnergyDependent/JValue/src/generateList.hpp" #include "ENDFtk/section/2/151/UnresolvedEnergyDependent/JValue/src/verifySize.hpp" - auto column( const int index ) const { + Column column( const int index ) const { + return ListRecord::list() - | ranges::view::drop_exactly( index + 6 ) - | ranges::view::stride(6); + | ranges::views::drop_exactly( index + 6 ) + | ranges::views::stride(6); } public: @@ -27,12 +34,12 @@ class JValue : protected ListRecord { /** * @brief Return the spin value */ - auto AJ() const { return ListRecord::C1(); } + double AJ() const { return ListRecord::C1(); } /** * @brief Return the spin value */ - auto spin() const { return this->AJ(); } + double spin() const { return this->AJ(); } /** * @brief Return the number of degrees of freedom for the neutron width. @@ -77,62 +84,62 @@ class JValue : protected ListRecord { /** * @brief Return the energy values. */ - auto ES() const { return this->column( 0 ); } + Column ES() const { return this->column( 0 ); } /** * @brief Return the energy values. */ - auto energies() const { return this->ES(); } + Column energies() const { return this->ES(); } /** * @brief Return the average level spacing. */ - auto D() const { return this->column( 1 ); } + Column D() const { return this->column( 1 ); } /** * @brief Return the average level spacing. */ - auto averageLevelSpacings() const { return this->D(); } + Column averageLevelSpacings() const { return this->D(); } /** * @brief Return the average neutron width. */ - auto GN() const { return this->column( 3 ); } + Column GN() const { return this->column( 3 ); } /** * @brief Return the average neutron width. */ - auto averageNeutronWidths() const { return this->GN(); } + Column averageNeutronWidths() const { return this->GN(); } /** * @brief Return the average gamma width. */ - auto GG() const { return this->column( 4 ); } + Column GG() const { return this->column( 4 ); } /** * @brief Return the average gamma width. */ - auto averageGammaWidths() const { return this->GG(); } + Column averageGammaWidths() const { return this->GG(); } /** * @brief Return the average fission widths (energy dependent). */ - auto GF() const { return this->column( 5 ); } + Column GF() const { return this->column( 5 ); } /** * @brief Return the average fission widths (energy dependent). */ - auto averageFissionWidths() const { return JValue::GF(); } + Column averageFissionWidths() const { return JValue::GF(); } /** * @brief Return the average competitive width. */ - auto GX() const { return this->column( 2 ); } + Column GX() const { return this->column( 2 ); } /** * @brief Return the average competitive width. */ - auto averageCompetitiveWidths() const { return JValue::GX(); } + Column averageCompetitiveWidths() const { return JValue::GX(); } /** * @brief Return the interpolation type. diff --git a/src/ENDFtk/section/2/151/UnresolvedEnergyDependentFissionWidths.hpp b/src/ENDFtk/section/2/151/UnresolvedEnergyDependentFissionWidths.hpp index 63d7ea53e..8941b5925 100644 --- a/src/ENDFtk/section/2/151/UnresolvedEnergyDependentFissionWidths.hpp +++ b/src/ENDFtk/section/2/151/UnresolvedEnergyDependentFissionWidths.hpp @@ -81,12 +81,12 @@ class UnresolvedEnergyDependentFissionWidths : /** * @brief Return the energy values for which fission widths are given */ - auto ES() const { return this->energies_.list(); } + AllRange< double > ES() const { return this->energies_.list(); } /** * @brief Return the energy values for which fission widths are given */ - auto energies() const { return this->ES(); } + AllRange< double > energies() const { return this->ES(); } using UnresolvedBaseWithoutSpin::spin; using UnresolvedBaseWithoutSpin::scatteringRadius; diff --git a/src/ENDFtk/section/2/151/UnresolvedEnergyDependentFissionWidths/JValue.hpp b/src/ENDFtk/section/2/151/UnresolvedEnergyDependentFissionWidths/JValue.hpp index 599c4015c..1f79a4efa 100644 --- a/src/ENDFtk/section/2/151/UnresolvedEnergyDependentFissionWidths/JValue.hpp +++ b/src/ENDFtk/section/2/151/UnresolvedEnergyDependentFissionWidths/JValue.hpp @@ -32,17 +32,17 @@ class JValue : protected ListRecord { /** * @brief Return the spin value */ - auto AJ() const { return ListRecord::list()[1]; } + double AJ() const { return ListRecord::list()[1]; } /** * @brief Return the spin value */ - auto spin() const { return this->AJ(); } + double spin() const { return this->AJ(); } /** * @brief Return the number of degrees of freedom for the neutron width. */ - int AMUN() const { return static_cast( ListRecord::list()[2] ); } + double AMUN() const { return static_cast( ListRecord::list()[2] ); } /** * @brief Return the number of degrees of freedom for the neutron width. @@ -125,15 +125,18 @@ class JValue : protected ListRecord { /** * @brief Return the average fission widths (energy dependent). */ - auto GF() const { + DropRange< AllRange< double > > GF() const { - return ListRecord::list() | ranges::view::drop_exactly( 6 ); + return ListRecord::list() | ranges::views::drop_exactly( 6 ); } /** * @brief Return the average fission widths (energy dependent). */ - auto averageFissionWidths() const { return JValue::GF(); } + DropRange< AllRange< double > > averageFissionWidths() const { + + return JValue::GF(); + } /** * @brief Return the number of average fission width points. diff --git a/src/ENDFtk/section/2/151/UnresolvedEnergyIndependent/JValue.hpp b/src/ENDFtk/section/2/151/UnresolvedEnergyIndependent/JValue.hpp index 3cdf626e9..0cc354568 100644 --- a/src/ENDFtk/section/2/151/UnresolvedEnergyIndependent/JValue.hpp +++ b/src/ENDFtk/section/2/151/UnresolvedEnergyIndependent/JValue.hpp @@ -24,12 +24,12 @@ class JValue { /** * @brief Return the spin value */ - auto AJ() const { return this->chunk[1]; } + double AJ() const { return this->chunk[1]; } /** * @brief Return the spin value */ - auto spin() const { return this->AJ(); } + double spin() const { return this->AJ(); } /** * @brief Return the average level spacing. diff --git a/src/ENDFtk/section/2/151/UnresolvedEnergyIndependent/LValue.hpp b/src/ENDFtk/section/2/151/UnresolvedEnergyIndependent/LValue.hpp index 7305fc812..515a51cd3 100644 --- a/src/ENDFtk/section/2/151/UnresolvedEnergyIndependent/LValue.hpp +++ b/src/ENDFtk/section/2/151/UnresolvedEnergyIndependent/LValue.hpp @@ -53,9 +53,9 @@ class LValue : protected ListRecord { */ auto jValues() const { - auto chunked = ListRecord::list() | ranges::view::chunk( 6 ); + auto chunked = ListRecord::list() | ranges::views::chunk( 6 ); using Range = decltype( chunked[0] ); - return chunked | ranges::view::transform( + return chunked | ranges::cpp20::views::transform( [] ( Range&& chunk ) -> JValue< Range > { return { std::move( chunk ) }; } ); } @@ -66,8 +66,8 @@ class LValue : protected ListRecord { auto D() const { return this->jValues() - | ranges::view::transform( [] ( const auto& jvalue ) - { return jvalue.D(); } ); + | ranges::cpp20::views::transform( [] ( const auto& jvalue ) + { return jvalue.D(); } ); } /** @@ -81,8 +81,8 @@ class LValue : protected ListRecord { auto AJ() const { return this->jValues() - | ranges::view::transform( [] ( const auto& jvalue ) - { return jvalue.AJ(); } ); + | ranges::cpp20::views::transform( [] ( const auto& jvalue ) + { return jvalue.AJ(); } ); } /** @@ -96,8 +96,8 @@ class LValue : protected ListRecord { auto AMUN() const { return this->jValues() - | ranges::view::transform( [] ( const auto& jvalue ) - { return jvalue.AMUN(); } ); + | ranges::cpp20::views::transform( [] ( const auto& jvalue ) + { return jvalue.AMUN(); } ); } /** @@ -108,7 +108,7 @@ class LValue : protected ListRecord { /** * @brief Return the degrees of freedom for the gamma width */ - auto AMUG() const { return ranges::view::repeat_n( 0.0, this->NJS() ); } + auto AMUG() const { return ranges::views::repeat_n( 0.0, this->NJS() ); } /** * @brief Return the degrees of freedom for the gamma width @@ -118,7 +118,7 @@ class LValue : protected ListRecord { /** * @brief Return the degrees of freedom for the fission width */ - auto AMUF() const { return ranges::view::repeat_n( 0.0, this->NJS() ); } + auto AMUF() const { return ranges::views::repeat_n( 0.0, this->NJS() ); } /** * @brief Return the degrees of freedom for the fission width @@ -128,7 +128,7 @@ class LValue : protected ListRecord { /** * @brief Return the degrees of freedom for the competitive width */ - auto AMUX() const { return ranges::view::repeat_n( 0.0, this->NJS() ); } + auto AMUX() const { return ranges::views::repeat_n( 0.0, this->NJS() ); } /** * @brief Return the degrees of freedom for the competitive width @@ -141,8 +141,8 @@ class LValue : protected ListRecord { auto GN() const { return this->jValues() - | ranges::view::transform( [] ( const auto& jvalue ) - { return jvalue.GN(); } ); + | ranges::cpp20::views::transform( [] ( const auto& jvalue ) + { return jvalue.GN(); } ); } /** @@ -156,8 +156,8 @@ class LValue : protected ListRecord { auto GG() const { return this->jValues() - | ranges::view::transform( [] ( const auto& jvalue ) - { return jvalue.GG(); } ); + | ranges::cpp20::views::transform( [] ( const auto& jvalue ) + { return jvalue.GG(); } ); } /** @@ -168,7 +168,7 @@ class LValue : protected ListRecord { /** * @brief Return the average fission width values. */ - auto GF() const { return ranges::view::repeat_n( 0.0, this->NJS() ); } + auto GF() const { return ranges::views::repeat_n( 0.0, this->NJS() ); } /** * @brief Return the average fission width values. @@ -178,7 +178,7 @@ class LValue : protected ListRecord { /** * @brief Return the average competitive width values. */ - auto GX() const { return ranges::view::repeat_n( 0.0, this->NJS() ); } + auto GX() const { return ranges::views::repeat_n( 0.0, this->NJS() ); } /** * @brief Return the average competitive width values. diff --git a/src/ENDFtk/section/2/151/UnresolvedLValueBase.hpp b/src/ENDFtk/section/2/151/UnresolvedLValueBase.hpp index 872fa84cc..00658116f 100644 --- a/src/ENDFtk/section/2/151/UnresolvedLValueBase.hpp +++ b/src/ENDFtk/section/2/151/UnresolvedLValueBase.hpp @@ -55,7 +55,10 @@ template < typename JValue > class UnresolvedLValueBase { /** * @brief Return the data for each of the J values */ - auto jValues() const { return ranges::view::all( this->jvalues_ ); } + AllRange< JValue > jValues() const { + + return ranges::cpp20::views::all( this->jvalues_ ); + } /** * @brief Return the number of fission width values diff --git a/src/ENDFtk/section/2/152.hpp b/src/ENDFtk/section/2/152.hpp index 9bc465008..a916ebb7c 100644 --- a/src/ENDFtk/section/2/152.hpp +++ b/src/ENDFtk/section/2/152.hpp @@ -67,12 +67,12 @@ namespace section { /** * @brief Return the temperature */ - auto TEMZ() const { return this->data_.C1(); } + double TEMZ() const { return this->data_.C1(); } /** * @brief Return the temperature */ - auto temperature() const { return this->TEMZ(); } + double temperature() const { return this->TEMZ(); } /** * @brief Return the number of data values @@ -87,7 +87,7 @@ namespace section { /** * @brief Return the number of reactions (normally 5) */ - auto numberReactions() const { return this->NREAC(); } + int numberReactions() const { return this->NREAC(); } /** * @brief Return the number of dilution or sigma zero values @@ -97,21 +97,21 @@ namespace section { /** * @brief Return the number of dilution or sigma zero values */ - auto numberDilutions() const { return this->NSIGZ(); } + int numberDilutions() const { return this->NSIGZ(); } /** * @brief Return the dilution or sigma zero values */ - auto SIGZ() const { + TakeRange< AllRange< double > > SIGZ() const { return this->data_.list() - | ranges::view::take_exactly( this->NSIGZ() ); + | ranges::views::take_exactly( this->NSIGZ() ); } /** * @brief Return the dilution or sigma zero values */ - auto dilutions() const { return this->SIGZ(); } + TakeRange< AllRange< double > > dilutions() const { return this->SIGZ(); } /** * @brief Return the number of energy values @@ -121,22 +121,25 @@ namespace section { /** * @brief Return the number of energy values */ - auto numberEnergies() const { return this->NUNR(); } + int numberEnergies() const { return this->NUNR(); } /** * @brief Return the unresolved resonance energies */ - auto EUNR() const { + StrideRange< DropRange< AllRange< double > > > EUNR() const { return this->data_.list() - | ranges::view::drop_exactly( this->NSIGZ() ) - | ranges::view::stride( 1 + this->NSIGZ() * 5 ); + | ranges::views::drop_exactly( this->NSIGZ() ) + | ranges::views::stride( 1 + this->NSIGZ() * 5 ); } /** * @brief Return the unresolved resonance energies */ - auto energies() const { return this->EUNR(); } + StrideRange< DropRange< AllRange< double > > > energies() const { + + return this->EUNR(); + } /** * @brief Return the total cross section values for each energy and dilution diff --git a/src/ENDFtk/section/2/152/src/reaction.hpp b/src/ENDFtk/section/2/152/src/reaction.hpp index 4873b194b..14c4eecb3 100644 --- a/src/ENDFtk/section/2/152/src/reaction.hpp +++ b/src/ENDFtk/section/2/152/src/reaction.hpp @@ -3,13 +3,14 @@ auto reaction( unsigned int i ) const { unsigned int nreac = this->data_.L1(); unsigned int nsigz = this->data_.L2(); auto chunks = this->data_.list() - | ranges::view::drop_exactly( nsigz ) - | ranges::view::chunk( 1 + nsigz * nreac ) - | ranges::view::transform( + | ranges::views::drop_exactly( nsigz ) + | ranges::views::chunk( 1 + nsigz * nreac ) + | ranges::cpp20::views::transform( [=] ( const auto& chunk ) - { return chunk | ranges::view::drop_exactly( 1 ) - | ranges::view::chunk( nsigz ); } ); + { return chunk | ranges::views::drop_exactly( 1 ) + | ranges::views::chunk( nsigz ); } ); - return chunks | ranges::view::transform( [=] ( const auto& reactions ) - { return reactions[i]; } ); + return chunks | ranges::cpp20::views::transform( + [=] ( const auto& reactions ) + { return reactions[i]; } ); } diff --git a/src/ENDFtk/section/3.hpp b/src/ENDFtk/section/3.hpp index 591cd15ef..11d8b0b19 100755 --- a/src/ENDFtk/section/3.hpp +++ b/src/ENDFtk/section/3.hpp @@ -74,22 +74,22 @@ namespace section{ /** * @brief Return the interpolation type for each range */ - auto interpolants() const { return this->table.interpolants(); } + AllRange< long > interpolants() const { return this->table.interpolants(); } /** * @brief Return the interpolation boundaries */ - auto boundaries() const { return this->table.boundaries(); } + AllRange< long > boundaries() const { return this->table.boundaries(); } /** * @brief Return the energy values */ - auto energies() const { return this->table.x(); } + AllRange< double > energies() const { return this->table.x(); } /** * @brief Return the cross section values */ - auto crossSections() const { return this->table.y(); } + AllRange< double > crossSections() const { return this->table.y(); } /** * @brief Return the number of lines in this MF3 section @@ -100,13 +100,13 @@ namespace section{ * @brief Return the energy values (common interface for interpolation * tables) */ - auto x() const { return this->energies(); } + AllRange< double > x() const { return this->energies(); } /** * @brief Return the cross section values (common interface for interpolation * tables) */ - auto y() const { return this->crossSections(); } + AllRange< double > y() const { return this->crossSections(); } /** * @brief Return the interpolation ragions (common interface for diff --git a/src/ENDFtk/section/4.hpp b/src/ENDFtk/section/4.hpp index fd003e630..416ff64e1 100644 --- a/src/ENDFtk/section/4.hpp +++ b/src/ENDFtk/section/4.hpp @@ -120,12 +120,12 @@ namespace section{ /** * @brief Return the partial distributions defined in this section */ - const auto& distributions() const { return this->distributions_; } + const Distributions& distributions() const { return this->distributions_; } /** * @brief Return the number of interpolation regions */ - auto NR() const { + long NR() const { return std::visit( utility::overload{ @@ -162,7 +162,7 @@ namespace section{ return std::visit( utility::overload{ [] ( const Isotropic& ) -> LongRange - { return ranges::view::empty< long >(); }, + { return ranges::cpp20::views::empty< long >; }, [] ( const auto& distributions ) -> LongRange { return distributions.boundaries(); } }, this->distributions_ ); @@ -176,7 +176,7 @@ namespace section{ return std::visit( utility::overload{ [] ( const Isotropic& ) -> LongRange - { return ranges::view::empty< long >(); }, + { return ranges::cpp20::views::empty< long >; }, [] ( const auto& distributions ) -> LongRange { return distributions.interpolants(); } }, this->distributions_ ); @@ -190,7 +190,7 @@ namespace section{ return std::visit( utility::overload{ [] ( const Isotropic& ) -> DoubleRange - { return ranges::view::empty< double >(); }, + { return ranges::cpp20::views::empty< double >; }, [] ( const auto& distributions ) -> DoubleRange { return distributions.incidentEnergies(); } }, this->distributions_ ); diff --git a/src/ENDFtk/section/4/AngularDistributions.hpp b/src/ENDFtk/section/4/AngularDistributions.hpp index 9bd26536e..eeec32e4d 100644 --- a/src/ENDFtk/section/4/AngularDistributions.hpp +++ b/src/ENDFtk/section/4/AngularDistributions.hpp @@ -15,6 +15,22 @@ class AngularDistributions : /* get methods */ + /** + * @brief Return the C1 value on the TAB2 record + */ + long C1() const { + + return InterpolationSequenceRecord< Records >::tab2().C1(); + } + + /** + * @brief Return the C2 value on the TAB2 record + */ + long C2() const { + + return InterpolationSequenceRecord< Records >::tab2().C2(); + } + /** * @brief Return the number interpolation regions for the incident energies */ @@ -35,7 +51,7 @@ class AngularDistributions : /** * @brief Return the interpolants for the incident energy axis */ - auto interpolants() const { + AllRange< long > interpolants() const { return InterpolationSequenceRecord< Records >::tab2().interpolants(); } @@ -44,7 +60,7 @@ class AngularDistributions : * @brief Return the interpolation region boundaries for the incident * energy axis */ - auto boundaries() const { + AllRange< long > boundaries() const { return InterpolationSequenceRecord< Records >::tab2().boundaries(); } @@ -55,7 +71,7 @@ class AngularDistributions : auto incidentEnergies() const { return InterpolationSequenceRecord< Records >::records() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( const auto& record ) { return record.incidentEnergy(); } ); } @@ -63,7 +79,7 @@ class AngularDistributions : /** * @brief Return the angular distributions (one for each incident energy) */ - auto angularDistributions() const { + AllRange< Records > angularDistributions() const { return InterpolationSequenceRecord< Records >::records(); } diff --git a/src/ENDFtk/section/4/AngularDistributions/src/ctor.hpp b/src/ENDFtk/section/4/AngularDistributions/src/ctor.hpp index 3f531529d..f42a583e2 100644 --- a/src/ENDFtk/section/4/AngularDistributions/src/ctor.hpp +++ b/src/ENDFtk/section/4/AngularDistributions/src/ctor.hpp @@ -1,15 +1,26 @@ +//! @todo pybind11 variant needs default constructor workaround +#ifdef PYBIND11 +/** + * @brief Default constructor - only enabled for pybind11 + */ +AngularDistributions() = default; +#endif + /** * @brief Constructor * * @param[in] boundaries the interpolation range boundaries * @param[in] interpolants the interpolation types for each range * @param[in] distributions the sequence of angular distributions + * @param[in] C1 the C1 value (default 0.0) + * @param[in] C2 the C2 value (default 0.0) */ AngularDistributions( std::vector< long >&& boundaries, std::vector< long >&& interpolants, - std::vector< Records >&& distributions ) : + std::vector< Records >&& distributions, + double C1 = 0.0, double C2 = 0.0 ) : InterpolationSequenceRecord< Records >( - InterpolationRecord( 0.0, 0.0, 0, 0, + InterpolationRecord( C1, C2, 0, 0, std::move( interpolants ), std::move( boundaries ) ), std::move( distributions ) ) {} diff --git a/src/ENDFtk/section/4/Isotropic.hpp b/src/ENDFtk/section/4/Isotropic.hpp index 6d4521a9d..58148af46 100644 --- a/src/ENDFtk/section/4/Isotropic.hpp +++ b/src/ENDFtk/section/4/Isotropic.hpp @@ -15,6 +15,16 @@ class Isotropic { public: + /** + * @brief Return the isotropic angular distribution flag + */ + static constexpr bool LI() { return true; } + + /** + * @brief Return the isotropic angular distribution flag + */ + bool isotropicAngularDistributions() const { return this->LI(); } + /** * @brief Return the angular distribution law */ diff --git a/src/ENDFtk/section/4/Isotropic/test/Isotropic.test.cpp b/src/ENDFtk/section/4/Isotropic/test/Isotropic.test.cpp index 4de925ed4..8bc911b57 100644 --- a/src/ENDFtk/section/4/Isotropic/test/Isotropic.test.cpp +++ b/src/ENDFtk/section/4/Isotropic/test/Isotropic.test.cpp @@ -18,6 +18,8 @@ SCENARIO( "Isotropic" ) { Isotropic chunk; + CHECK( true == chunk.LI() ); + CHECK( true == chunk.isotropicAngularDistributions() ); CHECK( 0 == chunk.LTT() ); CHECK( 0 == chunk.LAW() ); diff --git a/src/ENDFtk/section/4/LegendreCoefficients.hpp b/src/ENDFtk/section/4/LegendreCoefficients.hpp index c1aeacc30..6c6228296 100644 --- a/src/ENDFtk/section/4/LegendreCoefficients.hpp +++ b/src/ENDFtk/section/4/LegendreCoefficients.hpp @@ -47,13 +47,13 @@ class LegendreCoefficients : protected ListRecord { * @brief Return the Legendre coefficients in the distribution (a0 is not * present and assumed to be equal to 1) */ - auto A() const { return ListRecord::list(); } + AllRange< double > A() const { return ListRecord::list(); } /** * @brief Return the Legendre coefficients in the distribution (a0 is not * present and assumed to be equal to 1) */ - auto coefficients() const { return this->A(); } + AllRange< double > coefficients() const { return this->A(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/4/LegendreDistributions.hpp b/src/ENDFtk/section/4/LegendreDistributions.hpp index cb60fed1a..3734b5544 100644 --- a/src/ENDFtk/section/4/LegendreDistributions.hpp +++ b/src/ENDFtk/section/4/LegendreDistributions.hpp @@ -19,6 +19,16 @@ class LegendreDistributions : /* get methods */ + /** + * @brief Return the isotropic angular distribution flag + */ + static constexpr bool LI() { return false; } + + /** + * @brief Return the isotropic angular distribution flag + */ + bool isotropicAngularDistributions() const { return this->LI(); } + /** * @brief Return the distribution law */ diff --git a/src/ENDFtk/section/4/LegendreDistributions/test/LegendreDistributions.test.cpp b/src/ENDFtk/section/4/LegendreDistributions/test/LegendreDistributions.test.cpp index c90ec22ac..2e2b6aa32 100644 --- a/src/ENDFtk/section/4/LegendreDistributions/test/LegendreDistributions.test.cpp +++ b/src/ENDFtk/section/4/LegendreDistributions/test/LegendreDistributions.test.cpp @@ -152,6 +152,8 @@ std::string chunk() { void verifyChunk( const LegendreDistributions& chunk ) { + CHECK( false == chunk.LI() ); + CHECK( false == chunk.isotropicAngularDistributions() ); CHECK( 1 == chunk.LTT() ); CHECK( 1 == chunk.LAW() ); diff --git a/src/ENDFtk/section/4/MixedDistributions.hpp b/src/ENDFtk/section/4/MixedDistributions.hpp index f9d4081a0..d8af26857 100644 --- a/src/ENDFtk/section/4/MixedDistributions.hpp +++ b/src/ENDFtk/section/4/MixedDistributions.hpp @@ -25,6 +25,16 @@ class MixedDistributions { /* get methods */ + /** + * @brief Return the isotropic angular distribution flag + */ + static constexpr bool LI() { return false; } + + /** + * @brief Return the isotropic angular distribution flag + */ + bool isotropicAngularDistributions() const { return this->LI(); } + /** * @brief Return the angular distribution law */ @@ -38,17 +48,17 @@ class MixedDistributions { /** * @brief Return the Legendre distributions */ - const auto& legendre() const { return this->legendre_; } + const LegendreDistributions& legendre() const { return this->legendre_; } /** * @brief Return the tabulated distributions */ - const auto& tabulated() const { return this->tabulated_; } + const TabulatedDistributions& tabulated() const { return this->tabulated_; } /** * @brief Return the number of interpolation regions */ - auto NR() const { + long NR() const { return this->legendre().NR() + this->tabulated().NR(); } @@ -57,7 +67,7 @@ class MixedDistributions { * @brief Return the number of energy points for which angular distributions * are available. */ - auto NE() const { + long NE() const { return this->legendre().NE() + this->tabulated().NE(); } @@ -71,11 +81,12 @@ class MixedDistributions { auto boundaries() const { auto offset = this->legendre().boundaries().back(); - return ranges::view::concat( + return ranges::views::concat( this->legendre().boundaries(), this->tabulated().boundaries() - | ranges::view::transform( [=] ( auto index ) - { return index + offset; } ) ); + | ranges::cpp20::views::transform( + [=] ( auto index ) + { return index + offset; } ) ); } /** @@ -83,8 +94,8 @@ class MixedDistributions { */ auto interpolants() const { - return ranges::view::concat( this->legendre().interpolants(), - this->tabulated().interpolants() ); + return ranges::views::concat( this->legendre().interpolants(), + this->tabulated().interpolants() ); } /** @@ -92,8 +103,8 @@ class MixedDistributions { */ auto incidentEnergies() const { - return ranges::view::concat( this->legendre().incidentEnergies(), - this->tabulated().incidentEnergies() ); + return ranges::views::concat( this->legendre().incidentEnergies(), + this->tabulated().incidentEnergies() ); } #include "ENDFtk/section/4/MixedDistributions/src/angularDistributions.hpp" diff --git a/src/ENDFtk/section/4/MixedDistributions/src/angularDistributions.hpp b/src/ENDFtk/section/4/MixedDistributions/src/angularDistributions.hpp index 6b1a1663c..923d1060c 100644 --- a/src/ENDFtk/section/4/MixedDistributions/src/angularDistributions.hpp +++ b/src/ENDFtk/section/4/MixedDistributions/src/angularDistributions.hpp @@ -7,11 +7,11 @@ */ auto angularDistributions() const { - auto lift = ranges::view::transform( []( const auto& element ) -> Variant { + auto lift = ranges::cpp20::views::transform( []( const auto& element ) -> Variant { return std::cref( element ); } ); - return ranges::view::concat( this->legendre().angularDistributions() | lift, - this->tabulated().angularDistributions() | lift ); + return ranges::views::concat( this->legendre().angularDistributions() | lift, + this->tabulated().angularDistributions() | lift ); } diff --git a/src/ENDFtk/section/4/TabulatedDistribution.hpp b/src/ENDFtk/section/4/TabulatedDistribution.hpp index 83eaf1851..e57285e2a 100644 --- a/src/ENDFtk/section/4/TabulatedDistribution.hpp +++ b/src/ENDFtk/section/4/TabulatedDistribution.hpp @@ -34,22 +34,22 @@ class TabulatedDistribution : protected TabulationRecord { /** * @brief Return the cosine values */ - auto MU() const { return TabulationRecord::x(); } + AllRange< double > MU() const { return TabulationRecord::x(); } /** * @brief Return the cosine values */ - auto cosines() const { return this->MU(); } + AllRange< double > cosines() const { return this->MU(); } /** * @brief Return the distribution probabilities */ - auto F() const { return TabulationRecord::y(); } + AllRange< double > F() const { return TabulationRecord::y(); } /** * @brief Return the distribution probabilities */ - auto probabilities() const { return this->F(); } + AllRange< double > probabilities() const { return this->F(); } using TabulationRecord::NR; using TabulationRecord::NP; diff --git a/src/ENDFtk/section/4/TabulatedDistributions.hpp b/src/ENDFtk/section/4/TabulatedDistributions.hpp index 6df309912..f112837d3 100644 --- a/src/ENDFtk/section/4/TabulatedDistributions.hpp +++ b/src/ENDFtk/section/4/TabulatedDistributions.hpp @@ -19,6 +19,16 @@ class TabulatedDistributions : /* get methods */ + /** + * @brief Return the isotropic angular distribution flag + */ + static constexpr bool LI() { return false; } + + /** + * @brief Return the isotropic angular distribution flag + */ + bool isotropicAngularDistributions() const { return this->LI(); } + /** * @brief Return the distribution law */ diff --git a/src/ENDFtk/section/4/TabulatedDistributions/test/TabulatedDistributions.test.cpp b/src/ENDFtk/section/4/TabulatedDistributions/test/TabulatedDistributions.test.cpp index e7229c02f..7f7bed0cc 100644 --- a/src/ENDFtk/section/4/TabulatedDistributions/test/TabulatedDistributions.test.cpp +++ b/src/ENDFtk/section/4/TabulatedDistributions/test/TabulatedDistributions.test.cpp @@ -154,6 +154,8 @@ std::string chunk() { void verifyChunk( const TabulatedDistributions& chunk ) { + CHECK( false == chunk.LI() ); + CHECK( false == chunk.isotropicAngularDistributions() ); CHECK( 2 == chunk.LTT() ); CHECK( 2 == chunk.LAW() ); diff --git a/src/ENDFtk/section/4/src/angularDistributions.hpp b/src/ENDFtk/section/4/src/angularDistributions.hpp index 78a5ea38b..7813e6b8e 100644 --- a/src/ENDFtk/section/4/src/angularDistributions.hpp +++ b/src/ENDFtk/section/4/src/angularDistributions.hpp @@ -7,7 +7,7 @@ */ auto angularDistributions() const { - auto lift = ranges::view::transform( []( const auto& element ) -> Variant { + auto lift = ranges::cpp20::views::transform( []( const auto& element ) -> Variant { return std::cref( element ); } ); @@ -15,7 +15,7 @@ auto angularDistributions() const { return std::visit( utility::overload{ [] ( const Isotropic& ) -> VariantRange - { return ranges::view::empty< Variant >(); }, + { return ranges::cpp20::views::empty; }, [] ( const MixedDistributions& distributions ) -> VariantRange { return distributions.angularDistributions(); }, [&] ( const auto& distributions ) -> VariantRange diff --git a/src/ENDFtk/section/4/test/4.test.cpp b/src/ENDFtk/section/4/test/4.test.cpp index ca2fca272..276b1446b 100644 --- a/src/ENDFtk/section/4/test/4.test.cpp +++ b/src/ENDFtk/section/4/test/4.test.cpp @@ -329,10 +329,10 @@ void verifyChunkWithLTT0( const section::Type< 4 >& chunk ) { CHECK( 0 == chunk.NE() ); CHECK( 0 == chunk.NR() ); - CHECK( 0 == ranges::distance( chunk.boundaries() ) ); - CHECK( 0 == ranges::distance( chunk.interpolants() ) ); - CHECK( 0 == ranges::distance( chunk.incidentEnergies() ) ); - CHECK( 0 == ranges::distance( chunk.angularDistributions() ) ); + CHECK( 0 == ranges::cpp20::distance( chunk.boundaries() ) ); + CHECK( 0 == ranges::cpp20::distance( chunk.interpolants() ) ); + CHECK( 0 == ranges::cpp20::distance( chunk.incidentEnergies() ) ); + CHECK( 0 == ranges::cpp20::distance( chunk.angularDistributions() ) ); const auto& distribution = std::get< Isotropic >( chunk.distributions() ); CHECK( 0 == distribution.LTT() ); @@ -371,10 +371,10 @@ void verifyChunkWithLTT1( const section::Type< 4 >& chunk ) { CHECK( 2 == chunk.NE() ); CHECK( 1 == chunk.NR() ); - CHECK( 1 == ranges::distance( chunk.boundaries() ) ); - CHECK( 1 == ranges::distance( chunk.interpolants() ) ); - CHECK( 2 == ranges::distance( chunk.incidentEnergies() ) ); - CHECK( 2 == ranges::distance( chunk.angularDistributions() ) ); + CHECK( 1 == ranges::cpp20::distance( chunk.boundaries() ) ); + CHECK( 1 == ranges::cpp20::distance( chunk.interpolants() ) ); + CHECK( 2 == ranges::cpp20::distance( chunk.incidentEnergies() ) ); + CHECK( 2 == ranges::cpp20::distance( chunk.angularDistributions() ) ); CHECK( 1 == chunk.interpolants()[0] ); CHECK( 2 == chunk.boundaries()[0] ); @@ -461,10 +461,10 @@ void verifyChunkWithLTT2( const section::Type< 4 >& chunk ) { CHECK( 2 == chunk.NE() ); CHECK( 1 == chunk.NR() ); - CHECK( 1 == ranges::distance( chunk.boundaries() ) ); - CHECK( 1 == ranges::distance( chunk.interpolants() ) ); - CHECK( 2 == ranges::distance( chunk.incidentEnergies() ) ); - CHECK( 2 == ranges::distance( chunk.angularDistributions() ) ); + CHECK( 1 == ranges::cpp20::distance( chunk.boundaries() ) ); + CHECK( 1 == ranges::cpp20::distance( chunk.interpolants() ) ); + CHECK( 2 == ranges::cpp20::distance( chunk.incidentEnergies() ) ); + CHECK( 2 == ranges::cpp20::distance( chunk.angularDistributions() ) ); CHECK( 1 == chunk.interpolants()[0] ); CHECK( 2 == chunk.boundaries()[0] ); @@ -572,10 +572,10 @@ void verifyChunkWithLTT3( const section::Type< 4 >& chunk ) { CHECK( 4 == chunk.NE() ); CHECK( 2 == chunk.NR() ); - CHECK( 2 == ranges::distance( chunk.boundaries() ) ); - CHECK( 2 == ranges::distance( chunk.interpolants() ) ); - CHECK( 4 == ranges::distance( chunk.incidentEnergies() ) ); - CHECK( 4 == ranges::distance( chunk.angularDistributions() ) ); + CHECK( 2 == ranges::cpp20::distance( chunk.boundaries() ) ); + CHECK( 2 == ranges::cpp20::distance( chunk.interpolants() ) ); + CHECK( 4 == ranges::cpp20::distance( chunk.incidentEnergies() ) ); + CHECK( 4 == ranges::cpp20::distance( chunk.angularDistributions() ) ); CHECK( 1 == chunk.interpolants()[0] ); CHECK( 5 == chunk.interpolants()[1] ); diff --git a/src/ENDFtk/section/5.hpp b/src/ENDFtk/section/5.hpp index e66d884d5..e08c75af3 100644 --- a/src/ENDFtk/section/5.hpp +++ b/src/ENDFtk/section/5.hpp @@ -82,9 +82,9 @@ class Type< 5 > : protected Base { /** * @brief Return the partial distributions defined in this section */ - auto partialDistributions() const { + AllRange< PartialDistribution > partialDistributions() const { - return ranges::view::all( this->partials_ ); + return ranges::cpp20::views::all( this->partials_ ); } #include "ENDFtk/section/5/src/NC.hpp" diff --git a/src/ENDFtk/section/5/DistributionFunction.hpp b/src/ENDFtk/section/5/DistributionFunction.hpp index 1631baec1..eade2b2be 100644 --- a/src/ENDFtk/section/5/DistributionFunction.hpp +++ b/src/ENDFtk/section/5/DistributionFunction.hpp @@ -17,12 +17,12 @@ class DistributionFunction : protected TabulationRecord { /** * @brief Return the x values */ - auto X() const { return TabulationRecord::x(); } + AllRange< double > X() const { return TabulationRecord::x(); } /** * @brief Return the function values */ - auto G() const { return TabulationRecord::y(); } + AllRange< double > G() const { return TabulationRecord::y(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/5/EffectiveTemperature.hpp b/src/ENDFtk/section/5/EffectiveTemperature.hpp index 34bf99ab5..afc5b1098 100644 --- a/src/ENDFtk/section/5/EffectiveTemperature.hpp +++ b/src/ENDFtk/section/5/EffectiveTemperature.hpp @@ -19,17 +19,17 @@ class EffectiveTemperature : protected TabulationRecord { /** * @brief Return the energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the effective temperature values */ - auto thetas() const { return TabulationRecord::y(); } + AllRange< double > thetas() const { return TabulationRecord::y(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/5/GeneralEvaporationSpectrum.hpp b/src/ENDFtk/section/5/GeneralEvaporationSpectrum.hpp index 0715a941a..841b958f9 100644 --- a/src/ENDFtk/section/5/GeneralEvaporationSpectrum.hpp +++ b/src/ENDFtk/section/5/GeneralEvaporationSpectrum.hpp @@ -29,22 +29,25 @@ class GeneralEvaporationSpectrum { /** * @brief Return the effective temperature */ - const auto& theta() const { return this->temperature_; } + const EffectiveTemperature& theta() const { return this->temperature_; } /** * @brief Return the effective temperature */ - const auto& effectiveTemperature() const { return this->theta(); } + const EffectiveTemperature& effectiveTemperature() const { + + return this->theta(); + } /** * @brief Return the distribution function g(x) */ - const auto& g() const { return this->distribution_; } + const DistributionFunction& g() const { return this->distribution_; } /** * @brief Return the distribution function g(x) */ - const auto& distributionFunction() const { return this->g(); } + const DistributionFunction& distributionFunction() const { return this->g(); } #include "ENDFtk/section/5/GeneralEvaporationSpectrum/src/NC.hpp" #include "ENDFtk/section/5/GeneralEvaporationSpectrum/src/print.hpp" diff --git a/src/ENDFtk/section/5/MadlandNixSpectrum.hpp b/src/ENDFtk/section/5/MadlandNixSpectrum.hpp index 3df3045a8..9874518e7 100644 --- a/src/ENDFtk/section/5/MadlandNixSpectrum.hpp +++ b/src/ENDFtk/section/5/MadlandNixSpectrum.hpp @@ -50,22 +50,22 @@ class MadlandNixSpectrum : protected TabulationRecord { /** * @brief Return the energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the maximum temperature parameter values */ - auto TM() const { return TabulationRecord::y(); } + AllRange< double > TM() const { return TabulationRecord::y(); } /** * @brief Return the maximum temperature parameter values */ - auto maximumTemperatureValues() const { return this->TM(); } + AllRange< double > maximumTemperatureValues() const { return this->TM(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/5/Parameter.hpp b/src/ENDFtk/section/5/Parameter.hpp index 74004f1d7..9d85dffb0 100644 --- a/src/ENDFtk/section/5/Parameter.hpp +++ b/src/ENDFtk/section/5/Parameter.hpp @@ -17,17 +17,17 @@ class Parameter : protected TabulationRecord { /** * @brief Return the energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the function values */ - auto values() const { return TabulationRecord::y(); } + AllRange< double > values() const { return TabulationRecord::y(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/5/PartialDistribution.hpp b/src/ENDFtk/section/5/PartialDistribution.hpp index ec2e4eeb0..2ee7b7865 100644 --- a/src/ENDFtk/section/5/PartialDistribution.hpp +++ b/src/ENDFtk/section/5/PartialDistribution.hpp @@ -33,12 +33,12 @@ class PartialDistribution { /** * @brief Return the probability */ - const auto& probability() const { return this->probability_; } + const Probability& probability() const { return this->probability_; } /** * @brief Return the distribution */ - const auto& distribution() const { return this->distribution_; } + const Distribution& distribution() const { return this->distribution_; } #include "ENDFtk/section/5/PartialDistribution/src/NC.hpp" #include "ENDFtk/section/5/PartialDistribution/src/print.hpp" diff --git a/src/ENDFtk/section/5/Probability.hpp b/src/ENDFtk/section/5/Probability.hpp index dee78e6be..5c3d257e7 100644 --- a/src/ENDFtk/section/5/Probability.hpp +++ b/src/ENDFtk/section/5/Probability.hpp @@ -41,22 +41,22 @@ class Probability : protected TabulationRecord { /** * @brief Return the energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the probability values */ - auto P() const { return TabulationRecord::y(); } + AllRange< double > P() const { return TabulationRecord::y(); } /** * @brief Return the probability values */ - auto probabilities() const { return this->P(); } + AllRange< double > probabilities() const { return this->P(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/5/TabulatedSpectrum.hpp b/src/ENDFtk/section/5/TabulatedSpectrum.hpp index ff2010bfa..0a2962b0a 100644 --- a/src/ENDFtk/section/5/TabulatedSpectrum.hpp +++ b/src/ENDFtk/section/5/TabulatedSpectrum.hpp @@ -55,7 +55,10 @@ class TabulatedSpectrum { /** * @brief Return the outgoing energy distributions */ - auto outgoingDistributions() const { return this->data_.records(); } + AllRange< OutgoingEnergyDistribution > outgoingDistributions() const { + + return this->data_.records(); + } /** * @brief Return the incoming energies @@ -63,7 +66,7 @@ class TabulatedSpectrum { auto incidentEnergies() const { return this->outgoingDistributions() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( const auto& entry ) { return entry.incidentEnergy(); } ); } @@ -71,13 +74,19 @@ class TabulatedSpectrum { * @brief Return interpolation type for each range on the incoming * energy grid */ - auto interpolants() const { return this->data_.tab2().interpolants(); } + AllRange< long > interpolants() const { + + return this->data_.tab2().interpolants(); + } /** * @brief Return interpolation boundaries for the incoming * energy grid */ - auto boundaries() const { return this->data_.tab2().boundaries(); } + AllRange< long > boundaries() const { + + return this->data_.tab2().boundaries(); + } /** * @brief Return the number of lines in this MF5 component diff --git a/src/ENDFtk/section/5/WattSpectrum.hpp b/src/ENDFtk/section/5/WattSpectrum.hpp index faccd8408..70e9cc0d8 100644 --- a/src/ENDFtk/section/5/WattSpectrum.hpp +++ b/src/ENDFtk/section/5/WattSpectrum.hpp @@ -31,12 +31,12 @@ class WattSpectrum { /** * @brief Return the a parameter data */ - const auto& a() const { return this->parameters_[0]; } + const Parameter& a() const { return this->parameters_[0]; } /** * @brief Return the b parameter data */ - const auto& b() const { return this->parameters_[1]; } + const Parameter& b() const { return this->parameters_[1]; } #include "ENDFtk/section/5/WattSpectrum/src/NC.hpp" #include "ENDFtk/section/5/WattSpectrum/src/print.hpp" diff --git a/src/ENDFtk/section/6.hpp b/src/ENDFtk/section/6.hpp index 33f59f49d..edc2741f2 100644 --- a/src/ENDFtk/section/6.hpp +++ b/src/ENDFtk/section/6.hpp @@ -7,6 +7,7 @@ // other includes #include "boost/hana.hpp" #include "range/v3/algorithm/find_if_not.hpp" +#include "range/v3/range/conversion.hpp" #include "range/v3/view/all.hpp" #include "range/v3/view/chunk.hpp" #include "range/v3/view/concat.hpp" @@ -127,7 +128,10 @@ namespace hana = boost::hana; /** * @brief Return the reaction products defined in this section */ - auto reactionProducts() const { return ranges::view::all( this->products_ ); } + AllRange< ReactionProduct > reactionProducts() const { + + return ranges::cpp20::views::all( this->products_ ); + } #include "ENDFtk/section/6/src/NC.hpp" #include "ENDFtk/section/6/src/print.hpp" diff --git a/src/ENDFtk/section/6/ChargedParticleElasticScattering.hpp b/src/ENDFtk/section/6/ChargedParticleElasticScattering.hpp index c0ecdef8d..949c087ad 100644 --- a/src/ENDFtk/section/6/ChargedParticleElasticScattering.hpp +++ b/src/ENDFtk/section/6/ChargedParticleElasticScattering.hpp @@ -74,7 +74,10 @@ class ChargedParticleElasticScattering { /** * @brief Return the distributions, one for each incident energy */ - auto distributions() const { return this->data_.records(); } + AllRange< Variant > distributions() const { + + return this->data_.records(); + } /** * @brief Return the incident energy values @@ -82,7 +85,7 @@ class ChargedParticleElasticScattering { auto E() const { return this->distributions() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( const auto& variant ) { return std::visit( [] ( const auto& record ) { return record.incidentEnergy(); }, @@ -98,12 +101,18 @@ class ChargedParticleElasticScattering { * @brief Return interpolation type for each range on the incident * energy grid */ - auto interpolants() const { return this->data_.tab2().interpolants(); } + AllRange< long > interpolants() const { + + return this->data_.tab2().interpolants(); + } /** * @brief Return interpolation boundaries for the incident energy grid */ - auto boundaries() const { return this->data_.tab2().boundaries(); } + AllRange< long > boundaries() const { + + return this->data_.tab2().boundaries(); + } /** * @brief Return the number of lines in this MF6 component diff --git a/src/ENDFtk/section/6/ChargedParticleElasticScattering/LegendreCoefficients.hpp b/src/ENDFtk/section/6/ChargedParticleElasticScattering/LegendreCoefficients.hpp index d06d840e0..f45fae0e0 100644 --- a/src/ENDFtk/section/6/ChargedParticleElasticScattering/LegendreCoefficients.hpp +++ b/src/ENDFtk/section/6/ChargedParticleElasticScattering/LegendreCoefficients.hpp @@ -55,12 +55,12 @@ class LegendreCoefficients : protected ListRecord { /** * @brief Return the Legendre coefficients */ - auto A() const { return ListRecord::list(); } + AllRange< double > A() const { return ListRecord::list(); } /** * @brief Return the Legendre coefficients */ - auto coefficients() const { return this->A(); } + AllRange< double > coefficients() const { return this->A(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/6/ChargedParticleElasticScattering/NuclearAmplitudeExpansion.hpp b/src/ENDFtk/section/6/ChargedParticleElasticScattering/NuclearAmplitudeExpansion.hpp index 12e0f3bbe..ee74cce29 100644 --- a/src/ENDFtk/section/6/ChargedParticleElasticScattering/NuclearAmplitudeExpansion.hpp +++ b/src/ENDFtk/section/6/ChargedParticleElasticScattering/NuclearAmplitudeExpansion.hpp @@ -55,7 +55,7 @@ class NuclearAmplitudeExpansion : protected ListRecord { auto B() const { return ListRecord::list() - | ranges::view::take( this->NW() - 2 * this->NL() - 2 ); + | ranges::views::take( this->NW() - 2 * this->NL() - 2 ); } /** @@ -69,9 +69,9 @@ class NuclearAmplitudeExpansion : protected ListRecord { */ auto AR() const { - return ranges::view::drop_exactly( ListRecord::list(), + return ranges::views::drop_exactly( ListRecord::list(), this->NW() - 2 * this->NL() - 2 ) - | ranges::view::stride( 2 ); + | ranges::views::stride( 2 ); } /** @@ -84,9 +84,9 @@ class NuclearAmplitudeExpansion : protected ListRecord { */ auto AI() const { - return ranges::view::drop_exactly( ListRecord::list(), + return ranges::views::drop_exactly( ListRecord::list(), this->NW() - 2 * this->NL() - 1 ) - | ranges::view::stride( 2 ); + | ranges::views::stride( 2 ); } /** @@ -100,7 +100,7 @@ class NuclearAmplitudeExpansion : protected ListRecord { */ auto A() const { - return ranges::view::zip_with( + return ranges::views::zip_with( [] ( auto real, auto imag ) { return std::complex< double >( real, imag ); }, this->realInterferenceCoefficients(), diff --git a/src/ENDFtk/section/6/ChargedParticleElasticScattering/NuclearPlusInterference.hpp b/src/ENDFtk/section/6/ChargedParticleElasticScattering/NuclearPlusInterference.hpp index e24c597c2..730401aef 100644 --- a/src/ENDFtk/section/6/ChargedParticleElasticScattering/NuclearPlusInterference.hpp +++ b/src/ENDFtk/section/6/ChargedParticleElasticScattering/NuclearPlusInterference.hpp @@ -52,15 +52,15 @@ class NuclearPlusInterference : protected ListRecord { /** * @brief Return the cosine values */ - auto MU() const { + StrideRange< AllRange< double > > MU() const { - return ListRecord::list() | ranges::view::stride( 2 ); + return ListRecord::list() | ranges::views::stride( 2 ); } /** * @brief Return the cosine values */ - auto cosines() const { + StrideRange< AllRange< double > > cosines() const { return this->MU(); } @@ -68,16 +68,19 @@ class NuclearPlusInterference : protected ListRecord { /** * @brief Return the probabilities */ - auto PNI() const { + StrideRange< DropRange< AllRange< double > > > PNI() const { - return ranges::view::drop_exactly( ListRecord::list(), 1 ) - | ranges::view::stride( 2 ); + return ranges::views::drop_exactly( ListRecord::list(), 1 ) + | ranges::views::stride( 2 ); } /** * @brief Return the probabilities */ - auto probabilities() const { return this->PNI(); } + StrideRange< DropRange< AllRange< double > > > probabilities() const { + + return this->PNI(); + } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/6/ContinuumEnergyAngle.hpp b/src/ENDFtk/section/6/ContinuumEnergyAngle.hpp index e4758432c..4977c9a1e 100644 --- a/src/ENDFtk/section/6/ContinuumEnergyAngle.hpp +++ b/src/ENDFtk/section/6/ContinuumEnergyAngle.hpp @@ -65,25 +65,34 @@ class ContinuumEnergyAngle { long NR() const { return this->data_.tab2().NR(); } /** - * @brief Return the number of secondary energy values + * @brief Return the number of incident energy values */ long NE() const { return this->data_.tab2().NZ(); } /** * @brief Return the subsections, one for each incident energy */ - auto distributions() const { return this->data_.records(); } + AllRange< Variant > distributions() const { + + return this->data_.records(); + } /** * @brief Return interpolation type for each range on the incident * energy grid */ - auto interpolants() const { return this->data_.tab2().interpolants(); } + AllRange< long > interpolants() const { + + return this->data_.tab2().interpolants(); + } /** * @brief Return interpolation boundaries for the incident energy grid */ - auto boundaries() const { return this->data_.tab2().boundaries(); } + AllRange< long > boundaries() const { + + return this->data_.tab2().boundaries(); + } /** * @brief Return the incident energy values @@ -91,7 +100,7 @@ class ContinuumEnergyAngle { auto E() const { return this->distributions() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( const auto& variant ) { return std::visit( [] ( const auto& record ) { return record.incidentEnergy(); }, diff --git a/src/ENDFtk/section/6/ContinuumEnergyAngle/Base.hpp b/src/ENDFtk/section/6/ContinuumEnergyAngle/Base.hpp index 158abeeb6..5123a14f5 100644 --- a/src/ENDFtk/section/6/ContinuumEnergyAngle/Base.hpp +++ b/src/ENDFtk/section/6/ContinuumEnergyAngle/Base.hpp @@ -60,30 +60,33 @@ class Base : protected ListRecord { /** * @brief Return the secondary energy values */ - auto EP() const { + StrideRange< AllRange< double > > EP() const { - return ListRecord::list() - | ranges::view::stride( 2 + this->NA() ); + return ListRecord::list() | ranges::views::stride( 2 + this->NA() ); } /** * @brief Return the secondary energy values */ - auto energies() const { return this->EP(); } + StrideRange< AllRange< double > > energies() const { return this->EP(); } /** * @brief Return the total emission probabilities */ - auto F0() const { + StrideRange< DropRange< AllRange< double > > > F0() const { - return ranges::view::drop_exactly( ListRecord::list(), 1 ) - | ranges::view::stride( 2 + this->NA() ); + return ranges::views::drop_exactly( ListRecord::list(), 1 ) + | ranges::views::stride( 2 + this->NA() ); } /** * @brief Return the total emission probabilities */ - auto totalEmissionProbabilities() const { return this->F0(); } + StrideRange< DropRange< AllRange< double > > > + totalEmissionProbabilities() const { + + return this->F0(); + } private: @@ -102,8 +105,9 @@ class Base : protected ListRecord { */ auto data() const { - return ListRecord::list() | ranges::view::chunk( 2 + this->NA() ) - | ranges::view::transform( ranges::view::tail ); + return ListRecord::list() | ranges::views::chunk( 2 + this->NA() ) + | ranges::cpp20::views::transform( + ranges::views::tail ); } public: diff --git a/src/ENDFtk/section/6/ContinuumEnergyAngle/Base/src/ctor.hpp b/src/ENDFtk/section/6/ContinuumEnergyAngle/Base/src/ctor.hpp index 53fffefbf..cf58fca1b 100644 --- a/src/ENDFtk/section/6/ContinuumEnergyAngle/Base/src/ctor.hpp +++ b/src/ENDFtk/section/6/ContinuumEnergyAngle/Base/src/ctor.hpp @@ -9,7 +9,7 @@ Base() = default; Base( ListRecord&& list ) : ListRecord( std::move( list ) ) { - verifySorted( this->energies() | ranges::view::drop_exactly( this->ND() ), + verifySorted( this->energies() | ranges::views::drop_exactly( this->ND() ), "Energy" ); verifySize( this->NW(), this->NA(), this->NEP() ); }; diff --git a/src/ENDFtk/section/6/ContinuumEnergyAngle/KalbachMann/src/generateList.hpp b/src/ENDFtk/section/6/ContinuumEnergyAngle/KalbachMann/src/generateList.hpp index 5a34fd2e8..017b9bfe4 100644 --- a/src/ENDFtk/section/6/ContinuumEnergyAngle/KalbachMann/src/generateList.hpp +++ b/src/ENDFtk/section/6/ContinuumEnergyAngle/KalbachMann/src/generateList.hpp @@ -2,6 +2,5 @@ template < typename Array > static std::vector< double > generateList( std::vector< Array >&& data ) { - return data | ranges::view::join; + return ranges::to< std::vector< double > >( data | ranges::views::join ); } - diff --git a/src/ENDFtk/section/6/ContinuumEnergyAngle/LegendreCoefficients/src/generateList.hpp b/src/ENDFtk/section/6/ContinuumEnergyAngle/LegendreCoefficients/src/generateList.hpp index b7155ab04..ddf5bfd22 100644 --- a/src/ENDFtk/section/6/ContinuumEnergyAngle/LegendreCoefficients/src/generateList.hpp +++ b/src/ENDFtk/section/6/ContinuumEnergyAngle/LegendreCoefficients/src/generateList.hpp @@ -24,8 +24,10 @@ generateList( unsigned int na, } } - return ranges::view::zip_with( - ranges::view::concat, - energies | ranges::view::transform( ranges::view::single ), - coefficients ) | ranges::view::join | ranges::to_vector; + return ranges::to< std::vector< double > >( + ranges::views::zip_with( + ranges::views::concat, + energies | ranges::cpp20::views::transform( + ranges::cpp20::views::single ), + coefficients ) | ranges::views::join ); } diff --git a/src/ENDFtk/section/6/ContinuumEnergyAngle/TabulatedDistribution.hpp b/src/ENDFtk/section/6/ContinuumEnergyAngle/TabulatedDistribution.hpp index 1470ce024..d1d3c1dd3 100644 --- a/src/ENDFtk/section/6/ContinuumEnergyAngle/TabulatedDistribution.hpp +++ b/src/ENDFtk/section/6/ContinuumEnergyAngle/TabulatedDistribution.hpp @@ -58,9 +58,10 @@ class TabulatedDistribution : protected Base { auto MU() const { return Base::list() - | ranges::view::chunk( 2 + this->NA() ) - | ranges::view::transform( ranges::view::drop( 2 ) - | ranges::view::stride( 2 ) ); } + | ranges::views::chunk( 2 + this->NA() ) + | ranges::cpp20::views::transform( + ranges::views::drop( 2 ) + | ranges::views::stride( 2 ) ); } /** * @brief Return the cosine values @@ -73,9 +74,10 @@ class TabulatedDistribution : protected Base { auto F() const { return Base::list() - | ranges::view::chunk( 2 + this->NA() ) - | ranges::view::transform( ranges::view::drop( 3 ) - | ranges::view::stride( 2 ) ); } + | ranges::views::chunk( 2 + this->NA() ) + | ranges::cpp20::views::transform( + ranges::views::drop( 3 ) + | ranges::views::stride( 2 ) ); } /** * @brief Return the distribution probabilities diff --git a/src/ENDFtk/section/6/ContinuumEnergyAngle/ThermalScatteringData.hpp b/src/ENDFtk/section/6/ContinuumEnergyAngle/ThermalScatteringData.hpp index a435dace5..b173772fc 100644 --- a/src/ENDFtk/section/6/ContinuumEnergyAngle/ThermalScatteringData.hpp +++ b/src/ENDFtk/section/6/ContinuumEnergyAngle/ThermalScatteringData.hpp @@ -9,11 +9,6 @@ */ class ThermalScatteringData : protected ListRecord { - /* type aliases */ - using Range = decltype( std::declval< ListRecord >().list() ); - using StrideRange = decltype( std::declval< Range >() | ranges::view::stride( 0 ) ); - using DropStrideRange = decltype( std::declval< Range >() | ranges::view::drop_exactly( 0 ) | ranges::view::stride( 0 ) ); - /* auxiliary functions */ #include "ENDFtk/section/6/ContinuumEnergyAngle/ThermalScatteringData/src/generateList.hpp" @@ -47,7 +42,7 @@ class ThermalScatteringData : protected ListRecord { /** * @brief Return the data contained in this component */ - Range data() const { return ListRecord::list(); } + AllRange< double > data() const { return ListRecord::list(); } /** * @brief Return the data contained in this component @@ -74,23 +69,23 @@ class ThermalScatteringData : protected ListRecord { /** * @brief Return the number of energy points */ - StrideRange EP() const { + StrideRange< AllRange< double > > EP() const { - return this->data() | ranges::view::stride( this->N2() ); + return this->data() | ranges::views::stride( this->N2() ); } /** * @brief Return the number of energy points */ - StrideRange energies() const { return this->EP(); } + StrideRange< AllRange< double > > energies() const { return this->EP(); } /** * @brief Return second value for every energy */ - DropStrideRange PP() const { + StrideRange< DropRange< AllRange< double > > > PP() const { - return this->data() | ranges::view::drop_exactly( 1 ) - | ranges::view::stride( this->N2() ); + return this->data() | ranges::views::drop_exactly( 1 ) + | ranges::views::stride( this->N2() ); } /** @@ -99,10 +94,10 @@ class ThermalScatteringData : protected ListRecord { auto MU() const { return this->data() - | ranges::view::chunk( this->N2() ) - | ranges::view::transform( + | ranges::views::chunk( this->N2() ) + | ranges::cpp20::views::transform( [] ( const auto& array ) - { return array | ranges::view::drop_exactly( 2 ); } ); + { return array | ranges::views::drop_exactly( 2 ); } ); } /** diff --git a/src/ENDFtk/section/6/ContinuumEnergyAngle/src/verifyLANG.hpp b/src/ENDFtk/section/6/ContinuumEnergyAngle/src/verifyLANG.hpp index 5b567079b..1d8433bd2 100644 --- a/src/ENDFtk/section/6/ContinuumEnergyAngle/src/verifyLANG.hpp +++ b/src/ENDFtk/section/6/ContinuumEnergyAngle/src/verifyLANG.hpp @@ -7,13 +7,14 @@ verifyLANG( int LANG, const Array& sequence ) { { return entry.LANG(); }, variant ); }; - auto iter = ranges::find_if_not( sequence, hana::equal.to( LANG ), lang ); + auto iter = ranges::cpp20::find_if_not( sequence, hana::equal.to( LANG ), lang ); - if ( iter != ranges::end( sequence ) ) { + if ( iter != ranges::cpp20::end( sequence ) ) { Log::error( "All subsections must use the same LANG format option" ); Log::info( "Expected LANG={} for the subsection with index={}", LANG, - ranges::distance( ranges::begin( sequence ), iter ) ); + ranges::cpp20::distance( + ranges::cpp20::begin( sequence ), iter ) ); throw std::exception(); } } diff --git a/src/ENDFtk/section/6/DiscreteTwoBodyScattering.hpp b/src/ENDFtk/section/6/DiscreteTwoBodyScattering.hpp index fed29e985..8e0af1a38 100644 --- a/src/ENDFtk/section/6/DiscreteTwoBodyScattering.hpp +++ b/src/ENDFtk/section/6/DiscreteTwoBodyScattering.hpp @@ -51,7 +51,7 @@ class DiscreteTwoBodyScattering { /** * @brief Return the distributions, one for each incident energy */ - auto distributions() const { return this->data_.records(); } + AllRange< Variant > distributions() const { return this->data_.records(); } /** * @brief Return the incident energy values @@ -59,7 +59,7 @@ class DiscreteTwoBodyScattering { auto E() const { return this->distributions() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( const auto& variant ) { return std::visit( [] ( const auto& record ) { return record.incidentEnergy(); }, @@ -75,12 +75,18 @@ class DiscreteTwoBodyScattering { * @brief Return interpolation type for each range on the incident * energy grid */ - auto interpolants() const { return this->data_.tab2().interpolants(); } + AllRange< long > interpolants() const { + + return this->data_.tab2().interpolants(); + } /** * @brief Return interpolation boundaries for the incident energy grid */ - auto boundaries() const { return this->data_.tab2().boundaries(); } + AllRange< long > boundaries() const { + + return this->data_.tab2().boundaries(); + } /** * @brief Return the number of lines in this MF6 component diff --git a/src/ENDFtk/section/6/DiscreteTwoBodyScattering/LegendreCoefficients.hpp b/src/ENDFtk/section/6/DiscreteTwoBodyScattering/LegendreCoefficients.hpp index 56c4b2305..802f02a2c 100644 --- a/src/ENDFtk/section/6/DiscreteTwoBodyScattering/LegendreCoefficients.hpp +++ b/src/ENDFtk/section/6/DiscreteTwoBodyScattering/LegendreCoefficients.hpp @@ -62,13 +62,13 @@ class LegendreCoefficients : protected ListRecord { * @brief Return the Legendre coefficients in the distribution (a0 is not * present and assumed to be equal to 1) */ - auto A() const { return ListRecord::list(); } + AllRange< double > A() const { return ListRecord::list(); } /** * @brief Return the Legendre coefficients in the distribution (a0 is not * present and assumed to be equal to 1) */ - auto coefficients() const { return this->A(); } + AllRange< double > coefficients() const { return this->A(); } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/6/DiscreteTwoBodyScattering/TabulatedDistribution.hpp b/src/ENDFtk/section/6/DiscreteTwoBodyScattering/TabulatedDistribution.hpp index 375ac2a08..ab7572cbd 100644 --- a/src/ENDFtk/section/6/DiscreteTwoBodyScattering/TabulatedDistribution.hpp +++ b/src/ENDFtk/section/6/DiscreteTwoBodyScattering/TabulatedDistribution.hpp @@ -60,15 +60,15 @@ class TabulatedDistribution : protected ListRecord { /** * @brief Return the cosine values */ - auto MU() const { + StrideRange< AllRange< double > > MU() const { - return ListRecord::list() | ranges::view::stride( 2 ); + return ListRecord::list() | ranges::views::stride( 2 ); } /** * @brief Return the cosine values */ - auto cosines() const { + StrideRange< AllRange< double > > cosines() const { return this->MU(); } @@ -76,16 +76,16 @@ class TabulatedDistribution : protected ListRecord { /** * @brief Return the distribution probabilities */ - auto F() const { + StrideRange< DropRange< AllRange< double > > > F() const { - return ranges::view::drop_exactly( ListRecord::list(), 1 ) - | ranges::view::stride( 2 ); + return ranges::views::drop_exactly( ListRecord::list(), 1 ) + | ranges::views::stride( 2 ); } /** * @brief Return the distribution probabilities */ - auto probabilities() const { + StrideRange< DropRange< AllRange< double > > > probabilities() const { return this->F(); } diff --git a/src/ENDFtk/section/6/LaboratoryAngleEnergy.hpp b/src/ENDFtk/section/6/LaboratoryAngleEnergy.hpp index d9d3c3582..e9741dcfc 100644 --- a/src/ENDFtk/section/6/LaboratoryAngleEnergy.hpp +++ b/src/ENDFtk/section/6/LaboratoryAngleEnergy.hpp @@ -44,18 +44,28 @@ class LaboratoryAngleEnergy { /** * @brief Return the interpolants for the incident energy axis */ - auto interpolants() const { return this->data_.tab2().interpolants(); } + AllRange< long > interpolants() const { + + return this->data_.tab2().interpolants(); + } /** * @brief Return the interpolation region boundaries for the incident * energy axis */ - auto boundaries() const { return this->data_.tab2().boundaries(); } + AllRange< long > boundaries() const { + + return this->data_.tab2().boundaries(); + } /** * @brief Return the angular distributions */ - auto angularDistributions() const { return this->data_.records(); } + AllRange< LaboratoryAngleEnergy::AngularDistribution > + angularDistributions() const { + + return this->data_.records(); + } /** * @brief Return the incident energy values @@ -63,7 +73,7 @@ class LaboratoryAngleEnergy { auto E() const { return this->angularDistributions() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( const auto& record ) { return record.incidentEnergy(); } ); } diff --git a/src/ENDFtk/section/6/LaboratoryAngleEnergy/AngularDistribution.hpp b/src/ENDFtk/section/6/LaboratoryAngleEnergy/AngularDistribution.hpp index 26e3045a5..42e61c30c 100644 --- a/src/ENDFtk/section/6/LaboratoryAngleEnergy/AngularDistribution.hpp +++ b/src/ENDFtk/section/6/LaboratoryAngleEnergy/AngularDistribution.hpp @@ -48,7 +48,7 @@ class AngularDistribution : /** * @brief Return the interpolants for the cosine axis */ - auto interpolants() const { + AllRange< long > interpolants() const { return InterpolationSequenceRecord::tab2().interpolants(); } @@ -56,7 +56,7 @@ class AngularDistribution : /** * @brief Return the interpolation region boundaries for the cosine axis */ - auto boundaries() const { + AllRange< long > boundaries() const { return InterpolationSequenceRecord::tab2().boundaries(); } @@ -67,7 +67,7 @@ class AngularDistribution : auto MU() const { return InterpolationSequenceRecord::records() - | ranges::view::transform( + | ranges::cpp20::views::transform( [] ( const auto& record ) { return record.cosine(); } ); } @@ -80,7 +80,7 @@ class AngularDistribution : /** * @brief Return the energy distributions for this incident energy value */ - auto energyDistributions() const { + AllRange< EnergyDistribution > energyDistributions() const { return InterpolationSequenceRecord::records(); } diff --git a/src/ENDFtk/section/6/LaboratoryAngleEnergy/EnergyDistribution.hpp b/src/ENDFtk/section/6/LaboratoryAngleEnergy/EnergyDistribution.hpp index 9028083cb..07df0dc5b 100644 --- a/src/ENDFtk/section/6/LaboratoryAngleEnergy/EnergyDistribution.hpp +++ b/src/ENDFtk/section/6/LaboratoryAngleEnergy/EnergyDistribution.hpp @@ -36,22 +36,22 @@ class EnergyDistribution : protected TabulationRecord { /** * @brief Return the outgoing energy values */ - auto EP() const { return TabulationRecord::x(); } + AllRange< double > EP() const { return TabulationRecord::x(); } /** * @brief Return the outgoing energy values */ - auto energies() const { return this->EP(); } + AllRange< double > energies() const { return this->EP(); } /** * @brief Return the probabilities */ - auto F() const { return TabulationRecord::y(); } + AllRange< double > F() const { return TabulationRecord::y(); } /** * @brief Return the probabilities */ - auto probabilities() const { return this->F(); } + AllRange< double > probabilities() const { return this->F(); } using TabulationRecord::NR; using TabulationRecord::NP; diff --git a/src/ENDFtk/section/6/Multiplicity.hpp b/src/ENDFtk/section/6/Multiplicity.hpp index 81e511b4d..021c6690a 100644 --- a/src/ENDFtk/section/6/Multiplicity.hpp +++ b/src/ENDFtk/section/6/Multiplicity.hpp @@ -45,22 +45,22 @@ class Multiplicity : protected TabulationRecord { /** * @brief Return the energies */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the energies */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the multiplicities */ - auto Y() const { return TabulationRecord::y(); } + AllRange< double > Y() const { return TabulationRecord::y(); } /** * @brief Return the multiplicities */ - auto multiplicities() const { return this->Y(); } + AllRange< double > multiplicities() const { return this->Y(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/7/2/CoherentElastic.hpp b/src/ENDFtk/section/7/2/CoherentElastic.hpp index a11716677..d40513aa5 100644 --- a/src/ENDFtk/section/7/2/CoherentElastic.hpp +++ b/src/ENDFtk/section/7/2/CoherentElastic.hpp @@ -81,23 +81,30 @@ class CoherentElastic { /** * @brief Return interpolation type for each range on the energy grid */ - auto interpolants() const { return this->principal_.interpolants(); } + AllRange< long > interpolants() const { + + return this->principal_.interpolants(); + } /** * @brief Return interpolation boundaries for the energy grid */ - auto boundaries() const { return this->principal_.boundaries(); } + AllRange< long > boundaries() const { + + return this->principal_.boundaries(); + } /** * @brief Return all temperatures for which thermal scattering law data is * given */ auto T() const { - return ranges::view::concat( - ranges::view::single( this->principal_.C1() ), + + return ranges::views::concat( + ranges::cpp20::views::single( this->principal_.C1() ), this->temperatures_ | - ranges::view::transform( [] ( const auto& v ) - { return v.C1(); } ) ); + ranges::cpp20::views::transform( [] ( const auto& v ) + { return v.C1(); } ) ); } /** @@ -109,21 +116,22 @@ class CoherentElastic { /** * @brief Return the energy grid */ - auto E() const { return this->principal_.x(); } + AllRange< double > E() const { return this->principal_.x(); } /** * @brief Return the energy grid */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the temperature interpolation flags (LT values will be * given) */ auto LI() const { + return this->temperatures_ | - ranges::view::transform( [] ( const auto& v ) - { return v.L1(); } ); + ranges::cpp20::views::transform( [] ( const auto& v ) + { return v.L1(); } ); } /** @@ -137,11 +145,12 @@ class CoherentElastic { * temperature */ auto S() const { - return ranges::view::concat( - ranges::view::single( this->principal_.y() ), + + return ranges::views::concat( + ranges::cpp20::views::single( this->principal_.y() ), this->temperatures_ | - ranges::view::transform( [] ( const auto& v ) - { return v.list(); } ) ); + ranges::cpp20::views::transform( [] ( const auto& v ) + { return v.list(); } ) ); } /** diff --git a/src/ENDFtk/section/7/2/CoherentElastic/src/verifyTemperatures.hpp b/src/ENDFtk/section/7/2/CoherentElastic/src/verifyTemperatures.hpp index d10330aef..b79ee97ad 100644 --- a/src/ENDFtk/section/7/2/CoherentElastic/src/verifyTemperatures.hpp +++ b/src/ENDFtk/section/7/2/CoherentElastic/src/verifyTemperatures.hpp @@ -2,14 +2,15 @@ template< typename Array > static void verifyTemperatures( int NP, const Array& temperatures ) { - auto iter = ranges::find_if_not( temperatures, hana::equal.to( NP ), - &ListRecord::NPL ); + auto iter = ranges::cpp20::find_if_not( temperatures, hana::equal.to( NP ), + &ListRecord::NPL ); - if ( iter != ranges::end( temperatures ) ) { + if ( iter != ranges::cpp20::end( temperatures ) ) { Log::error( "All S(E,T) functions must have the same size" ); Log::info( "Expected NP={} for the temperature with index={}", NP, - ranges::distance( ranges::begin( temperatures ), iter ) ); + ranges::cpp20::distance( + ranges::cpp20::begin( temperatures ), iter ) ); throw std::exception(); } } diff --git a/src/ENDFtk/section/7/2/IncoherentElastic.hpp b/src/ENDFtk/section/7/2/IncoherentElastic.hpp index 2700ca5c7..7f6bbe717 100644 --- a/src/ENDFtk/section/7/2/IncoherentElastic.hpp +++ b/src/ENDFtk/section/7/2/IncoherentElastic.hpp @@ -37,22 +37,22 @@ class IncoherentElastic : protected TabulationRecord { /** * @brief Return the temperature values */ - auto T() const { return TabulationRecord::x(); } + AllRange< double > T() const { return TabulationRecord::x(); } /** * @brief Return the temperature values */ - auto temperatures() const { return this->T(); } + AllRange< double > temperatures() const { return this->T(); } /** * @brief Return the Debye-Waller integral divided by the atomic mass (eV^-1) */ - auto W() const { return TabulationRecord::y(); } + AllRange< double > W() const { return TabulationRecord::y(); } /** * @brief Return the Debye-Waller integral divided by the atomic mass (eV^-1) */ - auto debyeWallerValues() const { return this->W(); } + AllRange< double > debyeWallerValues() const { return this->W(); } /* get methods */ using TabulationRecord::NP; diff --git a/src/ENDFtk/section/7/4.hpp b/src/ENDFtk/section/7/4.hpp index dee2070f1..8d4ec8b6b 100644 --- a/src/ENDFtk/section/7/4.hpp +++ b/src/ENDFtk/section/7/4.hpp @@ -53,6 +53,9 @@ namespace section{ // B(1)!=0 TabulatedFunctions >; + /* type aliases */ + using OptionalEffectiveTemperature = std::optional< EffectiveTemperature >; + private: /* fields */ @@ -63,7 +66,7 @@ namespace section{ ScatteringLaw law_; EffectiveTemperature principal_; - std::vector< std::optional< EffectiveTemperature > > secondary_; + std::vector< OptionalEffectiveTemperature > secondary_; /* auxiliary functions */ #include "ENDFtk/section/7/4/src/readSecondaryTemperatures.hpp" @@ -113,6 +116,7 @@ namespace section{ * @brief Return the effective temperature for the principal scatterer */ const EffectiveTemperature& principalEffectiveTemperature() const { + return this->principal_; } @@ -120,8 +124,10 @@ namespace section{ * @brief Return the effective temperatures for the secondary scatterers * (if any are defined) */ - auto secondaryEffectiveTemperatures() const { - return ranges::view::all( this->secondary_ ); + AllRange< OptionalEffectiveTemperature > + secondaryEffectiveTemperatures() const { + + return ranges::cpp20::views::all( this->secondary_ ); } #include "ENDFtk/section/7/4/src/NC.hpp" diff --git a/src/ENDFtk/section/7/4/EffectiveTemperature.hpp b/src/ENDFtk/section/7/4/EffectiveTemperature.hpp index 4a58d7466..aee527c70 100644 --- a/src/ENDFtk/section/7/4/EffectiveTemperature.hpp +++ b/src/ENDFtk/section/7/4/EffectiveTemperature.hpp @@ -30,22 +30,22 @@ class EffectiveTemperature : protected TabulationRecord { /** * @brief Return the moderator temperatures */ - auto TMOD() const { return TabulationRecord::x(); } + AllRange< double > TMOD() const { return TabulationRecord::x(); } /** * @brief Return the moderator temperatures */ - auto moderatorTemperatures() const { return this->TMOD(); } + AllRange< double > moderatorTemperatures() const { return this->TMOD(); } /** * @brief Return the effective temperatures */ - auto TEFF() const { return TabulationRecord::y(); } + AllRange< double > TEFF() const { return TabulationRecord::y(); } /** * @brief Return the effective temperatures */ - auto effectiveTemperatures() const { return this->TEFF(); } + AllRange< double > effectiveTemperatures() const { return this->TEFF(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/7/4/ScatteringLawConstants.hpp b/src/ENDFtk/section/7/4/ScatteringLawConstants.hpp index 3676d5785..a5c0f60f7 100644 --- a/src/ENDFtk/section/7/4/ScatteringLawConstants.hpp +++ b/src/ENDFtk/section/7/4/ScatteringLawConstants.hpp @@ -81,16 +81,16 @@ class ScatteringLawConstants : protected ListRecord { switch(1 + NS) { case 1: { static constexpr std::array< std::ptrdiff_t, 1 > indices = {{0}}; - return ranges::make_iterator_range(indices.begin(), indices.end()); + return ranges::make_subrange(indices.begin(), indices.end()); } case 2: { static constexpr std::array< std::ptrdiff_t, 2 > indices = {{0, 7}}; - return ranges::make_iterator_range(indices.begin(), indices.end()); + return ranges::make_subrange(indices.begin(), indices.end()); } case 3: { static constexpr std::array< std::ptrdiff_t, 3 > indices = {{0, 7, 13}}; - return ranges::make_iterator_range(indices.begin(), indices.end()); + return ranges::make_subrange(indices.begin(), indices.end()); } case 4: { static constexpr std::array< std::ptrdiff_t, 4 > indices = {{0, 7, 13, 19}}; - return ranges::make_iterator_range(indices.begin(), indices.end()); + return ranges::make_subrange(indices.begin(), indices.end()); } default: { #ifdef __GNUC__ __builtin_unreachable(); @@ -102,7 +102,7 @@ class ScatteringLawConstants : protected ListRecord { auto element = [l = ListRecord::list()](auto index){ return l[index]; }; - return indices( this->NS() ) | ranges::view::transform( element ); + return indices( this->NS() ) | ranges::cpp20::views::transform( element ); } /** @@ -115,40 +115,51 @@ class ScatteringLawConstants : protected ListRecord { * @brief Return the ratio of the atomic weight to the neutron mass for each * scattering atom type, stored in B(3), B(9) and B(15) */ - auto AWR() const { + StrideRange< DropRange< AllRange< double > > > AWR() const { + return ListRecord::list() - | ranges::view::drop_exactly( 2 ) - | ranges::view::stride( 6 ); } + | ranges::views::drop_exactly( 2 ) + | ranges::views::stride( 6 ); } /** * @brief Return the ratio of the atomic weight to the neutron mass for each * scattering atom type, stored in B(3), B(9) and B(15) */ - auto atomicWeightRatios() const { return this->AWR(); } + StrideRange< DropRange< AllRange< double > > > atomicWeightRatios() const { + + return this->AWR(); + } /** * @brief Return the number of atoms for each scattering atom type present in * the molecule or unit cell, stored in B(6), B(12) and B(18) */ - auto M() const { + StrideRange< DropRange< AllRange< double > > > M() const { + return ListRecord::list() - | ranges::view::drop_exactly( 5 ) - | ranges::view::stride( 6 ); } + | ranges::views::drop_exactly( 5 ) + | ranges::views::stride( 6 ); } /** * @brief Return the number of atoms for each scattering atom type present in * the molecule or unit cell, stored in B(6), B(12) and B(18) */ - auto numberAtoms() const { return this->M(); } + StrideRange< DropRange< AllRange< double > > > numberAtoms() const { + + return this->M(); + } /** * @brief Return the analytical function type for each non-principal * scattering atom type, stored in B(7), B(13) and B(19) */ - auto analyticalFunctionTypes() const { + StrideRange< DropRange< AllRange< double > > > + analyticalFunctionTypes() const { + return ListRecord::list() - | ranges::view::drop_exactly( 6 ) - | ranges::view::stride( 6 ); } + | ranges::views::drop_exactly( 6 ) + | ranges::views::stride( 6 ); + } using ListRecord::NC; using ListRecord::print; diff --git a/src/ENDFtk/section/7/4/TabulatedFunctions.hpp b/src/ENDFtk/section/7/4/TabulatedFunctions.hpp index 7e145197f..6dc8a08d6 100644 --- a/src/ENDFtk/section/7/4/TabulatedFunctions.hpp +++ b/src/ENDFtk/section/7/4/TabulatedFunctions.hpp @@ -52,8 +52,8 @@ class TabulatedFunctions { auto B() const { return this->data_.records() - | ranges::view::transform( [] ( const auto& record ) - { return record.beta(); } ); + | ranges::cpp20::views::transform( [] ( const auto& record ) + { return record.beta(); } ); } /** @@ -64,22 +64,31 @@ class TabulatedFunctions { /** * @brief Return the beta values and associated S(alpha,T) functions */ - auto S() const { return this->data_.records(); } + AllRange< ScatteringFunction > S() const { return this->data_.records(); } /** * @brief Return the beta values and associated S(alpha,T) functions */ - auto scatteringFunctions() const { return this->S(); } + AllRange< ScatteringFunction > scatteringFunctions() const { + + return this->S(); + } /** * @brief Return the interpolation type for each range on the beta grid */ - auto interpolants() const { return this->data_.tab2().interpolants(); } + AllRange< long > interpolants() const { + + return this->data_.tab2().interpolants(); + } /** * @brief Return the interpolation boundaries for the beta grid */ - auto boundaries() const { return this->data_.tab2().boundaries(); } + AllRange< long > boundaries() const { + + return this->data_.tab2().boundaries(); + } /** * @brief Return the number of lines in this MF7/MT4 component diff --git a/src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction.hpp b/src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction.hpp index 556ab05e3..315dea1ff 100644 --- a/src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction.hpp +++ b/src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction.hpp @@ -86,23 +86,24 @@ class ScatteringFunction { /** * @brief Return interpolation type for each range on the alpha grid */ - auto interpolants() const { return this->alphas_.interpolants(); } + AllRange< long > interpolants() const { return this->alphas_.interpolants(); } /** * @brief Return interpolation boundaries for the alpha grid */ - auto boundaries() const { return this->alphas_.boundaries(); } + AllRange< long > boundaries() const { return this->alphas_.boundaries(); } /** * @brief Return all temperatures for which thermal scattering law data is * given */ auto T() const { - return ranges::view::concat( - ranges::view::single( this->alphas_.C1() ), + + return ranges::views::concat( + ranges::cpp20::views::single( this->alphas_.C1() ), this->temperatures_ | - ranges::view::transform( [] ( const auto& v ) - { return v.C1(); } ) ); + ranges::cpp20::views::transform( [] ( const auto& v ) + { return v.C1(); } ) ); } /** @@ -114,21 +115,22 @@ class ScatteringFunction { /** * @brief Return the alpha grid */ - auto A() const { return this->alphas_.x(); } + AllRange< double > A() const { return this->alphas_.x(); } /** * @brief Return the alpha grid */ - auto alphas() const { return this->A(); } + AllRange< double > alphas() const { return this->A(); } /** * @brief Return the temperature interpolation flags (LT values will be * given) */ auto LI() const { + return this->temperatures_ | - ranges::view::transform( [] ( const auto& v ) - { return v.L1(); } ); + ranges::cpp20::views::transform( [] ( const auto& v ) + { return v.L1(); } ); } /** @@ -142,11 +144,12 @@ class ScatteringFunction { * temperature */ auto S() const { - return ranges::view::concat( - ranges::view::single( this->alphas_.y() ), + + return ranges::views::concat( + ranges::cpp20::views::single( this->alphas_.y() ), this->temperatures_ | - ranges::view::transform( [] ( const auto& v ) - { return v.list(); } ) ); + ranges::cpp20::views::transform( [] ( const auto& v ) + { return v.list(); } ) ); } /** diff --git a/src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction/src/ctor.hpp b/src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction/src/ctor.hpp index 9e2a5b504..9570119de 100644 --- a/src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction/src/ctor.hpp +++ b/src/ENDFtk/section/7/4/TabulatedFunctions/ScatteringFunction/src/ctor.hpp @@ -12,8 +12,9 @@ ScatteringFunction( TabulationRecord&& alphas, if ( this->NT() != 1 ) { verifyBetaValues( this->beta(), this->temperatures_ | - ranges::view::transform( [] ( const auto& v ) - { return v.C2(); } ) ); + ranges::cpp20::views::transform( + [] ( const auto& v ) + { return v.C2(); } ) ); } } diff --git a/src/ENDFtk/section/7/4/TabulatedFunctions/test/TabulatedFunctions.test.cpp b/src/ENDFtk/section/7/4/TabulatedFunctions/test/TabulatedFunctions.test.cpp index 96bbfe3f1..7dc1ac229 100644 --- a/src/ENDFtk/section/7/4/TabulatedFunctions/test/TabulatedFunctions.test.cpp +++ b/src/ENDFtk/section/7/4/TabulatedFunctions/test/TabulatedFunctions.test.cpp @@ -230,7 +230,7 @@ void verifyChunkWithOneTemperature( const TabulatedFunctions& chunk ) { CHECK( 0 == value.LI().size() ); CHECK( 0 == value.temperatureInterpolants().size() ); - std::vector< std::vector< double > > values = value.S(); + decltype(auto) values = value.S(); CHECK( 1 == values.size() ); CHECK( 5 == values[0].size() ); CHECK( 2.386876e-4 == Approx( values[0][0] ) ); diff --git a/src/ENDFtk/section/7/4/src/ctor.hpp b/src/ENDFtk/section/7/4/src/ctor.hpp index 466541c8c..959ee48be 100644 --- a/src/ENDFtk/section/7/4/src/ctor.hpp +++ b/src/ENDFtk/section/7/4/src/ctor.hpp @@ -1,13 +1,13 @@ /** * @brief Constructor * - * @param[in] zaid the material ZAID value - * @param[in] awr the atomic weight ratio - * @param[in] lat the temperature flag for alpha and - * beta grid - * @param[in] lasym the S(a,b) symmetry flag - * @param[in] constants the thermal scattering law constants - * @param[in] law the thermal scattering law + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] lat the temperature flag for alpha and + * beta grid + * @param[in] lasym the S(a,b) symmetry flag + * @param[in] constants the thermal scattering law constants + * @param[in] law the thermal scattering law * @param[in] principals the effective temperature of the * principal scatterer * @param[in] secondaries the effective temperature of the diff --git a/src/ENDFtk/section/7/4/src/verifySecondaryTemperatures.hpp b/src/ENDFtk/section/7/4/src/verifySecondaryTemperatures.hpp index 3b082d892..8de384a18 100644 --- a/src/ENDFtk/section/7/4/src/verifySecondaryTemperatures.hpp +++ b/src/ENDFtk/section/7/4/src/verifySecondaryTemperatures.hpp @@ -16,18 +16,19 @@ verifySecondaryTemperatures( const TypeArray& types, if ( types.size() > 0 ) { auto needTemperature = - types | ranges::view::transform( [] ( double value ) - { return value == 0.0; } ); + types | ranges::cpp20::views::transform( [] ( double value ) + { return value == 0.0; } ); auto haveTemperature = - temperatures | ranges::view::transform( hana::to ); + temperatures | ranges::cpp20::views::transform( hana::to ); auto verify = - ranges::view::zip_with( std::equal_to<>{}, needTemperature, haveTemperature ); + ranges::views::zip_with( std::equal_to<>{}, + needTemperature, haveTemperature ); - auto iter = ranges::find( verify, false ); + auto iter = ranges::cpp20::find( verify, false ); - if ( iter != ranges::end( verify ) ) { + if ( iter != ranges::cpp20::end( verify ) ) { Log::error( "Available effective temperature data for secondary " "scatterers inconsistent with the thermal scattering " @@ -35,9 +36,8 @@ verifySecondaryTemperatures( const TypeArray& types, Log::info( "When B(7), B(13) or B(19) is zero, an effective temperature " "must be given" ); Log::info( "Encountered issue for the secondary scatterer with index={}", - ranges::distance( ranges::begin( verify ), iter ) ); + ranges::cpp20::distance( ranges::cpp20::begin( verify ), iter ) ); throw std::exception(); } } } - diff --git a/src/ENDFtk/section/8/454.hpp b/src/ENDFtk/section/8/454.hpp index 47fea7ed0..38eda4643 100644 --- a/src/ENDFtk/section/8/454.hpp +++ b/src/ENDFtk/section/8/454.hpp @@ -4,43 +4,82 @@ // system includes // other includes +#include "range/v3/range/conversion.hpp" +#include "ENDFtk/ControlRecord.hpp" +#include "ENDFtk/readSequence.hpp" #include "ENDFtk/section.hpp" +#include "ENDFtk/section/8/FissionYieldData.hpp" namespace njoy { namespace ENDFtk { namespace section { - /** - * @class - * @brief MF8 MT454 - unimplemented - */ template<> - class Type< 8, 454 > : protected NotImplementedYet< Type< 8, 454 > > { + class Type< 8, 454 > : protected BaseWithoutMT< Type< 8, 454 > > { - friend NotImplementedYet< Type< 8, 454 > >; + friend BaseWithoutMT< Type< 8, 454 > >; + + /* fields */ + std::vector< FissionYieldData > data_; + + /* auxiliary functions */ + #include "ENDFtk/section/8/454/src/generateFissionYields.hpp" public: - Type() : NotImplementedYet() {} - template< typename Iterator > - Type( HEAD& head, Iterator& begin, const Iterator& end, - long& lineNumber, int MAT ) : - NotImplementedYet( head, begin, end, - lineNumber, MAT ) {} + /* constructor */ + #include "ENDFtk/section/8/454/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return whether or not the fission yields are energy dependent + * or not + */ + bool LE() const { return this->data_.size() == 1; } + + /** + * @brief Return whether or not the fission yield data is energy independent + */ + bool isEnergyIndependent() const { return this->LE(); } + + /** + * @brief Return the fission yield data, one for each incident energy + */ + auto yields() const { return ranges::cpp20::views::all( this->data_ ); } + + /** + * @brief Return the number of incident energy values + */ + long NE() const { return this->data_.size(); } /** - * @brief Return the MF number of the section + * @brief Return the incident energy values */ - static constexpr int fileNumber(){ return 8; } + auto E() const { + + return this->yields() + | ranges::cpp20::views::transform( [] ( const auto& entry ) + { return entry.E(); } ); + } + + /** + * @brief Return the incident energy values + */ + auto incidentEnergies() const { return this->E(); } + + #include "ENDFtk/section/8/454/src/NC.hpp" + #include "ENDFtk/section/8/454/src/print.hpp" /** * @brief Return the MT number of the section */ - static constexpr int sectionNumber(){ return 454; } + static constexpr int sectionNumber() { return 454; } - using NotImplementedYet::MF; - using NotImplementedYet::MT; - using NotImplementedYet::print; + using BaseWithoutMT::MT; + using BaseWithoutMT::ZA; + using BaseWithoutMT::atomicWeightRatio; + using BaseWithoutMT::AWR; }; } // section namespace diff --git a/src/ENDFtk/section/8/454/src/NC.hpp b/src/ENDFtk/section/8/454/src/NC.hpp new file mode 100644 index 000000000..9a21aa462 --- /dev/null +++ b/src/ENDFtk/section/8/454/src/NC.hpp @@ -0,0 +1,9 @@ +/** + * @brief Return the number of lines in this MF7/MT2 section + */ +long NC() const { + + long NC = 1; + for ( const auto& entry : this->data_ ) { NC += entry.NC(); } + return NC; +}; diff --git a/src/ENDFtk/section/8/454/src/ctor.hpp b/src/ENDFtk/section/8/454/src/ctor.hpp new file mode 100644 index 000000000..1e87ad595 --- /dev/null +++ b/src/ENDFtk/section/8/454/src/ctor.hpp @@ -0,0 +1,92 @@ +/** + * @brief Constructor + * + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] yields the fission yield data + */ +Type( double zaid, double awr, std::vector< FissionYieldData >&& yields ) : + BaseWithoutMT( zaid, awr ), + data_( std::move( yields ) ) {} + +/** + * @brief Constructor for energy independent yields + * + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] identifiers the fission product identifiers (NFP values) + * @param[in] states the isomeric states (NFP values) + * @param[in] yields the fission yield values and uncertainties + * (NFP pairs) + */ +Type( double zaid, double awr, + std::vector< unsigned int >&& identifiers, + std::vector< unsigned int >&& states, + std::vector< std::array< double, 2 > >&& yields ) + try : Type( zaid, awr, + std::vector< FissionYieldData >{ + FissionYieldData( std::move( identifiers ), std::move( states ), + std::move( yields ) ) } ) {} + catch ( std::exception& e ) { + + Log::info( "Trouble while constructing section 454 of File 8" ); + throw; + } + +/** + * @brief Constructor for energy dependent yields where each energy has the + * same fission products + * + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] identifiers the fission product identifiers (NFP values) + * @param[in] states the isomeric states (NFP values) + * @param[in] energies the incident neutron energies (NE values) + * @param[in] interpolants the interpolation types (NE-1 values) + * @param[in] yields the fission yield values and uncertainties + * (NFP arrays of NE pairs) + */ +Type( double zaid, double awr, + std::vector< unsigned int >&& identifiers, + std::vector< unsigned int >&& states, + std::vector< double >&& energies, + std::vector< unsigned int >&& interpolants, + std::vector< std::vector< std::array< double, 2 > > >&& yields ) + try : Type( zaid, awr, + generateFissionYields( std::move( identifiers ), + std::move( states ), + std::move( energies ), + std::move( interpolants ), + std::move( yields ) ) ) {} + catch ( std::exception& e ) { + + Log::info( "Trouble while constructing section 454 of File 8" ); + throw; + } + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] head the head record of the section + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + */ +template< typename Iterator > +Type( HEAD& head, + Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT ) + try : Type( head.ZA(), head.AWR(), + readSequence< FissionYieldData >( begin, end, lineNumber, + MAT, 8, 454, head.L1() ) ) { + readSEND(begin, end, lineNumber, MAT, 8 ); + } catch ( std::exception& e ) { + Log::info( "Trouble while reading section 454 of File 8 of Material {}", + MAT ); + throw e; + } diff --git a/src/ENDFtk/section/8/454/src/generateFissionYields.hpp b/src/ENDFtk/section/8/454/src/generateFissionYields.hpp new file mode 100644 index 000000000..eb33aa32b --- /dev/null +++ b/src/ENDFtk/section/8/454/src/generateFissionYields.hpp @@ -0,0 +1,49 @@ +static std::vector< FissionYieldData > +generateFissionYields( std::vector< unsigned int >&& identifiers, + std::vector< unsigned int >&& states, + std::vector< double >&& energies, + std::vector< unsigned int >&& interpolants, + std::vector< std::vector< std::array< double, 2 > > >&& yields ) { + + unsigned int size = energies.size(); + std::vector< FissionYieldData > sequence; + sequence.reserve( size ); + + if ( size != interpolants.size() + 1 ) { + + Log::error( "Encountered inconsistent number of energy values and " + "interpolation flags" ); + Log::info( "Number of I values must be equal to NE - 1" ); + Log::info( "Number of I values: {}", interpolants.size() ); + Log::info( "NE value: {}", size ); + throw std::exception(); + } + + unsigned int nfp = identifiers.size(); + for ( unsigned int i = 0; i < nfp; ++i ) { + + if ( yields[i].size() != size ) { + + Log::info( "The number of fission yield values for the fission product " + "with index {} is not equal to the expected value", i ); + Log::info( "NE value: {}", size ); + Log::info( "yields[i].size(): {}", yields[i].size() ); + throw std::exception(); + } + } + + unsigned int i = 0; + while ( i++ < size ) { + + sequence.emplace_back( std::vector< unsigned int >( identifiers ), + std::vector< unsigned int >( states ), + ranges::to< std::vector< std::array< double, 2 > > >( + yields | ranges::cpp20::views::transform( + [i] ( const auto& range ) + { return range[i-1]; } ) ), + energies[i-1], + i - 1 == 0 ? energies.size() - 1 : interpolants[i-2] ); + } + + return sequence; +} diff --git a/src/ENDFtk/section/8/454/src/print.hpp b/src/ENDFtk/section/8/454/src/print.hpp new file mode 100644 index 000000000..fd1c5db7c --- /dev/null +++ b/src/ENDFtk/section/8/454/src/print.hpp @@ -0,0 +1,19 @@ +/** + * @brief Print the MF8/MT454 section (includes SEND record) + * + * @tparam OutputIterator an output iterator + * + * @param[in] it the current position in the output + * @param[in] MAT the MAT number + * @param[in] MF the MF number + */ +template< typename OutputIterator > +void print( OutputIterator& it, int MAT, int MF ) const { + + int MT = this->MT(); + ControlRecord( this->ZA(), this->AWR(), + this->data_.size() == 1 ? 1 : this->data_.size(), + 0, 0, 0 ).print( it, MAT, MF, MT ); + for ( const auto& entry : this->data_ ) { entry.print( it, MAT, MF, MT ); } + SEND( MAT, MF ).print( it ); +} diff --git a/src/ENDFtk/section/8/454/test/454.test.cpp b/src/ENDFtk/section/8/454/test/454.test.cpp new file mode 100644 index 000000000..aedddf14b --- /dev/null +++ b/src/ENDFtk/section/8/454/test/454.test.cpp @@ -0,0 +1,524 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/8/454.hpp" + +// other includes +#include "ENDFtk/tree/Section.hpp" + +// convenience typedefs +using namespace njoy::ENDFtk; +using FissionYieldData = section::FissionYieldData; + +// macros don't like multiple template arguments +using section8454 = section::Type< 8, 454 >; + +std::string chunk(); +void verifyChunk( const section::Type< 8, 454 >& ); +std::string chunkWithEnergyIndependentYields(); +void verifyChunkWithEnergyIndependentYields( const section::Type< 8, 454 >& ); +std::string validSEND(); +std::string invalidSEND(); + +SCENARIO( "section::Type< 8, 454 >" ) { + + GIVEN( "valid data for a section::Type< 8, 454 > for energy dependent yields" ) { + + std::string sectionString = chunk() + validSEND(); + + WHEN( "the data is given explicitly as arrays" ) { + + double zaid = 92235.; + double awr = 233.0250; + + std::vector< unsigned int > identifiers = { 23066, 54135, 72171 }; + std::vector< unsigned int > states = { 0, 0, 0 }; + + std::vector< double > energies = { 0.0253, 500e+3 }; + std::vector< unsigned int > interpolants = { 3 }; + + std::vector< std::vector< std::array< double, 2 > > > yields = { + + { {{ 2.05032e-19, 1.31220e-19 }}, {{ 4.48456e-18, 2.87012e-18 }} }, // 230660 + { {{ 7.851250e-4, 4.710750e-5 }}, {{ 1.196100e-3, 2.751030e-4 }} }, // 541350 + { {{ 0, 0 }}, {{ 0, 0 }} } // 721710 + }; + + section::Type< 8, 454 > chunk( zaid, awr, + std::move( identifiers ), + std::move( states ), + std::move( energies ), + std::move( interpolants ), + std::move( yields ) ); + + THEN( "a section::Type< 8, 454 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is given explicitly as a FissionYieldData array" ) { + + double zaid = 92235.; + double awr = 233.0250; + + std::vector< FissionYieldData > yields = { + + FissionYieldData( { 23066, 54135, 72171 }, { 0, 0, 0 }, + { {{ 2.05032e-19, 1.31220e-19 }}, + {{ 7.851250e-4, 4.710750e-5 }}, + {{ 0, 0 }} }, + 0.0253, 1 ), + FissionYieldData( { 23066, 54135, 72171 }, { 0, 0, 0 }, + { {{ 4.48456e-18, 2.87012e-18 }}, + {{ 1.196100e-3, 2.751030e-4 }}, + {{ 0, 0 }} }, + 500e+3, 3 ) }; + + section::Type< 8, 454 > chunk( zaid, awr, + std::move( yields ) ); + + THEN( "a section::Type< 8, 454 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 8, 454 > chunk( head, begin, end, lineNumber, 9228 ); + + THEN( "a section::Type< 8, 454 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } //WHEN + } // GIVEN + + GIVEN( "valid data for a section::Type< 8, 454 > for energy independent yields" ) { + + std::string sectionString = chunkWithEnergyIndependentYields() + validSEND(); + + WHEN( "the data is given explicitly using arrays" ) { + + double zaid = 92235.; + double awr = 233.0250; + + std::vector< unsigned int > identifiers = { 23066, 54135, 72171 }; + std::vector< unsigned int > states = { 0, 0, 0 }; + + std::vector< std::array< double, 2 > > yields = { + + {{ 2.05032e-19, 1.31220e-19 }}, + {{ 7.851250e-4, 4.710750e-5 }}, + {{ 0, 0 }} + }; + + section::Type< 8, 454 > chunk( zaid, awr, + std::move( identifiers ), + std::move( states ), + std::move( yields ) ); + + THEN( "a section::Type< 8, 454 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithEnergyIndependentYields( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 8, 454 > chunk( head, begin, end, lineNumber, 9228 ); + + THEN( "a section::Type< 8, 454 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithEnergyIndependentYields( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } //WHEN + + WHEN( "there is a tree::Section" ) { + + auto begin = sectionString.begin(); + auto position = begin; + auto end = sectionString.end(); + long lineNumber = 1; + auto head = HEAD( position, end, lineNumber ); + tree::Section< std::string::iterator > + section( head, begin, position, end, lineNumber ); + + section::Type< 8, 454 > chunk = section.parse< 8, 454 >( lineNumber ); + + THEN( "a section::Type< 8, 454 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithEnergyIndependentYields( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a section::Type< 8, 454 >" ) { + + WHEN( "a string representation of a valid section::Type< 8, 454 > with " + "an invalid SEND" ) { + + std::string sectionString = chunk() + invalidSEND(); + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( section8454( head, begin, end, lineNumber, 9228 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + + " 9.223500+4 2.330250+2 2 0 0 09228 8454 \n" + " 2.530000-2 0.000000+0 1 0 12 39228 8454 \n" + " 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8454 \n" + " 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n" + " 5.000000+5 0.000000+0 3 0 12 39228 8454 \n" + " 2.306600+4 0.000000+0 4.48456-18 2.87012-18 5.413500+4 0.000000+09228 8454 \n" + " 1.196100-3 2.751030-4 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n"; +} + +void verifyChunk( const section::Type< 8, 454 >& chunk ) { + + CHECK( 454 == chunk.MT() ); + CHECK( 454 == chunk.sectionNumber() ); + + CHECK( 92235. == Approx( chunk.ZA() ) ); + CHECK( 233.0250 == Approx( chunk.AWR() ) ); + CHECK( 233.0250 == Approx( chunk.atomicWeightRatio() ) ); + + CHECK( false == chunk.LE() ); + CHECK( false == chunk.isEnergyIndependent() ); + + CHECK( 2 == chunk.NE() ); + CHECK( 2 == chunk.E().size() ); + CHECK( 2 == chunk.incidentEnergies().size() ); + CHECK( 0.0253 == Approx( chunk.E()[0] ) ); + CHECK( 500e+3 == Approx( chunk.E()[1] ) ); + CHECK( 0.0253 == Approx( chunk.incidentEnergies()[0] ) ); + CHECK( 500e+3 == Approx( chunk.incidentEnergies()[1] ) ); + + CHECK( 2 == chunk.yields().size() ); + + auto data = chunk.yields()[0]; + CHECK( 1 == data.I() ); + CHECK( 1 == data.interpolationType() ); + CHECK( false == data.LE() ); + CHECK( false == data.isEnergyIndependent() ); + CHECK( 3 == data.NFP() ); + CHECK( 3 == data.numberFissionProducts() ); + CHECK( 0.0253 == Approx( data.E() ) ); + CHECK( 0.0253 == Approx( data.incidentEnergy() ) ); + + CHECK( 3 == data.fissionProducts().size() ); + CHECK( 23066 == data.fissionProducts()[0].ZAFP() ); + CHECK( 54135 == data.fissionProducts()[1].ZAFP() ); + CHECK( 72171 == data.fissionProducts()[2].ZAFP() ); + CHECK( 23066 == data.fissionProducts()[0].fissionProductIdentifier() ); + CHECK( 54135 == data.fissionProducts()[1].fissionProductIdentifier() ); + CHECK( 72171 == data.fissionProducts()[2].fissionProductIdentifier() ); + CHECK( 0 == data.fissionProducts()[0].FPS() ); + CHECK( 0 == data.fissionProducts()[1].FPS() ); + CHECK( 0 == data.fissionProducts()[2].FPS() ); + CHECK( 0 == data.fissionProducts()[0].isomericState() ); + CHECK( 0 == data.fissionProducts()[1].isomericState() ); + CHECK( 0 == data.fissionProducts()[2].isomericState() ); + CHECK( 2.05032e-19 == Approx( data.fissionProducts()[0].Y()[0] ) ); + CHECK( 1.31220e-19 == Approx( data.fissionProducts()[0].Y()[1] ) ); + CHECK( 7.851250e-4 == Approx( data.fissionProducts()[1].Y()[0] ) ); + CHECK( 4.710750e-5 == Approx( data.fissionProducts()[1].Y()[1] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[0] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[1] ) ); + + CHECK( 3 == data.ZAFP().size() ); + CHECK( 3 == data.fissionProductIdentifiers().size() ); + CHECK( 3 == data.FPS().size() ); + CHECK( 3 == data.isomericStates().size() ); + CHECK( 3 == data.Y().size() ); + CHECK( 3 == data.fissionYields().size() ); + CHECK( 23066 == data.ZAFP()[0] ); + CHECK( 54135 == data.ZAFP()[1] ); + CHECK( 72171 == data.ZAFP()[2] ); + CHECK( 23066 == data.fissionProductIdentifiers()[0] ); + CHECK( 54135 == data.fissionProductIdentifiers()[1] ); + CHECK( 72171 == data.fissionProductIdentifiers()[2] ); + CHECK( 0 == data.FPS()[0] ); + CHECK( 0 == data.FPS()[1] ); + CHECK( 0 == data.FPS()[2] ); + CHECK( 0 == data.isomericStates()[0] ); + CHECK( 0 == data.isomericStates()[1] ); + CHECK( 0 == data.isomericStates()[2] ); + CHECK( 2 == data.Y()[0].size() ); + CHECK( 2 == data.Y()[1].size() ); + CHECK( 2 == data.Y()[2].size() ); + CHECK( 2 == data.fissionYields()[0].size() ); + CHECK( 2 == data.fissionYields()[1].size() ); + CHECK( 2 == data.fissionYields()[2].size() ); + CHECK( 2.05032e-19 == Approx( data.Y()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( data.Y()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( data.Y()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( data.Y()[1][1] ) ); + CHECK( 0 == Approx( data.Y()[2][0] ) ); + CHECK( 0 == Approx( data.Y()[2][1] ) ); + CHECK( 2.05032e-19 == Approx( data.fissionYields()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( data.fissionYields()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( data.fissionYields()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( data.fissionYields()[1][1] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][0] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][1] ) ); + + data = chunk.yields()[1]; + CHECK( 3 == data.I() ); + CHECK( 3 == data.interpolationType() ); + CHECK( false == data.LE() ); + CHECK( false == data.isEnergyIndependent() ); + CHECK( 3 == data.NFP() ); + CHECK( 3 == data.numberFissionProducts() ); + CHECK( 500e+3 == Approx( data.E() ) ); + CHECK( 500e+3 == Approx( data.incidentEnergy() ) ); + + CHECK( 3 == data.fissionProducts().size() ); + CHECK( 23066 == data.fissionProducts()[0].ZAFP() ); + CHECK( 54135 == data.fissionProducts()[1].ZAFP() ); + CHECK( 72171 == data.fissionProducts()[2].ZAFP() ); + CHECK( 23066 == data.fissionProducts()[0].fissionProductIdentifier() ); + CHECK( 54135 == data.fissionProducts()[1].fissionProductIdentifier() ); + CHECK( 72171 == data.fissionProducts()[2].fissionProductIdentifier() ); + CHECK( 0 == data.fissionProducts()[0].FPS() ); + CHECK( 0 == data.fissionProducts()[1].FPS() ); + CHECK( 0 == data.fissionProducts()[2].FPS() ); + CHECK( 0 == data.fissionProducts()[0].isomericState() ); + CHECK( 0 == data.fissionProducts()[1].isomericState() ); + CHECK( 0 == data.fissionProducts()[2].isomericState() ); + CHECK( 4.48456e-18 == Approx( data.fissionProducts()[0].Y()[0] ) ); + CHECK( 2.87012e-18 == Approx( data.fissionProducts()[0].Y()[1] ) ); + CHECK( 1.196100e-3 == Approx( data.fissionProducts()[1].Y()[0] ) ); + CHECK( 2.751030e-4 == Approx( data.fissionProducts()[1].Y()[1] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[0] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[1] ) ); + + CHECK( 3 == data.ZAFP().size() ); + CHECK( 3 == data.fissionProductIdentifiers().size() ); + CHECK( 3 == data.FPS().size() ); + CHECK( 3 == data.isomericStates().size() ); + CHECK( 3 == data.Y().size() ); + CHECK( 3 == data.fissionYields().size() ); + CHECK( 23066 == data.ZAFP()[0] ); + CHECK( 54135 == data.ZAFP()[1] ); + CHECK( 72171 == data.ZAFP()[2] ); + CHECK( 23066 == data.fissionProductIdentifiers()[0] ); + CHECK( 54135 == data.fissionProductIdentifiers()[1] ); + CHECK( 72171 == data.fissionProductIdentifiers()[2] ); + CHECK( 0 == data.FPS()[0] ); + CHECK( 0 == data.FPS()[1] ); + CHECK( 0 == data.FPS()[2] ); + CHECK( 0 == data.isomericStates()[0] ); + CHECK( 0 == data.isomericStates()[1] ); + CHECK( 0 == data.isomericStates()[2] ); + CHECK( 2 == data.Y()[0].size() ); + CHECK( 2 == data.Y()[1].size() ); + CHECK( 2 == data.Y()[2].size() ); + CHECK( 2 == data.fissionYields()[0].size() ); + CHECK( 2 == data.fissionYields()[1].size() ); + CHECK( 2 == data.fissionYields()[2].size() ); + CHECK( 4.48456e-18 == Approx( data.Y()[0][0] ) ); + CHECK( 2.87012e-18 == Approx( data.Y()[0][1] ) ); + CHECK( 1.196100e-3 == Approx( data.Y()[1][0] ) ); + CHECK( 2.751030e-4 == Approx( data.Y()[1][1] ) ); + CHECK( 0 == Approx( data.Y()[2][0] ) ); + CHECK( 0 == Approx( data.Y()[2][1] ) ); + CHECK( 4.48456e-18 == Approx( data.fissionYields()[0][0] ) ); + CHECK( 2.87012e-18 == Approx( data.fissionYields()[0][1] ) ); + CHECK( 1.196100e-3 == Approx( data.fissionYields()[1][0] ) ); + CHECK( 2.751030e-4 == Approx( data.fissionYields()[1][1] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][0] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][1] ) ); + + CHECK( 7 == chunk.NC() ); +} + +std::string chunkWithEnergyIndependentYields() { + return + + " 9.223500+4 2.330250+2 1 0 0 09228 8454 \n" + " 0.000000+0 0.000000+0 0 0 12 39228 8454 \n" + " 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8454 \n" + " 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n"; +} + +void verifyChunkWithEnergyIndependentYields( const section::Type< 8, 454 >& chunk ) { + + CHECK( 454 == chunk.MT() ); + CHECK( 454 == chunk.sectionNumber() ); + + CHECK( 92235. == Approx( chunk.ZA() ) ); + CHECK( 233.0250 == Approx( chunk.AWR() ) ); + CHECK( 233.0250 == Approx( chunk.atomicWeightRatio() ) ); + + CHECK( true == chunk.LE() ); + CHECK( true == chunk.isEnergyIndependent() ); + + CHECK( 1 == chunk.NE() ); + CHECK( 1 == chunk.E().size() ); + CHECK( 1 == chunk.incidentEnergies().size() ); + CHECK( 0. == Approx( chunk.E()[0] ) ); + CHECK( 0. == Approx( chunk.incidentEnergies()[0] ) ); + + CHECK( 1 == chunk.yields().size() ); + + auto data = chunk.yields()[0]; + CHECK( 0 == data.I() ); + CHECK( 0 == data.interpolationType() ); + CHECK( true == data.LE() ); + CHECK( true == data.isEnergyIndependent() ); + CHECK( 3 == data.NFP() ); + CHECK( 3 == data.numberFissionProducts() ); + CHECK( 0. == Approx( data.E() ) ); + CHECK( 0. == Approx( data.incidentEnergy() ) ); + + CHECK( 3 == data.fissionProducts().size() ); + CHECK( 23066 == data.fissionProducts()[0].ZAFP() ); + CHECK( 54135 == data.fissionProducts()[1].ZAFP() ); + CHECK( 72171 == data.fissionProducts()[2].ZAFP() ); + CHECK( 23066 == data.fissionProducts()[0].fissionProductIdentifier() ); + CHECK( 54135 == data.fissionProducts()[1].fissionProductIdentifier() ); + CHECK( 72171 == data.fissionProducts()[2].fissionProductIdentifier() ); + CHECK( 0 == data.fissionProducts()[0].FPS() ); + CHECK( 0 == data.fissionProducts()[1].FPS() ); + CHECK( 0 == data.fissionProducts()[2].FPS() ); + CHECK( 0 == data.fissionProducts()[0].isomericState() ); + CHECK( 0 == data.fissionProducts()[1].isomericState() ); + CHECK( 0 == data.fissionProducts()[2].isomericState() ); + CHECK( 2.05032e-19 == Approx( data.fissionProducts()[0].Y()[0] ) ); + CHECK( 1.31220e-19 == Approx( data.fissionProducts()[0].Y()[1] ) ); + CHECK( 7.851250e-4 == Approx( data.fissionProducts()[1].Y()[0] ) ); + CHECK( 4.710750e-5 == Approx( data.fissionProducts()[1].Y()[1] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[0] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[1] ) ); + + CHECK( 3 == data.ZAFP().size() ); + CHECK( 3 == data.fissionProductIdentifiers().size() ); + CHECK( 3 == data.FPS().size() ); + CHECK( 3 == data.isomericStates().size() ); + CHECK( 3 == data.Y().size() ); + CHECK( 3 == data.fissionYields().size() ); + CHECK( 23066 == data.ZAFP()[0] ); + CHECK( 54135 == data.ZAFP()[1] ); + CHECK( 72171 == data.ZAFP()[2] ); + CHECK( 23066 == data.fissionProductIdentifiers()[0] ); + CHECK( 54135 == data.fissionProductIdentifiers()[1] ); + CHECK( 72171 == data.fissionProductIdentifiers()[2] ); + CHECK( 0 == data.FPS()[0] ); + CHECK( 0 == data.FPS()[1] ); + CHECK( 0 == data.FPS()[2] ); + CHECK( 0 == data.isomericStates()[0] ); + CHECK( 0 == data.isomericStates()[1] ); + CHECK( 0 == data.isomericStates()[2] ); + CHECK( 2 == data.Y()[0].size() ); + CHECK( 2 == data.Y()[1].size() ); + CHECK( 2 == data.Y()[2].size() ); + CHECK( 2 == data.fissionYields()[0].size() ); + CHECK( 2 == data.fissionYields()[1].size() ); + CHECK( 2 == data.fissionYields()[2].size() ); + CHECK( 2.05032e-19 == Approx( data.Y()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( data.Y()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( data.Y()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( data.Y()[1][1] ) ); + CHECK( 0 == Approx( data.Y()[2][0] ) ); + CHECK( 0 == Approx( data.Y()[2][1] ) ); + CHECK( 2.05032e-19 == Approx( data.fissionYields()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( data.fissionYields()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( data.fissionYields()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( data.fissionYields()[1][1] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][0] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][1] ) ); + + CHECK( 4 == chunk.NC() ); +} + +std::string validSEND() { + return + " 9228 8 0 \n"; +} + +std::string invalidSEND() { + return + " 9228 8 4 \n"; +} diff --git a/src/ENDFtk/section/8/454/test/CMakeLists.txt b/src/ENDFtk/section/8/454/test/CMakeLists.txt new file mode 100644 index 000000000..b6afcbe70 --- /dev/null +++ b/src/ENDFtk/section/8/454/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.8.454.test 454.test.cpp ) +target_compile_options( ENDFtk.section.8.454.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.8.454.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.8.454 COMMAND ENDFtk.section.8.454.test ) diff --git a/src/ENDFtk/section/8/457.hpp b/src/ENDFtk/section/8/457.hpp index f6326e7ae..e5db8a8db 100644 --- a/src/ENDFtk/section/8/457.hpp +++ b/src/ENDFtk/section/8/457.hpp @@ -5,6 +5,7 @@ // other includes #include "range/v3/action/join.hpp" +#include "range/v3/range/conversion.hpp" #include "range/v3/view/chunk.hpp" #include "range/v3/view/join.hpp" #include "ENDFtk/ControlRecord.hpp" @@ -139,7 +140,7 @@ namespace section{ */ auto decaySpectra() const { - return ranges::view::all( this->spectra_ ); + return ranges::cpp20::views::all( this->spectra_ ); } #include "ENDFtk/section/8/457/src/NC.hpp" diff --git a/src/ENDFtk/section/8/457/AverageDecayEnergies.hpp b/src/ENDFtk/section/8/457/AverageDecayEnergies.hpp index 25b7676dc..4ccf1ed32 100644 --- a/src/ENDFtk/section/8/457/AverageDecayEnergies.hpp +++ b/src/ENDFtk/section/8/457/AverageDecayEnergies.hpp @@ -55,7 +55,7 @@ class AverageDecayEnergies : protected ListRecord { */ auto E() const { - return ListRecord::list() | ranges::view::chunk( 2 ); + return ListRecord::list() | ranges::views::chunk( 2 ); } /** diff --git a/src/ENDFtk/section/8/457/AverageDecayEnergies/src/generateList.hpp b/src/ENDFtk/section/8/457/AverageDecayEnergies/src/generateList.hpp index 3b50d9bcf..61de9f2f3 100644 --- a/src/ENDFtk/section/8/457/AverageDecayEnergies/src/generateList.hpp +++ b/src/ENDFtk/section/8/457/AverageDecayEnergies/src/generateList.hpp @@ -1,5 +1,6 @@ static std::vector< double > generateList( std::vector< std::array< double, 2 > >&& energies ) { - return energies | ranges::view::join; + return ranges::to< std::vector< double > >( + ranges::cpp20::views::join( energies ) ); } diff --git a/src/ENDFtk/section/8/457/ContinuousSpectrum.hpp b/src/ENDFtk/section/8/457/ContinuousSpectrum.hpp index 234db2ea0..e2e11eee8 100644 --- a/src/ENDFtk/section/8/457/ContinuousSpectrum.hpp +++ b/src/ENDFtk/section/8/457/ContinuousSpectrum.hpp @@ -30,22 +30,22 @@ class ContinuousSpectrum : protected TabulationRecord { /** * @brief Return the energy values */ - auto E() const { return TabulationRecord::x(); } + AllRange< double > E() const { return TabulationRecord::x(); } /** * @brief Return the energy values */ - auto energies() const { return this->E(); } + AllRange< double > energies() const { return this->E(); } /** * @brief Return the spectral values */ - auto RP() const { return TabulationRecord::y(); } + AllRange< double > RP() const { return TabulationRecord::y(); } /** * @brief Return the spectral values */ - auto spectralValues() const { return this->RP(); } + AllRange< double > spectralValues() const { return this->RP(); } using TabulationRecord::NP; using TabulationRecord::NR; diff --git a/src/ENDFtk/section/8/457/DecayMode.hpp b/src/ENDFtk/section/8/457/DecayMode.hpp index e3691ae9d..9e6556e2d 100644 --- a/src/ENDFtk/section/8/457/DecayMode.hpp +++ b/src/ENDFtk/section/8/457/DecayMode.hpp @@ -28,27 +28,27 @@ class DecayMode { /** * @brief Return the decay chain */ - auto RTYP() const { return this->rtyp_; } + double RTYP() const { return this->rtyp_; } /** * @brief Return the decay chain */ - auto decayChain() const { return this->RTYP(); } + double decayChain() const { return this->RTYP(); } /** * @brief Return the final isomeric state */ - auto RFS() const { return this->rfs_; } + double RFS() const { return this->rfs_; } /** * @brief Return the final isomeric state */ - auto finalIsomericState() const { return this->RFS(); } + double finalIsomericState() const { return this->RFS(); } /** * @brief Return the Q value and its uncertainty */ - auto Q() const { return ranges::view::all( this->q_ ); } + auto Q() const { return ranges::cpp20::views::all( this->q_ ); } /** * @brief Return the Q value and its uncertainty @@ -58,7 +58,7 @@ class DecayMode { /** * @brief Return the branching ratio and its uncertainty */ - auto BR() const { return ranges::view::all( this->branch_ ); } + auto BR() const { return ranges::cpp20::views::all( this->branch_ ); } /** * @brief Return the branching ratio and its uncertainty diff --git a/src/ENDFtk/section/8/457/DecayModes.hpp b/src/ENDFtk/section/8/457/DecayModes.hpp index 605d6c70c..c61f0c2c5 100644 --- a/src/ENDFtk/section/8/457/DecayModes.hpp +++ b/src/ENDFtk/section/8/457/DecayModes.hpp @@ -25,22 +25,22 @@ class DecayModes : protected ListRecord { /** * @brief Return the spin of the target */ - auto SPI() const { return ListRecord::C1(); } + double SPI() const { return ListRecord::C1(); } /** * @brief Return the spin of the target */ - auto spin() const { return this->SPI(); } + double spin() const { return this->SPI(); } /** * @brief Return the parity of the target */ - auto PAR() const { return ListRecord::C2(); } + double PAR() const { return ListRecord::C2(); } /** * @brief Return the parity of the target */ - auto parity() const { return this->PAR(); } + double parity() const { return this->PAR(); } /** * @brief Return the number of decay modes NDK @@ -56,9 +56,10 @@ class DecayModes : protected ListRecord { * @brief Return the decay mode information */ auto decayModes() const { + return ListRecord::list() - | ranges::view::chunk( 6 ) - | ranges::view::transform( + | ranges::views::chunk( 6 ) + | ranges::cpp20::views::transform( [] ( const auto& range ) { return DecayMode( range[0], range[1], range[2], range[3], range[4], range[5] ); } ); diff --git a/src/ENDFtk/section/8/457/DecayModes/src/generateList.hpp b/src/ENDFtk/section/8/457/DecayModes/src/generateList.hpp index c8a3c50c7..64196893a 100644 --- a/src/ENDFtk/section/8/457/DecayModes/src/generateList.hpp +++ b/src/ENDFtk/section/8/457/DecayModes/src/generateList.hpp @@ -1,14 +1,14 @@ static std::vector< double > generateList( std::vector< DecayMode >&& modes ) { - return modes - | ranges::view::transform( - [] ( const auto& mode ) -> std::array< double, 6 > - { auto q = mode.qValue(); - auto br = mode.branchingRatio(); - return {{ mode.decayChain(), - mode.finalIsomericState(), - q[0], q[1], - br[0], br[1] }}; } ) - | ranges::action::join; + return ranges::to< std::vector< double > >( + modes | ranges::cpp20::views::transform( + [] ( const auto& mode ) -> std::array< double, 6 > + { auto q = mode.qValue(); + auto br = mode.branchingRatio(); + return {{ mode.decayChain(), + mode.finalIsomericState(), + q[0], q[1], + br[0], br[1] }}; } ) + | ranges::actions::join ); } diff --git a/src/ENDFtk/section/8/457/DecaySpectrum.hpp b/src/ENDFtk/section/8/457/DecaySpectrum.hpp index 22b2cd1df..f60c7f522 100644 --- a/src/ENDFtk/section/8/457/DecaySpectrum.hpp +++ b/src/ENDFtk/section/8/457/DecaySpectrum.hpp @@ -9,9 +9,15 @@ */ class DecaySpectrum { +public: + + using OptionalContinuousSpectrum = std::optional< ContinuousSpectrum >; + +private: + ListRecord data_; std::vector< DiscreteSpectrum > discrete_; - std::optional< ContinuousSpectrum > continuous_; + OptionalContinuousSpectrum continuous_; /* auxiliary functions */ #include "ENDFtk/section/8/457/DecaySpectrum/src/verifyLCOV.hpp" @@ -112,15 +118,18 @@ class DecaySpectrum { /** * @brief Return the discrete spectra, if any are defined */ - auto discreteSpectra() const { + AllRange< DiscreteSpectrum > discreteSpectra() const { - return ranges::view::all( this->discrete_ ); + return ranges::cpp20::views::all( this->discrete_ ); } /** * @brief Return the continuous spectrum, if it is defined */ - const auto& continuousSpectrum() const { return this->continuous_; } + const OptionalContinuousSpectrum& continuousSpectrum() const { + + return this->continuous_; + } #include "ENDFtk/section/8/457/DecaySpectrum/src/NC.hpp" #include "ENDFtk/section/8/457/DecaySpectrum/src/print.hpp" diff --git a/src/ENDFtk/section/8/457/DiscreteSpectrum.hpp b/src/ENDFtk/section/8/457/DiscreteSpectrum.hpp index c24ec2aba..123fd231b 100644 --- a/src/ENDFtk/section/8/457/DiscreteSpectrum.hpp +++ b/src/ENDFtk/section/8/457/DiscreteSpectrum.hpp @@ -45,8 +45,10 @@ class DiscreteSpectrum : protected ListRecord { * @brief Return the discrete energy value and uncertainty */ auto ER() const { + return std::array< double, 2 >( {{ ListRecord::C1(), - ListRecord::C2() }} ); } + ListRecord::C2() }} ); + } /** * @brief Return the discrete energy value and uncertainty diff --git a/src/ENDFtk/section/8/459.hpp b/src/ENDFtk/section/8/459.hpp index bfeaabaaa..ff89a0f1d 100644 --- a/src/ENDFtk/section/8/459.hpp +++ b/src/ENDFtk/section/8/459.hpp @@ -4,43 +4,85 @@ // system includes // other includes +#include "range/v3/range/conversion.hpp" +#include "ENDFtk/ControlRecord.hpp" +#include "ENDFtk/readSequence.hpp" #include "ENDFtk/section.hpp" +#include "ENDFtk/section/8/FissionYieldData.hpp" namespace njoy { namespace ENDFtk { namespace section { - /** - * @class - * @brief MF8 MT459 - unimplemented - */ template<> - class Type< 8, 459 > : protected NotImplementedYet< Type< 8, 459 > > { + class Type< 8, 459 > : protected BaseWithoutMT< Type< 8, 459 > > { - friend NotImplementedYet< Type< 8, 459 > >; + friend BaseWithoutMT< Type< 8, 459 > >; + + /* fields */ + std::vector< FissionYieldData > data_; + + /* auxiliary functions */ + #include "ENDFtk/section/8/454/src/generateFissionYields.hpp" // taken from 454 public: - Type() : NotImplementedYet() {} - template< typename Iterator > - Type( HEAD& head, Iterator& begin, const Iterator& end, - long& lineNumber, int MAT ) : - NotImplementedYet( head, begin, end, - lineNumber, MAT ) {} + /* constructor */ + #include "ENDFtk/section/8/459/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return whether or not the fission yields are energy dependent + * or not + */ + bool LE() const { return this->data_.size() == 1; } /** - * @brief Return the MF number of the section + * @brief Return whether or not the fission yield data is energy independent */ - static constexpr int fileNumber(){ return 8; } + bool isEnergyIndependent() const { return this->LE(); } + + /** + * @brief Return the fission yield data, one for each incident energy + */ + AllRange< FissionYieldData > yields() const { + + return ranges::cpp20::views::all( this->data_ ); + } + + /** + * @brief Return the number of incident energy values + */ + long NE() const { return this->data_.size(); } + + /** + * @brief Return the incident energy values + */ + auto E() const { + + return this->yields() + | ranges::cpp20::views::transform( [] ( const auto& entry ) + { return entry.E(); } ); + } + + /** + * @brief Return the incident energy values + */ + auto incidentEnergies() const { return this->E(); } + + #include "ENDFtk/section/8/459/src/NC.hpp" + #include "ENDFtk/section/8/459/src/print.hpp" /** * @brief Return the MT number of the section */ - static constexpr int sectionNumber(){ return 459; } + static constexpr int sectionNumber() { return 459; } - using NotImplementedYet::MF; - using NotImplementedYet::MT; - using NotImplementedYet::print; + using BaseWithoutMT::MT; + using BaseWithoutMT::ZA; + using BaseWithoutMT::atomicWeightRatio; + using BaseWithoutMT::AWR; }; } // section namespace diff --git a/src/ENDFtk/section/8/459/src/NC.hpp b/src/ENDFtk/section/8/459/src/NC.hpp new file mode 100644 index 000000000..9a21aa462 --- /dev/null +++ b/src/ENDFtk/section/8/459/src/NC.hpp @@ -0,0 +1,9 @@ +/** + * @brief Return the number of lines in this MF7/MT2 section + */ +long NC() const { + + long NC = 1; + for ( const auto& entry : this->data_ ) { NC += entry.NC(); } + return NC; +}; diff --git a/src/ENDFtk/section/8/459/src/ctor.hpp b/src/ENDFtk/section/8/459/src/ctor.hpp new file mode 100644 index 000000000..a40f7808e --- /dev/null +++ b/src/ENDFtk/section/8/459/src/ctor.hpp @@ -0,0 +1,92 @@ +/** + * @brief Constructor + * + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] yields the fission yield data + */ +Type( double zaid, double awr, std::vector< FissionYieldData >&& yields ) : + BaseWithoutMT( zaid, awr ), + data_( std::move( yields ) ) {} + +/** + * @brief Constructor for energy independent yields + * + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] identifiers the fission product identifiers (NFP values) + * @param[in] states the isomeric states (NFP values) + * @param[in] yields the fission yield values and uncertainties + * (NFP pairs) + */ +Type( double zaid, double awr, + std::vector< unsigned int >&& identifiers, + std::vector< unsigned int >&& states, + std::vector< std::array< double, 2 > >&& yields ) + try : Type( zaid, awr, + std::vector< FissionYieldData >{ + FissionYieldData( std::move( identifiers ), std::move( states ), + std::move( yields ) ) } ) {} + catch ( std::exception& e ) { + + Log::info( "Trouble while constructing section 459 of File 8" ); + throw; + } + +/** + * @brief Constructor for energy dependent yields where each energy has the + * same fission products + * + * @param[in] zaid the material ZAID value + * @param[in] awr the atomic weight ratio + * @param[in] identifiers the fission product identifiers (NFP values) + * @param[in] states the isomeric states (NFP values) + * @param[in] energies the incident neutron energies (NE values) + * @param[in] interpolants the interpolation types (NE-1 values) + * @param[in] yields the fission yield values and uncertainties + * (NFP arrays of NE pairs) + */ +Type( double zaid, double awr, + std::vector< unsigned int >&& identifiers, + std::vector< unsigned int >&& states, + std::vector< double >&& energies, + std::vector< unsigned int >&& interpolants, + std::vector< std::vector< std::array< double, 2 > > >&& yields ) + try : Type( zaid, awr, + generateFissionYields( std::move( identifiers ), + std::move( states ), + std::move( energies ), + std::move( interpolants ), + std::move( yields ) ) ) {} + catch ( std::exception& e ) { + + Log::info( "Trouble while constructing section 459 of File 8" ); + throw; + } + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] head the head record of the section + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + */ +template< typename Iterator > +Type( HEAD& head, + Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT ) + try : Type( head.ZA(), head.AWR(), + readSequence< FissionYieldData >( begin, end, lineNumber, + MAT, 8, 459, head.L1() ) ) { + readSEND(begin, end, lineNumber, MAT, 8 ); + } catch ( std::exception& e ) { + Log::info( "Trouble while reading section 459 of File 8 of Material {}", + MAT ); + throw e; + } diff --git a/src/ENDFtk/section/8/459/src/print.hpp b/src/ENDFtk/section/8/459/src/print.hpp new file mode 100644 index 000000000..50aa6dfa7 --- /dev/null +++ b/src/ENDFtk/section/8/459/src/print.hpp @@ -0,0 +1,19 @@ +/** + * @brief Print the MF8/MT459 section (includes SEND record) + * + * @tparam OutputIterator an output iterator + * + * @param[in] it the current position in the output + * @param[in] MAT the MAT number + * @param[in] MF the MF number + */ +template< typename OutputIterator > +void print( OutputIterator& it, int MAT, int MF ) const { + + int MT = this->MT(); + ControlRecord( this->ZA(), this->AWR(), + this->data_.size() == 1 ? 1 : this->data_.size(), + 0, 0, 0 ).print( it, MAT, MF, MT ); + for ( const auto& entry : this->data_ ) { entry.print( it, MAT, MF, MT ); } + SEND( MAT, MF ).print( it ); +} diff --git a/src/ENDFtk/section/8/459/test/459.test.cpp b/src/ENDFtk/section/8/459/test/459.test.cpp new file mode 100644 index 000000000..0db079cca --- /dev/null +++ b/src/ENDFtk/section/8/459/test/459.test.cpp @@ -0,0 +1,524 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/8/459.hpp" + +// other includes +#include "ENDFtk/tree/Section.hpp" + +// convenience typedefs +using namespace njoy::ENDFtk; +using FissionYieldData = section::FissionYieldData; + +// macros don't like multiple template arguments +using section8459 = section::Type< 8, 459 >; + +std::string chunk(); +void verifyChunk( const section::Type< 8, 459 >& ); +std::string chunkWithEnergyIndependentYields(); +void verifyChunkWithEnergyIndependentYields( const section::Type< 8, 459 >& ); +std::string validSEND(); +std::string invalidSEND(); + +SCENARIO( "section::Type< 8, 459 >" ) { + + GIVEN( "valid data for a section::Type< 8, 459 > for energy dependent yields" ) { + + std::string sectionString = chunk() + validSEND(); + + WHEN( "the data is given explicitly as arrays" ) { + + double zaid = 92235.; + double awr = 233.0250; + + std::vector< unsigned int > identifiers = { 23066, 54135, 72171 }; + std::vector< unsigned int > states = { 0, 0, 0 }; + + std::vector< double > energies = { 0.0253, 500e+3 }; + std::vector< unsigned int > interpolants = { 3 }; + + std::vector< std::vector< std::array< double, 2 > > > yields = { + + { {{ 2.05032e-19, 1.31220e-19 }}, {{ 4.48456e-18, 2.87012e-18 }} }, // 230660 + { {{ 7.851250e-4, 4.710750e-5 }}, {{ 1.196100e-3, 2.751030e-4 }} }, // 541350 + { {{ 0, 0 }}, {{ 0, 0 }} } // 721710 + }; + + section::Type< 8, 459 > chunk( zaid, awr, + std::move( identifiers ), + std::move( states ), + std::move( energies ), + std::move( interpolants ), + std::move( yields ) ); + + THEN( "a section::Type< 8, 459 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is given explicitly as a FissionYieldData array" ) { + + double zaid = 92235.; + double awr = 233.0250; + + std::vector< FissionYieldData > yields = { + + FissionYieldData( { 23066, 54135, 72171 }, { 0, 0, 0 }, + { {{ 2.05032e-19, 1.31220e-19 }}, + {{ 7.851250e-4, 4.710750e-5 }}, + {{ 0, 0 }} }, + 0.0253, 1 ), + FissionYieldData( { 23066, 54135, 72171 }, { 0, 0, 0 }, + { {{ 4.48456e-18, 2.87012e-18 }}, + {{ 1.196100e-3, 2.751030e-4 }}, + {{ 0, 0 }} }, + 500e+3, 3 ) }; + + section::Type< 8, 459 > chunk( zaid, awr, + std::move( yields ) ); + + THEN( "a section::Type< 8, 459 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 8, 459 > chunk( head, begin, end, lineNumber, 9228 ); + + THEN( "a section::Type< 8, 459 > can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } //WHEN + } // GIVEN + + GIVEN( "valid data for a section::Type< 8, 459 > for energy independent yields" ) { + + std::string sectionString = chunkWithEnergyIndependentYields() + validSEND(); + + WHEN( "the data is given explicitly using arrays" ) { + + double zaid = 92235.; + double awr = 233.0250; + + std::vector< unsigned int > identifiers = { 23066, 54135, 72171 }; + std::vector< unsigned int > states = { 0, 0, 0 }; + + std::vector< std::array< double, 2 > > yields = { + + {{ 2.05032e-19, 1.31220e-19 }}, + {{ 7.851250e-4, 4.710750e-5 }}, + {{ 0, 0 }} + }; + + section::Type< 8, 459 > chunk( zaid, awr, + std::move( identifiers ), + std::move( states ), + std::move( yields ) ); + + THEN( "a section::Type< 8, 459 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithEnergyIndependentYields( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 8, 459 > chunk( head, begin, end, lineNumber, 9228 ); + + THEN( "a section::Type< 8, 459 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithEnergyIndependentYields( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } //WHEN + + WHEN( "there is a tree::Section" ) { + + auto begin = sectionString.begin(); + auto position = begin; + auto end = sectionString.end(); + long lineNumber = 1; + auto head = HEAD( position, end, lineNumber ); + tree::Section< std::string::iterator > + section( head, begin, position, end, lineNumber ); + + section::Type< 8, 459 > chunk = section.parse< 8, 459 >( lineNumber ); + + THEN( "a section::Type< 8, 459 > can be constructed and members can be " + "tested" ) { + + verifyChunkWithEnergyIndependentYields( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a section::Type< 8, 459 >" ) { + + WHEN( "a string representation of a valid section::Type< 8, 459 > with " + "an invalid SEND" ) { + + std::string sectionString = chunk() + invalidSEND(); + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( section8459( head, begin, end, lineNumber, 9228 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + + " 9.223500+4 2.330250+2 2 0 0 09228 8459 \n" + " 2.530000-2 0.000000+0 1 0 12 39228 8459 \n" + " 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8459 \n" + " 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8459 \n" + " 5.000000+5 0.000000+0 3 0 12 39228 8459 \n" + " 2.306600+4 0.000000+0 4.48456-18 2.87012-18 5.413500+4 0.000000+09228 8459 \n" + " 1.196100-3 2.751030-4 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8459 \n"; +} + +void verifyChunk( const section::Type< 8, 459 >& chunk ) { + + CHECK( 459 == chunk.MT() ); + CHECK( 459 == chunk.sectionNumber() ); + + CHECK( 92235. == Approx( chunk.ZA() ) ); + CHECK( 233.0250 == Approx( chunk.AWR() ) ); + CHECK( 233.0250 == Approx( chunk.atomicWeightRatio() ) ); + + CHECK( false == chunk.LE() ); + CHECK( false == chunk.isEnergyIndependent() ); + + CHECK( 2 == chunk.NE() ); + CHECK( 2 == chunk.E().size() ); + CHECK( 2 == chunk.incidentEnergies().size() ); + CHECK( 0.0253 == Approx( chunk.E()[0] ) ); + CHECK( 500e+3 == Approx( chunk.E()[1] ) ); + CHECK( 0.0253 == Approx( chunk.incidentEnergies()[0] ) ); + CHECK( 500e+3 == Approx( chunk.incidentEnergies()[1] ) ); + + CHECK( 2 == chunk.yields().size() ); + + auto data = chunk.yields()[0]; + CHECK( 1 == data.I() ); + CHECK( 1 == data.interpolationType() ); + CHECK( false == data.LE() ); + CHECK( false == data.isEnergyIndependent() ); + CHECK( 3 == data.NFP() ); + CHECK( 3 == data.numberFissionProducts() ); + CHECK( 0.0253 == Approx( data.E() ) ); + CHECK( 0.0253 == Approx( data.incidentEnergy() ) ); + + CHECK( 3 == data.fissionProducts().size() ); + CHECK( 23066 == data.fissionProducts()[0].ZAFP() ); + CHECK( 54135 == data.fissionProducts()[1].ZAFP() ); + CHECK( 72171 == data.fissionProducts()[2].ZAFP() ); + CHECK( 23066 == data.fissionProducts()[0].fissionProductIdentifier() ); + CHECK( 54135 == data.fissionProducts()[1].fissionProductIdentifier() ); + CHECK( 72171 == data.fissionProducts()[2].fissionProductIdentifier() ); + CHECK( 0 == data.fissionProducts()[0].FPS() ); + CHECK( 0 == data.fissionProducts()[1].FPS() ); + CHECK( 0 == data.fissionProducts()[2].FPS() ); + CHECK( 0 == data.fissionProducts()[0].isomericState() ); + CHECK( 0 == data.fissionProducts()[1].isomericState() ); + CHECK( 0 == data.fissionProducts()[2].isomericState() ); + CHECK( 2.05032e-19 == Approx( data.fissionProducts()[0].Y()[0] ) ); + CHECK( 1.31220e-19 == Approx( data.fissionProducts()[0].Y()[1] ) ); + CHECK( 7.851250e-4 == Approx( data.fissionProducts()[1].Y()[0] ) ); + CHECK( 4.710750e-5 == Approx( data.fissionProducts()[1].Y()[1] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[0] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[1] ) ); + + CHECK( 3 == data.ZAFP().size() ); + CHECK( 3 == data.fissionProductIdentifiers().size() ); + CHECK( 3 == data.FPS().size() ); + CHECK( 3 == data.isomericStates().size() ); + CHECK( 3 == data.Y().size() ); + CHECK( 3 == data.fissionYields().size() ); + CHECK( 23066 == data.ZAFP()[0] ); + CHECK( 54135 == data.ZAFP()[1] ); + CHECK( 72171 == data.ZAFP()[2] ); + CHECK( 23066 == data.fissionProductIdentifiers()[0] ); + CHECK( 54135 == data.fissionProductIdentifiers()[1] ); + CHECK( 72171 == data.fissionProductIdentifiers()[2] ); + CHECK( 0 == data.FPS()[0] ); + CHECK( 0 == data.FPS()[1] ); + CHECK( 0 == data.FPS()[2] ); + CHECK( 0 == data.isomericStates()[0] ); + CHECK( 0 == data.isomericStates()[1] ); + CHECK( 0 == data.isomericStates()[2] ); + CHECK( 2 == data.Y()[0].size() ); + CHECK( 2 == data.Y()[1].size() ); + CHECK( 2 == data.Y()[2].size() ); + CHECK( 2 == data.fissionYields()[0].size() ); + CHECK( 2 == data.fissionYields()[1].size() ); + CHECK( 2 == data.fissionYields()[2].size() ); + CHECK( 2.05032e-19 == Approx( data.Y()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( data.Y()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( data.Y()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( data.Y()[1][1] ) ); + CHECK( 0 == Approx( data.Y()[2][0] ) ); + CHECK( 0 == Approx( data.Y()[2][1] ) ); + CHECK( 2.05032e-19 == Approx( data.fissionYields()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( data.fissionYields()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( data.fissionYields()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( data.fissionYields()[1][1] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][0] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][1] ) ); + + data = chunk.yields()[1]; + CHECK( 3 == data.I() ); + CHECK( 3 == data.interpolationType() ); + CHECK( false == data.LE() ); + CHECK( false == data.isEnergyIndependent() ); + CHECK( 3 == data.NFP() ); + CHECK( 3 == data.numberFissionProducts() ); + CHECK( 500e+3 == Approx( data.E() ) ); + CHECK( 500e+3 == Approx( data.incidentEnergy() ) ); + + CHECK( 3 == data.fissionProducts().size() ); + CHECK( 23066 == data.fissionProducts()[0].ZAFP() ); + CHECK( 54135 == data.fissionProducts()[1].ZAFP() ); + CHECK( 72171 == data.fissionProducts()[2].ZAFP() ); + CHECK( 23066 == data.fissionProducts()[0].fissionProductIdentifier() ); + CHECK( 54135 == data.fissionProducts()[1].fissionProductIdentifier() ); + CHECK( 72171 == data.fissionProducts()[2].fissionProductIdentifier() ); + CHECK( 0 == data.fissionProducts()[0].FPS() ); + CHECK( 0 == data.fissionProducts()[1].FPS() ); + CHECK( 0 == data.fissionProducts()[2].FPS() ); + CHECK( 0 == data.fissionProducts()[0].isomericState() ); + CHECK( 0 == data.fissionProducts()[1].isomericState() ); + CHECK( 0 == data.fissionProducts()[2].isomericState() ); + CHECK( 4.48456e-18 == Approx( data.fissionProducts()[0].Y()[0] ) ); + CHECK( 2.87012e-18 == Approx( data.fissionProducts()[0].Y()[1] ) ); + CHECK( 1.196100e-3 == Approx( data.fissionProducts()[1].Y()[0] ) ); + CHECK( 2.751030e-4 == Approx( data.fissionProducts()[1].Y()[1] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[0] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[1] ) ); + + CHECK( 3 == data.ZAFP().size() ); + CHECK( 3 == data.fissionProductIdentifiers().size() ); + CHECK( 3 == data.FPS().size() ); + CHECK( 3 == data.isomericStates().size() ); + CHECK( 3 == data.Y().size() ); + CHECK( 3 == data.fissionYields().size() ); + CHECK( 23066 == data.ZAFP()[0] ); + CHECK( 54135 == data.ZAFP()[1] ); + CHECK( 72171 == data.ZAFP()[2] ); + CHECK( 23066 == data.fissionProductIdentifiers()[0] ); + CHECK( 54135 == data.fissionProductIdentifiers()[1] ); + CHECK( 72171 == data.fissionProductIdentifiers()[2] ); + CHECK( 0 == data.FPS()[0] ); + CHECK( 0 == data.FPS()[1] ); + CHECK( 0 == data.FPS()[2] ); + CHECK( 0 == data.isomericStates()[0] ); + CHECK( 0 == data.isomericStates()[1] ); + CHECK( 0 == data.isomericStates()[2] ); + CHECK( 2 == data.Y()[0].size() ); + CHECK( 2 == data.Y()[1].size() ); + CHECK( 2 == data.Y()[2].size() ); + CHECK( 2 == data.fissionYields()[0].size() ); + CHECK( 2 == data.fissionYields()[1].size() ); + CHECK( 2 == data.fissionYields()[2].size() ); + CHECK( 4.48456e-18 == Approx( data.Y()[0][0] ) ); + CHECK( 2.87012e-18 == Approx( data.Y()[0][1] ) ); + CHECK( 1.196100e-3 == Approx( data.Y()[1][0] ) ); + CHECK( 2.751030e-4 == Approx( data.Y()[1][1] ) ); + CHECK( 0 == Approx( data.Y()[2][0] ) ); + CHECK( 0 == Approx( data.Y()[2][1] ) ); + CHECK( 4.48456e-18 == Approx( data.fissionYields()[0][0] ) ); + CHECK( 2.87012e-18 == Approx( data.fissionYields()[0][1] ) ); + CHECK( 1.196100e-3 == Approx( data.fissionYields()[1][0] ) ); + CHECK( 2.751030e-4 == Approx( data.fissionYields()[1][1] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][0] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][1] ) ); + + CHECK( 7 == chunk.NC() ); +} + +std::string chunkWithEnergyIndependentYields() { + return + + " 9.223500+4 2.330250+2 1 0 0 09228 8459 \n" + " 0.000000+0 0.000000+0 0 0 12 39228 8459 \n" + " 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8459 \n" + " 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8459 \n"; +} + +void verifyChunkWithEnergyIndependentYields( const section::Type< 8, 459 >& chunk ) { + + CHECK( 459 == chunk.MT() ); + CHECK( 459 == chunk.sectionNumber() ); + + CHECK( 92235. == Approx( chunk.ZA() ) ); + CHECK( 233.0250 == Approx( chunk.AWR() ) ); + CHECK( 233.0250 == Approx( chunk.atomicWeightRatio() ) ); + + CHECK( true == chunk.LE() ); + CHECK( true == chunk.isEnergyIndependent() ); + + CHECK( 1 == chunk.NE() ); + CHECK( 1 == chunk.E().size() ); + CHECK( 1 == chunk.incidentEnergies().size() ); + CHECK( 0. == Approx( chunk.E()[0] ) ); + CHECK( 0. == Approx( chunk.incidentEnergies()[0] ) ); + + CHECK( 1 == chunk.yields().size() ); + + auto data = chunk.yields()[0]; + CHECK( 0 == data.I() ); + CHECK( 0 == data.interpolationType() ); + CHECK( true == data.LE() ); + CHECK( true == data.isEnergyIndependent() ); + CHECK( 3 == data.NFP() ); + CHECK( 3 == data.numberFissionProducts() ); + CHECK( 0. == Approx( data.E() ) ); + CHECK( 0. == Approx( data.incidentEnergy() ) ); + + CHECK( 3 == data.fissionProducts().size() ); + CHECK( 23066 == data.fissionProducts()[0].ZAFP() ); + CHECK( 54135 == data.fissionProducts()[1].ZAFP() ); + CHECK( 72171 == data.fissionProducts()[2].ZAFP() ); + CHECK( 23066 == data.fissionProducts()[0].fissionProductIdentifier() ); + CHECK( 54135 == data.fissionProducts()[1].fissionProductIdentifier() ); + CHECK( 72171 == data.fissionProducts()[2].fissionProductIdentifier() ); + CHECK( 0 == data.fissionProducts()[0].FPS() ); + CHECK( 0 == data.fissionProducts()[1].FPS() ); + CHECK( 0 == data.fissionProducts()[2].FPS() ); + CHECK( 0 == data.fissionProducts()[0].isomericState() ); + CHECK( 0 == data.fissionProducts()[1].isomericState() ); + CHECK( 0 == data.fissionProducts()[2].isomericState() ); + CHECK( 2.05032e-19 == Approx( data.fissionProducts()[0].Y()[0] ) ); + CHECK( 1.31220e-19 == Approx( data.fissionProducts()[0].Y()[1] ) ); + CHECK( 7.851250e-4 == Approx( data.fissionProducts()[1].Y()[0] ) ); + CHECK( 4.710750e-5 == Approx( data.fissionProducts()[1].Y()[1] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[0] ) ); + CHECK( 0 == Approx( data.fissionProducts()[2].Y()[1] ) ); + + CHECK( 3 == data.ZAFP().size() ); + CHECK( 3 == data.fissionProductIdentifiers().size() ); + CHECK( 3 == data.FPS().size() ); + CHECK( 3 == data.isomericStates().size() ); + CHECK( 3 == data.Y().size() ); + CHECK( 3 == data.fissionYields().size() ); + CHECK( 23066 == data.ZAFP()[0] ); + CHECK( 54135 == data.ZAFP()[1] ); + CHECK( 72171 == data.ZAFP()[2] ); + CHECK( 23066 == data.fissionProductIdentifiers()[0] ); + CHECK( 54135 == data.fissionProductIdentifiers()[1] ); + CHECK( 72171 == data.fissionProductIdentifiers()[2] ); + CHECK( 0 == data.FPS()[0] ); + CHECK( 0 == data.FPS()[1] ); + CHECK( 0 == data.FPS()[2] ); + CHECK( 0 == data.isomericStates()[0] ); + CHECK( 0 == data.isomericStates()[1] ); + CHECK( 0 == data.isomericStates()[2] ); + CHECK( 2 == data.Y()[0].size() ); + CHECK( 2 == data.Y()[1].size() ); + CHECK( 2 == data.Y()[2].size() ); + CHECK( 2 == data.fissionYields()[0].size() ); + CHECK( 2 == data.fissionYields()[1].size() ); + CHECK( 2 == data.fissionYields()[2].size() ); + CHECK( 2.05032e-19 == Approx( data.Y()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( data.Y()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( data.Y()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( data.Y()[1][1] ) ); + CHECK( 0 == Approx( data.Y()[2][0] ) ); + CHECK( 0 == Approx( data.Y()[2][1] ) ); + CHECK( 2.05032e-19 == Approx( data.fissionYields()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( data.fissionYields()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( data.fissionYields()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( data.fissionYields()[1][1] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][0] ) ); + CHECK( 0 == Approx( data.fissionYields()[2][1] ) ); + + CHECK( 4 == chunk.NC() ); +} + +std::string validSEND() { + return + " 9228 8 0 \n"; +} + +std::string invalidSEND() { + return + " 9228 8 4 \n"; +} diff --git a/src/ENDFtk/section/8/459/test/CMakeLists.txt b/src/ENDFtk/section/8/459/test/CMakeLists.txt new file mode 100644 index 000000000..2a8861a9f --- /dev/null +++ b/src/ENDFtk/section/8/459/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.8.459.test 459.test.cpp ) +target_compile_options( ENDFtk.section.8.459.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.8.459.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.8.459 COMMAND ENDFtk.section.8.459.test ) diff --git a/src/ENDFtk/section/8/FissionYieldData.hpp b/src/ENDFtk/section/8/FissionYieldData.hpp new file mode 100644 index 000000000..edb3e2afb --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData.hpp @@ -0,0 +1,151 @@ +#ifndef NJOY_ENDFTK_SECTION_8_FISSIONYIELDDATA +#define NJOY_ENDFTK_SECTION_8_FISSIONYIELDDATA + +// system includes + +// other includes +#include "ENDFtk/ListRecord.hpp" +#include "range/v3/view/chunk.hpp" +#include "range/v3/view/drop_exactly.hpp" +#include "range/v3/view/stride.hpp" +#include "range/v3/view/transform.hpp" + +namespace njoy { +namespace ENDFtk { +namespace section{ + + /** + * @class + * @brief Fission yield data for a specific incident energy (or energy + * independent yields) + * + * This class is defined outside of any of the fission yield + * section::Type instances since this component is common to all of them. + * + * See ENDF102, section 8.3 for more information. + */ + class FissionYieldData : protected ListRecord { + + public: + + using Column = StrideRange< DropRange< AllRange< double > > >; + + private: + + /* auxiliary functions */ + #include "ENDFtk/section/8/FissionYieldData/src/verifySize.hpp" + #include "ENDFtk/section/8/FissionYieldData/src/generateList.hpp" + + Column column( unsigned int i ) const { + + return ListRecord::list() | ranges::views::drop_exactly( i ) + | ranges::views::stride( 4 ); + } + + public: + + #include "ENDFtk/section/8/FissionYieldData/FissionProduct.hpp" + + /* constructors */ + #include "ENDFtk/section/8/FissionYieldData/src/ctor.hpp" + + /* methods */ + + /** + * @brief Return the interpolation type (or LE value) + */ + int I() const { return ListRecord::L1(); } + + /** + * @brief Return the interpolation type (or LE value) + */ + int interpolationType() const { return this->I(); } + + /** + * @brief Return whether or not the fission yields are energy dependent + * or not + */ + bool LE() const { return this->I() == 0; } + + /** + * @brief Return whether or not the fission yield data is energy independent + */ + bool isEnergyIndependent() const { return this->LE(); } + + /** + * @brief Return the incident energy for which the fission yields are given + */ + double E() const { return ListRecord::C1(); } + + /** + * @brief Return the incident energy for which the fission yields are given + */ + double incidentEnergy() const { return this->E(); } + + /** + * @brief Return the number of fission products + */ + int NFP() const { return ListRecord::N2(); } + + /** + * @brief Return the number of fission products + */ + int numberFissionProducts() const { return this->NFP(); } + + /** + * @brief Return the fission product ZA identifiers + */ + Column ZAFP() const { return this->column( 0 ); } + + /** + * @brief Return the fission product ZA identifiers + */ + Column fissionProductIdentifiers() const { return this->ZAFP(); } + + /** + * @brief Return the fission product isomeric states + */ + Column FPS() const { return this->column( 1 ); } + + /** + * @brief Return the fission product isomeric states + */ + Column isomericStates() const { return this->FPS(); } + + /** + * @brief Return the fission yield values + */ + auto Y() const { + + return ListRecord::list() | ranges::views::drop_exactly( 2 ) + | ranges::views::chunk( 2 ) + | ranges::views::stride( 2 ); + } + + /** + * @brief Return the fission yield values and uncertainties + */ + auto fissionYields() const { return this->Y(); } + + /** + * @brief Return the fission products + */ + auto fissionProducts() const { + + using Chunk = decltype( ( ListRecord::list() + | ranges::views::chunk( 4 ) )[0] ); + return ListRecord::list() | ranges::views::chunk( 4 ) + | ranges::cpp20::views::transform( + [] ( Chunk&& chunk ) -> FissionProduct< Chunk > + { return { std::move( chunk ) }; } ); + } + + using ListRecord::NC; + using ListRecord::print; + }; + +} // section namespace +} // ENDFtk namespace +} // njoy namespace + +#endif diff --git a/src/ENDFtk/section/8/FissionYieldData/FissionProduct.hpp b/src/ENDFtk/section/8/FissionYieldData/FissionProduct.hpp new file mode 100644 index 000000000..5391148ba --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData/FissionProduct.hpp @@ -0,0 +1,50 @@ +/** + * @class + * @brief Convenience interface for fission yield data of a nuclide + * + * See ENDF102, section 8.3 for more information. + */ +template < typename Range > +class FissionProduct { + + /* fields */ + Range chunk; + +public: + + /* constructor */ + FissionProduct( Range&& chunk ) : chunk( std::move( chunk ) ) {} + + /** + * @brief Return the fission product ZA identifier + */ + unsigned int ZAFP() const { return this->chunk[0]; } + + /** + * @brief Return the fission product ZA identifier + */ + unsigned int fissionProductIdentifier() const { return this->ZAFP(); } + + /** + * @brief Return the fission product isomeric state + */ + unsigned int FPS() const { return this->chunk[1]; } + + /** + * @brief Return the fission product isomeric state + */ + unsigned int isomericState() const { return this->FPS(); } + + /** + * @brief Return the fission yield value and uncertainty + */ + std::array< double, 2 > Y() const { + + return {{ this->chunk[2], this->chunk[3] }}; + } + + /** + * @brief Return the fission yield value and uncertainty + */ + std::array< double, 2 > fissionYield() const { return this->Y(); } +}; diff --git a/src/ENDFtk/section/8/FissionYieldData/FissionProduct/test/CMakeLists.txt b/src/ENDFtk/section/8/FissionYieldData/FissionProduct/test/CMakeLists.txt new file mode 100644 index 000000000..78e2da637 --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData/FissionProduct/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.8.FissionProductData.FissionProduct.test FissionProduct.test.cpp ) +target_compile_options( ENDFtk.section.8.FissionProductData.FissionProduct.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.8.FissionProductData.FissionProduct.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.8.FissionProductData.FissionProduct COMMAND ENDFtk.section.8.FissionProductData.FissionProduct.test ) diff --git a/src/ENDFtk/section/8/FissionYieldData/FissionProduct/test/FissionProduct.test.cpp b/src/ENDFtk/section/8/FissionYieldData/FissionProduct/test/FissionProduct.test.cpp new file mode 100644 index 000000000..16d1efdeb --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData/FissionProduct/test/FissionProduct.test.cpp @@ -0,0 +1,41 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/8/FissionYieldData.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using FissionProduct = section::FissionYieldData::FissionProduct< std::vector< double > >; + +void verifyChunk( const FissionProduct& ); + +SCENARIO( "FissionProduct" ) { + + GIVEN( "valid data for a FissionProduct" ) { + + WHEN( "the data is given explicitly" ) { + + FissionProduct chunk( { 1001., 1., 1e-3, 1e-5 } ); + + THEN( "a FissionProduct can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +void verifyChunk( const FissionProduct& chunk ) { + + CHECK( 1001 == Approx( chunk.ZAFP() ) ); + CHECK( 1001 == Approx( chunk.fissionProductIdentifier() ) ); + CHECK( 1 == Approx( chunk.FPS() ) ); + CHECK( 1 == Approx( chunk.isomericState() ) ); + CHECK( 1e-3 == Approx( chunk.Y()[0] ) ); + CHECK( 1e-5 == Approx( chunk.Y()[1] ) ); + CHECK( 1e-3 == Approx( chunk.fissionYield()[0] ) ); + CHECK( 1e-5 == Approx( chunk.fissionYield()[1] ) ); +} diff --git a/src/ENDFtk/section/8/FissionYieldData/src/ctor.hpp b/src/ENDFtk/section/8/FissionYieldData/src/ctor.hpp new file mode 100644 index 000000000..cd0d1b64f --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData/src/ctor.hpp @@ -0,0 +1,61 @@ +private: + +/** + * @brief Private constructor + */ +FissionYieldData( ListRecord&& list ) : + ListRecord( std::move( list ) ) { + + verifySize( ListRecord::NPL(), this->NFP() ); +}; + +public: + +/** + * @brief Constructor + * + * @param[in] identifiers the fission product identifiers (ZA identifier) + * @param[in] states the isomeric state for each fission product + * @param[in] yields the fission yield values and uncertainties + * @param[in] energy the incident neutron energy (equal to zero for + * energy independent yields) + * @param[in] interpolation the interpolation type (equal to zero for + * energy independent yields) + */ +FissionYieldData( std::vector< unsigned int >&& identifiers, + std::vector< unsigned int >&& states, + std::vector< std::array< double, 2 > >&& yields, + double energy = 0.0, int interpolation = 0 ) + try : FissionYieldData( + ListRecord( energy, 0.0, + interpolation, 0, identifiers.size(), + generateList( std::move( identifiers ), + std::move( states ), + std::move( yields ) ) ) ) {} + catch ( std::exception& e ) { + + Log::info( "Encountered error while constructing fission yields" ); + throw; + } + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + * @param[in] MF the expected MF number + * @param[in] MT the expected MT number + */ +template< typename Iterator > +FissionYieldData( Iterator& begin, const Iterator& end, + long& lineNumber, int MAT, int MF, int MT ) + try : FissionYieldData( ListRecord( begin, end, lineNumber, MAT, MF, MT ) ) {} + catch ( std::exception& e ) { + + Log::info( "Encountered error while constructing fission yields" ); + throw; + } diff --git a/src/ENDFtk/section/8/FissionYieldData/src/generateList.hpp b/src/ENDFtk/section/8/FissionYieldData/src/generateList.hpp new file mode 100644 index 000000000..21d260a9b --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData/src/generateList.hpp @@ -0,0 +1,27 @@ +static std::vector< double > +generateList( std::vector< unsigned int >&& identifiers, + std::vector< unsigned int >&& states, + std::vector< std::array< double, 2 > >&& yields ) { + + unsigned int nfp = identifiers.size(); + if ( ( states.size() != nfp ) or ( yields.size() != nfp ) ) { + + Log::info( "The number of fission profucts and the fission product data " + "are not consistent" ); + Log::info( "NFP value: {}", nfp ); + Log::info( "identifiers.size(): {}", identifiers.size() ); + Log::info( "states.size(): {}", states.size() ); + Log::info( "yields.size(): {}", yields.size() ); + throw std::exception(); + } + + std::vector< double > list; + for ( unsigned int i = 0; i < nfp; ++i ) { + + list.push_back( identifiers[i] ); + list.push_back( states[i] ); + list.push_back( yields[i][0] ); + list.push_back( yields[i][1] ); + } + return list; +} diff --git a/src/ENDFtk/section/8/FissionYieldData/src/verifySize.hpp b/src/ENDFtk/section/8/FissionYieldData/src/verifySize.hpp new file mode 100644 index 000000000..371931fa1 --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData/src/verifySize.hpp @@ -0,0 +1,12 @@ +static void +verifySize( int NPL, int NFP ) { + + if ( NPL != NFP * 4 ) { + + Log::error( "Encountered illegal NPL and NFP values " ); + Log::info( "NPL must be equal to 4*NFP for fission yield data" ); + Log::info( "NPL value: {}", NPL ); + Log::info( "NFP value: {}", NFP ); + throw std::exception(); + } +} diff --git a/src/ENDFtk/section/8/FissionYieldData/test/CMakeLists.txt b/src/ENDFtk/section/8/FissionYieldData/test/CMakeLists.txt new file mode 100644 index 000000000..ee2ef3c20 --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.8.FissionYieldData.test FissionYieldData.test.cpp ) +target_compile_options( ENDFtk.section.8.FissionYieldData.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.8.FissionYieldData.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.8.FissionYieldData COMMAND ENDFtk.section.8.FissionYieldData.test ) diff --git a/src/ENDFtk/section/8/FissionYieldData/test/FissionYieldData.test.cpp b/src/ENDFtk/section/8/FissionYieldData/test/FissionYieldData.test.cpp new file mode 100644 index 000000000..2ad38da16 --- /dev/null +++ b/src/ENDFtk/section/8/FissionYieldData/test/FissionYieldData.test.cpp @@ -0,0 +1,177 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/8/FissionYieldData.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using FissionYieldData = section::FissionYieldData; + +std::string chunk(); +void verifyChunk( const FissionYieldData& ); +std::string invalidChunk(); + +SCENARIO( "FissionYieldData" ) { + + GIVEN( "valid data for a TabulatedMultiplicity" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double energy = 0.0253; + int interpolation = 2; + std::vector< unsigned int > identifiers = { 23066, 54135, 72171 }; + std::vector< unsigned int > states = { 0, 0, 0 }; + std::vector< std::array< double, 2 > > yields = { {{ 2.05032e-19, 1.31220e-19 }}, + {{ 7.851250e-4, 4.710750e-5 }}, + {{ 0., 0. }} }; + + FissionYieldData chunk( std::move( identifiers ), std::move( states ), + std::move( yields ), + energy, interpolation ); + + THEN( "an FissionYieldData can be constructed and members can be " + "tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8, 454 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + FissionYieldData chunk( begin, end, lineNumber, 9228, 8, 454 ); + + THEN( "a FissionYieldData can be constructed and members can be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9228, 8, 454 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a FissionYieldData" ) { + + WHEN( "a string representation with an error is given" ) { + + // NPL != 4*NFP + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( FissionYieldData( begin, end, lineNumber, 9228, 8, 454 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 2.530000-2 0.000000+0 2 0 12 39228 8454 \n" + " 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8454 \n" + " 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n"; +} + +void verifyChunk( const FissionYieldData& chunk ) { + + CHECK( 2 == chunk.I() ); + CHECK( 2 == chunk.interpolationType() ); + CHECK( false == chunk.LE() ); + CHECK( false == chunk.isEnergyIndependent() ); + CHECK( 3 == chunk.NFP() ); + CHECK( 3 == chunk.numberFissionProducts() ); + CHECK( 0.0253 == Approx( chunk.E() ) ); + CHECK( 0.0253 == Approx( chunk.incidentEnergy() ) ); + + CHECK( 3 == chunk.fissionProducts().size() ); + CHECK( 23066 == chunk.fissionProducts()[0].ZAFP() ); + CHECK( 54135 == chunk.fissionProducts()[1].ZAFP() ); + CHECK( 72171 == chunk.fissionProducts()[2].ZAFP() ); + CHECK( 23066 == chunk.fissionProducts()[0].fissionProductIdentifier() ); + CHECK( 54135 == chunk.fissionProducts()[1].fissionProductIdentifier() ); + CHECK( 72171 == chunk.fissionProducts()[2].fissionProductIdentifier() ); + CHECK( 0 == chunk.fissionProducts()[0].FPS() ); + CHECK( 0 == chunk.fissionProducts()[1].FPS() ); + CHECK( 0 == chunk.fissionProducts()[2].FPS() ); + CHECK( 0 == chunk.fissionProducts()[0].isomericState() ); + CHECK( 0 == chunk.fissionProducts()[1].isomericState() ); + CHECK( 0 == chunk.fissionProducts()[2].isomericState() ); + CHECK( 2.05032e-19 == Approx( chunk.fissionProducts()[0].Y()[0] ) ); + CHECK( 1.31220e-19 == Approx( chunk.fissionProducts()[0].Y()[1] ) ); + CHECK( 7.851250e-4 == Approx( chunk.fissionProducts()[1].Y()[0] ) ); + CHECK( 4.710750e-5 == Approx( chunk.fissionProducts()[1].Y()[1] ) ); + CHECK( 0 == Approx( chunk.fissionProducts()[2].Y()[0] ) ); + CHECK( 0 == Approx( chunk.fissionProducts()[2].Y()[1] ) ); + + CHECK( 3 == chunk.ZAFP().size() ); + CHECK( 3 == chunk.fissionProductIdentifiers().size() ); + CHECK( 3 == chunk.FPS().size() ); + CHECK( 3 == chunk.isomericStates().size() ); + CHECK( 3 == chunk.Y().size() ); + CHECK( 3 == chunk.fissionYields().size() ); + CHECK( 23066 == chunk.ZAFP()[0] ); + CHECK( 54135 == chunk.ZAFP()[1] ); + CHECK( 72171 == chunk.ZAFP()[2] ); + CHECK( 23066 == chunk.fissionProductIdentifiers()[0] ); + CHECK( 54135 == chunk.fissionProductIdentifiers()[1] ); + CHECK( 72171 == chunk.fissionProductIdentifiers()[2] ); + CHECK( 0 == chunk.FPS()[0] ); + CHECK( 0 == chunk.FPS()[1] ); + CHECK( 0 == chunk.FPS()[2] ); + CHECK( 0 == chunk.isomericStates()[0] ); + CHECK( 0 == chunk.isomericStates()[1] ); + CHECK( 0 == chunk.isomericStates()[2] ); + CHECK( 2 == chunk.Y()[0].size() ); + CHECK( 2 == chunk.Y()[1].size() ); + CHECK( 2 == chunk.Y()[2].size() ); + CHECK( 2 == chunk.fissionYields()[0].size() ); + CHECK( 2 == chunk.fissionYields()[1].size() ); + CHECK( 2 == chunk.fissionYields()[2].size() ); + CHECK( 2.05032e-19 == Approx( chunk.Y()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( chunk.Y()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( chunk.Y()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( chunk.Y()[1][1] ) ); + CHECK( 0 == Approx( chunk.Y()[2][0] ) ); + CHECK( 0 == Approx( chunk.Y()[2][1] ) ); + CHECK( 2.05032e-19 == Approx( chunk.fissionYields()[0][0] ) ); + CHECK( 1.31220e-19 == Approx( chunk.fissionYields()[0][1] ) ); + CHECK( 7.851250e-4 == Approx( chunk.fissionYields()[1][0] ) ); + CHECK( 4.710750e-5 == Approx( chunk.fissionYields()[1][1] ) ); + CHECK( 0 == Approx( chunk.fissionYields()[2][0] ) ); + CHECK( 0 == Approx( chunk.fissionYields()[2][1] ) ); + + CHECK( 3 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 2.530000-2 0.000000+0 2 0 16 39228 8454 \n" + " 2.306600+4 0.000000+0 2.05032-19 1.31220-19 5.413500+4 0.000000+09228 8454 \n" + " 7.851250-4 4.710750-5 7.217100+4 0.000000+0 0.000000+0 0.000000+09228 8454 \n"; +} diff --git a/src/ENDFtk/section/9.hpp b/src/ENDFtk/section/9.hpp new file mode 100644 index 000000000..a99a54ef4 --- /dev/null +++ b/src/ENDFtk/section/9.hpp @@ -0,0 +1,84 @@ +#ifndef NJOY_ENDFTK_SECTION_9 +#define NJOY_ENDFTK_SECTION_9 + +// system includes + +// other includes +#include "ENDFtk/ControlRecord.hpp" +#include "ENDFtk/TabulationRecord.hpp" +#include "ENDFtk/readSequence.hpp" +#include "ENDFtk/section.hpp" + +namespace njoy { +namespace ENDFtk { +namespace section{ + + /** + * @class + * @brief MF9 - multiplicities for radioactive nuclide production + * + * See ENDF102, section 9.2 for more information. + */ + template<> + class Type< 9 > : protected Base { + + public: + + #include "ENDFtk/section/9/ReactionProduct.hpp" + + private: + + /* fields */ + int lis_; + std::vector< ReactionProduct > products_; + + public: + + /* constructor */ + #include "ENDFtk/section/9/src/ctor.hpp" + + /* methods */ + + /** + * @brief Return the excited level number of the target + */ + int LIS() const { return this->lis_; } + + /** + * @brief Return the excited level number of the target + */ + int excitedLevel() const { return this->LIS(); } + + /** + * @brief Return the number of excited states for the reaction product + */ + int NS() const { return this->products_.size(); } + + /** + * @brief Return the number of excited states for the reaction product + */ + int numberReactionProducts() const { return this->NS(); } + + /** + * @brief Return the reaction product data + */ + AllRange< ReactionProduct > reactionProducts() const { + + return ranges::cpp20::views::all( this->products_ ); + } + + #include "ENDFtk/section/9/src/NC.hpp" + #include "ENDFtk/section/9/src/print.hpp" + + using Base::MT; + using Base::sectionNumber; + using Base::ZA; + using Base::atomicWeightRatio; + using Base::AWR; + }; + +} // section namespace +} // ENDFtk namespace +} // njoy namespace + +#endif diff --git a/src/ENDFtk/section/9/ReactionProduct.hpp b/src/ENDFtk/section/9/ReactionProduct.hpp new file mode 100644 index 000000000..086e70ae1 --- /dev/null +++ b/src/ENDFtk/section/9/ReactionProduct.hpp @@ -0,0 +1,87 @@ +/** + * @class + * @brief The reaction product data : Q values and multiplicities + * + * See ENDF102, section 9.2 for more information. + */ +class ReactionProduct : protected TabulationRecord { + + /* auxiliary functions */ + +public: + + /* constructor */ + #include "ENDFtk/section/9/ReactionProduct/src/ctor.hpp" + + /* get methods */ + + /** + * @brief Return the mass difference Q value + */ + double QM() const { return TabulationRecord::C1(); } + + /** + * @brief Return the mass difference Q value + */ + double massDifferenceQValue() const { return this->QM(); } + + /** + * @brief Return the reaction Q value + */ + double QI() const { return TabulationRecord::C2(); } + + /** + * @brief Return the reaction Q value + */ + double reactionQValue() const { return this->QI(); } + + /** + * @brief Return the ZA identifier for the product nucleus + */ + int IZAP() const { return TabulationRecord::L1(); } + + /** + * @brief Return the ZA identifier for the product nucleus + */ + int productIdentifier() const { return this->IZAP(); } + + /** + * @brief Return the excited level number of the product + */ + int LFS() const { return TabulationRecord::L2(); } + + /** + * @brief Return the excited level number of the product + */ + int excitedLevel() const { return this->LFS(); } + + /** + * @brief Return the incident energy values + */ + AllRange< double > E() const { return TabulationRecord::x(); } + + /** + * @brief Return the incident energy values + */ + AllRange< double > energies() const { return this->E(); } + + /** + * @brief Return the multiplicity values + */ + AllRange< double > Y() const { return TabulationRecord::y(); } + + /** + * @brief Return the multiplicity values + */ + AllRange< double > multiplicities() const { return this->Y(); } + + using TabulationRecord::NR; + using TabulationRecord::NP; + using TabulationRecord::interpolants; + using TabulationRecord::boundaries; + using TabulationRecord::x; + using TabulationRecord::y; + using TabulationRecord::regions; + using TabulationRecord::NC; + using TabulationRecord::print; +}; diff --git a/src/ENDFtk/section/9/ReactionProduct/src/ctor.hpp b/src/ENDFtk/section/9/ReactionProduct/src/ctor.hpp new file mode 100644 index 000000000..ab488fc80 --- /dev/null +++ b/src/ENDFtk/section/9/ReactionProduct/src/ctor.hpp @@ -0,0 +1,51 @@ +/** + * @brief Constructor + * + * @param[in] qm the mass difference Q value + * @param[in] qi the reaction Q value + * @param[in] izap the za identifier of the product + * @param[in] lfs the excited level number + * @param[in] boundaries the interpolation range boundaries + * @param[in] interpolants the interpolation types for each range + * @param[in] energies the energy values + * @param[in] multiplicities the multiplicities for every state + */ +ReactionProduct( double qm, double qi, long izap, long lfs, + std::vector< long >&& boundaries, + std::vector< long >&& interpolants, + std::vector< double >&& energies, + std::vector< double >&& multiplicities ) + try : TabulationRecord( qm, qi, izap, lfs, + std::move( boundaries ), + std::move( interpolants ), + std::move( energies ), + std::move( multiplicities ) ) {} + catch ( std::exception& e ) { + + Log::info( "Encountered error while constructing a radioactive reaction " + "product" ); + throw; + } + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + * @param[in] MF the expected MF number + * @param[in] MT the expected MT number + */ +template< typename Iterator > +ReactionProduct( Iterator& begin, const Iterator& end, + long& lineNumber, int MAT, int MF, int MT ) + try : TabulationRecord( begin, end, lineNumber, MAT, MF, MT ) {} + catch ( std::exception& e ) { + + Log::info( "Encountered error while constructing a radioactive reaction " + "product" ); + throw; + } diff --git a/src/ENDFtk/section/9/ReactionProduct/test/CMakeLists.txt b/src/ENDFtk/section/9/ReactionProduct/test/CMakeLists.txt new file mode 100644 index 000000000..7f86fe64f --- /dev/null +++ b/src/ENDFtk/section/9/ReactionProduct/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.9.ReactionProduct.test ReactionProduct.test.cpp ) +target_compile_options( ENDFtk.section.9.ReactionProduct.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.9.ReactionProduct.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.9.ReactionProduct COMMAND ENDFtk.section.9.ReactionProduct.test ) diff --git a/src/ENDFtk/section/9/ReactionProduct/test/ReactionProduct.test.cpp b/src/ENDFtk/section/9/ReactionProduct/test/ReactionProduct.test.cpp new file mode 100644 index 000000000..9d67f6d40 --- /dev/null +++ b/src/ENDFtk/section/9/ReactionProduct/test/ReactionProduct.test.cpp @@ -0,0 +1,171 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/9.hpp" + +// other includes + +// convenience typedefs +using namespace njoy::ENDFtk; +using ReactionProduct = section::Type< 9 >::ReactionProduct; + +std::string chunk(); +void verifyChunk( const ReactionProduct& ); +std::string invalidChunk(); + +SCENARIO( "ReactionProduct" ) { + + GIVEN( "valid data for a ReactionProduct" ) { + + std::string string = chunk(); + + WHEN( "the data is given explicitly" ) { + + double qm = 2.224648e+6; + double qi = 3.224648e+6; + long za = 95242; + long lfs = 2; + std::vector< long > boundaries = { 2 }; + std::vector< long > interpolants = { 5 }; + std::vector< double > x = { 1., 3. }; + std::vector< double > y = { 2., 4. }; + + ReactionProduct chunk( qm, qi, za, lfs, + std::move( boundaries ), + std::move( interpolants ), + std::move( x ), + std::move( y ) ); + + THEN( "a ReactionProduct can be constructed and members can be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9534, 9, 102 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream" ) { + + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + ReactionProduct chunk( begin, end, lineNumber, 9534, 9, 102 ); + + THEN( "a ReactionProduct can be constructed and members can be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9534, 9, 102 ); + + CHECK( buffer == string ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a ReactionProduct" ) { + + WHEN( "inconsistent data is used" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + double qm = 2.224648e+6; + double qi = 3.224648e+6; + long za = 95242; + long lfs = 2; + std::vector< long > boundaries = { 2 }; + std::vector< long > wrongInterpolants = { 5, 2 }; + std::vector< double > x = { 1., 3. }; + std::vector< double > y = { 2., 4. }; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( ReactionProduct( qm, qi, za, lfs, + std::move( boundaries ), + std::move( wrongInterpolants ), + std::move( x ), + std::move( y ) ) ); + } // THEN + } // WHEN + + WHEN( "a string representation with an error is given" ) { + + // no need to test every possibility (TAB1 takes care of tests) + + std::string string = invalidChunk(); + auto begin = string.begin(); + auto end = string.end(); + long lineNumber = 1; + + THEN( "an exception is thrown" ) { + + CHECK_THROWS( ReactionProduct( begin, end, lineNumber, 9534, 9, 102 ) ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +std::string chunk() { + return + " 2.224648+6 3.224648+6 95242 2 1 29534 9102 \n" + " 2 5 9534 9102 \n" + " 1.000000+0 2.000000+0 3.000000+0 4.000000+0 9534 9102 \n"; +} + +void verifyChunk( const ReactionProduct& chunk ) { + + CHECK( 2.224648e+6 == Approx( chunk.QM() ) ); + CHECK( 2.224648e+6 == Approx( chunk.massDifferenceQValue() ) ); + CHECK( 3.224648e+6 == Approx( chunk.QI() ) ); + CHECK( 3.224648e+6 == Approx( chunk.reactionQValue() ) ); + CHECK( 95242 == chunk.IZAP() ); + CHECK( 95242 == chunk.productIdentifier() ); + CHECK( 2 == chunk.LFS() ); + CHECK( 2 == chunk.excitedLevel() ); + + CHECK( 2 == chunk.NP() ); + CHECK( 1 == chunk.NR() ); + CHECK( 1 == chunk.interpolants().size() ); + CHECK( 1 == chunk.boundaries().size() ); + CHECK( 5 == chunk.interpolants()[0] ); + CHECK( 2 == chunk.boundaries()[0] ); + CHECK( 2 == chunk.E().size() ); + CHECK( 2 == chunk.energies().size() ); + CHECK( 2 == chunk.x().size() ); + CHECK( 2 == chunk.Y().size() ); + CHECK( 2 == chunk.multiplicities().size() ); + CHECK( 2 == chunk.y().size() ); + CHECK( 1. == Approx( chunk.E()[0] ) ); + CHECK( 3. == Approx( chunk.E()[1] ) ); + CHECK( 1. == Approx( chunk.energies()[0] ) ); + CHECK( 3. == Approx( chunk.energies()[1] ) ); + CHECK( 1. == Approx( chunk.x()[0] ) ); + CHECK( 3. == Approx( chunk.x()[1] ) ); + CHECK( 2. == Approx( chunk.Y()[0] ) ); + CHECK( 4. == Approx( chunk.Y()[1] ) ); + CHECK( 2. == Approx( chunk.multiplicities()[0] ) ); + CHECK( 4. == Approx( chunk.multiplicities()[1] ) ); + CHECK( 2. == Approx( chunk.y()[0] ) ); + CHECK( 4. == Approx( chunk.y()[1] ) ); + + CHECK( 3 == chunk.NC() ); +} + +std::string invalidChunk() { + return + " 2.224648+6 3.224648+6 95242 2 2 29534 9102 \n" + " 2 2 9534 9102 \n" + " 1.000000-5 8.579050+0 3.000000+7 1.487778+1 9534 9102 \n"; +} diff --git a/src/ENDFtk/section/9/src/NC.hpp b/src/ENDFtk/section/9/src/NC.hpp new file mode 100644 index 000000000..d34ec2b2c --- /dev/null +++ b/src/ENDFtk/section/9/src/NC.hpp @@ -0,0 +1,12 @@ +/** + * @brief Return the number of lines in this MF9 component + */ +long NC() const { + + long NC = 1; + for ( const auto& entry : this->products_ ) { + + NC += entry.NC(); + } + return NC; +}; diff --git a/src/ENDFtk/section/9/src/ctor.hpp b/src/ENDFtk/section/9/src/ctor.hpp new file mode 100644 index 000000000..42a24b599 --- /dev/null +++ b/src/ENDFtk/section/9/src/ctor.hpp @@ -0,0 +1,43 @@ +/** + * @brief Constructor + * + * @param[in] mt the MT number + * @param[in] zaid the ZA identifier + * @param[in] awr the atomic mass ratio + * @param[in] lis the target's excited level + * @param[in] products the reaction products (at least 1) + */ +Type( int mt, double zaid, double awr, long lis, + std::vector< ReactionProduct >&& products ) : + Base( zaid, awr, mt ), lis_( lis ), products_( std::move( products ) ) {} + +/** + * @brief Constructor (from a buffer) + * + * @tparam Iterator a buffer iterator + * + * @param[in] head the head record of the section + * @param[in] it the current position in the buffer + * @param[in] end the end of the buffer + * @param[in] lineNumber the current line number + * @param[in] MAT the expected MAT number + */ +template< typename Iterator > +Type ( HEAD& head, + Iterator& begin, + const Iterator& end, + long& lineNumber, + int MAT ) + try: Type( head.MT(), head.ZA(), head.AWR(), head.L1(), + readSequence< ReactionProduct >( begin, end, lineNumber, + MAT, 9, head.MT(), head.N1() ) ) { + + readSEND(begin, end, lineNumber, MAT, 9 ); + } + catch( std::exception& e ) { + + Log::info + ( "Encountered error while reading section {} of file 9 of material {}", + head.MT(), MAT ); + throw e; + } diff --git a/src/ENDFtk/section/9/src/print.hpp b/src/ENDFtk/section/9/src/print.hpp new file mode 100644 index 000000000..9965630a1 --- /dev/null +++ b/src/ENDFtk/section/9/src/print.hpp @@ -0,0 +1,22 @@ +/** + * @brief Print this MF9 component + * + * @tparam OutputIterator an output iterator + * + * @param[in] it the current position in the output + * @param[in] MAT the MAT number + * @param[in] MF the MF number + */ +template< typename OutputIterator > +void print( OutputIterator& it, int MAT, int MF ) const { + + int MT = this->MT(); + ControlRecord( this->ZA(), this->AWR(), + this->LIS(), 0, + this->products_.size(), 0 ).print( it, MAT, MF, MT ); + for ( const auto& entry : this->products_ ) { + + entry.print( it, MAT, MF, MT ); + } + SEND( MAT, MF ).print( it ); +} diff --git a/src/ENDFtk/section/9/test/9.test.cpp b/src/ENDFtk/section/9/test/9.test.cpp new file mode 100644 index 000000000..394bd484d --- /dev/null +++ b/src/ENDFtk/section/9/test/9.test.cpp @@ -0,0 +1,242 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" +#include "ENDFtk/section/9.hpp" + +// other includes +#include "ENDFtk/tree/Section.hpp" + +// convenience typedefs +using namespace njoy::ENDFtk; +using ReactionProduct = section::Type< 9 >::ReactionProduct; + +std::string chunk(); +void verifyChunk( const section::Type< 9 >& ); +std::string validSEND(); +std::string invalidSEND(); + +SCENARIO( "section::Type< 9 >" ) { + + GIVEN( "valid data for a section::Type< 9 >" ) { + + std::string sectionString = chunk() + validSEND(); + + WHEN( "the data is given explicitly" ) { + + int mt = 102; + int zaid = 95241; + int lis = 0; + double awr = 2.389860e+2; + + std::vector< ReactionProduct > multiplicities = { + + ReactionProduct( 5.537755e+6, 5.537755e+6, 95242, 0, + { 2 }, { 3 }, { 1e-5, 3e+7 }, { 0.9, 0.52 } ), + ReactionProduct( 5.537755e+6, 5.489125e+6, 95242, 2, + { 2 }, { 3 }, { 1e-5, 3e+7 }, { 0.1, 0.48 } ) }; + + section::Type< 9 > chunk( mt, zaid, awr, lis, + std::move( multiplicities ) ); + + THEN( "a section::Type< 9 > can be constructed and " + "members can be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9543, 9 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "the data is read from a string/stream with a valid SEND" ) { + + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 0; + HeadRecord head( begin, end, lineNumber ); + + section::Type< 9 > chunk( head, begin, end, lineNumber, 9543 ); + + THEN( "a section::Type< 9 > can be constructed and " + "members can be tested" ) { + + verifyChunk( chunk ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + auto output = std::back_inserter( buffer ); + chunk.print( output, 9543, 9 ); + + CHECK( buffer == sectionString ); + } // THEN + } // WHEN + + WHEN( "there is a tree::Section" ) { + + std::string sectionString = chunk() + validSEND(); + auto begin = sectionString.begin(); + auto position = begin; + auto end = sectionString.end(); + long lineNumber = 0; + auto head = HEAD( position, end, lineNumber ); + tree::Section< std::string::iterator > + section( head, begin, position, end, lineNumber ); + + section::Type< 9 > chunk = section.parse< 9 >(); + section::Type< 9 > chunk2 = section.parse< 9 >( lineNumber ); + section::Type< 9 > chunk3 = section.parse( 9_c ); + section::Type< 9 > chunk4 = section.parse( 9_c, lineNumber ); + + THEN( "a section::Type< 9 > can be constructed and " + "members can be tested" ) { + + verifyChunk( chunk ); + verifyChunk( chunk2 ); + verifyChunk( chunk3 ); + verifyChunk( chunk4 ); + } // THEN + + THEN( "it can be printed" ) { + + std::string buffer; + std::string buffer2; + std::string buffer3; + std::string buffer4; + auto output = std::back_inserter( buffer ); + auto output2 = std::back_inserter( buffer2 ); + auto output3 = std::back_inserter( buffer3 ); + auto output4 = std::back_inserter( buffer4 ); + chunk.print( output, 9543, 9 ); + chunk2.print( output2, 9543, 9 ); + chunk3.print( output3, 9543, 9 ); + chunk4.print( output4, 9543, 9 ); + + CHECK( buffer == sectionString ); + CHECK( buffer2 == sectionString ); + CHECK( buffer3 == sectionString ); + CHECK( buffer4 == sectionString ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "invalid data for a section::Type< 9 >" ) { + + WHEN( "a string representation of a section::Type< 9 > with " + "an invalid SEND" ) { + + std::string sectionString = chunk() + invalidSEND(); + auto begin = sectionString.begin(); + auto end = sectionString.end(); + long lineNumber = 1; + HeadRecord head( begin, end, lineNumber ); + + THEN( "an exception is thrown" ){ + + CHECK_THROWS( section::Type< 9 >( head, begin, end, + lineNumber, 9543 ) ); + } // THEN + } // WHEN + } // THEN +} // SCENARIO + +std::string chunk() { + + return + " 9.524100+4 2.389860+2 0 0 2 09543 9102 \n" + " 5.537755+6 5.537755+6 95242 0 1 29543 9102 \n" + " 2 3 9543 9102 \n" + " 1.000000-5 9.000000-1 3.000000+7 5.200000-1 9543 9102 \n" + " 5.537755+6 5.489125+6 95242 2 1 29543 9102 \n" + " 2 3 9543 9102 \n" + " 1.000000-5 1.000000-1 3.000000+7 4.800000-1 9543 9102 \n"; +} + +void verifyChunk( const section::Type< 9 >& chunk ) { + + CHECK( 102 == chunk.MT() ); + CHECK( 95241 == chunk.ZA() ); + CHECK( 2.389860e+2 == Approx( chunk.AWR() ) ); + CHECK( 2.389860e+2 == Approx( chunk.atomicWeightRatio() ) ); + CHECK( 0 == chunk.LIS() ); + CHECK( 0 == chunk.excitedLevel() ); + CHECK( 2 == chunk.NS() ); + CHECK( 2 == chunk.numberReactionProducts() ); + + CHECK( 2 == chunk.reactionProducts().size() ); + + auto product = chunk.reactionProducts()[0]; + CHECK( 5.537755e+6 == Approx( product.QM() ) ); + CHECK( 5.537755e+6 == Approx( product.massDifferenceQValue() ) ); + CHECK( 5.537755e+6 == Approx( product.QI() ) ); + CHECK( 5.537755e+6 == Approx( product.reactionQValue() ) ); + CHECK( 95242 == product.IZAP() ); + CHECK( 95242 == product.productIdentifier() ); + CHECK( 0 == product.LFS() ); + CHECK( 0 == product.excitedLevel() ); + CHECK( 2 == product.NP() ); + CHECK( 1 == product.NR() ); + CHECK( 1 == product.interpolants().size() ); + CHECK( 1 == product.boundaries().size() ); + CHECK( 3 == product.interpolants()[0] ); + CHECK( 2 == product.boundaries()[0] ); + CHECK( 2 == product.E().size() ); + CHECK( 2 == product.energies().size() ); + CHECK( 2 == product.Y().size() ); + CHECK( 2 == product.multiplicities().size() ); + CHECK( 1e-5 == Approx( product.E()[0] ) ); + CHECK( 3e+7 == Approx( product.E()[1] ) ); + CHECK( 1e-5 == Approx( product.energies()[0] ) ); + CHECK( 3e+7 == Approx( product.energies()[1] ) ); + CHECK( 0.9 == Approx( product.Y()[0] ) ); + CHECK( 0.52 == Approx( product.Y()[1] ) ); + CHECK( 0.9 == Approx( product.multiplicities()[0] ) ); + CHECK( 0.52 == Approx( product.multiplicities()[1] ) ); + + product = chunk.reactionProducts()[1]; + CHECK( 5.537755e+6 == Approx( product.QM() ) ); + CHECK( 5.537755e+6 == Approx( product.massDifferenceQValue() ) ); + CHECK( 5.489125e+6 == Approx( product.QI() ) ); + CHECK( 5.489125e+6 == Approx( product.reactionQValue() ) ); + CHECK( 95242 == product.IZAP() ); + CHECK( 95242 == product.productIdentifier() ); + CHECK( 2 == product.LFS() ); + CHECK( 2 == product.excitedLevel() ); + CHECK( 2 == product.NP() ); + CHECK( 1 == product.NR() ); + CHECK( 1 == product.interpolants().size() ); + CHECK( 1 == product.boundaries().size() ); + CHECK( 3 == product.interpolants()[0] ); + CHECK( 2 == product.boundaries()[0] ); + CHECK( 2 == product.E().size() ); + CHECK( 2 == product.energies().size() ); + CHECK( 2 == product.Y().size() ); + CHECK( 2 == product.multiplicities().size() ); + CHECK( 1e-5 == Approx( product.E()[0] ) ); + CHECK( 3e+7 == Approx( product.E()[1] ) ); + CHECK( 1e-5 == Approx( product.energies()[0] ) ); + CHECK( 3e+7 == Approx( product.energies()[1] ) ); + CHECK( 0.1 == Approx( product.Y()[0] ) ); + CHECK( 0.48 == Approx( product.Y()[1] ) ); + CHECK( 0.1 == Approx( product.multiplicities()[0] ) ); + CHECK( 0.48 == Approx( product.multiplicities()[1] ) ); + + CHECK( 7 == chunk.NC() ); +} + +std::string validSEND(){ + return + " 9543 9 0 \n"; +} + +std::string invalidSEND(){ + return + " 9543 9 1 \n"; +} diff --git a/src/ENDFtk/section/9/test/CMakeLists.txt b/src/ENDFtk/section/9/test/CMakeLists.txt new file mode 100644 index 000000000..448c7c09c --- /dev/null +++ b/src/ENDFtk/section/9/test/CMakeLists.txt @@ -0,0 +1,14 @@ + +add_executable( ENDFtk.section.9.test 9.test.cpp ) +target_compile_options( ENDFtk.section.9.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.9.test PUBLIC ENDFtk ) +add_test( NAME ENDFtk.section.9 COMMAND ENDFtk.section.9.test ) diff --git a/src/ENDFtk/section/BaseWithoutMT.hpp b/src/ENDFtk/section/BaseWithoutMT.hpp index 1df14c98c..8ea996044 100644 --- a/src/ENDFtk/section/BaseWithoutMT.hpp +++ b/src/ENDFtk/section/BaseWithoutMT.hpp @@ -32,7 +32,7 @@ namespace section{ */ constexpr int MT() const { - return static_cast< const Derived* >( this )->sectionNumber(); + return static_cast< const Derived* >( this )->sectionNumber(); } /** diff --git a/src/ENDFtk/test/isRedundant.test.hpp b/src/ENDFtk/test/isRedundant.test.hpp index 39984298e..831128ab9 100644 --- a/src/ENDFtk/test/isRedundant.test.hpp +++ b/src/ENDFtk/test/isRedundant.test.hpp @@ -141,9 +141,9 @@ SCENARIO( "Testing if MT number is a redundant ENDF reaction" ) { const std::vector< int > redundantMTs{ 1, 3, 4, 16, 18, 27, 101, 103, 104, 105, 106, 107 }; - auto nonRedundantMTs = ranges::view::iota( 1, 999 ) - | ranges::view::remove_if( - [&](int MT ){ return ranges::binary_search( redundantMTs, MT ); } ); + auto nonRedundantMTs = ranges::cpp20::views::iota( 1, 999 ) + | ranges::views::remove_if( + [&](int MT ){ return ranges::cpp20::binary_search( redundantMTs, MT ); } ); for( auto MT : nonRedundantMTs ){ THEN( "isRedundant returns false for MT=" + std::to_string( MT ) ){ diff --git a/src/ENDFtk/tree/File.hpp b/src/ENDFtk/tree/File.hpp index 60f62ba1f..66203af11 100644 --- a/src/ENDFtk/tree/File.hpp +++ b/src/ENDFtk/tree/File.hpp @@ -6,7 +6,7 @@ #include // other includes -#include "range/v3/iterator_range.hpp" +#include "range/v3/view/subrange.hpp" #include "range/v3/view/map.hpp" #include "header-utilities/echoErroneousLine.hpp" #include "ENDFtk/file/Type.hpp" @@ -96,35 +96,50 @@ namespace tree { /** * @brief Return all sections in the file */ - auto sections() { return this->sections_ | ranges::view::values; } + auto sections() { + + return this->sections_ | ranges::cpp20::views::values; + } /** * @brief Return all sections in the file */ - auto sections() const { return this->sections_ | ranges::view::values; } + auto sections() const { + + return this->sections_ | ranges::cpp20::views::values; + } /** * @brief Return a begin iterator to all sections */ - auto begin(){ return ( this->sections_ | ranges::view::values ).begin(); } + auto begin(){ + + return ( this->sections_ | ranges::cpp20::views::values ).begin(); + } /** * @brief Return an end iterator to all sections */ - auto end(){ return ( this->sections_ | ranges::view::values ).end(); } + auto end(){ + + return ( this->sections_ | ranges::cpp20::views::values ).end(); + } /** * @brief Return a begin iterator to all sections */ auto begin() const { - return ( this->sections_ | ranges::view::values ).begin(); + return ( this->sections_ | ranges::cpp20::views::values ).begin(); } /** * @brief Return an end iterator to all sections */ - auto end() const { return ( this->sections_ | ranges::view::values ).end(); } + auto end() const { + + return ( this->sections_ | ranges::cpp20::views::values ).end(); + } /** * @brief Return the number of files in the materials @@ -136,8 +151,8 @@ namespace tree { */ auto buffer() const { - return ranges::make_iterator_range( this->bufferLimits.first, - this->bufferLimits.second ); + return ranges::make_subrange( this->bufferLimits.first, + this->bufferLimits.second ); } /** @@ -165,7 +180,7 @@ namespace tree { */ auto sectionNumbers() const { - return ranges::view::keys( this->sections_ ); + return ranges::cpp20::views::keys( this->sections_ ); } }; diff --git a/src/ENDFtk/tree/File/test/File.test.cpp b/src/ENDFtk/tree/File/test/File.test.cpp index 39b097e1c..9b2823181 100755 --- a/src/ENDFtk/tree/File/test/File.test.cpp +++ b/src/ENDFtk/tree/File/test/File.test.cpp @@ -35,7 +35,7 @@ SCENARIO( "Creating a syntax tree of an ENDF File" ){ THEN( "We can exstract the MT numbers" ){ std::vector< int > refMTs{ 1, 2, 102 }; - CHECK( ranges::equal( refMTs, original->sectionNumbers() ) ); + CHECK( ranges::cpp20::equal( refMTs, original->sectionNumbers() ) ); } // THEN THEN( "the copy ctor will function correctly "){ diff --git a/src/ENDFtk/tree/Material.hpp b/src/ENDFtk/tree/Material.hpp index 3ef8477b2..822e5579d 100644 --- a/src/ENDFtk/tree/Material.hpp +++ b/src/ENDFtk/tree/Material.hpp @@ -90,35 +90,41 @@ namespace tree { /** * @brief Return all files in the material */ - auto files() { return this->files_ | ranges::view::values; } + auto files() { return this->files_ | ranges::cpp20::views::values; } /** * @brief Return all files in the material */ - auto files() const { return this->files_ | ranges::view::values; } + auto files() const { return this->files_ | ranges::cpp20::views::values; } /** * @brief Return a begin iterator to all files */ - auto begin(){ return ( this->files_ | ranges::view::values ).begin(); } + auto begin() { + + return ( this->files_ | ranges::cpp20::views::values ).begin(); + } /** * @brief Return an end iterator to all files */ - auto end(){ return ( this->files_ | ranges::view::values ).end(); } + auto end(){ return ( this->files_ | ranges::cpp20::views::values ).end(); } /** * @brief Return a begin iterator to all files */ auto begin() const { - return ( this->files_ | ranges::view::values ).begin(); + return ( this->files_ | ranges::cpp20::views::values ).begin(); } /** * @brief Return an end iterator to all files */ - auto end() const { return ( this->files_ | ranges::view::values ).end(); } + auto end() const { + + return ( this->files_ | ranges::cpp20::views::values ).end(); + } /** * @brief Return the number of files in the materials @@ -139,14 +145,18 @@ namespace tree { * @brief Return the material's buffer */ auto buffer() const { - return ranges::make_iterator_range( this->bufferLimits.first, - this->bufferLimits.second ); + + return ranges::make_subrange( this->bufferLimits.first, + this->bufferLimits.second ); } /** * @brief Return all file numbers in the material */ - auto fileNumbers() const { return ranges::view::keys( this->files_ ); } + auto fileNumbers() const { + + return ranges::cpp20::views::keys( this->files_ ); + } }; } // tree namespace diff --git a/src/ENDFtk/tree/Section.hpp b/src/ENDFtk/tree/Section.hpp index 195383906..0df58f0bf 100644 --- a/src/ENDFtk/tree/Section.hpp +++ b/src/ENDFtk/tree/Section.hpp @@ -5,7 +5,7 @@ // other includes #include "boost/hana.hpp" -#include "range/v3/iterator_range.hpp" +#include "range/v3/view/subrange.hpp" #include "ENDFtk/HeadRecord.hpp" #include "ENDFtk/section.hpp" #include "boost/hana.hpp" @@ -79,8 +79,8 @@ namespace tree { * @brief Return the section's buffer */ auto buffer() const { - return ranges::make_iterator_range( this->bufferLimits.first, - this->bufferLimits.second ); + return ranges::make_subrange( this->bufferLimits.first, + this->bufferLimits.second ); } }; diff --git a/src/ENDFtk/tree/Tape.hpp b/src/ENDFtk/tree/Tape.hpp index 80c5c40ed..50f412e9e 100644 --- a/src/ENDFtk/tree/Tape.hpp +++ b/src/ENDFtk/tree/Tape.hpp @@ -9,8 +9,7 @@ // other includes #include "range/v3/action/sort.hpp" #include "range/v3/action/unique.hpp" -#include "range/v3/iterator_range.hpp" -#include "range/v3/utility/iterator.hpp" +#include "range/v3/range/operations.hpp" #include "ENDFtk/TapeIdentification.hpp" #include "ENDFtk/Tape.hpp" #include "ENDFtk/tree/Material.hpp" @@ -131,12 +130,18 @@ namespace tree { /** * @brief Return all materials in the tape */ - auto materials() { return this->materials_ | ranges::view::values; } + auto materials() { + + return this->materials_ | ranges::cpp20::views::values; + } /** * @brief Return all materials in the tape */ - auto materials() const { return this->materials_ | ranges::view::values; } + auto materials() const { + + return this->materials_ | ranges::cpp20::views::values; + } /** * @brief Return a begin iterator to all materials @@ -169,7 +174,7 @@ namespace tree { /** * @brief Return the tape's buffer */ - auto buffer() const { return this->buffer_ | ranges::view::all; } + auto buffer() const { return this->buffer_ | ranges::cpp20::views::all; } /** * @brief Return the tape identification (the first line in the file) @@ -181,9 +186,9 @@ namespace tree { */ std::vector< int > materialNumbers() const { - return ranges::view::keys( this->materials_ ) + return ranges::cpp20::views::keys( this->materials_ ) | ranges::to_vector - | ranges::action::sort | ranges::action::unique; + | ranges::actions::sort | ranges::actions::unique; } }; diff --git a/src/ENDFtk/tree/Tape/src/ctor.hpp b/src/ENDFtk/tree/Tape/src/ctor.hpp index 40acbce7a..f4d84e749 100644 --- a/src/ENDFtk/tree/Tape/src/ctor.hpp +++ b/src/ENDFtk/tree/Tape/src/ctor.hpp @@ -9,11 +9,11 @@ Tape( Tape&& other, buffer_( std::move( other.buffer_ ) ), tpid( std::move( other.tpid ) ), materials_( - ranges::begin( this->buffer_ ) == start + ranges::cpp20::begin( this->buffer_ ) == start ? std::move( other.materials_ ) : createMap( - ranges::next( ranges::begin( this->buffer_ ), offset ), - ranges::end( this->buffer_ ) ) ) {} + ranges::cpp20::next( ranges::cpp20::begin( this->buffer_ ), offset ), + ranges::cpp20::end( this->buffer_ ) ) ) {} public: @@ -29,8 +29,8 @@ template< typename BufferArg, Tape( BufferArg&& buffer, long lineNumber = 0 ) try : buffer_( std::forward< BufferArg >( buffer ) ) { - auto position = ranges::begin( this->buffer_ ); - auto end = ranges::end( this->buffer_ ); + auto position = ranges::cpp20::begin( this->buffer_ ); + auto end = ranges::cpp20::end( this->buffer_ ); this->tpid = TapeIdentification{ position, end, lineNumber }; materials_ = createMap( position, end, lineNumber ); } @@ -51,13 +51,13 @@ Tape( const Tape& other ) buffer_( other.buffer_ ), tpid( other.tpid ), materials_( - ranges::begin( this->buffer_ ) == ranges::begin( other.buffer_ ) + ranges::cpp20::begin( this->buffer_ ) == ranges::cpp20::begin( other.buffer_ ) ? other.materials_ - : createMap( ranges::next( ranges::begin( this->buffer_ ), - ranges::distance( - ranges::begin( other.buffer_ ), - ranges::front( other ).buffer().begin() ) ), - ranges::end( this->buffer_ ) ) ) {} + : createMap( ranges::cpp20::next( ranges::cpp20::begin( this->buffer_ ), + ranges::cpp20::distance( + ranges::cpp20::begin( other.buffer_ ), + ranges::front( other ).buffer().begin() ) ), + ranges::cpp20::end( this->buffer_ ) ) ) {} catch( std::exception& ) { Log::info( "Trouble encountered while " @@ -72,10 +72,10 @@ Tape( const Tape& other ) */ Tape( Tape&& other ) try: Tape( std::move( other ), - ranges::distance( - ranges::begin( other.buffer_ ), + ranges::cpp20::distance( + ranges::cpp20::begin( other.buffer_ ), ranges::front( other ).buffer().begin() ), - ranges::begin( other.buffer_ ) ) {} + ranges::cpp20::begin( other.buffer_ ) ) {} catch( std::exception& ) { Log::info( "Trouble encountered while " diff --git a/src/ENDFtk/tree/Tape/src/material.hpp b/src/ENDFtk/tree/Tape/src/material.hpp index 3bab8040b..22115db36 100644 --- a/src/ENDFtk/tree/Tape/src/material.hpp +++ b/src/ENDFtk/tree/Tape/src/material.hpp @@ -15,8 +15,8 @@ auto material( int mat ) const { } auto bounds = this->materials_.equal_range( mat ); return - ranges::make_iterator_range( bounds.first, bounds.second ) - | ranges::view::values; + ranges::make_subrange( bounds.first, bounds.second ) + | ranges::cpp20::views::values; } /** @@ -28,7 +28,7 @@ auto material( int mat ) { return static_cast< const Tape& >( *this ).material( mat ) - | ranges::view::transform - ( []( const auto& material ) -> Material_t& - { return const_cast< Material_t& >( material ); } ); + | ranges::cpp20::views::transform + ( [] ( const auto& material ) -> Material_t& + { return const_cast< Material_t& >( material ); } ); } diff --git a/src/ENDFtk/types.hpp b/src/ENDFtk/types.hpp index 101c8bcdd..cf2fd1077 100644 --- a/src/ENDFtk/types.hpp +++ b/src/ENDFtk/types.hpp @@ -5,17 +5,27 @@ // other includes #include "range/v3/view/all.hpp" +#include "range/v3/view/chunk.hpp" +#include "range/v3/view/drop_exactly.hpp" +#include "range/v3/view/take_exactly.hpp" +#include "range/v3/view/stride.hpp" namespace njoy { namespace ENDFtk { /* derived types using ranges */ template < typename Type > using AllRange = - decltype( ranges::view::all( std::declval< const std::vector< Type > >() ) ); - - /* type aliases */ - using DoubleRange = AllRange< double >; - using LongRange = AllRange< long >; + decltype( ranges::cpp20::views::all( std::declval< const std::vector< Type >& >() ) ); + template < typename Range > using DropRange = + decltype( ranges::views::drop_exactly( std::declval< Range >(), std::declval< int >() ) ); + template < typename Range > using TakeRange = + decltype( ranges::views::take_exactly( std::declval< Range >(), std::declval< int >() ) ); + template < typename Range > using StrideRange = + decltype( ranges::views::stride( std::declval< Range >(), std::declval< int >() ) ); + template < typename Range > using ChunkRange = + decltype( ranges::views::chunk( std::declval< Range >(), std::declval< int >() ) ); + template < typename Range > using Chunk = + decltype( ranges::views::chunk( std::declval< Range >(), std::declval< int >() )[ std::declval< int >() ] ); } // ENDFtk namespace } // njoy namespace