diff --git a/openmc/capi/filter.py b/openmc/capi/filter.py index f671ce4016..aea968dadb 100644 --- a/openmc/capi/filter.py +++ b/openmc/capi/filter.py @@ -7,9 +7,15 @@ from .error import _error_handler __all__ = [] # Tally functions +_dll.openmc_energy_filter_set_bins.argtypes = [c_int32, c_int32, POINTER(c_double)] +_dll.openmc_energy_filter_set_bins.restype = c_int +_dll.openmc_energy_filter_set_bins.errcheck = _error_handler _dll.openmc_extend_filters.argtypes = [c_int32, POINTER(c_int32), POINTER(c_int32)] _dll.openmc_extend_filters.restype = c_int _dll.openmc_extend_filters.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_mesh_filter_set_mesh.argtypes = [c_int32, c_int32] +_dll.openmc_mesh_filter_set_mesh.restype = c_int +_dll.openmc_mesh_filter_set_mesh.errcheck = _error_handler diff --git a/openmc/capi/tally.py b/openmc/capi/tally.py index f2498ed90b..3b76aa4006 100644 --- a/openmc/capi/tally.py +++ b/openmc/capi/tally.py @@ -20,6 +20,9 @@ _dll.openmc_extend_tallies.errcheck = _error_handler _dll.openmc_tally_get_id.argtypes = [c_int32, POINTER(c_int32)] _dll.openmc_tally_get_id.restype = c_int _dll.openmc_tally_get_id.errcheck = _error_handler +_dll.openmc_tally_get_filters.argtypes = [c_int32, POINTER(c_int32), POINTER(c_int)] +_dll.openmc_tally_get_filters.restype = c_int +_dll.openmc_tally_get_filters.errcheck = _error_handler _dll.openmc_tally_get_nuclides.argtypes = [ c_int32, POINTER(POINTER(c_int)), POINTER(c_int)] _dll.openmc_tally_get_nuclides.restype = c_int @@ -28,9 +31,15 @@ _dll.openmc_tally_results.argtypes = [ c_int32, POINTER(POINTER(c_double)), POINTER(c_int*3)] _dll.openmc_tally_results.restype = c_int _dll.openmc_tally_results.errcheck = _error_handler +_dll.openmc_tally_set_filters.argtypes = [c_int32, c_int, POINTER(c_int32)] +_dll.openmc_tally_set_filters.restype = c_int +_dll.openmc_tally_set_filters.errcheck = _error_handler _dll.openmc_tally_set_nuclides.argtypes = [c_int32, c_int, POINTER(c_char_p)] _dll.openmc_tally_set_nuclides.restype = c_int _dll.openmc_tally_set_nuclides.errcheck = _error_handler +_dll.openmc_tally_set_scores.argtypes = [c_int32, c_int, POINTER(c_char_p)] +_dll.openmc_tally_set_scores.restype = c_int +_dll.openmc_tally_set_scores.errcheck = _error_handler class TallyView(object): diff --git a/src/api.F90 b/src/api.F90 index dec1c332ec..a6dc6aba8a 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -19,7 +19,7 @@ module openmc_api use random_lcg, only: seed, initialize_prng use tally_header use tally_filter_header - use tally_filter, only: openmc_filter_set_type + use tally_filter use simulation, only: openmc_run use string, only: to_f_string use volume_calc, only: openmc_calculate_volumes @@ -30,6 +30,7 @@ module openmc_api public :: openmc_calculate_volumes public :: openmc_cell_get_id public :: openmc_cell_set_temperature + public :: openmc_energy_filter_set_bins public :: openmc_extend_filters public :: openmc_extend_tallies public :: openmc_filter_set_type @@ -48,13 +49,16 @@ module openmc_api public :: openmc_material_get_densities public :: openmc_material_set_density public :: openmc_material_set_densities + public :: openmc_mesh_filter_set_mesh public :: openmc_nuclide_name public :: openmc_plot_geometry public :: openmc_reset public :: openmc_run public :: openmc_tally_get_id + public :: openmc_tally_get_filters public :: openmc_tally_get_nuclides public :: openmc_tally_results + public :: openmc_tally_set_filters public :: openmc_tally_set_nuclides public :: openmc_tally_set_scores diff --git a/src/error.F90 b/src/error.F90 index f72e3ad8b0..70f5c0a215 100644 --- a/src/error.F90 +++ b/src/error.F90 @@ -29,6 +29,8 @@ module error integer(C_INT), public, bind(C) :: E_CELL_NO_MATERIAL = -14 integer(C_INT), public, bind(C) :: E_ALREADY_ALLOCATED = -15 integer(C_INT), public, bind(C) :: E_ARGUMENT_INVALID = -16 + integer(C_INT), public, bind(C) :: E_WRONG_TYPE = -17 + integer(C_INT), public, bind(C) :: E_FILTER_NOT_ALLOCATED = -18 ! Warning codes integer(C_INT), public, bind(C) :: W_BELOW_MIN_BOUND = 1 diff --git a/src/tallies/tally_filter_energy.F90 b/src/tallies/tally_filter_energy.F90 index 29a203d17c..064359663f 100644 --- a/src/tallies/tally_filter_energy.F90 +++ b/src/tallies/tally_filter_energy.F90 @@ -1,17 +1,21 @@ module tally_filter_energy + use, intrinsic :: ISO_C_BINDING + use hdf5, only: HID_T use algorithm, only: binary_search use constants + use error use hdf5_interface use mgxs_header, only: num_energy_groups use particle_header, only: Particle use string, only: to_str - use tally_filter_header, only: TallyFilter, TallyFilterMatch + use tally_filter_header implicit none private + public :: openmc_energy_filter_set_bins !=============================================================================== ! ENERGYFILTER bins the incident neutron energy. @@ -157,4 +161,35 @@ contains // trim(to_str(E1)) // ")" end function text_label_energyout +!=============================================================================== +! C API FUNCTIONS +!=============================================================================== + + function openmc_energy_filter_set_bins(index, n, energies) result(err) bind(C) + ! Set the bounding energies for an energy filter + integer(C_INT32_T), value, intent(in) :: index + integer(C_INT32_T), value, intent(in) :: n + real(C_DOUBLE), intent(in) :: energies(n) + integer(C_INT) :: err + + err = 0 + if (index >= 1 .and. index <= n_filters) then + if (allocated(filters(index) % obj)) then + select type (f => filters(index) % obj) + type is (EnergyFilter) + f % n_bins = n - 1 + if (allocated(f % bins)) deallocate(f % bins) + allocate(f % bins(n)) + f % bins(:) = energies + class default + err = E_WRONG_TYPE + end select + else + err = E_FILTER_NOT_ALLOCATED + end if + else + err = E_OUT_OF_BOUNDS + end if + end function openmc_energy_filter_set_bins + end module tally_filter_energy diff --git a/src/tallies/tally_filter_mesh.F90 b/src/tallies/tally_filter_mesh.F90 index c56902bab1..bef1cd5fdc 100644 --- a/src/tallies/tally_filter_mesh.F90 +++ b/src/tallies/tally_filter_mesh.F90 @@ -1,17 +1,20 @@ module tally_filter_mesh + use, intrinsic :: ISO_C_BINDING + use hdf5 use constants - use error, only: warning - use mesh_header, only: RegularMesh, meshes + use error + use mesh_header, only: RegularMesh, meshes, n_meshes use hdf5_interface use particle_header, only: Particle use string, only: to_str - use tally_filter_header, only: TallyFilter, TallyFilterMatch + use tally_filter_header implicit none private + public :: openmc_mesh_filter_set_mesh !=============================================================================== ! MESHFILTER indexes the location of particle events to a regular mesh. For @@ -240,4 +243,36 @@ contains end associate end function text_label_mesh +!=============================================================================== +! C API FUNCTIONS +!=============================================================================== + + function openmc_mesh_filter_set_mesh(index, index_mesh) result(err) bind(C) + ! Set the mesh for a mesh filter + integer(C_INT32_T), value, intent(in) :: index + integer(C_INT32_T), value, intent(in) :: index_mesh + integer(C_INT) :: err + + err = 0 + if (index >= 1 .and. index <= n_filters) then + if (allocated(filters(index) % obj)) then + select type (f => filters(index) % obj) + type is (MeshFilter) + if (index_mesh >= 1 .and. index_mesh <= n_meshes) then + f % mesh = index_mesh + f % n_bins = product(meshes(index_mesh) % dimension) + else + err = E_OUT_OF_BOUNDS + end if + class default + err = E_WRONG_TYPE + end select + else + err = E_FILTER_NOT_ALLOCATED + end if + else + err = E_OUT_OF_BOUNDS + end if + end function openmc_mesh_filter_set_mesh + end module tally_filter_mesh diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index bcd156ae8c..66e00a65cb 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -9,7 +9,7 @@ module tally_header use dict_header, only: DictIntInt use nuclide_header, only: nuclide_dict use string, only: to_lower, to_f_string, str_to_int - use tally_filter_header, only: TallyFilterContainer, filters + use tally_filter_header, only: TallyFilterContainer, filters, n_filters use trigger_header, only: TriggerObject implicit none @@ -18,8 +18,10 @@ module tally_header public :: openmc_extend_tallies public :: openmc_get_tally public :: openmc_tally_get_id + public :: openmc_tally_get_filters public :: openmc_tally_get_nuclides public :: openmc_tally_results + public :: openmc_tally_set_filters public :: openmc_tally_set_nuclides public :: openmc_tally_set_scores @@ -337,6 +339,28 @@ contains end function openmc_tally_get_id + function openmc_tally_get_filters(index, filter_indices, n) result(err) bind(C) + ! Return the list of nuclides assigned to a tally + integer(C_INT32_T), value :: index + type(C_PTR), intent(out) :: filter_indices + integer(C_INT), intent(out) :: n + integer(C_INT) :: err + + err = E_UNASSIGNED + if (index >= 1 .and. index <= size(tallies)) then + associate (t => tallies(index)) + if (allocated(t % filter)) then + filter_indices = C_LOC(t % filter(1)) + n = size(t % filter) + err = 0 + end if + end associate + else + err = E_OUT_OF_BOUNDS + end if + end function openmc_tally_get_filters + + function openmc_tally_get_nuclides(index, nuclides, n) result(err) bind(C) ! Return the list of nuclides assigned to a tally integer(C_INT32_T), value :: index @@ -380,6 +404,34 @@ contains end function openmc_tally_results + function openmc_tally_set_filters(index, n, filter_indices) result(err) bind(C) + ! Set the list of filters for a tally + integer(C_INT32_T), value, intent(in) :: index + integer(C_INT), value, intent(in) :: n + integer(C_INT32_T), intent(in) :: filter_indices(n) + integer(C_INT) :: err + + integer :: i + + err = 0 + if (index >= 1 .and. index <= n_tallies) then + associate (t => tallies(index)) + if (allocated(t % filter)) deallocate(t % filter) + allocate(t % filter(n)) + do i = 1, n + if (filter_indices(n) < 1 .or. filter_indices(i) > n_filters) then + err = E_OUT_OF_BOUNDS + exit + end if + end do + if (err == 0) t % filter(:) = filter_indices + end associate + else + err = E_OUT_OF_BOUNDS + end if + end function openmc_tally_set_filters + + function openmc_tally_set_nuclides(index, n, nuclides) result(err) bind(C) ! Sets the nuclides in the tally which results should be scored for integer(C_INT32_T), value :: index @@ -425,6 +477,7 @@ contains end if end function openmc_tally_set_nuclides + function openmc_tally_set_scores(index, n, scores) result(err) bind(C) ! Sets the scores in the tally integer(C_INT32_T), value :: index