diff --git a/src/dryad/format/endf/createReactionProduct.hpp b/src/dryad/format/endf/createReactionProduct.hpp index 1482e3e..a65b829 100644 --- a/src/dryad/format/endf/createReactionProduct.hpp +++ b/src/dryad/format/endf/createReactionProduct.hpp @@ -8,6 +8,9 @@ #include "tools/Log.hpp" #include "dryad/format/endf/createProductIdentifier.hpp" #include "dryad/format/endf/createTabulatedMultiplicity.hpp" +#include "dryad/format/endf/createTabulatedEnergyDistributions.hpp" +#include "dryad/format/endf/createTabulatedAngularDistributions.hpp" +#include "dryad/format/endf/createTabulatedAverageEnergy.hpp" #include "dryad/ReactionProduct.hpp" #include "ENDFtk/Material.hpp" #include "ENDFtk/tree/Material.hpp" @@ -31,13 +34,12 @@ namespace endf { const ENDFtk::section::Type< 6 >::ReactionProduct& product, bool multiple ) { - id::ParticleID id = createProductIdentifier( product.productIdentifier(), product.productModifierFlag(), multiple ); Log::info( "Reading reaction product data for \'{}\'", id ); - TabulatedMultiplicity multiplicity = createTabulatedMultiplicity( product.multiplicity() ); + return ReactionProduct( std::move( id ), std::move( multiplicity ) ); } @@ -54,9 +56,39 @@ namespace endf { id::ParticleID id = createProductIdentifier( product.productIdentifier(), 0, false ); Log::info( "Reading reaction product data for \'{}\'", id ); - TabulatedMultiplicity multiplicity = createTabulatedMultiplicity( product.multiplicity() ); - return ReactionProduct( std::move( id ), std::move( multiplicity ) ); + + //! @todo what about the reference frames? + + switch ( product.LAW() ) { + + case 1 : { + + auto data = std::get< ENDFtk::section::Type< 26 >::ContinuumEnergyAngle >( product.distribution() ); + auto distribution = UncorrelatedDistributionData( ReferenceFrame::Laboratory, + IsotropicAngularDistributions(), + createTabulatedEnergyDistributions( data ) ); + return ReactionProduct( std::move( id ), std::move( multiplicity ), std::move( distribution ) ); + } + case 2 : { + + auto data = std::get< ENDFtk::section::Type< 26 >::DiscreteTwoBodyScattering >( product.distribution() ); + auto distribution = TwoBodyDistributionData( ReferenceFrame::CentreOfMass, + createTabulatedAngularDistributions( data ) ); + return ReactionProduct( std::move( id ), std::move( multiplicity ), std::move( distribution ) ); + } + case 8 : { + + auto data = std::get< ENDFtk::section::Type< 26 >::EnergyTransfer >( product.distribution() ); + auto average = createTabulatedAverageEnergy( data ); + return ReactionProduct( std::move( id ), std::move( multiplicity ), std::move( average ) ); + } + default : { + + Log::error( "This should be unreachable" ); + throw std::exception(); + } + } } } // endf namespace diff --git a/src/dryad/format/endf/createReactionProducts.hpp b/src/dryad/format/endf/createReactionProducts.hpp index d27e45c..ba93870 100644 --- a/src/dryad/format/endf/createReactionProducts.hpp +++ b/src/dryad/format/endf/createReactionProducts.hpp @@ -41,7 +41,15 @@ namespace endf { [&product] ( auto&& entry ) { return product.productIdentifier() == entry.productIdentifier(); } ) > 1; - products.emplace_back( createReactionProduct( projectile, target, product, multiple ) ); + if ( mt != 18 ) { + + products.emplace_back( createReactionProduct( projectile, target, product, multiple ) ); + } + else { + + //! @todo handle P(nu) case + Log::info( "Skipping P(nu) and P(nu_g) in MF6" ); + } } } else if ( material.hasSection( 26, mt ) ) { diff --git a/src/dryad/format/endf/createTabulatedAverageEnergy.hpp b/src/dryad/format/endf/createTabulatedAverageEnergy.hpp new file mode 100644 index 0000000..7701e2c --- /dev/null +++ b/src/dryad/format/endf/createTabulatedAverageEnergy.hpp @@ -0,0 +1,54 @@ +#ifndef NJOY_DRYAD_FORMAT_ENDF_CREATETABULATEDAVERAGEENERGY +#define NJOY_DRYAD_FORMAT_ENDF_CREATETABULATEDAVERAGEENERGY + +// system includes +#include + +// other includes +#include "tools/Log.hpp" +#include "dryad/id/ParticleID.hpp" +#include "dryad/format/createVector.hpp" +#include "dryad/format/endf/createBoundaries.hpp" +#include "dryad/format/endf/createInterpolants.hpp" +#include "dryad/TabulatedAverageEnergy.hpp" +#include "ENDFtk/section/26.hpp" + +namespace njoy { +namespace dryad { +namespace format { +namespace endf { + + /** + * @brief Create a TabulatedMultiplicity from a parsed ENDF multiplicity + */ + TabulatedAverageEnergy + createTabulatedAverageEnergy( const ENDFtk::section::Type< 26 >::EnergyTransfer& transfer ) { + + try { + + // the average outgoing electron energy is the incident electron energy minus the + // transfer value + + auto energies = createVector( transfer.energies() ); + auto values = createVector( transfer.energyTransferValues() ); + std::transform( energies.begin(), energies.end(), values.begin(), + values.begin(), std::minus{} ); + auto boundaries = createBoundaries( transfer.boundaries() ); + auto interpolants = createInterpolants( transfer.interpolants() ); + return TabulatedAverageEnergy( + std::move( energies ), std::move( values ), + std::move( boundaries ), std::move( interpolants ) ); + } + catch ( ... ) { + + Log::info( "Error encountered while creating an average reaction product energy table" ); + throw; + } + } + +} // endf namespace +} // format namespace +} // dryad namespace +} // njoy namespace + +#endif diff --git a/src/dryad/format/endf/createTabulatedEnergyDistribution.hpp b/src/dryad/format/endf/createTabulatedEnergyDistribution.hpp new file mode 100644 index 0000000..8b0f178 --- /dev/null +++ b/src/dryad/format/endf/createTabulatedEnergyDistribution.hpp @@ -0,0 +1,61 @@ +#ifndef NJOY_DRYAD_FORMAT_ENDF_CREATETABULATEDENERGYDISTRIBUTION +#define NJOY_DRYAD_FORMAT_ENDF_CREATETABULATEDENERGYDISTRIBUTION + +// system includes +#include + +// other includes +#include "tools/Log.hpp" +#include "dryad/format/createVector.hpp" +#include "dryad/format/endf/createBoundaries.hpp" +#include "dryad/format/endf/createInterpolants.hpp" +#include "dryad/TabulatedEnergyDistribution.hpp" +#include "ENDFtk/section/26.hpp" + +namespace njoy { +namespace dryad { +namespace format { +namespace endf { + + /** + * @brief Create a TabulatedEnergyDistribution from a parsed ENDF MF26 LAW = 1 + * LegendreCoefficients entry (with NA = 0) + */ + TabulatedEnergyDistribution + createTabulatedEnergyDistribution( + const ENDFtk::section::Type< 26 >::ContinuumEnergyAngle::LegendreCoefficients& distribution ) { + + if ( distribution.numberAngularParameters() != 0 ) { + + Log::error( "MF26 LAW = 1 data must be fully isotropic, found NA = {}", + distribution.numberAngularParameters() ); + throw std::exception(); + } + + //! @todo interpolants and boundaries on LegendreCoefficients for interpolation on + //! outgoing energy? + //! @todo what is the interpolation type over the outgoing energy axis? + + try { + + auto energies = createVector( distribution.energies() ); + auto values = createVector( distribution.totalEmissionProbabilities() ); + std::vector< std::size_t > boundaries = { energies.size() - 1 }; + std::vector< InterpolationType > interpolants = { InterpolationType::LinearLinear }; + return TabulatedEnergyDistribution( + std::move( energies ), std::move( values ), + std::move( boundaries ), std::move( interpolants ) ); + } + catch ( ... ) { + + Log::info( "Error encountered while creating an average reaction product energy table" ); + throw; + } + } + +} // endf namespace +} // format namespace +} // dryad namespace +} // njoy namespace + +#endif diff --git a/src/dryad/format/endf/createTabulatedEnergyDistributions.hpp b/src/dryad/format/endf/createTabulatedEnergyDistributions.hpp new file mode 100644 index 0000000..2c6f7f0 --- /dev/null +++ b/src/dryad/format/endf/createTabulatedEnergyDistributions.hpp @@ -0,0 +1,56 @@ +#ifndef NJOY_DRYAD_FORMAT_ENDF_TABULATEDENERGYDISTRIBUTIONS +#define NJOY_DRYAD_FORMAT_ENDF_TABULATEDENERGYDISTRIBUTIONS + +// system includes +#include + +// other includes +#include "tools/Log.hpp" +#include "dryad/id/ParticleID.hpp" +#include "dryad/format/createVector.hpp" +#include "dryad/format/endf/createBoundaries.hpp" +#include "dryad/format/endf/createInterpolants.hpp" +#include "dryad/format/endf/createTabulatedEnergyDistribution.hpp" +#include "dryad/TabulatedEnergyDistributions.hpp" +#include "ENDFtk/section/26.hpp" + +namespace njoy { +namespace dryad { +namespace format { +namespace endf { + + /** + * @brief Create a TabulatedEnergyDistributions instance from a parsed + * ENDF MF6 ContinuumEnergyAngle component + */ + TabulatedEnergyDistributions + createTabulatedEnergyDistributions( const ENDFtk::section::Type< 26 >::ContinuumEnergyAngle& distribution ) { + + try { + + auto energies = createVector( distribution.incidentEnergies() ); + std::vector< TabulatedEnergyDistribution > distributions; + distributions.reserve( energies.size() ); + for ( auto&& table : distribution.distributions() ) { + + distributions.emplace_back( createTabulatedEnergyDistribution( table ) ); + } + auto boundaries = createBoundaries( distribution.boundaries() ); + auto interpolants = createInterpolants( distribution.interpolants() ); + return TabulatedEnergyDistributions( + std::move( energies ), std::move( distributions ), + std::move( boundaries ), std::move( interpolants ) ); + } + catch ( ... ) { + + Log::info( "Error encountered while creating an average reaction product energy table" ); + throw; + } + } + +} // endf namespace +} // format namespace +} // dryad namespace +} // njoy namespace + +#endif