diff --git a/docs/source/capi/index.rst b/docs/source/capi/index.rst index 222f81c4b..52c0b2406 100644 --- a/docs/source/capi/index.rst +++ b/docs/source/capi/index.rst @@ -460,6 +460,13 @@ Functions :return: Return status (negative if an error occurs) :rtype: int +.. c:function:: int openmc_remove_tally(int32_t index); + + Given an index of a tally, remove it from the tallies array + :param int index: Index in tallies array + :return: Return status (negative if an error occurs) + :rtype: int + .. c:function:: int openmc_run() Run a simulation diff --git a/include/openmc/capi.h b/include/openmc/capi.h index 69d3ff1f6..29e900965 100644 --- a/include/openmc/capi.h +++ b/include/openmc/capi.h @@ -118,6 +118,7 @@ int openmc_regular_mesh_get_params( int openmc_regular_mesh_set_dimension(int32_t index, int n, const int* dims); int openmc_regular_mesh_set_params(int32_t index, int n, const double* ll, const double* ur, const double* width); +int openmc_remove_tally(int32_t index); int openmc_reset(); int openmc_reset_timers(); int openmc_run(); diff --git a/include/openmc/tallies/tally.h b/include/openmc/tallies/tally.h index 73618a3da..3cead91dc 100644 --- a/include/openmc/tallies/tally.h +++ b/include/openmc/tallies/tally.h @@ -47,9 +47,11 @@ public: void set_nuclides(const vector& nuclides); - const vector& filters() const { return filters_; } + //! returns vector of indices corresponding to the tally this is called on + const vector& filters() const { return filters_; } - int32_t filters(int i) const { return filters_[i]; } + //! \brief Returns the tally filter at index i + int32_t filters(int i) const { return filters_[i]; } void set_filters(gsl::span filters); diff --git a/openmc/lib/tally.py b/openmc/lib/tally.py index df28cb5dc..85af8ffff 100644 --- a/openmc/lib/tally.py +++ b/openmc/lib/tally.py @@ -87,6 +87,9 @@ _dll.openmc_tally_set_type.errcheck = _error_handler _dll.openmc_tally_set_writable.argtypes = [c_int32, c_bool] _dll.openmc_tally_set_writable.restype = c_int _dll.openmc_tally_set_writable.errcheck = _error_handler +_dll.openmc_remove_tally.argtypes = [c_int32] +_dll.openmc_remove_tally.restype = c_int +_dll.openmc_remove_tally.errcheck = _error_handler _dll.tallies_size.restype = c_size_t @@ -405,4 +408,8 @@ class _TallyMapping(Mapping): def __repr__(self): return repr(dict(self)) + def __delitem__(self, key): + """Delete a tally from tally vector and remove the ID,index pair from tally""" + _dll.openmc_remove_tally(self[key]._index) + tallies = _TallyMapping() diff --git a/src/tallies/tally.cpp b/src/tallies/tally.cpp index c0fedd973..59adce455 100644 --- a/src/tallies/tally.cpp +++ b/src/tallies/tally.cpp @@ -46,6 +46,7 @@ namespace openmc { //============================================================================== namespace model { +//! a mapping of tally ID to index in the tallies vector std::unordered_map tally_map; vector> tallies; vector active_tallies; @@ -1271,4 +1272,20 @@ extern "C" size_t tallies_size() return model::tallies.size(); } +// given a tally ID, remove it from the tallies vector +extern "C" int openmc_remove_tally(int32_t index) +{ + // check that id is in the map + if (index < 0 || index > model::tallies.size()) { + return OPENMC_E_OUT_OF_BOUNDS; + } + // grab tally so it's ID can be obtained to remove the (ID,index) pair from tally_map + auto& tally = model::tallies[index]; + // delete the tally via iterator pointing to correct position + // this calls the Tally destructor, removing the tally from the map as well + model::tallies.erase(model::tallies.begin() + index); + + return 0; +} + } // namespace openmc diff --git a/tests/unit_tests/test_lib.py b/tests/unit_tests/test_lib.py index b57242983..5063646f7 100644 --- a/tests/unit_tests/test_lib.py +++ b/tests/unit_tests/test_lib.py @@ -340,6 +340,20 @@ def test_new_tally(lib_init): assert len(openmc.lib.tallies) == 5 +def test_delete_tally(lib_init): + # delete tally 10 which was added in the above test + # check length is one less than before + del openmc.lib.tallies[10] + assert len(openmc.lib.tallies) == 4 + + +def test_invalid_tally_id(lib_init): + # attempt to access a tally that is guaranteed not to have a valid index + max_id = max(openmc.lib.tallies.keys()) + with pytest.raises(KeyError): + openmc.lib.tallies[max_id+1] + + def test_tally_activate(lib_simulation_init): t = openmc.lib.tallies[1] assert not t.active diff --git a/tests/unit_tests/test_tallies.py b/tests/unit_tests/test_tallies.py index bfff741a9..14319a0a2 100644 --- a/tests/unit_tests/test_tallies.py +++ b/tests/unit_tests/test_tallies.py @@ -38,4 +38,4 @@ def test_xml_roundtrip(run_in_tmpdir): assert len(new_tally.triggers) == 1 assert new_tally.triggers[0].trigger_type == tally.triggers[0].trigger_type assert new_tally.triggers[0].threshold == tally.triggers[0].threshold - assert new_tally.triggers[0].scores == tally.triggers[0].scores + assert new_tally.triggers[0].scores == tally.triggers[0].scores \ No newline at end of file