Change how tally filters are created from C API

This commit is contained in:
Paul Romano 2019-02-21 00:05:34 -06:00
parent d0b6d9fbd6
commit 487b62f760
5 changed files with 34 additions and 184 deletions

View file

@ -323,7 +323,6 @@ add_library(libopenmc SHARED
src/xml_interface.F90
src/tallies/tally.F90
src/tallies/tally_derivative_header.F90
src/tallies/tally_filter.F90
src/tallies/tally_filter_header.F90
src/tallies/tally_filter_distribcell.F90
src/tallies/tally_filter_particle.F90

View file

@ -40,9 +40,8 @@ extern "C" {
int openmc_extend_meshes(int32_t n, int32_t* index_start, int32_t* index_end);
int openmc_extend_tallies(int32_t n, int32_t* index_start, int32_t* index_end);
int openmc_filter_get_id(int32_t index, int32_t* id);
int openmc_filter_get_type(int32_t index, char* type);
int openmc_filter_get_type(int32_t index, const char** type);
int openmc_filter_set_id(int32_t index, int32_t id);
int openmc_filter_set_type(int32_t index, const char* type);
int openmc_finalize();
int openmc_find_cell(double* xyz, int32_t* index, int32_t* instance);
int openmc_get_cell_index(int32_t id, int32_t* index);
@ -82,6 +81,7 @@ extern "C" {
int openmc_mesh_set_params(int32_t index, int n, const double* ll, const double* ur, const double* width);
int openmc_meshsurface_filter_get_mesh(int32_t index, int32_t* index_mesh);
int openmc_meshsurface_filter_set_mesh(int32_t index, int32_t index_mesh);
int openmc_new_filter(const char* type, int32_t* index);
int openmc_next_batch(int* status);
int openmc_nuclide_name(int index, const char** name);
int openmc_plot_geometry();

View file

@ -40,15 +40,12 @@ _dll.openmc_extend_filters.errcheck = _error_handler
_dll.openmc_filter_get_id.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_filter_get_id.restype = c_int
_dll.openmc_filter_get_id.errcheck = _error_handler
_dll.openmc_filter_get_type.argtypes = [c_int32, c_char_p]
_dll.openmc_filter_get_type.argtypes = [c_int32, POINTER(c_char_p)]
_dll.openmc_filter_get_type.restype = c_int
_dll.openmc_filter_get_type.errcheck = _error_handler
_dll.openmc_filter_set_id.argtypes = [c_int32, c_int32]
_dll.openmc_filter_set_id.restype = c_int
_dll.openmc_filter_set_id.errcheck = _error_handler
_dll.openmc_filter_set_type.argtypes = [c_int32, c_char_p]
_dll.openmc_filter_set_type.restype = c_int
_dll.openmc_filter_set_type.errcheck = _error_handler
_dll.openmc_get_filter_index.argtypes = [c_int32, POINTER(c_int32)]
_dll.openmc_get_filter_index.restype = c_int
_dll.openmc_get_filter_index.errcheck = _error_handler
@ -77,6 +74,9 @@ _dll.openmc_meshsurface_filter_get_mesh.errcheck = _error_handler
_dll.openmc_meshsurface_filter_set_mesh.argtypes = [c_int32, c_int32]
_dll.openmc_meshsurface_filter_set_mesh.restype = c_int
_dll.openmc_meshsurface_filter_set_mesh.errcheck = _error_handler
_dll.openmc_new_filter.argtypes = [c_char_p, POINTER(c_int32_)]
_dll.openmc_new_filter.restype = c_int
_dll.openmc_new_filter.errcheck = _error_handler
_dll.openmc_spatial_legendre_filter_get_order.argtypes = [c_int32, POINTER(c_int)]
_dll.openmc_spatial_legendre_filter_get_order.restype = c_int
_dll.openmc_spatial_legendre_filter_get_order.errcheck = _error_handler
@ -111,13 +111,10 @@ class Filter(_FortranObjectWithID):
raise AllocationError('A filter with ID={} has already '
'been allocated.'.format(uid))
# Resize internal array
index = c_int32()
_dll.openmc_extend_filters(1, index, None)
# Set the filter type -- note that the filter_type attribute
# only exists on subclasses!
_dll.openmc_filter_set_type(index, cls.filter_type.encode())
index = c_int32()
_dll.openmc_new_filter(cls.filter_type.encode(), index)
index = index.value
else:
index = mapping[uid]._index

View file

@ -44,6 +44,10 @@ namespace model {
std::unordered_map<int, int> filter_map;
}
//==============================================================================
// Non-member functions
//==============================================================================
Filter*
allocate_filter(const std::string& type)
{
@ -97,6 +101,28 @@ allocate_filter(const std::string& type)
return model::tally_filters.back().get();
}
//==============================================================================
// C API functions
//==============================================================================
extern "C" int
openmc_filter_get_type(int32_t index, const char** type)
{
int err = verify_filter(index);
if (err) return err;
// TODO: off-by-one
*type = model::tally_filters[index-1]->type().c_str();
}
extern "C" int
openmc_new_filter(const char* type, int32_t* index)
{
allocate_filter(type);
// TODO: off-by-one
*index = model::tally_filters.size();
return 0;
}
//==============================================================================
// Fortran compatibility functions

View file

@ -1,172 +0,0 @@
module tally_filter
use, intrinsic :: ISO_C_BINDING
use error
use string, only: to_f_string
use tally_filter_header
! Inherit other filters
use tally_filter_distribcell
use tally_filter_particle
use tally_filter_sph_harm
implicit none
contains
!===============================================================================
! C API FUNCTIONS
!===============================================================================
function openmc_filter_get_type(index, type) result(err) bind(C)
! Get the type of a filter
integer(C_INT32_T), value, intent(in) :: index
character(kind=C_CHAR), intent(out) :: type(*)
integer(C_INT) :: err
integer :: i
character(20) :: type_
err = verify_filter(index)
if (err == 0) then
! Get type as a Fortran string
select type (f => filters(index) % obj)
type is (AzimuthalFilter)
type_ = 'azimuthal'
type is (CellFilter)
type_ = 'cell'
type is (CellbornFilter)
type_ = 'cellborn'
type is (CellfromFilter)
type_ = 'cellfrom'
type is (DelayedGroupFilter)
type_ = 'delayedgroup'
type is (DistribcellFilter)
type_ = 'distribcell'
type is (EnergyFilter)
type_ = 'energy'
type is (EnergyoutFilter)
type_ = 'energyout'
type is (EnergyFunctionFilter)
type_ = 'energyfunction'
type is (LegendreFilter)
type_ = 'legendre'
type is (MaterialFilter)
type_ = 'material'
type is (MeshFilter)
type_ = 'mesh'
type is (MeshSurfaceFilter)
type_ = 'meshsurface'
type is (MuFilter)
type_ = 'mu'
type is (PolarFilter)
type_ = 'polar'
type is (SphericalHarmonicsFilter)
type_ = 'sphericalharmonics'
type is (SpatialLegendreFilter)
type_ = 'spatiallegendre'
type is (SurfaceFilter)
type_ = 'surface'
type is (UniverseFilter)
type_ = 'universe'
type is (ZernikeFilter)
type_ = 'zernike'
type is (ParticleFilter)
type_ = 'particle'
type is (ZernikeRadialFilter)
type_ = 'zernikeradial'
end select
! Convert Fortran string to null-terminated C string. We assume the
! caller has allocated a char array buffer
do i = 1, len_trim(type_)
type(i) = type_(i:i)
end do
type(len_trim(type_) + 1) = C_NULL_CHAR
end if
end function openmc_filter_get_type
function openmc_filter_set_type(index, type) result(err) bind(C)
! Set the type of a filter
integer(C_INT32_T), value, intent(in) :: index
character(kind=C_CHAR), intent(in) :: type(*)
integer(C_INT) :: err
character(:), allocatable :: type_
! Convert C string to Fortran string
type_ = to_f_string(type)
err = 0
if (index >= 1 .and. index <= n_filters) then
if (allocated(filters(index) % obj)) then
err = E_ALLOCATE
call set_errmsg("Filter type has already been set.")
else
select case (type_)
case ('azimuthal')
allocate(AzimuthalFilter :: filters(index) % obj)
case ('cell')
allocate(CellFilter :: filters(index) % obj)
case ('cellborn')
allocate(CellbornFilter :: filters(index) % obj)
case ('cellfrom')
allocate(CellFromFilter :: filters(index) % obj)
case ('delayedgroup')
allocate(DelayedGroupFilter :: filters(index) % obj)
case ('distribcell')
allocate(DistribcellFilter :: filters(index) % obj)
case ('energy')
allocate(EnergyFilter :: filters(index) % obj)
case ('energyout')
allocate(EnergyoutFilter :: filters(index) % obj)
case ('energyfunction')
allocate(EnergyFunctionFilter :: filters(index) % obj)
case ('legendre')
allocate(LegendreFilter :: filters(index) % obj)
case ('material')
allocate(MaterialFilter :: filters(index) % obj)
case ('mesh')
allocate(MeshFilter :: filters(index) % obj)
case ('meshsurface')
allocate(MeshSurfaceFilter :: filters(index) % obj)
case ('mu')
allocate(MuFilter :: filters(index) % obj)
case ('particle')
allocate(ParticleFilter :: filters(index) % obj)
case ('polar')
allocate(PolarFilter :: filters(index) % obj)
case ('sphericalharmonics')
allocate(SphericalHarmonicsFilter :: filters(index) % obj)
case ('spatiallegendre')
allocate(SpatialLegendreFilter :: filters(index) % obj)
case ('surface')
allocate(SurfaceFilter :: filters(index) % obj)
case ('universe')
allocate(UniverseFilter :: filters(index) % obj)
case ('zernike')
allocate(ZernikeFilter :: filters(index) % obj)
case ('zernikeradial')
allocate(ZernikeRadialFilter :: filters(index) % obj)
case default
err = E_UNASSIGNED
call set_errmsg("Unknown filter type: " // trim(type_))
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
err = E_OUT_OF_BOUNDS
call set_errmsg("Index in filters array is out of bounds.")
end if
end function openmc_filter_set_type
end module tally_filter