diff --git a/include/openmc/tallies/tally_filter.h b/include/openmc/tallies/tally_filter.h index 85b6f8c72..190045ee8 100644 --- a/include/openmc/tallies/tally_filter.h +++ b/include/openmc/tallies/tally_filter.h @@ -4,6 +4,8 @@ #include #include +#include "openmc/xml_interface.h" + namespace openmc { @@ -17,8 +19,11 @@ class TallyFilterMatch; extern std::vector filter_matches; #pragma omp threadprivate(filter_matches) +class TallyFilter; +extern std::vector tally_filters; + //============================================================================== -//! Stores bins and weights for filtered tally events +//! Stores bins and weights for filtered tally events. //============================================================================== class TallyFilterMatch @@ -30,5 +35,16 @@ public: bool bins_present; }; +//============================================================================== +//! Modifies tally score events. +//============================================================================== + +class TallyFilter +{ +public: + virtual void from_xml(pugi::xml_node node) = 0; + virtual void initialize() = 0; +}; + } // namespace openmc -#endif // OPENMC_TALLY_FILTER +#endif // OPENMC_TALLY_FILTER_H diff --git a/include/openmc/tallies/tally_filter_cell.h b/include/openmc/tallies/tally_filter_cell.h new file mode 100644 index 000000000..f0a4bb430 --- /dev/null +++ b/include/openmc/tallies/tally_filter_cell.h @@ -0,0 +1,46 @@ +#ifndef OPENMC_TALLY_FILTER_CELL_H +#define OPENMC_TALLY_FILTER_CELL_H + +#include +#include +#include + +#include "openmc/cell.h" +#include "openmc/error.h" +#include "openmc/tallies/tally_filter.h" + + +namespace openmc { + +class CellFilter : public TallyFilter +{ +public: + virtual void + from_xml(pugi::xml_node node) + { + cells_ = get_node_array(node, "bins"); + } + + virtual void + initialize() + { + for (auto& c : cells_) { + auto search = cell_map.find(c); + if (search != cell_map.end()) { + c = search->second; + } else { + std::stringstream err_msg; + err_msg << "Could not find cell " << c << " specified on tally filter."; + fatal_error(err_msg); + } + } + + //TODO: mapping + } + +protected: + std::vector cells_; +}; + +} // namespace openmc +#endif // OPENMC_TALLY_FILTER_CELL_H diff --git a/src/cell.cpp b/src/cell.cpp index e579b9db4..3d81a577e 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -604,6 +604,20 @@ read_cells(pugi::xml_node* node) cells.push_back(new Cell(cell_node)); } + // Fill the cell map. + // TODO: update this map when openmc_extend_cells is called + for (int i = 0; i < cells.size(); i++) { + int32_t id = cells[i]->id_; + auto search = cell_map.find(id); + if (search == cell_map.end()) { + cell_map[id] = i; + } else { + std::stringstream err_msg; + err_msg << "Two or more cells use the same unique ID: " << id; + fatal_error(err_msg); + } + } + // Populate the Universe vector and map. for (int i = 0; i < cells.size(); i++) { int32_t uid = cells[i]->universe_; diff --git a/src/tallies/tally_filter.F90 b/src/tallies/tally_filter.F90 index 81b195816..caa088e5a 100644 --- a/src/tallies/tally_filter.F90 +++ b/src/tallies/tally_filter.F90 @@ -114,6 +114,14 @@ contains character(:), allocatable :: type_ + interface + function allocate_filter(type) result(ptr) bind(C) + import C_CHAR, C_PTR + character(kind=C_CHAR), intent(in) :: type(*) + type(C_PTR) :: ptr + end function allocate_filter + end interface + ! Convert C string to Fortran string type_ = to_f_string(type) @@ -128,6 +136,14 @@ contains allocate(AzimuthalFilter :: filters(index) % obj) case ('cell') allocate(CellFilter :: filters(index) % obj) + select type(filt => filters(index) % obj) + type is (CellFilter) + 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 case ('cellborn') allocate(CellbornFilter :: filters(index) % obj) case ('cellfrom') diff --git a/src/tallies/tally_filter.cpp b/src/tallies/tally_filter.cpp index 42589a579..d869f6cc6 100644 --- a/src/tallies/tally_filter.cpp +++ b/src/tallies/tally_filter.cpp @@ -1,5 +1,9 @@ #include "openmc/tallies/tally_filter.h" +#include + +#include "openmc/tallies/tally_filter_cell.h" + namespace openmc { @@ -8,6 +12,7 @@ namespace openmc { //============================================================================== std::vector filter_matches; +std::vector tally_filters; //============================================================================== // Fortran compatibility functions @@ -48,6 +53,23 @@ extern "C" { void filter_match_bins_set_data(TallyFilterMatch* match, int indx, int val) {match->bins.at(indx-1) = val;} + + TallyFilter* + allocate_filter(const char* type) + { + std::string type_ {type}; + if (type_ == "cell") { + tally_filters.push_back(new CellFilter()); + return tally_filters.back(); + } else { + return nullptr; + } + } + + void filter_from_xml(TallyFilter* filt, pugi::xml_node* node) + {filt->from_xml(*node);} + + void filter_initialize(TallyFilter* filt) {filt->initialize();} } } // namespace openmc diff --git a/src/tallies/tally_filter_cell.F90 b/src/tallies/tally_filter_cell.F90 index dae870e1f..3f3706621 100644 --- a/src/tallies/tally_filter_cell.F90 +++ b/src/tallies/tally_filter_cell.F90 @@ -20,7 +20,7 @@ module tally_filter_cell ! CELLFILTER specifies which geometric cells tally events reside in. !=============================================================================== - type, public, extends(TallyFilter) :: CellFilter + type, public, extends(CppTallyFilter) :: CellFilter integer(C_INT32_T), allocatable :: cells(:) type(DictIntInt) :: map contains @@ -39,6 +39,8 @@ contains integer :: n + call this % from_xml_c(node) + ! Determine how many bins were given n = node_word_count(node, "bins") @@ -91,6 +93,8 @@ contains integer :: i, id integer :: val + call this % initialize_c() + ! Convert ids to indices. do i = 1, this % n_bins id = this % cells(i) diff --git a/src/tallies/tally_filter_header.F90 b/src/tallies/tally_filter_header.F90 index 5f37b33ce..b1686235c 100644 --- a/src/tallies/tally_filter_header.F90 +++ b/src/tallies/tally_filter_header.F90 @@ -124,6 +124,16 @@ module tally_filter_header end interface +!=============================================================================== +!=============================================================================== + + type, public, abstract, extends(TallyFilter) :: CppTallyFilter + type(C_PTR) :: ptr + contains + procedure :: from_xml_c + procedure :: initialize_c + end type CppTallyFilter + !=============================================================================== ! TALLYFILTERCONTAINER contains an allocatable TallyFilter object for arrays of ! TallyFilters @@ -265,6 +275,32 @@ contains class(TallyFilter), intent(inout) :: this end subroutine filter_initialize +!=============================================================================== + + subroutine from_xml_c(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_c + + subroutine initialize_c(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_c + !=============================================================================== ! FREE_MEMORY_TALLY_FILTER deallocates global arrays defined in this module !===============================================================================