Skip to content
Snippets Groups Projects
Commit 3800fbc5 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add SubItemArrayPerArray

parent 83cd8774
Branches
Tags
1 merge request!84Add SubArray class
...@@ -13,6 +13,9 @@ class IConnectivity : public std::enable_shared_from_this<IConnectivity> ...@@ -13,6 +13,9 @@ class IConnectivity : public std::enable_shared_from_this<IConnectivity>
template <typename DataType, typename ItemOfItem, typename ConnectivityPtr> template <typename DataType, typename ItemOfItem, typename ConnectivityPtr>
friend class SubItemValuePerItem; friend class SubItemValuePerItem;
template <typename DataType, typename ItemOfItem, typename ConnectivityPtr>
friend class SubItemArrayPerItem;
virtual const ConnectivityMatrix& _getMatrix(const ItemType& item_type_0, const ItemType& item_type_1) const = 0; virtual const ConnectivityMatrix& _getMatrix(const ItemType& item_type_0, const ItemType& item_type_1) const = 0;
public: public:
......
#ifndef SUBITEM_ARRAY_PER_ITEM_HPP
#define SUBITEM_ARRAY_PER_ITEM_HPP
#include <mesh/ConnectivityMatrix.hpp>
#include <mesh/IConnectivity.hpp>
#include <mesh/ItemId.hpp>
#include <mesh/ItemOfItemType.hpp>
#include <mesh/ItemType.hpp>
#include <utils/Array.hpp>
#include <utils/PugsAssert.hpp>
#include <utils/SubArray.hpp>
#include <memory>
template <typename DataType, typename ItemOfItem, typename ConnectivityPtr = std::shared_ptr<const IConnectivity>>
class SubItemArrayPerItem
{
public:
static constexpr ItemType item_type{ItemOfItem::item_type};
static constexpr ItemType sub_item_type{ItemOfItem::sub_item_type};
using ItemOfItemType = ItemOfItem;
using data_type = DataType;
using ItemId = ItemIdT<item_type>;
using index_type = ItemId;
private:
using ConnectivitySharedPtr = std::shared_ptr<const IConnectivity>;
using ConnectivityWeakPtr = std::weak_ptr<const IConnectivity>;
static_assert(std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr> or
std::is_same_v<ConnectivityPtr, ConnectivityWeakPtr>);
ConnectivityPtr m_connectivity_ptr;
typename ConnectivityMatrix::HostRowType m_host_row_map;
Array<DataType> m_arrays_values;
size_t m_size_of_arrays;
// Allow const std:shared_ptr version to access our data
friend SubItemArrayPerItem<std::add_const_t<DataType>, ItemOfItem, ConnectivitySharedPtr>;
// Allow const std:weak_ptr version to access our data
friend SubItemArrayPerItem<std::add_const_t<DataType>, ItemOfItem, ConnectivityWeakPtr>;
// Allow const std:shared_ptr version to access our data
friend SubItemArrayPerItem<std::remove_const_t<DataType>, ItemOfItem, ConnectivitySharedPtr>;
// Allow const std:weak_ptr version to access our data
friend SubItemArrayPerItem<std::remove_const_t<DataType>, ItemOfItem, ConnectivityWeakPtr>;
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)
{
SubItemArrayPerItem<std::remove_const_t<DataType>, ItemOfItem, ConnectivityPtr> image;
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;
return image;
}
PUGS_INLINE
bool
isBuilt() const noexcept
{
return m_connectivity_ptr.use_count() != 0;
}
PUGS_INLINE
std::shared_ptr<const IConnectivity>
connectivity_ptr() const noexcept
{
if constexpr (std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr>) {
return m_connectivity_ptr;
} else {
return m_connectivity_ptr.lock();
}
}
template <typename IndexType, typename SubIndexType>
PUGS_FORCEINLINE SubArray<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);
}
// 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)
{
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];
}
PUGS_INLINE
size_t
numberOfValues() const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
return m_arrays_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) - 1;
}
PUGS_INLINE size_t
sizeOfArrays() const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
return m_size_of_arrays;
}
template <typename IndexType>
PUGS_INLINE size_t
numberOfSubArrays(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());
return m_host_row_map(size_t{item_id} + 1) - m_host_row_map(size_t{item_id});
}
template <typename IndexType>
PUGS_INLINE SubView
itemArrays(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);
}
// 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)
{
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);
}
template <typename DataType2, typename ConnectivityPtr2>
PUGS_INLINE SubItemArrayPerItem&
operator=(const SubItemArrayPerItem<DataType2, ItemOfItem, ConnectivityPtr2>& sub_item_array_per_item) noexcept
{
// ensures that DataType is the same as source DataType2
static_assert(std::is_same_v<std::remove_const_t<DataType>, std::remove_const_t<DataType2>>,
"Cannot assign SubItemArrayPerItem of different type");
// ensures that const is not lost through copy
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;
if constexpr (std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr> and
std::is_same_v<ConnectivityPtr2, ConnectivityWeakPtr>) {
m_connectivity_ptr = sub_item_array_per_item.m_connectivity_ptr.lock();
} else {
m_connectivity_ptr = sub_item_array_per_item.m_connectivity_ptr;
}
return *this;
}
template <typename DataType2, typename ConnectivityPtr2>
PUGS_INLINE
SubItemArrayPerItem(
const SubItemArrayPerItem<DataType2, ItemOfItem, ConnectivityPtr2>& sub_item_array_per_item) noexcept
{
this->operator=(sub_item_array_per_item);
}
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)
{
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);
}
~SubItemArrayPerItem() = default;
};
// Item arrays at nodes
template <typename DataType>
using NodeArrayPerEdge = SubItemArrayPerItem<DataType, NodeOfEdge>;
template <typename DataType>
using NodeArrayPerFace = SubItemArrayPerItem<DataType, NodeOfFace>;
template <typename DataType>
using NodeArrayPerCell = SubItemArrayPerItem<DataType, NodeOfCell>;
// Item arrays at edges
template <typename DataType>
using EdgeArrayPerNode = SubItemArrayPerItem<DataType, EdgeOfNode>;
template <typename DataType>
using EdgeArrayPerFace = SubItemArrayPerItem<DataType, EdgeOfFace>;
template <typename DataType>
using EdgeArrayPerCell = SubItemArrayPerItem<DataType, EdgeOfCell>;
// Item arrays at faces
template <typename DataType>
using FaceArrayPerNode = SubItemArrayPerItem<DataType, FaceOfNode>;
template <typename DataType>
using FaceArrayPerEdge = SubItemArrayPerItem<DataType, FaceOfEdge>;
template <typename DataType>
using FaceArrayPerCell = SubItemArrayPerItem<DataType, FaceOfCell>;
// Item arrays at cells
template <typename DataType>
using CellArrayPerNode = SubItemArrayPerItem<DataType, CellOfNode>;
template <typename DataType>
using CellArrayPerEdge = SubItemArrayPerItem<DataType, CellOfEdge>;
template <typename DataType>
using CellArrayPerFace = SubItemArrayPerItem<DataType, CellOfFace>;
// Weak versions: should not be used outside of Connectivity
// Item arrays at nodes
template <typename DataType, typename ItemOfItem>
using WeakSubItemArrayPerItem = SubItemArrayPerItem<DataType, ItemOfItem, std::weak_ptr<const IConnectivity>>;
template <typename DataType>
using WeakNodeArrayPerEdge = WeakSubItemArrayPerItem<DataType, NodeOfEdge>;
template <typename DataType>
using WeakNodeArrayPerFace = WeakSubItemArrayPerItem<DataType, NodeOfFace>;
template <typename DataType>
using WeakNodeArrayPerCell = WeakSubItemArrayPerItem<DataType, NodeOfCell>;
// Item arrays at edges
template <typename DataType>
using WeakEdgeArrayPerNode = WeakSubItemArrayPerItem<DataType, EdgeOfNode>;
template <typename DataType>
using WeakEdgeArrayPerFace = WeakSubItemArrayPerItem<DataType, EdgeOfFace>;
template <typename DataType>
using WeakEdgeArrayPerCell = WeakSubItemArrayPerItem<DataType, EdgeOfCell>;
// Item arrays at faces
template <typename DataType>
using WeakFaceArrayPerNode = WeakSubItemArrayPerItem<DataType, FaceOfNode>;
template <typename DataType>
using WeakFaceArrayPerEdge = WeakSubItemArrayPerItem<DataType, FaceOfEdge>;
template <typename DataType>
using WeakFaceArrayPerCell = WeakSubItemArrayPerItem<DataType, FaceOfCell>;
// Item arrays at cells
template <typename DataType>
using WeakCellArrayPerNode = WeakSubItemArrayPerItem<DataType, CellOfNode>;
template <typename DataType>
using WeakCellArrayPerEdge = WeakSubItemArrayPerItem<DataType, CellOfEdge>;
template <typename DataType>
using WeakCellArrayPerFace = WeakSubItemArrayPerItem<DataType, CellOfFace>;
#endif // SUBITEM_ARRAY_PER_ITEM_HPP
...@@ -105,6 +105,7 @@ add_executable (mpi_unit_tests ...@@ -105,6 +105,7 @@ add_executable (mpi_unit_tests
test_ItemValue.cpp test_ItemValue.cpp
test_ItemValueUtils.cpp test_ItemValueUtils.cpp
test_SubItemValuePerItem.cpp test_SubItemValuePerItem.cpp
test_SubItemArrayPerItem.cpp
) )
add_library(test_Pugs_MeshDataBase add_library(test_Pugs_MeshDataBase
......
#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/SubItemArrayPerItem.hpp>
#include <utils/Messenger.hpp>
// Instantiate to ensure full coverage is performed
template class SubItemArrayPerItem<size_t, NodeOfCell>;
// clazy:excludeall=non-pod-global-static
TEST_CASE("SubItemArrayPerItem", "[mesh]")
{
SECTION("default constructors")
{
REQUIRE_NOTHROW(NodeArrayPerEdge<int>{});
REQUIRE_NOTHROW(NodeArrayPerFace<int>{});
REQUIRE_NOTHROW(NodeArrayPerCell<int>{});
REQUIRE_NOTHROW(EdgeArrayPerNode<int>{});
REQUIRE_NOTHROW(EdgeArrayPerFace<int>{});
REQUIRE_NOTHROW(EdgeArrayPerCell<int>{});
REQUIRE_NOTHROW(FaceArrayPerNode<int>{});
REQUIRE_NOTHROW(FaceArrayPerEdge<int>{});
REQUIRE_NOTHROW(FaceArrayPerCell<int>{});
REQUIRE_NOTHROW(CellArrayPerNode<int>{});
REQUIRE_NOTHROW(CellArrayPerEdge<int>{});
REQUIRE_NOTHROW(CellArrayPerFace<int>{});
REQUIRE(not NodeArrayPerEdge<int>{}.isBuilt());
REQUIRE(not NodeArrayPerFace<int>{}.isBuilt());
REQUIRE(not NodeArrayPerCell<int>{}.isBuilt());
REQUIRE(not EdgeArrayPerNode<int>{}.isBuilt());
REQUIRE(not EdgeArrayPerFace<int>{}.isBuilt());
REQUIRE(not EdgeArrayPerCell<int>{}.isBuilt());
REQUIRE(not FaceArrayPerNode<int>{}.isBuilt());
REQUIRE(not FaceArrayPerEdge<int>{}.isBuilt());
REQUIRE(not FaceArrayPerCell<int>{}.isBuilt());
REQUIRE(not CellArrayPerNode<int>{}.isBuilt());
REQUIRE(not CellArrayPerEdge<int>{}.isBuilt());
REQUIRE(not CellArrayPerFace<int>{}.isBuilt());
}
SECTION("dimensions")
{
auto number_of_values = [](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();
}
}
return number;
};
SECTION("1D")
{
const Mesh<Connectivity<1>>& mesh_1d = MeshDataBaseForTests::get().cartesianMesh<1>();
const Connectivity<1>& connectivity = mesh_1d.connectivity();
SECTION("per cell")
{
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.sizeOfArrays() == 3);
auto cell_to_node_matrix = connectivity.cellToNodeMatrix();
{
bool is_correct = true;
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));
}
REQUIRE(is_correct);
}
const NodeArrayPerCell<const int> const_node_array_per_cell = node_array_per_cell;
{
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));
}
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.sizeOfArrays() == 4);
auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix();
{
bool is_correct = true;
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
is_correct &= (cell_to_edge_matrix[cell_id].size() == edge_array_per_cell.numberOfSubArrays(cell_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 2);
auto cell_to_face_matrix = connectivity.cellToFaceMatrix();
{
bool is_correct = true;
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
is_correct &= (cell_to_face_matrix[cell_id].size() == face_array_per_cell.numberOfSubArrays(cell_id));
}
REQUIRE(is_correct);
}
}
SECTION("per face")
{
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.sizeOfArrays() == 2);
auto face_to_cell_matrix = connectivity.faceToCellMatrix();
{
bool is_correct = true;
for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
is_correct &= (face_to_cell_matrix[face_id].size() == cell_array_per_face.numberOfSubArrays(face_id));
}
REQUIRE(is_correct);
}
}
SECTION("per edge")
{
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.sizeOfArrays() == 3);
auto edge_to_cell_matrix = connectivity.edgeToCellMatrix();
{
bool is_correct = true;
for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
is_correct &= (edge_to_cell_matrix[edge_id].size() == cell_array_per_edge.numberOfSubArrays(edge_id));
}
REQUIRE(is_correct);
}
}
SECTION("per node")
{
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.sizeOfArrays() == 4);
auto node_to_cell_matrix = connectivity.nodeToCellMatrix();
{
bool is_correct = true;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
is_correct &= (node_to_cell_matrix[node_id].size() == cell_array_per_node.numberOfSubArrays(node_id));
}
REQUIRE(is_correct);
}
}
}
SECTION("2D")
{
const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>();
const Connectivity<2>& connectivity = mesh_2d.connectivity();
SECTION("per cell")
{
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.sizeOfArrays() == 5);
auto cell_to_node_matrix = connectivity.cellToNodeMatrix();
{
bool is_correct = true;
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));
}
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.sizeOfArrays() == 4);
auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix();
{
bool is_correct = true;
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
is_correct &= (cell_to_edge_matrix[cell_id].size() == edge_array_per_cell.numberOfSubArrays(cell_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 3);
auto cell_to_face_matrix = connectivity.cellToFaceMatrix();
{
bool is_correct = true;
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
is_correct &= (cell_to_face_matrix[cell_id].size() == face_array_per_cell.numberOfSubArrays(cell_id));
}
REQUIRE(is_correct);
}
}
SECTION("per face")
{
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.sizeOfArrays() == 3);
auto face_to_cell_matrix = connectivity.faceToCellMatrix();
{
bool is_correct = true;
for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
is_correct &= (face_to_cell_matrix[face_id].size() == cell_array_per_face.numberOfSubArrays(face_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 2);
auto face_to_node_matrix = connectivity.faceToNodeMatrix();
{
bool is_correct = true;
for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
is_correct &= (face_to_node_matrix[face_id].size() == node_array_per_face.numberOfSubArrays(face_id));
}
REQUIRE(is_correct);
}
}
SECTION("per edge")
{
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.sizeOfArrays() == 3);
auto edge_to_cell_matrix = connectivity.edgeToCellMatrix();
{
bool is_correct = true;
for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
is_correct &= (edge_to_cell_matrix[edge_id].size() == cell_array_per_edge.numberOfSubArrays(edge_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 5);
auto edge_to_node_matrix = connectivity.edgeToNodeMatrix();
{
bool is_correct = true;
for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
is_correct &= (edge_to_node_matrix[edge_id].size() == node_array_per_edge.numberOfSubArrays(edge_id));
}
REQUIRE(is_correct);
}
}
SECTION("per node")
{
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.sizeOfArrays() == 4);
auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix();
{
bool is_correct = true;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
is_correct &= (node_to_edge_matrix[node_id].size() == edge_array_per_node.numberOfSubArrays(node_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 3);
auto node_to_face_matrix = connectivity.nodeToFaceMatrix();
{
bool is_correct = true;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
is_correct &= (node_to_face_matrix[node_id].size() == face_array_per_node.numberOfSubArrays(node_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 2);
auto node_to_cell_matrix = connectivity.nodeToCellMatrix();
{
bool is_correct = true;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
is_correct &= (node_to_cell_matrix[node_id].size() == cell_array_per_node.numberOfSubArrays(node_id));
}
REQUIRE(is_correct);
}
}
}
SECTION("3D")
{
const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>();
const Connectivity<3>& connectivity = mesh_3d.connectivity();
SECTION("per cell")
{
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.sizeOfArrays() == 3);
auto cell_to_node_matrix = connectivity.cellToNodeMatrix();
{
bool is_correct = true;
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));
}
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.sizeOfArrays() == 4);
auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix();
{
bool is_correct = true;
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
is_correct &= (cell_to_edge_matrix[cell_id].size() == edge_array_per_cell.numberOfSubArrays(cell_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 3);
auto cell_to_face_matrix = connectivity.cellToFaceMatrix();
{
bool is_correct = true;
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
is_correct &= (cell_to_face_matrix[cell_id].size() == face_array_per_cell.numberOfSubArrays(cell_id));
}
REQUIRE(is_correct);
}
}
SECTION("per face")
{
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.sizeOfArrays() == 5);
auto face_to_cell_matrix = connectivity.faceToCellMatrix();
{
bool is_correct = true;
for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
is_correct &= (face_to_cell_matrix[face_id].size() == cell_array_per_face.numberOfSubArrays(face_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 3);
auto face_to_edge_matrix = connectivity.faceToEdgeMatrix();
{
bool is_correct = true;
for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
is_correct &= (face_to_edge_matrix[face_id].size() == edge_array_per_face.numberOfSubArrays(face_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 2);
auto face_to_node_matrix = connectivity.faceToNodeMatrix();
{
bool is_correct = true;
for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
is_correct &= (face_to_node_matrix[face_id].size() == node_array_per_face.numberOfSubArrays(face_id));
}
REQUIRE(is_correct);
}
}
SECTION("per edge")
{
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.sizeOfArrays() == 3);
auto edge_to_cell_matrix = connectivity.edgeToCellMatrix();
{
bool is_correct = true;
for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
is_correct &= (edge_to_cell_matrix[edge_id].size() == cell_array_per_edge.numberOfSubArrays(edge_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 5);
auto edge_to_face_matrix = connectivity.edgeToFaceMatrix();
{
bool is_correct = true;
for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
is_correct &= (edge_to_face_matrix[edge_id].size() == face_array_per_edge.numberOfSubArrays(edge_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 3);
auto edge_to_node_matrix = connectivity.edgeToNodeMatrix();
{
bool is_correct = true;
for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
is_correct &= (edge_to_node_matrix[edge_id].size() == node_array_per_edge.numberOfSubArrays(edge_id));
}
REQUIRE(is_correct);
}
}
SECTION("per node")
{
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.sizeOfArrays() == 3);
auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix();
{
bool is_correct = true;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
is_correct &= (node_to_edge_matrix[node_id].size() == edge_array_per_node.numberOfSubArrays(node_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 4);
auto node_to_face_matrix = connectivity.nodeToFaceMatrix();
{
bool is_correct = true;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
is_correct &= (node_to_face_matrix[node_id].size() == face_array_per_node.numberOfSubArrays(node_id));
}
REQUIRE(is_correct);
}
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.sizeOfArrays() == 5);
auto node_to_cell_matrix = connectivity.nodeToCellMatrix();
{
bool is_correct = true;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
is_correct &= (node_to_cell_matrix[node_id].size() == cell_array_per_node.numberOfSubArrays(node_id));
}
REQUIRE(is_correct);
}
}
}
}
SECTION("array view")
{
SECTION("1D")
{
const Mesh<Connectivity<1>>& mesh_1d = MeshDataBaseForTests::get().cartesianMesh<1>();
const Connectivity<1>& connectivity = mesh_1d.connectivity();
EdgeArrayPerCell<size_t> edge_arrays_per_cell{connectivity, 3};
{
size_t array = 0;
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
for (size_t i_edge = 0; i_edge < edge_arrays_per_cell.numberOfSubArrays(cell_id); ++i_edge) {
for (size_t i = 0; i < edge_arrays_per_cell(cell_id, i_edge).size(); ++i) {
edge_arrays_per_cell(cell_id, i_edge)[i] = array++;
}
}
}
}
{
bool is_same = true;
for (size_t i = 0; i < edge_arrays_per_cell.numberOfValues(); ++i) {
is_same &= (edge_arrays_per_cell[i] == i);
}
REQUIRE(is_same);
}
for (size_t i = 0; i < edge_arrays_per_cell.numberOfValues(); ++i) {
edge_arrays_per_cell[i] = i * i + 1;
}
{
bool is_same = true;
size_t i = 0;
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
for (size_t i_edge = 0; i_edge < edge_arrays_per_cell.numberOfSubArrays(cell_id); ++i_edge) {
for (size_t l = 0; l < edge_arrays_per_cell(cell_id, i_edge).size(); ++l, ++i) {
is_same &= (edge_arrays_per_cell(cell_id, i_edge)[l] == i * i + 1);
}
}
}
REQUIRE(is_same);
}
}
SECTION("2D")
{
const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>();
const Connectivity<2>& connectivity = mesh_2d.connectivity();
CellArrayPerFace<size_t> cell_arrays_per_face{connectivity, 3};
{
size_t array = 0;
for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
for (size_t i_cell = 0; i_cell < cell_arrays_per_face.numberOfSubArrays(face_id); ++i_cell) {
for (size_t i = 0; i < cell_arrays_per_face(face_id, i_cell).size(); ++i) {
cell_arrays_per_face(face_id, i_cell)[i] = array++;
}
}
}
}
{
bool is_same = true;
for (size_t i = 0; i < cell_arrays_per_face.numberOfValues(); ++i) {
is_same &= (cell_arrays_per_face[i] == i);
}
REQUIRE(is_same);
}
for (size_t i = 0; i < cell_arrays_per_face.numberOfValues(); ++i) {
cell_arrays_per_face[i] = 3 * i + 1;
}
{
bool is_same = true;
size_t i = 0;
for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
for (size_t i_cell = 0; i_cell < cell_arrays_per_face.numberOfSubArrays(face_id); ++i_cell) {
for (size_t l = 0; l < cell_arrays_per_face(face_id, i_cell).size(); ++l, ++i) {
is_same &= (cell_arrays_per_face(face_id, i_cell)[l] == 3 * i + 1);
}
}
}
REQUIRE(is_same);
}
}
SECTION("3D")
{
const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>();
const Connectivity<3>& connectivity = mesh_3d.connectivity();
FaceArrayPerNode<size_t> face_arrays_per_node{connectivity, 3};
{
size_t array = 0;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
for (size_t i_face = 0; i_face < face_arrays_per_node.numberOfSubArrays(node_id); ++i_face) {
for (size_t i = 0; i < face_arrays_per_node(node_id, i_face).size(); ++i)
face_arrays_per_node(node_id, i_face)[i] = array++;
}
}
}
{
bool is_same = true;
for (size_t i = 0; i < face_arrays_per_node.numberOfValues(); ++i) {
is_same &= (face_arrays_per_node[i] == i);
}
REQUIRE(is_same);
}
for (size_t i = 0; i < face_arrays_per_node.numberOfValues(); ++i) {
face_arrays_per_node[i] = 3 + i * i;
}
{
bool is_same = true;
size_t i = 0;
for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
for (size_t i_face = 0; i_face < face_arrays_per_node.numberOfSubArrays(node_id); ++i_face) {
for (size_t l = 0; l < face_arrays_per_node(node_id, i_face).size(); ++l, ++i) {
is_same &= (face_arrays_per_node(node_id, i_face)[l] == 3 + i * i);
}
}
}
REQUIRE(is_same);
}
}
}
SECTION("copy")
{
const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>();
const Connectivity<3>& connectivity = mesh_3d.connectivity();
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;
}
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]);
}
REQUIRE(is_same);
}
{
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
auto node_array_list = node_array_per_cell.itemArrays(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];
for (size_t i = 0; i < node_array.size(); ++i) {
node_array[i] = cell_id + i_node + i;
}
}
}
}
{
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]);
}
REQUIRE(not is_same);
}
}
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;
}
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]);
}
REQUIRE(is_same);
}
{
for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
auto node_array_list = node_array_per_cell.itemArrays(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];
for (size_t i = 0; i < node_array.size(); ++i) {
node_array[i] = cell_id + i_node + i;
}
}
}
}
{
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]);
}
REQUIRE(not is_same);
}
}
}
SECTION("WeakSubItemArrayPerItem")
{
const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>();
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;
}
FaceArrayPerCell<const int> face_array_per_cell{weak_face_array_per_cell};
REQUIRE(face_array_per_cell.connectivity_ptr() == weak_face_array_per_cell.connectivity_ptr());
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]);
}
REQUIRE(is_same);
}
#ifndef NDEBUG
SECTION("error")
{
SECTION("checking for build SubItemArrayPerItem")
{
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(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.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(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.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(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.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(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.numberOfItems(), AssertError);
REQUIRE_THROWS_AS(node_array_per_face.numberOfSubArrays(FaceId{0}), AssertError);
}
SECTION("checking for bounds violation")
{
const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>();
const Connectivity<3>& connectivity = mesh_3d.connectivity();
CellArrayPerFace<int> cell_array_per_face{connectivity, 3};
{
FaceId invalid_face_id = connectivity.numberOfFaces();
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,
AssertError);
}
FaceArrayPerNode<int> face_array_per_node{connectivity, 5};
{
NodeId invalid_node_id = connectivity.numberOfNodes();
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,
AssertError);
}
EdgeArrayPerCell<int> edge_array_per_cell{connectivity, 3};
{
CellId invalid_cell_id = connectivity.numberOfCells();
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,
AssertError);
}
NodeArrayPerEdge<int> node_array_per_edge{connectivity, 3};
{
EdgeId invalid_edge_id = connectivity.numberOfEdges();
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,
AssertError);
}
}
}
#endif // NDEBUG
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment