From 9d7da3cd76f49fe46e895cae78fad64d5f37f637 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Thu, 4 Apr 2019 19:23:23 +0200
Subject: [PATCH] Continue clean-up: more template factorization

---
 src/mesh/Connectivity.hpp           |   9 +-
 src/mesh/ConnectivityDispatcher.cpp | 183 ++++++++++++++--------------
 src/mesh/ConnectivityDispatcher.hpp |  14 ++-
 3 files changed, 109 insertions(+), 97 deletions(-)

diff --git a/src/mesh/Connectivity.hpp b/src/mesh/Connectivity.hpp
index b6ce4b429..23a13a78d 100644
--- a/src/mesh/Connectivity.hpp
+++ b/src/mesh/Connectivity.hpp
@@ -47,9 +47,12 @@ class ConnectivityDescriptor
  public:
   std::vector<std::vector<unsigned int>> cell_to_node_vector;
 
-#warning should be set in 2d
+#warning should be set in 2d only
   std::vector<std::vector<unsigned int>> cell_to_face_vector;
-  // std::vector<std::vector<unsigned int>> face_to_cell_vector;
+
+#warning should be set in 3d only
+  // std::vector<std::vector<unsigned int>> cell_to_edge_vector;
+
   std::vector<std::vector<unsigned int>> face_to_node_vector;
 
   template <typename ItemOfItemT>
@@ -59,7 +62,7 @@ class ConnectivityDescriptor
       return cell_to_node_vector;
     } else if constexpr (std::is_same_v<ItemOfItemT,FaceOfCell>) {
       return cell_to_face_vector;
-    } else if constexpr (std::is_same_v<ItemOfItemT,NodeOfCell>) {
+    } else if constexpr (std::is_same_v<ItemOfItemT,NodeOfFace>) {
       return face_to_node_vector;
     } else {
       static_assert(is_false_v<ItemOfItemT>, "Unexpected item of item type");
diff --git a/src/mesh/ConnectivityDispatcher.cpp b/src/mesh/ConnectivityDispatcher.cpp
index 88b2238cb..8406ca9e2 100644
--- a/src/mesh/ConnectivityDispatcher.cpp
+++ b/src/mesh/ConnectivityDispatcher.cpp
@@ -46,6 +46,20 @@ ConnectivityDispatcher<Dimension>::_buildNewOwner()
   }
 }
 
+template <int Dimension>
+template <ItemType item_type>
+void ConnectivityDispatcher<Dimension>::
+_buildItemToExchangeLists()
+{
+  this->_buildItemListToSend<item_type>();
+  this->_buildNumberOfItemToExchange<item_type>();
+
+  if constexpr (item_type == ItemType::cell) {
+    this->_buildCellNumberIdMap();
+  }
+  this->_buildRecvItemIdCorrespondanceByProc<item_type>();
+}
+
 template <int Dimension>
 template <ItemType item_type>
 void
@@ -116,17 +130,22 @@ ConnectivityDispatcher<Dimension>::_buildItemListToSend()
 }
 
 template <int Dimension>
-Array<const unsigned int>
-ConnectivityDispatcher<Dimension>::_buildNbCellToSend()
+template <ItemType item_type>
+void
+ConnectivityDispatcher<Dimension>::_buildNumberOfItemToExchange()
 {
-  const auto& item_list_to_send_by_proc = this->_dispatchedInfo<ItemType::cell>().m_list_to_send_by_proc;
-  Array<unsigned int> nb_cell_to_send_by_proc(parallel::size());
+  const auto& item_list_to_send_by_proc = this->_dispatchedInfo<item_type>().m_list_to_send_by_proc;
+  Array<unsigned int> nb_item_to_send_by_proc(parallel::size());
   for (size_t i=0; i<parallel::size(); ++i) {
-    nb_cell_to_send_by_proc[i] = item_list_to_send_by_proc[i].size();
+    nb_item_to_send_by_proc[i] = item_list_to_send_by_proc[i].size();
   }
-  return nb_cell_to_send_by_proc;
+  this->_dispatchedInfo<item_type>().m_list_to_send_size_by_proc = nb_item_to_send_by_proc;
+
+  this->_dispatchedInfo<item_type>().m_list_to_recv_size_by_proc
+      = parallel::allToAll(nb_item_to_send_by_proc);
 }
 
+
 template <int Dimension>
 template<typename DataType, ItemType item_type, typename ConnectivityPtr>
 void
@@ -307,6 +326,42 @@ _getRecvItemSubItemNumberingByProc(const std::vector<Array<const int>>& recv_num
   return const_recv_item_sub_item_numbering_by_proc;
 }
 
+template <int Dimension>
+template <typename ItemOfItemT>
+void
+ConnectivityDispatcher<Dimension>::
+_buildItemToItemDescriptor()
+{
+  constexpr ItemType item_type = ItemOfItemT::item_type;
+  constexpr ItemType sub_item_type = ItemOfItemT::sub_item_type;
+
+  const auto& item_list_to_recv_size_by_proc =
+      this->_dispatchedInfo<item_type>().m_list_to_recv_size_by_proc;
+
+  const auto& recv_number_of_item_per_item_by_proc =
+      this->_dispatchedInfo<ItemOfItemT>().m_recv_number_of_item_per_item_by_proc;
+
+  const auto& sub_item_number_id_map =
+      this->_dispatchedInfo<sub_item_type>().m_number_to_id_map;
+
+  const auto& recv_item_of_item_numbers_by_proc =
+      this->_dispatchedInfo<ItemOfItemT>().m_recv_item_of_item_numbers_by_proc;
+
+  for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) {
+    int l=0;
+    for (size_t i=0; i<item_list_to_recv_size_by_proc[i_rank]; ++i) {
+      std::vector<unsigned int> sub_item_vector;
+      for (int k=0; k<recv_number_of_item_per_item_by_proc[i_rank][i]; ++k) {
+        const auto& searched_sub_item_id =
+            sub_item_number_id_map.find(recv_item_of_item_numbers_by_proc[i_rank][l++]);
+        Assert(searched_sub_item_id != sub_item_number_id_map.end());
+        sub_item_vector.push_back(searched_sub_item_id->second);
+      }
+      m_new_descriptor.itemOfItemVector<ItemOfItemT>().emplace_back(sub_item_vector);
+    }
+  }
+}
+
 template <int Dimension>
 template <ItemType item_type>
 void
@@ -359,74 +414,40 @@ ConnectivityDispatcher<Dimension>::_dispatchFaces()
     this->_dispatchedInfo<FaceOfCell>().m_recv_number_of_item_per_item_by_proc =
         _getRecvNumberOfSubItemPerItemByProc<FaceOfCell>();
 
-    const auto& recv_number_of_face_per_cell_by_proc =
-        this->_dispatchedInfo<FaceOfCell>().m_recv_number_of_item_per_item_by_proc;
-
-    std::vector<Array<const int>> recv_cell_face_numbering_by_proc
-      = this->_getRecvItemSubItemNumberingByProc<FaceOfCell>(recv_number_of_face_per_cell_by_proc);
-
-    this->_buildSubItemNumberToIdMap<FaceOfCell>(recv_cell_face_numbering_by_proc);
+    {
+      const auto& recv_number_of_face_per_cell_by_proc =
+          this->_dispatchedInfo<FaceOfCell>().m_recv_number_of_item_per_item_by_proc;
 
-    const std::unordered_map<int, int>& face_number_id_map =
-        this->_dispatchedInfo<ItemType::face>().m_number_to_id_map;
+      std::vector<Array<const int>>& recv_cell_face_numbering_by_proc
+          = this->_dispatchedInfo<FaceOfCell>().m_recv_item_of_item_numbers_by_proc;
 
-    this->_buildItemListToSend<ItemType::face>();
+      recv_cell_face_numbering_by_proc =
+          this->_getRecvItemSubItemNumberingByProc<FaceOfCell>(recv_number_of_face_per_cell_by_proc);
 
-#warning this patterns repeats for each item type. Should be factorized
-    Array<unsigned int> nb_face_to_send_by_proc(parallel::size());
-    for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-      nb_face_to_send_by_proc[i_rank] = m_dispatched_face_info.m_list_to_send_by_proc[i_rank].size();
+      this->_buildSubItemNumberToIdMap<FaceOfCell>(recv_cell_face_numbering_by_proc);
     }
-    this->_dispatchedInfo<ItemType::face>().m_list_to_recv_size_by_proc
-        = parallel::allToAll(nb_face_to_send_by_proc);
 
-    this->_buildRecvItemIdCorrespondanceByProc<ItemType::face>();
+    this->_buildItemToExchangeLists<ItemType::face>();
+
     this->_gatherFrom(m_connectivity.template number<ItemType::face>(), m_new_descriptor.face_number_vector);
 
