diff --git a/src/mesh/ItemValue.hpp b/src/mesh/ItemValue.hpp
index 45f92a728c221d57e0a83c565b6674a80f336066..ef10317521a3d26460dd0166de56679e84f11cd9 100644
--- a/src/mesh/ItemValue.hpp
+++ b/src/mesh/ItemValue.hpp
@@ -55,13 +55,13 @@ class ItemValue
 
  public:
   PASTIS_INLINE
-  bool isBuilt() const
+  bool isBuilt() const noexcept
   {
     return m_connectivity_ptr.use_count() != 0;
   }
 
   PASTIS_INLINE
-  std::shared_ptr<const IConnectivity> connectivity_ptr() const
+  std::shared_ptr<const IConnectivity> connectivity_ptr() const noexcept
   {
     if constexpr (std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr>) {
       return m_connectivity_ptr;
@@ -71,16 +71,16 @@ class ItemValue
   }
 
   PASTIS_INLINE
-  size_t size() const
+  size_t size() const noexcept(NO_ASSERT)
   {
     Assert(this->isBuilt());
     return m_values.size();
   }
 
   PASTIS_INLINE
-  void fill(const DataType& data) const
+  void fill(const DataType& data) const noexcept
   {
-    static_assert(not std::is_const<DataType>(),
+    static_assert(not std::is_const_v<DataType>,
                   "Cannot modify ItemValue of const");
     m_values.fill(data);
   }
@@ -97,15 +97,15 @@ class ItemValue
   template <typename IndexType>
   DataType& operator[](const IndexType& i) const noexcept(NO_ASSERT)
   {
-    static_assert(std::is_same<IndexType,ItemId>(),
+    static_assert(std::is_same_v<IndexType,ItemId>,
                   "ItemValue must be indexed by ItemId");
-    static_assert(not std::is_const<DataType>(),
+    static_assert(not std::is_const_v<DataType>,
                   "Cannot modify ItemValue of const");
     return m_values[i];
   }
 
   PASTIS_INLINE
-  size_t numberOfItems() const
+  size_t numberOfItems() const noexcept(NO_ASSERT)
   {
     Assert(this->isBuilt());
     return m_values.size();
@@ -114,34 +114,23 @@ class ItemValue
   template <typename DataType2>
   PASTIS_INLINE
   ItemValue&
-  operator=(const Array<DataType2>& values)
+  operator=(const Array<DataType2>& values) noexcept(NO_ASSERT)
   {
     // ensures that DataType is the same as source DataType2
-    static_assert(std::is_same<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>(),
+    static_assert(std::is_same_v<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>,
                   "Cannot assign ItemValue of different type");
     // ensures that const is not lost through copy
-    static_assert(((std::is_const<DataType2>() and std::is_const<DataType>())
-                   or not std::is_const<DataType2>()),
+    static_assert(((std::is_const_v<DataType2> and std::is_const_v<DataType>)
+                   or not std::is_const_v<DataType2>),
                   "Cannot assign ItemValue of const to ItemValue of non-const");
 
-    if (not this->isBuilt()) {
-      perr() << "Cannot assign an array of values to a non-built ItemValue\n";
-      std::terminate();
-    }
-
-    if (m_values.size() != values.size()) {
-      perr() << "Cannot assign an array of values of a different size\n";
-      std::terminate();
-    }
+    Assert((m_values.size() == values.size()),
+           "Cannot assign an array of values of a different size\n");
 
-    if (values.size() > 0) {
-      if (not this->isBuilt()) {
-        perr() << "Cannot assign array of values to a non-built ItemValue\n";
-        std::terminate();
-      }
+    Assert ((values.size() == 0) or this->isBuilt(),
+            "Cannot assign array of values to a non-built ItemValue\n");
 
-      m_values = values;
-    }
+    m_values = values;
 
     return *this;
   }
@@ -150,14 +139,14 @@ class ItemValue
             typename ConnectivityPtr2>
   PASTIS_INLINE
   ItemValue&
-  operator=(const ItemValue<DataType2, item_type, ConnectivityPtr2>& value_per_item)
+  operator=(const ItemValue<DataType2, item_type, ConnectivityPtr2>& value_per_item) noexcept
   {
     // ensures that DataType is the same as source DataType2
-    static_assert(std::is_same<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>(),
+    static_assert(std::is_same_v<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>,
                   "Cannot assign ItemValue of different type");
     // ensures that const is not lost through copy
-    static_assert(((std::is_const<DataType2>() and std::is_const<DataType>())
-                   or not std::is_const<DataType2>()),
+    static_assert(((std::is_const_v<DataType2> and std::is_const_v<DataType>)
+                   or not std::is_const_v<DataType2>),
                   "Cannot assign ItemValue of const to ItemValue of non-const");
 
     m_values = value_per_item.m_values;
@@ -174,7 +163,7 @@ class ItemValue
   template <typename DataType2,
             typename ConnectivityPtr2>
   PASTIS_INLINE
-  ItemValue(const ItemValue<DataType2, item_type, ConnectivityPtr2>& value_per_item)
+  ItemValue(const ItemValue<DataType2, item_type, ConnectivityPtr2>& value_per_item) noexcept
   {
     this->operator=(value_per_item);
   }
@@ -183,11 +172,11 @@ class ItemValue
   ItemValue() = default;
 
   PASTIS_INLINE
-  ItemValue(const IConnectivity& connectivity)
+  ItemValue(const IConnectivity& connectivity) noexcept
       : m_connectivity_ptr{connectivity.shared_ptr()},
         m_values{connectivity.numberOf<item_type>()}
   {
-    static_assert(not std::is_const<DataType>(),
+    static_assert(not std::is_const_v<DataType>,
                   "Cannot allocate ItemValue of const data: only view is supported"); ;
   }
 
@@ -207,16 +196,22 @@ using FaceValue = ItemValue<DataType, ItemType::face>;
 template <typename DataType>
 using CellValue = ItemValue<DataType, ItemType::cell>;
 
+// Weak versions: should not be used outside of Connectivity
+
+template <typename DataType,
+          ItemType item_type>
+using WeakItemValue = ItemValue<DataType, item_type, std::weak_ptr<const IConnectivity>>;
+
 template <typename DataType>
-using WeakNodeValue = ItemValue<DataType, ItemType::node, std::weak_ptr<const IConnectivity>>;
+using WeakNodeValue = WeakItemValue<DataType, ItemType::node>;
 
 template <typename DataType>
-using WeakEdgeValue = ItemValue<DataType, ItemType::edge, std::weak_ptr<const IConnectivity>>;
+using WeakEdgeValue = WeakItemValue<DataType, ItemType::edge>;
 
 template <typename DataType>
-using WeakFaceValue = ItemValue<DataType, ItemType::face, std::weak_ptr<const IConnectivity>>;
+using WeakFaceValue = WeakItemValue<DataType, ItemType::face>;
 
 template <typename DataType>
-using WeakCellValue = ItemValue<DataType, ItemType::cell, std::weak_ptr<const IConnectivity>>;
+using WeakCellValue = WeakItemValue<DataType, ItemType::cell>;
 
 #endif // ITEM_VALUE_HPP
diff --git a/src/mesh/SubItemValuePerItem.hpp b/src/mesh/SubItemValuePerItem.hpp
index 95d0d6949e30873f181aa08dd26800f663b241b2..2460e971c517dec3b00f07d3106e036213645a15 100644
--- a/src/mesh/SubItemValuePerItem.hpp
+++ b/src/mesh/SubItemValuePerItem.hpp
@@ -95,7 +95,7 @@ class SubItemValuePerItem<DataType,
     }
 
     PASTIS_INLINE
-    const size_t& size() const
+    size_t size() const noexcept
     {
       return m_size;
     }
@@ -103,7 +103,7 @@ class SubItemValuePerItem<DataType,
     SubView(const SubView&) = delete;
 
     PASTIS_INLINE
-    SubView(SubView&&) = default;
+    SubView(SubView&&) noexcept = default;
 
     PASTIS_INLINE
     SubView(const Array<DataType>& values,
@@ -118,7 +118,7 @@ class SubItemValuePerItem<DataType,
   };
 
   PASTIS_INLINE
-  bool isBuilt() const
+  bool isBuilt() const noexcept
   {
     return m_connectivity_ptr.use_count() != 0;
   }
@@ -136,8 +136,9 @@ class SubItemValuePerItem<DataType,
   PASTIS_FORCEINLINE
   DataType& operator()(const IndexType& j, const size_t& r) const noexcept(NO_ASSERT)
   {
-    static_assert(std::is_same<IndexType, size_t>(),
+    static_assert(std::is_same_v<IndexType, size_t>,
                   "SubItemValuePerItem indexed by ItemId");
+    Assert(this->isBuilt());
     return m_values[m_host_row_map(size_t{j})+r];
   }
 
@@ -160,8 +161,9 @@ class SubItemValuePerItem<DataType,
   template <typename IndexType>
   DataType& operator[](const IndexType& i) const noexcept(NO_ASSERT)
   {
-    static_assert(std::is_same<IndexType, size_t>(),
+    static_assert(std::is_same_v<IndexType, size_t>,
                   "Access to SubItemValuePerItem's array must be indexed by size_t");
+    Assert(this->isBuilt());
     return m_values[i];
   }
 
@@ -204,14 +206,14 @@ class SubItemValuePerItem<DataType,
             typename ConnectivityPtr2>
   PASTIS_INLINE
   SubItemValuePerItem&
-  operator=(const SubItemValuePerItem<DataType2, sub_item_type, item_type, ConnectivityPtr2>& sub_item_value_per_item)
+  operator=(const SubItemValuePerItem<DataType2, sub_item_type, item_type, ConnectivityPtr2>& sub_item_value_per_item) noexcept
   {
     // ensures that DataType is the same as source DataType2
-    static_assert(std::is_same<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>(),
+    static_assert(std::is_same_v<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>,
                   "Cannot assign SubItemValuePerItem of different type");
     // ensures that const is not lost through copy
-    static_assert(((std::is_const<DataType2>() and std::is_const<DataType>())
-                   or not std::is_const<DataType2>()),
+    static_assert(((std::is_const_v<DataType2> and std::is_const_v<DataType>)
+                   or not std::is_const_v<DataType2>),
                   "Cannot assign SubItemValuePerItem of const data to SubItemValuePerItem of non-const data");
     m_host_row_map = sub_item_value_per_item.m_host_row_map;
     m_values = sub_item_value_per_item.m_values;
@@ -229,17 +231,17 @@ class SubItemValuePerItem<DataType,
   template <typename DataType2,
             typename ConnectivityPtr2>
   PASTIS_INLINE
-  SubItemValuePerItem(const SubItemValuePerItem<DataType2, sub_item_type, item_type, ConnectivityPtr2>& sub_item_value_per_item)
+  SubItemValuePerItem(const SubItemValuePerItem<DataType2, sub_item_type, item_type, ConnectivityPtr2>& sub_item_value_per_item) noexcept
   {
     this->operator=(sub_item_value_per_item);
   }
 
   SubItemValuePerItem() = default;
 
-  SubItemValuePerItem(const IConnectivity& connectivity)
+  SubItemValuePerItem(const IConnectivity& connectivity) noexcept
       : m_connectivity_ptr{connectivity.shared_ptr()}
   {
-    static_assert(not std::is_const<DataType>(),
+    static_assert(not std::is_const_v<DataType>,
                   "Cannot allocate SubItemValuePerItem of const data: only view is supported"); ;
 
     ConnectivityMatrix connectivity_matrix
@@ -299,46 +301,51 @@ using CellValuePerFace = SubItemValuePerItem<DataType, ItemType::cell, ItemType:
 // Weak versions: should not be used outside of Connectivity
 // Item values at nodes
 
+template <typename DataType,
+          ItemType sub_item_type,
+          ItemType item_type>
+using WeakSubItemValuePerItem = SubItemValuePerItem<DataType, sub_item_type, item_type, std::weak_ptr<const IConnectivity>>;
+
 template <typename DataType>
-using WeakNodeValuePerEdge = SubItemValuePerItem<DataType, ItemType::node, ItemType::edge, std::weak_ptr<const IConnectivity>>;
+using WeakNodeValuePerEdge = WeakSubItemValuePerItem<DataType, ItemType::node, ItemType::edge>;
 
 template <typename DataType>
-using WeakNodeValuePerFace = SubItemValuePerItem<DataType, ItemType::node, ItemType::face, std::weak_ptr<const IConnectivity>>;
+using WeakNodeValuePerFace = WeakSubItemValuePerItem<DataType, ItemType::node, ItemType::face>;
 
 template <typename DataType>
-using WeakNodeValuePerCell = SubItemValuePerItem<DataType, ItemType::node, ItemType::cell, std::weak_ptr<const IConnectivity>>;
+using WeakNodeValuePerCell = WeakSubItemValuePerItem<DataType, ItemType::node, ItemType::cell>;
 
 // Item values at edges
 
 template <typename DataType>
-using WeakEdgeValuePerNode = SubItemValuePerItem<DataType, ItemType::edge, ItemType::node, std::weak_ptr<const IConnectivity>>;
+using WeakEdgeValuePerNode = WeakSubItemValuePerItem<DataType, ItemType::edge, ItemType::node>;
 
 template <typename DataType>
-using WeakEdgeValuePerFace = SubItemValuePerItem<DataType, ItemType::edge, ItemType::face, std::weak_ptr<const IConnectivity>>;
+using WeakEdgeValuePerFace = WeakSubItemValuePerItem<DataType, ItemType::edge, ItemType::face>;
 
 template <typename DataType>
-using WeakEdgeValuePerCell = SubItemValuePerItem<DataType, ItemType::edge, ItemType::cell, std::weak_ptr<const IConnectivity>>;
+using WeakEdgeValuePerCell = WeakSubItemValuePerItem<DataType, ItemType::edge, ItemType::cell>;
 
 // Item values at faces
 
 template <typename DataType>
-using WeakFaceValuePerNode = SubItemValuePerItem<DataType, ItemType::face, ItemType::node, std::weak_ptr<const IConnectivity>>;
+using WeakFaceValuePerNode = WeakSubItemValuePerItem<DataType, ItemType::face, ItemType::node>;
 
 template <typename DataType>
-using WeakFaceValuePerEdge = SubItemValuePerItem<DataType, ItemType::face, ItemType::edge, std::weak_ptr<const IConnectivity>>;
+using WeakFaceValuePerEdge = WeakSubItemValuePerItem<DataType, ItemType::face, ItemType::edge>;
 
 template <typename DataType>
-using WeakFaceValuePerCell = SubItemValuePerItem<DataType, ItemType::face, ItemType::cell, std::weak_ptr<const IConnectivity>>;
+using WeakFaceValuePerCell = WeakSubItemValuePerItem<DataType, ItemType::face, ItemType::cell>;
 
 // Item values at cells
 
 template <typename DataType>
-using WeakCellValuePerNode = SubItemValuePerItem<DataType, ItemType::cell, ItemType::node, std::weak_ptr<const IConnectivity>>;
+using WeakCellValuePerNode = WeakSubItemValuePerItem<DataType, ItemType::cell, ItemType::node>;
 
 template <typename DataType>
-using WeakCellValuePerEdge = SubItemValuePerItem<DataType, ItemType::cell, ItemType::edge, std::weak_ptr<const IConnectivity>>;
+using WeakCellValuePerEdge = WeakSubItemValuePerItem<DataType, ItemType::cell, ItemType::edge>;
 
 template <typename DataType>
-using WeakCellValuePerFace = SubItemValuePerItem<DataType, ItemType::cell, ItemType::face, std::weak_ptr<const IConnectivity>>;
+using WeakCellValuePerFace = WeakSubItemValuePerItem<DataType, ItemType::cell, ItemType::face>;
 
 #endif // SUBITEM_VALUE_PER_ITEM_HPP