diff --git a/src/mesh/DualMeshManager.hpp b/src/mesh/DualMeshManager.hpp
index 46ad9c9f8d62cbff40a7d33efcc72c02e79f1ac7..201b0e663835cad99fca62551319024763488dc9 100644
--- a/src/mesh/DualMeshManager.hpp
+++ b/src/mesh/DualMeshManager.hpp
@@ -34,6 +34,12 @@ class DualMeshManager
   ~DualMeshManager() = default;
 
  public:
+  const auto&
+  primalToDualMeshMap() const
+  {
+    return m_mesh_to_dual_mesh_map;
+  }
+
   static void create();
   static void destroy();
 
diff --git a/src/utils/checkpointing/Checkpoint.cpp b/src/utils/checkpointing/Checkpoint.cpp
index dbd10ca634f3a14aec59787f74e4b498f44e5ed3..5946e10e2f84f49ad29581522e660e16fd7cc37c 100644
--- a/src/utils/checkpointing/Checkpoint.cpp
+++ b/src/utils/checkpointing/Checkpoint.cpp
@@ -122,8 +122,20 @@ checkpoint()
         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';
+    }
+    {
+      const auto& primal_to_dual_mesh_info_map = DualMeshManager::instance().primalToDualMeshMap();
+      for (auto&& primal_to_dual_mesh_info : primal_to_dual_mesh_info_map) {
+        const DualMeshType type_of_dual = primal_to_dual_mesh_info.first.first;
+        const size_t primal_mesh_id     = primal_to_dual_mesh_info.first.second;
+        const size_t dual_mesh_id       = primal_to_dual_mesh_info.second->id();
+
+        HighFive::Group connectivity_group = checkpoint.createGroup("mesh/" + std::to_string(dual_mesh_id));
+        connectivity_group.createAttribute("type", std::string{"dual_mesh"});
+        connectivity_group.createAttribute("type_of_dual", type_of_dual);
+        connectivity_group.createAttribute("id", dual_mesh_id);
+        connectivity_group.createAttribute("primal_mesh_id", primal_mesh_id);
+      }
     }
 
     std::shared_ptr<const SymbolTable> p_symbol_table = ASTExecutionStack::getInstance().currentNode().m_symbol_table;
diff --git a/src/utils/checkpointing/Resume.cpp b/src/utils/checkpointing/Resume.cpp
index b5e65316112c1c41774c2bf00993aea3b301f6b3..b7ee29441743a35ecc30a3d9c56b20a0fc69e3c7 100644
--- a/src/utils/checkpointing/Resume.cpp
+++ b/src/utils/checkpointing/Resume.cpp
@@ -91,9 +91,6 @@ resume()
       default_options.method()  = linear_solver_options_default_group.getAttribute("method").read<LSMethod>();
       default_options.precond() = linear_solver_options_default_group.getAttribute("precond").read<LSPrecond>();
     }
-    {
-      std::cout << rang::fgB::magenta << "Resume DualMeshManager NIY" << rang::fg::reset << '\n';
-    }
 
     ResumingData::instance().readData(checkpoint, p_symbol_table);
 
diff --git a/src/utils/checkpointing/ResumingData.cpp b/src/utils/checkpointing/ResumingData.cpp
index a2d6c98b293d4927ccbcab08406926711f803914..d0e51c4a5ff81de59f633b7eaa58a3035fbad2eb 100644
--- a/src/utils/checkpointing/ResumingData.cpp
+++ b/src/utils/checkpointing/ResumingData.cpp
@@ -3,6 +3,7 @@
 #include <language/utils/SymbolTable.hpp>
 #include <mesh/ConnectivityDescriptor.hpp>
 #include <mesh/DualConnectivityManager.hpp>
+#include <mesh/DualMeshManager.hpp>
 #include <mesh/Mesh.hpp>
 #include <utils/Exceptions.hpp>
 #include <utils/checkpointing/DualMeshTypeHFType.hpp>
