diff --git a/src/dev/ParallelChecker.hpp b/src/dev/ParallelChecker.hpp
index 91b4bc1ab39907d681123387a016086fa3c1ca0e..97729f38a9f5d31356919bcb757b4e120accc38d 100644
--- a/src/dev/ParallelChecker.hpp
+++ b/src/dev/ParallelChecker.hpp
@@ -292,6 +292,31 @@ class ParallelChecker
     }
   }
 
+  template <ItemType item_type, ItemType sub_item_type>
+  Array<const typename ConnectivityMatrix::IndexType>
+  _getSubItemValues(const std::shared_ptr<const IConnectivity>& i_connectivity)
+  {
+    switch (i_connectivity->dimension()) {
+    case 1: {
+      const Connectivity<1>& connectivity = dynamic_cast<const Connectivity<1>&>(*i_connectivity);
+      return connectivity.getMatrix(item_type, sub_item_type).values();
+    }
+    case 2: {
+      const Connectivity<2>& connectivity = dynamic_cast<const Connectivity<2>&>(*i_connectivity);
+      return connectivity.getMatrix(item_type, sub_item_type).values();
+    }
+    case 3: {
+      const Connectivity<3>& connectivity = dynamic_cast<const Connectivity<3>&>(*i_connectivity);
+      return connectivity.getMatrix(item_type, sub_item_type).values();
+    }
+      // LCOV_EXCL_START
+    default: {
+      throw UnexpectedError("unexpected connectivity dimension");
+    }
+      // LCOV_EXCL_STOP
+    }
+  }
+
   template <ItemType item_type>
   Array<const int>
   _getItemOwner(const std::shared_ptr<const IConnectivity>& i_connectivity) const
@@ -371,14 +396,14 @@ class ParallelChecker
     }
 
     HighFive::DataSet item_numbers = file.getDataSet(item_number_path + "/numbers");
-    group.createHardLink("numbers", item_numbers);
+    group.createHardLink(std::string(itemName(item_type)) + "_numbers", item_numbers);
   }
 
   template <typename ItemOfItem>
   void
-  _writeSubItemRowsMap(const std::shared_ptr<const IConnectivity> i_connectivity,
-                       HighFive::File file,
-                       HighFive::Group group)
+  _writeSubItemMatrix(const std::shared_ptr<const IConnectivity> i_connectivity,
+                      HighFive::File file,
+                      HighFive::Group group)
   {
     constexpr ItemType item_type     = ItemOfItem::item_type;
     constexpr ItemType sub_item_type = ItemOfItem::sub_item_type;
@@ -391,10 +416,14 @@ class ParallelChecker
       HighFive::Group subitem_of_item_row_map_group = file.createGroup(subitem_of_item_row_map_path);
       this->_writeArray(subitem_of_item_row_map_group, "rows_map",
                         this->_getSubItemRowsMap<item_type, sub_item_type>(i_connectivity));
+      this->_writeArray(subitem_of_item_row_map_group, "sub_item_index",
+                        this->_getSubItemValues<item_type, sub_item_type>(i_connectivity));
     }
 
     HighFive::DataSet subitem_of_item_row_map = file.getDataSet(subitem_of_item_row_map_path + "/rows_map");
     group.createHardLink("rows_map", subitem_of_item_row_map);
+    HighFive::DataSet subitem_of_item_index = file.getDataSet(subitem_of_item_row_map_path + "/sub_item_index");
+    group.createHardLink("sub_item_index", subitem_of_item_index);
   }
 
   template <typename DataType, ItemType item_type>
@@ -640,7 +669,8 @@ class ParallelChecker
       this->_writeArray(group, name, subitem_value_per_item.arrayView());
 
       this->_writeItemNumbers<item_type>(i_connectivity, file, group);
-      this->_writeSubItemRowsMap<ItemOfItem>(i_connectivity, file, group);
+      this->_writeItemNumbers<sub_item_type>(i_connectivity, file, group);
+      this->_writeSubItemMatrix<ItemOfItem>(i_connectivity, file, group);
 
       ++m_tag;
 
@@ -685,7 +715,8 @@ class ParallelChecker
       this->_writeTable(group, name, subitem_value_per_item.tableView());
 
       this->_writeItemNumbers<item_type>(i_connectivity, file, group);
-      this->_writeSubItemRowsMap<ItemOfItem>(i_connectivity, file, group);
+      this->_writeItemNumbers<sub_item_type>(i_connectivity, file, group);
+      this->_writeSubItemMatrix<ItemOfItem>(i_connectivity, file, group);
 
       ++m_tag;
 
@@ -720,7 +751,8 @@ class ParallelChecker
                                                        std::vector<size_t>{item_value.numberOfItems()}, i_connectivity,
                                                        group);
 
