Select Git revision
SubItemValuePerItem.hpp
Stéphane Del Pino authored
`let_declaration` -> `fct_declaration` `declaration` -> `var_declaration`
SubItemValuePerItem.hpp 9.71 KiB
#ifndef SUBITEM_VALUE_PER_ITEM_HPP
#define SUBITEM_VALUE_PER_ITEM_HPP
#include <PugsAssert.hpp>
#include <Array.hpp>
#include <ItemId.hpp>
#include <ConnectivityMatrix.hpp>
#include <IConnectivity.hpp>
#include <ItemOfItemType.hpp>
#include <ItemType.hpp>
#include <memory>
template <typename DataType, typename ItemOfItem, typename ConnectivityPtr = std::shared_ptr<const IConnectivity>>
class SubItemValuePerItem
{
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_values;
// Allow const std:shared_ptr version to access our data
friend SubItemValuePerItem<std::add_const_t<DataType>, ItemOfItem, ConnectivitySharedPtr>;
// Allow const std:weak_ptr version to access our data
friend SubItemValuePerItem<std::add_const_t<DataType>, ItemOfItem, ConnectivityWeakPtr>;
public:
using ToShared = SubItemValuePerItem<DataType, ItemOfItem, ConnectivitySharedPtr>;
class SubView
{
public:
using data_type = DataType;
private:
PUGS_RESTRICT DataType* const m_sub_values;
const size_t m_size;
public:
PUGS_INLINE
const DataType&
operator[](const size_t& i) const noexcept(NO_ASSERT)
{
Assert(i < m_size);
return m_sub_values[i];
}
PUGS_FORCEINLINE
DataType&
operator[](const size_t& i) noexcept(NO_ASSERT)
{
Assert(i < m_size);
return m_sub_values[i];
}
PUGS_INLINE
size_t
size() const noexcept
{
return m_size;
}
SubView(const SubView&) = delete;
PUGS_INLINE
SubView(SubView&&) noexcept = default;
PUGS_INLINE
SubView(const Array<DataType>& values, const size_t& begin, const size_t& end) noexcept(NO_ASSERT)
: m_sub_values(&(values[begin])), m_size(end - begin)
{
Assert(begin <= end);
Assert(end <= values.size());
}
};
PUGS_INLINE
bool
isBuilt() const noexcept
{
return m_connectivity_ptr.use_count() != 0;
}
// Following Kokkos logic, these classes are view and const view does allow
// changes in data
PUGS_FORCEINLINE
DataType&
operator()(const ItemId& j, const size_t& r) const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
return m_values[m_host_row_map(size_t{j}) + r];
}
template <typename IndexType>
PUGS_FORCEINLINE DataType&
operator()(const IndexType& j, const size_t& r) const noexcept(NO_ASSERT)
{
static_assert(std::is_same_v<IndexType, ItemId>, "SubItemValuePerItem indexed by ItemId");
Assert(this->isBuilt());
return m_values[m_host_row_map(size_t{j}) + r];
}
PUGS_INLINE
size_t
numberOfValues() const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
return m_values.size();
}
// Following Kokkos logic, these classes are view and const view does allow
// changes in data
PUGS_FORCEINLINE
DataType&
operator[](const size_t& i) const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
return m_values[i];
}
template <typename IndexType>
DataType&
operator[](const IndexType& i) const noexcept(NO_ASSERT)
{
static_assert(std::is_same_v<IndexType, size_t>, "Access to SubItemValuePerItem's array must be indexed by "
"size_t");
Assert(this->isBuilt());
return m_values[i];
}
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);
}
PUGS_INLINE
size_t
numberOfSubValues(const size_t& i_cell) const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
return m_host_row_map(i_cell + 1) - m_host_row_map(i_cell);
}
PUGS_INLINE
SubView
itemValues(const size_t& i_cell) noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
const auto& cell_begin = m_host_row_map(i_cell);
const auto& cell_end = m_host_row_map(i_cell + 1);
return SubView(m_values, cell_begin, cell_end);
}
// Following Kokkos logic, these classes are view and const view does allow
// changes in data
PUGS_INLINE
SubView
itemValues(const size_t& i_cell) const noexcept(NO_ASSERT)
{
Assert(this->isBuilt());
const auto& cell_begin = m_host_row_map(i_cell);
const auto& cell_end = m_host_row_map(i_cell + 1);
return SubView(m_values, cell_begin, cell_end);
}
template <typename DataType2, typename ConnectivityPtr2>
PUGS_INLINE SubItemValuePerItem&
operator=(const SubItemValuePerItem<DataType2, ItemOfItem, ConnectivityPtr2>& sub_item_value_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 SubItemValuePerItem 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 SubItemValuePerItem of const data to "
"SubItemValuePerItem of non-const data");
m_host_row_map = sub_item_value_per_item.m_host_row_map;
m_values = sub_item_value_per_item.m_values;
if constexpr (std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr> and
std::is_same_v<ConnectivityPtr2, ConnectivityWeakPtr>) {
m_connectivity_ptr = sub_item_value_per_item.m_connectivity_ptr.lock();
} else {
m_connectivity_ptr = sub_item_value_per_item.m_connectivity_ptr;
}
return *this;
}
template <typename DataType2, typename ConnectivityPtr2>
PUGS_INLINE
SubItemValuePerItem(
const SubItemValuePerItem<DataType2, ItemOfItem, ConnectivityPtr2>& sub_item_value_per_item) noexcept
{
this->operator=(sub_item_value_per_item);
}
SubItemValuePerItem() = default;
SubItemValuePerItem(const IConnectivity& connectivity) noexcept : m_connectivity_ptr{connectivity.shared_ptr()}
{
static_assert(not std::is_const_v<DataType>, "Cannot allocate SubItemValuePerItem 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_values = Array<std::remove_const_t<DataType>>(connectivity_matrix.numEntries());
}
~SubItemValuePerItem() = default;
};
// Item values at nodes
template <typename DataType>
using NodeValuePerEdge = SubItemValuePerItem<DataType, NodeOfEdge>;
template <typename DataType>
using NodeValuePerFace = SubItemValuePerItem<DataType, NodeOfFace>;
template <typename DataType>
using NodeValuePerCell = SubItemValuePerItem<DataType, NodeOfCell>;
// Item values at edges
template <typename DataType>
using EdgeValuePerNode = SubItemValuePerItem<DataType, EdgeOfNode>;
template <typename DataType>
using EdgeValuePerFace = SubItemValuePerItem<DataType, EdgeOfFace>;
template <typename DataType>
using EdgeValuePerCell = SubItemValuePerItem<DataType, EdgeOfCell>;
// Item values at faces
template <typename DataType>
using FaceValuePerNode = SubItemValuePerItem<DataType, FaceOfNode>;
template <typename DataType>
using FaceValuePerEdge = SubItemValuePerItem<DataType, FaceOfEdge>;
template <typename DataType>
using FaceValuePerCell = SubItemValuePerItem<DataType, FaceOfCell>;
// Item values at cells
template <typename DataType>
using CellValuePerNode = SubItemValuePerItem<DataType, CellOfNode>;
template <typename DataType>
using CellValuePerEdge = SubItemValuePerItem<DataType, CellOfEdge>;
template <typename DataType>
using CellValuePerFace = SubItemValuePerItem<DataType, CellOfFace>;
// Weak versions: should not be used outside of Connectivity
// Item values at nodes
template <typename DataType, typename ItemOfItem>
using WeakSubItemValuePerItem = SubItemValuePerItem<DataType, ItemOfItem, std::weak_ptr<const IConnectivity>>;
template <typename DataType>
using WeakNodeValuePerEdge = WeakSubItemValuePerItem<DataType, NodeOfEdge>;
template <typename DataType>
using WeakNodeValuePerFace = WeakSubItemValuePerItem<DataType, NodeOfFace>;
template <typename DataType>
using WeakNodeValuePerCell = WeakSubItemValuePerItem<DataType, NodeOfCell>;
// Item values at edges
template <typename DataType>
using WeakEdgeValuePerNode = WeakSubItemValuePerItem<DataType, EdgeOfNode>;
template <typename DataType>
using WeakEdgeValuePerFace = WeakSubItemValuePerItem<DataType, EdgeOfFace>;
template <typename DataType>
using WeakEdgeValuePerCell = WeakSubItemValuePerItem<DataType, EdgeOfCell>;
// Item values at faces
template <typename DataType>
using WeakFaceValuePerNode = WeakSubItemValuePerItem<DataType, FaceOfNode>;
template <typename DataType>
using WeakFaceValuePerEdge = WeakSubItemValuePerItem<DataType, FaceOfEdge>;
template <typename DataType>
using WeakFaceValuePerCell = WeakSubItemValuePerItem<DataType, FaceOfCell>;
// Item values at cells
template <typename DataType>
using WeakCellValuePerNode = WeakSubItemValuePerItem<DataType, CellOfNode>;
template <typename DataType>
using WeakCellValuePerEdge = WeakSubItemValuePerItem<DataType, CellOfEdge>;
template <typename DataType>
using WeakCellValuePerFace = WeakSubItemValuePerItem<DataType, CellOfFace>;
#endif // SUBITEM_VALUE_PER_ITEM_HPP