From b1d0fcb3b0347e47a09a8ccc3f20c11b96886182 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Fri, 28 Sep 2018 09:50:30 +0200
Subject: [PATCH] Add construction and access to a cell to cell graph

The considered graph is built joining cells through their faces
---
 CMakeLists.txt            |  4 ++--
 src/mesh/Connectivity.hpp | 39 +++++++++++++++++++++++++++++++++++++++
 src/mesh/Mesh.hpp         |  9 +++++++++
 3 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index efae19025..caeef4763 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -264,5 +264,5 @@ target_link_libraries(
   kokkos
   ${PARMETIS_LIBRARIES}
   ${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES}
-  PastisUtils
-  PastisMesh)
+  PastisMesh
+  PastisUtils)
diff --git a/src/mesh/Connectivity.hpp b/src/mesh/Connectivity.hpp
index f876f70e1..3c0405952 100644
--- a/src/mesh/Connectivity.hpp
+++ b/src/mesh/Connectivity.hpp
@@ -25,6 +25,8 @@
 
 #include <CellType.hpp>
 
+#include <CSRGraph.hpp>
+
 #include <RefId.hpp>
 #include <ItemType.hpp>
 #include <RefNodeList.hpp>
@@ -32,6 +34,7 @@
 
 #include <tuple>
 #include <algorithm>
+#include <set>
 
 template <size_t Dimension>
 class Connectivity;
@@ -530,6 +533,42 @@ class Connectivity final
     return m_ref_node_list[i];
   }
 
+  PASTIS_INLINE
+  CSRGraph cellToCellGraph() const
+  {
+    std::vector<std::set<int>> cell_cells(this->numberOfCells());
+    const auto& face_to_cell_matrix
+        = this->faceToCellMatrix();
+
+    for (FaceId l=0; l<this->numberOfFaces(); ++l) {
+      const auto& face_to_cell = face_to_cell_matrix[l];
+      if (face_to_cell.size() == 2) {
+        const int cell_0 = face_to_cell[0];
+        const int cell_1 = face_to_cell[1];
+
+        cell_cells[cell_0].insert(cell_1);
+        cell_cells[cell_1].insert(cell_0);
+      }
+    }
+
+    Array<int> entries(this->numberOfCells()+1);
+    entries[0]=0;
+    for (size_t j=0; j<this->numberOfCells(); ++j) {
+      entries[j+1] = entries[j]+cell_cells[j].size();
+    }
+    Array<int> neighbors(entries[this->numberOfCells()]);
+    {
+      size_t k=0;
+      for (size_t j=0; j<this->numberOfCells(); ++j) {
+        for (auto cell_id : cell_cells[j]) {
+          neighbors[k] = cell_id;
+          ++k;
+        }
+      }
+    }
+    return CSRGraph(entries, neighbors);
+  }
+
   PASTIS_INLINE
   size_t numberOfNodes() const final
   {
diff --git a/src/mesh/Mesh.hpp b/src/mesh/Mesh.hpp
index c21910e7a..891d55400 100644
--- a/src/mesh/Mesh.hpp
+++ b/src/mesh/Mesh.hpp
@@ -4,11 +4,14 @@
 #include <ItemValue.hpp>
 #include <TinyVector.hpp>
 
+#include <CSRGraph.hpp>
+
 #include <memory>
 
 struct IMesh
 {
   virtual const size_t meshDimension() const = 0;
+  virtual CSRGraph cellToCellGraph() const = 0;
   ~IMesh() = default;
 };
 
@@ -27,6 +30,12 @@ private:
   NodeValue<Rd> m_mutable_xr;
 
 public:
+  PASTIS_INLINE
+  CSRGraph cellToCellGraph() const final
+  {
+    return m_connectivity->cellToCellGraph();
+  }
+
   PASTIS_INLINE
   const size_t meshDimension() const
   {
-- 
GitLab