mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-26 21:25:36 -04:00
Add framework for calling C++ filters from F90
This commit is contained in:
parent
0c8ea4f31f
commit
1cc0271f4c
7 changed files with 157 additions and 3 deletions
|
|
@ -4,6 +4,8 @@
|
|||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "openmc/xml_interface.h"
|
||||
|
||||
|
||||
namespace openmc {
|
||||
|
||||
|
|
@ -17,8 +19,11 @@ class TallyFilterMatch;
|
|||
extern std::vector<TallyFilterMatch> filter_matches;
|
||||
#pragma omp threadprivate(filter_matches)
|
||||
|
||||
class TallyFilter;
|
||||
extern std::vector<TallyFilter*> 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
|
||||
|
|
|
|||
46
include/openmc/tallies/tally_filter_cell.h
Normal file
46
include/openmc/tallies/tally_filter_cell.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef OPENMC_TALLY_FILTER_CELL_H
|
||||
#define OPENMC_TALLY_FILTER_CELL_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#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<int32_t>(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<int32_t> cells_;
|
||||
};
|
||||
|
||||
} // namespace openmc
|
||||
#endif // OPENMC_TALLY_FILTER_CELL_H
|
||||
14
src/cell.cpp
14
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_;
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
#include "openmc/tallies/tally_filter.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "openmc/tallies/tally_filter_cell.h"
|
||||
|
||||
|
||||
namespace openmc {
|
||||
|
||||
|
|
@ -8,6 +12,7 @@ namespace openmc {
|
|||
//==============================================================================
|
||||
|
||||
std::vector<TallyFilterMatch> filter_matches;
|
||||
std::vector<TallyFilter*> 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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
!===============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue