From 05c9d0618bd9438527cbfffdc6371776c10aee21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Sun, 12 Mar 2023 22:16:27 +0100
Subject: [PATCH] Add ItemArray and SubItemValuePerItem access in the language

---
 src/language/modules/MeshModule.cpp       |   4 +
 src/language/modules/MeshModule.hpp       |  10 ++
 src/mesh/ItemArrayVariant.hpp             | 113 ++++++++++++
 src/mesh/SubItemArrayPerItemVariant.hpp   | 202 +++++++++++++++++++++
 tests/CMakeLists.txt                      |   2 +
 tests/test_ItemArrayVariant.cpp           | 101 +++++++++++
 tests/test_SubItemArrayPerItemVariant.cpp | 204 ++++++++++++++++++++++
 7 files changed, 636 insertions(+)
 create mode 100644 src/mesh/ItemArrayVariant.hpp
 create mode 100644 src/mesh/SubItemArrayPerItemVariant.hpp
 create mode 100644 tests/test_ItemArrayVariant.cpp
 create mode 100644 tests/test_SubItemArrayPerItemVariant.cpp

diff --git a/src/language/modules/MeshModule.cpp b/src/language/modules/MeshModule.cpp
index af1fca45e..cd8120290 100644
--- a/src/language/modules/MeshModule.cpp
+++ b/src/language/modules/MeshModule.cpp
@@ -17,6 +17,7 @@
 #include <mesh/GmshReader.hpp>
 #include <mesh/IBoundaryDescriptor.hpp>
 #include <mesh/IZoneDescriptor.hpp>
+#include <mesh/ItemArrayVariant.hpp>
 #include <mesh/ItemValueVariant.hpp>
 #include <mesh/Mesh.hpp>
 #include <mesh/MeshRelaxer.hpp>
@@ -25,6 +26,7 @@
 #include <mesh/NamedZoneDescriptor.hpp>
 #include <mesh/NumberedBoundaryDescriptor.hpp>
 #include <mesh/NumberedZoneDescriptor.hpp>
+#include <mesh/SubItemArrayPerItemVariant.hpp>
 #include <mesh/SubItemValuePerItemVariant.hpp>
 #include <utils/Exceptions.hpp>
 
@@ -39,7 +41,9 @@ MeshModule::MeshModule()
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const ItemType>>);
 
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const ItemValueVariant>>);
+  this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const ItemArrayVariant>>);
   this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const SubItemValuePerItemVariant>>);
+  this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const SubItemArrayPerItemVariant>>);
 
   this->_addBuiltinFunction("cell", std::function(
 
diff --git a/src/language/modules/MeshModule.hpp b/src/language/modules/MeshModule.hpp
index bf9f0b714..580f25aa8 100644
--- a/src/language/modules/MeshModule.hpp
+++ b/src/language/modules/MeshModule.hpp
@@ -29,11 +29,21 @@ template <>
 inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const ItemValueVariant>> =
   ASTNodeDataType::build<ASTNodeDataType::type_id_t>("item_value");
 
+class ItemArrayVariant;
+template <>
+inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const ItemArrayVariant>> =
+  ASTNodeDataType::build<ASTNodeDataType::type_id_t>("item_array");
+
 class SubItemValuePerItemVariant;
 template <>
 inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const SubItemValuePerItemVariant>> =
   ASTNodeDataType::build<ASTNodeDataType::type_id_t>("sub_item_value");
 
+class SubItemArrayPerItemVariant;
+template <>
+inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const SubItemArrayPerItemVariant>> =
+  ASTNodeDataType::build<ASTNodeDataType::type_id_t>("sub_item_array");
+
 class MeshModule : public BuiltinModule
 {
  public:
diff --git a/src/mesh/ItemArrayVariant.hpp b/src/mesh/ItemArrayVariant.hpp
new file mode 100644
index 000000000..0284cce20
--- /dev/null
+++ b/src/mesh/ItemArrayVariant.hpp
@@ -0,0 +1,113 @@
+#ifndef ITEM_ARRAY_VARIANT_HPP
+#define ITEM_ARRAY_VARIANT_HPP
+
+#include <algebra/TinyMatrix.hpp>
+#include <algebra/TinyVector.hpp>
+#include <mesh/ItemArray.hpp>
+#include <utils/Exceptions.hpp>
+
+class ItemArrayVariant
+{
+ private:
+  using Variant = std::variant<NodeArray<const bool>,
+                               NodeArray<const long int>,
+                               NodeArray<const unsigned long int>,
+                               NodeArray<const double>,
+                               NodeArray<const TinyVector<1, double>>,
+                               NodeArray<const TinyVector<2, double>>,
+                               NodeArray<const TinyVector<3, double>>,
+                               NodeArray<const TinyMatrix<1, 1, double>>,
+                               NodeArray<const TinyMatrix<2, 2, double>>,
+                               NodeArray<const TinyMatrix<3, 3, double>>,
+
+                               EdgeArray<const bool>,
+                               EdgeArray<const long int>,
+                               EdgeArray<const unsigned long int>,
+                               EdgeArray<const double>,
+                               EdgeArray<const TinyVector<1, double>>,
+                               EdgeArray<const TinyVector<2, double>>,
+                               EdgeArray<const TinyVector<3, double>>,
+                               EdgeArray<const TinyMatrix<1, 1, double>>,
+                               EdgeArray<const TinyMatrix<2, 2, double>>,
+                               EdgeArray<const TinyMatrix<3, 3, double>>,
+
+                               FaceArray<const bool>,
+                               FaceArray<const long int>,
+                               FaceArray<const unsigned long int>,
+                               FaceArray<const double>,
+                               FaceArray<const TinyVector<1, double>>,
+                               FaceArray<const TinyVector<2, double>>,
+                               FaceArray<const TinyVector<3, double>>,
+                               FaceArray<const TinyMatrix<1, 1, double>>,
+                               FaceArray<const TinyMatrix<2, 2, double>>,
+                               FaceArray<const TinyMatrix<3, 3, double>>,
+
+                               CellArray<const bool>,
+                               CellArray<const long int>,
+                               CellArray<const unsigned long int>,
+                               CellArray<const double>,
+                               CellArray<const TinyVector<1, double>>,
+                               CellArray<const TinyVector<2, double>>,
+                               CellArray<const TinyVector<3, double>>,
+                               CellArray<const TinyMatrix<1, 1, double>>,
+                               CellArray<const TinyMatrix<2, 2, double>>,
+                               CellArray<const TinyMatrix<3, 3, double>>>;
+
+  Variant m_item_array;
+
+ public:
+  PUGS_INLINE
+  const Variant&
+  itemArray() const
+  {
+    return m_item_array;
+  }
+
+  template <typename ItemArrayT>
+  PUGS_INLINE auto
+  get() const
+  {
+    using DataType               = typename ItemArrayT::data_type;
+    constexpr ItemType item_type = ItemArrayT::item_t;
+
+    if constexpr (std::is_same_v<ItemArrayT, ItemArray<DataType, item_type>> or
+                  std::is_same_v<ItemArrayT, ItemArray<const DataType, item_type>> or
+                  std::is_same_v<ItemArrayT, WeakItemArray<DataType, item_type>> or
+                  std::is_same_v<ItemArrayT, WeakItemArray<const DataType, item_type>>) {
+      if (not std::holds_alternative<ItemArray<const DataType, item_type>>(this->m_item_array)) {
+        throw NormalError("invalid ItemArray type");
+      }
+      return std::get<ItemArray<const DataType, item_type>>(this->itemArray());
+    } else {
+      static_assert(std::is_same_v<ItemArrayT, ItemArrayT>, "invalid template argument");
+    }
+  }
+
+  template <typename DataType, ItemType item_type>
+  ItemArrayVariant(const ItemArray<DataType, item_type>& item_array)
+    : m_item_array{ItemArray<const DataType, item_type>{item_array}}
+  {
+    static_assert(std::is_same_v<std::remove_const_t<DataType>, bool> or                         //
+                    std::is_same_v<std::remove_const_t<DataType>, long int> or                   //
+                    std::is_same_v<std::remove_const_t<DataType>, unsigned long int> or          //
+                    std::is_same_v<std::remove_const_t<DataType>, double> or                     //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyVector<1, double>> or      //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyVector<2, double>> or      //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyVector<3, double>> or      //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyMatrix<1, 1, double>> or   //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyMatrix<2, 2, double>> or   //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyMatrix<3, 3, double>>,
+                  "ItemArray with this DataType is not allowed in variant");
+  }
+
+  ItemArrayVariant& operator=(ItemArrayVariant&&) = default;
+  ItemArrayVariant& operator=(const ItemArrayVariant&) = default;
+
+  ItemArrayVariant(const ItemArrayVariant&) = default;
+  ItemArrayVariant(ItemArrayVariant&&)      = default;
+
+  ItemArrayVariant()  = delete;
+  ~ItemArrayVariant() = default;
+};
+
+#endif   // ITEM_ARRAY_VARIANT_HPP
diff --git a/src/mesh/SubItemArrayPerItemVariant.hpp b/src/mesh/SubItemArrayPerItemVariant.hpp
new file mode 100644
index 000000000..ffb0ea673
--- /dev/null
+++ b/src/mesh/SubItemArrayPerItemVariant.hpp
@@ -0,0 +1,202 @@
+#ifndef SUB_ITEM_ARRAY_PER_ITEM_VARIANT_HPP
+#define SUB_ITEM_ARRAY_PER_ITEM_VARIANT_HPP
+
+#include <algebra/TinyMatrix.hpp>
+#include <algebra/TinyVector.hpp>
+#include <mesh/SubItemArrayPerItem.hpp>
+#include <utils/Exceptions.hpp>
+
+class SubItemArrayPerItemVariant
+{
+ private:
+  using Variant = std::variant<NodeArrayPerEdge<const bool>,
+                               NodeArrayPerEdge<const long int>,
+                               NodeArrayPerEdge<const unsigned long int>,
+                               NodeArrayPerEdge<const double>,
+                               NodeArrayPerEdge<const TinyVector<1, double>>,
+                               NodeArrayPerEdge<const TinyVector<2, double>>,
+                               NodeArrayPerEdge<const TinyVector<3, double>>,
+                               NodeArrayPerEdge<const TinyMatrix<1, 1, double>>,
+                               NodeArrayPerEdge<const TinyMatrix<2, 2, double>>,
+                               NodeArrayPerEdge<const TinyMatrix<3, 3, double>>,
+
+                               NodeArrayPerFace<const bool>,
+                               NodeArrayPerFace<const long int>,
+                               NodeArrayPerFace<const unsigned long int>,
+                               NodeArrayPerFace<const double>,
+                               NodeArrayPerFace<const TinyVector<1, double>>,
+                               NodeArrayPerFace<const TinyVector<2, double>>,
+                               NodeArrayPerFace<const TinyVector<3, double>>,
+                               NodeArrayPerFace<const TinyMatrix<1, 1, double>>,
+                               NodeArrayPerFace<const TinyMatrix<2, 2, double>>,
+                               NodeArrayPerFace<const TinyMatrix<3, 3, double>>,
+
+                               NodeArrayPerCell<const bool>,
+                               NodeArrayPerCell<const long int>,
+                               NodeArrayPerCell<const unsigned long int>,
+                               NodeArrayPerCell<const double>,
+                               NodeArrayPerCell<const TinyVector<1, double>>,
+                               NodeArrayPerCell<const TinyVector<2, double>>,
+                               NodeArrayPerCell<const TinyVector<3, double>>,
+                               NodeArrayPerCell<const TinyMatrix<1, 1, double>>,
+                               NodeArrayPerCell<const TinyMatrix<2, 2, double>>,
+                               NodeArrayPerCell<const TinyMatrix<3, 3, double>>,
+
+                               EdgeArrayPerNode<const bool>,
+                               EdgeArrayPerNode<const long int>,
+                               EdgeArrayPerNode<const unsigned long int>,
+                               EdgeArrayPerNode<const double>,
+                               EdgeArrayPerNode<const TinyVector<1, double>>,
+                               EdgeArrayPerNode<const TinyVector<2, double>>,
+                               EdgeArrayPerNode<const TinyVector<3, double>>,
+                               EdgeArrayPerNode<const TinyMatrix<1, 1, double>>,
+                               EdgeArrayPerNode<const TinyMatrix<2, 2, double>>,
+                               EdgeArrayPerNode<const TinyMatrix<3, 3, double>>,
+
+                               EdgeArrayPerFace<const bool>,
+                               EdgeArrayPerFace<const long int>,
+                               EdgeArrayPerFace<const unsigned long int>,
+                               EdgeArrayPerFace<const double>,
+                               EdgeArrayPerFace<const TinyVector<1, double>>,
+                               EdgeArrayPerFace<const TinyVector<2, double>>,
+                               EdgeArrayPerFace<const TinyVector<3, double>>,
+                               EdgeArrayPerFace<const TinyMatrix<1, 1, double>>,
+                               EdgeArrayPerFace<const TinyMatrix<2, 2, double>>,
+                               EdgeArrayPerFace<const TinyMatrix<3, 3, double>>,
+
+                               EdgeArrayPerCell<const bool>,
+                               EdgeArrayPerCell<const long int>,
+                               EdgeArrayPerCell<const unsigned long int>,
+                               EdgeArrayPerCell<const double>,
+                               EdgeArrayPerCell<const TinyVector<1, double>>,
+                               EdgeArrayPerCell<const TinyVector<2, double>>,
+                               EdgeArrayPerCell<const TinyVector<3, double>>,
+                               EdgeArrayPerCell<const TinyMatrix<1, 1, double>>,
+                               EdgeArrayPerCell<const TinyMatrix<2, 2, double>>,
+                               EdgeArrayPerCell<const TinyMatrix<3, 3, double>>,
+
+                               FaceArrayPerNode<const bool>,
+                               FaceArrayPerNode<const long int>,
+                               FaceArrayPerNode<const unsigned long int>,
+                               FaceArrayPerNode<const double>,
+                               FaceArrayPerNode<const TinyVector<1, double>>,
+                               FaceArrayPerNode<const TinyVector<2, double>>,
+                               FaceArrayPerNode<const TinyVector<3, double>>,
+                               FaceArrayPerNode<const TinyMatrix<1, 1, double>>,
+                               FaceArrayPerNode<const TinyMatrix<2, 2, double>>,
+                               FaceArrayPerNode<const TinyMatrix<3, 3, double>>,
+
+                               FaceArrayPerEdge<const bool>,
+                               FaceArrayPerEdge<const long int>,
+                               FaceArrayPerEdge<const unsigned long int>,
+                               FaceArrayPerEdge<const double>,
+                               FaceArrayPerEdge<const TinyVector<1, double>>,
+                               FaceArrayPerEdge<const TinyVector<2, double>>,
+                               FaceArrayPerEdge<const TinyVector<3, double>>,
+                               FaceArrayPerEdge<const TinyMatrix<1, 1, double>>,
+                               FaceArrayPerEdge<const TinyMatrix<2, 2, double>>,
+                               FaceArrayPerEdge<const TinyMatrix<3, 3, double>>,
+
+                               FaceArrayPerCell<const bool>,
+                               FaceArrayPerCell<const long int>,
+                               FaceArrayPerCell<const unsigned long int>,
+                               FaceArrayPerCell<const double>,
+                               FaceArrayPerCell<const TinyVector<1, double>>,
+                               FaceArrayPerCell<const TinyVector<2, double>>,
+                               FaceArrayPerCell<const TinyVector<3, double>>,
+                               FaceArrayPerCell<const TinyMatrix<1, 1, double>>,
+                               FaceArrayPerCell<const TinyMatrix<2, 2, double>>,
+                               FaceArrayPerCell<const TinyMatrix<3, 3, double>>,
+
+                               CellArrayPerNode<const bool>,
+                               CellArrayPerNode<const long int>,
+                               CellArrayPerNode<const unsigned long int>,
+                               CellArrayPerNode<const double>,
+                               CellArrayPerNode<const TinyVector<1, double>>,
+                               CellArrayPerNode<const TinyVector<2, double>>,
+                               CellArrayPerNode<const TinyVector<3, double>>,
+                               CellArrayPerNode<const TinyMatrix<1, 1, double>>,
+                               CellArrayPerNode<const TinyMatrix<2, 2, double>>,
+                               CellArrayPerNode<const TinyMatrix<3, 3, double>>,
+
+                               CellArrayPerEdge<const bool>,
+                               CellArrayPerEdge<const long int>,
+                               CellArrayPerEdge<const unsigned long int>,
+                               CellArrayPerEdge<const double>,
+                               CellArrayPerEdge<const TinyVector<1, double>>,
+                               CellArrayPerEdge<const TinyVector<2, double>>,
+                               CellArrayPerEdge<const TinyVector<3, double>>,
+                               CellArrayPerEdge<const TinyMatrix<1, 1, double>>,
+                               CellArrayPerEdge<const TinyMatrix<2, 2, double>>,
+                               CellArrayPerEdge<const TinyMatrix<3, 3, double>>,
+
+                               CellArrayPerFace<const bool>,
+                               CellArrayPerFace<const long int>,
+                               CellArrayPerFace<const unsigned long int>,
+                               CellArrayPerFace<const double>,
+                               CellArrayPerFace<const TinyVector<1, double>>,
+                               CellArrayPerFace<const TinyVector<2, double>>,
+                               CellArrayPerFace<const TinyVector<3, double>>,
+                               CellArrayPerFace<const TinyMatrix<1, 1, double>>,
+                               CellArrayPerFace<const TinyMatrix<2, 2, double>>,
+                               CellArrayPerFace<const TinyMatrix<3, 3, double>>>;
+
+  Variant m_sub_item_array_per_item;
+
+ public:
+  PUGS_INLINE
+  const Variant&
+  itemArray() const
+  {
+    return m_sub_item_array_per_item;
+  }
+
+  template <typename SubItemArrayPerItemT>
+  PUGS_INLINE auto
+  get() const
+  {
+    using DataType        = typename SubItemArrayPerItemT::data_type;
+    using ItemOfItemTypeT = typename SubItemArrayPerItemT::ItemOfItemType;
+
+    if constexpr (std::is_same_v<SubItemArrayPerItemT, SubItemArrayPerItem<DataType, ItemOfItemTypeT>> or
+                  std::is_same_v<SubItemArrayPerItemT, SubItemArrayPerItem<const DataType, ItemOfItemTypeT>> or
+                  std::is_same_v<SubItemArrayPerItemT, WeakSubItemArrayPerItem<DataType, ItemOfItemTypeT>> or
+                  std::is_same_v<SubItemArrayPerItemT, WeakSubItemArrayPerItem<const DataType, ItemOfItemTypeT>>) {
+      if (not std::holds_alternative<SubItemArrayPerItem<const DataType, ItemOfItemTypeT>>(
+            this->m_sub_item_array_per_item)) {
+        throw NormalError("invalid SubItemArrayPerItem type");
+      }
+      return std::get<SubItemArrayPerItem<const DataType, ItemOfItemTypeT>>(this->m_sub_item_array_per_item);
+    } else {
+      static_assert(std::is_same_v<SubItemArrayPerItemT, SubItemArrayPerItemT>, "invalid template argument");
+    }
+  }
+
+  template <typename DataType, typename ItemOfItemTypeT>
+  SubItemArrayPerItemVariant(const SubItemArrayPerItem<DataType, ItemOfItemTypeT>& sub_item_array_per_item)
+    : m_sub_item_array_per_item{SubItemArrayPerItem<const DataType, ItemOfItemTypeT>{sub_item_array_per_item}}
+  {
+    static_assert(std::is_same_v<std::remove_const_t<DataType>, bool> or                         //
+                    std::is_same_v<std::remove_const_t<DataType>, long int> or                   //
+                    std::is_same_v<std::remove_const_t<DataType>, unsigned long int> or          //
+                    std::is_same_v<std::remove_const_t<DataType>, double> or                     //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyVector<1, double>> or      //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyVector<2, double>> or      //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyVector<3, double>> or      //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyMatrix<1, 1, double>> or   //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyMatrix<2, 2, double>> or   //
+                    std::is_same_v<std::remove_const_t<DataType>, TinyMatrix<3, 3, double>>,
+                  "SubItemArrayPerItem with this DataType is not allowed in variant");
+  }
+
+  SubItemArrayPerItemVariant& operator=(SubItemArrayPerItemVariant&&) = default;
+  SubItemArrayPerItemVariant& operator=(const SubItemArrayPerItemVariant&) = default;
+
+  SubItemArrayPerItemVariant(const SubItemArrayPerItemVariant&) = default;
+  SubItemArrayPerItemVariant(SubItemArrayPerItemVariant&&)      = default;
+
+  SubItemArrayPerItemVariant()  = delete;
+  ~SubItemArrayPerItemVariant() = default;
+};
+
+#endif   // SUB_ITEM_ARRAY_PER_ITEM_VARIANT_HPP
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b5301f36a..6a3403df2 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -178,6 +178,7 @@ add_executable (mpi_unit_tests
   test_InterpolateItemValue.cpp
   test_ItemArray.cpp
   test_ItemArrayUtils.cpp
+  test_ItemArrayVariant.cpp
   test_ItemValue.cpp
   test_ItemValueUtils.cpp
   test_ItemValueVariant.cpp
@@ -195,6 +196,7 @@ add_executable (mpi_unit_tests
   test_OFStream.cpp
   test_Partitioner.cpp
   test_RandomEngine.cpp
+  test_SubItemArrayPerItemVariant.cpp
   test_SubItemValuePerItem.cpp
   test_SubItemValuePerItemVariant.cpp
   test_SubItemValuePerItemUtils.cpp
diff --git a/tests/test_ItemArrayVariant.cpp b/tests/test_ItemArrayVariant.cpp
new file mode 100644
index 000000000..f3b529126
--- /dev/null
+++ b/tests/test_ItemArrayVariant.cpp
@@ -0,0 +1,101 @@
+#include <catch2/catch_test_macros.hpp>
+#include <catch2/matchers/catch_matchers_all.hpp>
+
+#include <MeshDataBaseForTests.hpp>
+#include <mesh/Connectivity.hpp>
+#include <mesh/ItemArrayVariant.hpp>
+#include <mesh/Mesh.hpp>
+#include <utils/Messenger.hpp>
+
+// clazy:excludeall=non-pod-global-static
+
+TEST_CASE("ItemArrayVariant", "[mesh]")
+{
+  std::shared_ptr mesh = MeshDataBaseForTests::get().hybrid2DMesh();
+
+  const Connectivity<2>& connectivity = *mesh->shared_connectivity();
+
+  using R1 = TinyVector<1>;
+  using R2 = TinyVector<2>;
+  using R3 = TinyVector<3>;
+
+  using R1x1 = TinyMatrix<1>;
+  using R2x2 = TinyMatrix<2>;
+  using R3x3 = TinyMatrix<3>;
+
+  SECTION("NodeArray<double>")
+  {
+    NodeArray<double> node_array{connectivity, 2};
+    ItemArrayVariant v(node_array);
+    REQUIRE_NOTHROW(v.get<NodeArray<const double>>());
+    REQUIRE_THROWS_WITH(v.get<NodeArray<int64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<NodeArray<uint64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const R1>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const R2>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const R3>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const R1x1>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const R2x2>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const R3x3>>(), "error: invalid ItemArray type");
+
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<const double>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<const double>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const double>>(), "error: invalid ItemArray type");
+  }
+
+  SECTION("EdgeArray<R3>")
+  {
+    EdgeArray<R3> node_array{connectivity, 3};
+    ItemArrayVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<int64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<uint64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<double>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<const R1>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<const R2>>(), "error: invalid ItemArray type");
+    REQUIRE_NOTHROW(v.get<EdgeArray<const R3>>());
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<const R1x1>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<const R2x2>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<const R3x3>>(), "error: invalid ItemArray type");
+
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const R3>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<const R3>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const R3>>(), "error: invalid ItemArray type");
+  }
+
+  SECTION("FaceArray<R3x3>")
+  {
+    FaceArray<R3x3> node_array{connectivity, 2};
+    ItemArrayVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<FaceArray<int64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<uint64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<double>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<const R1>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<const R2>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<const R3>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<const R1x1>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<const R2x2>>(), "error: invalid ItemArray type");
+    REQUIRE_NOTHROW(v.get<FaceArray<const R3x3>>());
+
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const R3x3>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<const R3x3>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const R3x3>>(), "error: invalid ItemArray type");
+  }
+
+  SECTION("CellArray<int64_t>")
+  {
+    CellArray<int64_t> node_array{connectivity, 2};
+    ItemArrayVariant v(node_array);
+    REQUIRE_NOTHROW(v.get<CellArray<const int64_t>>());
+    REQUIRE_THROWS_WITH(v.get<CellArray<const uint64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const double>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const R1>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const R2>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const R3>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const R1x1>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const R2x2>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<CellArray<const R3x3>>(), "error: invalid ItemArray type");
+
+    REQUIRE_THROWS_WITH(v.get<NodeArray<const int64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArray<const int64_t>>(), "error: invalid ItemArray type");
+    REQUIRE_THROWS_WITH(v.get<FaceArray<const int64_t>>(), "error: invalid ItemArray type");
+  }
+}
diff --git a/tests/test_SubItemArrayPerItemVariant.cpp b/tests/test_SubItemArrayPerItemVariant.cpp
new file mode 100644
index 000000000..6e3413aec
--- /dev/null
+++ b/tests/test_SubItemArrayPerItemVariant.cpp
@@ -0,0 +1,204 @@
+#include <catch2/catch_test_macros.hpp>
+#include <catch2/matchers/catch_matchers_all.hpp>
+
+#include <MeshDataBaseForTests.hpp>
+#include <mesh/Connectivity.hpp>
+#include <mesh/Mesh.hpp>
+#include <mesh/SubItemArrayPerItemVariant.hpp>
+#include <utils/Messenger.hpp>
+
+// clazy:excludeall=non-pod-global-static
+
+TEST_CASE("SubItemArrayPerItemVariant", "[mesh]")
+{
+  std::shared_ptr mesh = MeshDataBaseForTests::get().hybrid3DMesh();
+
+  const Connectivity<3>& connectivity = *mesh->shared_connectivity();
+
+  using R1   = TinyVector<1>;
+  using R2   = TinyVector<2>;
+  using R3   = TinyVector<3>;
+  using R1x1 = TinyMatrix<1>;
+  using R2x2 = TinyMatrix<2>;
+  using R3x3 = TinyMatrix<3>;
+
+  SECTION("NodeArrayPerCell<double>")
+  {
+    NodeArrayPerCell<double> node_array{connectivity, 2};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_NOTHROW(v.get<NodeArrayPerCell<double>>());
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("NodeArrayPerFace<R1>")
+  {
+    NodeArrayPerFace<R1> node_array{connectivity, 2};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<const double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<const int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<const uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<NodeArrayPerFace<const R1>>());
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<const R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<const R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<const R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<const R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<const R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("NodeArrayPerEdge<int64_t>")
+  {
+    NodeArrayPerEdge<int64_t> node_array{connectivity, 3};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<NodeArrayPerEdge<int64_t>>());
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("EdgeArrayPerCell<R2>")
+  {
+    EdgeArrayPerCell<R2> node_array{connectivity, 3};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerCell<double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerCell<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerCell<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerCell<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<EdgeArrayPerCell<R2>>());
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerCell<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerCell<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerCell<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerCell<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("EdgeArrayPerFace<R1>")
+  {
+    EdgeArrayPerFace<R1> node_array{connectivity, 1};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerFace<const double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerFace<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerFace<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<EdgeArrayPerFace<R1>>());
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerFace<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerFace<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerFace<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerFace<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerFace<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("EdgeArrayPerNode<double>")
+  {
+    EdgeArrayPerNode<double> node_array{connectivity, 2};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_NOTHROW(v.get<EdgeArrayPerNode<double>>());
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerNode<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerNode<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerNode<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerNode<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerNode<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerNode<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerNode<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<EdgeArrayPerNode<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("FaceArrayPerCell<R3x3>")
+  {
+    FaceArrayPerCell<R3x3> node_array{connectivity, 1};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerCell<double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerCell<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerCell<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerCell<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerCell<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerCell<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerCell<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerCell<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<FaceArrayPerCell<R3x3>>());
+  }
+
+  SECTION("FaceArrayPerEdge<R2x2>")
+  {
+    FaceArrayPerEdge<R2x2> node_array{connectivity, 2};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerEdge<double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerEdge<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerEdge<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerEdge<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerEdge<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerEdge<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerEdge<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<FaceArrayPerEdge<R2x2>>());
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerEdge<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("FaceArrayPerNode<uint64_t>")
+  {
+    FaceArrayPerNode<uint64_t> node_array{connectivity, 2};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerNode<double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerNode<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<FaceArrayPerNode<uint64_t>>());
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerNode<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerNode<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerNode<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerNode<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerNode<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<FaceArrayPerNode<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("NodeArrayPerCell<R1x1>")
+  {
+    NodeArrayPerCell<R1x1> node_array{connectivity, 1};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<NodeArrayPerCell<R1x1>>());
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerCell<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("NodeArrayPerFace<R3>")
+  {
+    NodeArrayPerFace<R3> node_array{connectivity, 3};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<double>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_NOTHROW(v.get<NodeArrayPerFace<R3>>());
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerFace<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+
+  SECTION("NodeArrayPerEdge<double>")
+  {
+    NodeArrayPerEdge<double> node_array{connectivity, 2};
+    SubItemArrayPerItemVariant v(node_array);
+    REQUIRE_NOTHROW(v.get<NodeArrayPerEdge<double>>());
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<int64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<uint64_t>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R3>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R1x1>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R2x2>>(), "error: invalid SubItemArrayPerItem type");
+    REQUIRE_THROWS_WITH(v.get<NodeArrayPerEdge<R3x3>>(), "error: invalid SubItemArrayPerItem type");
+  }
+}
-- 
GitLab