SimiLie
Loading...
Searching...
No Matches
local_chain.hpp
1// SPDX-FileCopyrightText: 2024 Baptiste Legouix
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4#pragma once
5
6#include <array>
7#include <cstddef>
8#include <iostream>
9#include <iterator>
10#include <type_traits>
11
12#include <ddc/ddc.hpp>
13
14#include <similie/misc/are_all_same.hpp>
15#include <similie/misc/binomial_coefficient.hpp>
16#include <similie/misc/filled_struct.hpp>
17#include <similie/misc/specialization.hpp>
18
19#include "simplex.hpp"
20
21namespace sil {
22
23namespace exterior {
24
25template <
26 class SimplexType,
27 class LayoutStridedPolicy = Kokkos::LayoutRight,
28 class MemorySpace = Kokkos::HostSpace>
29class LocalChain;
30
31template <class SimplexType, class LayoutStridedPolicy, class MemorySpace>
33{
35
36 chain_type const* m_chain = nullptr;
37 std::size_t m_index = 0;
38
39public:
40 using difference_type = std::ptrdiff_t;
41 using value_type = SimplexType;
42 using pointer = value_type const*;
43 using reference = value_type const&;
44 using iterator_category = std::random_access_iterator_tag;
45
46 KOKKOS_DEFAULTED_FUNCTION constexpr LocalChainIterator() = default;
47
48 KOKKOS_FUNCTION constexpr LocalChainIterator(
49 chain_type const* chain,
50 std::size_t index) noexcept
51 : m_chain(chain)
52 , m_index(index)
53 {
54 }
55
56 KOKKOS_FUNCTION constexpr reference operator*() const noexcept
57 {
58 return (*m_chain)[m_index];
59 }
60
61 KOKKOS_FUNCTION constexpr pointer operator->() const noexcept
62 {
63 return &**this;
64 }
65
66 KOKKOS_FUNCTION constexpr LocalChainIterator& operator++() noexcept
67 {
68 ++m_index;
69 return *this;
70 }
71
72 KOKKOS_FUNCTION constexpr LocalChainIterator operator++(int) noexcept
73 {
74 LocalChainIterator tmp = *this;
75 ++(*this);
76 return tmp;
77 }
78
79 KOKKOS_FUNCTION constexpr LocalChainIterator& operator--() noexcept
80 {
81 --m_index;
82 return *this;
83 }
84
85 KOKKOS_FUNCTION constexpr LocalChainIterator operator+(difference_type n) const noexcept
86 {
87 return LocalChainIterator(m_chain, m_index + n);
88 }
89
90 KOKKOS_FUNCTION constexpr LocalChainIterator& operator+=(difference_type n) noexcept
91 {
92 m_index += n;
93 return *this;
94 }
95
96 KOKKOS_FUNCTION constexpr LocalChainIterator operator-(difference_type n) const noexcept
97 {
98 return LocalChainIterator(m_chain, m_index - n);
99 }
100
101 KOKKOS_FUNCTION constexpr difference_type operator-(
102 LocalChainIterator const& other) const noexcept
103 {
104 return static_cast<difference_type>(m_index) - static_cast<difference_type>(other.m_index);
105 }
106
107 KOKKOS_FUNCTION constexpr bool operator==(LocalChainIterator const& other) const noexcept
108 {
109 return m_index == other.m_index;
110 }
111
112 KOKKOS_FUNCTION constexpr bool operator!=(LocalChainIterator const& other) const noexcept
113 {
114 return !(*this == other);
115 }
116
117 KOKKOS_FUNCTION constexpr bool operator<(LocalChainIterator const& other) const noexcept
118 {
119 return m_index < other.m_index;
120 }
121};
122
123template <class SimplexType, class LayoutStridedPolicy, class MemorySpace>
125{
126public:
127 using memory_space = MemorySpace;
128 using simplex_type = SimplexType;
129 using discrete_element_type = typename simplex_type::discrete_element_type;
130 using discrete_vector_type = typename simplex_type::discrete_vector_type;
131 static constexpr std::size_t MAX_SIZE
132 = 1UL << ddc::type_seq_size_v<ddc::to_type_seq_t<discrete_vector_type>>;
133 using storage_type = std::array<simplex_type, MAX_SIZE>;
134
137
138private:
139 static constexpr bool s_is_local = true;
140 static constexpr std::size_t s_k = simplex_type::dimension();
142 storage_type m_vects {};
143 std::size_t m_size = 0;
144
145public:
146 KOKKOS_DEFAULTED_FUNCTION constexpr LocalChain() = default;
147 KOKKOS_DEFAULTED_FUNCTION constexpr LocalChain(LocalChain const&) = default;
148 KOKKOS_DEFAULTED_FUNCTION constexpr LocalChain(LocalChain&&) = default;
149 KOKKOS_DEFAULTED_FUNCTION constexpr ~LocalChain() = default;
150 KOKKOS_DEFAULTED_FUNCTION LocalChain& operator=(LocalChain const&) = default;
151 KOKKOS_DEFAULTED_FUNCTION LocalChain& operator=(LocalChain&&) = default;
152
153 KOKKOS_FUNCTION constexpr explicit LocalChain(
155 std::size_t size = 0) noexcept
156 : m_origin(origin)
157 , m_size(size)
158 {
159 assert(size <= MAX_SIZE);
160 }
161
162 template <misc::Specialization<Kokkos::View> AllocationType>
163 KOKKOS_FUNCTION constexpr explicit LocalChain(
164 AllocationType const&,
167 {
168 }
169
170 template <misc::NotSpecialization<ddc::DiscreteVector>... T>
171 KOKKOS_FUNCTION constexpr explicit LocalChain(
173 T... simplex) noexcept
174 : m_origin(origin)
175 , m_size(sizeof...(T))
176 {
177 static_assert(sizeof...(T) <= MAX_SIZE);
178 std::size_t i = 0;
179 ((m_vects[i++] = simplex), ...);
180 assert(check() == 0 && "there are duplicate simplices in the chain");
181 if constexpr (sizeof...(T) > 1) {
182 assert(misc::are_all_equal(simplex.discrete_element()...)
183 && "LocalChain must contain simplices with same origin (if not, use Chain)");
184 }
185 assert((!simplex.negative() && ...)
186 && "negative simplices are not supported in LocalChain");
187 }
188
189 template <
193 KOKKOS_FUNCTION constexpr explicit LocalChain(
194 AllocationType const&,
195 First first_simplex,
196 Rest... simplices) noexcept
197 : LocalChain(first_simplex.discrete_element(), first_simplex, simplices...)
198 {
199 }
200
201 template <misc::Specialization<ddc::DiscreteVector>... T>
202 requires(sizeof...(T) >= 1)
203 KOKKOS_FUNCTION constexpr explicit LocalChain(discrete_element_type origin, T... vect) noexcept
204 : m_origin(origin)
205 , m_size(sizeof...(T))
206 {
207 static_assert(sizeof...(T) <= MAX_SIZE);
208 std::size_t i = 0;
209 ((m_vects[i++] = simplex_type(origin, vect)), ...);
210 assert(check() == 0 && "there are duplicate simplices in the chain");
211 }
212
213 template <
216 requires(sizeof...(T) >= 1)
217 KOKKOS_FUNCTION constexpr explicit LocalChain(
218 AllocationType const&,
220 T... vect) noexcept
221 : LocalChain(origin, vect...)
222 {
223 }
224
225 static KOKKOS_FUNCTION constexpr bool is_local() noexcept
226 {
227 return s_is_local;
228 }
229
230 static KOKKOS_FUNCTION constexpr std::size_t dimension() noexcept
231 {
232 return s_k;
233 }
234
235 KOKKOS_FUNCTION constexpr discrete_element_type origin() const noexcept
236 {
237 return m_origin;
238 }
239
240 KOKKOS_FUNCTION constexpr storage_type& allocation() noexcept
241 {
242 return m_vects;
243 }
244
245 KOKKOS_FUNCTION constexpr storage_type const& allocation() const noexcept
246 {
247 return m_vects;
248 }
249
250 KOKKOS_FUNCTION constexpr std::size_t size() const noexcept
251 {
252 return m_size;
253 }
254
255 KOKKOS_FUNCTION constexpr std::size_t allocation_size() const noexcept
256 {
257 return MAX_SIZE;
258 }
259
260 static KOKKOS_FUNCTION constexpr bool negative()
261 {
262 return false;
263 }
264
265 KOKKOS_FUNCTION constexpr void resize(std::size_t size) noexcept
266 {
267 assert(size <= MAX_SIZE);
268 m_size = size;
269 }
270
271 KOKKOS_FUNCTION constexpr int check() const noexcept
272 {
273 for (auto i = begin(); i + 1 < end(); ++i) {
274 for (auto j = i + 1; j < end(); ++j) {
275 if (*i == *j) {
276 return -1;
277 }
278 }
279 }
280 return 0;
281 }
282
283 KOKKOS_FUNCTION constexpr iterator_type begin() noexcept
284 {
285 return iterator_type(this, 0);
286 }
287
288 KOKKOS_FUNCTION constexpr const_iterator_type begin() const noexcept
289 {
290 return const_iterator_type(this, 0);
291 }
292
293 KOKKOS_FUNCTION constexpr iterator_type end() noexcept
294 {
295 return iterator_type(this, m_size);
296 }
297
298 KOKKOS_FUNCTION constexpr const_iterator_type end() const noexcept
299 {
300 return const_iterator_type(this, m_size);
301 }
302
303 KOKKOS_FUNCTION constexpr const_iterator_type cbegin() const noexcept
304 {
305 return const_iterator_type(this, 0);
306 }
307
308 KOKKOS_FUNCTION constexpr const_iterator_type cend() const noexcept
309 {
310 return const_iterator_type(this, m_size);
311 }
312
313 KOKKOS_FUNCTION constexpr simplex_type const& operator[](std::size_t i) const noexcept
314 {
315 assert(i < m_size);
316 return m_vects[i];
317 }
318
319 KOKKOS_FUNCTION constexpr LocalChain& operator++()
320 {
321 assert(m_size < MAX_SIZE);
322 ++m_size;
323 return *this;
324 }
325
326 KOKKOS_FUNCTION constexpr LocalChain& operator+=(std::size_t n)
327 {
328 assert(m_size + n <= MAX_SIZE);
329 m_size += n;
330 return *this;
331 }
332
333 KOKKOS_FUNCTION constexpr LocalChain& operator+=(discrete_vector_type const& vect)
334 {
335 assert(m_size < MAX_SIZE);
336 m_vects[m_size++] = simplex_type(m_origin, vect);
337 return *this;
338 }
339
340 KOKKOS_FUNCTION constexpr LocalChain& operator+=(simplex_type const& simplex)
341 {
342 assert(m_size < MAX_SIZE);
343 m_vects[m_size++] = simplex;
344 return *this;
345 }
346
347 KOKKOS_FUNCTION constexpr LocalChain& operator+=(LocalChain const& simplices_to_add)
348 {
349 assert(m_size + simplices_to_add.size() <= MAX_SIZE);
350 std::size_t const old_size = m_size;
351 for (auto i = simplices_to_add.begin(); i < simplices_to_add.end(); ++i) {
352 m_vects[old_size + Kokkos::Experimental::distance(simplices_to_add.begin(), i)] = *i;
353 }
354 m_size += simplices_to_add.size();
355 return *this;
356 }
357
358 KOKKOS_FUNCTION constexpr LocalChain operator+(simplex_type const& simplex) const
359 {
360 LocalChain local_chain = *this;
361 local_chain += simplex;
362 return local_chain;
363 }
364
365 KOKKOS_FUNCTION constexpr LocalChain operator+(LocalChain const& simplices_to_add) const
366 {
367 LocalChain local_chain = *this;
368 local_chain += simplices_to_add;
369 return local_chain;
370 }
371
372 template <class T>
373 KOKKOS_FUNCTION constexpr LocalChain& operator*=(T t)
374 {
375 if (t == 1) {
376 } else if (t == -1) {
377 for (std::size_t i = 0; i < m_size; ++i) {
378 m_vects[i] = -m_vects[i];
379 }
380 } else {
381 assert(false && "chain must be multiplied by 1 or -1");
382 }
383 return *this;
384 }
385
386 template <class T>
387 KOKKOS_FUNCTION constexpr auto operator*(T t) const
388 {
389 LocalChain chain = *this;
390 chain *= t;
391 return chain;
392 }
393
394 KOKKOS_FUNCTION constexpr bool operator==(LocalChain const& simplices) const
395 {
396 if (m_size != simplices.m_size) {
397 return false;
398 }
399 auto simplex = begin();
400 auto other_simplex = simplices.begin();
401 for (; simplex < end(); ++simplex, ++other_simplex) {
402 if (*simplex != *other_simplex) {
403 return false;
404 }
405 }
406 return true;
407 }
408};
409
410namespace detail {
411
412template <std::size_t K, misc::Specialization<ddc::DiscreteDomain> Dom>
413struct TangentBasis;
414
415template <std::size_t K, class... Tag>
416struct TangentBasis<K, ddc::DiscreteDomain<Tag...>>
417{
418 template <class MemorySpace = Kokkos::HostSpace, class Elem>
419 KOKKOS_FUNCTION static constexpr auto run(Elem elem)
420 {
421 using chain_type = LocalChain<Simplex<K, Tag...>, Kokkos::LayoutRight, MemorySpace>;
422 std::array<std::ptrdiff_t, sizeof...(Tag)> permutation
423 = {0 * ddc::type_seq_rank_v<Tag, ddc::detail::TypeSeq<Tag...>>...};
424 for (auto i = permutation.begin(); i < permutation.begin() + K; ++i) {
425 *i = 1;
426 }
427 chain_type basis {typename chain_type::discrete_element_type(elem)};
428 do {
429 typename chain_type::discrete_vector_type vect;
430 ddc::detail::array(vect) = permutation;
431 basis += vect;
432 } while (std::prev_permutation(permutation.begin(), permutation.end()));
433 return basis;
434 }
435};
436
437} // namespace detail
438
439template <
440 std::size_t K,
441 misc::Specialization<ddc::DiscreteDomain> Dom,
442 misc::Specialization<ddc::DiscreteElement> Elem>
443KOKKOS_FUNCTION constexpr auto tangent_basis(Elem elem)
444{
445 return detail::TangentBasis<K, Dom>::template run<Kokkos::HostSpace>(elem);
446}
447
448template <std::size_t K, misc::Specialization<ddc::DiscreteDomain> Dom, class ExecSpace>
450constexpr auto tangent_basis([[maybe_unused]] ExecSpace const& exec_space)
451{
452 return detail::TangentBasis<K, Dom>::template run<typename ExecSpace::memory_space>(
454}
455
456template <misc::Specialization<LocalChain> ChainType>
457std::ostream& operator<<(std::ostream& out, ChainType const& chain)
458{
459 out << "[\n";
460 for (auto const& simplex : chain) {
461 out << " -> " << simplex << "\n";
462 }
463 out << "]";
464 return out;
465}
466
467template <misc::Specialization<Kokkos::View> AllocationType, class SimplexType, class... T>
468LocalChain(AllocationType, SimplexType, T...) -> LocalChain<
469 std::remove_cvref_t<SimplexType>,
470 typename AllocationType::array_layout,
471 typename AllocationType::memory_space>;
472
473} // namespace exterior
474
475} // namespace sil
KOKKOS_FUNCTION constexpr LocalChainIterator operator-(difference_type n) const noexcept
KOKKOS_DEFAULTED_FUNCTION constexpr LocalChainIterator()=default
KOKKOS_FUNCTION constexpr bool operator==(LocalChainIterator const &other) const noexcept
KOKKOS_FUNCTION constexpr LocalChainIterator & operator--() noexcept
KOKKOS_FUNCTION constexpr reference operator*() const noexcept
KOKKOS_FUNCTION constexpr difference_type operator-(LocalChainIterator const &other) const noexcept
KOKKOS_FUNCTION constexpr bool operator!=(LocalChainIterator const &other) const noexcept
KOKKOS_FUNCTION constexpr LocalChainIterator & operator++() noexcept
KOKKOS_FUNCTION constexpr bool operator<(LocalChainIterator const &other) const noexcept
KOKKOS_FUNCTION constexpr LocalChainIterator operator++(int) noexcept
KOKKOS_FUNCTION constexpr LocalChainIterator operator+(difference_type n) const noexcept
KOKKOS_FUNCTION constexpr LocalChainIterator(chain_type const *chain, std::size_t index) noexcept
KOKKOS_FUNCTION constexpr LocalChainIterator & operator+=(difference_type n) noexcept
KOKKOS_FUNCTION constexpr pointer operator->() const noexcept
std::random_access_iterator_tag iterator_category
KOKKOS_FUNCTION constexpr LocalChain operator+(simplex_type const &simplex) const
static KOKKOS_FUNCTION constexpr std::size_t dimension() noexcept
KOKKOS_FUNCTION constexpr discrete_element_type origin() const noexcept
KOKKOS_FUNCTION constexpr LocalChain & operator+=(std::size_t n)
KOKKOS_FUNCTION constexpr LocalChain operator+(LocalChain const &simplices_to_add) const
KOKKOS_FUNCTION constexpr iterator_type begin() noexcept
KOKKOS_FUNCTION constexpr const_iterator_type end() const noexcept
KOKKOS_DEFAULTED_FUNCTION LocalChain & operator=(LocalChain const &)=default
KOKKOS_FUNCTION constexpr std::size_t size() const noexcept
KOKKOS_FUNCTION constexpr int check() const noexcept
static KOKKOS_FUNCTION constexpr bool is_local() noexcept
LocalChainIterator< SimplexType, LayoutStridedPolicy, MemorySpace > iterator_type
KOKKOS_FUNCTION constexpr LocalChain(AllocationType const &, discrete_element_type origin, T... vect) noexcept
KOKKOS_DEFAULTED_FUNCTION LocalChain & operator=(LocalChain &&)=default
typename simplex_type::discrete_vector_type discrete_vector_type
iterator_type const_iterator_type
KOKKOS_DEFAULTED_FUNCTION constexpr LocalChain()=default
KOKKOS_DEFAULTED_FUNCTION constexpr LocalChain(LocalChain const &)=default
KOKKOS_FUNCTION constexpr LocalChain(discrete_element_type origin, std::size_t size=0) noexcept
KOKKOS_FUNCTION constexpr LocalChain & operator+=(LocalChain const &simplices_to_add)
KOKKOS_FUNCTION constexpr const_iterator_type cbegin() const noexcept
KOKKOS_FUNCTION constexpr simplex_type const & operator[](std::size_t i) const noexcept
KOKKOS_FUNCTION constexpr auto operator*(T t) const
KOKKOS_FUNCTION constexpr iterator_type end() noexcept
KOKKOS_FUNCTION constexpr bool operator==(LocalChain const &simplices) const
KOKKOS_FUNCTION constexpr LocalChain(AllocationType const &, discrete_element_type origin)
KOKKOS_DEFAULTED_FUNCTION constexpr ~LocalChain()=default
static constexpr std::size_t MAX_SIZE
typename simplex_type::discrete_element_type discrete_element_type
KOKKOS_DEFAULTED_FUNCTION constexpr LocalChain(LocalChain &&)=default
KOKKOS_FUNCTION constexpr LocalChain & operator+=(discrete_vector_type const &vect)
KOKKOS_FUNCTION constexpr LocalChain(discrete_element_type origin, T... vect) noexcept
KOKKOS_FUNCTION constexpr LocalChain & operator+=(simplex_type const &simplex)
KOKKOS_FUNCTION constexpr LocalChain(AllocationType const &, First first_simplex, Rest... simplices) noexcept
KOKKOS_FUNCTION constexpr LocalChain(discrete_element_type origin, T... simplex) noexcept
KOKKOS_FUNCTION constexpr void resize(std::size_t size) noexcept
KOKKOS_FUNCTION constexpr storage_type & allocation() noexcept
KOKKOS_FUNCTION constexpr const_iterator_type begin() const noexcept
KOKKOS_FUNCTION constexpr LocalChain & operator++()
std::array< simplex_type, MAX_SIZE > storage_type
KOKKOS_FUNCTION constexpr std::size_t allocation_size() const noexcept
KOKKOS_FUNCTION constexpr LocalChain & operator*=(T t)
KOKKOS_FUNCTION constexpr const_iterator_type cend() const noexcept
static KOKKOS_FUNCTION constexpr bool negative()
KOKKOS_FUNCTION constexpr storage_type const & allocation() const noexcept
std::ostream & operator<<(std::ostream &out, ChainType const &chain)
Definition chain.hpp:304
Simplex(ddc::DiscreteElement< Tag... >, ddc::DiscreteVector< T... >) -> Simplex< sizeof...(T), Tag... >
KOKKOS_FUNCTION constexpr auto tangent_basis(Elem elem)
LocalChain(AllocationType, SimplexType, T...) -> LocalChain< std::remove_cvref_t< SimplexType >, typename AllocationType::array_layout, typename AllocationType::memory_space >
constexpr bool are_all_equal(Head head, Tail... tail)
constexpr T filled_struct(ElementType const n=0)
The top-level namespace of SimiLie.
Definition csr.hpp:15