diff --git a/src/mesh/ItemArray.hpp b/src/mesh/ItemArray.hpp index ccfff9143c6d7e0f2ff9ff6eeea36533e016c7f3..78e5f8dd64c430ec8149c3e608d444897987f108 100644 --- a/src/mesh/ItemArray.hpp +++ b/src/mesh/ItemArray.hpp @@ -81,7 +81,7 @@ class ItemArray { Assert(this->isBuilt()); Assert(i < this->numberOfItems()); - return m_values.row(i); + return m_values[i]; } template <typename IndexType> diff --git a/src/mesh/SubItemArrayPerItem.hpp b/src/mesh/SubItemArrayPerItem.hpp index 431c3f4bee962857ff0b361c56a9ab5e987fde35..d39bff6a3015b61fbbe853dbeb9970e237068068 100644 --- a/src/mesh/SubItemArrayPerItem.hpp +++ b/src/mesh/SubItemArrayPerItem.hpp @@ -8,6 +8,8 @@ #include <mesh/ItemType.hpp> #include <utils/Array.hpp> #include <utils/PugsAssert.hpp> +#include <utils/Table.hpp> + #include <utils/SubArray.hpp> #include <memory> @@ -34,9 +36,7 @@ class SubItemArrayPerItem ConnectivityPtr m_connectivity_ptr; typename ConnectivityMatrix::HostRowType m_host_row_map; - Array<DataType> m_arrays_values; - - size_t m_size_of_arrays; + Table<DataType> m_values; // Allow const std:shared_ptr version to access our data friend SubItemArrayPerItem<std::add_const_t<DataType>, ItemOfItem, ConnectivitySharedPtr>; @@ -53,56 +53,6 @@ class SubItemArrayPerItem public: using ToShared = SubItemArrayPerItem<DataType, ItemOfItem, ConnectivitySharedPtr>; - class SubView - { - public: - using data_type = DataType; - - private: - PUGS_RESTRICT DataType* const m_sub_arrays; - const size_t m_size; - const size_t m_size_of_arrays; - - public: - template <typename IndexType> - PUGS_FORCEINLINE SubArray<DataType> - operator[](IndexType i) const noexcept(NO_ASSERT) - { - static_assert(std::is_integral_v<IndexType>, "SubView is indexed by integral arrays"); - Assert(static_cast<size_t>(i) < m_size); - return SubArray<DataType>(m_sub_arrays, i * m_size_of_arrays, m_size_of_arrays); - } - - template <typename IndexType> - PUGS_FORCEINLINE SubArray<DataType> - operator[](IndexType i) noexcept(NO_ASSERT) - { - static_assert(std::is_integral_v<IndexType>, "SubView is indexed by integral arrays"); - Assert(static_cast<size_t>(i) < m_size); - return SubArray<DataType>(m_sub_arrays, i * m_size_of_arrays, m_size_of_arrays); - } - - PUGS_INLINE - size_t - size() const noexcept - { - return m_size; - } - - SubView(const SubView&) = delete; - - PUGS_INLINE - SubView(SubView&&) noexcept = delete; - - PUGS_INLINE - SubView(const Array<DataType>& arrays, size_t begin, size_t end, size_t size_of_arrays) noexcept(NO_ASSERT) - : m_sub_arrays{&(arrays[begin * size_of_arrays])}, m_size{end - begin}, m_size_of_arrays{size_of_arrays} - { - Assert(begin <= end); - Assert(end <= arrays.size()); - } - }; - friend PUGS_INLINE SubItemArrayPerItem<std::remove_const_t<DataType>, ItemOfItem, ConnectivityPtr> copy(SubItemArrayPerItem<DataType, ItemOfItem, ConnectivityPtr>& source) { @@ -110,8 +60,8 @@ class SubItemArrayPerItem image.m_connectivity_ptr = source.m_connectivity_ptr; image.m_host_row_map = source.m_host_row_map; - image.m_arrays_values = copy(source.m_arrays_values); - image.m_size_of_arrays = source.m_size_of_arrays; + image.m_values = copy(source.m_values); + return image; } @@ -134,34 +84,34 @@ class SubItemArrayPerItem } template <typename IndexType, typename SubIndexType> - PUGS_FORCEINLINE SubArray<DataType> + PUGS_FORCEINLINE Array<DataType> operator()(IndexType item_id, SubIndexType i) const noexcept(NO_ASSERT) { static_assert(std::is_same_v<IndexType, ItemId>, "first index must be of the correct ItemId type"); static_assert(std::is_integral_v<SubIndexType>, "second index must be an integral type"); Assert(this->isBuilt()); Assert(i + m_host_row_map(size_t{item_id}) < m_host_row_map(size_t{item_id} + 1)); - return SubArray(m_arrays_values, (m_host_row_map(size_t{item_id}) + i) * m_size_of_arrays, m_size_of_arrays); + return m_values[m_host_row_map(size_t{item_id}) + i]; } // Following Kokkos logic, these classes are view and const view does allow // changes in data template <typename ArrayIndexType> - DataType& + Array<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()); - Assert(static_cast<size_t>(i) < m_arrays_values.size()); - return m_arrays_values[i]; + Assert(static_cast<size_t>(i) < m_values.nbRows()); + return m_values[i]; } PUGS_INLINE size_t - numberOfValues() const noexcept(NO_ASSERT) + numberOfArrays() const noexcept(NO_ASSERT) { Assert(this->isBuilt()); - return m_arrays_values.size(); + return m_values.nbRows(); } PUGS_INLINE @@ -177,7 +127,7 @@ class SubItemArrayPerItem sizeOfArrays() const noexcept(NO_ASSERT) { Assert(this->isBuilt()); - return m_size_of_arrays; + return m_values.nbColumns(); } template <typename IndexType> @@ -190,30 +140,38 @@ class SubItemArrayPerItem return m_host_row_map(size_t{item_id} + 1) - m_host_row_map(size_t{item_id}); } + PUGS_INLINE + void + fill(const DataType& data) const noexcept + { + static_assert(not std::is_const_v<DataType>, "Cannot modify ItemValue of const"); + m_values.fill(data); + } + template <typename IndexType> - PUGS_INLINE SubView - itemArrays(IndexType item_id) noexcept(NO_ASSERT) + PUGS_INLINE Table<DataType> + itemTable(IndexType item_id) noexcept(NO_ASSERT) { static_assert(std::is_same_v<IndexType, ItemId>, "index must be an ItemId"); Assert(this->isBuilt()); 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_arrays_values, item_begin, item_end, m_size_of_arrays); + return subTable(m_values, item_begin, item_end - item_begin, 0, this->sizeOfArrays()); } // Following Kokkos logic, these classes are view and const view does allow // changes in data template <typename IndexType> - PUGS_INLINE SubView - itemArrays(IndexType item_id) const noexcept(NO_ASSERT) + PUGS_INLINE Table<DataType> + itemTable(IndexType item_id) const noexcept(NO_ASSERT) { static_assert(std::is_same_v<IndexType, ItemId>, "index must be an ItemId"); Assert(this->isBuilt()); 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_arrays_values, item_begin, item_end, m_size_of_arrays); + return subTable(m_values, item_begin, item_end - item_begin, 0, this->sizeOfArrays()); } template <typename DataType2, typename ConnectivityPtr2> @@ -227,9 +185,8 @@ class SubItemArrayPerItem static_assert(((std::is_const_v<DataType2> and std::is_const_v<DataType>) or not std::is_const_v<DataType2>), "Cannot assign SubItemArrayPerItem of const data to " "SubItemArrayPerItem of non-const data"); - m_host_row_map = sub_item_array_per_item.m_host_row_map; - m_arrays_values = sub_item_array_per_item.m_arrays_values; - m_size_of_arrays = sub_item_array_per_item.m_size_of_arrays; + m_host_row_map = sub_item_array_per_item.m_host_row_map; + m_values = sub_item_array_per_item.m_values; if constexpr (std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr> and std::is_same_v<ConnectivityPtr2, ConnectivityWeakPtr>) { @@ -251,16 +208,16 @@ class SubItemArrayPerItem SubItemArrayPerItem() = default; - SubItemArrayPerItem(const IConnectivity& connectivity, size_t size_of_array) noexcept - : m_connectivity_ptr{connectivity.shared_ptr()}, m_size_of_arrays(size_of_array) + SubItemArrayPerItem(const IConnectivity& connectivity, size_t size_of_arrays) noexcept + : m_connectivity_ptr{connectivity.shared_ptr()} { static_assert(not std::is_const_v<DataType>, "Cannot allocate SubItemArrayPerItem of const data: only " "view is supported"); ConnectivityMatrix connectivity_matrix = connectivity._getMatrix(item_type, sub_item_type); - m_host_row_map = connectivity_matrix.rowsMap(); - m_arrays_values = Array<std::remove_const_t<DataType>>(connectivity_matrix.numEntries() * m_size_of_arrays); + m_host_row_map = connectivity_matrix.rowsMap(); + m_values = Table<std::remove_const_t<DataType>>(connectivity_matrix.numEntries(), size_of_arrays); } ~SubItemArrayPerItem() = default; diff --git a/src/utils/Table.hpp b/src/utils/Table.hpp index edb0712afe00ec962415db1a4ec4235f33672711..67f544b997f32086131a549237de091e75ba60c1 100644 --- a/src/utils/Table.hpp +++ b/src/utils/Table.hpp @@ -1,14 +1,12 @@ #ifndef TABLE_HPP #define TABLE_HPP +#include <Kokkos_CopyViews.hpp> +#include <utils/Array.hpp> +#include <utils/PugsAssert.hpp> #include <utils/PugsMacros.hpp> #include <utils/PugsUtils.hpp> -#include <utils/PugsAssert.hpp> - -#include <Kokkos_CopyViews.hpp> -#include <algorithm> - template <typename DataType> class [[nodiscard]] Table { @@ -33,14 +31,11 @@ class [[nodiscard]] Table return m_values.extent(1); } - Array<DataType> row(index_type i) const - { - return encapsulate(Kokkos::View<DataType*>(m_values, i, Kokkos::ALL())); - } - - Array<DataType> column(index_type j) const + PUGS_INLINE + Array<DataType> operator[](index_type i) const { - return encapsulate(Kokkos::View<DataType*>(m_values, Kokkos::ALL(), j)); + Assert(i < this->nbRows()); + return encapsulate(Kokkos::View<DataType*>(m_values, i, Kokkos::ALL)); } friend PUGS_INLINE Table<std::remove_const_t<DataType>> copy(const Table<DataType>& source) @@ -54,6 +49,13 @@ class [[nodiscard]] Table template <typename DataType2, typename... RT> friend PUGS_INLINE Table<DataType2> encapsulate(const Kokkos::View<DataType2**, RT...>& values); + template <typename DataType2> + friend PUGS_INLINE Table<DataType2> subTable(const Table<DataType2>& table, + typename Table<DataType2>::index_type row_begin, + typename Table<DataType2>::index_type row_size, + typename Table<DataType2>::index_type column_begin, + typename Table<DataType2>::index_type column_size); + PUGS_INLINE DataType& operator()(index_type i, index_type j) const noexcept(NO_ASSERT) { Assert(i < this->nbRows()); @@ -123,4 +125,20 @@ encapsulate(const Kokkos::View<DataType**, RT...>& values) return table; } +template <typename DataType> +PUGS_INLINE Table<DataType> +subTable(const Table<DataType>& table, + typename Table<DataType>::index_type row_begin, + typename Table<DataType>::index_type row_size, + typename Table<DataType>::index_type column_begin, + typename Table<DataType>::index_type column_size) +{ + Assert(row_begin < table.nbRows()); + Assert(row_begin + row_size <= table.nbRows()); + Assert(column_begin < table.nbColumns()); + Assert(column_begin + column_size <= table.nbColumns()); + return encapsulate(Kokkos::View<DataType**>(table.m_values, std::make_pair(row_begin, row_begin + row_size), + std::make_pair(column_begin, column_begin + column_size))); +} + #endif // TABLE_HPP diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c99154ff0dee78cf7aadf95c70cccfbeb36ffa75..c36830918d3d769870250d212ea6d04e5d8316fc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -85,8 +85,8 @@ add_executable (unit_tests test_PugsUtils.cpp test_RevisionInfo.cpp test_SparseMatrixDescriptor.cpp - test_SubArray.cpp test_SymbolTable.cpp + test_Table.cpp test_Timer.cpp test_TinyMatrix.cpp test_TinyVector.cpp diff --git a/tests/test_SubItemArrayPerItem.cpp b/tests/test_SubItemArrayPerItem.cpp index b453b9e79b430dc6b7496c1a9e533896a3df0ac1..7636ad420dc87ddf029d21b154ea0067a4eb5684 100644 --- a/tests/test_SubItemArrayPerItem.cpp +++ b/tests/test_SubItemArrayPerItem.cpp @@ -51,15 +51,13 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") SECTION("dimensions") { - auto number_of_values = [](const auto& sub_item_array_per_item) -> size_t { + auto number_of_arrays = [](const auto& sub_item_array_per_item) -> size_t { using SubItemArrayPerItemType = std::decay_t<decltype(sub_item_array_per_item)>; using ItemId = typename SubItemArrayPerItemType::ItemId; size_t number = 0; for (ItemId item_id = 0; item_id < sub_item_array_per_item.numberOfItems(); ++item_id) { - for (size_t i = 0; i < sub_item_array_per_item.numberOfSubArrays(item_id); ++i) { - number += sub_item_array_per_item(item_id, i).size(); - } + number += sub_item_array_per_item.numberOfSubArrays(item_id); } return number; }; @@ -73,7 +71,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { NodeArrayPerCell<int> node_array_per_cell{connectivity, 3}; REQUIRE(node_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(node_array_per_cell.numberOfValues() == number_of_values(node_array_per_cell)); + REQUIRE(node_array_per_cell.numberOfArrays() == number_of_arrays(node_array_per_cell)); REQUIRE(node_array_per_cell.sizeOfArrays() == 3); auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); @@ -82,7 +80,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { is_correct &= (cell_to_node_matrix[cell_id].size() == node_array_per_cell.numberOfSubArrays(cell_id)) and - (node_array_per_cell.itemArrays(cell_id).size() == node_array_per_cell.numberOfSubArrays(cell_id)); + (node_array_per_cell.itemTable(cell_id).nbRows() == node_array_per_cell.numberOfSubArrays(cell_id)); } REQUIRE(is_correct); } @@ -92,14 +90,14 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") bool is_correct = true; for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { is_correct &= - (const_node_array_per_cell.itemArrays(cell_id).size() == node_array_per_cell.numberOfSubArrays(cell_id)); + (const_node_array_per_cell.itemTable(cell_id).nbRows() == node_array_per_cell.numberOfSubArrays(cell_id)); } REQUIRE(is_correct); } EdgeArrayPerCell<int> edge_array_per_cell{connectivity, 4}; REQUIRE(edge_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(edge_array_per_cell.numberOfValues() == number_of_values(edge_array_per_cell)); + REQUIRE(edge_array_per_cell.numberOfArrays() == number_of_arrays(edge_array_per_cell)); REQUIRE(edge_array_per_cell.sizeOfArrays() == 4); auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); @@ -113,7 +111,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") FaceArrayPerCell<int> face_array_per_cell{connectivity, 2}; REQUIRE(face_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(face_array_per_cell.numberOfValues() == number_of_values(face_array_per_cell)); + REQUIRE(face_array_per_cell.numberOfArrays() == number_of_arrays(face_array_per_cell)); REQUIRE(face_array_per_cell.sizeOfArrays() == 2); auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); @@ -130,7 +128,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { CellArrayPerFace<int> cell_array_per_face{connectivity, 2}; REQUIRE(cell_array_per_face.numberOfItems() == connectivity.numberOfFaces()); - REQUIRE(cell_array_per_face.numberOfValues() == number_of_values(cell_array_per_face)); + REQUIRE(cell_array_per_face.numberOfArrays() == number_of_arrays(cell_array_per_face)); REQUIRE(cell_array_per_face.sizeOfArrays() == 2); auto face_to_cell_matrix = connectivity.faceToCellMatrix(); @@ -147,7 +145,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { CellArrayPerEdge<int> cell_array_per_edge{connectivity, 3}; REQUIRE(cell_array_per_edge.numberOfItems() == connectivity.numberOfEdges()); - REQUIRE(cell_array_per_edge.numberOfValues() == number_of_values(cell_array_per_edge)); + REQUIRE(cell_array_per_edge.numberOfArrays() == number_of_arrays(cell_array_per_edge)); REQUIRE(cell_array_per_edge.sizeOfArrays() == 3); auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); @@ -164,7 +162,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { CellArrayPerNode<int> cell_array_per_node{connectivity, 4}; REQUIRE(cell_array_per_node.numberOfItems() == connectivity.numberOfNodes()); - REQUIRE(cell_array_per_node.numberOfValues() == number_of_values(cell_array_per_node)); + REQUIRE(cell_array_per_node.numberOfArrays() == number_of_arrays(cell_array_per_node)); REQUIRE(cell_array_per_node.sizeOfArrays() == 4); auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); @@ -187,7 +185,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { NodeArrayPerCell<int> node_array_per_cell{connectivity, 5}; REQUIRE(node_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(node_array_per_cell.numberOfValues() == number_of_values(node_array_per_cell)); + REQUIRE(node_array_per_cell.numberOfArrays() == number_of_arrays(node_array_per_cell)); REQUIRE(node_array_per_cell.sizeOfArrays() == 5); auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); @@ -201,7 +199,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") EdgeArrayPerCell<int> edge_array_per_cell{connectivity, 4}; REQUIRE(edge_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(edge_array_per_cell.numberOfValues() == number_of_values(edge_array_per_cell)); + REQUIRE(edge_array_per_cell.numberOfArrays() == number_of_arrays(edge_array_per_cell)); REQUIRE(edge_array_per_cell.sizeOfArrays() == 4); auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); @@ -215,7 +213,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") FaceArrayPerCell<int> face_array_per_cell{connectivity, 3}; REQUIRE(face_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(face_array_per_cell.numberOfValues() == number_of_values(face_array_per_cell)); + REQUIRE(face_array_per_cell.numberOfArrays() == number_of_arrays(face_array_per_cell)); REQUIRE(face_array_per_cell.sizeOfArrays() == 3); auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); @@ -232,7 +230,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { CellArrayPerFace<int> cell_array_per_face{connectivity, 3}; REQUIRE(cell_array_per_face.numberOfItems() == connectivity.numberOfFaces()); - REQUIRE(cell_array_per_face.numberOfValues() == number_of_values(cell_array_per_face)); + REQUIRE(cell_array_per_face.numberOfArrays() == number_of_arrays(cell_array_per_face)); REQUIRE(cell_array_per_face.sizeOfArrays() == 3); auto face_to_cell_matrix = connectivity.faceToCellMatrix(); @@ -246,7 +244,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") NodeArrayPerFace<int> node_array_per_face{connectivity, 2}; REQUIRE(node_array_per_face.numberOfItems() == connectivity.numberOfFaces()); - REQUIRE(node_array_per_face.numberOfValues() == number_of_values(node_array_per_face)); + REQUIRE(node_array_per_face.numberOfArrays() == number_of_arrays(node_array_per_face)); REQUIRE(node_array_per_face.sizeOfArrays() == 2); auto face_to_node_matrix = connectivity.faceToNodeMatrix(); @@ -263,7 +261,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { CellArrayPerEdge<int> cell_array_per_edge{connectivity, 3}; REQUIRE(cell_array_per_edge.numberOfItems() == connectivity.numberOfEdges()); - REQUIRE(cell_array_per_edge.numberOfValues() == number_of_values(cell_array_per_edge)); + REQUIRE(cell_array_per_edge.numberOfArrays() == number_of_arrays(cell_array_per_edge)); REQUIRE(cell_array_per_edge.sizeOfArrays() == 3); auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); @@ -277,7 +275,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") NodeArrayPerEdge<int> node_array_per_edge{connectivity, 5}; REQUIRE(node_array_per_edge.numberOfItems() == connectivity.numberOfEdges()); - REQUIRE(node_array_per_edge.numberOfValues() == number_of_values(node_array_per_edge)); + REQUIRE(node_array_per_edge.numberOfArrays() == number_of_arrays(node_array_per_edge)); REQUIRE(node_array_per_edge.sizeOfArrays() == 5); auto edge_to_node_matrix = connectivity.edgeToNodeMatrix(); @@ -294,7 +292,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { EdgeArrayPerNode<int> edge_array_per_node{connectivity, 4}; REQUIRE(edge_array_per_node.numberOfItems() == connectivity.numberOfNodes()); - REQUIRE(edge_array_per_node.numberOfValues() == number_of_values(edge_array_per_node)); + REQUIRE(edge_array_per_node.numberOfArrays() == number_of_arrays(edge_array_per_node)); REQUIRE(edge_array_per_node.sizeOfArrays() == 4); auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix(); @@ -308,7 +306,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") FaceArrayPerNode<int> face_array_per_node{connectivity, 3}; REQUIRE(face_array_per_node.numberOfItems() == connectivity.numberOfNodes()); - REQUIRE(face_array_per_node.numberOfValues() == number_of_values(face_array_per_node)); + REQUIRE(face_array_per_node.numberOfArrays() == number_of_arrays(face_array_per_node)); REQUIRE(face_array_per_node.sizeOfArrays() == 3); auto node_to_face_matrix = connectivity.nodeToFaceMatrix(); @@ -322,7 +320,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") CellArrayPerNode<int> cell_array_per_node{connectivity, 2}; REQUIRE(cell_array_per_node.numberOfItems() == connectivity.numberOfNodes()); - REQUIRE(cell_array_per_node.numberOfValues() == number_of_values(cell_array_per_node)); + REQUIRE(cell_array_per_node.numberOfArrays() == number_of_arrays(cell_array_per_node)); REQUIRE(cell_array_per_node.sizeOfArrays() == 2); auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); @@ -344,7 +342,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { NodeArrayPerCell<int> node_array_per_cell{connectivity, 3}; REQUIRE(node_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(node_array_per_cell.numberOfValues() == number_of_values(node_array_per_cell)); + REQUIRE(node_array_per_cell.numberOfArrays() == number_of_arrays(node_array_per_cell)); REQUIRE(node_array_per_cell.sizeOfArrays() == 3); auto cell_to_node_matrix = connectivity.cellToNodeMatrix(); @@ -358,7 +356,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") EdgeArrayPerCell<int> edge_array_per_cell{connectivity, 4}; REQUIRE(edge_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(edge_array_per_cell.numberOfValues() == number_of_values(edge_array_per_cell)); + REQUIRE(edge_array_per_cell.numberOfArrays() == number_of_arrays(edge_array_per_cell)); REQUIRE(edge_array_per_cell.sizeOfArrays() == 4); auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix(); @@ -372,7 +370,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") FaceArrayPerCell<int> face_array_per_cell{connectivity, 3}; REQUIRE(face_array_per_cell.numberOfItems() == connectivity.numberOfCells()); - REQUIRE(face_array_per_cell.numberOfValues() == number_of_values(face_array_per_cell)); + REQUIRE(face_array_per_cell.numberOfArrays() == number_of_arrays(face_array_per_cell)); REQUIRE(face_array_per_cell.sizeOfArrays() == 3); auto cell_to_face_matrix = connectivity.cellToFaceMatrix(); @@ -389,7 +387,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { CellArrayPerFace<int> cell_array_per_face{connectivity, 5}; REQUIRE(cell_array_per_face.numberOfItems() == connectivity.numberOfFaces()); - REQUIRE(cell_array_per_face.numberOfValues() == number_of_values(cell_array_per_face)); + REQUIRE(cell_array_per_face.numberOfArrays() == number_of_arrays(cell_array_per_face)); REQUIRE(cell_array_per_face.sizeOfArrays() == 5); auto face_to_cell_matrix = connectivity.faceToCellMatrix(); @@ -403,7 +401,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") EdgeArrayPerFace<int> edge_array_per_face{connectivity, 3}; REQUIRE(edge_array_per_face.numberOfItems() == connectivity.numberOfFaces()); - REQUIRE(edge_array_per_face.numberOfValues() == number_of_values(edge_array_per_face)); + REQUIRE(edge_array_per_face.numberOfArrays() == number_of_arrays(edge_array_per_face)); REQUIRE(edge_array_per_face.sizeOfArrays() == 3); auto face_to_edge_matrix = connectivity.faceToEdgeMatrix(); @@ -417,7 +415,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") NodeArrayPerFace<int> node_array_per_face{connectivity, 2}; REQUIRE(node_array_per_face.numberOfItems() == connectivity.numberOfFaces()); - REQUIRE(node_array_per_face.numberOfValues() == number_of_values(node_array_per_face)); + REQUIRE(node_array_per_face.numberOfArrays() == number_of_arrays(node_array_per_face)); REQUIRE(node_array_per_face.sizeOfArrays() == 2); auto face_to_node_matrix = connectivity.faceToNodeMatrix(); @@ -434,7 +432,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { CellArrayPerEdge<int> cell_array_per_edge{connectivity, 3}; REQUIRE(cell_array_per_edge.numberOfItems() == connectivity.numberOfEdges()); - REQUIRE(cell_array_per_edge.numberOfValues() == number_of_values(cell_array_per_edge)); + REQUIRE(cell_array_per_edge.numberOfArrays() == number_of_arrays(cell_array_per_edge)); REQUIRE(cell_array_per_edge.sizeOfArrays() == 3); auto edge_to_cell_matrix = connectivity.edgeToCellMatrix(); @@ -448,7 +446,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") FaceArrayPerEdge<int> face_array_per_edge{connectivity, 5}; REQUIRE(face_array_per_edge.numberOfItems() == connectivity.numberOfEdges()); - REQUIRE(face_array_per_edge.numberOfValues() == number_of_values(face_array_per_edge)); + REQUIRE(face_array_per_edge.numberOfArrays() == number_of_arrays(face_array_per_edge)); REQUIRE(face_array_per_edge.sizeOfArrays() == 5); auto edge_to_face_matrix = connectivity.edgeToFaceMatrix(); @@ -462,7 +460,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") NodeArrayPerEdge<int> node_array_per_edge{connectivity, 3}; REQUIRE(node_array_per_edge.numberOfItems() == connectivity.numberOfEdges()); - REQUIRE(node_array_per_edge.numberOfValues() == number_of_values(node_array_per_edge)); + REQUIRE(node_array_per_edge.numberOfArrays() == number_of_arrays(node_array_per_edge)); REQUIRE(node_array_per_edge.sizeOfArrays() == 3); auto edge_to_node_matrix = connectivity.edgeToNodeMatrix(); @@ -479,7 +477,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { EdgeArrayPerNode<int> edge_array_per_node{connectivity, 3}; REQUIRE(edge_array_per_node.numberOfItems() == connectivity.numberOfNodes()); - REQUIRE(edge_array_per_node.numberOfValues() == number_of_values(edge_array_per_node)); + REQUIRE(edge_array_per_node.numberOfArrays() == number_of_arrays(edge_array_per_node)); REQUIRE(edge_array_per_node.sizeOfArrays() == 3); auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix(); @@ -493,7 +491,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") FaceArrayPerNode<int> face_array_per_node{connectivity, 4}; REQUIRE(face_array_per_node.numberOfItems() == connectivity.numberOfNodes()); - REQUIRE(face_array_per_node.numberOfValues() == number_of_values(face_array_per_node)); + REQUIRE(face_array_per_node.numberOfArrays() == number_of_arrays(face_array_per_node)); REQUIRE(face_array_per_node.sizeOfArrays() == 4); auto node_to_face_matrix = connectivity.nodeToFaceMatrix(); @@ -507,7 +505,7 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") CellArrayPerNode<int> cell_array_per_node{connectivity, 5}; REQUIRE(cell_array_per_node.numberOfItems() == connectivity.numberOfNodes()); - REQUIRE(cell_array_per_node.numberOfValues() == number_of_values(cell_array_per_node)); + REQUIRE(cell_array_per_node.numberOfArrays() == number_of_arrays(cell_array_per_node)); REQUIRE(cell_array_per_node.sizeOfArrays() == 5); auto node_to_cell_matrix = connectivity.nodeToCellMatrix(); @@ -542,14 +540,22 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") } { bool is_same = true; - for (size_t i = 0; i < edge_arrays_per_cell.numberOfValues(); ++i) { - is_same &= (edge_arrays_per_cell[i] == i); + size_t k = 0; + for (size_t i = 0; i < edge_arrays_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < edge_arrays_per_cell.sizeOfArrays(); ++j, ++k) { + is_same &= (edge_arrays_per_cell[i][j] == k); + } } REQUIRE(is_same); } - for (size_t i = 0; i < edge_arrays_per_cell.numberOfValues(); ++i) { - edge_arrays_per_cell[i] = i * i + 1; + { + size_t k = 0; + for (size_t i = 0; i < edge_arrays_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < edge_arrays_per_cell.sizeOfArrays(); ++j, ++k) { + edge_arrays_per_cell[i][j] = k * k + 1; + } + } } { bool is_same = true; @@ -569,9 +575,9 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") bool is_same = true; size_t i = 0; for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { - const auto& edge_arrays = const_edge_arrays_per_cell.itemArrays(cell_id); - for (size_t i_edge = 0; i_edge < edge_arrays.size(); ++i_edge) { - const auto& array = edge_arrays[i_edge]; + const auto& cell_table = const_edge_arrays_per_cell.itemTable(cell_id); + for (size_t i_edge = 0; i_edge < cell_table.nbRows(); ++i_edge) { + const auto& array = cell_table[i_edge]; for (size_t l = 0; l < array.size(); ++l, ++i) { is_same &= (array[l] == i * i + 1); } @@ -599,13 +605,21 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") } { bool is_same = true; - for (size_t i = 0; i < cell_arrays_per_face.numberOfValues(); ++i) { - is_same &= (cell_arrays_per_face[i] == i); + size_t k = 0; + for (size_t i = 0; i < cell_arrays_per_face.numberOfArrays(); ++i) { + for (size_t j = 0; j < cell_arrays_per_face.sizeOfArrays(); ++j, ++k) { + is_same &= (cell_arrays_per_face[i][j] == k); + } } REQUIRE(is_same); } - for (size_t i = 0; i < cell_arrays_per_face.numberOfValues(); ++i) { - cell_arrays_per_face[i] = 3 * i + 1; + { + size_t k = 0; + for (size_t i = 0; i < cell_arrays_per_face.numberOfArrays(); ++i) { + for (size_t j = 0; j < cell_arrays_per_face.sizeOfArrays(); ++j, ++k) { + cell_arrays_per_face[i][j] = 3 * k + 1; + } + } } { bool is_same = true; @@ -625,9 +639,9 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") bool is_same = true; size_t i = 0; for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) { - const auto& cell_arrays = const_cell_arrays_per_face.itemArrays(face_id); - for (size_t i_cell = 0; i_cell < cell_arrays.size(); ++i_cell) { - const auto& array = cell_arrays[i_cell]; + const auto& face_table = const_cell_arrays_per_face.itemTable(face_id); + for (size_t i_cell = 0; i_cell < face_table.nbRows(); ++i_cell) { + const auto& array = face_table[i_cell]; for (size_t l = 0; l < array.size(); ++l, ++i) { is_same &= (array[l] == 3 * i + 1); } @@ -654,14 +668,21 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") } { bool is_same = true; - for (size_t i = 0; i < face_arrays_per_node.numberOfValues(); ++i) { - is_same &= (face_arrays_per_node[i] == i); + size_t k = 0; + for (size_t i = 0; i < face_arrays_per_node.numberOfArrays(); ++i) { + for (size_t j = 0; j < face_arrays_per_node.sizeOfArrays(); ++j, ++k) { + is_same &= (face_arrays_per_node[i][j] == k); + } + REQUIRE(is_same); } - REQUIRE(is_same); } - - for (size_t i = 0; i < face_arrays_per_node.numberOfValues(); ++i) { - face_arrays_per_node[i] = 3 + i * i; + { + size_t k = 0; + for (size_t i = 0; i < face_arrays_per_node.numberOfArrays(); ++i) { + for (size_t j = 0; j < face_arrays_per_node.sizeOfArrays(); ++j, ++k) { + face_arrays_per_node[i][j] = 3 + k * k; + } + } } { bool is_same = true; @@ -681,9 +702,9 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") bool is_same = true; size_t i = 0; for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) { - const auto& face_arrays = const_face_arrays_per_node.itemArrays(node_id); - for (size_t i_face = 0; i_face < face_arrays.size(); ++i_face) { - const auto& array = face_arrays[i_face]; + const auto& node_table = const_face_arrays_per_node.itemTable(node_id); + for (size_t i_face = 0; i_face < node_table.nbRows(); ++i_face) { + const auto& array = node_table[i_face]; for (size_t l = 0; l < array.size(); ++l, ++i) { is_same &= (array[l] == 3 + i * i); } @@ -702,15 +723,21 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") SECTION("classic") { NodeArrayPerCell<size_t> node_array_per_cell{connectivity, 3}; - for (size_t i = 0; i < node_array_per_cell.numberOfValues(); ++i) { - node_array_per_cell[i] = i; + { + size_t k = 0; + for (size_t i = 0; i < node_array_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < node_array_per_cell.sizeOfArrays(); ++j, ++k) { + node_array_per_cell[i][j] = k; + } + } } - NodeArrayPerCell<size_t> copy_node_array_per_cell = copy(node_array_per_cell); { bool is_same = true; - for (size_t i = 0; i < copy_node_array_per_cell.numberOfValues(); ++i) { - is_same &= (copy_node_array_per_cell[i] == node_array_per_cell[i]); + for (size_t i = 0; i < copy_node_array_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < node_array_per_cell.sizeOfArrays(); ++j) { + is_same &= (copy_node_array_per_cell[i][j] == node_array_per_cell[i][j]); + } } REQUIRE(is_same); @@ -718,9 +745,9 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { - auto node_array_list = node_array_per_cell.itemArrays(cell_id); + auto cell_table = node_array_per_cell.itemTable(cell_id); for (size_t i_node = 0; i_node < node_array_per_cell.numberOfSubArrays(cell_id); ++i_node) { - auto node_array = node_array_list[i_node]; + auto node_array = cell_table[i_node]; for (size_t i = 0; i < node_array.size(); ++i) { node_array[i] = cell_id + i_node + i; } @@ -730,8 +757,10 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { bool is_same = true; - for (size_t i = 0; i < copy_node_array_per_cell.numberOfValues(); ++i) { - is_same &= (copy_node_array_per_cell[i] == node_array_per_cell[i]); + for (size_t i = 0; i < copy_node_array_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < copy_node_array_per_cell.sizeOfArrays(); ++j) { + is_same &= (copy_node_array_per_cell[i][j] == node_array_per_cell[i][j]); + } } REQUIRE(not is_same); @@ -741,15 +770,22 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") SECTION("from weak") { WeakNodeArrayPerCell<size_t> node_array_per_cell{connectivity, 3}; - for (size_t i = 0; i < node_array_per_cell.numberOfValues(); ++i) { - node_array_per_cell[i] = i; + { + size_t k = 0; + for (size_t i = 0; i < node_array_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < node_array_per_cell.sizeOfArrays(); ++j, ++k) { + node_array_per_cell[i][j] = k; + } + } } NodeArrayPerCell<size_t> copy_node_array_per_cell = copy(node_array_per_cell); { bool is_same = true; - for (size_t i = 0; i < copy_node_array_per_cell.numberOfValues(); ++i) { - is_same &= (copy_node_array_per_cell[i] == node_array_per_cell[i]); + for (size_t i = 0; i < copy_node_array_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < node_array_per_cell.sizeOfArrays(); ++j) { + is_same &= (copy_node_array_per_cell[i][j] == node_array_per_cell[i][j]); + } } REQUIRE(is_same); @@ -757,9 +793,9 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) { - auto node_array_list = node_array_per_cell.itemArrays(cell_id); + auto cell_table = node_array_per_cell.itemTable(cell_id); for (size_t i_node = 0; i_node < node_array_per_cell.numberOfSubArrays(cell_id); ++i_node) { - auto node_array = node_array_list[i_node]; + auto node_array = cell_table[i_node]; for (size_t i = 0; i < node_array.size(); ++i) { node_array[i] = cell_id + i_node + i; } @@ -769,8 +805,10 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { bool is_same = true; - for (size_t i = 0; i < copy_node_array_per_cell.numberOfValues(); ++i) { - is_same &= (copy_node_array_per_cell[i] == node_array_per_cell[i]); + for (size_t i = 0; i < copy_node_array_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < node_array_per_cell.sizeOfArrays(); ++j) { + is_same &= (copy_node_array_per_cell[i][j] == node_array_per_cell[i][j]); + } } REQUIRE(not is_same); @@ -784,9 +822,13 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") const Connectivity<2>& connectivity = mesh_2d.connectivity(); WeakFaceArrayPerCell<int> weak_face_array_per_cell{connectivity, 3}; - - for (size_t i = 0; i < weak_face_array_per_cell.numberOfValues(); ++i) { - weak_face_array_per_cell[i] = i; + { + size_t k = 0; + for (size_t i = 0; i < weak_face_array_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < weak_face_array_per_cell.sizeOfArrays(); ++j, ++k) { + weak_face_array_per_cell[i][j] = k; + } + } } FaceArrayPerCell<const int> face_array_per_cell{weak_face_array_per_cell}; @@ -795,8 +837,10 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") REQUIRE(face_array_per_cell.sizeOfArrays() == weak_face_array_per_cell.sizeOfArrays()); bool is_same = true; - for (size_t i = 0; i < weak_face_array_per_cell.numberOfValues(); ++i) { - is_same &= (face_array_per_cell[i] == weak_face_array_per_cell[i]); + for (size_t i = 0; i < weak_face_array_per_cell.numberOfArrays(); ++i) { + for (size_t j = 0; j < weak_face_array_per_cell.sizeOfArrays(); ++j) { + is_same &= (face_array_per_cell[i][j] == weak_face_array_per_cell[i][j]); + } } REQUIRE(is_same); } @@ -808,37 +852,37 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") { CellArrayPerNode<int> cell_array_per_node; REQUIRE_THROWS_AS(cell_array_per_node[0], AssertError); - REQUIRE_THROWS_AS(cell_array_per_node.itemArrays(NodeId{0}), AssertError); + REQUIRE_THROWS_AS(cell_array_per_node.itemTable(NodeId{0}), AssertError); REQUIRE_THROWS_AS(cell_array_per_node(NodeId{0}, 0), AssertError); REQUIRE_THROWS_AS(cell_array_per_node.sizeOfArrays(), AssertError); - REQUIRE_THROWS_AS(cell_array_per_node.numberOfValues(), AssertError); + REQUIRE_THROWS_AS(cell_array_per_node.numberOfArrays(), AssertError); REQUIRE_THROWS_AS(cell_array_per_node.numberOfItems(), AssertError); REQUIRE_THROWS_AS(cell_array_per_node.numberOfSubArrays(NodeId{0}), AssertError); FaceArrayPerCell<int> face_array_per_cell; REQUIRE_THROWS_AS(face_array_per_cell[0], AssertError); - REQUIRE_THROWS_AS(face_array_per_cell.itemArrays(CellId{0}), AssertError); + REQUIRE_THROWS_AS(face_array_per_cell.itemTable(CellId{0}), AssertError); REQUIRE_THROWS_AS(face_array_per_cell(CellId{0}, 0), AssertError); REQUIRE_THROWS_AS(face_array_per_cell.sizeOfArrays(), AssertError); - REQUIRE_THROWS_AS(face_array_per_cell.numberOfValues(), AssertError); + REQUIRE_THROWS_AS(face_array_per_cell.numberOfArrays(), AssertError); REQUIRE_THROWS_AS(face_array_per_cell.numberOfItems(), AssertError); REQUIRE_THROWS_AS(face_array_per_cell.numberOfSubArrays(CellId{0}), AssertError); CellArrayPerEdge<int> cell_array_per_edge; REQUIRE_THROWS_AS(cell_array_per_edge[0], AssertError); - REQUIRE_THROWS_AS(cell_array_per_edge.itemArrays(EdgeId{0}), AssertError); + REQUIRE_THROWS_AS(cell_array_per_edge.itemTable(EdgeId{0}), AssertError); REQUIRE_THROWS_AS(cell_array_per_edge(EdgeId{0}, 0), AssertError); REQUIRE_THROWS_AS(cell_array_per_edge.sizeOfArrays(), AssertError); - REQUIRE_THROWS_AS(cell_array_per_edge.numberOfValues(), AssertError); + REQUIRE_THROWS_AS(cell_array_per_edge.numberOfArrays(), AssertError); REQUIRE_THROWS_AS(cell_array_per_edge.numberOfItems(), AssertError); REQUIRE_THROWS_AS(cell_array_per_edge.numberOfSubArrays(EdgeId{0}), AssertError); NodeArrayPerFace<int> node_array_per_face; REQUIRE_THROWS_AS(node_array_per_face[0], AssertError); - REQUIRE_THROWS_AS(node_array_per_face.itemArrays(FaceId{0}), AssertError); + REQUIRE_THROWS_AS(node_array_per_face.itemTable(FaceId{0}), AssertError); REQUIRE_THROWS_AS(node_array_per_face(FaceId{0}, 0), AssertError); REQUIRE_THROWS_AS(node_array_per_face.sizeOfArrays(), AssertError); - REQUIRE_THROWS_AS(node_array_per_face.numberOfValues(), AssertError); + REQUIRE_THROWS_AS(node_array_per_face.numberOfArrays(), AssertError); REQUIRE_THROWS_AS(node_array_per_face.numberOfItems(), AssertError); REQUIRE_THROWS_AS(node_array_per_face.numberOfSubArrays(FaceId{0}), AssertError); } @@ -854,13 +898,13 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") REQUIRE_THROWS_AS(cell_array_per_face(invalid_face_id, 0), AssertError); } if (connectivity.numberOfFaces() > 0) { - FaceId face_id = 0; - const auto& cell_arrays = cell_array_per_face.itemArrays(face_id); - REQUIRE_THROWS_AS(cell_array_per_face(face_id, cell_arrays.size()), AssertError); - REQUIRE_THROWS_AS(cell_arrays[cell_arrays.size()], AssertError); - REQUIRE_THROWS_AS(cell_array_per_face.itemArrays(face_id)[cell_arrays.size()], AssertError); - REQUIRE_THROWS_AS(cell_array_per_face.itemArrays(face_id)[0][cell_array_per_face.sizeOfArrays()], AssertError); - REQUIRE_THROWS_AS(cell_array_per_face.itemArrays(face_id)[0][cell_array_per_face.sizeOfArrays()] = 2, + FaceId face_id = 0; + const auto& face_table = cell_array_per_face.itemTable(face_id); + REQUIRE_THROWS_AS(cell_array_per_face(face_id, face_table.nbRows()), AssertError); + REQUIRE_THROWS_AS(face_table[face_table.nbRows()], AssertError); + REQUIRE_THROWS_AS(cell_array_per_face.itemTable(face_id)[face_table.nbRows()], AssertError); + REQUIRE_THROWS_AS(cell_array_per_face.itemTable(face_id)[0][cell_array_per_face.sizeOfArrays()], AssertError); + REQUIRE_THROWS_AS(cell_array_per_face.itemTable(face_id)[0][cell_array_per_face.sizeOfArrays()] = 2, AssertError); } @@ -870,13 +914,13 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") REQUIRE_THROWS_AS(face_array_per_node(invalid_node_id, 0), AssertError); } if (connectivity.numberOfNodes() > 0) { - NodeId node_id = 0; - const auto& face_arrays = face_array_per_node.itemArrays(node_id); - REQUIRE_THROWS_AS(face_array_per_node(node_id, face_arrays.size()), AssertError); - REQUIRE_THROWS_AS(face_arrays[face_arrays.size()], AssertError); - REQUIRE_THROWS_AS(face_array_per_node.itemArrays(node_id)[face_arrays.size()], AssertError); - REQUIRE_THROWS_AS(face_array_per_node.itemArrays(node_id)[0][face_array_per_node.sizeOfArrays()], AssertError); - REQUIRE_THROWS_AS(face_array_per_node.itemArrays(node_id)[0][face_array_per_node.sizeOfArrays()] = 2, + NodeId node_id = 0; + const auto& node_table = face_array_per_node.itemTable(node_id); + REQUIRE_THROWS_AS(face_array_per_node(node_id, node_table.nbRows()), AssertError); + REQUIRE_THROWS_AS(node_table[node_table.nbRows()], AssertError); + REQUIRE_THROWS_AS(face_array_per_node.itemTable(node_id)[node_table.nbRows()], AssertError); + REQUIRE_THROWS_AS(face_array_per_node.itemTable(node_id)[0][face_array_per_node.sizeOfArrays()], AssertError); + REQUIRE_THROWS_AS(face_array_per_node.itemTable(node_id)[0][face_array_per_node.sizeOfArrays()] = 2, AssertError); } @@ -886,13 +930,13 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") REQUIRE_THROWS_AS(edge_array_per_cell(invalid_cell_id, 0), AssertError); } if (connectivity.numberOfCells() > 0) { - CellId cell_id = 0; - const auto& edge_arrays = edge_array_per_cell.itemArrays(cell_id); - REQUIRE_THROWS_AS(edge_array_per_cell(cell_id, edge_arrays.size()), AssertError); - REQUIRE_THROWS_AS(edge_arrays[edge_arrays.size()], AssertError); - REQUIRE_THROWS_AS(edge_array_per_cell.itemArrays(cell_id)[edge_arrays.size()], AssertError); - REQUIRE_THROWS_AS(edge_array_per_cell.itemArrays(cell_id)[0][edge_array_per_cell.sizeOfArrays()], AssertError); - REQUIRE_THROWS_AS(edge_array_per_cell.itemArrays(cell_id)[0][edge_array_per_cell.sizeOfArrays()] == 2, + CellId cell_id = 0; + const auto& cell_table = edge_array_per_cell.itemTable(cell_id); + REQUIRE_THROWS_AS(edge_array_per_cell(cell_id, cell_table.nbRows()), AssertError); + REQUIRE_THROWS_AS(cell_table[cell_table.nbRows()], AssertError); + REQUIRE_THROWS_AS(edge_array_per_cell.itemTable(cell_id)[cell_table.nbRows()], AssertError); + REQUIRE_THROWS_AS(edge_array_per_cell.itemTable(cell_id)[0][edge_array_per_cell.sizeOfArrays()], AssertError); + REQUIRE_THROWS_AS(edge_array_per_cell.itemTable(cell_id)[0][edge_array_per_cell.sizeOfArrays()] == 2, AssertError); } @@ -902,13 +946,13 @@ TEST_CASE("SubItemArrayPerItem", "[mesh]") REQUIRE_THROWS_AS(node_array_per_edge(invalid_edge_id, 0), AssertError); } if (connectivity.numberOfEdges() > 0) { - EdgeId edge_id = 0; - const auto& node_arrays = node_array_per_edge.itemArrays(edge_id); - REQUIRE_THROWS_AS(node_array_per_edge(edge_id, node_arrays.size()), AssertError); - REQUIRE_THROWS_AS(node_arrays[node_arrays.size()], AssertError); - REQUIRE_THROWS_AS(node_array_per_edge.itemArrays(edge_id)[node_arrays.size()], AssertError); - REQUIRE_THROWS_AS(node_array_per_edge.itemArrays(edge_id)[0][node_array_per_edge.sizeOfArrays()], AssertError); - REQUIRE_THROWS_AS(node_array_per_edge.itemArrays(edge_id)[0][node_array_per_edge.sizeOfArrays()] = 2, + EdgeId edge_id = 0; + const auto& edge_table = node_array_per_edge.itemTable(edge_id); + REQUIRE_THROWS_AS(node_array_per_edge(edge_id, edge_table.nbRows()), AssertError); + REQUIRE_THROWS_AS(edge_table[edge_table.nbRows()], AssertError); + REQUIRE_THROWS_AS(node_array_per_edge.itemTable(edge_id)[edge_table.nbRows()], AssertError); + REQUIRE_THROWS_AS(node_array_per_edge.itemTable(edge_id)[0][node_array_per_edge.sizeOfArrays()], AssertError); + REQUIRE_THROWS_AS(node_array_per_edge.itemTable(edge_id)[0][node_array_per_edge.sizeOfArrays()] = 2, AssertError); } } diff --git a/tests/test_Table.cpp b/tests/test_Table.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7b736f3d76f87129b45885fed737a361bf73562e --- /dev/null +++ b/tests/test_Table.cpp @@ -0,0 +1,171 @@ +#include <catch2/catch_test_macros.hpp> +#include <catch2/matchers/catch_matchers_all.hpp> + +#include <utils/PugsAssert.hpp> +#include <utils/Table.hpp> +#include <utils/Types.hpp> + +// Instantiate to ensure full coverage is performed +template class Table<int>; + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("Table", "[utils]") +{ + Table<int> a(4, 3); + REQUIRE(a.nbRows() == 4); + REQUIRE(a.nbColumns() == 3); + REQUIRE(a[0].size() == 3); + REQUIRE(a[1].size() == 3); + REQUIRE(a[2].size() == 3); + REQUIRE(a[3].size() == 3); + + for (size_t i = 0; i < a.nbRows(); ++i) { + for (size_t j = 0; j < a.nbColumns(); ++j) { + a(i, j) = 2 * i + j; + } + } + + REQUIRE(((a(0, 0) == 0) and (a(1, 0) == 2) and (a(2, 0) == 4) and (a(3, 0) == 6) and // + (a(0, 1) == 1) and (a(1, 1) == 3) and (a(2, 1) == 5) and (a(3, 1) == 7) and // + (a(0, 2) == 2) and (a(1, 2) == 4) and (a(2, 2) == 6) and (a(3, 2) == 8))); + + SECTION("checking for rows") + { + REQUIRE(((a[0][0] == 0) and (a[1][0] == 2) and (a[2][0] == 4) and (a[3][0] == 6) and // + (a[0][1] == 1) and (a[1][1] == 3) and (a[2][1] == 5) and (a[3][1] == 7) and // + (a[0][2] == 2) and (a[1][2] == 4) and (a[2][2] == 6) and (a[3][2] == 8))); + + a[2][1] = 17; + REQUIRE(a[2][1] == a(2, 1)); + a[2][1] = 5; + } + + SECTION("checking for copies") + { + Table<const int> b{a}; + + REQUIRE(((b(0, 0) == 0) and (b(1, 0) == 2) and (b(2, 0) == 4) and (b(3, 0) == 6) and // + (b(0, 1) == 1) and (b(1, 1) == 3) and (b(2, 1) == 5) and (b(3, 1) == 7) and // + (b(0, 2) == 2) and (b(1, 2) == 4) and (b(2, 2) == 6) and (b(3, 2) == 8))); + + Table<int> c{a}; + + REQUIRE(((c(0, 0) == 0) and (c(1, 0) == 2) and (c(2, 0) == 4) and (c(3, 0) == 6) and // + (c(0, 1) == 1) and (c(1, 1) == 3) and (c(2, 1) == 5) and (c(3, 1) == 7) and // + (c(0, 2) == 2) and (c(1, 2) == 4) and (c(2, 2) == 6) and (c(3, 2) == 8))); + + Table<int> d = std::move(c); + + REQUIRE(((d(0, 0) == 0) and (d(1, 0) == 2) and (d(2, 0) == 4) and (d(3, 0) == 6) and // + (d(0, 1) == 1) and (d(1, 1) == 3) and (d(2, 1) == 5) and (d(3, 1) == 7) and // + (d(0, 2) == 2) and (d(1, 2) == 4) and (d(2, 2) == 6) and (d(3, 2) == 8))); + + a(2, 2) = 17; + + REQUIRE(a(2, 2) == 17); + REQUIRE(b(2, 2) == 17); + REQUIRE(d(2, 2) == 17); + + a(2, 2) = 6; + + REQUIRE(a(2, 2) == 6); + REQUIRE(b(2, 2) == 6); + REQUIRE(d(2, 2) == 6); + } + + SECTION("checking for fill") + { + Table<int> b(3, 2); + b.fill(3); + + REQUIRE(((b(0, 0) == 3) and (b(1, 0) == 3) and (b(2, 0) == 3) and // + (b(0, 1) == 3) and (b(1, 1) == 3) and (b(2, 1) == 3))); + } + + SECTION("checking for affectations (shallow copy)") + { + Table<const int> b; + b = a; + + REQUIRE(((b(0, 0) == 0) and (b(1, 0) == 2) and (b(2, 0) == 4) and (b(3, 0) == 6) and // + (b(0, 1) == 1) and (b(1, 1) == 3) and (b(2, 1) == 5) and (b(3, 1) == 7) and // + (b(0, 2) == 2) and (b(1, 2) == 4) and (b(2, 2) == 6) and (b(3, 2) == 8))); + + Table<int> c; + c = a; + + REQUIRE(((c(0, 0) == 0) and (c(1, 0) == 2) and (c(2, 0) == 4) and (c(3, 0) == 6) and // + (c(0, 1) == 1) and (c(1, 1) == 3) and (c(2, 1) == 5) and (c(3, 1) == 7) and // + (c(0, 2) == 2) and (c(1, 2) == 4) and (c(2, 2) == 6) and (c(3, 2) == 8))); + + Table<int> d; + d = std::move(c); + + REQUIRE(((d(0, 0) == 0) and (d(1, 0) == 2) and (d(2, 0) == 4) and (d(3, 0) == 6) and // + (d(0, 1) == 1) and (d(1, 1) == 3) and (d(2, 1) == 5) and (d(3, 1) == 7) and // + (d(0, 2) == 2) and (d(1, 2) == 4) and (d(2, 2) == 6) and (d(3, 2) == 8))); + } + + SECTION("checking for affectations (deep copy)") + { + Table<int> b(copy(a)); + + REQUIRE(((b(0, 0) == 0) and (b(1, 0) == 2) and (b(2, 0) == 4) and (b(3, 0) == 6) and // + (b(0, 1) == 1) and (b(1, 1) == 3) and (b(2, 1) == 5) and (b(3, 1) == 7) and // + (b(0, 2) == 2) and (b(1, 2) == 4) and (b(2, 2) == 6) and (b(3, 2) == 8))); + + b.fill(2); + + REQUIRE(((b(0, 0) == 2) and (b(1, 0) == 2) and (b(2, 0) == 2) and (b(3, 0) == 2) and // + (b(0, 1) == 2) and (b(1, 1) == 2) and (b(2, 1) == 2) and (b(3, 1) == 2) and // + (b(0, 2) == 2) and (b(1, 2) == 2) and (b(2, 2) == 2) and (b(3, 2) == 2))); + + REQUIRE(((a(0, 0) == 0) and (a(1, 0) == 2) and (a(2, 0) == 4) and (a(3, 0) == 6) and // + (a(0, 1) == 1) and (a(1, 1) == 3) and (a(2, 1) == 5) and (a(3, 1) == 7) and // + (a(0, 2) == 2) and (a(1, 2) == 4) and (a(2, 2) == 6) and (a(3, 2) == 8))); + + Table<int> c; + c = a; + + REQUIRE(((c(0, 0) == 0) and (c(1, 0) == 2) and (c(2, 0) == 4) and (c(3, 0) == 6) and // + (c(0, 1) == 1) and (c(1, 1) == 3) and (c(2, 1) == 5) and (c(3, 1) == 7) and // + (c(0, 2) == 2) and (c(1, 2) == 4) and (c(2, 2) == 6) and (c(3, 2) == 8))); + + c = copy(b); + + REQUIRE(((c(0, 0) == 2) and (c(1, 0) == 2) and (c(2, 0) == 2) and (c(3, 0) == 2) and // + (c(0, 1) == 2) and (c(1, 1) == 2) and (c(2, 1) == 2) and (c(3, 1) == 2) and // + (c(0, 2) == 2) and (c(1, 2) == 2) and (c(2, 2) == 2) and (c(3, 2) == 2))); + } + + SECTION("checking for Kokkos::View encaspulation") + { + { + Kokkos::View<double**> kokkos_view("anonymous", 10, 3); + for (size_t i = 0; i < 10; ++i) { + for (size_t j = 0; j < 3; ++j) { + kokkos_view(i, j) = 3 * i + j; + } + } + + Table table = encapsulate(kokkos_view); + + REQUIRE(table.nbRows() == kokkos_view.extent(0)); + REQUIRE(table.nbColumns() == kokkos_view.extent(1)); + for (size_t i = 0; i < table.nbRows(); ++i) { + for (size_t j = 0; j < table.nbColumns(); ++j) { + REQUIRE(&table(i, j) == &kokkos_view(i, j)); + } + } + } + } + +#ifndef NDEBUG + SECTION("checking for bounds violation") + { + REQUIRE_THROWS_AS(a(4, 0), AssertError); + REQUIRE_THROWS_AS(a(0, 3), AssertError); + } +#endif // NDEBUG +}