From c859314328644ab75a3a35563f874d07d43eefc1 Mon Sep 17 00:00:00 2001 From: Wim Haeck Date: Wed, 7 Aug 2024 15:22:23 -0600 Subject: [PATCH] Adding logic to convert tabulated to constant multiplicity, started work on createReactionProduct test --- cmake/release_dependencies.cmake | 2 +- src/dryad/format/endf.hpp | 8 ++ src/dryad/format/endf/createMultiplicity.hpp | 43 ++++++++ .../format/endf/createReactionProduct.hpp | 13 ++- src/dryad/format/endf/test/CMakeLists.txt | 2 + .../endf/test/createMultiplicity.test.cpp | 104 ++++++++++++++++++ .../endf/test/createReactionProduct.test.cpp | 65 +++++++++++ 7 files changed, 233 insertions(+), 4 deletions(-) create mode 100644 src/dryad/format/endf/createMultiplicity.hpp create mode 100644 src/dryad/format/endf/test/createMultiplicity.test.cpp create mode 100644 src/dryad/format/endf/test/createReactionProduct.test.cpp diff --git a/cmake/release_dependencies.cmake b/cmake/release_dependencies.cmake index d1c9327..2b9796f 100644 --- a/cmake/release_dependencies.cmake +++ b/cmake/release_dependencies.cmake @@ -42,7 +42,7 @@ FetchContent_Declare( range-v3 FetchContent_Declare( scion GIT_REPOSITORY https://github.com/njoy/scion - GIT_TAG 6079dc15153b1948c772835096662be65b062676 + GIT_TAG fd76c11780fcdde507f8952c8698085cf47b0369 ) FetchContent_Declare( spdlog diff --git a/src/dryad/format/endf.hpp b/src/dryad/format/endf.hpp index 915c5cb..e7983bd 100644 --- a/src/dryad/format/endf.hpp +++ b/src/dryad/format/endf.hpp @@ -8,7 +8,15 @@ #include "dryad/format/endf/createInteractionType.hpp" #include "dryad/format/endf/createTabulatedMultiplicity.hpp" +#include "dryad/format/endf/createMultiplicity.hpp" #include "dryad/format/endf/createTabulatedCrossSection.hpp" +#include "dryad/format/endf/createTabulatedAngularDistribution.hpp" +#include "dryad/format/endf/createTabulatedAngularDistributions.hpp" +#include "dryad/format/endf/createTabulatedEnergyDistribution.hpp" +#include "dryad/format/endf/createTabulatedEnergyDistributions.hpp" +#include "dryad/format/endf/createTabulatedAverageEnergy.hpp" +#include "dryad/format/endf/createReactionProduct.hpp" +#include "dryad/format/endf/createReactionProducts.hpp" #include "dryad/format/endf/createReaction.hpp" #include "dryad/format/endf/createReactions.hpp" #include "dryad/format/endf/createProjectileTarget.hpp" diff --git a/src/dryad/format/endf/createMultiplicity.hpp b/src/dryad/format/endf/createMultiplicity.hpp new file mode 100644 index 0000000..9b92ea5 --- /dev/null +++ b/src/dryad/format/endf/createMultiplicity.hpp @@ -0,0 +1,43 @@ +#ifndef NJOY_DRYAD_FORMAT_ENDF_CREATEMULTIPLICITY +#define NJOY_DRYAD_FORMAT_ENDF_CREATEMULTIPLICITY + +// system includes +#include + +// other includes +#include "tools/Log.hpp" +#include "dryad/format/endf/createTabulatedMultiplicity.hpp" +#include "dryad/TabulatedMultiplicity.hpp" +#include "ENDFtk/section/6.hpp" +#include "ENDFtk/section/26.hpp" + +namespace njoy { +namespace dryad { +namespace format { +namespace endf { + + /** + * @brief Create an integer or tabulated multiplicity from a parsed ENDF multiplicity + */ + template < typename Multiplicity > + auto createMultiplicity( const Multiplicity& multiplicity ) + -> std::enable_if_t< ( std::is_same_v< Multiplicity, ENDFtk::section::Type< 6 >::Multiplicity > || + std::is_same_v< Multiplicity, ENDFtk::section::Type< 26 >::Multiplicity > ), + std::variant< int, TabulatedMultiplicity > > { + + if ( scion::verification::isAllSameElement( multiplicity.multiplicities() ) ) { + + return static_cast< int >( std::round( multiplicity.multiplicities().front() ) ); + } + else { + + return createTabulatedMultiplicity( multiplicity ); + } + } + +} // endf namespace +} // format namespace +} // dryad namespace +} // njoy namespace + +#endif diff --git a/src/dryad/format/endf/createReactionProduct.hpp b/src/dryad/format/endf/createReactionProduct.hpp index db76ffa..3b6cbe0 100644 --- a/src/dryad/format/endf/createReactionProduct.hpp +++ b/src/dryad/format/endf/createReactionProduct.hpp @@ -7,7 +7,7 @@ // other includes #include "tools/Log.hpp" #include "dryad/format/endf/createProductIdentifier.hpp" -#include "dryad/format/endf/createTabulatedMultiplicity.hpp" +#include "dryad/format/endf/createMultiplicity.hpp" #include "dryad/format/endf/createTabulatedEnergyDistributions.hpp" #include "dryad/format/endf/createTabulatedAngularDistributions.hpp" #include "dryad/format/endf/createTabulatedAverageEnergy.hpp" @@ -38,7 +38,7 @@ namespace endf { product.productModifierFlag(), multiple ); Log::info( "Reading reaction product data for \'{}\'", id ); - TabulatedMultiplicity multiplicity = createTabulatedMultiplicity( product.multiplicity() ); + auto multiplicity = createMultiplicity( product.multiplicity() ); return ReactionProduct( std::move( id ), std::move( multiplicity ) ); } @@ -56,7 +56,7 @@ namespace endf { id::ParticleID id = createProductIdentifier( product.productIdentifier(), 0, false ); Log::info( "Reading reaction product data for \'{}\'", id ); - TabulatedMultiplicity multiplicity = createTabulatedMultiplicity( product.multiplicity() ); + auto multiplicity = createMultiplicity( product.multiplicity() ); //! @todo what about the reference frames? @@ -64,6 +64,13 @@ namespace endf { case 1 : { + // ENDF/B-VIII.0 erroneously uses 11 for the gamma identifier + if ( id == "e-" ) { + + id = createProductIdentifier( 0, 0, false ); + Log::warning( "Reaction product identifier changed from \'e-\' to \'g\'" ); + } + // MF26 LAW = 1 : NA must be 0 and LANG must be 1 decltype(auto) data = std::get< ENDFtk::section::Type< 26 >::ContinuumEnergyAngle >( product.distribution() ); auto distribution = UncorrelatedDistributionData( ReferenceFrame::Laboratory, diff --git a/src/dryad/format/endf/test/CMakeLists.txt b/src/dryad/format/endf/test/CMakeLists.txt index d8bdc24..2882e59 100644 --- a/src/dryad/format/endf/test/CMakeLists.txt +++ b/src/dryad/format/endf/test/CMakeLists.txt @@ -8,11 +8,13 @@ add_cpp_test( format.endf.createInteractionType createInteractionType.test. add_cpp_test( format.endf.createTabulatedCrossSection createTabulatedCrossSection.test.cpp ) add_cpp_test( format.endf.createTabulatedMultiplicity createTabulatedMultiplicity.test.cpp ) +add_cpp_test( format.endf.createMultiplicity createMultiplicity.test.cpp ) add_cpp_test( format.endf.createTabulatedAngularDistribution createTabulatedAngularDistribution.test.cpp ) add_cpp_test( format.endf.createTabulatedAngularDistributions createTabulatedAngularDistributions.test.cpp ) add_cpp_test( format.endf.createTabulatedEnergyDistribution createTabulatedEnergyDistribution.test.cpp ) add_cpp_test( format.endf.createTabulatedEnergyDistributions createTabulatedEnergyDistributions.test.cpp ) add_cpp_test( format.endf.createTabulatedAverageEnergy createTabulatedAverageEnergy.test.cpp ) +add_cpp_test( format.endf.createReactionProduct createReactionProduct.test.cpp ) add_cpp_test( format.endf.createReaction createReaction.test.cpp ) add_cpp_test( format.endf.createReactions createReactions.test.cpp ) add_cpp_test( format.endf.createProjectileTarget createProjectileTarget.test.cpp ) diff --git a/src/dryad/format/endf/test/createMultiplicity.test.cpp b/src/dryad/format/endf/test/createMultiplicity.test.cpp new file mode 100644 index 0000000..b2c5dbb --- /dev/null +++ b/src/dryad/format/endf/test/createMultiplicity.test.cpp @@ -0,0 +1,104 @@ +// include Catch2 +#include +#include +using Catch::Matchers::WithinRel; + +// what we are testing +#include "dryad/format/endf/createMultiplicity.hpp" + +// other includes +#include "ENDFtk/tree/fromFile.hpp" + +// convenience typedefs +using namespace njoy::dryad; +using Multiplicity = std::variant< int, TabulatedMultiplicity >; + +void verifyNeutronConstantChunk( const Multiplicity& ); +void verifyNeutronTabulatedChunk( const Multiplicity& ); +void verifyElectronConstantChunk( const Multiplicity& ); + +//! @todo look for an electron example where the multiplicity is tabulated? + +SCENARIO( "createTabulatedMultiplicity" ) { + + GIVEN( "ENDF MF6 multiplicities" ) { + + auto tape = njoy::ENDFtk::tree::fromFile( "n-017_Cl_035.endf" ); + auto section = tape.materials().front().section( 6, 16 ).parse< 6 >(); + auto constant = section.reactionProduct( 1 ).multiplicity(); + auto tabulated = section.reactionProduct( 0 ).multiplicity(); + + WHEN( "a single parsed MF6 multiplicity with a constant value is given" ) { + + THEN( "it can be converted" ) { + + auto chunk = format::endf::createMultiplicity( constant ); + + verifyNeutronConstantChunk( chunk ); + } // THEN + } // WHEN + + WHEN( "a single parsed MF6 multiplicity with tabulated values is given" ) { + + THEN( "it can be converted" ) { + + auto chunk = format::endf::createMultiplicity( tabulated ); + + verifyNeutronTabulatedChunk( chunk ); + } // THEN + } // WHEN + } // GIVEN + + GIVEN( "ENDF MF26 multiplicities" ) { + + auto tape = njoy::ENDFtk::tree::fromFile( "e-001_H_000.endf" ); + auto section = tape.materials().front().section( 26, 527 ).parse< 26 >(); + auto constant = section.reactionProducts()[0].multiplicity(); + + WHEN( "a single parsed MF6 multiplicity with a constant value is given" ) { + + THEN( "it can be converted" ) { + + auto chunk = format::endf::createMultiplicity( constant ); + + verifyElectronConstantChunk( chunk ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +void verifyNeutronConstantChunk( const Multiplicity& chunk ) { + + CHECK( true == std::holds_alternative< int >( chunk ) ); + + auto multiplicity = std::get< int >( chunk ); + CHECK( 2 == multiplicity ); +} + +void verifyNeutronTabulatedChunk( const Multiplicity& chunk ) { + + CHECK( true == std::holds_alternative< TabulatedMultiplicity >( chunk ) ); + + auto multiplicity = std::get< TabulatedMultiplicity >( chunk ); + CHECK( true == multiplicity.isLinearised() ); + CHECK( 15 == multiplicity.numberPoints() ); + CHECK( 1 == multiplicity.numberRegions() ); + CHECK( 15 == multiplicity.energies().size() ); + CHECK( 15 == multiplicity.values().size() ); + CHECK( 1 == multiplicity.boundaries().size() ); + CHECK( 1 == multiplicity.interpolants().size() ); + CHECK( 14 == multiplicity.boundaries()[0] ); + CHECK( InterpolationType::LinearLinear == multiplicity.interpolants()[0] ); + CHECK_THAT( 1.300979e+7, WithinRel( multiplicity.energies()[0] ) ); + CHECK_THAT( 2e+7 , WithinRel( multiplicity.energies()[14] ) ); + CHECK_THAT( 0.8634751 , WithinRel( multiplicity.values()[0] ) ); + CHECK_THAT( 1.618791 , WithinRel( multiplicity.values()[14] ) ); +} + +void verifyElectronConstantChunk( const Multiplicity& chunk ) { + + CHECK( true == std::holds_alternative< int >( chunk ) ); + + auto multiplicity = std::get< int >( chunk ); + CHECK( 1 == multiplicity ); +} diff --git a/src/dryad/format/endf/test/createReactionProduct.test.cpp b/src/dryad/format/endf/test/createReactionProduct.test.cpp new file mode 100644 index 0000000..684be45 --- /dev/null +++ b/src/dryad/format/endf/test/createReactionProduct.test.cpp @@ -0,0 +1,65 @@ +// include Catch2 +#include +#include +using Catch::Matchers::WithinRel; + +// what we are testing +#include "dryad/format/endf/createReactionProduct.hpp" + +// other includes +#include "ENDFtk/tree/fromFile.hpp" + +// convenience typedefs +using namespace njoy::dryad; + +void verifyElectronlargeAngleElasticElectronProduct( const ReactionProduct& ); +void verifyElectronBremsstrahlungPhotonProduct( const ReactionProduct& ); +void verifyElectronBremsstrahlungElectronProduct( const ReactionProduct& ); + +SCENARIO( "createReactionProduct" ) { + + GIVEN( "ENDF reaction products - electro-atomic interactions" ) { + + auto tape = njoy::ENDFtk::tree::fromFile( "e-001_H_000.endf" ); + auto material = tape.materials().front(); + + WHEN( "a single ENDF reaction product is given" ) { + + THEN( "a Reaction can be created" ) { + + auto elastic = tape.materials().front().section( 26, 525 ).parse< 26 >(); + auto bremsstrahlung = tape.materials().front().section( 26, 527 ).parse< 26 >(); + + id::ParticleID projectile( "e-" ); + id::ParticleID target( "H1" ); + + auto product = elastic.reactionProducts()[0]; + ReactionProduct electron_elastic = format::endf::createReactionProduct( projectile, target, product ); + verifyElectronlargeAngleElasticElectronProduct( electron_elastic ); + + product = bremsstrahlung.reactionProducts()[0]; + ReactionProduct photon_bremsstrahlung = format::endf::createReactionProduct( projectile, target, product ); + verifyElectronBremsstrahlungPhotonProduct( photon_bremsstrahlung ); + + product = bremsstrahlung.reactionProducts()[1]; + ReactionProduct electron_bremsstrahlung = format::endf::createReactionProduct( projectile, target, product ); + verifyElectronBremsstrahlungElectronProduct( electron_bremsstrahlung ); + } // THEN + } // WHEN + } // GIVEN +} // SCENARIO + +void verifyElectronlargeAngleElasticElectronProduct( const ReactionProduct& chunk ) { + + CHECK( id::ParticleID( "e-" ) == chunk.identifier() ); +} + +void verifyElectronBremsstrahlungPhotonProduct( const ReactionProduct& chunk ) { + + CHECK( id::ParticleID( "g" ) == chunk.identifier() ); +} + +void verifyElectronBremsstrahlungElectronProduct( const ReactionProduct& chunk ) { + + CHECK( id::ParticleID( "e-" ) == chunk.identifier() ); +}