-    {
-      const auto& cell_list_to_recv_size_by_proc =
-          this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc;
-      const auto& recv_number_of_face_per_cell_by_proc =
-          this->_dispatchedInfo<FaceOfCell>().m_recv_number_of_item_per_item_by_proc;
-
-      for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) {
-        int l=0;
-        for (size_t i=0; i<cell_list_to_recv_size_by_proc[i_rank]; ++i) {
-          std::vector<unsigned int> face_vector;
-          for (int k=0; k<recv_number_of_face_per_cell_by_proc[i_rank][i]; ++k) {
-            const auto& searched_face_id = face_number_id_map.find(recv_cell_face_numbering_by_proc[i_rank][l++]);
-            Assert(searched_face_id != face_number_id_map.end());
-            face_vector.push_back(searched_face_id->second);
-          }
-          m_new_descriptor.itemOfItemVector<FaceOfCell>().emplace_back(face_vector);
-        }
-      }
-    }
+    this->_buildItemToItemDescriptor<FaceOfCell>();
 
     this->_gatherFrom(m_connectivity.cellFaceIsReversed(), m_new_descriptor.cell_face_is_reversed_vector);
 
     this->_gatherFrom(this->_dispatchedInfo<ItemType::face>().m_new_owner, m_new_descriptor.face_owner_vector);
 
     {
-      std::vector<Array<const int>> recv_number_of_node_per_face_by_proc =
+      auto& recv_number_of_node_per_face_by_proc =
+          this->_dispatchedInfo<NodeOfFace>().m_recv_number_of_item_per_item_by_proc;
+
+      recv_number_of_node_per_face_by_proc =
           _getRecvNumberOfSubItemPerItemByProc<NodeOfFace>();
 
-      std::vector<Array<const int>> recv_face_node_numbering_by_proc
+      this->_dispatchedInfo<NodeOfFace>().m_recv_item_of_item_numbers_by_proc
           = this->_getRecvItemSubItemNumberingByProc<NodeOfFace>(recv_number_of_node_per_face_by_proc);
 
-      const auto& node_number_id_map = this->_dispatchedInfo<ItemType::node>().m_number_to_id_map;
-      for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) {
-        int l=0;
-        for (size_t i=0; i<recv_number_of_node_per_face_by_proc[i_rank].size(); ++i) {
-          std::vector<unsigned int> node_vector;
-          for (int k=0; k<recv_number_of_node_per_face_by_proc[i_rank][i]; ++k) {
-            const auto& searched_node_id = node_number_id_map.find(recv_face_node_numbering_by_proc[i_rank][l++]);
-            Assert(searched_node_id != node_number_id_map.end());
-            node_vector.push_back(searched_node_id->second);
-          }
-          m_new_descriptor.face_to_node_vector.emplace_back(node_vector);
-        }
-      }
+      this->_buildItemToItemDescriptor<NodeOfFace>();
     }
 
     // Getting references
@@ -536,8 +557,11 @@ ConnectivityDispatcher<Dimension>::_dispatchFaces()
             }
           }
 
+          const auto& nb_face_to_send_by_proc =
+              this->_dispatchedInfo<ItemType::face>().m_list_to_send_size_by_proc;
           const auto& send_face_id_by_proc = m_dispatched_face_info.m_list_to_send_by_proc;
           std::vector<Array<const block_type>> send_face_refs_by_proc(parallel::size());
+
           for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
             Array<block_type> send_face_refs(nb_face_to_send_by_proc[i_rank]);
             const Array<const FaceId> send_face_id = send_face_id_by_proc[i_rank];
@@ -598,32 +622,25 @@ ConnectivityDispatcher<Dimension>::ConnectivityDispatcher(const ConnectivityType
   // this->_buildNewOwner<ItemType::edge>();
   this->_buildNewOwner<ItemType::node>();
 
-  this->_buildItemListToSend<ItemType::cell>();
-  this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc
-      = parallel::allToAll(this->_buildNbCellToSend());
+  this->_buildItemToExchangeLists<ItemType::cell>();
 
-  this->_buildCellNumberIdMap();
+  auto& recv_number_of_node_per_cell_by_proc=
+      this->_dispatchedInfo<NodeOfCell>().m_recv_number_of_item_per_item_by_proc;
 
-  const std::vector<Array<const int>> recv_number_of_node_per_cell_by_proc
+  recv_number_of_node_per_cell_by_proc
       = this->_getRecvNumberOfSubItemPerItemByProc<NodeOfCell>();
 
-  const std::vector<Array<const int>> recv_cell_node_numbering_by_proc
+  auto& recv_cell_node_numbering_by_proc =
+      this->_dispatchedInfo<NodeOfCell>().m_recv_item_of_item_numbers_by_proc;
+
+  recv_cell_node_numbering_by_proc
       = this->_getRecvItemSubItemNumberingByProc<NodeOfCell>(recv_number_of_node_per_cell_by_proc);
 
-  this->_buildRecvItemIdCorrespondanceByProc<ItemType::cell>();
   this->_gatherFrom(m_connectivity.template number<ItemType::cell>(), m_new_descriptor.cell_number_vector);
 
   this->_buildSubItemNumberToIdMap<NodeOfCell>(recv_cell_node_numbering_by_proc);
-  this->_buildItemListToSend<ItemType::node>();
 
-  Array<unsigned int> nb_node_to_send_by_proc(parallel::size());
-  for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-    nb_node_to_send_by_proc[i_rank] = m_dispatched_node_info.m_list_to_send_by_proc[i_rank].size();
-  }
-  this->_dispatchedInfo<ItemType::node>().m_list_to_recv_size_by_proc
-      = parallel::allToAll(nb_node_to_send_by_proc);
-
-  this->_buildRecvItemIdCorrespondanceByProc<ItemType::node>();
+  this->_buildItemToExchangeLists<ItemType::node>();
 
   // Fill new descriptor
   this->_gatherFrom(m_connectivity.cellType(), m_new_descriptor.cell_type_vector);
