Skip to content
Snippets Groups Projects
Select Git revision
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • feature/serraille
  • feature/variational-hydro
  • develop default protected
  • feature/composite-scheme
  • hyperplastic
  • feature/local-dt-fsi
  • feature/kinetic-schemes
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • master protected
  • feature/escobar-smoother
  • feature/hypoelasticity-clean
  • feature/hypoelasticity
  • feature/Navier-Stokes
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
32 results

SubItemValuePerItem.hpp

Blame
  • SubItemValuePerItem.hpp 11.24 KiB
    #ifndef SUBITEM_VALUE_PER_ITEM_HPP
    #define SUBITEM_VALUE_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 <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>;
    
      // Allow const std:shared_ptr version to access our data
      friend SubItemValuePerItem<std::remove_const_t<DataType>, ItemOfItem, ConnectivitySharedPtr>;
    
      // Allow const std:weak_ptr version to access our data
      friend SubItemValuePerItem<std::remove_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:
        template <typename IndexType>
        PUGS_INLINE const DataType&
        operator[](IndexType i) const noexcept(NO_ASSERT)
        {
          static_assert(std::is_integral_v<IndexType>, "SubView is indexed by integral values");
          Assert(i < m_size);
          return m_sub_values[i];
        }
    
        template <typename IndexType>
        PUGS_FORCEINLINE DataType&
        operator[](IndexType i) noexcept(NO_ASSERT)
        {
          static_assert(std::is_integral_v<IndexType>, "SubView is indexed by integral values");
          Assert(i < m_size);
          return m_sub_values[i];
        }
    
        PUGS_INLINE
        size_t
        size() const noexcept
        {
          return m_size;
        }
    
        SubView(const SubView&)     = delete;
        SubView(SubView&&) noexcept = delete;
    
        PUGS_INLINE
        SubView(const Array<DataType>& values, size_t begin, size_t end) noexcept(NO_ASSERT)
          : m_sub_values(&(values[begin])), m_size(end - begin)
        {
          Assert(begin <= end);
          Assert(end <= values.size());
        }
    
        ~SubView() = default;
      };
    
      friend PUGS_INLINE SubItemValuePerItem<std::remove_const_t<DataType>, ItemOfItem, ConnectivityPtr>
      copy(SubItemValuePerItem<DataType, ItemOfItem, ConnectivityPtr>& source)
      {
        SubItemValuePerItem<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_values           = copy(source.m_values);
        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 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 m_values[m_host_row_map(size_t{item_id}) + i];
      }
    
      // Following Kokkos logic, these classes are view and const view does allow
      // changes in data
      template <typename ArrayIndexType>
      DataType&
      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_values.size());
        return m_values[i];
      }
    
      PUGS_INLINE
      size_t
      numberOfValues() const noexcept(NO_ASSERT)
      {
        Assert(this->isBuilt());
        return m_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;
      }
    
      template <typename IndexType>
      PUGS_INLINE size_t
      numberOfSubValues(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
      itemValues(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_values, item_begin, item_end);
      }
    
      // Following Kokkos logic, these classes are view and const view does allow
      // changes in data
      template <typename IndexType>
      PUGS_INLINE SubView
      itemValues(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_values, item_begin, item_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