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
This commit is part of merge request !84. Comments created here will be created in the context of that merge request.
...@@ -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
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment