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
No related branches found
No related tags found
1 merge request!84Add SubArray class
......@@ -13,6 +13,9 @@ class IConnectivity : public std::enable_shared_from_this<IConnectivity>
template <typename DataType, typename ItemOfItem, typename ConnectivityPtr>
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;
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
test_ItemValue.cpp
test_ItemValueUtils.cpp
test_SubItemValuePerItem.cpp
test_SubItemArrayPerItem.cpp
)
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