From 8d3f9d3c69d06e9233d6d064b6fd5ae714b5a5bf Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sat, 27 Oct 2018 15:11:49 -0400 Subject: [PATCH 01/10] Move most EnergyFilter functionality to C++ --- CMakeLists.txt | 1 + include/openmc/constants.h | 1 + include/openmc/tallies/filter_energy.h | 55 +++++++++++ src/geometry.cpp | 2 - src/tallies/filter.cpp | 5 + src/tallies/filter_energy.cpp | 116 +++++++++++++++++++++++ src/tallies/tally_filter_energy.F90 | 124 +------------------------ 7 files changed, 182 insertions(+), 122 deletions(-) create mode 100644 include/openmc/tallies/filter_energy.h create mode 100644 src/tallies/filter_energy.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ac9d9c5d7..636c5fb532 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -438,6 +438,7 @@ add_library(libopenmc SHARED src/tallies/filter_cell.cpp src/tallies/filter_distribcell.cpp src/tallies/filter_energyfunc.cpp + src/tallies/filter_energy.cpp src/tallies/filter_legendre.cpp src/tallies/filter_material.cpp src/tallies/filter_mesh.cpp diff --git a/include/openmc/constants.h b/include/openmc/constants.h index d249e4cb5b..75da02c0a6 100644 --- a/include/openmc/constants.h +++ b/include/openmc/constants.h @@ -420,6 +420,7 @@ constexpr int DIFF_NUCLIDE_DENSITY {2}; constexpr int DIFF_TEMPERATURE {3}; constexpr int C_NONE {-1}; +constexpr int F90_NONE {0}; //TODO: replace usage of this with C_NONE // Interpolation rules enum class Interpolation { diff --git a/include/openmc/tallies/filter_energy.h b/include/openmc/tallies/filter_energy.h new file mode 100644 index 0000000000..9f613e33d4 --- /dev/null +++ b/include/openmc/tallies/filter_energy.h @@ -0,0 +1,55 @@ +#ifndef OPENMC_TALLIES_FILTER_ENERGY_H +#define OPENMC_TALLIES_FILTER_ENERGY_H + +//#include +//#include +#include + +#include "openmc/tallies/filter.h" + +namespace openmc { + +//============================================================================== +//! Bins the incident neutron energy. +//============================================================================== + +class EnergyFilter : public Filter +{ +public: + ~EnergyFilter() = default; + + std::string type() const override {return "energy";} + + void from_xml(pugi::xml_node node) override; + + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) + const override; + + void to_statepoint(hid_t filter_group) const override; + + std::string text_label(int bin) const override; + + std::vector bins_; + bool matches_transport_groups_ {false}; +}; + +//============================================================================== +//! Bins the outgoing neutron energy. +//! +//! Only scattering events use the get_all_bins functionality. Nu-fission +//! tallies manually iterate over the filter bins. +//============================================================================== + +class EnergyoutFilter : public EnergyFilter +{ +public: + std::string type() const override {return "energyout";} + + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) + const override; + + std::string text_label(int bin) const override; +}; + +} // namespace openmc +#endif // OPENMC_TALLIES_FILTER_ENERGY_H diff --git a/src/geometry.cpp b/src/geometry.cpp index 28885a5db3..cff5657a56 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -16,8 +16,6 @@ namespace openmc { std::vector overlap_check_count; -constexpr int F90_NONE {0}; //TODO: replace usage of this with C_NONE - //============================================================================== extern "C" bool diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index 44758f3799..cd79d44ae9 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -11,6 +11,7 @@ #include "openmc/tallies/filter_cellfrom.h" #include "openmc/tallies/filter_distribcell.h" #include "openmc/tallies/filter_energyfunc.h" +#include "openmc/tallies/filter_energy.h" #include "openmc/tallies/filter_legendre.h" #include "openmc/tallies/filter_material.h" #include "openmc/tallies/filter_mesh.h" @@ -105,6 +106,10 @@ extern "C" { tally_filters.push_back(new DistribcellFilter()); } else if (type_ == "energyfunction") { tally_filters.push_back(new EnergyFunctionFilter()); + } else if (type_ == "energy") { + tally_filters.push_back(new EnergyFilter()); + } else if (type_ == "energyout") { + tally_filters.push_back(new EnergyoutFilter()); } else if (type_ == "legendre") { tally_filters.push_back(new LegendreFilter()); } else if (type_ == "material") { diff --git a/src/tallies/filter_energy.cpp b/src/tallies/filter_energy.cpp new file mode 100644 index 0000000000..35d34bf0a4 --- /dev/null +++ b/src/tallies/filter_energy.cpp @@ -0,0 +1,116 @@ +#include "openmc/tallies/filter_energy.h" + +#include "openmc/constants.h" // For F90_NONE +#include "openmc/mgxs_interface.h" +#include "openmc/search.h" +#include "openmc/settings.h" +#include "openmc/xml_interface.h" + +namespace openmc { + +//============================================================================== +// EnergyFilter implementation +//============================================================================== + +// Used to grab the rev_energy_bins array defined in Fortran. +extern "C" double* rev_energy_bins_ptr(); + +void +EnergyFilter::from_xml(pugi::xml_node node) +{ + bins_ = get_node_array(node, "bins"); + n_bins_ = bins_.size() - 1; + + // In MG mode, check if the filter bins match the transport bins. + // We can save tallying time if we know that the tally bins match the energy + // group structure. In that case, the matching bin index is simply the group + // (after flipping for the different ordering of the library and tallying + // systems). + if (!settings::run_CE) { + if (n_bins_ == num_energy_groups) { + matches_transport_groups_ = true; + double* rev_energy_bins = rev_energy_bins_ptr(); + for (auto i = 0; i < n_bins_ + 1; i++) { + if (rev_energy_bins[i] != bins_[i]) { + matches_transport_groups_ = false; + break; + } + } + } + } +} + +void +EnergyFilter::get_all_bins(const Particle* p, int estimator, FilterMatch& match) +const +{ + if (p->g != F90_NONE && matches_transport_groups_) { + if (estimator == ESTIMATOR_TRACKLENGTH) { + //TODO: off-by-one + match.bins_.push_back(num_energy_groups - p->g + 1); + } else { + //TODO: off-by-one + match.bins_.push_back(num_energy_groups - p->last_g + 1); + } + match.weights_.push_back(1.0); + + } else { + // Get the pre-collision energy of the particle. + auto E = p->last_E; + + // Bin the energy. + if (E >= bins_.front() && E <= bins_.back()) { + //TODO: off-by-one + auto bin = lower_bound_index(bins_.begin(), bins_.end(), E) + 1; + match.bins_.push_back(bin); + match.weights_.push_back(1.0); + } + } +} + +void +EnergyFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", bins_); +} + +std::string +EnergyFilter::text_label(int bin) const +{ + std::stringstream out; + out << "Incoming Energy [" << bins_[bin-1] << ", " << bins_[bin] << ")"; + return out.str(); +} + +//============================================================================== +// EnergyoutFilter implementation +//============================================================================== + +void +EnergyoutFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const +{ + if (p->g != F90_NONE && matches_transport_groups_) { + match.bins_.push_back(num_energy_groups - p->g + 1); + match.weights_.push_back(1.0); + + } else { + if (p->E >= bins_.front() && p->E <= bins_.back()) { + //TODO: off-by-one + auto bin = lower_bound_index(bins_.begin(), bins_.end(), p->E) + 1; + match.bins_.push_back(bin); + match.weights_.push_back(1.0); + } + } +} + +std::string +EnergyoutFilter::text_label(int bin) const +{ + std::stringstream out; + out << "Outgoing Energy [" << bins_[bin-1] << ", " << bins_[bin] << ")"; + return out.str(); +} + +}// namespace openmc diff --git a/src/tallies/tally_filter_energy.F90 b/src/tallies/tally_filter_energy.F90 index 70142156e2..338384f9d9 100644 --- a/src/tallies/tally_filter_energy.F90 +++ b/src/tallies/tally_filter_energy.F90 @@ -10,7 +10,7 @@ module tally_filter_energy use particle_header, only: Particle use settings, only: run_CE use string, only: to_str - use tally_filter_header + use tally_filter_cpp use xml_interface implicit none @@ -22,16 +22,13 @@ module tally_filter_energy ! ENERGYFILTER bins the incident neutron energy. !=============================================================================== - type, public, extends(TallyFilter) :: EnergyFilter + type, public, extends(CppTallyFilter) :: EnergyFilter real(8), allocatable :: bins(:) ! True if transport group number can be used directly to get bin number logical :: matches_transport_groups = .false. contains procedure :: from_xml => from_xml_energy - procedure :: get_all_bins => get_all_bins_energy - procedure :: to_statepoint => to_statepoint_energy - procedure :: text_label => text_label_energy end type EnergyFilter !=============================================================================== @@ -41,11 +38,6 @@ module tally_filter_energy !=============================================================================== type, public, extends(EnergyFilter) :: EnergyoutFilter - contains - ! Inherit from_xml from EnergyFilter - procedure :: get_all_bins => get_all_bins_energyout - procedure :: to_statepoint => to_statepoint_energyout - procedure :: text_label => text_label_energyout end type EnergyoutFilter contains @@ -60,6 +52,8 @@ contains integer :: n + call this % from_xml_cpp_inner(node) + n = node_word_count(node, "bins") ! Allocate and store bins @@ -81,116 +75,6 @@ contains end if end subroutine from_xml_energy - subroutine get_all_bins_energy(this, p, estimator, match) - class(EnergyFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: n - integer :: bin - real(8) :: E - - n = this % n_bins - - if (p % g /= NONE .and. this % matches_transport_groups) then - if (estimator == ESTIMATOR_TRACKLENGTH) then - call match % bins_push_back(num_energy_groups - p % g + 1) - call match % weights_push_back(ONE) - else - call match % bins_push_back(num_energy_groups - p % last_g + 1) - call match % weights_push_back(ONE) - end if - - else - ! Pre-collision energy of particle - E = p % last_E - - ! Search to find incoming energy bin. - bin = binary_search(this % bins, n + 1, E) - if (bin /= NO_BIN_FOUND) then - call match % bins_push_back(bin) - call match % weights_push_back(ONE) - end if - end if - end subroutine get_all_bins_energy - - subroutine to_statepoint_energy(this, filter_group) - class(EnergyFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "energy") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", this % bins) - end subroutine to_statepoint_energy - - function text_label_energy(this, bin) result(label) - class(EnergyFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - real(8) :: E0, E1 - - E0 = this % bins(bin) - E1 = this % bins(bin + 1) - label = "Incoming Energy [" // trim(to_str(E0)) // ", " & - // trim(to_str(E1)) // ")" - end function text_label_energy - -!=============================================================================== -! EnergyoutFilter methods -!=============================================================================== - - subroutine get_all_bins_energyout(this, p, estimator, match) - class(EnergyoutFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: n - integer :: bin - - n = this % n_bins - - if (p % g /= NONE .and. this % matches_transport_groups) then - ! Tallies are ordered in increasing groups, group indices - ! however are the opposite, so switch - call match % bins_push_back(num_energy_groups - p % g + 1) - call match % weights_push_back(ONE) - - else - - ! Search to find incoming energy bin. - bin = binary_search(this % bins, n + 1, p % E) - if (bin /= NO_BIN_FOUND) then - call match % bins_push_back(bin) - call match % weights_push_back(ONE) - end if - end if - end subroutine get_all_bins_energyout - - subroutine to_statepoint_energyout(this, filter_group) - class(EnergyoutFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "energyout") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", this % bins) - end subroutine to_statepoint_energyout - - function text_label_energyout(this, bin) result(label) - class(EnergyoutFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - real(8) :: E0, E1 - - E0 = this % bins(bin) - E1 = this % bins(bin + 1) - label = "Outgoing Energy [" // trim(to_str(E0)) // ", " & - // trim(to_str(E1)) // ")" - end function text_label_energyout - !=============================================================================== ! C API FUNCTIONS !=============================================================================== From 432a6a51096d49c20e0635f184853a2d4235f284 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sat, 27 Oct 2018 16:29:59 -0400 Subject: [PATCH 02/10] Finish moving EnergyFilter implementation to C++ --- include/openmc/tallies/filter_energy.h | 2 + src/api.F90 | 2 - src/tallies/filter_energy.cpp | 71 ++++++++++++++ src/tallies/tally.F90 | 18 ++-- src/tallies/tally_filter_energy.F90 | 130 ++++++++----------------- 5 files changed, 123 insertions(+), 100 deletions(-) diff --git a/include/openmc/tallies/filter_energy.h b/include/openmc/tallies/filter_energy.h index 9f613e33d4..fb027c130a 100644 --- a/include/openmc/tallies/filter_energy.h +++ b/include/openmc/tallies/filter_energy.h @@ -30,6 +30,8 @@ public: std::string text_label(int bin) const override; std::vector bins_; + + //! True if transport group number can be used directly to get bin number bool matches_transport_groups_ {false}; }; diff --git a/src/api.F90 b/src/api.F90 index b9ccdca48c..aa9887effc 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -39,8 +39,6 @@ module openmc_api public :: openmc_calculate_volumes public :: openmc_cell_get_id public :: openmc_cell_set_id - public :: openmc_energy_filter_get_bins - public :: openmc_energy_filter_set_bins public :: openmc_extend_filters public :: openmc_extend_cells public :: openmc_extend_materials diff --git a/src/tallies/filter_energy.cpp b/src/tallies/filter_energy.cpp index 35d34bf0a4..779681b849 100644 --- a/src/tallies/filter_energy.cpp +++ b/src/tallies/filter_energy.cpp @@ -1,5 +1,6 @@ #include "openmc/tallies/filter_energy.h" +#include "openmc/capi.h" #include "openmc/constants.h" // For F90_NONE #include "openmc/mgxs_interface.h" #include "openmc/search.h" @@ -113,4 +114,74 @@ EnergyoutFilter::text_label(int bin) const return out.str(); } +//============================================================================== +// Fortran interoperability +//============================================================================== + +extern "C" bool energy_filter_matches_transport_groups(EnergyFilter* filt) +{return filt->matches_transport_groups_;} + +extern "C" int +energy_filter_search(EnergyFilter* filt, double val) +{ + if (val < filt->bins_.front() || val > filt->bins_.back()) { + return -1; + } else { + //TODO: off-by-one + return lower_bound_index(filt->bins_.begin(), filt->bins_.end(), val) + 1; + } +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern"C" int +openmc_energy_filter_get_bins(int32_t index, double** energies, int32_t* n) +{ + // Make sure this is a valid index to an allocated filter. + int err = verify_filter(index); + if (err) return err; + + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { + set_errmsg("Tried to get energy bins on a non-energy filter."); + return OPENMC_E_INVALID_TYPE; + } + + // Output the bins. + *energies = filt->bins_.data(); + *n = filt->bins_.size(); + return 0; +} + +extern "C" int +openmc_energy_filter_set_bins(int32_t index, int32_t n, const double* energies) +{ + // Make sure this is a valid index to an allocated filter. + int err = verify_filter(index); + if (err) return err; + + // Get a pointer to the filter and downcast. + auto* filt_base = filter_from_f(index); + auto* filt = dynamic_cast(filt_base); + + // Check the filter type. + if (!filt) { + set_errmsg("Tried to set energy bins on a non-energy filter."); + return OPENMC_E_INVALID_TYPE; + } + + // Update the filter. + filt->bins_.clear(); + filt->bins_.resize(n); + for (int i = 0; i < n; i++) filt->bins_[i] = energies[i]; + filt->n_bins_ = n - 1; + filter_update_n_bins(index); +} + }// namespace openmc diff --git a/src/tallies/tally.F90 b/src/tallies/tally.F90 index c15325418d..b8622dacef 100644 --- a/src/tallies/tally.F90 +++ b/src/tallies/tally.F90 @@ -2344,11 +2344,11 @@ contains integer :: d ! delayed group integer :: g ! another delayed group integer :: d_bin ! delayed group bin index - integer :: n ! number of energies on filter integer :: k ! loop index for bank sites integer :: l ! loop index for tally filters integer :: f ! index in filters array integer :: b ! index of filter bin + integer :: i_match ! matching bin index on energyout filter integer :: i_bin ! index of matching filter bin integer :: bin_energyout ! original outgoing energy bin integer :: i_filter ! index for matching filter bin combination @@ -2366,9 +2366,6 @@ contains select type(eo_filt => filters(i) % obj) type is (EnergyoutFilter) - ! Get number of energies on filter - n = size(eo_filt % bins) - ! Since the creation of fission sites is weighted such that it is ! expected to create n_particles sites, we need to multiply the ! score by keff to get the true nu-fission rate. Otherwise, the sum @@ -2397,7 +2394,7 @@ contains ! modify the value so that g_out = 1 corresponds to the highest ! energy bin - g_out = size(eo_filt % bins) - g_out + g_out = eo_filt % n_bins - g_out + 1 ! change outgoing energy bin call filter_matches(i) % bins_set_data(i_bin, g_out) @@ -2412,12 +2409,11 @@ contains % E)) end if - ! check if outgoing energy is within specified range on filter - if (E_out < eo_filt % bins(1) .or. E_out > eo_filt % bins(n)) cycle - - ! change outgoing energy bin - call filter_matches(i) % bins_set_data(i_bin, & - binary_search(eo_filt % bins, n, E_out)) + ! If this outgoing energy falls within the energyout filter's range, + ! set the appropriate filter_matches bin. + i_match = eo_filt % search(E_out) + if (i_match == -1) cycle + call filter_matches(i) % bins_set_data(i_bin, i_match) end if diff --git a/src/tallies/tally_filter_energy.F90 b/src/tallies/tally_filter_energy.F90 index 338384f9d9..af55025630 100644 --- a/src/tallies/tally_filter_energy.F90 +++ b/src/tallies/tally_filter_energy.F90 @@ -2,14 +2,6 @@ module tally_filter_energy use, intrinsic :: ISO_C_BINDING - use algorithm, only: binary_search - use constants - use error - use hdf5_interface - use mgxs_interface, only: num_energy_groups, rev_energy_bins - use particle_header, only: Particle - use settings, only: run_CE - use string, only: to_str use tally_filter_cpp use xml_interface @@ -18,17 +10,33 @@ module tally_filter_energy public :: openmc_energy_filter_get_bins public :: openmc_energy_filter_set_bins + interface + function openmc_energy_filter_get_bins(index, energies, n) result(err) bind(C) + import C_INT32_T, C_PTR, C_INT + integer(C_INT32_T), value :: index + type(C_PTR), intent(out) :: energies + integer(C_INT32_T), intent(out) :: n + integer(C_INT) :: err + end function + function openmc_energy_filter_set_bins(index, n, energies) result(err) bind(C) + import C_INT32_T, C_DOUBLE, C_INT + integer(C_INT32_T), value, intent(in) :: index + integer(C_INT32_T), value, intent(in) :: n + real(C_DOUBLE), intent(in) :: energies(n) + integer(C_INT) :: err + end function + end interface + !=============================================================================== ! ENERGYFILTER bins the incident neutron energy. !=============================================================================== type, public, extends(CppTallyFilter) :: EnergyFilter - real(8), allocatable :: bins(:) - ! True if transport group number can be used directly to get bin number logical :: matches_transport_groups = .false. contains procedure :: from_xml => from_xml_energy + procedure :: search end type EnergyFilter !=============================================================================== @@ -50,86 +58,34 @@ contains class(EnergyFilter), intent(inout) :: this type(XMLNode), intent(in) :: node - integer :: n + interface + function energy_filter_matches_transport_groups(filt) result(matches) & + bind(C) + import C_PTR, C_BOOL + type(C_PTR), value :: filt + logical(C_BOOL) :: matches + end function + end interface call this % from_xml_cpp_inner(node) - - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - 1 - allocate(this % bins(n)) - call get_node_array(node, "bins", this % bins) - - ! We can save tallying time if we know that the tally bins match - ! the energy group structure. In that case, the matching bin - ! index is simply the group (after flipping for the different - ! ordering of the library and tallying systems). - if (.not. run_CE) then - if (n == num_energy_groups + 1) then - if (all(this % bins == rev_energy_bins)) & - then - this % matches_transport_groups = .true. - end if - end if - end if + this % n_bins = this % n_bins_cpp() + this % matches_transport_groups = & + energy_filter_matches_transport_groups(this % ptr) end subroutine from_xml_energy -!=============================================================================== -! C API FUNCTIONS -!=============================================================================== - - function openmc_energy_filter_get_bins(index, energies, n) result(err) bind(C) - ! Return the bounding energies for an energy filter - integer(C_INT32_T), value :: index - type(C_PTR), intent(out) :: energies - integer(C_INT32_T), intent(out) :: n - integer(C_INT) :: err - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (EnergyFilter) - energies = C_LOC(f % bins) - n = size(f % bins) - err = 0 - type is (EnergyoutFilter) - energies = C_LOC(f % bins) - n = size(f % bins) - err = 0 - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to get energy bins on a non-energy filter.") - end select - end if - end function openmc_energy_filter_get_bins - - - function openmc_energy_filter_set_bins(index, n, energies) result(err) bind(C) - ! Set the bounding energies for an energy filter - integer(C_INT32_T), value, intent(in) :: index - integer(C_INT32_T), value, intent(in) :: n - real(C_DOUBLE), intent(in) :: energies(n) - integer(C_INT) :: err - - err = verify_filter(index) - if (err == 0) then - select type (f => filters(index) % obj) - type is (EnergyFilter) - f % n_bins = n - 1 - if (allocated(f % bins)) deallocate(f % bins) - allocate(f % bins(n)) - f % bins(:) = energies - type is (EnergyoutFilter) - f % n_bins = n - 1 - if (allocated(f % bins)) deallocate(f % bins) - allocate(f % bins(n)) - f % bins(:) = energies - class default - err = E_INVALID_TYPE - call set_errmsg("Tried to get energy bins on a non-energy filter.") - end select - end if - end function openmc_energy_filter_set_bins + function search(this, val) result(bin) + class(EnergyFilter), intent(in) :: this + real(8), intent(in) :: val + integer :: bin + interface + function energy_filter_search(filt, val) result(bin) bind(C) + import C_PTR, C_DOUBLE, C_INT + type(C_PTR), value :: filt + real(C_DOUBLE), value :: val + integer(C_INT) :: bin + end function + end interface + bin = energy_filter_search(this % ptr, val) + end function search end module tally_filter_energy From 69c65ddf23a51abf86882597eb3281531e49f053 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 28 Oct 2018 15:52:01 -0400 Subject: [PATCH 03/10] Move the DelayedGroupFilter to C++ --- CMakeLists.txt | 1 + include/openmc/tallies/filter_delayedgroup.h | 37 +++++++++ src/tallies/filter.cpp | 3 + src/tallies/filter_delayedgroup.cpp | 57 ++++++++++++++ src/tallies/tally_filter_delayedgroup.F90 | 80 ++++---------------- 5 files changed, 114 insertions(+), 64 deletions(-) create mode 100644 include/openmc/tallies/filter_delayedgroup.h create mode 100644 src/tallies/filter_delayedgroup.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 636c5fb532..283e444a61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -436,6 +436,7 @@ add_library(libopenmc SHARED src/tallies/filter_cellborn.cpp src/tallies/filter_cellfrom.cpp src/tallies/filter_cell.cpp + src/tallies/filter_delayedgroup.cpp src/tallies/filter_distribcell.cpp src/tallies/filter_energyfunc.cpp src/tallies/filter_energy.cpp diff --git a/include/openmc/tallies/filter_delayedgroup.h b/include/openmc/tallies/filter_delayedgroup.h new file mode 100644 index 0000000000..2f65a50593 --- /dev/null +++ b/include/openmc/tallies/filter_delayedgroup.h @@ -0,0 +1,37 @@ +#ifndef OPENMC_TALLIES_FILTER_DELAYEDGROUP_H +#define OPENMC_TALLIES_FILTER_DELAYEDGROUP_H + +#include + +#include "openmc/tallies/filter.h" + +namespace openmc { + +//============================================================================== +//! Bins outgoing fission neutrons in their delayed groups. +//! +//! The get_all_bins functionality is not actually used. The bins are manually +//! iterated over in the scoring subroutines. +//============================================================================== + +class DelayedGroupFilter : public Filter +{ +public: + ~DelayedGroupFilter() = default; + + std::string type() const override {return "delayedgroup";} + + void from_xml(pugi::xml_node node) override; + + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) + const override; + + void to_statepoint(hid_t filter_group) const override; + + std::string text_label(int bin) const override; + + std::vector groups_; +}; + +} // namespace openmc +#endif // OPENMC_TALLIES_FILTER_DELAYEDGROUP_H diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index cd79d44ae9..08461de212 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -9,6 +9,7 @@ #include "openmc/tallies/filter_cell.h" #include "openmc/tallies/filter_cellborn.h" #include "openmc/tallies/filter_cellfrom.h" +#include "openmc/tallies/filter_delayedgroup.h" #include "openmc/tallies/filter_distribcell.h" #include "openmc/tallies/filter_energyfunc.h" #include "openmc/tallies/filter_energy.h" @@ -104,6 +105,8 @@ extern "C" { tally_filters.push_back(new CellFromFilter()); } else if (type_ == "distribcell") { tally_filters.push_back(new DistribcellFilter()); + } else if (type_ == "delayedgroup") { + tally_filters.push_back(new DelayedGroupFilter()); } else if (type_ == "energyfunction") { tally_filters.push_back(new EnergyFunctionFilter()); } else if (type_ == "energy") { diff --git a/src/tallies/filter_delayedgroup.cpp b/src/tallies/filter_delayedgroup.cpp new file mode 100644 index 0000000000..fd7a3c85a5 --- /dev/null +++ b/src/tallies/filter_delayedgroup.cpp @@ -0,0 +1,57 @@ +#include "openmc/tallies/filter_delayedgroup.h" + +#include "openmc/error.h" +#include "openmc/xml_interface.h" + +namespace openmc { + +void +DelayedGroupFilter::from_xml(pugi::xml_node node) +{ + groups_ = get_node_array(node, "bins"); + n_bins_ = groups_.size(); + + // Make sure all the group index values are valid. + // TODO: do these need to be decremented for zero-based indexing? + for (auto group : groups_) { + if (group < 1) { + fatal_error("Encountered delayedgroup bin with index " + + std::to_string(group) + " which is less than 1"); + } else if (group > MAX_DELAYED_GROUPS) { + fatal_error("Encountered delayedgroup bin with index " + + std::to_string(group) + " which is greater than MAX_DELATED_GROUPS (" + + std::to_string(MAX_DELAYED_GROUPS) + ")"); + } + } +} + +void +DelayedGroupFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const +{ + //TODO: off-by-one + match.bins_.push_back(1); + match.weights_.push_back(1.0); +} + +void +DelayedGroupFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", groups_); +} + +std::string +DelayedGroupFilter::text_label(int bin) const +{ + return "Delayed Group " + std::to_string(groups_[bin-1]); +} + +//============================================================================== +// Fortran interoperability +//============================================================================== + +extern "C" int delayedgroup_filter_groups(DelayedGroupFilter* filt, int i) +{return filt->groups_[i-1];} + +} // namespace openmc diff --git a/src/tallies/tally_filter_delayedgroup.F90 b/src/tallies/tally_filter_delayedgroup.F90 index 130469a71b..82e36753df 100644 --- a/src/tallies/tally_filter_delayedgroup.F90 +++ b/src/tallies/tally_filter_delayedgroup.F90 @@ -2,13 +2,7 @@ module tally_filter_delayedgroup use, intrinsic :: ISO_C_BINDING - use constants, only: ONE, MAX_LINE_LEN, MAX_DELAYED_GROUPS - use error, only: fatal_error - use hdf5_interface - use particle_header, only: Particle - use string, only: to_str - use tally_filter_header - use xml_interface + use tally_filter_cpp implicit none private @@ -19,68 +13,26 @@ module tally_filter_delayedgroup ! iterated over in the scoring subroutines. !=============================================================================== - type, public, extends(TallyFilter) :: DelayedGroupFilter - integer, allocatable :: groups(:) + type, public, extends(CppTallyFilter) :: DelayedGroupFilter contains - procedure :: from_xml - procedure :: get_all_bins => get_all_bins_dg - procedure :: to_statepoint => to_statepoint_dg - procedure :: text_label => text_label_dg + procedure :: groups end type DelayedGroupFilter contains - subroutine from_xml(this, node) - class(DelayedGroupFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: i - integer :: n - - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - allocate(this % groups(n)) - call get_node_array(node, "bins", this % groups) - - ! Check that bins are all are between 1 and MAX_DELAYED_GROUPS - do i = 1, n - if (this % groups(i) < 1 .or. & - this % groups(i) > MAX_DELAYED_GROUPS) then - call fatal_error("Encountered delayedgroup bin with index " & - // trim(to_str(this % groups(i))) // " that is outside & - &the range of 1 to MAX_DELAYED_GROUPS ( " & - // trim(to_str(MAX_DELAYED_GROUPS)) // ")") - end if - end do - end subroutine from_xml - - subroutine get_all_bins_dg(this, p, estimator, match) - class(DelayedGroupFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - call match % bins_push_back(1) - call match % weights_push_back(ONE) - end subroutine get_all_bins_dg - - subroutine to_statepoint_dg(this, filter_group) + function groups(this, i) result(group) class(DelayedGroupFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "delayedgroup") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", this % groups) - end subroutine to_statepoint_dg - - function text_label_dg(this, bin) result(label) - class(DelayedGroupFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = "Delayed Group " // to_str(this % groups(bin)) - end function text_label_dg + integer, intent(in) :: i + integer :: group + interface + function delayedgroup_filter_groups(filt, i) result(group) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT), value :: i + integer(C_INT) :: group + end function + end interface + group = delayedgroup_filter_groups(this % ptr, i) + end function groups end module tally_filter_delayedgroup From bdac2854cee1b78625054b12c94f9879a43f64df Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 28 Oct 2018 16:26:22 -0400 Subject: [PATCH 04/10] Move ParticleFilter to C++ --- CMakeLists.txt | 1 + include/openmc/tallies/filter_particle.h | 34 +++++++++++ src/tallies/filter.cpp | 3 + src/tallies/filter_delayedgroup.cpp | 2 +- src/tallies/filter_particle.cpp | 47 +++++++++++++++ src/tallies/tally_filter_particle.F90 | 74 +++++------------------- 6 files changed, 102 insertions(+), 59 deletions(-) create mode 100644 include/openmc/tallies/filter_particle.h create mode 100644 src/tallies/filter_particle.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 283e444a61..0bfea87405 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -445,6 +445,7 @@ add_library(libopenmc SHARED src/tallies/filter_mesh.cpp src/tallies/filter_meshsurface.cpp src/tallies/filter_mu.cpp + src/tallies/filter_particle.cpp src/tallies/filter_polar.cpp src/tallies/filter_sph_harm.cpp src/tallies/filter_sptl_legendre.cpp diff --git a/include/openmc/tallies/filter_particle.h b/include/openmc/tallies/filter_particle.h new file mode 100644 index 0000000000..9f9328ace7 --- /dev/null +++ b/include/openmc/tallies/filter_particle.h @@ -0,0 +1,34 @@ +#ifndef OPENMC_TALLIES_FILTER_PARTICLE_H +#define OPENMC_TALLIES_FILTER_PARTICLE_H + +#include + +#include "openmc/tallies/filter.h" + +namespace openmc { + +//============================================================================== +//! Bins by type of particle (e.g. neutron, photon). +//============================================================================== + +class ParticleFilter : public Filter +{ +public: + ~ParticleFilter() = default; + + std::string type() const override {return "particle";} + + void from_xml(pugi::xml_node node) override; + + void get_all_bins(const Particle* p, int estimator, FilterMatch& match) + const override; + + void to_statepoint(hid_t filter_group) const override; + + std::string text_label(int bin) const override; + + std::vector particles_; +}; + +} // namespace openmc +#endif // OPENMC_TALLIES_FILTER_PARTICLE_H diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index 08461de212..5905f20b5c 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -18,6 +18,7 @@ #include "openmc/tallies/filter_mesh.h" #include "openmc/tallies/filter_meshsurface.h" #include "openmc/tallies/filter_mu.h" +#include "openmc/tallies/filter_particle.h" #include "openmc/tallies/filter_polar.h" #include "openmc/tallies/filter_sph_harm.h" #include "openmc/tallies/filter_sptl_legendre.h" @@ -123,6 +124,8 @@ extern "C" { tally_filters.push_back(new MeshSurfaceFilter()); } else if (type_ == "mu") { tally_filters.push_back(new MuFilter()); + } else if (type_ == "particle") { + tally_filters.push_back(new ParticleFilter()); } else if (type_ == "polar") { tally_filters.push_back(new PolarFilter()); } else if (type_ == "surface") { diff --git a/src/tallies/filter_delayedgroup.cpp b/src/tallies/filter_delayedgroup.cpp index fd7a3c85a5..ac226b74db 100644 --- a/src/tallies/filter_delayedgroup.cpp +++ b/src/tallies/filter_delayedgroup.cpp @@ -27,7 +27,7 @@ DelayedGroupFilter::from_xml(pugi::xml_node node) void DelayedGroupFilter::get_all_bins(const Particle* p, int estimator, - FilterMatch& match) const + FilterMatch& match) const { //TODO: off-by-one match.bins_.push_back(1); diff --git a/src/tallies/filter_particle.cpp b/src/tallies/filter_particle.cpp new file mode 100644 index 0000000000..251bb1011a --- /dev/null +++ b/src/tallies/filter_particle.cpp @@ -0,0 +1,47 @@ +#include "openmc/tallies/filter_particle.h" + +#include "openmc/xml_interface.h" + +namespace openmc { + +void +ParticleFilter::from_xml(pugi::xml_node node) +{ + particles_ = get_node_array(node, "bins"); + n_bins_ = particles_.size(); +} + +void +ParticleFilter::get_all_bins(const Particle* p, int estimator, + FilterMatch& match) const +{ + for (auto i = 0; i < particles_.size(); i++) { + if (particles_[i] == p->type) { + //TODO: off-by-one + match.bins_.push_back(i + 1); + match.weights_.push_back(1.0); + } + } +} + +void +ParticleFilter::to_statepoint(hid_t filter_group) const +{ + Filter::to_statepoint(filter_group); + write_dataset(filter_group, "bins", particles_); +} + +std::string +ParticleFilter::text_label(int bin) const +{ + return "Particle " + std::to_string(particles_[bin-1]); +} + +//============================================================================== +// Fortran interoperability +//============================================================================== + +extern "C" int particle_filter_particles(ParticleFilter* filt, int i) +{return filt->particles_[i];} + +} // namespace openmc diff --git a/src/tallies/tally_filter_particle.F90 b/src/tallies/tally_filter_particle.F90 index 665ea5cf3f..611bbf29ee 100644 --- a/src/tallies/tally_filter_particle.F90 +++ b/src/tallies/tally_filter_particle.F90 @@ -2,12 +2,7 @@ module tally_filter_particle use, intrinsic :: ISO_C_BINDING - use constants, only: ONE, MAX_LINE_LEN - use hdf5_interface - use particle_header, only: Particle - use string, only: to_str - use tally_filter_header - use xml_interface + use tally_filter_cpp implicit none private @@ -16,63 +11,26 @@ module tally_filter_particle ! PARTICLEFILTER specifies what particles can score to a tally !=============================================================================== - type, public, extends(TallyFilter) :: ParticleFilter - integer, allocatable :: particles(:) + type, public, extends(CppTallyFilter) :: ParticleFilter contains - procedure :: from_xml - procedure :: get_all_bins - procedure :: to_statepoint - procedure :: text_label + procedure :: particles end type ParticleFilter contains - subroutine from_xml(this, node) - class(ParticleFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - - integer :: n - - ! Determine how many bins were given - n = node_word_count(node, "bins") - - ! Allocate and store bins - this % n_bins = n - allocate(this % particles(n)) - call get_node_array(node, "bins", this % particles) - end subroutine from_xml - - subroutine get_all_bins(this, p, estimator, match) - class(ParticleFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - - integer :: i - - do i = 1, this % n_bins - if (this % particles(i) == p % type) then - call match % bins_push_back(i) - call match % weights_push_back(ONE) - end if - end do - end subroutine get_all_bins - - subroutine to_statepoint(this, filter_group) + function particles(this, i) result(ptype) class(ParticleFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - - call write_dataset(filter_group, "type", "particle") - call write_dataset(filter_group, "n_bins", this % n_bins) - call write_dataset(filter_group, "bins", this % particles) - end subroutine to_statepoint - - function text_label(this, bin) result(label) - class(ParticleFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - - label = "Particle " // to_str(this % particles(bin)) - end function text_label + integer, intent(in) :: i + integer :: ptype + interface + function particle_filter_particles(filt, i) result(ptype) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT), value :: i + integer(C_INT) :: ptype + end function + end interface + ptype = particle_filter_particles(this % ptr, i) + end function particles end module tally_filter_particle From a65ea4cce8d2316b7afa7c2985d75f3e3c07a99d Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 28 Oct 2018 19:18:34 -0400 Subject: [PATCH 05/10] Remove unnecessary wrapper code --- include/openmc/tallies/filter_energy.h | 2 - src/tallies/tally_filter_cpp.F90 | 78 +++++++++----------------- 2 files changed, 27 insertions(+), 53 deletions(-) diff --git a/include/openmc/tallies/filter_energy.h b/include/openmc/tallies/filter_energy.h index fb027c130a..025a77c624 100644 --- a/include/openmc/tallies/filter_energy.h +++ b/include/openmc/tallies/filter_energy.h @@ -1,8 +1,6 @@ #ifndef OPENMC_TALLIES_FILTER_ENERGY_H #define OPENMC_TALLIES_FILTER_ENERGY_H -//#include -//#include #include #include "openmc/tallies/filter.h" diff --git a/src/tallies/tally_filter_cpp.F90 b/src/tallies/tally_filter_cpp.F90 index d0e8abfb4a..40c77edd8f 100644 --- a/src/tallies/tally_filter_cpp.F90 +++ b/src/tallies/tally_filter_cpp.F90 @@ -22,14 +22,11 @@ module tally_filter_cpp contains procedure :: n_bins_cpp procedure :: from_xml_cpp_inner - procedure :: get_all_bins_cpp_inner - procedure :: to_statepoint_cpp_inner - procedure :: text_label_cpp_inner procedure :: initialize_cpp_inner procedure :: from_xml => from_xml_cpp_default - procedure :: get_all_bins => get_all_bins_cpp_default - procedure :: to_statepoint => to_statepoint_cpp_default - procedure :: text_label => text_label_cpp_default + procedure :: get_all_bins => get_all_bins_cpp + procedure :: to_statepoint => to_statepoint_cpp + procedure :: text_label => text_label_cpp procedure :: initialize => initialize_cpp_default end type CppTallyFilter @@ -110,7 +107,25 @@ contains call filter_from_xml(this % ptr, node % ptr) end subroutine from_xml_cpp_inner - subroutine get_all_bins_cpp_inner(this, p, estimator, match) + subroutine initialize_cpp_inner(this) + class(CppTallyFilter), intent(inout) :: this + interface + subroutine filter_initialize(filt) bind(C) + import C_PTR + type(C_PTR), value :: filt + end subroutine filter_initialize + end interface + call filter_initialize(this % ptr) + end subroutine initialize_cpp_inner + + subroutine from_xml_cpp_default(this, node) + class(CppTallyFilter), intent(inout) :: this + type(XMLNode), intent(in) :: node + call this % from_xml_cpp_inner(node) + this % n_bins = this % n_bins_cpp() + end subroutine from_xml_cpp_default + + subroutine get_all_bins_cpp(this, p, estimator, match) class(CppTallyFilter), intent(in) :: this type(Particle), intent(in) :: p integer, intent(in) :: estimator @@ -125,9 +140,9 @@ contains end subroutine filter_get_all_bins end interface call filter_get_all_bins(this % ptr, p, estimator, match % ptr) - end subroutine get_all_bins_cpp_inner + end subroutine get_all_bins_cpp - subroutine to_statepoint_cpp_inner(this, filter_group) + subroutine to_statepoint_cpp(this, filter_group) class(CppTallyFilter), intent(in) :: this integer(HID_T), intent(in) :: filter_group interface @@ -138,9 +153,9 @@ contains end subroutine filter_to_statepoint end interface call filter_to_statepoint(this % ptr, filter_group) - end subroutine to_statepoint_cpp_inner + end subroutine to_statepoint_cpp - function text_label_cpp_inner(this, bin) result(label) + function text_label_cpp(this, bin) result(label) class(CppTallyFilter), intent(in) :: this integer, intent(in) :: bin character(MAX_LINE_LEN) :: label @@ -160,46 +175,7 @@ contains if (label_(i) == C_NULL_CHAR) exit label(i:i) = label_(i) end do - end function text_label_cpp_inner - - subroutine initialize_cpp_inner(this) - class(CppTallyFilter), intent(inout) :: this - interface - subroutine filter_initialize(filt) bind(C) - import C_PTR - type(C_PTR), value :: filt - end subroutine filter_initialize - end interface - call filter_initialize(this % ptr) - end subroutine initialize_cpp_inner - - subroutine from_xml_cpp_default(this, node) - class(CppTallyFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - call this % from_xml_cpp_inner(node) - this % n_bins = this % n_bins_cpp() - end subroutine from_xml_cpp_default - - subroutine get_all_bins_cpp_default(this, p, estimator, match) - class(CppTallyFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - call this % get_all_bins_cpp_inner(p, estimator, match) - end subroutine get_all_bins_cpp_default - - subroutine to_statepoint_cpp_default(this, filter_group) - class(CppTallyFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - call this % to_statepoint_cpp_inner(filter_group) - end subroutine to_statepoint_cpp_default - - function text_label_cpp_default(this, bin) result(label) - class(CppTallyFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - label = this % text_label_cpp_inner(bin) - end function text_label_cpp_default + end function text_label_cpp subroutine initialize_cpp_default(this) class(CppTallyFilter), intent(inout) :: this From 89bf3a6afb53efa0cfe6cd049b11343d7b7bb0be Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 28 Oct 2018 20:51:36 -0400 Subject: [PATCH 06/10] Move CppTallyFilter functionality to TallyFilter --- CMakeLists.txt | 1 - src/tallies/tally_filter.F90 | 13 +- src/tallies/tally_filter_cpp.F90 | 211 -------------------- src/tallies/tally_filter_delayedgroup.F90 | 4 +- src/tallies/tally_filter_distribcell.F90 | 6 +- src/tallies/tally_filter_energy.F90 | 6 +- src/tallies/tally_filter_header.F90 | 222 ++++++++++++++++------ src/tallies/tally_filter_legendre.F90 | 4 +- src/tallies/tally_filter_mesh.F90 | 4 +- src/tallies/tally_filter_meshsurface.F90 | 4 +- src/tallies/tally_filter_particle.F90 | 4 +- src/tallies/tally_filter_sph_harm.F90 | 4 +- 12 files changed, 190 insertions(+), 293 deletions(-) delete mode 100644 src/tallies/tally_filter_cpp.F90 diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bfea87405..2dd13529bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -373,7 +373,6 @@ add_library(libopenmc SHARED src/tallies/tally_derivative_header.F90 src/tallies/tally_filter.F90 src/tallies/tally_filter_header.F90 - src/tallies/tally_filter_cpp.F90 src/tallies/tally_filter_delayedgroup.F90 src/tallies/tally_filter_distribcell.F90 src/tallies/tally_filter_energy.F90 diff --git a/src/tallies/tally_filter.F90 b/src/tallies/tally_filter.F90 index 98b7bf9a37..da644b16f2 100644 --- a/src/tallies/tally_filter.F90 +++ b/src/tallies/tally_filter.F90 @@ -170,14 +170,11 @@ contains call set_errmsg("Unknown filter type: " // trim(type_)) end select - select type(filt => filters(index) % obj) - class is (CppTallyFilter) - filt % ptr = allocate_filter(type) - if (.not. c_associated(filt % ptr)) then - err = E_UNASSIGNED - call set_errmsg("Could not allocate C++ tally filter") - end if - end select + filters(index) % obj % ptr = allocate_filter(type) + if (.not. c_associated(filters(index) % obj % ptr)) then + err = E_UNASSIGNED + call set_errmsg("Could not allocate C++ tally filter") + end if end if else diff --git a/src/tallies/tally_filter_cpp.F90 b/src/tallies/tally_filter_cpp.F90 deleted file mode 100644 index 40c77edd8f..0000000000 --- a/src/tallies/tally_filter_cpp.F90 +++ /dev/null @@ -1,211 +0,0 @@ -module tally_filter_cpp - use, intrinsic :: ISO_C_BINDING - - use constants, only: MAX_LINE_LEN - use hdf5_interface, only: HID_T - use particle_header, only: Particle - use tally_filter_header - use xml_interface, only: XMLNode - - implicit none - -!=============================================================================== -! CPPTALLYFILTER is a TallyFilter that is at least partially implemented in C++. -! -! Moving a tally to C++ is easier if done piece-by-piece, so this filter has -! *_cpp_inner procedures that allows the Fortran code to override e.g. -! get_all_bins and still call the C++ implementation for side-by-side comparison -!=============================================================================== - - type, abstract, extends(TallyFilter) :: CppTallyFilter - type(C_PTR) :: ptr - contains - procedure :: n_bins_cpp - procedure :: from_xml_cpp_inner - procedure :: initialize_cpp_inner - procedure :: from_xml => from_xml_cpp_default - procedure :: get_all_bins => get_all_bins_cpp - procedure :: to_statepoint => to_statepoint_cpp - procedure :: text_label => text_label_cpp - procedure :: initialize => initialize_cpp_default - end type CppTallyFilter - -!=============================================================================== -! Pure C++ filters -!=============================================================================== - - type, extends(CppTallyFilter) :: AzimuthalFilter - end type - - type, extends(CppTallyFilter) :: CellFilter - end type - - type, extends(CppTallyFilter) :: CellbornFilter - end type - - type, extends(CellFilter) :: CellFromFilter - end type - - type, extends(CppTallyFilter) :: EnergyFunctionFilter - end type - - type, extends(CppTallyFilter) :: MaterialFilter - end type - - type, extends(CppTallyFilter) :: MuFilter - end type - - type, extends(CppTallyFilter) :: PolarFilter - end type - - type, extends(CppTallyFilter) :: SpatialLegendreFilter - end type - - type, extends(CppTallyFilter) :: SurfaceFilter - ! True if this filter is used for surface currents - logical :: current = .false. - end type - - type, extends(CppTallyFilter) :: UniverseFilter - end type - - type, extends(CppTallyFilter) :: ZernikeFilter - end type - - type, extends(ZernikeFilter) :: ZernikeRadialFilter - end type - -contains - -!=============================================================================== -! CppTallyFilter implementation -!=============================================================================== - - function n_bins_cpp(this) result(n_bins) - class(CppTallyFilter), intent(inout) :: this - integer :: n_bins - interface - function filter_n_bins(filt) result(n_bins) bind(C) - import C_PTR, C_INT - type(C_PTR), value :: filt - integer(C_INT) :: n_bins - end function filter_n_bins - end interface - n_bins = filter_n_bins(this % ptr) - end function n_bins_cpp - - subroutine from_xml_cpp_inner(this, node) - class(CppTallyFilter), intent(inout) :: this - class(XMLNode), intent(in) :: node - interface - subroutine filter_from_xml(filt, node) bind(C) - import C_PTR - type(C_PTR), value :: filt - type(C_PTR) :: node - end subroutine filter_from_xml - end interface - call filter_from_xml(this % ptr, node % ptr) - end subroutine from_xml_cpp_inner - - subroutine initialize_cpp_inner(this) - class(CppTallyFilter), intent(inout) :: this - interface - subroutine filter_initialize(filt) bind(C) - import C_PTR - type(C_PTR), value :: filt - end subroutine filter_initialize - end interface - call filter_initialize(this % ptr) - end subroutine initialize_cpp_inner - - subroutine from_xml_cpp_default(this, node) - class(CppTallyFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - call this % from_xml_cpp_inner(node) - this % n_bins = this % n_bins_cpp() - end subroutine from_xml_cpp_default - - subroutine get_all_bins_cpp(this, p, estimator, match) - class(CppTallyFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - interface - subroutine filter_get_all_bins(filt, p, estimator, match) bind(C) - import C_PTR, Particle, C_INT - type(C_PTR), value :: filt - type(Particle), intent(in) :: p - integer(C_INT), intent(in), value :: estimator - type(C_PTR), value :: match - end subroutine filter_get_all_bins - end interface - call filter_get_all_bins(this % ptr, p, estimator, match % ptr) - end subroutine get_all_bins_cpp - - subroutine to_statepoint_cpp(this, filter_group) - class(CppTallyFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - interface - subroutine filter_to_statepoint(filt, filter_group) bind(C) - import C_PTR, HID_T - type(C_PTR), value :: filt - integer(HID_T), intent(in), value :: filter_group - end subroutine filter_to_statepoint - end interface - call filter_to_statepoint(this % ptr, filter_group) - end subroutine to_statepoint_cpp - - function text_label_cpp(this, bin) result(label) - class(CppTallyFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - character(kind=C_CHAR) :: label_(MAX_LINE_LEN+1) - integer :: i - interface - subroutine filter_text_label(filt, bin, label) bind(C) - import C_PTR, C_INT, C_CHAR - type(C_PTR), value :: filt - integer(C_INT), value :: bin - character(kind=C_CHAR) :: label(*) - end subroutine filter_text_label - end interface - call filter_text_label(this % ptr, bin, label_) - label = " " - do i = 1, MAX_LINE_LEN - if (label_(i) == C_NULL_CHAR) exit - label(i:i) = label_(i) - end do - end function text_label_cpp - - subroutine initialize_cpp_default(this) - class(CppTallyFilter), intent(inout) :: this - call this % initialize_cpp_inner() - end subroutine initialize_cpp_default - -!=============================================================================== -! FILTER_FROM_F given a Fortran index, return a pointer to a C++ filter. -!=============================================================================== - - function filter_from_f(index) result(filt) bind(C) - integer(C_INT32_T), intent(in), value :: index - type(C_PTR) :: filt - - filt = C_NULL_PTR - select type(f => filters(index) % obj) - class is (CppTallyFilter) - filt = f % ptr - end select - end function - -!=============================================================================== -! FILTER_UPDATE_N_BINS given a Fortran index, updates filt % n_bins using C++. -!=============================================================================== - - subroutine filter_update_n_bins(index) bind(C) - integer(C_INT32_T), intent(in), value :: index - select type(f => filters(index) % obj) - class is (CppTallyFilter) - f % n_bins = f % n_bins_cpp() - end select - end subroutine -end module tally_filter_cpp diff --git a/src/tallies/tally_filter_delayedgroup.F90 b/src/tallies/tally_filter_delayedgroup.F90 index 82e36753df..deebb0b1b0 100644 --- a/src/tallies/tally_filter_delayedgroup.F90 +++ b/src/tallies/tally_filter_delayedgroup.F90 @@ -2,7 +2,7 @@ module tally_filter_delayedgroup use, intrinsic :: ISO_C_BINDING - use tally_filter_cpp + use tally_filter_header implicit none private @@ -13,7 +13,7 @@ module tally_filter_delayedgroup ! iterated over in the scoring subroutines. !=============================================================================== - type, public, extends(CppTallyFilter) :: DelayedGroupFilter + type, public, extends(TallyFilter) :: DelayedGroupFilter contains procedure :: groups end type DelayedGroupFilter diff --git a/src/tallies/tally_filter_distribcell.F90 b/src/tallies/tally_filter_distribcell.F90 index 9033ae6a01..8082b43322 100644 --- a/src/tallies/tally_filter_distribcell.F90 +++ b/src/tallies/tally_filter_distribcell.F90 @@ -1,11 +1,11 @@ module tally_filter_distribcell - use tally_filter_cpp + use tally_filter_header implicit none private - type, public, extends(CppTallyFilter) :: DistribcellFilter + type, public, extends(TallyFilter) :: DistribcellFilter contains procedure :: initialize => initialize_distribcell end type DistribcellFilter @@ -14,7 +14,7 @@ contains subroutine initialize_distribcell(this) class(DistribcellFilter), intent(inout) :: this - call this % initialize_cpp_inner() + call this % initialize_cpp() this % n_bins = this % n_bins_cpp() end subroutine initialize_distribcell diff --git a/src/tallies/tally_filter_energy.F90 b/src/tallies/tally_filter_energy.F90 index af55025630..851de7ee8f 100644 --- a/src/tallies/tally_filter_energy.F90 +++ b/src/tallies/tally_filter_energy.F90 @@ -2,7 +2,7 @@ module tally_filter_energy use, intrinsic :: ISO_C_BINDING - use tally_filter_cpp + use tally_filter_header use xml_interface implicit none @@ -31,7 +31,7 @@ module tally_filter_energy ! ENERGYFILTER bins the incident neutron energy. !=============================================================================== - type, public, extends(CppTallyFilter) :: EnergyFilter + type, public, extends(TallyFilter) :: EnergyFilter ! True if transport group number can be used directly to get bin number logical :: matches_transport_groups = .false. contains @@ -67,7 +67,7 @@ contains end function end interface - call this % from_xml_cpp_inner(node) + call this % from_xml_cpp(node) this % n_bins = this % n_bins_cpp() this % matches_transport_groups = & energy_filter_matches_transport_groups(this % ptr) diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 4116934b33..e79b2fa368 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -62,66 +62,62 @@ module tally_filter_header type, public, abstract :: TallyFilter integer :: id integer :: n_bins = 0 + type(C_PTR) :: ptr contains - procedure(from_xml_), deferred :: from_xml - procedure(get_all_bins_), deferred :: get_all_bins - procedure(to_statepoint_), deferred :: to_statepoint - procedure(text_label_), deferred :: text_label - procedure :: initialize => filter_initialize + procedure :: from_xml + procedure :: get_all_bins + procedure :: to_statepoint + procedure :: text_label + procedure :: initialize + procedure :: n_bins_cpp + procedure :: from_xml_cpp + procedure :: initialize_cpp end type TallyFilter - abstract interface - - subroutine from_xml_(this, node) - import TallyFilter, XMLNode - class(TallyFilter), intent(inout) :: this - type(XMLNode), intent(in) :: node - end subroutine from_xml_ - !=============================================================================== -! GET_NEXT_BIN gives the index for the next valid filter bin and a weight that -! will be applied to the flux. -! -! In principle, a filter can have multiple valid bins. If current_bin = -! NO_BIN_FOUND, then this method should give the first valid bin. Providing the -! first valid bin should then give the second valid bin, and so on. When there -! are no valid bins left, the next_bin should be NO_VALID_BIN. - - subroutine get_all_bins_(this, p, estimator, match) - import TallyFilter - import Particle - import TallyFilterMatch - class(TallyFilter), intent(in) :: this - type(Particle), intent(in) :: p - integer, intent(in) :: estimator - type(TallyFilterMatch), intent(inout) :: match - end subroutine get_all_bins_ - +! Pure C++ filters !=============================================================================== -! TO_STATEPOINT writes all the information needed to reconstruct the filter to -! the given filter_group. - subroutine to_statepoint_(this, filter_group) - import TallyFilter - import HID_T - class(TallyFilter), intent(in) :: this - integer(HID_T), intent(in) :: filter_group - end subroutine to_statepoint_ + type, public, extends(TallyFilter) :: AzimuthalFilter + end type -!=============================================================================== -! TEXT_LABEL returns a string describing the given filter bin. For example, an -! energy filter might return the string "Incoming Energy [0.625E-6, 20.0)". -! This is used to write the tallies.out file. + type, public, extends(TallyFilter) :: CellFilter + end type - function text_label_(this, bin) result(label) - import TallyFilter - import MAX_LINE_LEN - class(TallyFilter), intent(in) :: this - integer, intent(in) :: bin - character(MAX_LINE_LEN) :: label - end function text_label_ + type, public, extends(TallyFilter) :: CellbornFilter + end type - end interface + type, public, extends(CellFilter) :: CellFromFilter + end type + + type, public, extends(TallyFilter) :: EnergyFunctionFilter + end type + + type, public, extends(TallyFilter) :: MaterialFilter + end type + + type, public, extends(TallyFilter) :: MuFilter + end type + + type, public, extends(TallyFilter) :: PolarFilter + end type + + type, public, extends(TallyFilter) :: SpatialLegendreFilter + end type + + type, public, extends(TallyFilter) :: SurfaceFilter + ! True if this filter is used for surface currents + logical :: current = .false. + end type + + type, public, extends(TallyFilter) :: UniverseFilter + end type + + type, public, extends(TallyFilter) :: ZernikeFilter + end type + + type, public, extends(ZernikeFilter) :: ZernikeRadialFilter + end type !=============================================================================== ! TALLYFILTERCONTAINER contains an allocatable TallyFilter object for arrays of @@ -258,12 +254,128 @@ contains end subroutine bins_set_data !=============================================================================== -! INITIALIZE sets up any internal data, as necessary. If this procedure is not -! overriden by the derived class, then it will do nothing by default. +! TallyFilter implementation +!=============================================================================== - subroutine filter_initialize(this) + subroutine from_xml(this, node) class(TallyFilter), intent(inout) :: this - end subroutine filter_initialize + type(XMLNode), intent(in) :: node + call this % from_xml_cpp(node) + this % n_bins = this % n_bins_cpp() + end subroutine from_xml + + subroutine get_all_bins(this, p, estimator, match) + class(TallyFilter), intent(in) :: this + type(Particle), intent(in) :: p + integer, intent(in) :: estimator + type(TallyFilterMatch), intent(inout) :: match + interface + subroutine filter_get_all_bins(filt, p, estimator, match) bind(C) + import C_PTR, Particle, C_INT + type(C_PTR), value :: filt + type(Particle), intent(in) :: p + integer(C_INT), intent(in), value :: estimator + type(C_PTR), value :: match + end subroutine filter_get_all_bins + end interface + call filter_get_all_bins(this % ptr, p, estimator, match % ptr) + end subroutine get_all_bins + + subroutine to_statepoint(this, filter_group) + class(TallyFilter), intent(in) :: this + integer(HID_T), intent(in) :: filter_group + interface + subroutine filter_to_statepoint(filt, filter_group) bind(C) + import C_PTR, HID_T + type(C_PTR), value :: filt + integer(HID_T), intent(in), value :: filter_group + end subroutine filter_to_statepoint + end interface + call filter_to_statepoint(this % ptr, filter_group) + end subroutine to_statepoint + + function text_label(this, bin) result(label) + class(TallyFilter), intent(in) :: this + integer, intent(in) :: bin + character(MAX_LINE_LEN) :: label + character(kind=C_CHAR) :: label_(MAX_LINE_LEN+1) + integer :: i + interface + subroutine filter_text_label(filt, bin, label) bind(C) + import C_PTR, C_INT, C_CHAR + type(C_PTR), value :: filt + integer(C_INT), value :: bin + character(kind=C_CHAR) :: label(*) + end subroutine filter_text_label + end interface + call filter_text_label(this % ptr, bin, label_) + label = " " + do i = 1, MAX_LINE_LEN + if (label_(i) == C_NULL_CHAR) exit + label(i:i) = label_(i) + end do + end function text_label + + subroutine initialize(this) + class(TallyFilter), intent(inout) :: this + call this % initialize_cpp() + end subroutine initialize + + function n_bins_cpp(this) result(n_bins) + class(TallyFilter), intent(in) :: this + integer :: n_bins + interface + function filter_n_bins(filt) result(n_bins) bind(C) + import C_PTR, C_INT + type(C_PTR), value :: filt + integer(C_INT) :: n_bins + end function filter_n_bins + end interface + n_bins = filter_n_bins(this % ptr) + end function n_bins_cpp + + subroutine from_xml_cpp(this, node) + class(TallyFilter), intent(inout) :: this + class(XMLNode), intent(in) :: node + interface + subroutine filter_from_xml(filt, node) bind(C) + import C_PTR + type(C_PTR), value :: filt + type(C_PTR) :: node + end subroutine filter_from_xml + end interface + call filter_from_xml(this % ptr, node % ptr) + end subroutine from_xml_cpp + + subroutine initialize_cpp(this) + class(TallyFilter), intent(inout) :: this + interface + subroutine filter_initialize(filt) bind(C) + import C_PTR + type(C_PTR), value :: filt + end subroutine filter_initialize + end interface + call filter_initialize(this % ptr) + end subroutine initialize_cpp + +!=============================================================================== +! FILTER_FROM_F given a Fortran index, return a pointer to a C++ filter. +!=============================================================================== + + function filter_from_f(index) result(filt) bind(C) + integer(C_INT32_T), intent(in), value :: index + type(C_PTR) :: filt + filt = filters(index) % obj % ptr + end function + +!=============================================================================== +! FILTER_UPDATE_N_BINS given a Fortran index, updates filt % n_bins using C++. +!=============================================================================== + + subroutine filter_update_n_bins(index) bind(C) + integer(C_INT32_T), intent(in), value :: index + filters(index) % obj % n_bins = filters(index) % obj % n_bins_cpp() + end subroutine !=============================================================================== ! FREE_MEMORY_TALLY_FILTER deallocates global arrays defined in this module diff --git a/src/tallies/tally_filter_legendre.F90 b/src/tallies/tally_filter_legendre.F90 index 9c0f9e41a3..e5eb34bc05 100644 --- a/src/tallies/tally_filter_legendre.F90 +++ b/src/tallies/tally_filter_legendre.F90 @@ -2,7 +2,7 @@ module tally_filter_legendre use, intrinsic :: ISO_C_BINDING - use tally_filter_cpp + use tally_filter_header implicit none @@ -15,7 +15,7 @@ module tally_filter_legendre end function end interface - type, extends(CppTallyFilter) :: LegendreFilter + type, extends(TallyFilter) :: LegendreFilter end type LegendreFilter end module tally_filter_legendre diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index 8f6dd185e9..626ed4b156 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -2,7 +2,7 @@ module tally_filter_mesh use, intrinsic :: ISO_C_BINDING - use tally_filter_cpp + use tally_filter_header implicit none @@ -15,7 +15,7 @@ module tally_filter_mesh end function end interface - type, public, extends(CppTallyFilter) :: MeshFilter + type, public, extends(TallyFilter) :: MeshFilter contains procedure :: mesh => get_mesh end type MeshFilter diff --git a/src/tallies/tally_filter_meshsurface.F90 b/src/tallies/tally_filter_meshsurface.F90 index f70f5425f1..574d2c8b7e 100644 --- a/src/tallies/tally_filter_meshsurface.F90 +++ b/src/tallies/tally_filter_meshsurface.F90 @@ -2,7 +2,7 @@ module tally_filter_meshsurface use, intrinsic :: ISO_C_BINDING - use tally_filter_cpp + use tally_filter_header implicit none @@ -16,7 +16,7 @@ module tally_filter_meshsurface end function end interface - type, extends(CppTallyFilter) :: MeshSurfaceFilter + type, extends(TallyFilter) :: MeshSurfaceFilter end type MeshSurfaceFilter end module tally_filter_meshsurface diff --git a/src/tallies/tally_filter_particle.F90 b/src/tallies/tally_filter_particle.F90 index 611bbf29ee..5b736fe5a6 100644 --- a/src/tallies/tally_filter_particle.F90 +++ b/src/tallies/tally_filter_particle.F90 @@ -2,7 +2,7 @@ module tally_filter_particle use, intrinsic :: ISO_C_BINDING - use tally_filter_cpp + use tally_filter_header implicit none private @@ -11,7 +11,7 @@ module tally_filter_particle ! PARTICLEFILTER specifies what particles can score to a tally !=============================================================================== - type, public, extends(CppTallyFilter) :: ParticleFilter + type, public, extends(TallyFilter) :: ParticleFilter contains procedure :: particles end type ParticleFilter diff --git a/src/tallies/tally_filter_sph_harm.F90 b/src/tallies/tally_filter_sph_harm.F90 index 455da042cb..8848e9ace2 100644 --- a/src/tallies/tally_filter_sph_harm.F90 +++ b/src/tallies/tally_filter_sph_harm.F90 @@ -2,7 +2,7 @@ module tally_filter_sph_harm use, intrinsic :: ISO_C_BINDING - use tally_filter_cpp + use tally_filter_header implicit none private @@ -10,7 +10,7 @@ module tally_filter_sph_harm integer, public, parameter :: COSINE_SCATTER = 1 integer, public, parameter :: COSINE_PARTICLE = 2 - type, public, extends(CppTallyFilter) :: SphericalHarmonicsFilter + type, public, extends(TallyFilter) :: SphericalHarmonicsFilter contains procedure :: cosine end type SphericalHarmonicsFilter From 9f6801ca7465ecc87c5957b78d22c2ebc0ed4bae Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 28 Oct 2018 21:25:29 -0400 Subject: [PATCH 07/10] Use uniqe_ptr for global filter vector --- include/openmc/tallies/filter.h | 3 +- src/geometry_aux.cpp | 6 ++-- src/tallies/filter.cpp | 49 ++++++++++++++++----------------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/include/openmc/tallies/filter.h b/include/openmc/tallies/filter.h index 7920191aa1..af84b43eb1 100644 --- a/include/openmc/tallies/filter.h +++ b/include/openmc/tallies/filter.h @@ -2,6 +2,7 @@ #define OPENMC_TALLIES_FILTER_H #include +#include #include #include @@ -23,7 +24,7 @@ extern std::vector filter_matches; #pragma omp threadprivate(filter_matches) class Filter; -extern std::vector tally_filters; +extern std::vector> tally_filters; //============================================================================== //! Stores bins and weights for filtered tally events. diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index c0d9066a01..e3934480b6 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -187,9 +187,9 @@ prepare_distribcell() { // Find all cells listed in a DistribcellFilter. std::unordered_set distribcells; - for (auto* filt : tally_filters) { - if (filt->type() == "distribcell") { - auto* distrib_filt = static_cast(filt); + for (auto& filt : tally_filters) { + auto* distrib_filt = dynamic_cast(filt.get()); + if (distrib_filt) { distribcells.insert(distrib_filt->cell_); } } diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index 5905f20b5c..ef4ab345d6 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -34,7 +34,7 @@ namespace openmc { //============================================================================== std::vector filter_matches; -std::vector tally_filters; +std::vector> tally_filters; //============================================================================== // Non-member functions @@ -48,7 +48,6 @@ free_memory_tally_c() filter_matches.clear(); } - for (Filter* filt : tally_filters) {delete filt;} tally_filters.clear(); } @@ -97,53 +96,53 @@ extern "C" { { std::string type_ {type}; if (type_ == "azimuthal") { - tally_filters.push_back(new AzimuthalFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "cell") { - tally_filters.push_back(new CellFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "cellborn") { - tally_filters.push_back(new CellbornFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "cellfrom") { - tally_filters.push_back(new CellFromFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "distribcell") { - tally_filters.push_back(new DistribcellFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "delayedgroup") { - tally_filters.push_back(new DelayedGroupFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "energyfunction") { - tally_filters.push_back(new EnergyFunctionFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "energy") { - tally_filters.push_back(new EnergyFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "energyout") { - tally_filters.push_back(new EnergyoutFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "legendre") { - tally_filters.push_back(new LegendreFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "material") { - tally_filters.push_back(new MaterialFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "mesh") { - tally_filters.push_back(new MeshFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "meshsurface") { - tally_filters.push_back(new MeshSurfaceFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "mu") { - tally_filters.push_back(new MuFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "particle") { - tally_filters.push_back(new ParticleFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "polar") { - tally_filters.push_back(new PolarFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "surface") { - tally_filters.push_back(new SurfaceFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "spatiallegendre") { - tally_filters.push_back(new SpatialLegendreFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "sphericalharmonics") { - tally_filters.push_back(new SphericalHarmonicsFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "universe") { - tally_filters.push_back(new UniverseFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "zernike") { - tally_filters.push_back(new ZernikeFilter()); + tally_filters.push_back(std::make_unique()); } else if (type_ == "zernikeradial") { - tally_filters.push_back(new ZernikeRadialFilter()); + tally_filters.push_back(std::make_unique()); } else { return nullptr; } - return tally_filters.back(); + return tally_filters.back().get(); } void filter_from_xml(Filter* filt, pugi::xml_node* node) From 9bb54d03f149c75503b79a3ea8226b18717afcba Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 28 Oct 2018 22:19:42 -0400 Subject: [PATCH 08/10] Remove tally_filter_cpp import --- src/tallies/tally_filter.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tallies/tally_filter.F90 b/src/tallies/tally_filter.F90 index da644b16f2..b8d5d60c0f 100644 --- a/src/tallies/tally_filter.F90 +++ b/src/tallies/tally_filter.F90 @@ -7,7 +7,6 @@ module tally_filter use tally_filter_header ! Inherit other filters - use tally_filter_cpp use tally_filter_delayedgroup use tally_filter_distribcell use tally_filter_energy From 009e1548d538cc85dbcfec497cde139d02261052 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 31 Oct 2018 10:20:29 -0400 Subject: [PATCH 09/10] Make energy_bins/rev_energy_bins match F90 impl. --- src/mgxs_interface.cpp | 8 ++++---- src/source.cpp | 9 ++------- src/tallies/filter_energy.cpp | 6 ++---- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/mgxs_interface.cpp b/src/mgxs_interface.cpp index 5cec8811f1..0729e466c7 100644 --- a/src/mgxs_interface.cpp +++ b/src/mgxs_interface.cpp @@ -99,11 +99,11 @@ void read_mg_cross_sections_header_c(hid_t file_id) read_attribute(file_id, "energy_groups", num_energy_groups); ensure_exists(file_id, "group structure", true); - read_attribute(file_id, "group structure", energy_bins); + read_attribute(file_id, "group structure", rev_energy_bins); - // Create reverse energy bins - std::copy(energy_bins.crbegin(), energy_bins.crend(), - std::back_inserter(rev_energy_bins)); + // Reverse energy bins + std::copy(rev_energy_bins.crbegin(), rev_energy_bins.crend(), + std::back_inserter(energy_bins)); // Create average energies for (int i = 0; i < energy_bins.size() - 1; ++i) { diff --git a/src/source.cpp b/src/source.cpp index bfed41b6a3..315ff2cdd8 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -292,8 +292,6 @@ void initialize_source() } } -extern "C" double* rev_energy_bins_ptr(); - Bank sample_external_source() { // Set the random number generator to the source stream. @@ -320,11 +318,8 @@ Bank sample_external_source() // If running in MG, convert site % E to group if (!settings::run_CE) { - // Get pointer to rev_energy_bins array on Fortran side - double* rev_energy_bins = rev_energy_bins_ptr(); - - int n = num_energy_groups + 1; - site.E = lower_bound_index(rev_energy_bins, rev_energy_bins + n, site.E); + site.E = lower_bound_index(rev_energy_bins.begin(), rev_energy_bins.end(), + site.E); site.E = num_energy_groups - site.E; } diff --git a/src/tallies/filter_energy.cpp b/src/tallies/filter_energy.cpp index 779681b849..d6dd8b9ac2 100644 --- a/src/tallies/filter_energy.cpp +++ b/src/tallies/filter_energy.cpp @@ -13,9 +13,6 @@ namespace openmc { // EnergyFilter implementation //============================================================================== -// Used to grab the rev_energy_bins array defined in Fortran. -extern "C" double* rev_energy_bins_ptr(); - void EnergyFilter::from_xml(pugi::xml_node node) { @@ -30,7 +27,6 @@ EnergyFilter::from_xml(pugi::xml_node node) if (!settings::run_CE) { if (n_bins_ == num_energy_groups) { matches_transport_groups_ = true; - double* rev_energy_bins = rev_energy_bins_ptr(); for (auto i = 0; i < n_bins_ + 1; i++) { if (rev_energy_bins[i] != bins_[i]) { matches_transport_groups_ = false; @@ -80,6 +76,7 @@ std::string EnergyFilter::text_label(int bin) const { std::stringstream out; + //TODO: off-by-one out << "Incoming Energy [" << bins_[bin-1] << ", " << bins_[bin] << ")"; return out.str(); } @@ -110,6 +107,7 @@ std::string EnergyoutFilter::text_label(int bin) const { std::stringstream out; + //TODO: off-by-one out << "Outgoing Energy [" << bins_[bin-1] << ", " << bins_[bin] << ")"; return out.str(); } From 773e73b323ff7977844b3511d658795291df0afd Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 31 Oct 2018 10:21:12 -0400 Subject: [PATCH 10/10] Add TODO comments for 1-based indexing in filters --- src/tallies/filter_azimuthal.cpp | 1 + src/tallies/filter_cell.cpp | 1 + src/tallies/filter_cellborn.cpp | 1 + src/tallies/filter_cellfrom.cpp | 1 + src/tallies/filter_delayedgroup.cpp | 1 + src/tallies/filter_distribcell.cpp | 1 + src/tallies/filter_legendre.cpp | 1 + src/tallies/filter_material.cpp | 1 + src/tallies/filter_meshsurface.cpp | 1 + src/tallies/filter_mu.cpp | 1 + src/tallies/filter_particle.cpp | 3 ++- src/tallies/filter_polar.cpp | 1 + src/tallies/filter_sph_harm.cpp | 1 + src/tallies/filter_sptl_legendre.cpp | 1 + src/tallies/filter_surface.cpp | 1 + src/tallies/filter_universe.cpp | 1 + src/tallies/filter_zernike.cpp | 2 ++ 17 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/tallies/filter_azimuthal.cpp b/src/tallies/filter_azimuthal.cpp index 99a649cd91..dc65284820 100644 --- a/src/tallies/filter_azimuthal.cpp +++ b/src/tallies/filter_azimuthal.cpp @@ -66,6 +66,7 @@ std::string AzimuthalFilter::text_label(int bin) const { std::stringstream out; + //TODO: off-by-one out << "Azimuthal Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; return out.str(); } diff --git a/src/tallies/filter_cell.cpp b/src/tallies/filter_cell.cpp index a09c331bf9..9e0a6721e5 100644 --- a/src/tallies/filter_cell.cpp +++ b/src/tallies/filter_cell.cpp @@ -63,6 +63,7 @@ CellFilter::to_statepoint(hid_t filter_group) const std::string CellFilter::text_label(int bin) const { + //TODO: off-by-one return "Cell " + std::to_string(cells[cells_[bin-1]]->id_); } diff --git a/src/tallies/filter_cellborn.cpp b/src/tallies/filter_cellborn.cpp index e77c2e42f7..4f86ad34cd 100644 --- a/src/tallies/filter_cellborn.cpp +++ b/src/tallies/filter_cellborn.cpp @@ -19,6 +19,7 @@ CellbornFilter::get_all_bins(const Particle* p, int estimator, std::string CellbornFilter::text_label(int bin) const { + //TODO: off-by-one return "Birth Cell " + std::to_string(cells[cells_[bin-1]]->id_); } diff --git a/src/tallies/filter_cellfrom.cpp b/src/tallies/filter_cellfrom.cpp index 4ce24e8900..b4b1a57ef0 100644 --- a/src/tallies/filter_cellfrom.cpp +++ b/src/tallies/filter_cellfrom.cpp @@ -21,6 +21,7 @@ CellFromFilter::get_all_bins(const Particle* p, int estimator, std::string CellFromFilter::text_label(int bin) const { + //TODO: off-by-one return "Cell from " + std::to_string(cells[cells_[bin-1]]->id_); } diff --git a/src/tallies/filter_delayedgroup.cpp b/src/tallies/filter_delayedgroup.cpp index ac226b74db..2b63027cf4 100644 --- a/src/tallies/filter_delayedgroup.cpp +++ b/src/tallies/filter_delayedgroup.cpp @@ -44,6 +44,7 @@ DelayedGroupFilter::to_statepoint(hid_t filter_group) const std::string DelayedGroupFilter::text_label(int bin) const { + //TODO: off-by-one return "Delayed Group " + std::to_string(groups_[bin-1]); } diff --git a/src/tallies/filter_distribcell.cpp b/src/tallies/filter_distribcell.cpp index f1e69b62a0..39459672fc 100644 --- a/src/tallies/filter_distribcell.cpp +++ b/src/tallies/filter_distribcell.cpp @@ -73,6 +73,7 @@ std::string DistribcellFilter::text_label(int bin) const { auto map = cells[cell_]->distribcell_index_; + //TODO: off-by-one auto path = distribcell_path(cell_, map, bin-1); return "Distributed Cell " + path; } diff --git a/src/tallies/filter_legendre.cpp b/src/tallies/filter_legendre.cpp index 3b59fa763d..67d3e21d44 100644 --- a/src/tallies/filter_legendre.cpp +++ b/src/tallies/filter_legendre.cpp @@ -37,6 +37,7 @@ LegendreFilter::to_statepoint(hid_t filter_group) const std::string LegendreFilter::text_label(int bin) const { + //TODO: off-by-one return "Legendre expansion, P" + std::to_string(bin - 1); } diff --git a/src/tallies/filter_material.cpp b/src/tallies/filter_material.cpp index 0334efae94..d36175e9b1 100644 --- a/src/tallies/filter_material.cpp +++ b/src/tallies/filter_material.cpp @@ -62,6 +62,7 @@ MaterialFilter::to_statepoint(hid_t filter_group) const std::string MaterialFilter::text_label(int bin) const { + //TODO: off-by-one return "Material " + std::to_string(materials[materials_[bin-1]]->id_); } diff --git a/src/tallies/filter_meshsurface.cpp b/src/tallies/filter_meshsurface.cpp index 8074b4a4c9..af9bc53218 100644 --- a/src/tallies/filter_meshsurface.cpp +++ b/src/tallies/filter_meshsurface.cpp @@ -22,6 +22,7 @@ MeshSurfaceFilter::text_label(int bin) const int n_dim = mesh.n_dimension_; // Get flattend mesh index and surface index. + //TODO: off-by-one int i_mesh = (bin - 1) / (4 * n_dim) + 1; int i_surf = ((bin - 1) % (4 * n_dim)) + 1; diff --git a/src/tallies/filter_mu.cpp b/src/tallies/filter_mu.cpp index e57a8aa2e5..521deefe3d 100644 --- a/src/tallies/filter_mu.cpp +++ b/src/tallies/filter_mu.cpp @@ -57,6 +57,7 @@ std::string MuFilter::text_label(int bin) const { std::stringstream out; + //TODO: off-by-one out << "Change-in-Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; return out.str(); } diff --git a/src/tallies/filter_particle.cpp b/src/tallies/filter_particle.cpp index 251bb1011a..27558c59b4 100644 --- a/src/tallies/filter_particle.cpp +++ b/src/tallies/filter_particle.cpp @@ -34,6 +34,7 @@ ParticleFilter::to_statepoint(hid_t filter_group) const std::string ParticleFilter::text_label(int bin) const { + //TODO: off-by-one return "Particle " + std::to_string(particles_[bin-1]); } @@ -42,6 +43,6 @@ ParticleFilter::text_label(int bin) const //============================================================================== extern "C" int particle_filter_particles(ParticleFilter* filt, int i) -{return filt->particles_[i];} +{return filt->particles_[i-1];} } // namespace openmc diff --git a/src/tallies/filter_polar.cpp b/src/tallies/filter_polar.cpp index bfa87a3417..50fc47999c 100644 --- a/src/tallies/filter_polar.cpp +++ b/src/tallies/filter_polar.cpp @@ -65,6 +65,7 @@ std::string PolarFilter::text_label(int bin) const { std::stringstream out; + //TODO: off-by-one out << "Polar Angle [" << bins_[bin-1] << ", " << bins_[bin] << ")"; return out.str(); } diff --git a/src/tallies/filter_sph_harm.cpp b/src/tallies/filter_sph_harm.cpp index 764c56223f..001f291193 100644 --- a/src/tallies/filter_sph_harm.cpp +++ b/src/tallies/filter_sph_harm.cpp @@ -78,6 +78,7 @@ SphericalHarmonicsFilter::text_label(int bin) const std::stringstream out; for (int n = 0; n < order_ + 1; n++) { if (bin <= (n + 1) * (n + 1)) { + //TODO: off-by-one int m = (bin - n*n - 1) - n; out << "Spherical harmonic expansion, Y" << n << "," << m; return out.str(); diff --git a/src/tallies/filter_sptl_legendre.cpp b/src/tallies/filter_sptl_legendre.cpp index 3f93be1cb0..df0d8cd236 100644 --- a/src/tallies/filter_sptl_legendre.cpp +++ b/src/tallies/filter_sptl_legendre.cpp @@ -88,6 +88,7 @@ SpatialLegendreFilter::text_label(int bin) const } else { out << "z"; } + //TODO: off-by-one out << " axis, P" << std::to_string(bin - 1); return out.str(); } diff --git a/src/tallies/filter_surface.cpp b/src/tallies/filter_surface.cpp index 7fd2c6e24e..5458d20519 100644 --- a/src/tallies/filter_surface.cpp +++ b/src/tallies/filter_surface.cpp @@ -65,6 +65,7 @@ SurfaceFilter::to_statepoint(hid_t filter_group) const std::string SurfaceFilter::text_label(int bin) const { + //TODO: off-by-one return "Surface " + std::to_string(surfaces[surfaces_[bin-1]]->id_); } diff --git a/src/tallies/filter_universe.cpp b/src/tallies/filter_universe.cpp index de0d33d294..05d8c3e0dd 100644 --- a/src/tallies/filter_universe.cpp +++ b/src/tallies/filter_universe.cpp @@ -63,6 +63,7 @@ UniverseFilter::to_statepoint(hid_t filter_group) const std::string UniverseFilter::text_label(int bin) const { + //TODO: off-by-one return "Universe " + std::to_string(universes[universes_[bin-1]]->id_); } diff --git a/src/tallies/filter_zernike.cpp b/src/tallies/filter_zernike.cpp index 198bd8cb71..a8f41cfeb5 100644 --- a/src/tallies/filter_zernike.cpp +++ b/src/tallies/filter_zernike.cpp @@ -62,6 +62,7 @@ ZernikeFilter::text_label(int bin) const std::stringstream out; for (int n = 0; n < order_+1; n++) { int last = (n + 1) * (n + 2) / 2; + //TODO: off-by-one if (bin <= last) { int first = last - n; int m = -n + (bin - first) * 2; @@ -106,6 +107,7 @@ ZernikeRadialFilter::get_all_bins(const Particle* p, int estimator, std::string ZernikeRadialFilter::text_label(int bin) const { + //TODO: off-by-one return "Zernike expansion, Z" + std::to_string(2*(bin-1)) + ",0"; }