@@ -632,24 +649,8 @@ ConnectivityDispatcher<Dimension>::ConnectivityDispatcher(const ConnectivityType
   this->_gatherFrom(m_connectivity.template number<ItemType::node>(), m_new_descriptor.node_number_vector);
   this->_gatherFrom(this->_dispatchedInfo<ItemType::node>().m_new_owner, m_new_descriptor.node_owner_vector);
 
-  { // build cells connectivity
-    const auto& cell_list_to_recv_size_by_proc =
-        this->_dispatchedInfo<ItemType::cell>().m_list_to_recv_size_by_proc;
-
-    const auto& node_number_id_map  = this->_dispatchedInfo<ItemType::node>().m_number_to_id_map;
-    for (size_t i_rank=0; i_rank < parallel::size(); ++i_rank) {
-      int l=0;
-      for (size_t i=0; i<cell_list_to_recv_size_by_proc[i_rank]; ++i) {
-        std::vector<unsigned int> node_vector;
-        for (int k=0; k<recv_number_of_node_per_cell_by_proc[i_rank][i]; ++k) {
-          const auto& searched_node_id = node_number_id_map.find(recv_cell_node_numbering_by_proc[i_rank][l++]);
-          Assert(searched_node_id != node_number_id_map.end());
-          node_vector.push_back(searched_node_id->second);
-        }
-        m_new_descriptor.cell_to_node_vector.emplace_back(node_vector);
-      }
-    }
-  }
+  this->_buildItemToItemDescriptor<NodeOfCell>();
+
   this->_dispatchFaces();
 
   m_dispatched_connectivity = ConnectivityType::build(m_new_descriptor);
diff --git a/src/mesh/ConnectivityDispatcher.hpp b/src/mesh/ConnectivityDispatcher.hpp
index 43dd2e75f..a893c8151 100644
--- a/src/mesh/ConnectivityDispatcher.hpp
+++ b/src/mesh/ConnectivityDispatcher.hpp
@@ -23,8 +23,8 @@ class ConnectivityDispatcher
   {
     using ItemId = ItemIdT<item_type>;
     ItemValue<const int, item_type> m_new_owner;
+    Array<const unsigned int> m_list_to_send_size_by_proc;
     std::vector<Array<const ItemId>> m_list_to_send_by_proc;
-#warning is m_list_to_recv_size_by_proc really necessary?
     Array<const unsigned int> m_list_to_recv_size_by_proc;
     std::unordered_map<int, int> m_number_to_id_map;
     std::vector<Array<const ItemId>> m_recv_id_correspondance_by_proc;
@@ -69,6 +69,7 @@ class ConnectivityDispatcher
   struct DispatchedItemOfItemInfo
   {
     std::vector<Array<const int>> m_recv_number_of_item_per_item_by_proc;
+    std::vector<Array<const int>> m_recv_item_of_item_numbers_by_proc;
   };
 
   DispatchedItemOfItemInfo<NodeOfCell> m_dispatched_node_of_cell_info;
@@ -159,13 +160,20 @@ class ConnectivityDispatcher
   template <ItemType item_type>
   void _buildItemListToSend();
 
-  Array<const unsigned int> _buildNbCellToSend();
-
   void _buildCellNumberIdMap();
 
   template <typename ItemOfItemT>
   void _buildSubItemNumberToIdMap(const std::vector<Array<const int>>& recv_cell_node_number_by_proc);
 
+  template <ItemType item_type>
+  void _buildItemToExchangeLists();
+
+  template <ItemType item_type>
+  void _buildNumberOfItemToExchange();
+
+  template <typename ItemOfItemT>
+  void _buildItemToItemDescriptor();
+
   void _dispatchFaces();
 
   template<typename DataType, ItemType item_type, typename ConnectivityPtr>
-- 
GitLab