diff --git a/src/mesh/DualConnectivityManager.hpp b/src/mesh/DualConnectivityManager.hpp
index 6389c5d459ac677295c09fcfce730cec2bd2f525..d82eabb72c7d42f215ffdf44cec579749f21e88c 100644
--- a/src/mesh/DualConnectivityManager.hpp
+++ b/src/mesh/DualConnectivityManager.hpp
@@ -44,7 +44,7 @@ class DualConnectivityManager
     }
 
     DualConnectivityInfo& operator=(const DualConnectivityInfo&) = default;
-    DualConnectivityInfo& operator=(DualConnectivityInfo&&) = delete;
+    DualConnectivityInfo& operator=(DualConnectivityInfo&&)      = delete;
 
     DualConnectivityInfo()                            = default;
     DualConnectivityInfo(const DualConnectivityInfo&) = default;
@@ -86,6 +86,12 @@ class DualConnectivityManager
   ~DualConnectivityManager() = default;
 
  public:
+  const auto&
+  primalToDualConnectivityInfoMap() const
+  {
+    return m_primal_to_dual_connectivity_info_map;
+  }
+
   static void create();
   static void destroy();
 
diff --git a/src/utils/checkpointing/Checkpoint.cpp b/src/utils/checkpointing/Checkpoint.cpp
index 70166a86175bd5621bc545112db7ac17e28e668a..dbd10ca634f3a14aec59787f74e4b498f44e5ed3 100644
--- a/src/utils/checkpointing/Checkpoint.cpp
+++ b/src/utils/checkpointing/Checkpoint.cpp
@@ -25,10 +25,13 @@
 #include <language/utils/ASTNodeDataTypeTraits.hpp>
 #include <language/utils/CheckpointResumeRepository.hpp>
 #include <language/utils/DataHandler.hpp>
+#include <mesh/DualConnectivityManager.hpp>
+#include <mesh/DualMeshManager.hpp>
 #include <mesh/MeshVariant.hpp>
 #include <utils/GlobalVariableManager.hpp>
 #include <utils/RandomEngine.hpp>
 
+#include <utils/checkpointing/DualMeshTypeHFType.hpp>
 #include <utils/checkpointing/LinearSolverOptionsHFType.hpp>
 #include <utils/checkpointing/ParallelCheckerHFType.hpp>
 
@@ -105,7 +108,21 @@ checkpoint()
       linear_solver_options_default_group.createAttribute("precond", default_options.precond());
     }
     {
-      std::cout << rang::fgB::magenta << "Checkpoint DualConnectivityManager NIY" << rang::fg::reset << '\n';
+      const auto& primal_to_dual_connectivity_info_map =
+        DualConnectivityManager::instance().primalToDualConnectivityInfoMap();
+      for (auto&& primal_to_dual_connectivity_info : primal_to_dual_connectivity_info_map) {
+        const DualMeshType type_of_dual     = primal_to_dual_connectivity_info.first.first;
+        const size_t primal_connectivity_id = primal_to_dual_connectivity_info.first.second->id();
+        const size_t dual_connectivity_id   = primal_to_dual_connectivity_info.second.dualConnectivity()->id();
+
+        HighFive::Group connectivity_group =
+          checkpoint.createGroup("connectivity/" + std::to_string(dual_connectivity_id));
+        connectivity_group.createAttribute("type", std::string{"dual_connectivity"});
+        connectivity_group.createAttribute("type_of_dual", type_of_dual);
+        connectivity_group.createAttribute("id", dual_connectivity_id);
+        connectivity_group.createAttribute("primal_connectivity_id", primal_connectivity_id);
+      }
+
       std::cout << rang::fgB::magenta << "Checkpoint DualMeshManager NIY" << rang::fg::reset << '\n';
     }
 
