From eebc9d8d281ba3c3f40b32b35c3cc441346f2b26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Tue, 21 Dec 2021 17:17:03 +0100
Subject: [PATCH] Add tests for ConnectivityToMedianDualConnectivityDataMapper

---
 ...vityToMedianDualConnectivityDataMapper.hpp |  36 +++-
 tests/CMakeLists.txt                          |   1 +
 ...vityToMedianDualConnectivityDataMapper.cpp | 191 ++++++++++++++++++
 3 files changed, 217 insertions(+), 11 deletions(-)
 create mode 100644 tests/test_ConnectivityToMedianDualConnectivityDataMapper.cpp

diff --git a/src/mesh/ConnectivityToMedianDualConnectivityDataMapper.hpp b/src/mesh/ConnectivityToMedianDualConnectivityDataMapper.hpp
index ae9288be2..822e813e1 100644
--- a/src/mesh/ConnectivityToMedianDualConnectivityDataMapper.hpp
+++ b/src/mesh/ConnectivityToMedianDualConnectivityDataMapper.hpp
@@ -33,9 +33,14 @@ class ConnectivityToMedianDualConnectivityDataMapper : public IConnectivityToDua
     static_assert(std::is_same_v<std::remove_const_t<OriginDataType2>, DestinationDataType>, "incompatible types");
     static_assert(std::is_same_v<std::remove_const_t<OriginDataType3>, DestinationDataType>, "incompatible types");
 
-    Assert(m_primal_connectivity == primal_cell_value.connectivity_ptr().get());
-    Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get());
-    Assert(m_dual_connectivity == dual_node_value.connectivity_ptr().get());
+    Assert(m_primal_connectivity == primal_cell_value.connectivity_ptr().get(),
+           "unexpected connectivity for primal CellValue");
+    Assert(m_primal_connectivity == primal_face_value.connectivity_ptr().get(),
+           "unexpected connectivity for primal FaceValue");
+    Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get(),
+           "unexpected connectivity for primal NodeValue");
+    Assert(m_dual_connectivity == dual_node_value.connectivity_ptr().get(),
+           "unexpected connectivity for dual NodeValue");
 
     parallel_for(
       m_primal_boundary_node_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) {
@@ -66,7 +71,7 @@ class ConnectivityToMedianDualConnectivityDataMapper : public IConnectivityToDua
   void
   fromDualNode(const NodeValue<OriginDataType>& dual_node_value,
                const NodeValue<DestinationDataType1>& primal_node_value,
-               const NodeValue<DestinationDataType2>& primal_face_value,
+               const FaceValue<DestinationDataType2>& primal_face_value,
                const CellValue<DestinationDataType3>& primal_cell_value) const
   {
     static_assert(not std::is_const_v<DestinationDataType1>, "destination data type must not be constant");
@@ -76,9 +81,14 @@ class ConnectivityToMedianDualConnectivityDataMapper : public IConnectivityToDua
     static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType2>, "incompatible types");
     static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType3>, "incompatible types");
 
-    Assert(m_primal_connectivity == primal_cell_value.connectivity_ptr().get());
-    Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get());
-    Assert(m_dual_connectivity == dual_node_value.connectivity_ptr().get());
+    Assert(m_primal_connectivity == primal_cell_value.connectivity_ptr().get(),
+           "unexpected connectivity for primal CellValue");
+    Assert(m_primal_connectivity == primal_face_value.connectivity_ptr().get(),
+           "unexpected connectivity for primal FaceValue");
+    Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get(),
+           "unexpected connectivity for primal NodeValue");
+    Assert(m_dual_connectivity == dual_node_value.connectivity_ptr().get(),
+           "unexpected connectivity for dual NodeValue");
 
     parallel_for(
       m_primal_boundary_node_to_dual_node_map.size(), PUGS_LAMBDA(size_t i) {
@@ -110,8 +120,10 @@ class ConnectivityToMedianDualConnectivityDataMapper : public IConnectivityToDua
     static_assert(not std::is_const_v<DestinationDataType>, "destination data type must not be constant");
     static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType>, "incompatible types");
 
-    Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get());
-    Assert(m_dual_connectivity == dual_cell_value.connectivity_ptr().get());
+    Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get(),
+           "unexpected connectivity for primal NodeValue");
+    Assert(m_dual_connectivity == dual_cell_value.connectivity_ptr().get(),
+           "unexpected connectivity for dual CellValue");
 
     parallel_for(
       m_primal_node_to_dual_cell_map.size(), PUGS_LAMBDA(size_t i) {
@@ -129,8 +141,10 @@ class ConnectivityToMedianDualConnectivityDataMapper : public IConnectivityToDua
     static_assert(not std::is_const_v<DestinationDataType>, "destination data type must not be constant");
     static_assert(std::is_same_v<std::remove_const_t<OriginDataType>, DestinationDataType>, "incompatible types");
 
-    Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get());
-    Assert(m_dual_connectivity == dual_cell_value.connectivity_ptr().get());
+    Assert(m_primal_connectivity == primal_node_value.connectivity_ptr().get(),
+           "unexpected connectivity for primal NodeValue");
+    Assert(m_dual_connectivity == dual_cell_value.connectivity_ptr().get(),
+           "unexpected connectivity for dual CellValue");
 
     parallel_for(
       m_primal_node_to_dual_cell_map.size(), PUGS_LAMBDA(size_t i) {
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 3358d2966..159c9a5fc 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -57,6 +57,7 @@ add_executable (unit_tests
   test_ConsoleManager.cpp
   test_CG.cpp
   test_ConnectivityToDiamondDualConnectivityDataMapper.cpp
+  test_ConnectivityToMedianDualConnectivityDataMapper.cpp
   test_ContinueProcessor.cpp
   test_ConcatExpressionProcessor.cpp
   test_CRSGraph.cpp
diff --git a/tests/test_ConnectivityToMedianDualConnectivityDataMapper.cpp b/tests/test_ConnectivityToMedianDualConnectivityDataMapper.cpp
new file mode 100644
index 000000000..96ea22940
--- /dev/null
+++ b/tests/test_ConnectivityToMedianDualConnectivityDataMapper.cpp
@@ -0,0 +1,191 @@
+#include <catch2/catch_test_macros.hpp>
+#include <catch2/matchers/catch_matchers_all.hpp>
+
+#include <MeshDataBaseForTests.hpp>
+#include <mesh/ConnectivityToMedianDualConnectivityDataMapper.hpp>
+#include <mesh/DualConnectivityManager.hpp>
+
+#include <mesh/Connectivity.hpp>
+#include <mesh/Mesh.hpp>
+
+// clazy:excludeall=non-pod-global-static
+
+TEST_CASE("ConnectivityToMedianDualConnectivityDataMapper", "[mesh]")
+{
+  SECTION("2D")
+  {
+    constexpr static size_t Dimension = 2;
+
+    using ConnectivityType = Connectivity<Dimension>;
+    using MeshType         = Mesh<ConnectivityType>;
+
+    std::shared_ptr<const MeshType> mesh        = MeshDataBaseForTests::get().hybrid2DMesh();
+    const ConnectivityType& primal_connectivity = mesh->connectivity();
+
+    std::shared_ptr p_median_dual_connectivity =
+      DualConnectivityManager::instance().getMedianDualConnectivity(primal_connectivity);
+    const ConnectivityType& dual_connectivity = *p_median_dual_connectivity;
+
+    std::shared_ptr p_connectivity_to_dual_connectivity_mapper =
+      DualConnectivityManager::instance().getConnectivityToMedianDualConnectivityDataMapper(primal_connectivity);
+    const auto& connectivity_to_dual_connectivity_mapper = *p_connectivity_to_dual_connectivity_mapper;
+
+    SECTION("check data transfer between primal nodes to dual cells")
+    {
+      const auto& primal_node_to_face_matrix = primal_connectivity.nodeToFaceMatrix();
+
+      NodeValue<size_t> primal_node_value{primal_connectivity};
+      parallel_for(
+        primal_node_value.numberOfItems(), PUGS_LAMBDA(const NodeId node_id) {
+          primal_node_value[node_id] = 2 * primal_node_to_face_matrix[node_id].size() + node_id;
+        });
+
+      CellValue<size_t> dual_from_primal_node_value{dual_connectivity};
+
+      connectivity_to_dual_connectivity_mapper.toDualCell(primal_node_value, dual_from_primal_node_value);
+
+      {
+        const auto& dual_cell_to_node_matrix = dual_connectivity.cellToNodeMatrix();
+        bool correct_value                   = true;
+        for (CellId cell_id = 0; cell_id < dual_connectivity.numberOfCells(); ++cell_id) {
+          correct_value &= (dual_cell_to_node_matrix[cell_id].size() + cell_id == dual_from_primal_node_value[cell_id]);
+        }
+        REQUIRE(correct_value);
+      }
+
+      {
+        bool is_same = true;
+        NodeValue<size_t> primal_from_dual_cell_value{primal_connectivity};
+        connectivity_to_dual_connectivity_mapper.fromDualCell(dual_from_primal_node_value, primal_from_dual_cell_value);
+        for (NodeId node_id = 0; node_id < primal_connectivity.numberOfNodes(); ++node_id) {
+          is_same &= (primal_from_dual_cell_value[node_id] == primal_node_value[node_id]);
+        }
+        REQUIRE(is_same);
+      }
+
+#ifndef NDEBUG
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.toDualCell(NodeValue<size_t>{dual_connectivity},
+                                                                              dual_from_primal_node_value),
+                          "unexpected connectivity for primal NodeValue");
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.toDualCell(primal_node_value,
+                                                                              CellValue<size_t>{primal_connectivity}),
+                          "unexpected connectivity for dual CellValue");
+
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.fromDualCell(dual_from_primal_node_value,
+                                                                                NodeValue<size_t>{dual_connectivity}),
+                          "unexpected connectivity for primal NodeValue");
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.fromDualCell(CellValue<size_t>{primal_connectivity},
+                                                                                primal_node_value),
+                          "unexpected connectivity for dual CellValue");
+
+#endif   // NDEBUG
+    }
+
+    SECTION("check data transfer between primal faces and cells to dual nodes")
+    {
+      const auto& primal_cell_to_node_matrix = primal_connectivity.cellToNodeMatrix();
+      CellValue<size_t> primal_cell_value{primal_connectivity};
+      parallel_for(
+        primal_cell_value.numberOfItems(),
+        PUGS_LAMBDA(const CellId cell_id) { primal_cell_value[cell_id] = primal_cell_to_node_matrix[cell_id].size(); });
+
+      const auto& primal_face_to_cell_matrix = primal_connectivity.faceToCellMatrix();
+      FaceValue<size_t> primal_face_value{primal_connectivity};
+      parallel_for(
+        primal_face_value.numberOfItems(), PUGS_LAMBDA(const FaceId face_id) {
+          primal_face_value[face_id] = 2 + (primal_face_to_cell_matrix[face_id].size() == 1);
+        });
+
+      NodeValue<size_t> primal_node_value{primal_connectivity};
+      primal_node_value.fill(2);
+
+      NodeValue<size_t> dual_from_primal_value{dual_connectivity};
+      connectivity_to_dual_connectivity_mapper.toDualNode(primal_node_value, primal_face_value, primal_cell_value,
+                                                          dual_from_primal_value);
+
+      {
+        const auto& dual_node_to_face_matrix = dual_connectivity.nodeToFaceMatrix();
+        auto dual_node_number                = dual_connectivity.nodeNumber();
+        bool correct_dual_value              = true;
+        for (NodeId node_id = 0; node_id < dual_connectivity.numberOfNodes(); ++node_id) {
+          correct_dual_value &= (dual_from_primal_value[node_id] == dual_node_to_face_matrix[node_id].size());
+        }
+        REQUIRE(correct_dual_value);
+      }
+
+      {
+        bool is_same = true;
+        NodeValue<size_t> primal_from_dual_node_value{primal_connectivity};
+        FaceValue<size_t> primal_from_dual_face_value{primal_connectivity};
+        CellValue<size_t> primal_from_dual_cell_value{primal_connectivity};
+        connectivity_to_dual_connectivity_mapper.fromDualNode(dual_from_primal_value,        //
+                                                              primal_from_dual_node_value,   //
+                                                              primal_from_dual_face_value,   //
+                                                              primal_from_dual_cell_value);
+
+        for (CellId cell_id = 0; cell_id < primal_connectivity.numberOfCells(); ++cell_id) {
+          is_same &= (primal_cell_value[cell_id] == primal_from_dual_cell_value[cell_id]);
+        }
+        for (FaceId face_id = 0; face_id < primal_connectivity.numberOfFaces(); ++face_id) {
+          is_same &= (primal_face_value[face_id] == primal_from_dual_face_value[face_id]);
+        }
+        auto primal_face_to_node_matrix = primal_connectivity.faceToNodeMatrix();
+        for (FaceId face_id = 0; face_id < primal_connectivity.numberOfFaces(); ++face_id) {
+          if (primal_face_to_cell_matrix[face_id].size() == 1) {
+            for (size_t i_node = 0; i_node < primal_face_to_node_matrix[face_id].size(); ++i_node) {
+              NodeId node_id = primal_face_to_node_matrix[face_id][i_node];
+              is_same &= (primal_node_value[node_id] == primal_from_dual_node_value[node_id]);
+            }
+          }
+        }
+
+        REQUIRE(is_same);
+      }
+
+#ifndef NDEBUG
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.toDualNode(NodeValue<size_t>{dual_connectivity},
+                                                                              primal_face_value,   //
+                                                                              primal_cell_value,
+                                                                              dual_from_primal_value),
+                          "unexpected connectivity for primal NodeValue");
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.toDualNode(primal_node_value,
+                                                                              FaceValue<size_t>{dual_connectivity},
+                                                                              primal_cell_value,
+                                                                              dual_from_primal_value),
+                          "unexpected connectivity for primal FaceValue");
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.toDualNode(primal_node_value,   //
+                                                                              primal_face_value,   //
+                                                                              CellValue<size_t>{dual_connectivity},
+                                                                              dual_from_primal_value),
+                          "unexpected connectivity for primal CellValue");
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.toDualNode(primal_node_value,   //
+                                                                              primal_face_value,   //
+                                                                              primal_cell_value,
+                                                                              NodeValue<size_t>{primal_connectivity}),
+                          "unexpected connectivity for dual NodeValue");
+
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.fromDualNode(dual_from_primal_value,
+                                                                                NodeValue<size_t>{dual_connectivity},
+                                                                                primal_face_value,   //
+                                                                                primal_cell_value),
+                          "unexpected connectivity for primal NodeValue");
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.fromDualNode(dual_from_primal_value,
+                                                                                primal_node_value,
+                                                                                FaceValue<size_t>{dual_connectivity},
+                                                                                primal_cell_value),
+                          "unexpected connectivity for primal FaceValue");
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.fromDualNode(dual_from_primal_value,
+                                                                                primal_node_value,   //
+                                                                                primal_face_value,   //
+                                                                                CellValue<size_t>{dual_connectivity}),
+                          "unexpected connectivity for primal CellValue");
+      REQUIRE_THROWS_WITH(connectivity_to_dual_connectivity_mapper.fromDualNode(NodeValue<size_t>{primal_connectivity},
+                                                                                primal_node_value,   //
+                                                                                primal_face_value,   //
+                                                                                primal_cell_value),
+                          "unexpected connectivity for dual NodeValue");
+
+#endif   // NDEBUG
+    }
+  }
+}
-- 
GitLab