mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 14:15:42 -04:00
Merge pull request #997 from lindsayad/tally-filter-api
Expand C API, targeting FETs
This commit is contained in:
commit
cacde822f9
5 changed files with 171 additions and 8 deletions
|
|
@ -17,6 +17,7 @@ extern "C" {
|
|||
};
|
||||
|
||||
int openmc_calculate_volumes();
|
||||
int openmc_cell_filter_get_bins(int32_t index, int32_t** cells, int32_t* n);
|
||||
int openmc_cell_get_fill(int32_t index, int* type, int32_t** indices, int32_t* n);
|
||||
int openmc_cell_get_id(int32_t index, int32_t* id);
|
||||
int openmc_cell_set_fill(int32_t index, int type, int32_t n, const int32_t* indices);
|
||||
|
|
@ -31,7 +32,7 @@ extern "C" {
|
|||
int openmc_extend_sources(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, const char** type);
|
||||
int openmc_filter_get_type(int32_t index, 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();
|
||||
|
|
|
|||
|
|
@ -17,11 +17,16 @@ from .mesh import Mesh
|
|||
__all__ = ['Filter', 'AzimuthalFilter', 'CellFilter',
|
||||
'CellbornFilter', 'CellfromFilter', 'DistribcellFilter',
|
||||
'DelayedGroupFilter', 'EnergyFilter', 'EnergyoutFilter',
|
||||
'EnergyFunctionFilter', 'MaterialFilter', 'MeshFilter',
|
||||
'MeshSurfaceFilter', 'MuFilter', 'PolarFilter', 'SurfaceFilter',
|
||||
'UniverseFilter', 'filters']
|
||||
'EnergyFunctionFilter', 'LegendreFilter', 'MaterialFilter', 'MeshFilter',
|
||||
'MeshSurfaceFilter', 'MuFilter', 'PolarFilter', 'SphericalHarmonicsFilter',
|
||||
'SpatialLegendreFilter', 'SurfaceFilter',
|
||||
'UniverseFilter', 'ZernikeFilter', 'filters']
|
||||
|
||||
# Tally functions
|
||||
_dll.openmc_cell_filter_get_bins.argtypes = [
|
||||
c_int32, POINTER(POINTER(c_int32)), POINTER(c_int32)]
|
||||
_dll.openmc_cell_filter_get_bins.restype = c_int
|
||||
_dll.openmc_cell_filter_get_bins.errcheck = _error_handler
|
||||
_dll.openmc_energy_filter_get_bins.argtypes = [
|
||||
c_int32, POINTER(POINTER(c_double)), POINTER(c_int32)]
|
||||
_dll.openmc_energy_filter_get_bins.restype = c_int
|
||||
|
|
@ -47,6 +52,12 @@ _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
|
||||
_dll.openmc_legendre_filter_get_order.argtypes = [c_int32, POINTER(c_int)]
|
||||
_dll.openmc_legendre_filter_get_order.restype = c_int
|
||||
_dll.openmc_legendre_filter_get_order.errcheck = _error_handler
|
||||
_dll.openmc_legendre_filter_set_order.argtypes = [c_int32, c_int]
|
||||
_dll.openmc_legendre_filter_set_order.restype = c_int
|
||||
_dll.openmc_legendre_filter_set_order.errcheck = _error_handler
|
||||
_dll.openmc_material_filter_get_bins.argtypes = [
|
||||
c_int32, POINTER(POINTER(c_int32)), POINTER(c_int32)]
|
||||
_dll.openmc_material_filter_get_bins.restype = c_int
|
||||
|
|
@ -66,7 +77,24 @@ _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_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
|
||||
_dll.openmc_spatial_legendre_filter_set_order.argtypes = [c_int32, c_int]
|
||||
_dll.openmc_spatial_legendre_filter_set_order.restype = c_int
|
||||
_dll.openmc_spatial_legendre_filter_set_order.errcheck = _error_handler
|
||||
_dll.openmc_sphharm_filter_get_order.argtypes = [c_int32, POINTER(c_int)]
|
||||
_dll.openmc_sphharm_filter_get_order.restype = c_int
|
||||
_dll.openmc_sphharm_filter_get_order.errcheck = _error_handler
|
||||
_dll.openmc_sphharm_filter_set_order.argtypes = [c_int32, c_int]
|
||||
_dll.openmc_sphharm_filter_set_order.restype = c_int
|
||||
_dll.openmc_sphharm_filter_set_order.errcheck = _error_handler
|
||||
_dll.openmc_zernike_filter_get_order.argtypes = [c_int32, POINTER(c_int)]
|
||||
_dll.openmc_zernike_filter_get_order.restype = c_int
|
||||
_dll.openmc_zernike_filter_get_order.errcheck = _error_handler
|
||||
_dll.openmc_zernike_filter_set_order.argtypes = [c_int32, c_int]
|
||||
_dll.openmc_zernike_filter_set_order.restype = c_int
|
||||
_dll.openmc_zernike_filter_set_order.errcheck = _error_handler
|
||||
|
||||
class Filter(_FortranObjectWithID):
|
||||
__instances = WeakValueDictionary()
|
||||
|
|
@ -150,6 +178,13 @@ class AzimuthalFilter(Filter):
|
|||
class CellFilter(Filter):
|
||||
filter_type = 'cell'
|
||||
|
||||
@property
|
||||
def bins(self):
|
||||
cells = POINTER(c_int32)()
|
||||
n = c_int32()
|
||||
_dll.openmc_cell_filter_get_bins(self._index, cells, n)
|
||||
return as_array(cells, (n.value,))
|
||||
|
||||
|
||||
class CellbornFilter(Filter):
|
||||
filter_type = 'cellborn'
|
||||
|
|
@ -171,6 +206,25 @@ class EnergyFunctionFilter(Filter):
|
|||
filter_type = 'energyfunction'
|
||||
|
||||
|
||||
class LegendreFilter(Filter):
|
||||
filter_type = 'legendre'
|
||||
|
||||
def __init__(self, order=None, uid=None, new=True, index=None):
|
||||
super().__init__(uid, new, index)
|
||||
if order is not None:
|
||||
self.order = order
|
||||
|
||||
@property
|
||||
def order(self):
|
||||
temp_order = c_int()
|
||||
_dll.openmc_legendre_filter_get_order(self._index, temp_order)
|
||||
return temp_order.value
|
||||
|
||||
@order.setter
|
||||
def order(self, order):
|
||||
_dll.openmc_legendre_filter_set_order(self._index, order)
|
||||
|
||||
|
||||
class MaterialFilter(Filter):
|
||||
filter_type = 'material'
|
||||
|
||||
|
|
@ -241,6 +295,44 @@ class PolarFilter(Filter):
|
|||
filter_type = 'polar'
|
||||
|
||||
|
||||
class SphericalHarmonicsFilter(Filter):
|
||||
filter_type = 'sphericalharmonics'
|
||||
|
||||
def __init__(self, order=None, uid=None, new=True, index=None):
|
||||
super().__init__(uid, new, index)
|
||||
if order is not None:
|
||||
self.order = order
|
||||
|
||||
@property
|
||||
def order(self):
|
||||
temp_order = c_int()
|
||||
_dll.openmc_sphharm_filter_get_order(self._index, temp_order)
|
||||
return temp_order.value
|
||||
|
||||
@order.setter
|
||||
def order(self, order):
|
||||
_dll.openmc_sphharm_filter_set_order(self._index, order)
|
||||
|
||||
|
||||
class SpatialLegendreFilter(Filter):
|
||||
filter_type = 'spatiallegendre'
|
||||
|
||||
def __init__(self, order=None, uid=None, new=True, index=None):
|
||||
super().__init__(uid, new, index)
|
||||
if order is not None:
|
||||
self.order = order
|
||||
|
||||
@property
|
||||
def order(self):
|
||||
temp_order = c_int()
|
||||
_dll.openmc_spatial_legendre_filter_get_order(self._index, temp_order)
|
||||
return temp_order.value
|
||||
|
||||
@order.setter
|
||||
def order(self, order):
|
||||
_dll.openmc_spatial_legendre_filter_set_order(self._index, order)
|
||||
|
||||
|
||||
class SurfaceFilter(Filter):
|
||||
filter_type = 'surface'
|
||||
|
||||
|
|
@ -249,6 +341,25 @@ class UniverseFilter(Filter):
|
|||
filter_type = 'universe'
|
||||
|
||||
|
||||
class ZernikeFilter(Filter):
|
||||
filter_type = 'zernike'
|
||||
|
||||
def __init__(self, order=None, uid=None, new=True, index=None):
|
||||
super().__init__(uid, new, index)
|
||||
if order is not None:
|
||||
self.order = order
|
||||
|
||||
@property
|
||||
def order(self):
|
||||
temp_order = c_int()
|
||||
_dll.openmc_zernike_filter_get_order(self._index, temp_order)
|
||||
return temp_order.value
|
||||
|
||||
@order.setter
|
||||
def order(self, order):
|
||||
_dll.openmc_zernike_filter_set_order(self._index, order)
|
||||
|
||||
|
||||
_FILTER_TYPE_MAP = {
|
||||
'azimuthal': AzimuthalFilter,
|
||||
'cell': CellFilter,
|
||||
|
|
@ -259,13 +370,17 @@ _FILTER_TYPE_MAP = {
|
|||
'energy': EnergyFilter,
|
||||
'energyout': EnergyoutFilter,
|
||||
'energyfunction': EnergyFunctionFilter,
|
||||
'legendre': LegendreFilter,
|
||||
'material': MaterialFilter,
|
||||
'mesh': MeshFilter,
|
||||
'meshsurface': MeshSurfaceFilter,
|
||||
'mu': MuFilter,
|
||||
'polar': PolarFilter,
|
||||
'sphericalharmonics': SphericalHarmonicsFilter,
|
||||
'spatiallegendre': SpatialLegendreFilter,
|
||||
'surface': SurfaceFilter,
|
||||
'universe': UniverseFilter,
|
||||
'zernike': ZernikeFilter
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ module openmc_api
|
|||
|
||||
private
|
||||
public :: openmc_calculate_volumes
|
||||
public :: openmc_cell_filter_get_bins
|
||||
public :: openmc_cell_get_id
|
||||
public :: openmc_cell_get_fill
|
||||
public :: openmc_cell_set_fill
|
||||
|
|
|
|||
|
|
@ -14,13 +14,14 @@ module tally_filter_cell
|
|||
|
||||
implicit none
|
||||
private
|
||||
public :: openmc_cell_filter_get_bins
|
||||
|
||||
!===============================================================================
|
||||
! CELLFILTER specifies which geometric cells tally events reside in.
|
||||
!===============================================================================
|
||||
|
||||
type, public, extends(TallyFilter) :: CellFilter
|
||||
integer, allocatable :: cells(:)
|
||||
integer(C_INT32_T), allocatable :: cells(:)
|
||||
type(DictIntInt) :: map
|
||||
contains
|
||||
procedure :: from_xml
|
||||
|
|
@ -116,4 +117,28 @@ contains
|
|||
label = "Cell " // to_str(cells(this % cells(bin)) % id)
|
||||
end function text_label_cell
|
||||
|
||||
!===============================================================================
|
||||
! C API FUNCTIONS
|
||||
!===============================================================================
|
||||
|
||||
function openmc_cell_filter_get_bins(index, cells, n) result(err) bind(C)
|
||||
! Return the cells associated with a cell filter
|
||||
integer(C_INT32_T), value :: index
|
||||
type(C_PTR), intent(out) :: cells
|
||||
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 (CellFilter)
|
||||
cells = C_LOC(f % cells)
|
||||
n = size(f % cells)
|
||||
class default
|
||||
err = E_INVALID_TYPE
|
||||
call set_errmsg("Tried to get cells from a non-cell filter.")
|
||||
end select
|
||||
end if
|
||||
end function openmc_cell_filter_get_bins
|
||||
|
||||
end module tally_filter_cell
|
||||
|
|
|
|||
|
|
@ -26,6 +26,15 @@ def pincell_model():
|
|||
mat_tally.scores = ['total', 'elastic', '(n,gamma)']
|
||||
pincell.tallies.append(mat_tally)
|
||||
|
||||
# Add an expansion tally
|
||||
zernike_tally = openmc.Tally()
|
||||
filter3 = openmc.ZernikeFilter(5, r=.63)
|
||||
cells = pincell.geometry.root_universe.cells
|
||||
filter4 = openmc.CellFilter(list(cells.values()))
|
||||
zernike_tally.filters = [filter3, filter4]
|
||||
zernike_tally.scores = ['fission']
|
||||
pincell.tallies.append(zernike_tally)
|
||||
|
||||
# Write XML files in tmpdir
|
||||
with cdtemp():
|
||||
pincell.export_to_xml()
|
||||
|
|
@ -132,7 +141,7 @@ def test_settings(capi_init):
|
|||
def test_tally_mapping(capi_init):
|
||||
tallies = openmc.capi.tallies
|
||||
assert isinstance(tallies, Mapping)
|
||||
assert len(tallies) == 1
|
||||
assert len(tallies) == 2
|
||||
for tally_id, tally in tallies.items():
|
||||
assert isinstance(tally, openmc.capi.Tally)
|
||||
assert tally_id == tally.id
|
||||
|
|
@ -168,6 +177,14 @@ def test_tally(capi_init):
|
|||
t.active = True
|
||||
assert t.active
|
||||
|
||||
t2 = openmc.capi.tallies[2]
|
||||
t2.id = 2
|
||||
assert len(t2.filters) == 2
|
||||
assert isinstance(t2.filters[0], openmc.capi.ZernikeFilter)
|
||||
assert isinstance(t2.filters[1], openmc.capi.CellFilter)
|
||||
assert len(t2.filters[1].bins) == 3
|
||||
assert t2.filters[0].order == 5
|
||||
|
||||
|
||||
def test_new_tally(capi_init):
|
||||
with pytest.raises(exc.AllocationError):
|
||||
|
|
@ -176,7 +193,7 @@ def test_new_tally(capi_init):
|
|||
new_tally.scores = ['flux']
|
||||
new_tally_with_id = openmc.capi.Tally(10)
|
||||
new_tally_with_id.scores = ['flux']
|
||||
assert len(openmc.capi.tallies) == 3
|
||||
assert len(openmc.capi.tallies) == 4
|
||||
|
||||
|
||||
def test_tally_results(capi_run):
|
||||
|
|
@ -187,6 +204,10 @@ def test_tally_results(capi_run):
|
|||
assert np.all(t.std_dev[nonzero] >= 0)
|
||||
assert np.all(t.ci_width()[nonzero] >= 1.95*t.std_dev[nonzero])
|
||||
|
||||
t2 = openmc.capi.tallies[2]
|
||||
n = 5
|
||||
assert t2.mean.size == (n + 1) * (n + 2) // 2 * 3 # Number of Zernike coeffs * 3 cells
|
||||
|
||||
|
||||
def test_global_tallies(capi_run):
|
||||
assert openmc.capi.num_realizations() == 5
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue