diff --git a/src/mesh/SubItemValuePerItem.hpp b/src/mesh/SubItemValuePerItem.hpp index 66af694c7255da41ff7570d294dd4777acb0164f..170ffd76d4d3bcf9908cb92c0dfa60edb5e0c07a 100644 --- a/src/mesh/SubItemValuePerItem.hpp +++ b/src/mesh/SubItemValuePerItem.hpp @@ -55,7 +55,8 @@ class SubItemValuePerItem public: template <typename IndexType> - PUGS_INLINE const DataType& operator[](IndexType i) const noexcept(NO_ASSERT) + PUGS_INLINE const DataType& + operator[](IndexType i) const noexcept(NO_ASSERT) { static_assert(std::is_integral_v<IndexType>, "SubView is indexed by integral values"); Assert(i < m_size); @@ -63,7 +64,8 @@ class SubItemValuePerItem } template <typename IndexType> - PUGS_FORCEINLINE DataType& operator[](IndexType i) noexcept(NO_ASSERT) + PUGS_FORCEINLINE DataType& + operator[](IndexType i) noexcept(NO_ASSERT) { static_assert(std::is_integral_v<IndexType>, "SubView is indexed by integral values"); Assert(i < m_size); @@ -91,6 +93,15 @@ class SubItemValuePerItem } }; + friend PUGS_INLINE SubItemValuePerItem<std::remove_const_t<DataType>, ItemOfItem, ConnectivityPtr> + copy(SubItemValuePerItem<DataType, ItemOfItem, ConnectivityPtr>& source) + { + SubItemValuePerItem<std::remove_const_t<DataType>, ItemOfItem, ConnectivityPtr> image(*source.m_connectivity_ptr); + + image.m_values = copy(source.m_values); + return image; + } + PUGS_INLINE bool isBuilt() const noexcept @@ -109,18 +120,11 @@ class SubItemValuePerItem return m_values[m_host_row_map(size_t{item_id}) + i]; } - PUGS_INLINE - size_t - numberOfValues() const noexcept(NO_ASSERT) - { - Assert(this->isBuilt()); - return m_values.size(); - } - // Following Kokkos logic, these classes are view and const view does allow // changes in data template <typename ArrayIndexType> - DataType& operator[](const ArrayIndexType& i) const noexcept(NO_ASSERT) + DataType& + operator[](const ArrayIndexType& i) const noexcept(NO_ASSERT) { static_assert(std::is_integral_v<ArrayIndexType>, "index must be an integral type"); Assert(this->isBuilt()); @@ -128,13 +132,21 @@ class SubItemValuePerItem return m_values[i]; } + PUGS_INLINE + size_t + numberOfValues() const noexcept(NO_ASSERT) + { + Assert(this->isBuilt()); + return m_values.size(); + } + PUGS_INLINE size_t numberOfItems() const noexcept(NO_ASSERT) { Assert(this->isBuilt()); - Assert(m_host_row_map.extent(0) != 0); - return m_host_row_map.extent(0); + Assert(m_host_row_map.extent(0) > 0); + return m_host_row_map.extent(0) - 1; } template <typename IndexType> @@ -143,7 +155,7 @@ class SubItemValuePerItem { static_assert(std::is_same_v<IndexType, ItemId>, "index must be an ItemId"); Assert(this->isBuilt()); - Assert(item_id < m_host_row_map.extent(0)); + Assert(item_id < this->numberOfItems()); return m_host_row_map(size_t{item_id} + 1) - m_host_row_map(size_t{item_id}); } @@ -153,7 +165,7 @@ class SubItemValuePerItem { static_assert(std::is_same_v<IndexType, ItemId>, "index must be an ItemId"); Assert(this->isBuilt()); - Assert(item_id < m_host_row_map.extent(0)); + Assert(item_id < this->numberOfItems()); const auto& item_begin = m_host_row_map(size_t{item_id}); const auto& item_end = m_host_row_map(size_t{item_id} + 1); return SubView(m_values, item_begin, item_end); @@ -167,7 +179,7 @@ class SubItemValuePerItem { static_assert(std::is_same_v<IndexType, ItemId>, "index must be an ItemId"); Assert(this->isBuilt()); - Assert(item_id < m_host_row_map.extent(0)); + Assert(item_id < this->numberOfItems()); const auto& item_begin = m_host_row_map(size_t{item_id}); const auto& item_end = m_host_row_map(size_t{item_id} + 1); return SubView(m_values, item_begin, item_end); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2fc30ddd2d0845b8d113bece1fc71b2b261b4a0d..d6fff1695d274cb71cf411f9045a41525122e26a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -102,6 +102,7 @@ add_executable (mpi_unit_tests test_Partitioner.cpp test_ItemValue.cpp test_ItemValueUtils.cpp + test_SubItemValuePerItem.cpp ) add_library(test_Pugs_MeshDataBase diff --git a/tests/test_SubItemValuePerItem.cpp b/tests/test_SubItemValuePerItem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b7549c444f8a93e776d427b6ff6b308033bdde50 --- /dev/null +++ b/tests/test_SubItemValuePerItem.cpp @@ -0,0 +1,595 @@ +#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/SubItemValuePerItem.hpp> +#include <utils/Messenger.hpp> + +// Instantiate to ensure full coverage is performed +template class SubItemValuePerItem<size_t, NodeOfCell>; + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("SubItemValuePerItem", "[mesh]") +{ + SECTION("default constructors") + { + REQUIRE_NOTHROW(NodeValuePerEdge<int>{}); + REQUIRE_NOTHROW(NodeValuePerFace<int>{}); + REQUIRE_NOTHROW(NodeValuePerCell<int>{}); + + REQUIRE_NOTHROW(EdgeValuePerNode<int>{}); + REQUIRE_NOTHROW(EdgeValuePerFace<int>{}); + REQUIRE_NOTHROW(EdgeValuePerCell<int>{}); + + REQUIRE_NOTHROW(FaceValuePerNode<int>{}); + REQUIRE_NOTHROW(FaceValuePerEdge<int>{}); + REQUIRE_NOTHROW(FaceValuePerCell<int>{}); + + REQUIRE_NOTHROW(CellValuePerNode<int>{}); + REQUIRE_NOTHROW(CellValuePerEdge<int>{}); + REQUIRE_NOTHROW(CellValuePerFace<int>{}); + + REQUIRE(not NodeValuePerEdge<int>{}.isBuilt()); + REQUIRE(not NodeValuePerFace<int>{}.isBuilt()); + REQUIRE(not NodeValuePerCell<int>{}.isBuilt()); + + REQUIRE(not EdgeValuePerNode<int>{}.isBuilt()); + REQUIRE(not EdgeValuePerFace<int>{}.isBuilt()); + REQUIRE(not EdgeValuePerCell<int>{}.isBuilt()); + + REQUIRE(not FaceValuePerNode<int>{}.isBuilt()); + REQUIRE(not FaceValuePerEdge<int>{}.isBuilt()); + REQUIRE(not FaceValuePerCell<int>{}.isBuilt()); + + REQUIRE(not CellValuePerNode<int>{}.isBuilt()); + REQUIRE(not CellValuePerEdge<int>{}.isBuilt()); + REQUIRE(not CellValuePerFace<int>{}.isBuilt()); + } + + SECTION("dimensions") + { + auto number_of_values = [](const auto& sub_item_value_per_item) -> size_t { + using SubItemValuePerItemType = std::decay_t<decltype(sub_item_value_per_item)>; + using ItemId = typename SubItemValuePerItemType::ItemId; + + size_t number = 0; + for (ItemId item_id = 0; item_id < sub_item_value_per_item.numberOfItems(); ++item_id) { + number += sub_item_value_per_item.numberOfSubValues(item_id); + } + return number; + }; + + SECTION("1D") + { + const Mesh<Connectivity<1>>& mesh_1d = MeshDataBaseForTests::get().cartesianMesh<1>(); + const Connectivity<1>& connectivity = mesh_1d.connectivity(); + + SECTION("per cell") + { + NodeValuePerCell<int> node_value_per_cell{connectivity}; + REQUIRE(node_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(node_value_per_cell.numberOfValues() == number_of_values(node_value_per_cell)); + + auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id)); + REQUIRE(node_value_per_cell.itemValues(cell_id).size() == node_value_per_cell.numberOfSubValues(cell_id)); + } + + const NodeValuePerCell<const int> const_node_value_per_cell = node_value_per_cell; + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(const_node_value_per_cell.itemValues(cell_id).size() == + node_value_per_cell.numberOfSubValues(cell_id)); + } + + EdgeValuePerCell<int> edge_value_per_cell{connectivity}; + REQUIRE(edge_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(edge_value_per_cell.numberOfValues() == number_of_values(edge_value_per_cell)); + + auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id)); + } + + FaceValuePerCell<int> face_value_per_cell{connectivity}; + REQUIRE(face_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(face_value_per_cell.numberOfValues() == number_of_values(face_value_per_cell)); + + auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id)); + } + } + + SECTION("per face") + { + CellValuePerFace<int> cell_value_per_face{connectivity}; + REQUIRE(cell_value_per_face.numberOfItems() == connectivity.numberOfFaces()); + REQUIRE(cell_value_per_face.numberOfValues() == number_of_values(cell_value_per_face)); + + auto face_to_cell_matrix = connectivity.faceToCellMatrix(); + for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { + REQUIRE(face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id)); + } + } + + SECTION("per edge") + { + CellValuePerEdge<int> cell_value_per_edge{connectivity}; + REQUIRE(cell_value_per_edge.numberOfItems() == connectivity.numberOfEdges()); + REQUIRE(cell_value_per_edge.numberOfValues() == number_of_values(cell_value_per_edge)); + + auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); + for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) { + REQUIRE(edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id)); + } + } + + SECTION("per node") + { + CellValuePerNode<int> cell_value_per_node{connectivity}; + REQUIRE(cell_value_per_node.numberOfItems() == connectivity.numberOfNodes()); + REQUIRE(cell_value_per_node.numberOfValues() == number_of_values(cell_value_per_node)); + + auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + REQUIRE(node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id)); + } + } + } + + SECTION("2D") + { + const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>(); + const Connectivity<2>& connectivity = mesh_2d.connectivity(); + + SECTION("per cell") + { + NodeValuePerCell<int> node_value_per_cell{connectivity}; + REQUIRE(node_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(node_value_per_cell.numberOfValues() == number_of_values(node_value_per_cell)); + + auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id)); + } + + EdgeValuePerCell<int> edge_value_per_cell{connectivity}; + REQUIRE(edge_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(edge_value_per_cell.numberOfValues() == number_of_values(edge_value_per_cell)); + + auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id)); + } + + FaceValuePerCell<int> face_value_per_cell{connectivity}; + REQUIRE(face_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(face_value_per_cell.numberOfValues() == number_of_values(face_value_per_cell)); + + auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id)); + } + } + + SECTION("per face") + { + CellValuePerFace<int> cell_value_per_face{connectivity}; + REQUIRE(cell_value_per_face.numberOfItems() == connectivity.numberOfFaces()); + REQUIRE(cell_value_per_face.numberOfValues() == number_of_values(cell_value_per_face)); + + auto face_to_cell_matrix = connectivity.faceToCellMatrix(); + for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { + REQUIRE(face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id)); + } + + NodeValuePerFace<int> node_value_per_face{connectivity}; + REQUIRE(node_value_per_face.numberOfItems() == connectivity.numberOfFaces()); + REQUIRE(node_value_per_face.numberOfValues() == number_of_values(node_value_per_face)); + + auto face_to_node_matrix = connectivity.faceToNodeMatrix(); + for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { + REQUIRE(face_to_node_matrix[face_id].size() == node_value_per_face.numberOfSubValues(face_id)); + } + } + + SECTION("per edge") + { + CellValuePerEdge<int> cell_value_per_edge{connectivity}; + REQUIRE(cell_value_per_edge.numberOfItems() == connectivity.numberOfEdges()); + REQUIRE(cell_value_per_edge.numberOfValues() == number_of_values(cell_value_per_edge)); + + auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); + for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) { + REQUIRE(edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id)); + } + + NodeValuePerEdge<int> node_value_per_edge{connectivity}; + REQUIRE(node_value_per_edge.numberOfItems() == connectivity.numberOfEdges()); + REQUIRE(node_value_per_edge.numberOfValues() == number_of_values(node_value_per_edge)); + + auto edge_to_node_matrix = connectivity.edgeToNodeMatrix(); + for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) { + REQUIRE(edge_to_node_matrix[edge_id].size() == node_value_per_edge.numberOfSubValues(edge_id)); + } + } + + SECTION("per node") + { + EdgeValuePerNode<int> edge_value_per_node{connectivity}; + REQUIRE(edge_value_per_node.numberOfItems() == connectivity.numberOfNodes()); + REQUIRE(edge_value_per_node.numberOfValues() == number_of_values(edge_value_per_node)); + + auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix(); + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + REQUIRE(node_to_edge_matrix[node_id].size() == edge_value_per_node.numberOfSubValues(node_id)); + } + + FaceValuePerNode<int> face_value_per_node{connectivity}; + REQUIRE(face_value_per_node.numberOfItems() == connectivity.numberOfNodes()); + REQUIRE(face_value_per_node.numberOfValues() == number_of_values(face_value_per_node)); + + auto node_to_face_matrix = connectivity.nodeToFaceMatrix(); + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + REQUIRE(node_to_face_matrix[node_id].size() == face_value_per_node.numberOfSubValues(node_id)); + } + + CellValuePerNode<int> cell_value_per_node{connectivity}; + REQUIRE(cell_value_per_node.numberOfItems() == connectivity.numberOfNodes()); + REQUIRE(cell_value_per_node.numberOfValues() == number_of_values(cell_value_per_node)); + + auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + REQUIRE(node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id)); + } + } + } + + SECTION("3D") + { + const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); + const Connectivity<3>& connectivity = mesh_3d.connectivity(); + + SECTION("per cell") + { + NodeValuePerCell<int> node_value_per_cell{connectivity}; + REQUIRE(node_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(node_value_per_cell.numberOfValues() == number_of_values(node_value_per_cell)); + + auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id)); + } + + EdgeValuePerCell<int> edge_value_per_cell{connectivity}; + REQUIRE(edge_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(edge_value_per_cell.numberOfValues() == number_of_values(edge_value_per_cell)); + + auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id)); + } + + FaceValuePerCell<int> face_value_per_cell{connectivity}; + REQUIRE(face_value_per_cell.numberOfItems() == connectivity.numberOfCells()); + REQUIRE(face_value_per_cell.numberOfValues() == number_of_values(face_value_per_cell)); + + auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + REQUIRE(cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id)); + } + } + + SECTION("per face") + { + CellValuePerFace<int> cell_value_per_face{connectivity}; + REQUIRE(cell_value_per_face.numberOfItems() == connectivity.numberOfFaces()); + REQUIRE(cell_value_per_face.numberOfValues() == number_of_values(cell_value_per_face)); + + auto face_to_cell_matrix = connectivity.faceToCellMatrix(); + for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { + REQUIRE(face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id)); + } + + EdgeValuePerFace<int> edge_value_per_face{connectivity}; + REQUIRE(edge_value_per_face.numberOfItems() == connectivity.numberOfFaces()); + REQUIRE(edge_value_per_face.numberOfValues() == number_of_values(edge_value_per_face)); + + auto face_to_edge_matrix = connectivity.faceToEdgeMatrix(); + for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { + REQUIRE(face_to_edge_matrix[face_id].size() == edge_value_per_face.numberOfSubValues(face_id)); + } + + NodeValuePerFace<int> node_value_per_face{connectivity}; + REQUIRE(node_value_per_face.numberOfItems() == connectivity.numberOfFaces()); + REQUIRE(node_value_per_face.numberOfValues() == number_of_values(node_value_per_face)); + + auto face_to_node_matrix = connectivity.faceToNodeMatrix(); + for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { + REQUIRE(face_to_node_matrix[face_id].size() == node_value_per_face.numberOfSubValues(face_id)); + } + } + + SECTION("per edge") + { + CellValuePerEdge<int> cell_value_per_edge{connectivity}; + REQUIRE(cell_value_per_edge.numberOfItems() == connectivity.numberOfEdges()); + REQUIRE(cell_value_per_edge.numberOfValues() == number_of_values(cell_value_per_edge)); + + auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); + for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) { + REQUIRE(edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id)); + } + + FaceValuePerEdge<int> face_value_per_edge{connectivity}; + REQUIRE(face_value_per_edge.numberOfItems() == connectivity.numberOfEdges()); + REQUIRE(face_value_per_edge.numberOfValues() == number_of_values(face_value_per_edge)); + + auto edge_to_face_matrix = connectivity.edgeToFaceMatrix(); + for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) { + REQUIRE(edge_to_face_matrix[edge_id].size() == face_value_per_edge.numberOfSubValues(edge_id)); + } + + NodeValuePerEdge<int> node_value_per_edge{connectivity}; + REQUIRE(node_value_per_edge.numberOfItems() == connectivity.numberOfEdges()); + REQUIRE(node_value_per_edge.numberOfValues() == number_of_values(node_value_per_edge)); + + auto edge_to_node_matrix = connectivity.edgeToNodeMatrix(); + for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) { + REQUIRE(edge_to_node_matrix[edge_id].size() == node_value_per_edge.numberOfSubValues(edge_id)); + } + } + + SECTION("per node") + { + EdgeValuePerNode<int> edge_value_per_node{connectivity}; + REQUIRE(edge_value_per_node.numberOfItems() == connectivity.numberOfNodes()); + REQUIRE(edge_value_per_node.numberOfValues() == number_of_values(edge_value_per_node)); + + auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix(); + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + REQUIRE(node_to_edge_matrix[node_id].size() == edge_value_per_node.numberOfSubValues(node_id)); + } + + FaceValuePerNode<int> face_value_per_node{connectivity}; + REQUIRE(face_value_per_node.numberOfItems() == connectivity.numberOfNodes()); + REQUIRE(face_value_per_node.numberOfValues() == number_of_values(face_value_per_node)); + + auto node_to_face_matrix = connectivity.nodeToFaceMatrix(); + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + REQUIRE(node_to_face_matrix[node_id].size() == face_value_per_node.numberOfSubValues(node_id)); + } + + CellValuePerNode<int> cell_value_per_node{connectivity}; + REQUIRE(cell_value_per_node.numberOfItems() == connectivity.numberOfNodes()); + REQUIRE(cell_value_per_node.numberOfValues() == number_of_values(cell_value_per_node)); + + auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + REQUIRE(node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id)); + } + } + } + } + + SECTION("array view") + { + SECTION("1D") + { + const Mesh<Connectivity<1>>& mesh_1d = MeshDataBaseForTests::get().cartesianMesh<1>(); + const Connectivity<1>& connectivity = mesh_1d.connectivity(); + + EdgeValuePerCell<size_t> edge_values_per_cell{connectivity}; + { + size_t value = 0; + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + for (size_t i_edge = 0; i_edge < edge_values_per_cell.numberOfSubValues(cell_id); ++i_edge) { + edge_values_per_cell(cell_id, i_edge) = value++; + } + } + } + for (size_t i = 0; i < edge_values_per_cell.numberOfValues(); ++i) { + REQUIRE(edge_values_per_cell[i] == i); + } + + for (size_t i = 0; i < edge_values_per_cell.numberOfValues(); ++i) { + edge_values_per_cell[i] = i * i + 1; + } + { + size_t i = 0; + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + for (size_t i_edge = 0; i_edge < edge_values_per_cell.numberOfSubValues(cell_id); ++i_edge, ++i) { + REQUIRE(edge_values_per_cell(cell_id, i_edge) == i * i + 1); + } + } + } + } + + SECTION("2D") + { + const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>(); + const Connectivity<2>& connectivity = mesh_2d.connectivity(); + + CellValuePerFace<size_t> cell_values_per_face{connectivity}; + { + size_t value = 0; + for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { + for (size_t i_cell = 0; i_cell < cell_values_per_face.numberOfSubValues(face_id); ++i_cell) { + cell_values_per_face(face_id, i_cell) = value++; + } + } + } + for (size_t i = 0; i < cell_values_per_face.numberOfValues(); ++i) { + REQUIRE(cell_values_per_face[i] == i); + } + + for (size_t i = 0; i < cell_values_per_face.numberOfValues(); ++i) { + cell_values_per_face[i] = 3 * i + 1; + } + { + size_t i = 0; + for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { + for (size_t i_cell = 0; i_cell < cell_values_per_face.numberOfSubValues(face_id); ++i_cell, ++i) { + REQUIRE(cell_values_per_face(face_id, i_cell) == 3 * i + 1); + } + } + } + } + + SECTION("3D") + { + const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); + const Connectivity<3>& connectivity = mesh_3d.connectivity(); + + FaceValuePerNode<size_t> face_values_per_node{connectivity}; + { + size_t value = 0; + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + for (size_t i_face = 0; i_face < face_values_per_node.numberOfSubValues(node_id); ++i_face) { + face_values_per_node.itemValues(node_id)[i_face] = value++; + } + } + } + for (size_t i = 0; i < face_values_per_node.numberOfValues(); ++i) { + REQUIRE(face_values_per_node[i] == i); + } + + for (size_t i = 0; i < face_values_per_node.numberOfValues(); ++i) { + face_values_per_node[i] = 3 + i * i; + } + { + size_t i = 0; + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + for (size_t i_face = 0; i_face < face_values_per_node.numberOfSubValues(node_id); ++i_face, ++i) { + face_values_per_node(node_id, i_face) = 3 + i * i; + } + } + } + + { + size_t i = 0; + for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { + for (size_t i_face = 0; i_face < face_values_per_node.numberOfSubValues(node_id); ++i_face, ++i) { + face_values_per_node.itemValues(node_id)[i_face] = 3 + i * i; + } + } + } + } + } + + SECTION("copy") + { + const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); + const Connectivity<3>& connectivity = mesh_3d.connectivity(); + + NodeValuePerCell<size_t> node_value_per_cell{connectivity}; + + { + size_t value = 0; + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + for (size_t i_node = 0; i_node < node_value_per_cell.numberOfSubValues(cell_id); ++i_node) { + node_value_per_cell.itemValues(cell_id)[i_node] = value++; + } + } + } + + NodeValuePerCell<size_t> copy_node_value_per_cell = copy(node_value_per_cell); + + { + bool is_same = true; + for (size_t i = 0; i < copy_node_value_per_cell.numberOfValues(); ++i) { + is_same &= (copy_node_value_per_cell[i] == node_value_per_cell[i]); + } + + REQUIRE(is_same); + } + + { + for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { + for (size_t i_node = 0; i_node < node_value_per_cell.numberOfSubValues(cell_id); ++i_node) { + node_value_per_cell.itemValues(cell_id)[i_node] = i_node; + } + } + } + + { + bool is_same = true; + for (size_t i = 0; i < copy_node_value_per_cell.numberOfValues(); ++i) { + is_same &= (copy_node_value_per_cell[i] == node_value_per_cell[i]); + } + + REQUIRE(not is_same); + } + } + + SECTION("WeakItemValue") + { + // const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>(); + // const Connectivity<2>& connectivity = mesh_2d.connectivity(); + + // WeakFaceValue<int> weak_face_value{connectivity}; + + // weak_face_value.fill(parallel::rank()); + + // FaceValue<const int> face_value{weak_face_value}; + + // REQUIRE(face_value.connectivity_ptr() == weak_face_value.connectivity_ptr()); + } + +#ifndef NDEBUG + SECTION("error") + { + SECTION("checking for build ItemValue") + { + // CellValue<int> cell_value; + // REQUIRE_THROWS_AS(cell_value[CellId{0}], AssertError); + + // FaceValue<int> face_value; + // REQUIRE_THROWS_AS(face_value[FaceId{0}], AssertError); + + // EdgeValue<int> edge_value; + // REQUIRE_THROWS_AS(edge_value[EdgeId{0}], AssertError); + + // NodeValue<int> node_value; + // REQUIRE_THROWS_AS(node_value[NodeId{0}], AssertError); + } + + SECTION("checking for bounds violation") + { + // const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); + // const Connectivity<3>& connectivity = mesh_3d.connectivity(); + + // CellValue<int> cell_value{connectivity}; + // CellId invalid_cell_id = connectivity.numberOfCells(); + // REQUIRE_THROWS_AS(cell_value[invalid_cell_id], AssertError); + + // FaceValue<int> face_value{connectivity}; + // FaceId invalid_face_id = connectivity.numberOfFaces(); + // REQUIRE_THROWS_AS(face_value[invalid_face_id], AssertError); + + // EdgeValue<int> edge_value{connectivity}; + // EdgeId invalid_edge_id = connectivity.numberOfEdges(); + // REQUIRE_THROWS_AS(edge_value[invalid_edge_id], AssertError); + + // NodeValue<int> node_value{connectivity}; + // NodeId invalid_node_id = connectivity.numberOfNodes(); + // REQUIRE_THROWS_AS(node_value[invalid_node_id], AssertError); + } + + SECTION("set values from invalid array size") + { + // const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>(); + // const Connectivity<3>& connectivity = mesh_3d.connectivity(); + + // CellValue<size_t> cell_value{connectivity}; + + // Array<size_t> values{3 + cell_value.size()}; + // REQUIRE_THROWS_AS(cell_value = values, AssertError); + } + } +#endif // NDEBUG +} diff --git a/tests/test_SubItemValuePerItem.hpp b/tests/test_SubItemValuePerItem.hpp new file mode 100644 index 0000000000000000000000000000000000000000..eee086bd4eca8a91d19286c2661484482cf5dca1 --- /dev/null +++ b/tests/test_SubItemValuePerItem.hpp @@ -0,0 +1 @@ +edge_values_per_faceedge_values_per_faceedge_values_per_faceedge_values_per_faceedge_values_per_face