diff --git a/src/mesh/ItemArray.hpp b/src/mesh/ItemArray.hpp
index 5a16861a37b5642ba10977d8c9e2d5ecd25fd194..3bd7de633659e81eb8fc178f275ee76a449048cf 100644
--- a/src/mesh/ItemArray.hpp
+++ b/src/mesh/ItemArray.hpp
@@ -36,6 +36,12 @@ class ItemArray
   // Allow const std:weak_ptr version to access our data
   friend ItemArray<std::add_const_t<DataType>, item_type, ConnectivityWeakPtr>;
 
+  // Allow non-const std:shared_ptr version to access our data
+  friend ItemArray<std::remove_const_t<DataType>, item_type, ConnectivitySharedPtr>;
+
+  // Allow non-const std:weak_ptr version to access our data
+  friend ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityWeakPtr>;
+
  public:
   friend PUGS_INLINE ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityPtr>
   copy(const ItemArray<DataType, item_type, ConnectivityPtr>& source)
diff --git a/src/mesh/ItemValue.hpp b/src/mesh/ItemValue.hpp
index d48468f3931a2dc0dc546cb2a2dfee630df9e87e..981ebcc196d4d637d9e775231fe14edc8a70a2f2 100644
--- a/src/mesh/ItemValue.hpp
+++ b/src/mesh/ItemValue.hpp
@@ -36,6 +36,12 @@ class ItemValue
   // Allow const std:weak_ptr version to access our data
   friend ItemValue<std::add_const_t<DataType>, item_type, ConnectivityWeakPtr>;
 
+  // Allow non-const std:shared_ptr version to access our data
+  friend ItemValue<std::remove_const_t<DataType>, item_type, ConnectivitySharedPtr>;
+
+  // Allow non-const std:weak_ptr version to access our data
+  friend ItemValue<std::remove_const_t<DataType>, item_type, ConnectivityWeakPtr>;
+
  public:
   friend PUGS_INLINE ItemValue<std::remove_const_t<DataType>, item_type, ConnectivityPtr>
   copy(const ItemValue<DataType, item_type, ConnectivityPtr>& source)
diff --git a/tests/test_ItemArray.cpp b/tests/test_ItemArray.cpp
index 3422d1da9c8e9627abf75fae743a826809ca5505..9b3b95fded76400eb5953d4a3d70f50481dadde8 100644
--- a/tests/test_ItemArray.cpp
+++ b/tests/test_ItemArray.cpp
@@ -232,12 +232,41 @@ TEST_CASE("ItemArray", "[mesh]")
         const Connectivity<2>& connectivity = mesh_2d->connectivity();
 
         WeakFaceArray<int> weak_face_array{connectivity, 5};
-
-        weak_face_array.fill(parallel::rank());
+        for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) {
+          for (size_t i = 0; i < weak_face_array.sizeOfArrays(); ++i) {
+            weak_face_array[face_id][i] = 2 * face_id + 3 * i;
+          }
+        }
 
         FaceArray<const int> face_array{weak_face_array};
 
         REQUIRE(face_array.connectivity_ptr() == weak_face_array.connectivity_ptr());
+
+        FaceArray<int> copied_face_array = copy(weak_face_array);
+        REQUIRE(copied_face_array.connectivity_ptr() == weak_face_array.connectivity_ptr());
+        REQUIRE(weak_face_array.sizeOfArrays() == copied_face_array.sizeOfArrays());
+
+        weak_face_array.fill(0);
+
+        {
+          bool is_same = true;
+          for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) {
+            for (size_t i = 0; i < face_array.sizeOfArrays(); ++i) {
+              is_same &= (face_array[face_id][i] == 0);
+            }
+          }
+          REQUIRE(is_same);
+        }
+
+        {
+          bool is_same = true;
+          for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) {
+            for (size_t i = 0; i < copied_face_array.sizeOfArrays(); ++i) {
+              is_same &= (copied_face_array[face_id][i] == static_cast<int>(2 * face_id + 3 * i));
+            }
+          }
+          REQUIRE(is_same);
+        }
       }
     }
   }
diff --git a/tests/test_ItemValue.cpp b/tests/test_ItemValue.cpp
index 84778227aa28e7a23267f9ec355822d257718c89..5ec3fdb892eb5474b80381a250d1f2dc487574de 100644
--- a/tests/test_ItemValue.cpp
+++ b/tests/test_ItemValue.cpp
@@ -130,8 +130,12 @@ TEST_CASE("ItemValue", "[mesh]")
 
         cell_value = values;
 
