From a55d74a5cbfc0e46e4b5db5b623d9dfc2450309b Mon Sep 17 00:00:00 2001 From: Joffrey Dorville Date: Fri, 23 Feb 2024 11:01:20 -0600 Subject: [PATCH 1/3] Add a meshborn filter for tallies --- CMakeLists.txt | 1 + docs/source/capi/index.rst | 102 ++++++++++++ docs/source/pythonapi/base.rst | 1 + docs/source/pythonapi/capi.rst | 1 + include/openmc/particle_data.h | 5 + include/openmc/tallies/filter.h | 1 + include/openmc/tallies/filter_meshborn.h | 27 ++++ openmc/filter.py | 28 ++++ openmc/lib/filter.py | 148 ++++++++++++++++-- src/particle.cpp | 1 + src/tallies/filter.cpp | 3 + src/tallies/filter_mesh.cpp | 2 + src/tallies/filter_meshborn.cpp | 66 ++++++++ src/tallies/filter_meshsurface.cpp | 12 ++ src/tallies/tally.cpp | 1 + .../filter_meshborn/__init__.py | 0 .../filter_meshborn/inputs_true.dat | 52 ++++++ .../filter_meshborn/results_true.dat | 54 +++++++ .../regression_tests/filter_meshborn/test.py | 131 ++++++++++++++++ tests/unit_tests/test_filter_meshborn.py | 144 +++++++++++++++++ tests/unit_tests/test_tallies.py | 7 +- 21 files changed, 776 insertions(+), 11 deletions(-) create mode 100644 include/openmc/tallies/filter_meshborn.h create mode 100644 src/tallies/filter_meshborn.cpp create mode 100644 tests/regression_tests/filter_meshborn/__init__.py create mode 100644 tests/regression_tests/filter_meshborn/inputs_true.dat create mode 100644 tests/regression_tests/filter_meshborn/results_true.dat create mode 100644 tests/regression_tests/filter_meshborn/test.py create mode 100644 tests/unit_tests/test_filter_meshborn.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 1280daf2b96..6922e6b89a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -411,6 +411,7 @@ list(APPEND libopenmc_SOURCES src/tallies/filter_material.cpp src/tallies/filter_materialfrom.cpp src/tallies/filter_mesh.cpp + src/tallies/filter_meshborn.cpp src/tallies/filter_meshsurface.cpp src/tallies/filter_mu.cpp src/tallies/filter_particle.cpp diff --git a/docs/source/capi/index.rst b/docs/source/capi/index.rst index 52c0b2406aa..d9ac0d1e019 100644 --- a/docs/source/capi/index.rst +++ b/docs/source/capi/index.rst @@ -420,6 +420,16 @@ Functions :return: Return status (negative if an error occurred) :rtype: int +.. c:function:: int openmc_mesh_filter_get_mesh(int32_t index, int32_t* index_mesh) + + Get the mesh for a mesh filter + + :param int32_t index: Index in the filters array + :param index_mesh: Index in the meshes array + :type index_mesh: int32_t* + :return: Return status (negative if an error occurred) + :rtype: int + .. c:function:: int openmc_mesh_filter_set_mesh(int32_t index, int32_t index_mesh) Set the mesh for a mesh filter @@ -429,6 +439,98 @@ Functions :return: Return status (negative if an error occurred) :rtype: int +.. c:function:: int openmc_mesh_filter_get_translation(int32_t index, double translation[3]) + + Get the 3-D translation coordinates for a mesh filter + + :param int32_t index: Index in the filters array + :param double[3] translation: 3-D translation coordinates + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_mesh_filter_set_translation(int32_t index, double translation[3]) + + Set the 3-D translation coordinates for a mesh filter + + :param int32_t index: Index in the filters array + :param double[3] translation: 3-D translation coordinates + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_meshborn_filter_get_mesh(int32_t index, int32_t* index_mesh) + + Get the mesh for a meshborn filter + + :param int32_t index: Index in the filters array + :param index_mesh: Index in the meshes array + :type index_mesh: int32_t* + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_meshborn_filter_set_mesh(int32_t index, int32_t index_mesh) + + Set the mesh for a meshborn filter + + :param int32_t index: Index in the filters array + :param int32_t index_mesh: Index in the meshes array + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_meshborn_filter_get_translation(int32_t index, double translation[3]) + + Get the 3-D translation coordinates for a meshborn filter + + :param int32_t index: Index in the filters array + :param double[3] translation: 3-D translation coordinates + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_meshborn_filter_set_translation(int32_t index, double translation[3]) + + Set the 3-D translation coordinates for a meshborn filter + + :param int32_t index: Index in the filters array + :param double[3] translation: 3-D translation coordinates + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_meshsurface_filter_get_mesh(int32_t index, int32_t* index_mesh) + + Get the mesh for a mesh surface filter + + :param int32_t index: Index in the filters array + :param index_mesh: Index in the meshes array + :type index_mesh: int32_t* + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_meshsurface_filter_set_mesh(int32_t index, int32_t index_mesh) + + Set the mesh for a mesh surface filter + + :param int32_t index: Index in the filters array + :param int32_t index_mesh: Index in the meshes array + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_meshsurface_filter_get_translation(int32_t index, double translation[3]) + + Get the 3-D translation coordinates for a mesh surface filter + + :param int32_t index: Index in the filters array + :param double[3] translation: 3-D translation coordinates + :return: Return status (negative if an error occurred) + :rtype: int + +.. c:function:: int openmc_meshsurface_filter_set_translation(int32_t index, double translation[3]) + + Set the 3-D translation coordinates for a mesh surface filter + + :param int32_t index: Index in the filters array + :param double[3] translation: 3-D translation coordinates + :return: Return status (negative if an error occurred) + :rtype: int + .. c:function:: int openmc_next_batch() Simulate next batch of particles. Must be called after openmc_simulation_init(). diff --git a/docs/source/pythonapi/base.rst b/docs/source/pythonapi/base.rst index 7b924e37499..5ae9f20edf4 100644 --- a/docs/source/pythonapi/base.rst +++ b/docs/source/pythonapi/base.rst @@ -128,6 +128,7 @@ Constructing Tallies openmc.CollisionFilter openmc.SurfaceFilter openmc.MeshFilter + openmc.MeshBornFilter openmc.MeshSurfaceFilter openmc.EnergyFilter openmc.EnergyoutFilter diff --git a/docs/source/pythonapi/capi.rst b/docs/source/pythonapi/capi.rst index ef713801ccc..16bb68ca433 100644 --- a/docs/source/pythonapi/capi.rst +++ b/docs/source/pythonapi/capi.rst @@ -59,6 +59,7 @@ Classes MaterialFilter Material MeshFilter + MeshBornFilter MeshSurfaceFilter Nuclide RectilinearMesh diff --git a/include/openmc/particle_data.h b/include/openmc/particle_data.h index cb68fc45740..cceab1d1106 100644 --- a/include/openmc/particle_data.h +++ b/include/openmc/particle_data.h @@ -262,6 +262,10 @@ class GeometryState { int& cell_last(int i) { return cell_last_[i]; } const int& cell_last(int i) const { return cell_last_[i]; } + // Coordinates at birth + Position& r_born() { return r_born_; } + const Position& r_born() const { return r_born_; } + // Coordinates of last collision or reflective/periodic surface // crossing for current tallies Position& r_last_current() { return r_last_current_; } @@ -323,6 +327,7 @@ class GeometryState { int n_coord_last_ {1}; //!< number of current coordinates vector cell_last_; //!< coordinates for all levels + Position r_born_; //!< coordinates at birth Position r_last_current_; //!< coordinates of the last collision or //!< reflective/periodic surface crossing for //!< current tallies diff --git a/include/openmc/tallies/filter.h b/include/openmc/tallies/filter.h index dc5872ce670..1166c0eee53 100644 --- a/include/openmc/tallies/filter.h +++ b/include/openmc/tallies/filter.h @@ -33,6 +33,7 @@ enum class FilterType { MATERIAL, MATERIALFROM, MESH, + MESHBORN, MESH_SURFACE, MU, PARTICLE, diff --git a/include/openmc/tallies/filter_meshborn.h b/include/openmc/tallies/filter_meshborn.h new file mode 100644 index 00000000000..dd48135baab --- /dev/null +++ b/include/openmc/tallies/filter_meshborn.h @@ -0,0 +1,27 @@ +#ifndef OPENMC_TALLIES_FILTER_MESHBORN_H +#define OPENMC_TALLIES_FILTER_MESHBORN_H + +#include + +#include "openmc/position.h" +#include "openmc/tallies/filter_mesh.h" + +namespace openmc { + +class MeshBornFilter : public MeshFilter { +public: + //---------------------------------------------------------------------------- + // Methods + + std::string type_str() const override { return "meshborn"; } + FilterType type() const override { return FilterType::MESHBORN; } + + void get_all_bins(const Particle& p, TallyEstimator estimator, + FilterMatch& match) const override; + + std::string text_label(int bin) const override; + +}; + +} // namespace openmc +#endif // OPENMC_TALLIES_FILTER_MESHBORN_H diff --git a/openmc/filter.py b/openmc/filter.py index f2bbf2f5050..04b30261da2 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -982,6 +982,34 @@ def from_xml_element(cls, elem, **kwargs): if translation: out.translation = [float(x) for x in translation.split()] return out + + +class MeshBornFilter(MeshFilter): + """Filter events by the mesh cell a particle originated from. + + Parameters + ---------- + mesh : openmc.MeshBase + The mesh object that events will be tallied onto + filter_id : int + Unique identifier for the filter + + Attributes + ---------- + mesh : openmc.MeshBase + The mesh object that events will be tallied onto + id : int + Unique identifier for the filter + translation : Iterable of float + This array specifies a vector that is used to translate (shift) + the mesh for this filter + bins : list of tuple + A list of mesh indices for each filter bin, e.g. [(1, 1, 1), (2, 1, 1), + ...] + num_bins : Integral + The number of filter bins + + """ class MeshSurfaceFilter(MeshFilter): diff --git a/openmc/lib/filter.py b/openmc/lib/filter.py index 7c2e7e5c45f..6a02eee1e0a 100644 --- a/openmc/lib/filter.py +++ b/openmc/lib/filter.py @@ -20,7 +20,8 @@ 'Filter', 'AzimuthalFilter', 'CellFilter', 'CellbornFilter', 'CellfromFilter', 'CellInstanceFilter', 'CollisionFilter', 'DistribcellFilter', 'DelayedGroupFilter', 'EnergyFilter', 'EnergyoutFilter', 'EnergyFunctionFilter', 'LegendreFilter', - 'MaterialFilter', 'MaterialFromFilter', 'MeshFilter', 'MeshSurfaceFilter', 'MuFilter', 'ParticleFilter', + 'MaterialFilter', 'MaterialFromFilter', 'MeshFilter', 'MeshBornFilter', + 'MeshSurfaceFilter', 'MuFilter', 'ParticleFilter', 'PolarFilter', 'SphericalHarmonicsFilter', 'SpatialLegendreFilter', 'SurfaceFilter', 'UniverseFilter', 'ZernikeFilter', 'ZernikeRadialFilter', 'filters' ] @@ -89,18 +90,36 @@ _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 -_dll.openmc_meshsurface_filter_get_mesh.argtypes = [c_int32, POINTER(c_int32)] -_dll.openmc_meshsurface_filter_get_mesh.restype = c_int -_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_mesh_filter_get_translation.argtypes = [c_int32, POINTER(c_double*3)] _dll.openmc_mesh_filter_get_translation.restype = c_int _dll.openmc_mesh_filter_get_translation.errcheck = _error_handler _dll.openmc_mesh_filter_set_translation.argtypes = [c_int32, POINTER(c_double*3)] _dll.openmc_mesh_filter_set_translation.restype = c_int _dll.openmc_mesh_filter_set_translation.errcheck = _error_handler +_dll.openmc_meshborn_filter_get_mesh.argtypes = [c_int32, POINTER(c_int32)] +_dll.openmc_meshborn_filter_get_mesh.restype = c_int +_dll.openmc_meshborn_filter_get_mesh.errcheck = _error_handler +_dll.openmc_meshborn_filter_set_mesh.argtypes = [c_int32, c_int32] +_dll.openmc_meshborn_filter_set_mesh.restype = c_int +_dll.openmc_meshborn_filter_set_mesh.errcheck = _error_handler +_dll.openmc_meshborn_filter_get_translation.argtypes = [c_int32, POINTER(c_double*3)] +_dll.openmc_meshborn_filter_get_translation.restype = c_int +_dll.openmc_meshborn_filter_get_translation.errcheck = _error_handler +_dll.openmc_meshborn_filter_set_translation.argtypes = [c_int32, POINTER(c_double*3)] +_dll.openmc_meshborn_filter_set_translation.restype = c_int +_dll.openmc_meshborn_filter_set_translation.errcheck = _error_handler +_dll.openmc_meshsurface_filter_get_mesh.argtypes = [c_int32, POINTER(c_int32)] +_dll.openmc_meshsurface_filter_get_mesh.restype = c_int +_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_meshsurface_filter_get_translation.argtypes = [c_int32, POINTER(c_double*3)] +_dll.openmc_meshsurface_filter_get_translation.restype = c_int +_dll.openmc_meshsurface_filter_get_translation.errcheck = _error_handler +_dll.openmc_meshsurface_filter_set_translation.argtypes = [c_int32, POINTER(c_double*3)] +_dll.openmc_meshsurface_filter_set_translation.restype = c_int +_dll.openmc_meshsurface_filter_set_translation.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 @@ -347,6 +366,33 @@ class MaterialFromFilter(Filter): class MeshFilter(Filter): + """Mesh filter stored internally. + + This class exposes a Mesh filter that is stored internally in the OpenMC library. + To obtain a view of a Mesh filter with a given ID, use the :data:`openmc.lib.filters` mapping. + + Parameters + ---------- + mesh : openmc.lib.Mesh + Mesh to use for the filter + uid : int or None + Unique ID of the Mesh filter + new : bool + When `index` is None, this argument controls whether a new object is + created or a view of an existing object is returned. + index : int + Index in the `filters` array. + + Attributes + ---------- + filter_type : str + Type of filter + mesh : openmc.lib.Mesh + Mesh used for the filter + translation : Iterable of float + 3-D coordinates of the translation vector + + """ filter_type = 'mesh' def __init__(self, mesh=None, uid=None, new=True, index=None): @@ -375,7 +421,90 @@ def translation(self, translation): _dll.openmc_mesh_filter_set_translation(self._index, (c_double*3)(*translation)) +class MeshBornFilter(Filter): + """MeshBorn filter stored internally. + + This class exposes a MeshBorn filter that is stored internally in the OpenMC library. + To obtain a view of a MeshBorn filter with a given ID, use the :data:`openmc.lib.filters` mapping. + + Parameters + ---------- + mesh : openmc.lib.Mesh + Mesh to use for the filter + uid : int or None + Unique ID of the MeshBorn filter + new : bool + When `index` is None, this argument controls whether a new object is + created or a view of an existing object is returned. + index : int + Index in the `filters` array. + + Attributes + ---------- + filter_type : str + Type of filter + mesh : openmc.lib.Mesh + Mesh used for the filter + translation : Iterable of float + 3-D coordinates of the translation vector + + """ + filter_type = 'meshborn' + + def __init__(self, mesh=None, uid=None, new=True, index=None): + super().__init__(uid, new, index) + if mesh is not None: + self.mesh = mesh + + @property + def mesh(self): + index_mesh = c_int32() + _dll.openmc_meshborn_filter_get_mesh(self._index, index_mesh) + return _get_mesh(index_mesh.value) + + @mesh.setter + def mesh(self, mesh): + _dll.openmc_meshborn_filter_set_mesh(self._index, mesh._index) + + @property + def translation(self): + translation = (c_double*3)() + _dll.openmc_meshborn_filter_get_translation(self._index, translation) + return tuple(translation) + + @translation.setter + def translation(self, translation): + _dll.openmc_meshborn_filter_set_translation(self._index, (c_double*3)(*translation)) + + class MeshSurfaceFilter(Filter): + """MeshSurface filter stored internally. + + This class exposes a MeshSurface filter that is stored internally in the OpenMC library. + To obtain a view of a MeshSurface filter with a given ID, use the :data:`openmc.lib.filters` mapping. + + Parameters + ---------- + mesh : openmc.lib.Mesh + Mesh to use for the filter + uid : int or None + Unique ID of the MeshSurface filter + new : bool + When `index` is None, this argument controls whether a new object is + created or a view of an existing object is returned. + index : int + Index in the `filters` array. + + Attributes + ---------- + filter_type : str + Type of filter + mesh : openmc.lib.Mesh + Mesh used for the filter + translation : Iterable of float + 3-D coordinates of the translation vector + + """ filter_type = 'meshsurface' def __init__(self, mesh=None, uid=None, new=True, index=None): @@ -396,12 +525,12 @@ def mesh(self, mesh): @property def translation(self): translation = (c_double*3)() - _dll.openmc_mesh_filter_get_translation(self._index, translation) + _dll.openmc_meshsurface_filter_get_translation(self._index, translation) return tuple(translation) @translation.setter def translation(self, translation): - _dll.openmc_mesh_filter_set_translation(self._index, (c_double*3)(*translation)) + _dll.openmc_meshsurface_filter_set_translation(self._index, (c_double*3)(*translation)) class MuFilter(Filter): @@ -507,6 +636,7 @@ class ZernikeRadialFilter(ZernikeFilter): 'material': MaterialFilter, 'materialfrom': MaterialFromFilter, 'mesh': MeshFilter, + 'meshborn': MeshBornFilter, 'meshsurface': MeshSurfaceFilter, 'mu': MuFilter, 'particle': ParticleFilter, diff --git a/src/particle.cpp b/src/particle.cpp index 549de5cff65..fc92f019531 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -121,6 +121,7 @@ void Particle::from_source(const SourceSite* src) wgt_last() = src->wgt; r() = src->r; u() = src->u; + r_born() = src-> r; r_last_current() = src->r; r_last() = src->r; u_last() = src->u; diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index 5fae4cf600b..ff7a3416b90 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -23,6 +23,7 @@ #include "openmc/tallies/filter_material.h" #include "openmc/tallies/filter_materialfrom.h" #include "openmc/tallies/filter_mesh.h" +#include "openmc/tallies/filter_meshborn.h" #include "openmc/tallies/filter_meshsurface.h" #include "openmc/tallies/filter_mu.h" #include "openmc/tallies/filter_particle.h" @@ -126,6 +127,8 @@ Filter* Filter::create(const std::string& type, int32_t id) return Filter::create(id); } else if (type == "mesh") { return Filter::create(id); + } else if (type == "meshborn") { + return Filter::create(id); } else if (type == "meshsurface") { return Filter::create(id); } else if (type == "mu") { diff --git a/src/tallies/filter_mesh.cpp b/src/tallies/filter_mesh.cpp index ed9c7166735..5b01da1f65a 100644 --- a/src/tallies/filter_mesh.cpp +++ b/src/tallies/filter_mesh.cpp @@ -161,6 +161,7 @@ extern "C" int openmc_mesh_filter_get_translation( // Check the filter type const auto& filter = model::tally_filters[index]; if (filter->type() != FilterType::MESH && + filter->type() != FilterType::MESHBORN && filter->type() != FilterType::MESH_SURFACE) { set_errmsg("Tried to get a translation from a non-mesh-based filter."); return OPENMC_E_INVALID_TYPE; @@ -186,6 +187,7 @@ extern "C" int openmc_mesh_filter_set_translation( const auto& filter = model::tally_filters[index]; // Check the filter type if (filter->type() != FilterType::MESH && + filter->type() != FilterType::MESHBORN && filter->type() != FilterType::MESH_SURFACE) { set_errmsg("Tried to set mesh on a non-mesh-based filter."); return OPENMC_E_INVALID_TYPE; diff --git a/src/tallies/filter_meshborn.cpp b/src/tallies/filter_meshborn.cpp new file mode 100644 index 00000000000..3109788ca79 --- /dev/null +++ b/src/tallies/filter_meshborn.cpp @@ -0,0 +1,66 @@ +#include "openmc/tallies/filter_meshborn.h" + +#include +#include + +#include "openmc/capi.h" +#include "openmc/constants.h" +#include "openmc/error.h" +#include "openmc/mesh.h" + +namespace openmc { + +void MeshBornFilter::get_all_bins( + const Particle& p, TallyEstimator estimator, FilterMatch& match) const +{ + Position r_born = p.r_born(); + + // apply translation if present + if (translated_) { + r_born -= translation(); + } + + auto bin = model::meshes[mesh_]->get_bin(r_born); + if (bin >= 0) { + match.bins_.push_back(bin); + match.weights_.push_back(1.0); + } +} + +std::string MeshBornFilter::text_label(int bin) const +{ + auto& mesh = *model::meshes.at(mesh_); + std::string label = mesh.bin_label(bin); + label += " (" + type_str() + ")"; + return label; +} + +//============================================================================== +// C-API functions +//============================================================================== + +extern "C" int openmc_meshborn_filter_get_mesh( + int32_t index, int32_t* index_mesh) +{ + return openmc_mesh_filter_get_mesh(index, index_mesh); +} + +extern "C" int openmc_meshborn_filter_set_mesh( + int32_t index, int32_t index_mesh) +{ + return openmc_mesh_filter_set_mesh(index, index_mesh); +} + +extern "C" int openmc_meshborn_filter_get_translation( + int32_t index, double translation[3]) +{ + return openmc_mesh_filter_get_translation(index, translation); +} + +extern "C" int openmc_meshborn_filter_set_translation( + int32_t index, double translation[3]) +{ + return openmc_mesh_filter_set_translation(index, translation); +} + +} // namespace openmc diff --git a/src/tallies/filter_meshsurface.cpp b/src/tallies/filter_meshsurface.cpp index b22085ebbfe..b26cd198b32 100644 --- a/src/tallies/filter_meshsurface.cpp +++ b/src/tallies/filter_meshsurface.cpp @@ -100,4 +100,16 @@ extern "C" int openmc_meshsurface_filter_set_mesh( return openmc_mesh_filter_set_mesh(index, index_mesh); } +extern "C" int openmc_meshsurface_filter_get_translation( + int32_t index, double translation[3]) +{ + return openmc_mesh_filter_get_translation(index, translation); +} + +extern "C" int openmc_meshsurface_filter_set_translation( + int32_t index, double translation[3]) +{ + return openmc_mesh_filter_set_translation(index, translation); +} + } // namespace openmc diff --git a/src/tallies/tally.cpp b/src/tallies/tally.cpp index 7fd444a58b4..df1ec5ea797 100644 --- a/src/tallies/tally.cpp +++ b/src/tallies/tally.cpp @@ -26,6 +26,7 @@ #include "openmc/tallies/filter_energy.h" #include "openmc/tallies/filter_legendre.h" #include "openmc/tallies/filter_mesh.h" +#include "openmc/tallies/filter_meshborn.h" #include "openmc/tallies/filter_meshsurface.h" #include "openmc/tallies/filter_particle.h" #include "openmc/tallies/filter_sph_harm.h" diff --git a/tests/regression_tests/filter_meshborn/__init__.py b/tests/regression_tests/filter_meshborn/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/regression_tests/filter_meshborn/inputs_true.dat b/tests/regression_tests/filter_meshborn/inputs_true.dat new file mode 100644 index 00000000000..6d0061fc416 --- /dev/null +++ b/tests/regression_tests/filter_meshborn/inputs_true.dat @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + fixed source + 2000 + 8 + + + 0.0 -10.0 -10.0 10.0 10.0 10.0 + + + false + + + + 2 2 1 + -10.0 -10.0 -10.0 + 10.0 10.0 10.0 + + + 1 + + + 1 + + + 1 2 + scatter + + + 1 + scatter + + + 2 + scatter + + + scatter + + + diff --git a/tests/regression_tests/filter_meshborn/results_true.dat b/tests/regression_tests/filter_meshborn/results_true.dat new file mode 100644 index 00000000000..62f2707ffc3 --- /dev/null +++ b/tests/regression_tests/filter_meshborn/results_true.dat @@ -0,0 +1,54 @@ +tally 1: +0.000000E+00 +0.000000E+00 +2.631246E+01 +8.845079E+01 +0.000000E+00 +0.000000E+00 +2.450265E+00 +9.462266E-01 +0.000000E+00 +0.000000E+00 +3.878380E+02 +1.881752E+04 +0.000000E+00 +0.000000E+00 +2.932956E+01 +1.091674E+02 +0.000000E+00 +0.000000E+00 +1.837753E+00 +5.195343E-01 +0.000000E+00 +0.000000E+00 +2.944919E+01 +1.095819E+02 +0.000000E+00 +0.000000E+00 +2.921731E+01 +1.097387E+02 +0.000000E+00 +0.000000E+00 +4.019442E+02 +2.021184E+04 +tally 2: +2.876273E+01 +1.060244E+02 +4.171676E+02 +2.176683E+04 +3.128695E+01 +1.238772E+02 +4.311615E+02 +2.325871E+04 +tally 3: +0.000000E+00 +0.000000E+00 +4.452055E+02 +2.478148E+04 +0.000000E+00 +0.000000E+00 +4.631732E+02 +2.683862E+04 +tally 4: +9.083787E+02 +1.031695E+05 diff --git a/tests/regression_tests/filter_meshborn/test.py b/tests/regression_tests/filter_meshborn/test.py new file mode 100644 index 00000000000..7987c119cd5 --- /dev/null +++ b/tests/regression_tests/filter_meshborn/test.py @@ -0,0 +1,131 @@ +"""Test the meshborn filter using a fixed source calculation on a H1 sphere. + +""" + +from numpy.testing import assert_allclose +import numpy as np +import openmc +import pytest + +from tests.testing_harness import PyAPITestHarness + + +RTOL = 1.0e-7 +ATOL = 0.0 + + +@pytest.fixture +def model(): + """Sphere of H1 with one hemisphere containing the source (x>0) and one + hemisphere with no source (x<0). + + """ + openmc.reset_auto_ids() + model = openmc.model.Model() + + # ============================================================================= + # Materials + # ============================================================================= + + h1 = openmc.Material() + h1.add_nuclide("H1", 1.0) + h1.set_density("g/cm3", 1.0) + + model.materials = openmc.Materials([h1]) + + # ============================================================================= + # Geometry + # ============================================================================= + + # Core geometry + radius = 10.0 + sphere = openmc.Sphere(r=radius, boundary_type="reflective") + core_region = -sphere + core = openmc.Cell(fill=h1, region=core_region) + + # Root universe + root = openmc.Universe(cells=[core]) + + # Register geometry + model.geometry = openmc.Geometry(root) + + # ============================================================================= + # Settings + # ============================================================================= + + model.settings = openmc.Settings() + model.settings.run_mode = 'fixed source' + model.settings.particles = 2000 + model.settings.batches = 8 + model.settings.photon_transport = False + + bounds = [0., -radius, -radius, radius, radius, radius] + distribution = openmc.stats.Box(bounds[:3], bounds[3:]) + model.settings.source = openmc.source.IndependentSource(space=distribution) + + # ============================================================================= + # Tallies + # ============================================================================= + + mesh = openmc.RegularMesh() + mesh.dimension = [2,2,1] + mesh.lower_left = [-radius, -radius, -radius] + mesh.upper_right = [radius, radius, radius] + + f_1 = openmc.MeshFilter(mesh) + f_2 = openmc.MeshBornFilter(mesh) + + t_1 = openmc.Tally(name="scatter") + t_1.filters = [f_1, f_2] + t_1.scores = ["scatter"] + + t_2 = openmc.Tally(name="scatter-mesh") + t_2.filters = [f_1] + t_2.scores = ["scatter"] + + t_3 = openmc.Tally(name="scatter-meshborn") + t_3.filters = [f_2] + t_3.scores = ["scatter"] + + t_4 = openmc.Tally(name="scatter-total") + t_4.scores = ["scatter"] + + model.tallies += [t_1, t_2, t_3, t_4] + + return model + + +class MeshBornFilterTest(PyAPITestHarness): + + def _compare_results(self): + """Additional unit tests on the tally results to check consistency.""" + with openmc.StatePoint(self.statepoint_name) as sp: + + t1 = sp.get_tally(name="scatter").mean.reshape(4, 4) + t2 = sp.get_tally(name="scatter-mesh").mean.reshape(4) + t3 = sp.get_tally(name="scatter-meshborn").mean.reshape(4) + t4 = sp.get_tally(name="scatter-total").mean.reshape(1) + + # Consistency between mesh+meshborn matrix tally and meshborn tally + for i in range(4): + assert_allclose(t1[:,i].sum(), t3[i], rtol=RTOL, atol=ATOL) + + # Consistency between mesh+meshborn matrix tally and mesh tally + for i in range(4): + assert_allclose(t1[i,:].sum(), t2[i], rtol=RTOL, atol=ATOL) + + # Mesh cells in x<0 do not contribute to meshborn + assert_allclose(t1[:,0].sum(), np.zeros(4), rtol=RTOL, atol=ATOL) + assert_allclose(t1[:,2].sum(), np.zeros(4), rtol=RTOL, atol=ATOL) + + # Consistency with total scattering + assert_allclose(t1.sum(), t4, rtol=RTOL, atol=ATOL) + assert_allclose(t2.sum(), t4, rtol=RTOL, atol=ATOL) + assert_allclose(t3.sum(), t4, rtol=RTOL, atol=ATOL) + + return super()._compare_results() + + +def test_filter_meshborn(model): + harness = MeshBornFilterTest("statepoint.8.h5", model) + harness.main() diff --git a/tests/unit_tests/test_filter_meshborn.py b/tests/unit_tests/test_filter_meshborn.py new file mode 100644 index 00000000000..0817edfa59b --- /dev/null +++ b/tests/unit_tests/test_filter_meshborn.py @@ -0,0 +1,144 @@ +"""Test the meshborn filter using a fixed source calculation on a H1 sphere. + +""" + +import numpy as np +from uncertainties import unumpy +import openmc +import pytest + + +@pytest.fixture +def model(): + """Sphere of H1 with one hemisphere containing the source (x>0) and one + hemisphere with no source (x<0). + + """ + openmc.reset_auto_ids() + model = openmc.model.Model() + + # ============================================================================= + # Materials + # ============================================================================= + + h1 = openmc.Material() + h1.add_nuclide("H1", 1.0) + h1.set_density("g/cm3", 1.0) + + model.materials = openmc.Materials([h1]) + + # ============================================================================= + # Geometry + # ============================================================================= + + # Core geometry + radius = 10.0 + sphere = openmc.Sphere(r=radius, boundary_type="reflective") + core_region = -sphere + core = openmc.Cell(fill=h1, region=core_region) + + # Root universe + root = openmc.Universe(cells=[core]) + + # Register geometry + model.geometry = openmc.Geometry(root) + + # ============================================================================= + # Settings + # ============================================================================= + + model.settings = openmc.Settings() + model.settings.run_mode = 'fixed source' + model.settings.particles = 2000 + model.settings.batches = 8 + model.settings.photon_transport = False + + bounds = [0., -radius, -radius, radius, radius, radius] + distribution = openmc.stats.Box(bounds[:3], bounds[3:]) + model.settings.source = openmc.source.IndependentSource(space=distribution) + + # ============================================================================= + # Tallies + # ============================================================================= + + mesh_1 = openmc.RegularMesh() + mesh_1.dimension = [2,2,1] + mesh_1.lower_left = [-radius, -radius, -radius] + mesh_1.upper_right = [radius, radius, radius] + + f_1 = openmc.MeshBornFilter(mesh_1) + + t_1 = openmc.Tally(name="scatter-collision") + t_1.filters = [f_1] + t_1.scores = ["scatter"] + t_1.estimator = "collision" + + mesh_2 = openmc.RegularMesh() + mesh_2.dimension = [2,2,1] + mesh_2.lower_left = [-radius, -radius, -radius] + mesh_2.upper_right = [radius, radius, radius] + + f_2 = openmc.MeshBornFilter(mesh_2) + + t_2 = openmc.Tally(name="scatter-tracklength") + t_2.filters = [f_2] + t_2.scores = ["scatter"] + t_2.estimator = "tracklength" + + model.tallies += [t_1, t_2] + + return model + + +def test_estimator_consistency(model, run_in_tmpdir): + """Test that resuts obtained from a tracklength estimator are + consistent with results obtained from a collision estimator. + + """ + # Run OpenMC + sp_filename = model.run() + + # Get radial flux distribution + with openmc.StatePoint(sp_filename) as sp: + scatter_collision = sp.get_tally(name="scatter-collision").mean.ravel() + scatter_collision_std_dev = sp.get_tally(name="scatter-collision").std_dev.ravel() + scatter_tracklength = sp.get_tally(name="scatter-tracklength").mean.ravel() + scatter_tracklength_std_dev = sp.get_tally(name="scatter-tracklength").std_dev.ravel() + + collision = unumpy.uarray(scatter_collision, scatter_collision_std_dev) + tracklength = unumpy.uarray(scatter_tracklength, scatter_tracklength_std_dev) + delta = abs(collision - tracklength) + + diff = unumpy.nominal_values(delta) + std_dev = unumpy.std_devs(delta) + assert np.all(diff <= 3 * std_dev) + + +def test_xml_serialization(): + """Test xml serialization of the meshborn filter.""" + openmc.reset_auto_ids() + + mesh = openmc.RegularMesh() + mesh.dimension = [1, 1, 1] + mesh.lower_left = [0.0, 0.0, 0.0] + mesh.upper_right = [1.0, 1.0, 1.0] + + filter = openmc.MeshBornFilter(mesh) + filter.translation = [2.0 ,2.0 ,2.0] + assert filter.mesh.id == 1 + assert filter.mesh.dimension == (1, 1 ,1) + assert filter.mesh.lower_left == [0.0, 0.0, 0.0] + assert filter.mesh.upper_right == [1.0 ,1.0 ,1.0] + + repr(filter) + + elem = filter.to_xml_element() + assert elem.tag == 'filter' + assert elem.attrib['type'] == 'meshborn' + assert elem[0].text == "1" + assert elem.get("translation") == "2.0 2.0 2.0" + + meshes = {1: mesh} + new_filter = openmc.Filter.from_xml_element(elem, meshes=meshes) + assert new_filter.bins == filter.bins + np.testing.assert_equal(new_filter.translation, [2.0, 2.0, 2.0]) diff --git a/tests/unit_tests/test_tallies.py b/tests/unit_tests/test_tallies.py index 14319a0a29d..54444331257 100644 --- a/tests/unit_tests/test_tallies.py +++ b/tests/unit_tests/test_tallies.py @@ -10,8 +10,9 @@ def test_xml_roundtrip(run_in_tmpdir): mesh.upper_right = (10., 10., 10.,) mesh.dimension = (5, 5, 5) mesh_filter = openmc.MeshFilter(mesh) + meshborn_filter = openmc.MeshBornFilter(mesh) tally = openmc.Tally() - tally.filters = [mesh_filter] + tally.filters = [mesh_filter, meshborn_filter] tally.nuclides = ['U235', 'I135', 'Li6'] tally.scores = ['total', 'fission', 'heating'] tally.derivative = openmc.TallyDerivative( @@ -27,9 +28,11 @@ def test_xml_roundtrip(run_in_tmpdir): assert len(new_tallies) == 1 new_tally = new_tallies[0] assert new_tally.id == tally.id - assert len(new_tally.filters) == 1 + assert len(new_tally.filters) == 2 assert isinstance(new_tally.filters[0], openmc.MeshFilter) assert np.allclose(new_tally.filters[0].mesh.lower_left, mesh.lower_left) + assert isinstance(new_tally.filters[1], openmc.MeshBornFilter) + assert np.allclose(new_tally.filters[1].mesh.lower_left, mesh.lower_left) assert new_tally.nuclides == tally.nuclides assert new_tally.scores == tally.scores assert new_tally.derivative.variable == tally.derivative.variable From c715448c73e5dfca6e284e04ad9100d8d4fcf9bd Mon Sep 17 00:00:00 2001 From: Joffrey Dorville Date: Wed, 27 Mar 2024 11:32:33 -0500 Subject: [PATCH 2/3] Formatting correction --- include/openmc/tallies/filter_meshborn.h | 1 - src/particle.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/openmc/tallies/filter_meshborn.h b/include/openmc/tallies/filter_meshborn.h index dd48135baab..8ab7a8c766b 100644 --- a/include/openmc/tallies/filter_meshborn.h +++ b/include/openmc/tallies/filter_meshborn.h @@ -20,7 +20,6 @@ class MeshBornFilter : public MeshFilter { FilterMatch& match) const override; std::string text_label(int bin) const override; - }; } // namespace openmc diff --git a/src/particle.cpp b/src/particle.cpp index fc92f019531..c2e340201bb 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -121,7 +121,7 @@ void Particle::from_source(const SourceSite* src) wgt_last() = src->wgt; r() = src->r; u() = src->u; - r_born() = src-> r; + r_born() = src->r; r_last_current() = src->r; r_last() = src->r; u_last() = src->u; From eb2470fa7bec000b605f67fa929a7963bedbdb7e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 4 Apr 2024 22:14:11 +0200 Subject: [PATCH 3/3] Small style changes --- openmc/lib/filter.py | 15 ++-- src/tallies/filter_meshborn.cpp | 7 +- .../filter_meshborn/inputs_true.dat | 1 - .../regression_tests/filter_meshborn/test.py | 56 +++++---------- tests/unit_tests/test_filter_meshborn.py | 72 ++++++------------- 5 files changed, 48 insertions(+), 103 deletions(-) diff --git a/openmc/lib/filter.py b/openmc/lib/filter.py index 6a02eee1e0a..340c2fa3448 100644 --- a/openmc/lib/filter.py +++ b/openmc/lib/filter.py @@ -368,8 +368,9 @@ class MaterialFromFilter(Filter): class MeshFilter(Filter): """Mesh filter stored internally. - This class exposes a Mesh filter that is stored internally in the OpenMC library. - To obtain a view of a Mesh filter with a given ID, use the :data:`openmc.lib.filters` mapping. + This class exposes a Mesh filter that is stored internally in the OpenMC + library. To obtain a view of a Mesh filter with a given ID, use the + :data:`openmc.lib.filters` mapping. Parameters ---------- @@ -424,8 +425,9 @@ def translation(self, translation): class MeshBornFilter(Filter): """MeshBorn filter stored internally. - This class exposes a MeshBorn filter that is stored internally in the OpenMC library. - To obtain a view of a MeshBorn filter with a given ID, use the :data:`openmc.lib.filters` mapping. + This class exposes a MeshBorn filter that is stored internally in the OpenMC + library. To obtain a view of a MeshBorn filter with a given ID, use the + :data:`openmc.lib.filters` mapping. Parameters ---------- @@ -480,8 +482,9 @@ def translation(self, translation): class MeshSurfaceFilter(Filter): """MeshSurface filter stored internally. - This class exposes a MeshSurface filter that is stored internally in the OpenMC library. - To obtain a view of a MeshSurface filter with a given ID, use the :data:`openmc.lib.filters` mapping. + This class exposes a MeshSurface filter that is stored internally in the + OpenMC library. To obtain a view of a MeshSurface filter with a given ID, + use the :data:`openmc.lib.filters` mapping. Parameters ---------- diff --git a/src/tallies/filter_meshborn.cpp b/src/tallies/filter_meshborn.cpp index 3109788ca79..c95dc3dc78a 100644 --- a/src/tallies/filter_meshborn.cpp +++ b/src/tallies/filter_meshborn.cpp @@ -1,8 +1,5 @@ #include "openmc/tallies/filter_meshborn.h" -#include -#include - #include "openmc/capi.h" #include "openmc/constants.h" #include "openmc/error.h" @@ -30,9 +27,7 @@ void MeshBornFilter::get_all_bins( std::string MeshBornFilter::text_label(int bin) const { auto& mesh = *model::meshes.at(mesh_); - std::string label = mesh.bin_label(bin); - label += " (" + type_str() + ")"; - return label; + return mesh.bin_label(bin) + " (born)"; } //============================================================================== diff --git a/tests/regression_tests/filter_meshborn/inputs_true.dat b/tests/regression_tests/filter_meshborn/inputs_true.dat index 6d0061fc416..3ba38d56e60 100644 --- a/tests/regression_tests/filter_meshborn/inputs_true.dat +++ b/tests/regression_tests/filter_meshborn/inputs_true.dat @@ -19,7 +19,6 @@ 0.0 -10.0 -10.0 10.0 10.0 10.0 - false diff --git a/tests/regression_tests/filter_meshborn/test.py b/tests/regression_tests/filter_meshborn/test.py index 7987c119cd5..ff4adbc9f04 100644 --- a/tests/regression_tests/filter_meshborn/test.py +++ b/tests/regression_tests/filter_meshborn/test.py @@ -21,56 +21,32 @@ def model(): """ openmc.reset_auto_ids() - model = openmc.model.Model() + model = openmc.Model() - # ============================================================================= # Materials - # ============================================================================= - h1 = openmc.Material() h1.add_nuclide("H1", 1.0) h1.set_density("g/cm3", 1.0) - model.materials = openmc.Materials([h1]) - # ============================================================================= - # Geometry - # ============================================================================= - # Core geometry - radius = 10.0 - sphere = openmc.Sphere(r=radius, boundary_type="reflective") - core_region = -sphere - core = openmc.Cell(fill=h1, region=core_region) - - # Root universe - root = openmc.Universe(cells=[core]) + r = 10.0 + sphere = openmc.Sphere(r=r, boundary_type="reflective") + core = openmc.Cell(fill=h1, region=-sphere) + model.geometry = openmc.Geometry([core]) - # Register geometry - model.geometry = openmc.Geometry(root) - - # ============================================================================= # Settings - # ============================================================================= - - model.settings = openmc.Settings() model.settings.run_mode = 'fixed source' model.settings.particles = 2000 model.settings.batches = 8 - model.settings.photon_transport = False + distribution = openmc.stats.Box((0., -r, -r), (r, r, r)) + model.settings.source = openmc.IndependentSource(space=distribution) - bounds = [0., -radius, -radius, radius, radius, radius] - distribution = openmc.stats.Box(bounds[:3], bounds[3:]) - model.settings.source = openmc.source.IndependentSource(space=distribution) - - # ============================================================================= # Tallies - # ============================================================================= - mesh = openmc.RegularMesh() - mesh.dimension = [2,2,1] - mesh.lower_left = [-radius, -radius, -radius] - mesh.upper_right = [radius, radius, radius] + mesh.dimension = (2, 2, 1) + mesh.lower_left = (-r, -r, -r) + mesh.upper_right = (r, r, r) f_1 = openmc.MeshFilter(mesh) f_2 = openmc.MeshBornFilter(mesh) @@ -90,7 +66,7 @@ def model(): t_4 = openmc.Tally(name="scatter-total") t_4.scores = ["scatter"] - model.tallies += [t_1, t_2, t_3, t_4] + model.tallies = [t_1, t_2, t_3, t_4] return model @@ -108,22 +84,22 @@ def _compare_results(self): # Consistency between mesh+meshborn matrix tally and meshborn tally for i in range(4): - assert_allclose(t1[:,i].sum(), t3[i], rtol=RTOL, atol=ATOL) + assert_allclose(t1[:, i].sum(), t3[i], rtol=RTOL, atol=ATOL) # Consistency between mesh+meshborn matrix tally and mesh tally for i in range(4): - assert_allclose(t1[i,:].sum(), t2[i], rtol=RTOL, atol=ATOL) + assert_allclose(t1[i, :].sum(), t2[i], rtol=RTOL, atol=ATOL) # Mesh cells in x<0 do not contribute to meshborn - assert_allclose(t1[:,0].sum(), np.zeros(4), rtol=RTOL, atol=ATOL) - assert_allclose(t1[:,2].sum(), np.zeros(4), rtol=RTOL, atol=ATOL) + assert_allclose(t1[:, 0].sum(), np.zeros(4), rtol=RTOL, atol=ATOL) + assert_allclose(t1[:, 2].sum(), np.zeros(4), rtol=RTOL, atol=ATOL) # Consistency with total scattering assert_allclose(t1.sum(), t4, rtol=RTOL, atol=ATOL) assert_allclose(t2.sum(), t4, rtol=RTOL, atol=ATOL) assert_allclose(t3.sum(), t4, rtol=RTOL, atol=ATOL) - return super()._compare_results() + super()._compare_results() def test_filter_meshborn(model): diff --git a/tests/unit_tests/test_filter_meshborn.py b/tests/unit_tests/test_filter_meshborn.py index 0817edfa59b..62fa1174e75 100644 --- a/tests/unit_tests/test_filter_meshborn.py +++ b/tests/unit_tests/test_filter_meshborn.py @@ -15,77 +15,49 @@ def model(): """ openmc.reset_auto_ids() - model = openmc.model.Model() + model = openmc.Model() - # ============================================================================= # Materials - # ============================================================================= - h1 = openmc.Material() h1.add_nuclide("H1", 1.0) h1.set_density("g/cm3", 1.0) - model.materials = openmc.Materials([h1]) - # ============================================================================= - # Geometry - # ============================================================================= - # Core geometry - radius = 10.0 - sphere = openmc.Sphere(r=radius, boundary_type="reflective") - core_region = -sphere - core = openmc.Cell(fill=h1, region=core_region) - - # Root universe - root = openmc.Universe(cells=[core]) + r = 10.0 + sphere = openmc.Sphere(r=r, boundary_type="reflective") + core = openmc.Cell(fill=h1, region=-sphere) + model.geometry = openmc.Geometry([core]) - # Register geometry - model.geometry = openmc.Geometry(root) - - # ============================================================================= # Settings - # ============================================================================= - - model.settings = openmc.Settings() model.settings.run_mode = 'fixed source' model.settings.particles = 2000 model.settings.batches = 8 - model.settings.photon_transport = False - bounds = [0., -radius, -radius, radius, radius, radius] - distribution = openmc.stats.Box(bounds[:3], bounds[3:]) - model.settings.source = openmc.source.IndependentSource(space=distribution) + distribution = openmc.stats.Box((0., -r, -r), (r, r, r)) + model.settings.source = openmc.IndependentSource(space=distribution) # ============================================================================= # Tallies # ============================================================================= - mesh_1 = openmc.RegularMesh() - mesh_1.dimension = [2,2,1] - mesh_1.lower_left = [-radius, -radius, -radius] - mesh_1.upper_right = [radius, radius, radius] - - f_1 = openmc.MeshBornFilter(mesh_1) + mesh = openmc.RegularMesh() + mesh.dimension = (2, 2, 1) + mesh.lower_left = (-r, -r, -r) + mesh.upper_right = (r, r, r) + f = openmc.MeshBornFilter(mesh) t_1 = openmc.Tally(name="scatter-collision") - t_1.filters = [f_1] + t_1.filters = [f] t_1.scores = ["scatter"] t_1.estimator = "collision" - mesh_2 = openmc.RegularMesh() - mesh_2.dimension = [2,2,1] - mesh_2.lower_left = [-radius, -radius, -radius] - mesh_2.upper_right = [radius, radius, radius] - - f_2 = openmc.MeshBornFilter(mesh_2) - t_2 = openmc.Tally(name="scatter-tracklength") - t_2.filters = [f_2] + t_2.filters = [f] t_2.scores = ["scatter"] t_2.estimator = "tracklength" - model.tallies += [t_1, t_2] + model.tallies = [t_1, t_2] return model @@ -119,16 +91,16 @@ def test_xml_serialization(): openmc.reset_auto_ids() mesh = openmc.RegularMesh() - mesh.dimension = [1, 1, 1] - mesh.lower_left = [0.0, 0.0, 0.0] - mesh.upper_right = [1.0, 1.0, 1.0] + mesh.dimension = (1, 1, 1) + mesh.lower_left = (0.0, 0.0, 0.0) + mesh.upper_right = (1.0, 1.0, 1.0) filter = openmc.MeshBornFilter(mesh) - filter.translation = [2.0 ,2.0 ,2.0] + filter.translation = (2.0, 2.0, 2.0) assert filter.mesh.id == 1 - assert filter.mesh.dimension == (1, 1 ,1) - assert filter.mesh.lower_left == [0.0, 0.0, 0.0] - assert filter.mesh.upper_right == [1.0 ,1.0 ,1.0] + assert filter.mesh.dimension == (1, 1, 1) + assert filter.mesh.lower_left == (0.0, 0.0, 0.0) + assert filter.mesh.upper_right == (1.0, 1.0, 1.0) repr(filter)