diff --git a/src/utils/checkpointing/CheckpointUtils.cpp b/src/utils/checkpointing/CheckpointUtils.cpp
index d457e55f418d860cb9461185a593cedfe9abb252..fb0e9361ffb5f26ffc41ac7a31c699debd4bed85 100644
--- a/src/utils/checkpointing/CheckpointUtils.cpp
+++ b/src/utils/checkpointing/CheckpointUtils.cpp
@@ -100,11 +100,16 @@ writeConnectivity(const Connectivity<Dimension>& connectivity, HighFive::File& f
   if (not checkpoint_group.exist(connectivity_group_name)) {
     bool linked = false;
     for (auto group_name : file.listObjectNames()) {
-      if (file.exist(group_name + "/" + connectivity_group_name)) {
-        checkpoint_group.createHardLink(connectivity_group_name,
-                                        file.getGroup(group_name + "/" + connectivity_group_name));
-        linked = true;
-        break;
+      const std::string stored_connectivity_group_name = group_name + "/" + connectivity_group_name;
+      if (file.exist(stored_connectivity_group_name)) {
+        HighFive::Group stored_connectivity_group = file.getGroup(stored_connectivity_group_name);
+
+        const std::string type_name = stored_connectivity_group.getAttribute("type").read<std::string>();
+        if (type_name != "dual_connectivity") {
+          checkpoint_group.createHardLink(connectivity_group_name, file.getGroup(stored_connectivity_group_name));
+          linked = true;
+          break;
+        }
       }
     }
 
diff --git a/src/utils/checkpointing/DualMeshTypeHFType.hpp b/src/utils/checkpointing/DualMeshTypeHFType.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..14010b647f13aa978446ccf9723fd7e79b232cd4
--- /dev/null
+++ b/src/utils/checkpointing/DualMeshTypeHFType.hpp
@@ -0,0 +1,14 @@
+#ifndef DUAL_MESH_TYPE_HF_TYPE_HPP
+#define DUAL_MESH_TYPE_HF_TYPE_HPP
+
+#include <mesh/DualConnectivityManager.hpp>
+#include <utils/checkpointing/CheckpointUtils.hpp>
+
+HighFive::EnumType<DualMeshType> PUGS_INLINE
+create_enum_DualMeshType_type()
+{
+  return {{"dual1d", DualMeshType::Dual1D}, {"diamond", DualMeshType::Diamond}, {"median", DualMeshType::Median}};
+}
+HIGHFIVE_REGISTER_TYPE(DualMeshType, create_enum_DualMeshType_type)
+
+#endif   // DUAL_MESH_TYPE_HF_TYPE_HPP
diff --git a/src/utils/checkpointing/LinearSolverOptionsHFType.hpp b/src/utils/checkpointing/LinearSolverOptionsHFType.hpp
index ce95f2a90519a1b00e1f1f28849908c7176468ac..127fdddc0dfa292d1228d12bf3cd6d7ca39ce4e3 100644
--- a/src/utils/checkpointing/LinearSolverOptionsHFType.hpp
+++ b/src/utils/checkpointing/LinearSolverOptionsHFType.hpp
@@ -1,5 +1,5 @@
-#ifndef LINEAR_SOLVER_OPTIONS_H_F_TYPE_HPP
-#define LINEAR_SOLVER_OPTIONS_H_F_TYPE_HPP
+#ifndef LINEAR_SOLVER_OPTIONS_HF_TYPE_HPP
+#define LINEAR_SOLVER_OPTIONS_HF_TYPE_HPP
 
 #include <algebra/LinearSolverOptions.hpp>
 #include <utils/checkpointing/CheckpointUtils.hpp>
@@ -34,4 +34,4 @@ create_enum_LSOptions_precond_type()
 }
 HIGHFIVE_REGISTER_TYPE(LSPrecond, create_enum_LSOptions_precond_type)
 
-#endif   // LINEAR_SOLVER_OPTIONS_H_F_TYPE_HPP
+#endif   // LINEAR_SOLVER_OPTIONS_HF_TYPE_HPP
diff --git a/src/utils/checkpointing/Resume.cpp b/src/utils/checkpointing/Resume.cpp
index 757458fc45fbed692b015c6407dff89cca752196..b5e65316112c1c41774c2bf00993aea3b301f6b3 100644
--- a/src/utils/checkpointing/Resume.cpp
+++ b/src/utils/checkpointing/Resume.cpp
@@ -92,7 +92,6 @@ resume()
       default_options.precond() = linear_solver_options_default_group.getAttribute("precond").read<LSPrecond>();
     }
     {
-      std::cout << rang::fgB::magenta << "Resume DualConnectivityManager NIY" << rang::fg::reset << '\n';
       std::cout << rang::fgB::magenta << "Resume DualMeshManager NIY" << rang::fg::reset << '\n';
     }
 
diff --git a/src/utils/checkpointing/ResumingData.cpp b/src/utils/checkpointing/ResumingData.cpp
index 8e121cd1c3614c799e57858e0539a764cf3b95bd..a2d6c98b293d4927ccbcab08406926711f803914 100644
--- a/src/utils/checkpointing/ResumingData.cpp
+++ b/src/utils/checkpointing/ResumingData.cpp
@@ -2,8 +2,10 @@
 
 #include <language/utils/SymbolTable.hpp>
 #include <mesh/ConnectivityDescriptor.hpp>
+#include <mesh/DualConnectivityManager.hpp>
 #include <mesh/Mesh.hpp>
 #include <utils/Exceptions.hpp>
+#include <utils/checkpointing/DualMeshTypeHFType.hpp>
 #include <utils/checkpointing/RefItemListHFType.hpp>
 #include <utils/checkpointing/ResumeUtils.hpp>
 
@@ -23,126 +25,183 @@ ResumingData::_getConnectivityList(const HighFive::Group& checkpoint)
 
     for (auto [id, name] : id_name_map) {
       HighFive::Group connectivity_data = connectivity_group.getGroup(name);
-      const uint64_t dimension          = connectivity_data.getAttribute("dimension").read<uint64_t>();
       const std::string type            = connectivity_data.getAttribute("type").read<std::string>();
 
-      if (type != "unstructured") {
-        throw UnexpectedError("invalid connectivity type: " + type);
+      while (id > GlobalVariableManager::instance().getConnectivityId()) {
+        GlobalVariableManager::instance().getAndIncrementConnectivityId();
       }
 
-      ConnectivityDescriptor descriptor;
-      descriptor.setCellTypeVector(readArray<CellType>(connectivity_data, "cell_type"));
-      descriptor.setCellNumberVector(readArray<int>(connectivity_data, "cell_numbers"));
-      descriptor.setNodeNumberVector(readArray<int>(connectivity_data, "node_numbers"));
+      if (m_id_to_iconnectivity_map.contains(id)) {
+        throw UnexpectedError("connectivity of id " + std::to_string(id) + " already defined!");
+      }
 
-      descriptor.setCellOwnerVector(readArray<int>(connectivity_data, "cell_owner"));
-      descriptor.setNodeOwnerVector(readArray<int>(connectivity_data, "node_owner"));
+      if (type == "unstructured") {
+        const uint64_t dimension = connectivity_data.getAttribute("dimension").read<uint64_t>();
 
-      using index_type = typename ConnectivityMatrix::IndexType;
+        ConnectivityDescriptor descriptor;
+        descriptor.setCellTypeVector(readArray<CellType>(connectivity_data, "cell_type"));
+        descriptor.setCellNumberVector(readArray<int>(connectivity_data, "cell_numbers"));
+        descriptor.setNodeNumberVector(readArray<int>(connectivity_data, "node_numbers"));
 
-      descriptor.setCellToNodeMatrix(
-        ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_node_matrix_rowsMap"),
-                           readArray<index_type>(connectivity_data, "cell_to_node_matrix_values")});
+        descriptor.setCellOwnerVector(readArray<int>(connectivity_data, "cell_owner"));
+        descriptor.setNodeOwnerVector(readArray<int>(connectivity_data, "node_owner"));
 
-      if (dimension > 1) {
-        descriptor.setFaceNumberVector(readArray<int>(connectivity_data, "face_numbers"));
-        descriptor.setFaceOwnerVector(readArray<int>(connectivity_data, "face_owner"));
+        using index_type = typename ConnectivityMatrix::IndexType;
 
-        descriptor.setCellToFaceMatrix(
-          ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_face_matrix_rowsMap"),
-                             readArray<index_type>(connectivity_data, "cell_to_face_matrix_values")});
+        descriptor.setCellToNodeMatrix(
+          ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_node_matrix_rowsMap"),
+                             readArray<index_type>(connectivity_data, "cell_to_node_matrix_values")});
 
-        descriptor.setFaceToNodeMatrix(
-          ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_node_matrix_rowsMap"),
-                             readArray<index_type>(connectivity_data, "face_to_node_matrix_values")});
+        if (dimension > 1) {
+          descriptor.setFaceNumberVector(readArray<int>(connectivity_data, "face_numbers"));
+          descriptor.setFaceOwnerVector(readArray<int>(connectivity_data, "face_owner"));
 
-        descriptor.setNodeToFaceMatrix(
-          ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_face_matrix_rowsMap"),
-                             readArray<index_type>(connectivity_data, "node_to_face_matrix_values")});
+          descriptor.setCellToFaceMatrix(
+            ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_face_matrix_rowsMap"),
+                               readArray<index_type>(connectivity_data, "cell_to_face_matrix_values")});
 
