mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 14:15:42 -04:00
Change how tally filters are created from C API
This commit is contained in:
parent
d0b6d9fbd6
commit
487b62f760
5 changed files with 34 additions and 184 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue