diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp
index 76581725b80642815fbac8ad9c8f88649a9a1d4c..7f7464879ba6c24ee855d47fe6792bef0a9bb8c8 100644
--- a/src/language/modules/SchemeModule.cpp
+++ b/src/language/modules/SchemeModule.cpp
@@ -689,6 +689,19 @@ SchemeModule::registerOperators() const
 void
 SchemeModule::registerCheckpointResume() const
 {
+  CheckpointResumeRepository::instance()
+    .addCheckpointResume(ast_node_data_type_from<std::shared_ptr<const DiscreteFunctionVariant>>,
+                         std::function([](const std::string& symbol_name, const EmbeddedData& embedded_data,
+                                          HighFive::File& file, HighFive::Group& checkpoint_group,
+                                          HighFive::Group& symbol_table_group) {
+                           writeDiscreteFunctionVariant(symbol_name, embedded_data, file, checkpoint_group,
+                                                        symbol_table_group);
+                         }),
+                         std::function([](const std::string& symbol_name,
+                                          const HighFive::Group& symbol_table_group) -> EmbeddedData {
+                           return readDiscreteFunctionVariant(symbol_name, symbol_table_group);
+                         }));
+
   CheckpointResumeRepository::instance()
     .addCheckpointResume(ast_node_data_type_from<std::shared_ptr<const IBoundaryConditionDescriptor>>,
                          std::function([](const std::string& symbol_name, const EmbeddedData& embedded_data,
diff --git a/src/utils/checkpointing/CheckpointUtils.cpp b/src/utils/checkpointing/CheckpointUtils.cpp
index afb542d7a9477d876751566396eb69b1e6b0839d..519b5a29cf805d4bb701ebb47cbefc892632d1d7 100644
--- a/src/utils/checkpointing/CheckpointUtils.cpp
+++ b/src/utils/checkpointing/CheckpointUtils.cpp
@@ -18,6 +18,7 @@
 #include <mesh/NumberedZoneDescriptor.hpp>
 #include <scheme/DiscreteFunctionP0.hpp>
 #include <scheme/DiscreteFunctionP0Vector.hpp>
+#include <scheme/DiscreteFunctionVariant.hpp>
 #include <scheme/IBoundaryConditionDescriptor.hpp>
 #include <utils/checkpointing/DiscreteFunctionTypeHFType.hpp>
 #include <utils/checkpointing/IBoundaryConditionDescriptorHFType.hpp>
@@ -409,20 +410,8 @@ writeIZoneDescriptor(const std::string& symbol_name,
 }
 
 void
-writeMesh(const std::string& symbol_name,
-          const EmbeddedData& embedded_data,
-          HighFive::File& file,
-          HighFive::Group& checkpoint_group,
-          HighFive::Group& symbol_table_group)
+writeMesh(std::shared_ptr<const MeshVariant> mesh_v, HighFive::File& file, HighFive::Group& checkpoint_group)
 {
-  HighFive::Group variable_group = symbol_table_group.createGroup("embedded/" + symbol_name);
-
-  std::shared_ptr<const MeshVariant> mesh_v =
-    dynamic_cast<const DataHandler<const MeshVariant>&>(embedded_data.get()).data_ptr();
-
-  variable_group.createAttribute("type", dataTypeName(ast_node_data_type_from<decltype(mesh_v)>));
-  variable_group.createAttribute("id", mesh_v->id());
-
   std::string mesh_group_name = "mesh/" + std::to_string(mesh_v->id());
   if (not checkpoint_group.exist(mesh_group_name)) {
     bool linked = false;
@@ -463,6 +452,61 @@ writeMesh(const std::string& symbol_name,
     mesh_v->variant());
 }
 
+void
+writeMesh(const std::string& symbol_name,
+          const EmbeddedData& embedded_data,
+          HighFive::File& file,
+          HighFive::Group& checkpoint_group,
+          HighFive::Group& symbol_table_group)
+{
+  HighFive::Group variable_group = symbol_table_group.createGroup("embedded/" + symbol_name);
+
+  std::shared_ptr<const MeshVariant> mesh_v =
+    dynamic_cast<const DataHandler<const MeshVariant>&>(embedded_data.get()).data_ptr();
+
+  variable_group.createAttribute("type", dataTypeName(ast_node_data_type_from<decltype(mesh_v)>));
+  variable_group.createAttribute("id", mesh_v->id());
+
+  writeMesh(mesh_v, file, checkpoint_group);
+}
+
+void
+writeDiscreteFunctionVariant(const std::string& symbol_name,
+                             const EmbeddedData& embedded_data,
+                             HighFive::File& file,
+                             HighFive::Group& checkpoint_group,
+                             HighFive::Group& symbol_table_group)
+{
+  HighFive::Group variable_group = symbol_table_group.createGroup("embedded/" + symbol_name);
+
+  std::shared_ptr<const DiscreteFunctionVariant> discrete_function_v =
+    dynamic_cast<const DataHandler<const DiscreteFunctionVariant>&>(embedded_data.get()).data_ptr();
+
+  variable_group.createAttribute("type", dataTypeName(ast_node_data_type_from<decltype(discrete_function_v)>));
+
+  std::visit(
+    [&](auto&& discrete_function) {
+      auto mesh_v  = discrete_function.meshVariant();
+      using DFType = std::decay_t<decltype(discrete_function)>;
+      variable_group.createAttribute("Vh_type", discrete_function.descriptor().type());
+
+      variable_group.createAttribute("mesh_id", mesh_v->id());
+      writeMesh(mesh_v, file, checkpoint_group);
+      if constexpr (is_discrete_function_P0_v<DFType>) {
+        using data_type = std::decay_t<typename DFType::data_type>;
+        // variable_group.createAttribute("Vh_type", "P0");
+        variable_group.createAttribute("data_type", dataTypeName(ast_node_data_type_from<data_type>));
+        write(variable_group, "values", discrete_function.cellValues());
+      } else if constexpr (is_discrete_function_P0_vector_v<DFType>) {
+        using data_type = std::decay_t<typename DFType::data_type>;
+        // variable_group.createAttribute("Vh_type", "P0Vector");
+        variable_group.createAttribute("data_type", dataTypeName(ast_node_data_type_from<data_type>));
+        //        write(variable_group, "values", discrete_function.cellArrays());
+      }
+    },
+    discrete_function_v->discreteFunction());
+}
+
 void
 writeOStream(const std::string& symbol_name,
              const EmbeddedData& embedded_data,
diff --git a/src/utils/checkpointing/CheckpointUtils.hpp b/src/utils/checkpointing/CheckpointUtils.hpp
index 0870184203c36bce615818d138cf29ff3e215ed3..5a5fe066d9bd457cb603ae8c3f4af9cf800e6dea 100644
--- a/src/utils/checkpointing/CheckpointUtils.hpp
+++ b/src/utils/checkpointing/CheckpointUtils.hpp
@@ -42,6 +42,12 @@ write(HighFive::Group& group,
   write(group, name, item_value.arrayView());
 }
 
+void writeDiscreteFunctionVariant(const std::string& symbol_name,
+                                  const EmbeddedData& embedded_data,
+                                  HighFive::File& file,
+                                  HighFive::Group& checkpoint_group,
+                                  HighFive::Group& symbol_table_group);
+
 void writeIBoundaryConditionDescriptor(const std::string& symbol_name,
                                        const EmbeddedData& embedded_data,
                                        HighFive::File& file,
diff --git a/src/utils/checkpointing/ResumeUtils.cpp b/src/utils/checkpointing/ResumeUtils.cpp
index 125fe1f9c753f8038e013a12ab334d560d24a147..367372bd4ba3469847f6db88b60320279ee223d1 100644
--- a/src/utils/checkpointing/ResumeUtils.cpp
+++ b/src/utils/checkpointing/ResumeUtils.cpp
@@ -12,9 +12,21 @@
 #include <mesh/NumberedBoundaryDescriptor.hpp>
 #include <mesh/NumberedInterfaceDescriptor.hpp>
 #include <mesh/NumberedZoneDescriptor.hpp>
+#include <scheme/AxisBoundaryConditionDescriptor.hpp>
+#include <scheme/DirichletBoundaryConditionDescriptor.hpp>
 #include <scheme/DiscreteFunctionDescriptorP0.hpp>
 #include <scheme/DiscreteFunctionDescriptorP0Vector.hpp>
+#include <scheme/DiscreteFunctionP0.hpp>
+#include <scheme/DiscreteFunctionVariant.hpp>
+#include <scheme/ExternalBoundaryConditionDescriptor.hpp>
+#include <scheme/FixedBoundaryConditionDescriptor.hpp>
+#include <scheme/FourierBoundaryConditionDescriptor.hpp>
+#include <scheme/FreeBoundaryConditionDescriptor.hpp>
 #include <scheme/IBoundaryConditionDescriptor.hpp>
+#include <scheme/InflowBoundaryConditionDescriptor.hpp>
+#include <scheme/NeumannBoundaryConditionDescriptor.hpp>
+#include <scheme/OutflowBoundaryConditionDescriptor.hpp>
+#include <scheme/SymmetryBoundaryConditionDescriptor.hpp>
 #include <utils/checkpointing/DiscreteFunctionTypeHFType.hpp>
 #include <utils/checkpointing/IBoundaryConditionDescriptorHFType.hpp>
 #include <utils/checkpointing/IBoundaryDescriptorHFType.hpp>
@@ -25,16 +37,19 @@
 #include <utils/checkpointing/QuadratureTypeHFType.hpp>
 #include <utils/checkpointing/ResumingData.hpp>
 
-#include <scheme/AxisBoundaryConditionDescriptor.hpp>
-#include <scheme/DirichletBoundaryConditionDescriptor.hpp>
-#include <scheme/ExternalBoundaryConditionDescriptor.hpp>
-#include <scheme/FixedBoundaryConditionDescriptor.hpp>
-#include <scheme/FourierBoundaryConditionDescriptor.hpp>
-#include <scheme/FreeBoundaryConditionDescriptor.hpp>
-#include <scheme/InflowBoundaryConditionDescriptor.hpp>
-#include <scheme/NeumannBoundaryConditionDescriptor.hpp>
-#include <scheme/OutflowBoundaryConditionDescriptor.hpp>
-#include <scheme/SymmetryBoundaryConditionDescriptor.hpp>
+template <typename T, ItemType item_type>
+ItemValue<T, item_type>
+readItemValue(const HighFive::Group& group, const std::string& name, const IConnectivity& connectivity)
+{
+  return {connectivity, readArray<T>(group, name)};
+}
+
+template <typename T, ItemType item_type>
+ItemArray<T, item_type>
+readItemArray(const HighFive::Group& group, const std::string& name, const IConnectivity& connectivity)
+{
+  return {connectivity, readTable<T>(group, name)};
+}
 
 std::shared_ptr<const IBoundaryDescriptor>
 readIBoundaryDescriptor(const HighFive::Group& iboundarydescriptor_group)
@@ -269,6 +284,81 @@ readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_gro
   return {std::make_shared<DataHandler<const MeshVariant>>(ResumingData::instance().meshVariant(mesh_id))};
 }
 
+EmbeddedData
+readDiscreteFunctionVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group discrete_function_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+  DiscreteFunctionType type = discrete_function_group.getAttribute("Vh_type").read<DiscreteFunctionType>();
+  size_t mesh_id            = discrete_function_group.getAttribute("mesh_id").read<size_t>();
+
+  std::shared_ptr<const MeshVariant> mesh_v = ResumingData::instance().meshVariant(mesh_id);
+
+  const std::string data_type = discrete_function_group.getAttribute("data_type").read<std::string>();
+
+  std::shared_ptr<DiscreteFunctionVariant> p_discrete_function;
+  switch (type) {
+  case DiscreteFunctionType::P0: {
+    if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const double>(mesh_v,
+                                         readItemValue<double, ItemType::cell>(discrete_function_group, "values",
+                                                                               mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<1>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyVector<1>>(mesh_v,
+                                                readItemValue<TinyVector<1>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<2>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyVector<2>>(mesh_v,
+                                                readItemValue<TinyVector<2>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<3>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyVector<3>>(mesh_v,
+                                                readItemValue<TinyVector<3>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<1>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyMatrix<1>>(mesh_v,
+                                                readItemValue<TinyMatrix<1>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<2>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyMatrix<2>>(mesh_v,
+                                                readItemValue<TinyMatrix<2>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<3>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyMatrix<3>>(mesh_v,
+                                                readItemValue<TinyMatrix<3>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else {
+      throw UnexpectedError("unexpected discrete function data type: " + data_type);
+    }
+    break;
+  }
+  case DiscreteFunctionType::P0Vector: {
+    if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0Vector<const double>(mesh_v,
+                                               readItemArray<double, ItemType::cell>(discrete_function_group, "values",
+                                                                                     mesh_v->connectivity())));
+    } else {
+      throw UnexpectedError("unexpected discrete function vector data type: " + data_type);
+    }
+    break;
+  }
+  }
+  return {std::make_shared<DataHandler<const DiscreteFunctionVariant>>(p_discrete_function)};
+}
+
 EmbeddedData
 readOStream(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
 {
diff --git a/src/utils/checkpointing/ResumeUtils.hpp b/src/utils/checkpointing/ResumeUtils.hpp
index c66f48207eaf073f5b5ab09f66c5715837f0de82..1ade7973f9c09d3c9bfca4c374958f947a96e2fb 100644
--- a/src/utils/checkpointing/ResumeUtils.hpp
+++ b/src/utils/checkpointing/ResumeUtils.hpp
@@ -5,11 +5,12 @@
 
 #include <language/utils/SymbolTable.hpp>
 #include <mesh/CellType.hpp>
+#include <mesh/ItemArray.hpp>
 #include <mesh/ItemValue.hpp>
 
 template <typename DataType>
 PUGS_INLINE Array<DataType>
-read(const HighFive::Group& group, const std::string& name)
+readArray(const HighFive::Group& group, const std::string& name)
 {
   using data_type = std::remove_const_t<DataType>;
 
@@ -28,6 +29,28 @@ read(const HighFive::Group& group, const std::string& name)
   return array;
 }
 
+template <typename DataType>
+PUGS_INLINE Table<DataType>
+readTable(const HighFive::Group& group, const std::string& name)
+{
+  using data_type = std::remove_const_t<DataType>;
+
+  auto dataset = group.getDataSet(name);
+  Table<DataType> table(dataset.getDimensions()[0], dataset.getDimensions()[1]);
+  if constexpr (std::is_same_v<CellType, data_type>) {
+    dataset.template read<short>(reinterpret_cast<short*>(&(table(0, 0))));
+  } else if constexpr ((std::is_same_v<CellId, data_type>) or (std::is_same_v<FaceId, data_type>) or
+                       (std::is_same_v<EdgeId, data_type>) or (std::is_same_v<NodeId, data_type>)) {
+    using base_type = typename data_type::base_type;
+    dataset.template read<base_type>(reinterpret_cast<base_type*>(&(table(0, 0))));
+  } else {
+    dataset.template read<data_type>(&(table(0, 0)));
+  }
+
+  return table;
+}
+
+EmbeddedData readDiscreteFunctionVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
 EmbeddedData readIBoundaryConditionDescriptor(const std::string& symbol_name,
                                               const HighFive::Group& symbol_table_group);
 EmbeddedData readIBoundaryDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
diff --git a/src/utils/checkpointing/ResumingData.cpp b/src/utils/checkpointing/ResumingData.cpp
index 5743e98fd04185018b67a2f40ffb6f85caa7b70d..86dd4428919dce9e6cc6b1dfbf1dd735b527bb89 100644
--- a/src/utils/checkpointing/ResumingData.cpp
+++ b/src/utils/checkpointing/ResumingData.cpp
@@ -31,59 +31,59 @@ ResumingData::_getConnectivityList(const HighFive::Group& checkpoint)
       }
 
       ConnectivityDescriptor descriptor;
-      descriptor.setCellTypeVector(read<CellType>(connectivity_data, "cell_type"));
-      descriptor.setCellNumberVector(read<int>(connectivity_data, "cell_numbers"));
-      descriptor.setNodeNumberVector(read<int>(connectivity_data, "node_numbers"));
+      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.setCellOwnerVector(read<int>(connectivity_data, "cell_owner"));
-      descriptor.setNodeOwnerVector(read<int>(connectivity_data, "node_owner"));
+      descriptor.setCellOwnerVector(readArray<int>(connectivity_data, "cell_owner"));
+      descriptor.setNodeOwnerVector(readArray<int>(connectivity_data, "node_owner"));
 
       using index_type = typename ConnectivityMatrix::IndexType;
 
       descriptor.setCellToNodeMatrix(
-        ConnectivityMatrix{read<index_type>(connectivity_data, "cell_to_node_matrix_rowsMap"),
-                           read<index_type>(connectivity_data, "cell_to_node_matrix_values")});
+        ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_node_matrix_rowsMap"),
+                           readArray<index_type>(connectivity_data, "cell_to_node_matrix_values")});
 
       if (dimension > 1) {
-        descriptor.setFaceNumberVector(read<int>(connectivity_data, "face_numbers"));
-        descriptor.setFaceOwnerVector(read<int>(connectivity_data, "face_owner"));
+        descriptor.setFaceNumberVector(readArray<int>(connectivity_data, "face_numbers"));
+        descriptor.setFaceOwnerVector(readArray<int>(connectivity_data, "face_owner"));
 
         descriptor.setCellToFaceMatrix(
-          ConnectivityMatrix{read<index_type>(connectivity_data, "cell_to_face_matrix_rowsMap"),
-                             read<index_type>(connectivity_data, "cell_to_face_matrix_values")});
+          ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_face_matrix_rowsMap"),
+                             readArray<index_type>(connectivity_data, "cell_to_face_matrix_values")});
 
         descriptor.setFaceToNodeMatrix(
-          ConnectivityMatrix{read<index_type>(connectivity_data, "face_to_node_matrix_rowsMap"),
-                             read<index_type>(connectivity_data, "face_to_node_matrix_values")});
+          ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_node_matrix_rowsMap"),
+                             readArray<index_type>(connectivity_data, "face_to_node_matrix_values")});
 
         descriptor.setNodeToFaceMatrix(
-          ConnectivityMatrix{read<index_type>(connectivity_data, "node_to_face_matrix_rowsMap"),
-                             read<index_type>(connectivity_data, "node_to_face_matrix_values")});
+          ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_face_matrix_rowsMap"),
+                             readArray<index_type>(connectivity_data, "node_to_face_matrix_values")});
 
-        descriptor.setCellFaceIsReversed(read<bool>(connectivity_data, "cell_face_is_reversed"));
+        descriptor.setCellFaceIsReversed(readArray<bool>(connectivity_data, "cell_face_is_reversed"));
       }
 
       if (dimension > 2) {
-        descriptor.setEdgeNumberVector(read<int>(connectivity_data, "edge_numbers"));
-        descriptor.setEdgeOwnerVector(read<int>(connectivity_data, "edge_owner"));
+        descriptor.setEdgeNumberVector(readArray<int>(connectivity_data, "edge_numbers"));
+        descriptor.setEdgeOwnerVector(readArray<int>(connectivity_data, "edge_owner"));
 
         descriptor.setCellToEdgeMatrix(
-          ConnectivityMatrix{read<index_type>(connectivity_data, "cell_to_edge_matrix_rowsMap"),
-                             read<index_type>(connectivity_data, "cell_to_edge_matrix_values")});
+          ConnectivityMatrix{readArray<index_type>(connectivity_data, "cell_to_edge_matrix_rowsMap"),
+                             readArray<index_type>(connectivity_data, "cell_to_edge_matrix_values")});
 
         descriptor.setFaceToEdgeMatrix(
-          ConnectivityMatrix{read<index_type>(connectivity_data, "face_to_edge_matrix_rowsMap"),
-                             read<index_type>(connectivity_data, "face_to_edge_matrix_values")});
+          ConnectivityMatrix{readArray<index_type>(connectivity_data, "face_to_edge_matrix_rowsMap"),
+                             readArray<index_type>(connectivity_data, "face_to_edge_matrix_values")});
 
         descriptor.setEdgeToNodeMatrix(
-          ConnectivityMatrix{read<index_type>(connectivity_data, "edge_to_node_matrix_rowsMap"),
-                             read<index_type>(connectivity_data, "edge_to_node_matrix_values")});
+          ConnectivityMatrix{readArray<index_type>(connectivity_data, "edge_to_node_matrix_rowsMap"),
+                             readArray<index_type>(connectivity_data, "edge_to_node_matrix_values")});
 
         descriptor.setNodeToEdgeMatrix(
-          ConnectivityMatrix{read<index_type>(connectivity_data, "node_to_edge_matrix_rowsMap"),
-                             read<index_type>(connectivity_data, "node_to_edge_matrix_values")});
+          ConnectivityMatrix{readArray<index_type>(connectivity_data, "node_to_edge_matrix_rowsMap"),
+                             readArray<index_type>(connectivity_data, "node_to_edge_matrix_values")});
 
-        descriptor.setFaceEdgeIsReversed(read<bool>(connectivity_data, "face_edge_is_reversed"));
+        descriptor.setFaceEdgeIsReversed(readArray<bool>(connectivity_data, "face_edge_is_reversed"));
       }
 
       if (connectivity_data.exist("item_ref_list")) {
@@ -102,16 +102,16 @@ ResumingData::_getConnectivityList(const HighFive::Group& checkpoint)
 
             if (item_type_name == "cell") {
               descriptor.addRefItemList(
-                RefItemList<ItemType::cell>{ref_id, read<CellId>(item_ref_list_data, "list"), ref_item_list_type});
+                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, read<FaceId>(item_ref_list_data, "list"), ref_item_list_type});
+                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, read<EdgeId>(item_ref_list_data, "list"), ref_item_list_type});
+                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, read<NodeId>(item_ref_list_data, "list"), ref_item_list_type});
+                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);
             }
@@ -172,7 +172,7 @@ ResumingData::_readPolygonalMesh(const HighFive::Group& mesh_data)
   std::shared_ptr<const Connectivity<Dimension>> connectivity =
     std::dynamic_pointer_cast<const Connectivity<Dimension>>(i_connectivity);
 
-  Array<const TinyVector<Dimension>> xr_array = read<TinyVector<Dimension>>(mesh_data, "xr");
+  Array<const TinyVector<Dimension>> xr_array = readArray<TinyVector<Dimension>>(mesh_data, "xr");
   NodeValue<const TinyVector<Dimension>> xr{*connectivity, xr_array};
 
   std::shared_ptr mesh = std::make_shared<const Mesh<Dimension>>(connectivity, xr);