-        descriptor.setCellFaceIsReversed(readArray<bool>(connectivity_data, "cell_face_is_reversed"));
-      }
+          descriptor.setFaceToNodeMatrix(
+            ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_node_matrix_rowsMap"),
+                               readArray<index_type>(connectivity_data, "face_to_node_matrix_values")});
 
-      if (dimension > 2) {
-        descriptor.setEdgeNumberVector(readArray<int>(connectivity_data, "edge_numbers"));
-        descriptor.setEdgeOwnerVector(readArray<int>(connectivity_data, "edge_owner"));
+          descriptor.setNodeToFaceMatrix(
+            ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_face_matrix_rowsMap"),
+                               readArray<index_type>(connectivity_data, "node_to_face_matrix_values")});
 
-        descriptor.setCellToEdgeMatrix(
-          ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_edge_matrix_rowsMap"),
-                             readArray<index_type>(connectivity_data, "cell_to_edge_matrix_values")});
+          descriptor.setCellFaceIsReversed(readArray<bool>(connectivity_data, "cell_face_is_reversed"));
+        }
 
-        descriptor.setFaceToEdgeMatrix(
-          ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_edge_matrix_rowsMap"),
-                             readArray<index_type>(connectivity_data, "face_to_edge_matrix_values")});
+        if (dimension > 2) {
+          descriptor.setEdgeNumberVector(readArray<int>(connectivity_data, "edge_numbers"));
+          descriptor.setEdgeOwnerVector(readArray<int>(connectivity_data, "edge_owner"));
 
-        descriptor.setEdgeToNodeMatrix(
-          ConnectivityMatrix{readArray<index_type>(connectivity_data, "edge_to_node_matrix_rowsMap"),
-                             readArray<index_type>(connectivity_data, "edge_to_node_matrix_values")});
+          descriptor.setCellToEdgeMatrix(
+            ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_edge_matrix_rowsMap"),
+                               readArray<index_type>(connectivity_data, "cell_to_edge_matrix_values")});
 