-      Array<const int> reference_item_numbers    = this->_readArray<int>(group, "numbers");
+      Array<const int> reference_item_numbers =
+        this->_readArray<int>(group, std::string{itemName(item_type)} + "_numbers");
       Array<const DataType> reference_item_value = this->_readArray<DataType>(group, reference_name);
 
       Array<const int> item_numbers = this->_getItemNumber<item_type>(i_connectivity);
@@ -846,7 +878,8 @@ class ParallelChecker
                                                                            item_array.sizeOfArrays()},
                                                        i_connectivity, group);
 
-      Array<const int> reference_item_numbers    = this->_readArray<int>(group, "numbers");
+      Array<const int> reference_item_numbers =
+        this->_readArray<int>(group, std::string{itemName(item_type)} + "_numbers");
       Table<const DataType> reference_item_array = this->_readTable<DataType>(group, reference_name);
 
       Array<const int> item_numbers = this->_getItemNumber<item_type>(i_connectivity);
@@ -980,12 +1013,17 @@ class ParallelChecker
       constexpr ItemType sub_item_type = ItemOfItem::sub_item_type;
       using IndexType                  = typename ConnectivityMatrix::IndexType;
 
-      Array<const int> reference_item_numbers           = this->_readArray<int>(group, "numbers");
+      Array<const int> reference_item_numbers =
+        this->_readArray<int>(group, std::string{itemName(item_type)} + "_numbers");
+      Array<const int> reference_sub_item_numbers =
+        this->_readArray<int>(group, std::string{itemName(sub_item_type)} + "_numbers");
       Array<const IndexType> reference_subitem_rows_map = this->_readArray<IndexType>(group, "rows_map");
+      Array<const IndexType> reference_subitem_index    = this->_readArray<IndexType>(group, "sub_item_index");
 
       Array<const DataType> reference_subitem_value_per_item = this->_readArray<DataType>(group, reference_name);
 
       Array<const int> item_numbers           = this->_getItemNumber<item_type>(i_connectivity);
+      Array<const int> sub_item_numbers       = this->_getItemNumber<sub_item_type>(i_connectivity);
       Array<const IndexType> sub_item_row_map = this->_getSubItemRowsMap<item_type, sub_item_type>(i_connectivity);
 
       using ItemId = ItemIdT<item_type>;
@@ -1019,6 +1057,8 @@ class ParallelChecker
       }
       this->_checkGlobalNumberOfItems<item_type>(i_connectivity, reference_item_numbers.size());
 
+      auto item_to_sub_item_matrix = i_connectivity->getMatrix(item_type, sub_item_type);
+
       Array<const int> owner = this->_getItemOwner<item_type>(i_connectivity);
 
       bool has_own_differences = false;
@@ -1030,12 +1070,29 @@ class ParallelChecker
         const size_t index_end_in_reference   = reference_subitem_rows_map[reference_item_index + 1];
 
         bool item_is_same = true;
