#include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_all.hpp> #include <MeshDataBaseForTests.hpp> #include <mesh/DualMeshManager.hpp> #include <mesh/Connectivity.hpp> #include <mesh/Mesh.hpp> // clazy:excludeall=non-pod-global-static TEST_CASE("DualMeshManager", "[mesh]") { SECTION("same 1D dual connectivities ") { using ConnectivityType = Connectivity<1>; using MeshType = Mesh<ConnectivityType>; std::shared_ptr<const MeshType> mesh = MeshDataBaseForTests::get().unordered1DMesh(); std::shared_ptr p_diamond_dual_mesh = DualMeshManager::instance().getDiamondDualMesh(*mesh); std::shared_ptr p_median_dual_mesh = DualMeshManager::instance().getMedianDualMesh(*mesh); std::shared_ptr p_dual1d_mesh = DualMeshManager::instance().getDual1DMesh(*mesh); // In 1d all these dual meshes are the same REQUIRE(p_dual1d_mesh.get() == p_diamond_dual_mesh.get()); REQUIRE(p_dual1d_mesh.get() == p_median_dual_mesh.get()); } SECTION("2D") { using ConnectivityType = Connectivity<2>; using MeshType = Mesh<ConnectivityType>; std::shared_ptr<const MeshType> mesh = MeshDataBaseForTests::get().hybrid2DMesh(); SECTION("diamond dual mesh access") { std::shared_ptr p_diamond_dual_mesh = DualMeshManager::instance().getDiamondDualMesh(*mesh); const auto ref_counter = p_diamond_dual_mesh.use_count(); { std::shared_ptr p_diamond_dual_mesh2 = DualMeshManager::instance().getDiamondDualMesh(*mesh); REQUIRE(p_diamond_dual_mesh == p_diamond_dual_mesh2); REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter + 1); } REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter); DualMeshManager::instance().deleteMesh(mesh.get()); REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter - 1); // Can delete mesh from the list again. This means that no // dual mesh associated with it is managed. REQUIRE_NOTHROW(DualMeshManager::instance().deleteMesh(mesh.get())); REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter - 1); // A new dual mesh is built std::shared_ptr p_diamond_dual_mesh_rebuilt = DualMeshManager::instance().getDiamondDualMesh(*mesh); REQUIRE(p_diamond_dual_mesh != p_diamond_dual_mesh_rebuilt); REQUIRE(p_diamond_dual_mesh.get() != p_diamond_dual_mesh_rebuilt.get()); // Exactly two references to the dual mesh. One here and // one in the manager. REQUIRE(p_diamond_dual_mesh_rebuilt.use_count() == 2); } SECTION("median dual mesh access") { std::shared_ptr p_median_dual_mesh = DualMeshManager::instance().getMedianDualMesh(*mesh); const auto ref_counter = p_median_dual_mesh.use_count(); { std::shared_ptr p_median_dual_mesh2 = DualMeshManager::instance().getMedianDualMesh(*mesh); REQUIRE(p_median_dual_mesh == p_median_dual_mesh2); REQUIRE(p_median_dual_mesh.use_count() == ref_counter + 1); } REQUIRE(p_median_dual_mesh.use_count() == ref_counter); DualMeshManager::instance().deleteMesh(mesh.get()); REQUIRE(p_median_dual_mesh.use_count() == ref_counter - 1); // Can delete mesh from the list again. This means that no // dual mesh associated with it is managed. REQUIRE_NOTHROW(DualMeshManager::instance().deleteMesh(mesh.get())); REQUIRE(p_median_dual_mesh.use_count() == ref_counter - 1); // A new dual mesh is built std::shared_ptr p_median_dual_mesh_rebuilt = DualMeshManager::instance().getMedianDualMesh(*mesh); REQUIRE(p_median_dual_mesh != p_median_dual_mesh_rebuilt); REQUIRE(p_median_dual_mesh.get() != p_median_dual_mesh_rebuilt.get()); // Exactly two references to the dual mesh. One here and // one in the manager. REQUIRE(p_median_dual_mesh_rebuilt.use_count() == 2); } SECTION("check multiple dual mesh using/freeing") { std::shared_ptr p_median_dual_mesh = DualMeshManager::instance().getMedianDualMesh(*mesh); std::shared_ptr p_diamond_dual_mesh = DualMeshManager::instance().getDiamondDualMesh(*mesh); const auto median_ref_counter = p_median_dual_mesh.use_count(); const auto diamond_ref_counter = p_diamond_dual_mesh.use_count(); REQUIRE(p_median_dual_mesh != p_diamond_dual_mesh); REQUIRE_NOTHROW(DualMeshManager::instance().deleteMesh(mesh.get())); REQUIRE(p_median_dual_mesh.use_count() == median_ref_counter - 1); REQUIRE(p_diamond_dual_mesh.use_count() == diamond_ref_counter - 1); } } SECTION("3D") { using ConnectivityType = Connectivity<3>; using MeshType = Mesh<ConnectivityType>; std::shared_ptr<const MeshType> mesh = MeshDataBaseForTests::get().hybrid3DMesh(); SECTION("diamond dual mesh access") { std::shared_ptr p_diamond_dual_mesh = DualMeshManager::instance().getDiamondDualMesh(*mesh); const auto ref_counter = p_diamond_dual_mesh.use_count(); { std::shared_ptr p_diamond_dual_mesh2 = DualMeshManager::instance().getDiamondDualMesh(*mesh); REQUIRE(p_diamond_dual_mesh == p_diamond_dual_mesh2); REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter + 1); } REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter); DualMeshManager::instance().deleteMesh(mesh.get()); REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter - 1); // Can delete mesh from the list again. This means that no // dual mesh associated with it is managed. REQUIRE_NOTHROW(DualMeshManager::instance().deleteMesh(mesh.get())); REQUIRE(p_diamond_dual_mesh.use_count() == ref_counter - 1); // A new dual mesh is built std::shared_ptr p_diamond_dual_mesh_rebuilt = DualMeshManager::instance().getDiamondDualMesh(*mesh); REQUIRE(p_diamond_dual_mesh != p_diamond_dual_mesh_rebuilt); REQUIRE(p_diamond_dual_mesh.get() != p_diamond_dual_mesh_rebuilt.get()); // Exactly two references to the dual mesh. One here and // one in the manager. REQUIRE(p_diamond_dual_mesh_rebuilt.use_count() == 2); } } }