diff --git a/src/mesh/MeshFaceBoundary.cpp b/src/mesh/MeshFaceBoundary.cpp index 3690c5c0c614a844060fa4c266e75fdcea42e377..751bcf962ca9ce2b8f7e7e5eab240a1c4768bcfb 100644 --- a/src/mesh/MeshFaceBoundary.cpp +++ b/src/mesh/MeshFaceBoundary.cpp @@ -26,7 +26,18 @@ getMeshFaceBoundary(const Mesh<Connectivity<Dimension>>& mesh, const IBoundaryDe } std::ostringstream ost; - ost << "cannot find surface with name " << rang::fgB::red << boundary_descriptor << rang::style::reset; + ost << "cannot find surface with name " << rang::fgB::red << boundary_descriptor << rang::style::reset << '\n'; + ost << "The mesh contains " << mesh.connectivity().template numberOfRefItemList<ItemType::face>() + << " face boundaries: "; + for (size_t i_ref_face_list = 0; i_ref_face_list < mesh.connectivity().template numberOfRefItemList<ItemType::face>(); + ++i_ref_face_list) { + const auto& ref_face_list = mesh.connectivity().template refItemList<ItemType::face>(i_ref_face_list); + const RefId& ref = ref_face_list.refId(); + if (i_ref_face_list > 0) { + ost << ", "; + } + ost << rang::fgB::yellow << ref << rang::style::reset; + } throw NormalError(ost.str()); } diff --git a/src/mesh/MeshFaceBoundary.hpp b/src/mesh/MeshFaceBoundary.hpp index a45108aa5893c798230f41e14a8cacb071c60c0b..7493e9cd46e4d434902e65116024bbd7b82f5069 100644 --- a/src/mesh/MeshFaceBoundary.hpp +++ b/src/mesh/MeshFaceBoundary.hpp @@ -39,8 +39,8 @@ class [[nodiscard]] MeshFaceBoundary // clazy:exclude=copyable-polymorphic MeshFaceBoundary(const Mesh<Connectivity<Dimension>>& mesh, const RefFaceList& ref_face_list); public: - MeshFaceBoundary(const MeshFaceBoundary&) = default; - MeshFaceBoundary(MeshFaceBoundary &&) = default; + MeshFaceBoundary(const MeshFaceBoundary&) = default; // LCOV_EXCL_LINE + MeshFaceBoundary(MeshFaceBoundary &&) = default; // LCOV_EXCL_LINE MeshFaceBoundary() = default; virtual ~MeshFaceBoundary() = default; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 52a41bcb69fc8181fce73b92059b49cf1cccf314..ede705d518895f33e40790818a5ea2ccb7099892 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -175,6 +175,7 @@ add_executable (mpi_unit_tests test_ItemArrayUtils.cpp test_ItemValue.cpp test_ItemValueUtils.cpp + test_MeshFaceBoundary.cpp test_Messenger.cpp test_OFStream.cpp test_Partitioner.cpp diff --git a/tests/test_MeshFaceBoundary.cpp b/tests/test_MeshFaceBoundary.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b390e17f6b56001cb9abd119eeb8486a97b6dff --- /dev/null +++ b/tests/test_MeshFaceBoundary.cpp @@ -0,0 +1,220 @@ +#include <catch2/catch_test_macros.hpp> +#include <catch2/matchers/catch_matchers_all.hpp> + +#include <MeshDataBaseForTests.hpp> + +#include <mesh/Connectivity.hpp> +#include <mesh/Mesh.hpp> +#include <mesh/MeshFaceBoundary.hpp> +#include <mesh/NamedBoundaryDescriptor.hpp> +#include <mesh/NumberedBoundaryDescriptor.hpp> + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("MeshFaceBoundary", "[mesh]") +{ + auto is_same = [](const auto& a, const auto& b) -> bool { + if (a.size() > 0 and b.size() > 0) { + return (a[0] == b[0]); + } else { + return (a.size() == b.size()); + } + }; + + SECTION("1D") + { + static constexpr size_t Dimension = 1; + + using ConnectivityType = Connectivity<Dimension>; + using MeshType = Mesh<ConnectivityType>; + + SECTION("cartesian 1d") + { + std::shared_ptr p_mesh = MeshDataBaseForTests::get().cartesian1DMesh(); + const MeshType& mesh = *p_mesh; + + const ConnectivityType& connectivity = mesh.connectivity(); + + for (size_t i = 0; i < connectivity.numberOfRefItemList<ItemType::face>(); ++i) { + const auto& ref_face_list = connectivity.refItemList<ItemType::face>(i); + const RefId ref_id = ref_face_list.refId(); + + { + NumberedBoundaryDescriptor numbered_boundary_descriptor(ref_id.tagNumber()); + const auto& face_boundary = getMeshFaceBoundary(mesh, numbered_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + + { + NamedBoundaryDescriptor named_boundary_descriptor(ref_id.tagName()); + const auto& face_boundary = getMeshFaceBoundary(mesh, named_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + } + } + + SECTION("unordered 1d") + { + std::shared_ptr p_mesh = MeshDataBaseForTests::get().unordered1DMesh(); + const MeshType& mesh = *p_mesh; + + const ConnectivityType& connectivity = mesh.connectivity(); + + for (size_t i = 0; i < connectivity.numberOfRefItemList<ItemType::face>(); ++i) { + const auto& ref_face_list = connectivity.refItemList<ItemType::face>(i); + const RefId ref_id = ref_face_list.refId(); + + { + NumberedBoundaryDescriptor numbered_boundary_descriptor(ref_id.tagNumber()); + const auto& face_boundary = getMeshFaceBoundary(mesh, numbered_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + + { + NamedBoundaryDescriptor named_boundary_descriptor(ref_id.tagName()); + const auto& face_boundary = getMeshFaceBoundary(mesh, named_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + } + } + } + + SECTION("2D") + { + static constexpr size_t Dimension = 2; + + using ConnectivityType = Connectivity<Dimension>; + using MeshType = Mesh<ConnectivityType>; + + SECTION("cartesian 2d") + { + std::shared_ptr p_mesh = MeshDataBaseForTests::get().cartesian2DMesh(); + const MeshType& mesh = *p_mesh; + + const ConnectivityType& connectivity = mesh.connectivity(); + + for (size_t i = 0; i < connectivity.numberOfRefItemList<ItemType::face>(); ++i) { + const auto& ref_face_list = connectivity.refItemList<ItemType::face>(i); + const RefId ref_id = ref_face_list.refId(); + + { + NumberedBoundaryDescriptor numbered_boundary_descriptor(ref_id.tagNumber()); + const auto& face_boundary = getMeshFaceBoundary(mesh, numbered_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + + { + NamedBoundaryDescriptor named_boundary_descriptor(ref_id.tagName()); + const auto& face_boundary = getMeshFaceBoundary(mesh, named_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + } + } + + SECTION("hybrid 2d") + { + std::shared_ptr p_mesh = MeshDataBaseForTests::get().hybrid2DMesh(); + const MeshType& mesh = *p_mesh; + + const ConnectivityType& connectivity = mesh.connectivity(); + + for (size_t i = 0; i < connectivity.numberOfRefItemList<ItemType::face>(); ++i) { + const auto& ref_face_list = connectivity.refItemList<ItemType::face>(i); + const RefId ref_id = ref_face_list.refId(); + + { + NumberedBoundaryDescriptor numbered_boundary_descriptor(ref_id.tagNumber()); + const auto& face_boundary = getMeshFaceBoundary(mesh, numbered_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + + { + NamedBoundaryDescriptor named_boundary_descriptor(ref_id.tagName()); + const auto& face_boundary = getMeshFaceBoundary(mesh, named_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + } + } + } + + SECTION("3D") + { + static constexpr size_t Dimension = 3; + + using ConnectivityType = Connectivity<Dimension>; + using MeshType = Mesh<ConnectivityType>; + + SECTION("cartesian 3d") + { + std::shared_ptr p_mesh = MeshDataBaseForTests::get().cartesian3DMesh(); + const MeshType& mesh = *p_mesh; + + const ConnectivityType& connectivity = mesh.connectivity(); + + for (size_t i = 0; i < connectivity.numberOfRefItemList<ItemType::face>(); ++i) { + const auto& ref_face_list = connectivity.refItemList<ItemType::face>(i); + const RefId ref_id = ref_face_list.refId(); + + { + NumberedBoundaryDescriptor numbered_boundary_descriptor(ref_id.tagNumber()); + // force copy for tests + auto face_boundary = getMeshFaceBoundary(mesh, numbered_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + + { + NamedBoundaryDescriptor named_boundary_descriptor(ref_id.tagName()); + const auto& face_boundary = getMeshFaceBoundary(mesh, named_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + } + } + + SECTION("hybrid 3d") + { + std::shared_ptr p_mesh = MeshDataBaseForTests::get().hybrid3DMesh(); + const MeshType& mesh = *p_mesh; + + const ConnectivityType& connectivity = mesh.connectivity(); + + for (size_t i = 0; i < connectivity.numberOfRefItemList<ItemType::face>(); ++i) { + const auto& ref_face_list = connectivity.refItemList<ItemType::face>(i); + const RefId ref_id = ref_face_list.refId(); + + { + NumberedBoundaryDescriptor numbered_boundary_descriptor(ref_id.tagNumber()); + // force copy for tests + auto face_boundary = getMeshFaceBoundary(mesh, numbered_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + + { + NamedBoundaryDescriptor named_boundary_descriptor(ref_id.tagName()); + const auto& face_boundary = getMeshFaceBoundary(mesh, named_boundary_descriptor); + REQUIRE(is_same(face_boundary.faceList(), ref_face_list.list())); + } + } + } + } + + SECTION("errors") + { + SECTION("cannot find boundary") + { + static constexpr size_t Dimension = 3; + + using ConnectivityType = Connectivity<Dimension>; + using MeshType = Mesh<ConnectivityType>; + + std::shared_ptr p_mesh = MeshDataBaseForTests::get().hybrid3DMesh(); + const MeshType& mesh = *p_mesh; + + NamedBoundaryDescriptor named_boundary_descriptor("invalid_boundary"); + + REQUIRE_THROWS_WITH(getMeshFaceBoundary(mesh, named_boundary_descriptor), + "error: cannot find surface with name \"invalid_boundary\"\nThe mesh contains 8 face " + "boundaries: XMIN(22), XMAX(23), ZMAX(24), ZMIN(25), YMAX(26), YMIN(27), INTERFACE1(55), " + "INTERFACE2(56)"); + } + } +}