-        if ((index_end_in_reference - index_begin_in_reference) != subitem_value_per_item[item_id].size()) {
-          item_is_same = false;
+
+        if ((item_type > sub_item_type) or (static_cast<size_t>(owner[item_id]) == parallel::rank())) {
+          if ((index_end_in_reference - index_begin_in_reference) != subitem_value_per_item[item_id].size()) {
+            item_is_same = false;
+          } else {
+            for (size_t i_sub_item = 0; i_sub_item < subitem_value_per_item[item_id].size(); ++i_sub_item) {
+              if (reference_subitem_value_per_item[index_begin_in_reference + i_sub_item] !=
+                  subitem_value_per_item[item_id][i_sub_item]) {
+                item_is_same = false;
+              }
+            }
+          }
         } else {
-          for (size_t i_sub_item = 0; i_sub_item < subitem_value_per_item[item_id].size(); ++i_sub_item) {
-            if (reference_subitem_value_per_item[index_begin_in_reference + i_sub_item] !=
-                subitem_value_per_item[item_id][i_sub_item]) {
+          std::map<int, size_t> sub_item_number_to_index;
+          for (size_t index = index_begin_in_reference; index < index_end_in_reference; ++index) {
+            sub_item_number_to_index[reference_sub_item_numbers[reference_subitem_index[index]]] = index;
+          }
+
+          auto sub_item_list = item_to_sub_item_matrix[item_id];
+          for (size_t i_sub_item = 0; i_sub_item < sub_item_list.size(); ++i_sub_item) {
+            auto sub_item_id = sub_item_list[i_sub_item];
+            auto index       = sub_item_number_to_index.at(sub_item_numbers[sub_item_id]);
+            if (reference_subitem_value_per_item[index] != subitem_value_per_item[item_id][i_sub_item]) {
               item_is_same = false;
             }
           }
@@ -1147,12 +1204,17 @@ class ParallelChecker
       constexpr ItemType sub_item_type = ItemOfItem::sub_item_type;
       using IndexType                  = typename ConnectivityMatrix::IndexType;
 
-      Array<const int> reference_item_numbers           = this->_readArray<int>(group, "numbers");
+      Array<const int> reference_item_numbers =
+        this->_readArray<int>(group, std::string{itemName(item_type)} + "_numbers");
+      Array<const int> reference_sub_item_numbers =
+        this->_readArray<int>(group, std::string{itemName(sub_item_type)} + "_numbers");
       Array<const IndexType> reference_subitem_rows_map = this->_readArray<IndexType>(group, "rows_map");
+      Array<const IndexType> reference_subitem_index    = this->_readArray<IndexType>(group, "sub_item_index");
 
       Table<const DataType> reference_subitem_array_per_item = this->_readTable<DataType>(group, reference_name);
 
       Array<const int> item_numbers           = this->_getItemNumber<item_type>(i_connectivity);
+      Array<const int> sub_item_numbers       = this->_getItemNumber<sub_item_type>(i_connectivity);
       Array<const IndexType> sub_item_row_map = this->_getSubItemRowsMap<item_type, sub_item_type>(i_connectivity);
 
       using ItemId = ItemIdT<item_type>;
@@ -1186,6 +1248,8 @@ class ParallelChecker
       }
       this->_checkGlobalNumberOfItems<item_type>(i_connectivity, reference_item_numbers.size());
 
+      auto item_to_sub_item_matrix = i_connectivity->getMatrix(item_type, sub_item_type);
+
       Array<const int> owner = this->_getItemOwner<item_type>(i_connectivity);
 
       bool has_own_differences = false;
@@ -1197,13 +1261,32 @@ class ParallelChecker
         const size_t index_end_in_reference   = reference_subitem_rows_map[reference_item_index + 1];
 
         bool item_is_same = true;
-        if ((index_end_in_reference - index_begin_in_reference) != subitem_array_per_item[item_id].numberOfRows()) {
-          item_is_same = false;
+
+        if ((item_type > sub_item_type) or (static_cast<size_t>(owner[item_id]) == parallel::rank())) {
+          if ((index_end_in_reference - index_begin_in_reference) != subitem_array_per_item[item_id].numberOfRows()) {
+            item_is_same = false;
+          } else {
+            for (size_t i_sub_item = 0; i_sub_item < subitem_array_per_item[item_id].numberOfRows(); ++i_sub_item) {
+              for (size_t i = 0; i < subitem_array_per_item.sizeOfArrays(); ++i) {
+                if (reference_subitem_array_per_item[index_begin_in_reference + i_sub_item][i] !=
+                    subitem_array_per_item[item_id][i_sub_item][i]) {
+                  item_is_same = false;
+                }
+              }
+            }
+          }
         } else {
-          for (size_t i_sub_item = 0; i_sub_item < subitem_array_per_item[item_id].numberOfRows(); ++i_sub_item) {
+          std::map<int, size_t> sub_item_number_to_index;
+          for (size_t index = index_begin_in_reference; index < index_end_in_reference; ++index) {
+            sub_item_number_to_index[reference_sub_item_numbers[reference_subitem_index[index]]] = index;
+          }
+
+          auto sub_item_list = item_to_sub_item_matrix[item_id];
+          for (size_t i_sub_item = 0; i_sub_item < sub_item_list.size(); ++i_sub_item) {
+            auto sub_item_id = sub_item_list[i_sub_item];
+            auto index       = sub_item_number_to_index.at(sub_item_numbers[sub_item_id]);
             for (size_t i = 0; i < subitem_array_per_item.sizeOfArrays(); ++i) {
-              if (reference_subitem_array_per_item[index_begin_in_reference + i_sub_item][i] !=
-                  subitem_array_per_item[item_id][i_sub_item][i]) {
+              if (reference_subitem_array_per_item[index][i] != subitem_array_per_item[item_id][i_sub_item][i]) {
                 item_is_same = false;
               }
             }
diff --git a/tests/test_ParallelChecker_read.cpp b/tests/test_ParallelChecker_read.cpp
index 026cd4063fc0837dcec9a83bac312d4d58619561..40628382f6336517a9e2636d5e65fbe90cb774ab 100644
--- a/tests/test_ParallelChecker_read.cpp
+++ b/tests/test_ParallelChecker_read.cpp
@@ -181,6 +181,116 @@ TEST_CASE("ParallelChecker_read", "[dev]")
     }
   };
 
+  auto get_subitem_index = [&get_item_numbers]<typename ConnectivityT>(const ConnectivityT& connectivity,
+                                                                       ItemType item_type, ItemType subitem_type)
+    -> Array<const typename ConnectivityMatrix::IndexType> {
+    auto item_to_subitem_matrix = connectivity.getMatrix(item_type, subitem_type);
+
+    Array sub_item_index = item_to_subitem_matrix.values();
+    Array rows_map       = connectivity.getMatrix(item_type, subitem_type).rowsMap();
+
+    if (parallel::size() == 1) {
+      return sub_item_index;
+    } else {
+      Array<const bool> is_owned;
+      switch (item_type) {
+      case ItemType::cell: {
+        is_owned = connectivity.cellIsOwned().arrayView();
+        break;
+      }
+      case ItemType::face: {
+        is_owned = connectivity.faceIsOwned().arrayView();
+        break;
+      }
+      case ItemType::edge: {
+        is_owned = connectivity.edgeIsOwned().arrayView();
+        break;
+      }
+      case ItemType::node: {
+        is_owned = connectivity.nodeIsOwned().arrayView();
+        break;
+      }
+      }
+
+      Array<const int> subitem_numbers;
+      switch (subitem_type) {
+      case ItemType::cell: {
+        subitem_numbers = connectivity.cellNumber().arrayView();
+        break;
+      }
+      case ItemType::face: {
+        subitem_numbers = connectivity.faceNumber().arrayView();
+        break;
+      }
+      case ItemType::edge: {
+        subitem_numbers = connectivity.edgeNumber().arrayView();
+        break;
+      }
+      case ItemType::node: {
+        subitem_numbers = connectivity.nodeNumber().arrayView();
+        break;
+      }
+      }
+
+      Array<size_t> nb_subitem_per_item(rows_map.size() - 1);
+
+      for (size_t i = 0; i < nb_subitem_per_item.size(); ++i) {
+        nb_subitem_per_item[i] = rows_map[i + 1] - rows_map[i];
+      }
+
+      const size_t nb_local_item = [is_owned]() {
+        size_t count = 0;
+        for (size_t i = 0; i < is_owned.size(); ++i) {
+          count += is_owned[i];
+        }
+        return count;
+      }();
+
+      Array<int> global_subitem_numbers;
+      {
+        Array<size_t> owned_nb_subitem_per_item{nb_local_item};
+        for (size_t i = 0, l = 0; i < is_owned.size(); ++i) {
+          if (is_owned[i]) {
+            owned_nb_subitem_per_item[l++] = nb_subitem_per_item[i];
+          }
+        }
+
+        size_t owned_nb_subitem = sum(owned_nb_subitem_per_item);
+
+        Array<int> owned_subitem_numbers{owned_nb_subitem};
+
+        size_t l = 0;
+        for (size_t item_id = 0; item_id < item_to_subitem_matrix.numberOfRows(); ++item_id) {
+          if (is_owned[item_id]) {
+            for (size_t i = 0; i < item_to_subitem_matrix[item_id].size(); ++i) {
+              owned_subitem_numbers[l++] = subitem_numbers[item_to_subitem_matrix[item_id][i]];
+            }
+          }
+        }
+
+        global_subitem_numbers = parallel::allGatherVariable(owned_subitem_numbers);
+      }
+
+      Array sub_item_numbers = get_item_numbers(connectivity, subitem_type);
+
+      std::map<typename ConnectivityMatrix::IndexType, int> number_to_id_map;
+      {
+        for (size_t i = 0; i < sub_item_numbers.size(); ++i) {
+          number_to_id_map[sub_item_numbers[i]] = i;
+        }
+        REQUIRE(sub_item_numbers.size() == number_to_id_map.size());
+      }
+
+      Array<typename ConnectivityMatrix::IndexType> global_values{global_subitem_numbers.size()};
+
+      for (size_t i = 0; i < global_subitem_numbers.size(); ++i) {
+        global_values[i] = number_to_id_map.at(global_subitem_numbers[i]);
+      }
+
+      return global_values;
+    }
+  };
+
   SECTION("check parallel write implementation")
   {
     if (parallel::size() == 1) {
@@ -207,21 +317,21 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       SourceLocation source_location;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::cell);
+      Array cell_numbers = get_item_numbers(connectivity, ItemType::cell);
 
       int tag = 12;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("cell_numbers", HighFive::DataSpace{std::vector<size_t>{cell_numbers.size()}})
+          .write_raw<int>(&(cell_numbers[0]));
 
-        Array<double> values{numbers.size()};
-        for (size_t i = 0; i < numbers.size(); ++i) {
-          values[i] = std::sin(numbers[i]);
+        Array<double> values{cell_numbers.size()};
+        for (size_t i = 0; i < cell_numbers.size(); ++i) {
+          values[i] = std::sin(cell_numbers[i]);
         }
-        group.createDataSet<double>(name, HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
+        group.createDataSet<double>(name, HighFive::DataSpace{std::vector<size_t>{cell_numbers.size()}})
           .write_raw<double>(&(values[0]));
 
         group.createAttribute("filename", source_location.filename());
@@ -392,7 +502,7 @@ TEST_CASE("ParallelChecker_read", "[dev]")
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
+        group.createDataSet<int>("cell_numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
           .write_raw<int>(&(numbers[0]));
 
         Table<double> double_table{numbers.size(), 2};
@@ -525,7 +635,7 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       SourceLocation source_location;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::node);
+      Array node_numbers = get_item_numbers(connectivity, ItemType::node);
 
       using DataType = TinyVector<3>;
 
@@ -534,17 +644,17 @@ TEST_CASE("ParallelChecker_read", "[dev]")
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("node_numbers", HighFive::DataSpace{std::vector<size_t>{node_numbers.size()}})
+          .write_raw<int>(&(node_numbers[0]));
 
-        Array<DataType> values{numbers.size()};
-        for (size_t i = 0; i < numbers.size(); ++i) {
+        Array<DataType> values{node_numbers.size()};
+        for (size_t i = 0; i < node_numbers.size(); ++i) {
           for (size_t j = 0; j < DataType::Dimension; ++j) {
-            values[i][j] = std::sin(numbers[i] + j);
+            values[i][j] = std::sin(node_numbers[i] + j);
           }
         }
         group
-          .createDataSet(name, HighFive::DataSpace{std::vector<size_t>{numbers.size()}},
+          .createDataSet(name, HighFive::DataSpace{std::vector<size_t>{node_numbers.size()}},
                          test_TinyVectorDataType<DataType>{})
           .template write_raw<double>(&(values[0][0]), test_TinyVectorDataType<DataType>{});
 
@@ -620,22 +730,22 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       using DataType = TinyMatrix<3, 2>;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::face);
+      Array face_numbers = get_item_numbers(connectivity, ItemType::face);
 
       int tag = 12;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("face_numbers", HighFive::DataSpace{std::vector<size_t>{face_numbers.size()}})
+          .write_raw<int>(&(face_numbers[0]));
 
-        Table<DataType> dt_table{numbers.size(), 2};
+        Table<DataType> dt_table{face_numbers.size(), 2};
         for (size_t i = 0; i < dt_table.numberOfRows(); ++i) {
           for (size_t j = 0; j < dt_table.numberOfColumns(); ++j) {
             for (size_t k = 0; k < DataType::NumberOfRows; ++k) {
               for (size_t l = 0; l < DataType::NumberOfColumns; ++l) {
-                dt_table[i][j](k, l) = std::sin(2 * numbers[i] + j + 3 * k + 2 * l);
+                dt_table[i][j](k, l) = std::sin(2 * face_numbers[i] + j + 3 * k + 2 * l);
               }
             }
           }
@@ -769,7 +879,7 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       SourceLocation source_location;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::node);
+      Array node_numbers = get_item_numbers(connectivity, ItemType::node);
 
       using DataType = TinyMatrix<2, 3>;
 
@@ -778,19 +888,19 @@ TEST_CASE("ParallelChecker_read", "[dev]")
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("node_numbers", HighFive::DataSpace{std::vector<size_t>{node_numbers.size()}})
+          .write_raw<int>(&(node_numbers[0]));
 
-        Array<DataType> values{numbers.size()};
-        for (size_t i = 0; i < numbers.size(); ++i) {
+        Array<DataType> values{node_numbers.size()};
+        for (size_t i = 0; i < node_numbers.size(); ++i) {
           for (size_t j = 0; j < DataType::NumberOfRows; ++j) {
             for (size_t k = 0; k < DataType::NumberOfColumns; ++k) {
-              values[i](j, k) = std::sin(numbers[i] + j + 2 * k);
+              values[i](j, k) = std::sin(node_numbers[i] + j + 2 * k);
             }
           }
         }
         group
-          .createDataSet(name, HighFive::DataSpace{std::vector<size_t>{numbers.size()}},
+          .createDataSet(name, HighFive::DataSpace{std::vector<size_t>{node_numbers.size()}},
                          test_TinyMatrixDataType<DataType>{})
           .template write_raw<double>(&(values[0](0, 0)), test_TinyMatrixDataType<DataType>{});
 
@@ -868,21 +978,21 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       using DataType = TinyVector<2>;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::face);
+      Array face_numbers = get_item_numbers(connectivity, ItemType::face);
 
       int tag = 7;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("face_numbers", HighFive::DataSpace{std::vector<size_t>{face_numbers.size()}})
+          .write_raw<int>(&(face_numbers[0]));
 
-        Table<DataType> dt_table{numbers.size(), 2};
+        Table<DataType> dt_table{face_numbers.size(), 2};
         for (size_t i = 0; i < dt_table.numberOfRows(); ++i) {
           for (size_t j = 0; j < dt_table.numberOfColumns(); ++j) {
             for (size_t k = 0; k < DataType::Dimension; ++k) {
-              dt_table[i][j][k] = std::sin(2 * numbers[i] + j + 3 * k);
+              dt_table[i][j][k] = std::sin(2 * face_numbers[i] + j + 3 * k);
             }
           }
         }
@@ -1014,27 +1124,37 @@ TEST_CASE("ParallelChecker_read", "[dev]")
       const std::string name = "sin";
 
       SourceLocation source_location;
-      Array numbers = get_item_numbers(connectivity, ItemType::node);
+      Array node_numbers = get_item_numbers(connectivity, ItemType::node);
+      Array cell_numbers = get_item_numbers(connectivity, ItemType::cell);
       Array<const typename ConnectivityMatrix::IndexType> rows_map =
         get_subitem_rows_map(connectivity, ItemType::node, ItemType::cell);
+      Array<const typename ConnectivityMatrix::IndexType> sub_item_index =
+        get_subitem_index(connectivity, ItemType::node, ItemType::cell);
 
       int tag = 6;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("node_numbers", HighFive::DataSpace{std::vector<size_t>{node_numbers.size()}})
+          .write_raw<int>(&(node_numbers[0]));
+        group.createDataSet<int>("cell_numbers", HighFive::DataSpace{std::vector<size_t>{cell_numbers.size()}})
+          .write_raw<int>(&(cell_numbers[0]));
         group
           .createDataSet<typename ConnectivityMatrix::IndexType>("rows_map", HighFive::DataSpace{std::vector<size_t>{
                                                                                rows_map.size()}})
           .write_raw<typename ConnectivityMatrix::IndexType>(&(rows_map[0]));
+        group
+          .createDataSet<typename ConnectivityMatrix::IndexType>("sub_item_index",
+                                                                 HighFive::DataSpace{
+                                                                   std::vector<size_t>{sub_item_index.size()}})
+          .write_raw<typename ConnectivityMatrix::IndexType>(&(sub_item_index[0]));
 
         Array<double> values{rows_map[rows_map.size() - 1]};
-        for (size_t i = 0; i < numbers.size(); ++i) {
+        for (size_t i = 0; i < node_numbers.size(); ++i) {
           for (size_t i_row = rows_map[i]; i_row < rows_map[i + 1]; ++i_row) {
             const size_t j = i_row - rows_map[i];
-            values[i_row]  = std::sin(numbers[i] + 2 * j);
+            values[i_row]  = std::sin(node_numbers[i] + 2 * j);
           }
         }
 
@@ -1220,28 +1340,38 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       SourceLocation source_location;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::cell);
+      Array cell_numbers = get_item_numbers(connectivity, ItemType::cell);
+      Array node_numbers = get_item_numbers(connectivity, ItemType::node);
       Array<const typename ConnectivityMatrix::IndexType> rows_map =
         get_subitem_rows_map(connectivity, ItemType::cell, ItemType::node);
+      Array<const typename ConnectivityMatrix::IndexType> sub_item_index =
+        get_subitem_index(connectivity, ItemType::cell, ItemType::node);
 
       int tag = 12;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("cell_numbers", HighFive::DataSpace{std::vector<size_t>{cell_numbers.size()}})
+          .write_raw<int>(&(cell_numbers[0]));
+        group.createDataSet<int>("node_numbers", HighFive::DataSpace{std::vector<size_t>{node_numbers.size()}})
+          .write_raw<int>(&(node_numbers[0]));
         group
           .createDataSet<typename ConnectivityMatrix::IndexType>("rows_map", HighFive::DataSpace{std::vector<size_t>{
                                                                                rows_map.size()}})
           .write_raw<typename ConnectivityMatrix::IndexType>(&(rows_map[0]));
+        group
+          .createDataSet<typename ConnectivityMatrix::IndexType>("sub_item_index",
+                                                                 HighFive::DataSpace{
+                                                                   std::vector<size_t>{sub_item_index.size()}})
+          .write_raw<typename ConnectivityMatrix::IndexType>(&(sub_item_index[0]));
 
         Table<double> double_table{rows_map[rows_map.size() - 1], 2};
-        for (size_t i = 0; i < numbers.size(); ++i) {
+        for (size_t i = 0; i < cell_numbers.size(); ++i) {
           for (size_t i_row = rows_map[i]; i_row < rows_map[i + 1]; ++i_row) {
             const size_t j = i_row - rows_map[i];
             for (size_t k = 0; k < 2; ++k) {
-              double_table[i_row][k] = std::sin(2 * numbers[i] + (1 + k) * j);
+              double_table[i_row][k] = std::sin(2 * cell_numbers[i] + (1 + k) * j);
             }
           }
         }
@@ -1376,22 +1506,22 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       using DataType = TinyMatrix<3, 2>;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::face);
+      Array face_numbers = get_item_numbers(connectivity, ItemType::face);
 
       int tag = 12;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("face_numbers", HighFive::DataSpace{std::vector<size_t>{face_numbers.size()}})
+          .write_raw<int>(&(face_numbers[0]));
 
-        Table<DataType> dt_table{numbers.size(), 2};
+        Table<DataType> dt_table{face_numbers.size(), 2};
         for (size_t i = 0; i < dt_table.numberOfRows(); ++i) {
           for (size_t j = 0; j < dt_table.numberOfColumns(); ++j) {
             for (size_t k = 0; k < DataType::NumberOfRows; ++k) {
               for (size_t l = 0; l < DataType::NumberOfColumns; ++l) {
-                dt_table[i][j](k, l) = std::sin(2 * numbers[i] + j + 3 * k + 2 * l);
+                dt_table[i][j](k, l) = std::sin(2 * face_numbers[i] + j + 3 * k + 2 * l);
               }
             }
           }
@@ -1524,27 +1654,37 @@ TEST_CASE("ParallelChecker_read", "[dev]")
       const std::string name = "sin";
 
       SourceLocation source_location;
-      Array numbers = get_item_numbers(connectivity, ItemType::node);
+      Array node_numbers = get_item_numbers(connectivity, ItemType::node);
+      Array cell_numbers = get_item_numbers(connectivity, ItemType::cell);
       Array<const typename ConnectivityMatrix::IndexType> rows_map =
         get_subitem_rows_map(connectivity, ItemType::node, ItemType::cell);
+      Array<const typename ConnectivityMatrix::IndexType> sub_item_index =
+        get_subitem_index(connectivity, ItemType::node, ItemType::cell);
 
       int tag = 6;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("node_numbers", HighFive::DataSpace{std::vector<size_t>{node_numbers.size()}})
+          .write_raw<int>(&(node_numbers[0]));
+        group.createDataSet<int>("cell_numbers", HighFive::DataSpace{std::vector<size_t>{cell_numbers.size()}})
+          .write_raw<int>(&(cell_numbers[0]));
         group
           .createDataSet<typename ConnectivityMatrix::IndexType>("rows_map", HighFive::DataSpace{std::vector<size_t>{
                                                                                rows_map.size()}})
           .write_raw<typename ConnectivityMatrix::IndexType>(&(rows_map[0]));
+        group
+          .createDataSet<typename ConnectivityMatrix::IndexType>("sub_item_index",
+                                                                 HighFive::DataSpace{
+                                                                   std::vector<size_t>{sub_item_index.size()}})
+          .write_raw<typename ConnectivityMatrix::IndexType>(&(sub_item_index[0]));
 
         Array<double> values{rows_map[rows_map.size() - 1]};
-        for (size_t i = 0; i < numbers.size(); ++i) {
+        for (size_t i = 0; i < node_numbers.size(); ++i) {
           for (size_t i_row = rows_map[i]; i_row < rows_map[i + 1]; ++i_row) {
             const size_t j = i_row - rows_map[i];
-            values[i_row]  = std::sin(numbers[i] + 2 * j);
+            values[i_row]  = std::sin(node_numbers[i] + 2 * j);
           }
         }
 
@@ -1732,21 +1872,21 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       using DataType = TinyVector<2>;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::face);
+      Array face_numbers = get_item_numbers(connectivity, ItemType::face);
 
       int tag = 7;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("face_numbers", HighFive::DataSpace{std::vector<size_t>{face_numbers.size()}})
+          .write_raw<int>(&(face_numbers[0]));
 
-        Table<DataType> dt_table{numbers.size(), 2};
+        Table<DataType> dt_table{face_numbers.size(), 2};
         for (size_t i = 0; i < dt_table.numberOfRows(); ++i) {
           for (size_t j = 0; j < dt_table.numberOfColumns(); ++j) {
             for (size_t k = 0; k < DataType::Dimension; ++k) {
-              dt_table[i][j][k] = std::sin(2 * numbers[i] + j + 3 * k);
+              dt_table[i][j][k] = std::sin(2 * face_numbers[i] + j + 3 * k);
             }
           }
         }
@@ -1876,28 +2016,38 @@ TEST_CASE("ParallelChecker_read", "[dev]")
 
       SourceLocation source_location;
 
-      Array numbers = get_item_numbers(connectivity, ItemType::cell);
+      Array cell_numbers = get_item_numbers(connectivity, ItemType::cell);
+      Array node_numbers = get_item_numbers(connectivity, ItemType::node);
       Array<const typename ConnectivityMatrix::IndexType> rows_map =
         get_subitem_rows_map(connectivity, ItemType::cell, ItemType::node);
+      Array<const typename ConnectivityMatrix::IndexType> sub_item_index =
+        get_subitem_index(connectivity, ItemType::cell, ItemType::node);
 
       int tag = 12;
       if (parallel::rank() == 0) {
         HighFive::File file(filename, HighFive::File::Overwrite);
         HighFive::Group group = file.createGroup("/values/" + std::to_string(tag));
 
-        group.createDataSet<int>("numbers", HighFive::DataSpace{std::vector<size_t>{numbers.size()}})
-          .write_raw<int>(&(numbers[0]));
+        group.createDataSet<int>("cell_numbers", HighFive::DataSpace{std::vector<size_t>{cell_numbers.size()}})
+          .write_raw<int>(&(cell_numbers[0]));
+        group.createDataSet<int>("node_numbers", HighFive::DataSpace{std::vector<size_t>{node_numbers.size()}})
+          .write_raw<int>(&(node_numbers[0]));
         group
           .createDataSet<typename ConnectivityMatrix::IndexType>("rows_map", HighFive::DataSpace{std::vector<size_t>{
                                                                                rows_map.size()}})
           .write_raw<typename ConnectivityMatrix::IndexType>(&(rows_map[0]));
+        group
+          .createDataSet<typename ConnectivityMatrix::IndexType>("sub_item_index",
+                                                                 HighFive::DataSpace{
+                                                                   std::vector<size_t>{sub_item_index.size()}})
+          .write_raw<typename ConnectivityMatrix::IndexType>(&(sub_item_index[0]));
 
         Table<double> double_table{rows_map[rows_map.size() - 1], 2};
-        for (size_t i = 0; i < numbers.size(); ++i) {
+        for (size_t i = 0; i < cell_numbers.size(); ++i) {
           for (size_t i_row = rows_map[i]; i_row < rows_map[i + 1]; ++i_row) {
             const size_t j = i_row - rows_map[i];
             for (size_t k = 0; k < 2; ++k) {
-              double_table[i_row][k] = std::sin(2 * numbers[i] + (1 + k) * j);
+              double_table[i_row][k] = std::sin(2 * cell_numbers[i] + (1 + k) * j);
             }
           }
         }
diff --git a/tests/test_ParallelChecker_write.cpp b/tests/test_ParallelChecker_write.cpp
index 8ca7ceb50cdd2d2e8c1d4f3f5a2fd2669d9d9806..460d77dadf6f0519c0f0d808071b3933a8d6df33 100644
--- a/tests/test_ParallelChecker_write.cpp
+++ b/tests/test_ParallelChecker_write.cpp
@@ -108,7 +108,7 @@ TEST_CASE("ParallelChecker_write", "[dev]")
       HighFive::Group group_var0 = file.getGroup("values/" + std::to_string(tag));
       REQUIRE(group_var0.getNumberObjects() == 2);
 
-      REQUIRE(group_var0.exist("numbers"));
+      REQUIRE(group_var0.exist(std::string{itemName(item_type)} + "_numbers"));
       REQUIRE(group_var0.exist(var_name));
 
       REQUIRE(group_var0.getNumberAttributes() == 7);
@@ -366,9 +366,11 @@ TEST_CASE("ParallelChecker_write", "[dev]")
 
       HighFive::File file(ParallelChecker::instance().filename(), HighFive::File::ReadOnly);
       HighFive::Group group_var0 = file.getGroup("values/" + std::to_string(tag));
-      REQUIRE(group_var0.getNumberObjects() == 3);
+      REQUIRE(group_var0.getNumberObjects() == 5);
 
-      REQUIRE(group_var0.exist("numbers"));
+      REQUIRE(group_var0.exist(std::string{itemName(item_type)} + "_numbers"));
+      REQUIRE(group_var0.exist(std::string{itemName(sub_item_type)} + "_numbers"));
+      REQUIRE(group_var0.exist("sub_item_index"));
       REQUIRE(group_var0.exist("rows_map"));
       REQUIRE(group_var0.exist(var_name));