SimiLie
Loading...
Searching...
No Matches
symmetric_tensor.hpp
1// SPDX-FileCopyrightText: 2024 Baptiste Legouix
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
6#include <ddc/ddc.hpp>
7
8#include <similie/misc/binomial_coefficient.hpp>
9#include <similie/misc/portable_stl.hpp>
10
11#include "tensor_impl.hpp"
12
13namespace sil {
14
15namespace tensor {
16
17// struct representing an abstract unique index sweeping on all possible combination of natural indices, for a summetric tensor.
18template <TensorNatIndex... TensorIndex>
20{
21 static constexpr bool is_tensor_index = true;
22 static constexpr bool is_explicitely_stored_tensor = true;
23
24 using subindices_domain_t = ddc::DiscreteDomain<TensorIndex...>;
25
26 KOKKOS_FUNCTION static constexpr subindices_domain_t subindices_domain()
27 {
28 return ddc::DiscreteDomain<TensorIndex...>(
29 ddc::DiscreteElement<TensorIndex...>(ddc::DiscreteElement<TensorIndex>(0)...),
30 ddc::DiscreteVector<TensorIndex...>(
31 ddc::DiscreteVector<TensorIndex>(TensorIndex::size())...));
32 }
33
34 KOKKOS_FUNCTION static constexpr std::size_t rank()
35 {
36 return (TensorIndex::rank() + ...);
37 }
38
39 KOKKOS_FUNCTION static constexpr std::size_t size()
40 {
41 return (TensorIndex::size() * ...);
42 }
43
44 KOKKOS_FUNCTION static constexpr std::size_t mem_size()
45 {
47 ddc::type_seq_element_t<0, ddc::detail::TypeSeq<TensorIndex...>>::mem_size()
48 + rank() - 1,
49 rank());
50 }
51
52 KOKKOS_FUNCTION static constexpr std::size_t access_size()
53 {
54 return mem_size();
55 }
56
57 KOKKOS_FUNCTION static constexpr std::size_t mem_id(
58 std::array<std::size_t, rank()> const natural_ids)
59 {
60 std::array<std::size_t, rank()> sorted_ids(natural_ids);
61 misc::detail::sort(sorted_ids.begin(), sorted_ids.end());
63 ddc::type_seq_element_t<0, ddc::detail::TypeSeq<TensorIndex...>>::mem_size()
64 + rank() - 1,
65 rank())
66 - ((sorted_ids[ddc::type_seq_rank_v<
68 ddc::detail::TypeSeq<TensorIndex...>>]
69 == TensorIndex::mem_size() - 1
70 ? 0
72 TensorIndex::mem_size()
73 - sorted_ids[ddc::type_seq_rank_v<
75 ddc::detail::TypeSeq<TensorIndex...>>]
76 + rank()
77 - ddc::type_seq_rank_v<
79 ddc::detail::TypeSeq<TensorIndex...>>
80 - 2,
81 rank()
82 - ddc::type_seq_rank_v<
84 ddc::detail::TypeSeq<TensorIndex...>>))
85 + ...)
86 - 1;
87 }
88
89 KOKKOS_FUNCTION static constexpr std::size_t access_id(
90 std::array<std::size_t, rank()> const natural_ids)
91 {
92 return mem_id(natural_ids);
93 }
94
95 KOKKOS_FUNCTION static constexpr std::size_t access_id_to_mem_id(std::size_t access_id)
96 {
97 return access_id;
98 }
99
100 template <class Tensor, class Elem, class Id, class FunctorType>
101 KOKKOS_FUNCTION static constexpr Tensor::element_type process_access(
102 const FunctorType& access,
103 Tensor tensor,
104 Elem elem)
105 {
106 return access(tensor, elem);
107 }
108
109 KOKKOS_FUNCTION static constexpr std::array<std::size_t, rank()>
111 {
112 assert(mem_id < mem_size());
113 if constexpr (rank() == 0) {
114 return std::array<std::size_t, rank()> {};
115 } else {
116 std::array<std::size_t, rank()> ids;
117 std::size_t d
118 = ddc::type_seq_element_t<0, ddc::detail::TypeSeq<TensorIndex...>>::mem_size();
119 std::size_t r = rank();
120 for (std::size_t i = 0; i < rank(); ++i) {
121 const std::size_t triangle_size = misc::binomial_coefficient(d + r - i - 1, r - i);
122 for (std::size_t j = 0; j < d; ++j) {
123 const std::size_t subtriangle_size
124 = misc::binomial_coefficient(d - j + r - i - 2, r - i);
125 if (triangle_size - subtriangle_size > mem_id) {
126 ids[i] = ddc::type_seq_element_t<0, ddc::detail::TypeSeq<TensorIndex...>>::
127 mem_size()
128 - d + j;
129 mem_id -= triangle_size
130 - misc::binomial_coefficient(d - j + r - i - 1, r - i);
131 d -= j;
132 break;
133 }
134 ids[i] = 0;
135 }
136 }
137 return ids;
138 }
139 }
140};
141
142} // namespace tensor
143
144} // namespace sil
constexpr std::size_t binomial_coefficient(std::size_t n, std::size_t k) noexcept
Tensor(ddc::Chunk< ElementType, SupportType, Allocator >) -> Tensor< ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
The top-level namespace of SimiLie.
Definition csr.hpp:14
static constexpr bool is_explicitely_stored_tensor
ddc::DiscreteDomain< TensorIndex... > subindices_domain_t
static KOKKOS_FUNCTION constexpr std::size_t access_id(std::array< std::size_t, rank()> const natural_ids)
static KOKKOS_FUNCTION constexpr std::size_t access_id_to_mem_id(std::size_t access_id)
static KOKKOS_FUNCTION constexpr subindices_domain_t subindices_domain()
static KOKKOS_FUNCTION constexpr std::array< std::size_t, rank()> mem_id_to_canonical_natural_ids(std::size_t mem_id)
static KOKKOS_FUNCTION constexpr std::size_t access_size()
static KOKKOS_FUNCTION constexpr Tensor::element_type process_access(const FunctorType &access, Tensor tensor, Elem elem)
static KOKKOS_FUNCTION constexpr std::size_t size()
static KOKKOS_FUNCTION constexpr std::size_t mem_size()
static KOKKOS_FUNCTION constexpr std::size_t rank()
static KOKKOS_FUNCTION constexpr std::size_t mem_id(std::array< std::size_t, rank()> const natural_ids)