-        descriptor.setNodeToEdgeMatrix(
-          ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_edge_matrix_rowsMap"),
-                             readArray<index_type>(connectivity_data, "node_to_edge_matrix_values")});
+          descriptor.setFaceToEdgeMatrix(
+            ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_edge_matrix_rowsMap"),
+                               readArray<index_type>(connectivity_data, "face_to_edge_matrix_values")});
 
-        descriptor.setFaceEdgeIsReversed(readArray<bool>(connectivity_data, "face_edge_is_reversed"));
-      }
+          descriptor.setEdgeToNodeMatrix(
+            ConnectivityMatrix{readArray<index_type>(connectivity_data, "edge_to_node_matrix_rowsMap"),
+                               readArray<index_type>(connectivity_data, "edge_to_node_matrix_values")});
 
-      if (connectivity_data.exist("item_ref_list")) {
-        HighFive::Group item_group = connectivity_data.getGroup("item_ref_list");
-        for (auto item_type_name : item_group.listObjectNames()) {
-          HighFive::Group item_ref_name_list = item_group.getGroup(item_type_name);
-
-          for (auto item_ref_list_name : item_ref_name_list.listObjectNames()) {
-            HighFive::Group item_ref_list_data = item_ref_name_list.getGroup(item_ref_list_name);
-
-            RefId ref_id(item_ref_list_data.getAttribute("tag_number").read<uint64_t>(),
-                         item_ref_list_data.getAttribute("tag_name").read<std::string>());
-
-            RefItemListBase::Type ref_item_list_type =
-              item_ref_list_data.getAttribute("type").read<RefItemListBase::Type>();
-
-            if (item_type_name == "cell") {
-              descriptor.addRefItemList(
-                RefItemList<ItemType::cell>{ref_id, readArray<CellId>(item_ref_list_data, "list"), ref_item_list_type});
-            } else if (item_type_name == "face") {
-              descriptor.addRefItemList(
-                RefItemList<ItemType::face>{ref_id, readArray<FaceId>(item_ref_list_data, "list"), ref_item_list_type});
-            } else if (item_type_name == "edge") {
-              descriptor.addRefItemList(
-                RefItemList<ItemType::edge>{ref_id, readArray<EdgeId>(item_ref_list_data, "list"), ref_item_list_type});
-            } else if (item_type_name == "node") {
-              descriptor.addRefItemList(
-                RefItemList<ItemType::node>{ref_id, readArray<NodeId>(item_ref_list_data, "list"), ref_item_list_type});
-            } else {
-              throw UnexpectedError("invalid item type: " + item_type_name);
+          descriptor.setNodeToEdgeMatrix(
+            ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_edge_matrix_rowsMap"),
+                               readArray<index_type>(connectivity_data, "node_to_edge_matrix_values")});
+
+          descriptor.setFaceEdgeIsReversed(readArray<bool>(connectivity_data, "face_edge_is_reversed"));
+        }
+
+        if (connectivity_data.exist("item_ref_list")) {
+          HighFive::Group item_group = connectivity_data.getGroup("item_ref_list");
+          for (auto item_type_name : item_group.listObjectNames()) {
+            HighFive::Group item_ref_name_list = item_group.getGroup(item_type_name);
+
+            for (auto item_ref_list_name : item_ref_name_list.listObjectNames()) {
+              HighFive::Group item_ref_list_data = item_ref_name_list.getGroup(item_ref_list_name);
+
+              RefId ref_id(item_ref_list_data.getAttribute("tag_number").read<uint64_t>(),
+                           item_ref_list_data.getAttribute("tag_name").read<std::string>());
+
+              RefItemListBase::Type ref_item_list_type =
+                item_ref_list_data.getAttribute("type").read<RefItemListBase::Type>();
+
+              if (item_type_name == "cell") {
+                descriptor.addRefItemList(RefItemList<ItemType::cell>{ref_id,
+                                                                      readArray<CellId>(item_ref_list_data, "list"),
+                                                                      ref_item_list_type});
+              } else if (item_type_name == "face") {
+                descriptor.addRefItemList(RefItemList<ItemType::face>{ref_id,
+                                                                      readArray<FaceId>(item_ref_list_data, "list"),
+                                                                      ref_item_list_type});
+              } else if (item_type_name == "edge") {
+                descriptor.addRefItemList(RefItemList<ItemType::edge>{ref_id,
+                                                                      readArray<EdgeId>(item_ref_list_data, "list"),
+                                                                      ref_item_list_type});
+              } else if (item_type_name == "node") {
+                descriptor.addRefItemList(RefItemList<ItemType::node>{ref_id,
+                                                                      readArray<NodeId>(item_ref_list_data, "list"),
+                                                                      ref_item_list_type});
+              } else {
+                throw UnexpectedError("invalid item type: " + item_type_name);
+              }
             }
           }
         }
-      }
 
-      while (id > GlobalVariableManager::instance().getConnectivityId()) {
-        GlobalVariableManager::instance().getAndIncrementConnectivityId();
-      }
+        switch (dimension) {
+        case 1: {
+          m_id_to_iconnectivity_map.insert({id, Connectivity<1>::build(descriptor)});
+          break;
+        }
+        case 2: {
+          m_id_to_iconnectivity_map.insert({id, Connectivity<2>::build(descriptor)});
+          break;
+        }
+        case 3: {
+          m_id_to_iconnectivity_map.insert({id, Connectivity<3>::build(descriptor)});
+          break;
+        }
+        default: {
+          throw UnexpectedError("invalid dimension " + std::to_string(dimension));
+        }
+        }
+      } else if (type == "dual_connectivity") {
+        const DualMeshType type_of_dual     = connectivity_data.getAttribute("type_of_dual").read<DualMeshType>();
+        const size_t primal_connectivity_id = connectivity_data.getAttribute("primal_connectivity_id").read<size_t>();
 
-      if (m_id_to_iconnectivity_map.contains(id)) {
-        throw UnexpectedError("connectivity of id " + std::to_string(id) + " already defined!");
-      }
+        std::cout << "reading " << id << " " << ::name(type_of_dual) << " of " << primal_connectivity_id << '\n';
 
-      switch (dimension) {
-      case 1: {
-        m_id_to_iconnectivity_map.insert({id, Connectivity<1>::build(descriptor)});
-        break;
-      }
-      case 2: {
-        m_id_to_iconnectivity_map.insert({id, Connectivity<2>::build(descriptor)});
-        break;
-      }
-      case 3: {
-        m_id_to_iconnectivity_map.insert({id, Connectivity<3>::build(descriptor)});
-        break;
-      }
-      default: {
-        throw UnexpectedError("invalid dimension " + std::to_string(dimension));
-      }
+        std::shared_ptr<const IConnectivity> iprimal_connectivity =
+          m_id_to_iconnectivity_map.at(primal_connectivity_id);
+
+        switch (iprimal_connectivity->dimension()) {
+        case 1: {
+          if (type_of_dual != DualMeshType::Dual1D) {
+            throw UnexpectedError("unexpected dual mesh type");
+          }
+
+          const Connectivity<1>& primal_connectivity = dynamic_cast<const Connectivity<1>&>(*iprimal_connectivity);
+          m_id_to_iconnectivity_map.insert(
+            {id, DualConnectivityManager::instance().getDual1DConnectivity(primal_connectivity)});
+          break;
+        }
+        case 2: {
+          const Connectivity<2>& primal_connectivity = dynamic_cast<const Connectivity<2>&>(*iprimal_connectivity);
+
+          if (type_of_dual == DualMeshType::Diamond) {
+            m_id_to_iconnectivity_map.insert(
+              {id, DualConnectivityManager::instance().getDiamondDualConnectivity(primal_connectivity)});
+          } else if (type_of_dual == DualMeshType::Median) {
+            m_id_to_iconnectivity_map.insert(
+              {id, DualConnectivityManager::instance().getMedianDualConnectivity(primal_connectivity)});
+          } else {
+            throw UnexpectedError("unexpected dual mesh type");
+          }
+          break;
+        }
+        case 3: {
+          const Connectivity<3>& primal_connectivity = dynamic_cast<const Connectivity<3>&>(*iprimal_connectivity);
+
+          if (type_of_dual == DualMeshType::Diamond) {
+            m_id_to_iconnectivity_map.insert(
+              {id, DualConnectivityManager::instance().getDiamondDualConnectivity(primal_connectivity)});
+          } else if (type_of_dual == DualMeshType::Median) {
+            m_id_to_iconnectivity_map.insert(
+              {id, DualConnectivityManager::instance().getMedianDualConnectivity(primal_connectivity)});
+          } else {
+            throw UnexpectedError("unexpected dual mesh type");
+          }
+          break;
+        }
+        default: {
+          throw UnexpectedError("unexpected dimension");
+        }
+        }
+      } else {
+        throw UnexpectedError("invalid connectivity type: " + type);
       }
     }
   }