-        for (CellId i_cell = 0; i_cell < mesh_3d->numberOfCells(); ++i_cell) {
-          REQUIRE(cell_value[i_cell] == i_cell);
+        {
+          bool is_same = true;
+          for (CellId i_cell = 0; i_cell < mesh_3d->numberOfCells(); ++i_cell) {
+            is_same &= (cell_value[i_cell] == i_cell);
+          }
+          REQUIRE(is_same);
         }
       }
     }
@@ -156,12 +160,20 @@ TEST_CASE("ItemValue", "[mesh]")
 
         cell_value.fill(0);
 
-        for (CellId i_cell = 0; i_cell < mesh_3d->numberOfCells(); ++i_cell) {
-          REQUIRE(cell_value[i_cell] == 0);
+        {
+          bool is_same = true;
+          for (CellId i_cell = 0; i_cell < mesh_3d->numberOfCells(); ++i_cell) {
+            is_same &= (cell_value[i_cell] == 0);
+          }
+          REQUIRE(is_same);
         }
 
-        for (CellId i_cell = 0; i_cell < mesh_3d->numberOfCells(); ++i_cell) {
-          REQUIRE(const_cell_value[i_cell] == static_cast<std::int64_t>(parallel::rank()));
+        {
+          bool is_same = true;
+          for (CellId i_cell = 0; i_cell < mesh_3d->numberOfCells(); ++i_cell) {
+            is_same &= (const_cell_value[i_cell] == static_cast<std::int64_t>(parallel::rank()));
+          }
+          REQUIRE(is_same);
         }
       }
     }
@@ -179,12 +191,29 @@ TEST_CASE("ItemValue", "[mesh]")
         const Connectivity<2>& connectivity = mesh_2d->connectivity();
 
         WeakFaceValue<int> weak_face_value{connectivity};
-
-        weak_face_value.fill(parallel::rank());
+        for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) {
+          weak_face_value[face_id] = 2 * face_id + 1;
+        }
 
         FaceValue<const int> face_value{weak_face_value};
 
         REQUIRE(face_value.connectivity_ptr() == weak_face_value.connectivity_ptr());
+
+        FaceValue<int> copied_face_value = copy(weak_face_value);
+        REQUIRE(copied_face_value.connectivity_ptr() == weak_face_value.connectivity_ptr());
+
+        weak_face_value.fill(0);
+        for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) {
+          REQUIRE(face_value[face_id] == static_cast<int>(0));
+        }
+
+        {
+          bool is_same = true;
+          for (FaceId face_id = 0; face_id < mesh_2d->numberOfFaces(); ++face_id) {
+            is_same &= (copied_face_value[face_id] == static_cast<int>(2 * face_id + 1));
+          }
+          REQUIRE(is_same);
+        }
       }
     }
   }
diff --git a/tests/test_SubItemArrayPerItem.cpp b/tests/test_SubItemArrayPerItem.cpp
index 23be4a345906919286bb5d35b14fcfdd3f83de80..71a226f01379cccd86ca48c27683ca0b467f80fa 100644
--- a/tests/test_SubItemArrayPerItem.cpp
+++ b/tests/test_SubItemArrayPerItem.cpp
@@ -835,7 +835,9 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]")
             }
           }
 
-          NodeArrayPerCell<size_t> copy_node_array_per_cell = copy(node_array_per_cell);
+          WeakNodeArrayPerCell<const size_t> node_const_array_per_cell = node_array_per_cell;
+
+          NodeArrayPerCell<size_t> copy_node_array_per_cell = copy(node_const_array_per_cell);
           {
             bool is_same = true;
             for (size_t i = 0; i < copy_node_array_per_cell.numberOfArrays(); ++i) {
diff --git a/tests/test_SubItemValuePerItem.cpp b/tests/test_SubItemValuePerItem.cpp
index 5eaadd94d88d07d2c802e9da867ab5ae2442aa5a..4063133a30f71e2304d865fb1250e975470c7ed0 100644
--- a/tests/test_SubItemValuePerItem.cpp
+++ b/tests/test_SubItemValuePerItem.cpp
@@ -720,7 +720,8 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
             }
           }
 
-          NodeValuePerCell<size_t> copy_node_value_per_cell = copy(node_value_per_cell);
+          WeakNodeValuePerCell<const size_t> node_const_value_per_cell = node_value_per_cell;
+          NodeValuePerCell<size_t> copy_node_value_per_cell            = copy(node_const_value_per_cell);
 
           {
             bool is_same = true;