@@ -17,6 +18,8 @@ ResumingData::_getConnectivityList(const HighFive::Group& checkpoint)
   if (checkpoint.exist("connectivity")) {
     HighFive::Group connectivity_group = checkpoint.getGroup("connectivity");
 
+    // it is important to use a map here. "id"s must be treated in
+    // increasing order.
     std::map<size_t, std::string> id_name_map;
     for (auto connectivity_id_name : connectivity_group.listObjectNames()) {
       HighFive::Group connectivity_info = connectivity_group.getGroup(connectivity_id_name);
@@ -152,8 +155,6 @@ ResumingData::_getConnectivityList(const HighFive::Group& checkpoint)
         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>();
 
-        std::cout << "reading " << id << " " << ::name(type_of_dual) << " of " << primal_connectivity_id << '\n';
-
         std::shared_ptr<const IConnectivity> iprimal_connectivity =
           m_id_to_iconnectivity_map.at(primal_connectivity_id);
 
@@ -244,41 +245,77 @@ ResumingData::_getMeshVariantList(const HighFive::Group& checkpoint)
   if (checkpoint.exist("mesh")) {
     HighFive::Group mesh_group = checkpoint.getGroup("mesh");
 
+    // it is important to use a map here. "id"s must be treated in
+    // increasing order.
     std::map<size_t, std::string> id_name_map;
     for (auto mesh_id_name : mesh_group.listObjectNames()) {
       HighFive::Group mesh_info                                  = mesh_group.getGroup(mesh_id_name);
       id_name_map[mesh_info.getAttribute("id").read<uint64_t>()] = mesh_id_name;
     }
 
-    for (auto [id, name] : id_name_map) {
+    for (auto&& id_name : id_name_map) {
+      // workaround due to clang not handling correctly captures
+      const auto& id   = id_name.first;
+      const auto& name = id_name.second;
+
       HighFive::Group mesh_data = mesh_group.getGroup(name);
       const std::string type    = mesh_data.getAttribute("type").read<std::string>();
-      const uint64_t dimension  = mesh_data.getAttribute("dimension").read<uint64_t>();
-
-      if (type != "polygonal") {
-        throw UnexpectedError("invalid connectivity type");
-      }
 
       while (id > GlobalVariableManager::instance().getMeshId()) {
         GlobalVariableManager::instance().getAndIncrementMeshId();
       }
 
-      switch (dimension) {
-      case 1: {
-        m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<1>(mesh_data)});
-        break;
-      }
-      case 2: {
-        m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<2>(mesh_data)});
-        break;
-      }
-      case 3: {
-        m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<3>(mesh_data)});
-        break;
-      }
-      default: {
-        throw UnexpectedError("invalid mesh dimension " + std::to_string(dimension));
-      }
+      if (type == "polygonal") {
+        const uint64_t dimension = mesh_data.getAttribute("dimension").read<uint64_t>();
+
+        switch (dimension) {
+        case 1: {
+          m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<1>(mesh_data)});
+          break;
+        }
+        case 2: {
+          m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<2>(mesh_data)});
+          break;
+        }
+        case 3: {
+          m_id_to_mesh_variant_map.insert({id, this->_readPolygonalMesh<3>(mesh_data)});
+          break;
+        }
+        default: {
+          throw UnexpectedError("invalid mesh dimension " + std::to_string(dimension));
+        }
+        }
+      } else if (type == "dual_mesh") {
+        const DualMeshType type_of_dual = mesh_data.getAttribute("type_of_dual").read<DualMeshType>();
+        const size_t primal_mesh_id     = mesh_data.getAttribute("primal_mesh_id").read<size_t>();
+
+        std::shared_ptr<const MeshVariant> primal_mesh_variant = m_id_to_mesh_variant_map.at(primal_mesh_id);
+
+        std::visit(
+          [&](auto&& mesh) {
+            using MeshType = std::decay_t<decltype(*mesh)>;
+            if constexpr (std::is_same_v<MeshType, Mesh<1>>) {
+              if (type_of_dual == DualMeshType::Dual1D) {
+                m_id_to_mesh_variant_map.insert({id, DualMeshManager::instance().getDual1DMesh(primal_mesh_variant)});
+              } else {
+                throw UnexpectedError("unexpected dual mesh type");
+              }
+            } else if constexpr (std::is_same_v<MeshType, Mesh<2>> or std::is_same_v<MeshType, Mesh<3>>) {
+              if (type_of_dual == DualMeshType::Diamond) {
+                m_id_to_mesh_variant_map.insert(
+                  {id, DualMeshManager::instance().getDiamondDualMesh(primal_mesh_variant)});
+              } else if (type_of_dual == DualMeshType::Median) {
+                m_id_to_mesh_variant_map.insert(
+                  {id, DualMeshManager::instance().getMedianDualMesh(primal_mesh_variant)});
+              } else {
+                throw UnexpectedError("unexpected dual mesh type");
+              }
+            }
+          },
+          primal_mesh_variant->variant());
+
+      } else {
+        throw UnexpectedError("invalid mesh type");
       }
     }
   }
@@ -361,11 +398,11 @@ ResumingData::iConnectivity(const size_t connectivity_id) const
 const std::shared_ptr<const MeshVariant>&
 ResumingData::meshVariant(const size_t mesh_id) const
 {
-  auto i_id_to_connectivity = m_id_to_mesh_variant_map.find(mesh_id);
-  if (i_id_to_connectivity == m_id_to_mesh_variant_map.end()) {
-    throw UnexpectedError("cannot find connectivity of id " + std::to_string(mesh_id));
+  auto i_id_to_mesh = m_id_to_mesh_variant_map.find(mesh_id);
+  if (i_id_to_mesh == m_id_to_mesh_variant_map.end()) {
+    throw UnexpectedError("cannot find mesh of id " + std::to_string(mesh_id));
   } else {
-    return i_id_to_connectivity->second;
+    return i_id_to_mesh->second;
   }
 }