/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/coordinates/coordinates.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/coordinates/coordinates.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
coordinates.hh
Go to the documentation of this file.
1#pragma once
2
3// standard library
4#include <cmath>
5#include <cstddef>
6#include <cstdio>
7#include <cstdlib>
8#include <limits>
9#include <stdexcept>
10#include <tuple>
11#include <type_traits>
12#include <vector>
13
14// DiFfRG
17
18namespace DiFfRG
19{
20 // A concept for what is a coordinate class
21 template <typename T>
22 concept is_coordinates = requires(T t) {
23 typename T::ctype;
24 T::dim;
25 t.size();
27 { t.from_linear_index(size_t{}) } -> std::same_as<device::array<size_t, T::dim>>;
28 };
29
30 namespace internal
31 {
32 template <typename T, typename = void> struct coord_periodic : std::false_type {
33 };
34 template <typename T>
35 struct coord_periodic<T, std::void_t<decltype(T::periodic)>> : std::bool_constant<T::periodic> {
36 };
37 } // namespace internal
38
43 template <typename T> inline constexpr bool is_periodic_coordinate_v = internal::coord_periodic<T>::value;
44
45 namespace internal
46 {
47 template <typename C, size_t i, typename = void> struct axis_periodic : std::false_type {
48 };
49 template <typename C, size_t i>
50 struct axis_periodic<C, i, std::void_t<typename C::template coordinate_type<i>>>
51 : std::bool_constant<is_periodic_coordinate_v<typename C::template coordinate_type<i>>> {
52 };
53 } // namespace internal
54
59 template <typename C, size_t i> inline constexpr bool is_periodic_axis_v = internal::axis_periodic<C, i>::value;
60
66 template <typename... Coordinates> class CoordinatePackND
67 {
68 // Assert that all coordinates have the same ctype
69 static_assert((std::is_same<typename Coordinates::ctype,
70 typename device::tuple_element<0, device::tuple<Coordinates...>>::type::ctype>::value &&
71 ...),
72 "CoordinatePackND: all coordinate systems must use the same ctype");
73 static_assert(sizeof...(Coordinates) > 0, "CoordinatePackND requires at least one coordinate system");
74 // Assert that all coordinates have the dim 1
75 static_assert(((Coordinates::dim == 1) && ...), "CoordinatePackND requires all coordinates to have dim 1");
76
77 public:
78 using ctype = typename device::tuple_element<0, device::tuple<Coordinates...>>::type::ctype;
79 static constexpr size_t dim = sizeof...(Coordinates);
80
87
88 template <typename... I>
89 requires(std::is_convertible_v<std::decay_t<I>, size_t> && ...)
90 KOKKOS_FORCEINLINE_FUNCTION device::array<ctype, dim> forward(I &&...i) const
91 {
92 static_assert(sizeof...(I) == sizeof...(Coordinates));
93 return forward_impl(device::make_integer_sequence<int, sizeof...(I)>(), device::forward<I>(i)...);
94 }
95 template <typename IT>
96 KOKKOS_FORCEINLINE_FUNCTION device::array<ctype, dim> forward(const device::array<IT, dim> &coords) const
97 {
98 return device::apply([&](const auto &...iargs) { return forward(iargs...); }, coords);
99 }
100
101 template <typename... I, int... Is>
102 device::array<ctype, dim> KOKKOS_FORCEINLINE_FUNCTION forward_impl(device::integer_sequence<int, Is...>,
103 I &&...i) const
104 {
105 return {{device::get<Is>(coordinates).forward(device::get<Is>(device::tie(i...)))...}};
106 }
107
108 template <typename... I> KOKKOS_FORCEINLINE_FUNCTION device::array<ctype, sizeof...(I)> backward(I &&...i) const
109 {
110 static_assert(sizeof...(I) == sizeof...(Coordinates));
111 return backward_impl(device::make_integer_sequence<int, sizeof...(I)>(), device::forward<I>(i)...);
112 }
113
114 template <typename... I, int... Is>
115 device::array<ctype, sizeof...(I)> KOKKOS_FORCEINLINE_FUNCTION backward_impl(device::integer_sequence<int, Is...>,
116 I &&...i) const
117 {
118 return {{device::get<Is>(coordinates).backward(device::get<Is>(device::tie(i...)))...}};
119 }
120
121 template <size_t i> const auto &get_coordinates() const { return device::get<i>(coordinates); }
122
126 template <size_t i>
127 using coordinate_type = typename device::tuple_element<i, device::tuple<Coordinates...>>::type;
128
129 size_t KOKKOS_FORCEINLINE_FUNCTION size() const
130 {
131 // multiply all sizes
132 size_t size = 1;
133 constexpr_for<0, sizeof...(Coordinates), 1>([&](auto i) { size *= device::get<i>(coordinates).size(); });
134 return size;
135 }
136
137 device::array<size_t, sizeof...(Coordinates)> KOKKOS_FORCEINLINE_FUNCTION sizes() const
138 {
139 device::array<size_t, sizeof...(Coordinates)> sizes;
140 constexpr_for<0, sizeof...(Coordinates), 1>([&](auto i) { sizes[i] = device::get<i>(coordinates).size(); });
141 return sizes;
142 }
143
144 device::array<size_t, sizeof...(Coordinates)> KOKKOS_INLINE_FUNCTION from_linear_index(size_t s) const
145 {
146 device::array<size_t, sizeof...(Coordinates)> idx;
147 // calculate the index for each coordinate system
148 constexpr_for<0, sizeof...(Coordinates), 1>([&](auto i) {
149 idx[sizeof...(Coordinates) - 1 - i] = s % device::get<sizeof...(Coordinates) - 1 - i>(coordinates).size();
150 s = s / device::get<sizeof...(Coordinates) - 1 - i>(coordinates).size();
151 });
152
153 return idx;
154 }
155
156 template <typename... Coordinates2>
158 {
159 if constexpr (sizeof...(Coordinates) != sizeof...(Coordinates2)) return false; // Different number of coordinates
160 if constexpr ((!std::is_same_v<Coordinates, Coordinates2> && ...))
161 return false; // Different types of coordinates
162 else if constexpr (sizeof...(Coordinates) == 0)
163 return true; // Empty coordinate pack, always equal
164 else {
165 // Check if all coordinates are equal
166 bool equal = true;
167 constexpr_for<0, sizeof...(Coordinates), 1>(
168 [&](auto i) { equal &= (device::get<i>(r.coordinates) == device::get<i>(l.coordinates)); });
169 return equal;
170 }
171 }
172
173 std::string to_string() const
174 {
175 std::string ret = "CoordinatePackND(";
176 constexpr_for<0, dim, 1>([&](auto i) {
177 ret += device::get<i>(coordinates).to_string();
178 if (i + 1 < dim) ret += ", ";
179 });
180 ret += ")";
181 return ret;
182 }
183
184 protected:
185 const device::tuple<Coordinates...> coordinates;
186 };
187
206 template <typename Base> class SubCoordinates : public Base
207 {
208 public:
209 using ctype = typename Base::ctype;
210 static constexpr size_t dim = Base::dim;
211
212 SubCoordinates(const Base &base, size_t offset, size_t size) : Base(base), m_offset(offset), m_size(size)
213 {
214 if (size == 0) throw std::runtime_error("SubCoordinates: size must be > 0");
215 if (offset + size > base.size()) throw std::runtime_error("SubCoordinates: offset + size must be <= base.size()");
216 }
217
222 device::array<size_t, dim> KOKKOS_FORCEINLINE_FUNCTION sizes() const
223 {
224 static_assert(dim == 1, "SubCoordinates is a linear index window, which is a per-axis box only for dim == 1.");
226 }
227
228 size_t KOKKOS_FORCEINLINE_FUNCTION size() const { return m_size; }
229
233 device::array<size_t, dim> KOKKOS_INLINE_FUNCTION from_linear_index(size_t s) const
234 {
235 return Base::from_linear_index(m_offset + s);
236 }
237
241 template <typename... I>
242 requires(std::is_convertible_v<std::decay_t<I>, size_t> && ...)
243 KOKKOS_FORCEINLINE_FUNCTION device::array<ctype, dim> forward(I &&...i) const
244 {
245 static_assert(sizeof...(I) == dim);
246 return forward(device::array<size_t, dim>{{static_cast<size_t>(i)...}});
247 }
248
250 template <typename IT> KOKKOS_INLINE_FUNCTION device::array<ctype, dim> forward(device::array<IT, dim> i) const
251 {
252 return Base::forward(i);
253 }
254
255 // backward() is deliberately not overridden: it is the inverse of forward(), which is now
256 // Base's unchanged, so Base::backward is already the right answer and is inherited as is.
257
260 std::string to_string() const
261 {
262 return "SubCoordinates(" + Base::to_string() + ", " + std::to_string(m_offset) + ", " + std::to_string(m_size) +
263 ")";
264 }
265
266 private:
267 size_t m_offset;
268 size_t m_size;
269 };
270
271 template <typename NT = double>
272 requires std::is_floating_point_v<NT>
274 {
275 public:
276 using ctype = NT;
277 static constexpr size_t dim = 1;
278
281 {
282 if (grid_extent == 0) throw std::runtime_error("LinearCoordinates1D: grid_extent must be > 0");
283 a = (stop - start) / (grid_extent - 1.);
284 }
285
286 template <typename NT2>
288 : LinearCoordinates1D(other.size(), other.start, other.stop)
289 {
290 }
291
292 device::array<size_t, 1> KOKKOS_FORCEINLINE_FUNCTION from_linear_index(size_t i) const
293 {
294 return device::array<size_t, 1>{i};
295 }
296
303 template <typename IT> NT KOKKOS_FORCEINLINE_FUNCTION forward(const IT &x) const { return start + a * x; }
304
305 template <typename IT> device::array<NT, 1> KOKKOS_FORCEINLINE_FUNCTION forward(const device::array<IT, 1> &x) const
306 {
307 return {forward(x[0])};
308 }
309
316 NT KOKKOS_FORCEINLINE_FUNCTION backward(const NT &y) const { return (y - start) / a; }
317
318 size_t KOKKOS_FORCEINLINE_FUNCTION size() const { return grid_extent; }
319
320 device::array<size_t, 1> KOKKOS_FORCEINLINE_FUNCTION sizes() const { return {grid_extent}; }
321
322 const NT start, stop;
323
324 template <typename NT2>
326 {
327 if constexpr (!std::is_same_v<NT, NT2>) return false; // Different types, cannot be equal
328 return lhs.start == rhs.start && lhs.stop == rhs.stop && lhs.grid_extent == rhs.grid_extent;
329 }
330
331 std::string to_string() const
332 {
333 return "LinearCoordinates1D(" + std::to_string(grid_extent) + ", " + std::to_string(start) + ", " +
334 std::to_string(stop) + ")";
335 }
336
337 private:
338 const size_t grid_extent;
339 NT a;
340 };
341
353 template <typename NT = double>
354 requires std::is_floating_point_v<NT>
356 {
357 public:
358 using ctype = NT;
359 static constexpr size_t dim = 1;
360 static constexpr bool periodic = true;
361
363 : start(start), stop(stop), grid_extent(grid_extent), extent(static_cast<NT>(grid_extent))
364 {
365 if (grid_extent == 0) throw std::runtime_error("LinearPeriodicCoordinates1D: grid_extent must be > 0");
366 a = (stop - start) / NT(grid_extent);
367 }
368
369 template <typename NT2>
374
375 device::array<size_t, 1> KOKKOS_FORCEINLINE_FUNCTION from_linear_index(size_t i) const
376 {
377 return device::array<size_t, 1>{i};
378 }
379
386 template <typename IT> NT KOKKOS_FORCEINLINE_FUNCTION forward(const IT &x) const { return start + a * x; }
387
388 template <typename IT> device::array<NT, 1> KOKKOS_FORCEINLINE_FUNCTION forward(const device::array<IT, 1> &x) const
389 {
390 return {forward(x[0])};
391 }
392
399 NT KOKKOS_FORCEINLINE_FUNCTION backward(const NT &y) const
400 {
401 using Kokkos::floor;
402 // fmod would keep the sign of idx, so fold explicitly into [0, grid_extent)
403 NT idx = (y - start) / a;
404 idx -= floor(idx / extent) * extent;
405 // right at the seam the division can round such that the fold leaves idx just outside the interval
406 if (idx >= extent) idx -= extent;
407 if (idx < NT(0)) idx = NT(0);
408 return idx;
409 }
410
411 size_t KOKKOS_FORCEINLINE_FUNCTION size() const { return grid_extent; }
412
413 device::array<size_t, 1> KOKKOS_FORCEINLINE_FUNCTION sizes() const { return {grid_extent}; }
414
415 const NT start, stop;
416
417 template <typename NT2>
419 {
420 if constexpr (!std::is_same_v<NT, NT2>) return false; // Different types, cannot be equal
421 return lhs.start == rhs.start && lhs.stop == rhs.stop && lhs.grid_extent == rhs.grid_extent;
422 }
423
424 std::string to_string() const
425 {
426 return "LinearPeriodicCoordinates1D(" + std::to_string(grid_extent) + ", " + std::to_string(start) + ", " +
427 std::to_string(stop) + ")";
428 }
429
430 private:
431 const size_t grid_extent;
432 const NT extent;
433 NT a;
434 };
435
436 template <typename NT = double>
437 requires std::is_floating_point_v<NT>
439 {
440 public:
441 using ctype = NT;
442 static constexpr size_t dim = 1;
443
446 gem1inv(1. / (grid_extent - 1.))
447 {
448 if (grid_extent == 0) throw std::runtime_error("LogarithmicCoordinates1D: grid_extent must be > 0");
449 using Kokkos::expm1;
450 a = bias;
451 b = (stop - start) / expm1(a);
452 c = start;
453 }
454
455 template <typename NT2>
457 : LogarithmicCoordinates1D(other.size(), other.start, other.stop, other.bias)
458 {
459 }
460
461 device::array<size_t, 1> KOKKOS_FORCEINLINE_FUNCTION from_linear_index(size_t i) const
462 {
463 return device::array<size_t, 1>{i};
464 }
465
472 template <typename IT> NT KOKKOS_FORCEINLINE_FUNCTION forward(const IT &x) const
473 {
474 using Kokkos::expm1;
475 return b * expm1(a * x * gem1inv) + c;
476 }
477
478 template <typename IT> device::array<NT, 1> KOKKOS_FORCEINLINE_FUNCTION forward(const device::array<IT, 1> &x) const
479 {
480 return {forward(x[0])};
481 }
482
489 NT KOKKOS_FORCEINLINE_FUNCTION backward(const NT &y) const
490 {
491 using Kokkos::log1p;
492 return log1p((y - c) / b) * gem1 / a;
493 }
494
495 NT KOKKOS_FORCEINLINE_FUNCTION backward_derivative(const NT &y) const { return 1. / (y - c) * gem1 / a; }
496
497 size_t KOKKOS_FORCEINLINE_FUNCTION size() const { return grid_extent; }
498
499 device::array<size_t, 1> KOKKOS_FORCEINLINE_FUNCTION sizes() const { return {grid_extent}; }
500
501 const NT start, stop, bias;
502
503 template <typename NT2>
505 {
506 if constexpr (!std::is_same_v<NT, NT2>) return false; // Different types, cannot be equal
507 return lhs.start == rhs.start && lhs.stop == rhs.stop && lhs.bias == rhs.bias &&
508 lhs.grid_extent == rhs.grid_extent;
509 }
510
511 std::string to_string() const
512 {
513 return "LogarithmicCoordinates1D(" + std::to_string(start) + ", " + std::to_string(stop) + ", " +
514 std::to_string(bias) + ", " + std::to_string(grid_extent) + ")";
515 }
516
517 private:
518 const size_t grid_extent;
519 const NT gem1, gem1inv;
520 NT a, b, c;
521 };
522
552 template <typename NT = double>
553 requires std::is_floating_point_v<NT>
555 {
556 public:
557 using ctype = NT;
558 static constexpr size_t dim = 1;
559
571 {
572 if (grid_extent < 2) throw std::runtime_error("FocusedLogCoordinates1D: grid_extent must be > 1");
573 if (!(start > NT(0))) throw std::runtime_error("FocusedLogCoordinates1D: start must be > 0");
574 if (!(stop > start)) throw std::runtime_error("FocusedLogCoordinates1D: stop must be > start");
575 if (!(center > NT(0))) throw std::runtime_error("FocusedLogCoordinates1D: center must be > 0");
576 if (!(focus >= NT(0))) throw std::runtime_error("FocusedLogCoordinates1D: focus must be >= 0");
577
578 using Kokkos::log;
579 const NT u_start = log(start);
580 const NT u_stop = log(stop);
581
582 u0 = log(center);
583 c = focus;
584 // sinh(s)/c is 0/0 at c == 0; below this threshold the map is a pure logarithmic grid to
585 // within round-off anyway, so switch to it explicitly.
586 pure_log = !(focus > NT(1e-8));
587
588 if (pure_log) {
589 // in this branch s *is* u, so forward() degenerates to start * exp(u - log(start))
590 c_inv = NT(1);
591 s_min = u_start;
592 a = (u_stop - u_start) / NT(grid_extent - 1);
593 g_min = s_min;
594 } else {
595 c_inv = NT(1) / c;
596 s_min = s_of_u(u_start);
597 a = (s_of_u(u_stop) - s_min) / NT(grid_extent - 1);
598 using Kokkos::sinh;
599 // Store sinh(s_min), NOT sinh(s_min) * c_inv: forward() subtracts this BEFORE scaling by
600 // c_inv, which is what makes x == 0 cancel exactly. See the note in forward().
601 g_min = sinh(s_min);
602 }
603 a_inv = NT(1) / a;
604 }
605
606 template <typename NT2>
608 : FocusedLogCoordinates1D(other.size(), other.start, other.stop, other.center, other.focus)
609 {
610 }
611
612 device::array<size_t, 1> KOKKOS_FORCEINLINE_FUNCTION from_linear_index(size_t i) const
613 {
614 return device::array<size_t, 1>{i};
615 }
616
623 template <typename IT> NT KOKKOS_FORCEINLINE_FUNCTION forward(const IT &x) const
624 {
625 using Kokkos::exp, Kokkos::sinh;
626 const NT s = s_min + a * x;
627 // Factored as start * exp(...) rather than exp(log(start) + ...) so that x == 0 gives back
628 // start bit-for-bit: the models pair grid element 0 with the p_grid_min parameter directly.
629 // The upper end is then accurate to a handful of ulp, which nothing reads that way.
630 //
631 // The subtraction MUST happen before the multiplication by c_inv. Written the other way
632 // round, `sinh(s) * c_inv - g_min` is a multiply-add, which the compiler is free to
633 // contract into an FMA: the product is then kept at infinite precision and the ALREADY
634 // ROUNDED g_min subtracted from it, so x == 0 yields that rounding error instead of zero
635 // and start comes back off by an ulp. As written, `sinh(s) - g_min` is exactly zero at
636 // x == 0 (identical argument, same function), and 0 * c_inv is exactly zero.
637 const NT d = pure_log ? (s - g_min) : (sinh(s) - g_min) * c_inv;
638 return start * exp(d);
639 }
640
641 template <typename IT> device::array<NT, 1> KOKKOS_FORCEINLINE_FUNCTION forward(const device::array<IT, 1> &x) const
642 {
643 return {forward(x[0])};
644 }
645
652 NT KOKKOS_FORCEINLINE_FUNCTION backward(const NT &y) const
653 {
654 using Kokkos::log;
655 const NT u = log(y);
656 return ((pure_log ? u : s_of_u(u)) - s_min) * a_inv;
657 }
658
659 NT KOKKOS_FORCEINLINE_FUNCTION backward_derivative(const NT &y) const
660 {
661 using Kokkos::log, Kokkos::sqrt;
662 if (pure_log) return a_inv / y;
663 const NT v = c * (log(y) - u0);
664 return a_inv * c / (sqrt(v * v + NT(1)) * y);
665 }
666
667 size_t KOKKOS_FORCEINLINE_FUNCTION size() const { return grid_extent; }
668
669 device::array<size_t, 1> KOKKOS_FORCEINLINE_FUNCTION sizes() const { return {grid_extent}; }
670
671 const NT start, stop, center, focus;
672
673 template <typename NT2>
675 {
676 if constexpr (!std::is_same_v<NT, NT2>) return false; // Different types, cannot be equal
677 return lhs.start == rhs.start && lhs.stop == rhs.stop && lhs.center == rhs.center && lhs.focus == rhs.focus &&
678 lhs.size() == rhs.size();
679 }
680
681 std::string to_string() const
682 {
683 return "FocusedLogCoordinates1D(" + std::to_string(grid_extent) + ", " + round_trip(start) + ", " +
684 round_trip(stop) + ", " + round_trip(center) + ", " + round_trip(focus) + ")";
685 }
686
687 private:
699 static std::string round_trip(const NT value)
700 {
701 char buffer[40];
702 for (int precision = 6; precision < std::numeric_limits<NT>::max_digits10; ++precision) {
703 std::snprintf(buffer, sizeof(buffer), "%.*g", precision, double(value));
704 if (NT(std::strtod(buffer, nullptr)) == value) return std::string(buffer);
705 }
706 std::snprintf(buffer, sizeof(buffer), "%.*g", std::numeric_limits<NT>::max_digits10, double(value));
707 return std::string(buffer);
708 }
709
718 NT KOKKOS_FORCEINLINE_FUNCTION s_of_u(const NT u) const
719 {
720 using Kokkos::log, Kokkos::sqrt;
721 const NT v = c * (u - u0);
722 const NT D = sqrt(v * v + NT(1));
723 return v >= NT(0) ? log(v + D) : -log(D - v);
724 }
725
726 const size_t grid_extent;
729 };
730
731 template <typename Coordinates> auto make_grid(const Coordinates &coordinates)
732 {
733 using ctype = typename Coordinates::ctype;
735 std::vector<cortype> grid(coordinates.size());
736 for (size_t i = 0; i < coordinates.size(); ++i) {
737 const auto forwarded = coordinates.forward(coordinates.from_linear_index(i));
738 for (size_t j = 0; j < Coordinates::dim; ++j) {
739 grid[i][j] = forwarded[j];
740 }
741 }
742 return grid;
743 }
744
745 template <typename Coordinates> auto make_idx_grid(const Coordinates &coordinates) -> std::vector<double>
746 {
747 using ctype = typename Coordinates::ctype;
749 std::vector<cortype> grid(coordinates.size());
750 for (size_t i = 0; i < coordinates.size(); ++i) {
751 const auto forwarded = coordinates.from_linear_index(i);
752 for (size_t j = 0; j < Coordinates::dim; ++j) {
753 grid[i][j] = forwarded[j];
754 }
755 }
756 return grid;
757 }
758
759 template <typename Coordinates> std::vector<typename Coordinates::ctype> dump_grid(const Coordinates &coordinates)
760 {
761 using ctype = typename Coordinates::ctype;
762 std::vector<typename Coordinates::ctype> grid(coordinates.size() * Coordinates::dim);
763 for (size_t i = 0; i < coordinates.size(); ++i) {
764 for (size_t j = 0; j < Coordinates::dim; ++j) {
765 const auto forwarded = coordinates.forward(coordinates.from_linear_index(i));
766 grid[i * coordinates.dim + j] = forwarded[j];
767 }
768 }
769 return grid;
770 }
771
772 // Definitions of useful combined coordinates
785
786 // Logarithmic coordinates focused on an interior scale, see FocusedLogCoordinates1D
791
792 // Periodic (angular) coordinates
803} // namespace DiFfRG
Utility class for combining multiple coordinate systems into one.
Definition coordinates.hh:67
const auto & get_coordinates() const
Definition coordinates.hh:121
KOKKOS_FORCEINLINE_FUNCTION device::array< ctype, sizeof...(I)> backward(I &&...i) const
Definition coordinates.hh:108
size_t KOKKOS_FORCEINLINE_FUNCTION size() const
Definition coordinates.hh:129
std::string to_string() const
Definition coordinates.hh:173
KOKKOS_FORCEINLINE_FUNCTION device::array< ctype, dim > forward(I &&...i) const
Definition coordinates.hh:90
typename device::tuple_element< i, device::tuple< Coordinates... > >::type coordinate_type
The type of the i-th axis. Used e.g. to query per-axis periodicity, see is_periodic_axis_v.
Definition coordinates.hh:127
static constexpr size_t dim
Definition coordinates.hh:79
device::array< size_t, sizeof...(Coordinates)> KOKKOS_INLINE_FUNCTION from_linear_index(size_t s) const
Definition coordinates.hh:144
CoordinatePackND(Coordinates... coordinates)
Construct a new CoordinatePackND object.
Definition coordinates.hh:86
device::array< ctype, sizeof...(I)> KOKKOS_FORCEINLINE_FUNCTION backward_impl(device::integer_sequence< int, Is... >, I &&...i) const
Definition coordinates.hh:115
friend bool operator==(const CoordinatePackND< Coordinates... > &r, const CoordinatePackND< Coordinates2... > &l)
Definition coordinates.hh:157
device::array< size_t, sizeof...(Coordinates)> KOKKOS_FORCEINLINE_FUNCTION sizes() const
Definition coordinates.hh:137
device::array< ctype, dim > KOKKOS_FORCEINLINE_FUNCTION forward_impl(device::integer_sequence< int, Is... >, I &&...i) const
Definition coordinates.hh:102
const device::tuple< Coordinates... > coordinates
Definition coordinates.hh:185
KOKKOS_FORCEINLINE_FUNCTION device::array< ctype, dim > forward(const device::array< IT, dim > &coords) const
Definition coordinates.hh:96
typename device::tuple_element< 0, device::tuple< Coordinates... > >::type::ctype ctype
Definition coordinates.hh:78
Logarithmic coordinates which cluster grid points around an interior scale.
Definition coordinates.hh:555
NT a
Definition coordinates.hh:727
bool pure_log
Definition coordinates.hh:728
const size_t grid_extent
Definition coordinates.hh:726
NT a_inv
Definition coordinates.hh:727
FocusedLogCoordinates1D(const FocusedLogCoordinates1D< NT2 > &other)
Definition coordinates.hh:607
const NT start
Definition coordinates.hh:671
device::array< size_t, 1 > KOKKOS_FORCEINLINE_FUNCTION from_linear_index(size_t i) const
Definition coordinates.hh:612
NT c
Definition coordinates.hh:727
NT KOKKOS_FORCEINLINE_FUNCTION forward(const IT &x) const
Transform from the grid to the physical space.
Definition coordinates.hh:623
NT ctype
Definition coordinates.hh:557
FocusedLogCoordinates1D(size_t grid_extent, NT start, NT stop, NT center, NT focus)
Construct a new FocusedLogCoordinates1D object.
Definition coordinates.hh:569
NT s_min
Definition coordinates.hh:727
const NT stop
Definition coordinates.hh:671
NT KOKKOS_FORCEINLINE_FUNCTION backward_derivative(const NT &y) const
Definition coordinates.hh:659
NT KOKKOS_FORCEINLINE_FUNCTION backward(const NT &y) const
Transform from the physical space to the grid.
Definition coordinates.hh:652
static std::string round_trip(const NT value)
Format a parameter with the fewest digits that still identify it uniquely.
Definition coordinates.hh:699
std::string to_string() const
Definition coordinates.hh:681
const NT center
Definition coordinates.hh:671
NT KOKKOS_FORCEINLINE_FUNCTION s_of_u(const NT u) const
asinh(c * (u - u0)), written out to pick the cancellation-free branch.
Definition coordinates.hh:718
friend bool operator==(const FocusedLogCoordinates1D< NT > &lhs, const FocusedLogCoordinates1D< NT2 > &rhs)
Definition coordinates.hh:674
const NT focus
Definition coordinates.hh:671
size_t KOKKOS_FORCEINLINE_FUNCTION size() const
Definition coordinates.hh:667
NT c_inv
Definition coordinates.hh:727
static constexpr size_t dim
Definition coordinates.hh:558
device::array< NT, 1 > KOKKOS_FORCEINLINE_FUNCTION forward(const device::array< IT, 1 > &x) const
Definition coordinates.hh:641
NT g_min
Definition coordinates.hh:727
NT u0
Definition coordinates.hh:727
device::array< size_t, 1 > KOKKOS_FORCEINLINE_FUNCTION sizes() const
Definition coordinates.hh:669
Definition coordinates.hh:274
device::array< size_t, 1 > KOKKOS_FORCEINLINE_FUNCTION from_linear_index(size_t i) const
Definition coordinates.hh:292
friend bool operator==(const LinearCoordinates1D< NT > &lhs, const LinearCoordinates1D< NT2 > &rhs)
Definition coordinates.hh:325
LinearCoordinates1D(size_t grid_extent, double start, double stop)
Definition coordinates.hh:279
NT KOKKOS_FORCEINLINE_FUNCTION backward(const NT &y) const
Transform from the physical space to the grid.
Definition coordinates.hh:316
NT a
Definition coordinates.hh:339
static constexpr size_t dim
Definition coordinates.hh:277
const NT stop
Definition coordinates.hh:322
std::string to_string() const
Definition coordinates.hh:331
size_t KOKKOS_FORCEINLINE_FUNCTION size() const
Definition coordinates.hh:318
const NT start
Definition coordinates.hh:322
NT KOKKOS_FORCEINLINE_FUNCTION forward(const IT &x) const
Transform from the grid to the physical space.
Definition coordinates.hh:303
NT ctype
Definition coordinates.hh:276
LinearCoordinates1D(const LinearCoordinates1D< NT2 > &other)
Definition coordinates.hh:287
const size_t grid_extent
Definition coordinates.hh:338
device::array< size_t, 1 > KOKKOS_FORCEINLINE_FUNCTION sizes() const
Definition coordinates.hh:320
device::array< NT, 1 > KOKKOS_FORCEINLINE_FUNCTION forward(const device::array< IT, 1 > &x) const
Definition coordinates.hh:305
Linear coordinates on a periodic axis of period (stop - start).
Definition coordinates.hh:356
LinearPeriodicCoordinates1D(const LinearPeriodicCoordinates1D< NT2 > &other)
Definition coordinates.hh:370
NT ctype
Definition coordinates.hh:358
NT KOKKOS_FORCEINLINE_FUNCTION backward(const NT &y) const
Transform from the physical space to the grid, folded into [0, grid_extent)
Definition coordinates.hh:399
std::string to_string() const
Definition coordinates.hh:424
const NT stop
Definition coordinates.hh:415
NT KOKKOS_FORCEINLINE_FUNCTION forward(const IT &x) const
Transform from the grid to the physical space.
Definition coordinates.hh:386
static constexpr bool periodic
Definition coordinates.hh:360
friend bool operator==(const LinearPeriodicCoordinates1D< NT > &lhs, const LinearPeriodicCoordinates1D< NT2 > &rhs)
Definition coordinates.hh:418
device::array< size_t, 1 > KOKKOS_FORCEINLINE_FUNCTION from_linear_index(size_t i) const
Definition coordinates.hh:375
size_t KOKKOS_FORCEINLINE_FUNCTION size() const
Definition coordinates.hh:411
LinearPeriodicCoordinates1D(size_t grid_extent, double start, double stop)
Definition coordinates.hh:362
static constexpr size_t dim
Definition coordinates.hh:359
const NT extent
Definition coordinates.hh:432
device::array< NT, 1 > KOKKOS_FORCEINLINE_FUNCTION forward(const device::array< IT, 1 > &x) const
Definition coordinates.hh:388
const size_t grid_extent
Definition coordinates.hh:431
const NT start
Definition coordinates.hh:415
NT a
Definition coordinates.hh:433
device::array< size_t, 1 > KOKKOS_FORCEINLINE_FUNCTION sizes() const
Definition coordinates.hh:413
Definition coordinates.hh:439
const NT gem1
Definition coordinates.hh:519
LogarithmicCoordinates1D(const LogarithmicCoordinates1D< NT2 > &other)
Definition coordinates.hh:456
device::array< size_t, 1 > KOKKOS_FORCEINLINE_FUNCTION from_linear_index(size_t i) const
Definition coordinates.hh:461
NT KOKKOS_FORCEINLINE_FUNCTION backward_derivative(const NT &y) const
Definition coordinates.hh:495
const NT stop
Definition coordinates.hh:501
friend bool operator==(const LogarithmicCoordinates1D< NT > &lhs, const LogarithmicCoordinates1D< NT2 > &rhs)
Definition coordinates.hh:504
const NT gem1inv
Definition coordinates.hh:519
device::array< size_t, 1 > KOKKOS_FORCEINLINE_FUNCTION sizes() const
Definition coordinates.hh:499
std::string to_string() const
Definition coordinates.hh:511
NT KOKKOS_FORCEINLINE_FUNCTION forward(const IT &x) const
Transform from the grid to the physical space.
Definition coordinates.hh:472
const NT start
Definition coordinates.hh:501
NT a
Definition coordinates.hh:520
NT KOKKOS_FORCEINLINE_FUNCTION backward(const NT &y) const
Transform from the physical space to the grid.
Definition coordinates.hh:489
size_t KOKKOS_FORCEINLINE_FUNCTION size() const
Definition coordinates.hh:497
NT ctype
Definition coordinates.hh:441
device::array< NT, 1 > KOKKOS_FORCEINLINE_FUNCTION forward(const device::array< IT, 1 > &x) const
Definition coordinates.hh:478
LogarithmicCoordinates1D(size_t grid_extent, NT start, NT stop, NT bias)
Definition coordinates.hh:444
const NT bias
Definition coordinates.hh:501
NT b
Definition coordinates.hh:520
NT c
Definition coordinates.hh:520
static constexpr size_t dim
Definition coordinates.hh:442
const size_t grid_extent
Definition coordinates.hh:518
A contiguous window into the linear index range of another coordinate system.
Definition coordinates.hh:207
size_t m_offset
Definition coordinates.hh:267
KOKKOS_FORCEINLINE_FUNCTION device::array< ctype, dim > forward(I &&...i) const
Definition coordinates.hh:243
KOKKOS_INLINE_FUNCTION device::array< ctype, dim > forward(device::array< IT, dim > i) const
Takes a base multi-index, i.e. what from_linear_index() above returns.
Definition coordinates.hh:250
size_t KOKKOS_FORCEINLINE_FUNCTION size() const
Definition coordinates.hh:228
static constexpr size_t dim
Definition coordinates.hh:210
size_t m_size
Definition coordinates.hh:268
device::array< size_t, dim > KOKKOS_INLINE_FUNCTION from_linear_index(size_t s) const
Definition coordinates.hh:233
SubCoordinates(const Base &base, size_t offset, size_t size)
Definition coordinates.hh:212
std::string to_string() const
Definition coordinates.hh:260
typename Base::ctype ctype
Definition coordinates.hh:209
device::array< size_t, dim > KOKKOS_FORCEINLINE_FUNCTION sizes() const
Definition coordinates.hh:222
Definition coordinates.hh:22
std::array< T, N > array
Definition kokkos.hh:155
std::tuple< T... > tuple
Definition kokkos.hh:154
Definition complex_math.hh:10
constexpr bool is_periodic_axis_v
Whether axis i of a (possibly multi-dimensional) coordinate system is periodic. Falls back to false f...
Definition coordinates.hh:59
std::vector< typename Coordinates::ctype > dump_grid(const Coordinates &coordinates)
Definition coordinates.hh:759
constexpr void constexpr_for(F &&f)
A compile-time for loop, which calls the lambda f of signature void(integer) for each index.
Definition utils.hh:31
auto make_idx_grid(const Coordinates &coordinates) -> std::vector< double >
Definition coordinates.hh:745
constexpr bool is_periodic_coordinate_v
Whether a 1D coordinate class describes a periodic axis, i.e. one where the last grid point is follow...
Definition coordinates.hh:43
auto make_grid(const Coordinates &coordinates)
Definition coordinates.hh:731
Definition coordinates.hh:47
Definition coordinates.hh:32