SimiLie
Loading...
Searching...
No Matches
simplex.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/specialization.hpp>
9
10namespace sil {
11
12namespace exterior {
13
14namespace detail {
15
16template <class... T>
17struct Reorient;
18
19template <>
20struct Reorient<>
21{
22 template <class Elem, class Vect>
23 static constexpr Elem run_elem(Elem elem, [[maybe_unused]] Vect)
24 {
25 return elem;
26 }
27
28 template <class Elem, class Vect>
29 static constexpr Vect run_vect([[maybe_unused]] Elem, Vect vect)
30 {
31 return vect;
32 }
33
34 template <class Vect>
35 static constexpr bool run_negative([[maybe_unused]] Vect vect, bool negative)
36 {
37 return negative;
38 }
39};
40
41template <class HeadTag, class... TailTag>
42struct Reorient<HeadTag, TailTag...>
43{
44 template <class Elem, class Vect>
45 static constexpr Elem run_elem(Elem elem, Vect vect)
46 {
47 if (vect.template get<HeadTag>() == -1) {
48 elem.template uid<HeadTag>()--;
49 }
50 return Reorient<TailTag...>::run_elem(elem, vect);
51 }
52
53 template <class Elem, class Vect>
54 static constexpr Vect run_vect(Elem elem, Vect vect)
55 {
56 if (vect.template get<HeadTag>() == -1) {
57 vect.template get<HeadTag>() = 1;
58 }
59 return Reorient<TailTag...>::run_vect(elem, vect);
60 }
61
62 template <class Vect>
63 static constexpr bool run_negative(Vect vect, bool negative)
64 {
65 return Reorient<
66 TailTag...>::run_negative(vect, (vect.template get<HeadTag>() == -1) != negative);
67 }
68};
69
70} // namespace detail
71
73template <std::size_t K, class... Tag>
74class Simplex : public ddc::DiscreteElement<Tag...>
75{
76protected:
77 using base_type = ddc::DiscreteElement<Tag...>;
78
79public:
81 using discrete_vector_type = ddc::DiscreteVector<Tag...>;
82
83private:
84 static constexpr std::size_t s_k = K;
86 m_vect; // Only booleans are stored but ddc::DiscreteVector supports only std::ptrdiff_t
87 bool m_negative;
88
89 template <class Tag_, class... T>
90 requires(!ddc::type_seq_contains_v<ddc::detail::TypeSeq<Tag_>, ddc::detail::TypeSeq<T...>>)
91 static constexpr ddc::DiscreteVector<Tag_> add_eventually_null_dimensions_(
92 [[maybe_unused]] ddc::DiscreteVector<T...> vect)
93 {
94 return ddc::DiscreteVector<Tag_> {0};
95 }
96
97 template <class Tag_, class... T>
98 requires(ddc::type_seq_contains_v<ddc::detail::TypeSeq<Tag_>, ddc::detail::TypeSeq<T...>>)
99 static constexpr ddc::DiscreteVector<Tag_> add_eventually_null_dimensions_(
100 ddc::DiscreteVector<T...> vect)
101 {
102 return ddc::DiscreteVector<Tag_>(vect);
103 }
104
105 template <class... T>
106 static constexpr discrete_vector_type add_null_dimensions(ddc::DiscreteVector<T...> vect)
107 {
108 return discrete_vector_type(add_eventually_null_dimensions_<Tag, T...>(vect)...);
109 }
110
111public:
112 KOKKOS_DEFAULTED_FUNCTION constexpr Simplex() = default;
113
114 KOKKOS_DEFAULTED_FUNCTION constexpr Simplex(Simplex const&) = default;
115
116 KOKKOS_DEFAULTED_FUNCTION constexpr Simplex(Simplex&&) = default;
117
118 template <misc::Specialization<ddc::DiscreteVector> T>
119 KOKKOS_FUNCTION constexpr explicit Simplex(
121 T vect = ddc::DiscreteVector<> {},
122 bool negative = false) noexcept
123 : base_type(detail::Reorient<Tag...>::run_elem(elem, add_null_dimensions(vect)))
124 , m_vect(detail::Reorient<Tag...>::run_vect(elem, add_null_dimensions(vect)))
125 , m_negative(detail::Reorient<Tag...>::run_negative(add_null_dimensions(vect), negative))
126 {
127 assert(((m_vect.template get<Tag>() == 0 || m_vect.template get<Tag>() == 1) && ...)
128 && "simplex vector must contain only -1, 0 or 1");
129 }
130
131 template <misc::Specialization<ddc::DiscreteVector> T = ddc::DiscreteVector<>>
132 KOKKOS_FUNCTION constexpr explicit Simplex(
133 std::integral_constant<std::size_t, K>,
135 T vect = ddc::DiscreteVector<> {},
136 bool negative = false) noexcept
137 : base_type(detail::Reorient<Tag...>::run_elem(elem, add_null_dimensions(vect)))
138 , m_vect(detail::Reorient<Tag...>::run_vect(elem, add_null_dimensions(vect)))
139 , m_negative(detail::Reorient<Tag...>::run_negative(add_null_dimensions(vect), negative))
140 {
141 assert(((m_vect.template get<Tag>() == 0 || m_vect.template get<Tag>() == 1) && ...)
142 && "simplex vector must contain only -1, 0 or 1");
143 }
144
145 KOKKOS_DEFAULTED_FUNCTION ~Simplex() = default;
146
147 KOKKOS_DEFAULTED_FUNCTION Simplex& operator=(Simplex const& other) = default;
148
149 KOKKOS_DEFAULTED_FUNCTION Simplex& operator=(Simplex&& other) = default;
150
151 static KOKKOS_FUNCTION constexpr std::size_t dimension() noexcept
152 {
153 return s_k;
154 }
155
156 KOKKOS_FUNCTION base_type discrete_element() noexcept // TODO base_type& ?
157 {
158 return base_type {this->template uid<Tag>()...};
159 }
160
161 KOKKOS_FUNCTION const base_type discrete_element() const noexcept // TODO base_type& ?
162 {
163 return base_type {this->template uid<Tag>()...};
164 }
165
166 KOKKOS_FUNCTION discrete_vector_type& discrete_vector() noexcept
167 {
168 return m_vect;
169 }
170
171 KOKKOS_FUNCTION discrete_vector_type const& discrete_vector() const noexcept
172 {
173 return m_vect;
174 }
175
176 KOKKOS_FUNCTION bool& negative() noexcept
177 {
178 return m_negative;
179 }
180
181 KOKKOS_FUNCTION bool const& negative() const noexcept
182 {
183 return m_negative;
184 }
185
186 KOKKOS_FUNCTION Simplex<s_k, Tag...> operator-()
187 {
188 return Simplex<s_k, Tag...>(discrete_element(), discrete_vector(), !negative());
189 }
190
191 template <class T>
192 KOKKOS_FUNCTION auto operator*(T t)
193 {
194 if (t == 1) {
195 return *this;
196 } else if (t == -1) {
197 return -*this;
198 } else {
199 assert(false && "simplex must be multiplied by 1 or -1");
200 }
201 }
202
203 KOKKOS_FUNCTION bool operator==(Simplex<s_k, Tag...> simplex)
204 {
205 return (discrete_element() == simplex.discrete_element()
206 && discrete_vector() == simplex.discrete_vector()
207 && negative() == simplex.negative());
208 }
209};
210
211template <class... Tag, class... T>
212Simplex(ddc::DiscreteElement<Tag...>, ddc::DiscreteVector<T...>) -> Simplex<sizeof...(T), Tag...>;
213
214template <class... Tag, class... T>
215Simplex(ddc::DiscreteElement<Tag...>,
216 ddc::DiscreteVector<T...>,
217 bool) -> Simplex<sizeof...(T), Tag...>;
218
219namespace detail {
220
221template <std::size_t K, class Dom>
222struct SimplexForDomain;
223
224template <std::size_t K, class... Tag>
225struct SimplexForDomain<K, ddc::DiscreteDomain<Tag...>>
226{
227 using type = Simplex<K, Tag...>;
228};
229
230} // namespace detail
231
232template <std::size_t K, class Dom>
233using simplex_for_domain_t = detail::SimplexForDomain<K, Dom>::type;
234
235template <std::size_t K, class... Tag>
236std::ostream& operator<<(std::ostream& out, Simplex<K, Tag...> const& simplex)
237{
238 out << " ";
239 out << simplex.discrete_element();
240 out << (simplex.negative() ? " <- " : " -> ");
241 out << simplex.discrete_element() + simplex.discrete_vector();
242 out << " ";
243 return out;
244}
245
246} // namespace exterior
247
248} // namespace sil
Simplex class.
Definition simplex.hpp:75
KOKKOS_FUNCTION constexpr Simplex(discrete_element_type elem, T vect=ddc::DiscreteVector<> {}, bool negative=false) noexcept
Definition simplex.hpp:119
KOKKOS_FUNCTION bool operator==(Simplex< s_k, Tag... > simplex)
Definition simplex.hpp:203
KOKKOS_FUNCTION discrete_vector_type const & discrete_vector() const noexcept
Definition simplex.hpp:171
KOKKOS_FUNCTION constexpr Simplex(std::integral_constant< std::size_t, K >, discrete_element_type elem, T vect=ddc::DiscreteVector<> {}, bool negative=false) noexcept
Definition simplex.hpp:132
KOKKOS_FUNCTION bool const & negative() const noexcept
Definition simplex.hpp:181
KOKKOS_DEFAULTED_FUNCTION Simplex & operator=(Simplex &&other)=default
KOKKOS_FUNCTION bool & negative() noexcept
Definition simplex.hpp:176
KOKKOS_DEFAULTED_FUNCTION ~Simplex()=default
KOKKOS_FUNCTION base_type discrete_element() noexcept
Definition simplex.hpp:156
KOKKOS_FUNCTION auto operator*(T t)
Definition simplex.hpp:192
KOKKOS_DEFAULTED_FUNCTION constexpr Simplex(Simplex const &)=default
ddc::DiscreteVector< Tag... > discrete_vector_type
Definition simplex.hpp:81
KOKKOS_FUNCTION discrete_vector_type & discrete_vector() noexcept
Definition simplex.hpp:166
static KOKKOS_FUNCTION constexpr std::size_t dimension() noexcept
Definition simplex.hpp:151
KOKKOS_FUNCTION const base_type discrete_element() const noexcept
Definition simplex.hpp:161
KOKKOS_DEFAULTED_FUNCTION constexpr Simplex()=default
KOKKOS_DEFAULTED_FUNCTION Simplex & operator=(Simplex const &other)=default
ddc::DiscreteElement< Tag... > base_type
Definition simplex.hpp:77
base_type discrete_element_type
Definition simplex.hpp:80
KOKKOS_DEFAULTED_FUNCTION constexpr Simplex(Simplex &&)=default
KOKKOS_FUNCTION Simplex< s_k, Tag... > operator-()
Definition simplex.hpp:186
std::ostream & operator<<(std::ostream &out, ChainType const &chain)
Definition chain.hpp:304
Simplex(ddc::DiscreteElement< Tag... >, ddc::DiscreteVector< T... >) -> Simplex< sizeof...(T), Tag... >
detail::SimplexForDomain< K, Dom >::type simplex_for_domain_t
Definition simplex.hpp:233
The top-level namespace of SimiLie.
Definition csr.hpp:14