IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
NDIndex.hpp
Go to the documentation of this file.
1//
2// Class NDIndex
3// This is a simple wrapper around Index that just keeps track of
4// N of them and passes along requests for intersect, etc.
5//
6#include <iostream>
7
8namespace ippl {
9 template <unsigned Dim>
10 template <class... Args>
11 KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(const Args&... args)
12 : NDIndex({args...}) {
13 static_assert(Dim == sizeof...(args), "Wrong number of arguments.");
14 }
15
16 template <unsigned Dim>
17 KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(std::initializer_list<Index> indices) {
18 unsigned int i = 0;
19 for (auto& index : indices) {
20 indices_m[i] = index;
21 ++i;
22 }
23 }
24
25 template <unsigned Dim>
26 KOKKOS_FUNCTION NDIndex<Dim>::NDIndex(const Vector<unsigned, Dim>& sizes) {
27 for (unsigned int d = 0; d < Dim; ++d) {
28 indices_m[d] = Index(sizes[d]);
29 }
30 }
31
32 template <unsigned Dim>
33 KOKKOS_INLINE_FUNCTION const Index& NDIndex<Dim>::operator[](unsigned d) const noexcept {
34 return indices_m[d];
35 }
36
37 template <unsigned Dim>
38 KOKKOS_INLINE_FUNCTION Index& NDIndex<Dim>::operator[](unsigned d) noexcept {
39 return indices_m[d];
40 }
41
42 template <unsigned Dim>
43 KOKKOS_INLINE_FUNCTION unsigned NDIndex<Dim>::size() const noexcept {
44 unsigned s = indices_m[0].length();
45 for (unsigned int d = 1; d < Dim; ++d) {
46 s *= indices_m[d].length();
47 }
48 return s;
49 }
50
51 template <unsigned Dim>
52 KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::empty() const noexcept {
53 bool r = false;
54 for (unsigned d = 0; d < Dim; ++d) {
55 r = r || indices_m[d].empty();
56 }
57 return r;
58 }
59
60 template <unsigned Dim>
61 inline std::ostream& operator<<(std::ostream& out, const NDIndex<Dim>& idx) {
62 out << '{';
63 for (unsigned d = 0; d < Dim; ++d) {
64 out << idx[d] << ((d == Dim - 1) ? '}' : ',');
65 }
66 return out;
67 }
68
69 template <unsigned Dim>
70 KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::intersect(const NDIndex<Dim>& ndi) const {
72 for (unsigned d = 0; d < Dim; ++d) {
73 r[d] = indices_m[d].intersect(ndi[d]);
74 }
75 return r;
76 }
77
78 template <unsigned Dim>
79 KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells) const {
81 for (unsigned d = 0; d < Dim; ++d) {
82 r[d] = indices_m[d].grow(ncells);
83 }
84 return r;
85 }
86
87 template <unsigned Dim>
88 KOKKOS_INLINE_FUNCTION NDIndex<Dim> NDIndex<Dim>::grow(int ncells, unsigned int dim) const {
89 NDIndex<Dim> r = *this;
90 r[dim] = indices_m[dim].grow(ncells);
91 return r;
92 }
93
94 template <unsigned Dim>
95 KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::touches(const NDIndex<Dim>& a) const {
96 bool touch = true;
97 for (unsigned int d = 0; (d < Dim) && touch; ++d) {
98 touch = touch && indices_m[d].touches(a.indices_m[d]);
99 }
100 return touch;
101 }
102
103 template <unsigned Dim>
104 KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::contains(const NDIndex<Dim>& a) const {
105 bool cont = true;
106 for (unsigned int d = 0; (d < Dim) && cont; ++d) {
107 cont = cont && indices_m[d].contains(a.indices_m[d]);
108 }
109 return cont;
110 }
111
112 template <unsigned Dim>
113 KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r, unsigned d,
114 int i) const {
115 if (&l != this) {
116 l = *this;
117 }
118 if (&r != this) {
119 r = *this;
120 }
121 return indices_m[d].split(l[d], r[d], i);
122 }
123
124 template <unsigned Dim>
125 KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r, unsigned d,
126 double a) const {
127 if (&l != this) {
128 l = *this;
129 }
130 if (&r != this) {
131 r = *this;
132 }
133 return indices_m[d].split(l[d], r[d], a);
134 }
135
136 template <unsigned Dim>
137 KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r,
138 unsigned d) const {
139 if (&l != this) {
140 l = *this;
141 }
142 if (&r != this) {
143 r = *this;
144 }
145 return indices_m[d].split(l[d], r[d]);
146 }
147
148 template <unsigned Dim>
149 KOKKOS_INLINE_FUNCTION bool NDIndex<Dim>::split(NDIndex<Dim>& l, NDIndex<Dim>& r) const {
150 unsigned int max_dim = 0;
151 unsigned int max_length = 0;
152 for (unsigned int d = 0; d < Dim; ++d) {
153 if (indices_m[d].length() > max_length) {
154 max_dim = d;
155 max_length = indices_m[d].length();
156 }
157 }
158 return split(l, r, max_dim);
159 }
160
161 template <unsigned Dim>
162 KOKKOS_INLINE_FUNCTION Vector<size_t, Dim> NDIndex<Dim>::length() const {
163 auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
164 return Vector<size_t, Dim>{indices_m[Idx].length()...};
165 };
166 return construct(std::make_index_sequence<Dim>{});
167 }
168
169 template <unsigned Dim>
170 KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::first() const {
171 auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
172 return Vector<int, Dim>{indices_m[Idx].first()...};
173 };
174 return construct(std::make_index_sequence<Dim>{});
175 }
176
177 template <unsigned Dim>
178 KOKKOS_INLINE_FUNCTION Vector<int, Dim> NDIndex<Dim>::last() const {
179 auto construct = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
180 return Vector<int, Dim>{indices_m[Idx].last()...};
181 };
182 return construct(std::make_index_sequence<Dim>{});
183 }
184
185 template <unsigned Dim>
186 KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::iterator NDIndex<Dim>::begin() {
187 return indices_m;
188 }
189
190 template <unsigned Dim>
191 KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::iterator NDIndex<Dim>::end() {
192 return indices_m + Dim;
193 }
194
195 template <unsigned Dim>
196 KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::begin()
197 const {
198 return indices_m;
199 }
200
201 template <unsigned Dim>
202 KOKKOS_INLINE_FUNCTION constexpr typename NDIndex<Dim>::const_iterator NDIndex<Dim>::end()
203 const {
204 return indices_m + Dim;
205 }
206
207 template <unsigned Dim>
208 bool operator==(const NDIndex<Dim>& nd1, const NDIndex<Dim>& nd2) {
209 for (unsigned d = 0; d < Dim; d++) {
210 if (nd1[d] != nd2[d]) {
211 return false;
212 }
213 }
214 return true;
215 }
216
217 template <unsigned Dim>
218 bool operator!=(const NDIndex<Dim>& nd1, const NDIndex<Dim>& nd2) {
219 return !(nd1 == nd2);
220 }
221} // namespace ippl
constexpr unsigned Dim
Definition Archive.h:20
bool operator!=(const NDIndex< Dim > &nd1, const NDIndex< Dim > &nd2)
Definition NDIndex.hpp:218
bool operator==(const NDIndex< Dim > &nd1, const NDIndex< Dim > &nd2)
Definition NDIndex.hpp:208
std::ostream & operator<<(std::ostream &os, const BConds< Field, Dim > &bc)
Definition BConds.h:49
const Index * const_iterator
Definition NDIndex.h:82
KOKKOS_INLINE_FUNCTION constexpr iterator begin()
Definition NDIndex.hpp:186
Index * iterator
Definition NDIndex.h:81
KOKKOS_INLINE_FUNCTION bool touches(const NDIndex< Dim > &) const
Definition NDIndex.hpp:95
KOKKOS_INLINE_FUNCTION bool empty() const noexcept
Definition NDIndex.hpp:52
KOKKOS_INLINE_FUNCTION Vector< int, Dim > last() const
Definition NDIndex.hpp:178
KOKKOS_INLINE_FUNCTION unsigned size() const noexcept
Definition NDIndex.hpp:43
KOKKOS_INLINE_FUNCTION Vector< int, Dim > first() const
Definition NDIndex.hpp:170
KOKKOS_FUNCTION NDIndex()
Definition NDIndex.h:24
KOKKOS_INLINE_FUNCTION const ippl::Index & operator[](unsigned d) const noexcept
Definition NDIndex.hpp:33
KOKKOS_INLINE_FUNCTION bool split(NDIndex< Dim > &l, NDIndex< Dim > &r, unsigned d, int i) const
Definition NDIndex.hpp:113
KOKKOS_INLINE_FUNCTION NDIndex< Dim > intersect(const NDIndex< Dim > &) const
Definition NDIndex.hpp:70
Index indices_m[Dim]
Array of indices.
Definition NDIndex.h:93
KOKKOS_INLINE_FUNCTION bool contains(const NDIndex< Dim > &a) const
Definition NDIndex.hpp:104
KOKKOS_INLINE_FUNCTION Vector< size_t, Dim > length() const
Definition NDIndex.hpp:162
KOKKOS_INLINE_FUNCTION constexpr iterator end()
Definition NDIndex.hpp:191
KOKKOS_INLINE_FUNCTION NDIndex< Dim > grow(int ncells) const
Definition NDIndex.hpp:79