diff --git a/openmc/capi/filter.py b/openmc/capi/filter.py index 2d3766dbfe..0bcab11106 100644 --- a/openmc/capi/filter.py +++ b/openmc/capi/filter.py @@ -145,6 +145,16 @@ class MaterialFilterView(FilterView): _dll.openmc_material_filter_set_bins(self._index, n, bins) + @classmethod + def new(cls, bins=None): + index = c_int32() + _dll.openmc_extend_filters(1, index, None) + _dll.openmc_filter_set_type(index, b'material') + f = cls(index.value) + if bins is not None: + f.bins = bins + return f + class MeshFilterView(FilterView): pass diff --git a/openmc/capi/tally.py b/openmc/capi/tally.py index 155b0eaf54..6a62fb8bdc 100644 --- a/openmc/capi/tally.py +++ b/openmc/capi/tally.py @@ -36,12 +36,18 @@ _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_id.argtypes = [c_int32, c_int32] +_dll.openmc_tally_set_id.restype = c_int +_dll.openmc_tally_set_id.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 +_dll.openmc_tally_set_type.argtypes = [c_int32, c_char_p] +_dll.openmc_tally_set_type.restype = c_int +_dll.openmc_tally_set_type.errcheck = _error_handler class TallyView(object): @@ -85,6 +91,10 @@ class TallyView(object): _dll.openmc_tally_get_id(self._index, tally_id) return tally_id.value + @id.setter + def id(self, tally_id): + _dll.openmc_tally_set_id(self._index, tally_id) + @property def filters(self): filt_idx = POINTER(c_int32)() @@ -121,6 +131,23 @@ class TallyView(object): nucs[:] = [x.encode() for x in nuclides] _dll.openmc_tally_set_nuclides(self._index, len(nuclides), nucs) + @property + def scores(self): + pass + + @scores.setter + def scores(self, scores): + scores_ = (c_char_p * len(scores))() + scores_[:] = [x.encode() for x in scores] + _dll.openmc_tally_set_scores(self._index, len(scores), scores_) + + @classmethod + def new(cls): + index = c_int32() + _dll.openmc_extend_tallies(1, index, None) + _dll.openmc_tally_set_type(index, b'generic') + return cls(index.value) + class _TallyMapping(Mapping): def __getitem__(self, key): diff --git a/src/api.F90 b/src/api.F90 index af00cdd837..247410d2b2 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -66,6 +66,7 @@ module openmc_api public :: openmc_tally_get_nuclides public :: openmc_tally_results public :: openmc_tally_set_filters + public :: openmc_tally_set_id public :: openmc_tally_set_nuclides public :: openmc_tally_set_scores public :: openmc_tally_set_type diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 071677fe46..ee6dd98d4c 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -3249,17 +3249,6 @@ contains ! Get pointer to tally xml node node_tal = node_tal_list(i) - ! Set tally type to volume by default - t % type = TALLY_VOLUME - - ! It's desirable to use a track-length esimator for tallies since - ! generally more events will score to the tally, reducing the - ! variance. However, for tallies that require information on - ! post-collision parameters (e.g. tally with an energyout filter) the - ! analog esimator must be used. - - t % estimator = ESTIMATOR_TRACKLENGTH - ! Copy tally id if (check_for_node(node_tal, "id")) then call get_node_value(node_tal, "id", t % id) @@ -3318,8 +3307,6 @@ contains ! Set the filters err = openmc_tally_set_filters(i_start + i - 1, n_filter, temp_filter) - else - allocate(t % filter(n_filter)) end if deallocate(temp_filter) diff --git a/src/tallies/tally.F90 b/src/tallies/tally.F90 index 77747b85a0..3c83aa6e92 100644 --- a/src/tallies/tally.F90 +++ b/src/tallies/tally.F90 @@ -4429,6 +4429,7 @@ contains character(kind=C_CHAR), intent(in) :: type(*) integer(C_INT) :: err + integer(C_INT32_T) :: empty(0) character(:), allocatable :: type_ ! Convert C string to Fortran string @@ -4445,6 +4446,9 @@ contains case default err = E_UNASSIGNED end select + + ! When a tally is allocated, set it to have 0 filters + err = tallies(index) % obj % set_filters(empty) end if else err = E_OUT_OF_BOUNDS diff --git a/src/tallies/tally_header.F90 b/src/tallies/tally_header.F90 index f97df50b8c..6c5c3106b1 100644 --- a/src/tallies/tally_header.F90 +++ b/src/tallies/tally_header.F90 @@ -24,6 +24,7 @@ module tally_header public :: openmc_tally_get_nuclides public :: openmc_tally_results public :: openmc_tally_set_filters + public :: openmc_tally_set_id public :: openmc_tally_set_nuclides public :: openmc_tally_set_scores @@ -51,8 +52,8 @@ module tally_header integer :: id ! user-defined identifier character(len=104) :: name = "" ! user-defined name - integer :: type ! volume, surface current - integer :: estimator ! collision, track-length + integer :: type = TALLY_VOLUME ! volume, surface current + integer :: estimator = ESTIMATOR_TRACKLENGTH ! collision, track-length real(8) :: volume ! volume of region logical :: active = .false. integer, allocatable :: filter(:) ! index in filters array @@ -235,6 +236,13 @@ contains subroutine tally_allocate_results(this) class(TallyObject), intent(inout) :: this + ! If no nuclides were specified, add a single bin for total material + if (.not. allocated(this % nuclide_bins)) then + allocate(this % nuclide_bins(1)) + this % nuclide_bins(1) = -1 + this % n_nuclide_bins = 1 + end if + ! Set total number of filter and scoring bins this % total_score_bins = this % n_score_bins * this % n_nuclide_bins @@ -520,6 +528,27 @@ contains end function openmc_tally_set_filters + function openmc_tally_set_id(index, id) result(err) bind(C) + ! Set the ID of a tally + integer(C_INT32_T), value, intent(in) :: index + integer(C_INT32_T), value, intent(in) :: id + integer(C_INT) :: err + + if (index >= 1 .and. index <= n_tallies) then + if (allocated(tallies(index) % obj)) then + tallies(index) % obj % id = id + call tally_dict % add_key(id, index) + + err = 0 + else + err = E_FILTER_NOT_ALLOCATED + end if + else + err = E_OUT_OF_BOUNDS + end if + end function openmc_tally_set_id + + 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