Block-Structured AMR Software Framework
AMReX_IndexType.H
Go to the documentation of this file.
1 
2 #ifndef BL_INDEXTYPE_H
3 #define BL_INDEXTYPE_H
4 #include <AMReX_Config.H>
5 
6 #include <AMReX_IntVect.H>
7 #include <AMReX_SPACE.H>
8 #include <AMReX_Tuple.H>
9 
10 #include <iosfwd>
11 
12 namespace amrex {
13 
18 struct CellIndexEnum {
20  enum CellIndex { CELL = 0, NODE = 1 };
21 };
22 
31 template<int dim>
32 class IndexTypeND : public CellIndexEnum
33 {
34 public:
35  static_assert(1 <= dim && dim <= 31, "The number of dimensions of IndexTypeND must be positive"
36  " and less than 32");
37 
40  constexpr IndexTypeND () noexcept = default;
43  explicit IndexTypeND (const IntVectND<dim>& iv) noexcept {
44  for (int i=0; i<dim; ++i) {
45  itype |= (iv[i] ? 1U : 0U) << i;
46  }
47  }
53  template <class...Args,
54  std::enable_if_t<
55  (sizeof...(Args)+1 == dim) &&
56  IsConvertible_v<CellIndex, Args...>,
57  int> = 0>
59  constexpr IndexTypeND (CellIndex i, Args...js) noexcept {
60  CellIndex locarr[dim] = {i, static_cast<CellIndex>(js)...};
61  for (int s=0; s<dim; ++s) {
62  itype |= ((locarr[s] == CellIndex::NODE) ? 1U : 0U) << s;
63  }
64  }
65  // dtor, copy-ctor, copy-op=, move-ctor, and move-op= are compiler generated.
66 
69  void set (int dir) noexcept { itype |= mask(dir); }
72  void unset (int dir) noexcept { itype &= ~mask(dir); }
75  bool test (int dir) const noexcept { return (itype & mask(dir)) != 0; }
78  void setall () noexcept { itype = (1U << dim) - 1; }
81  void clear () noexcept { itype = 0; }
84  bool any () const noexcept { return itype != 0; }
87  bool ok () const noexcept { return itype < (1U << dim); }
90  void flip (int i) noexcept { itype ^= mask(i); }
93  bool operator== (const IndexTypeND& t) const noexcept { return t.itype == itype; }
96  bool operator!= (const IndexTypeND& t) const noexcept { return t.itype != itype; }
98  bool operator< (const IndexTypeND& t) const noexcept { return itype < t.itype; }
101  bool cellCentered () const noexcept { return itype == 0; }
104  bool cellCentered (int dir) const noexcept { return (itype & mask(dir)) == 0; }
107  bool nodeCentered () const noexcept { return itype == (1U<<dim)-1; }
110  bool nodeCentered (int dir) const noexcept { return (itype & mask(dir)) != 0; }
113  void setType (int dir, CellIndex t) noexcept { t == CELL ? unset(dir) : set(dir); }
115  [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
116  CellIndex ixType (int dir) const noexcept { return (CellIndex) ((itype & (1U<<dir)) >> dir); }
119  int operator[] (int dir) const noexcept { return test(dir); }
121  template<std::size_t i>
122  [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
123  CellIndex get () const noexcept { static_assert(0<=i && i<dim); return ixType(i); }
126  IntVectND<dim> ixType () const noexcept {
127  IntVectND<dim> retval(0);
128  for (int i=0; i<dim; ++i) {
129  retval[i] = test(i);
130  }
131  return retval;
132  }
135  IntVectND<dim> toIntVect () const noexcept {
136  IntVectND<dim> retval(0);
137  for (int i=0; i<dim; ++i) {
138  retval[i] = test(i);
139  }
140  return retval;
141  }
149  static constexpr IndexTypeND<dim> TheCellType () noexcept {
150  return IndexTypeND<dim>{};
151  }
159  static constexpr IndexTypeND<dim> TheNodeType () noexcept {
160  IndexTypeND<dim> retval{};
161  retval.setall();
162  return retval;
163  }
164 
167  static constexpr std::size_t size () noexcept {
168  return static_cast<std::size_t>(dim);
169  }
170 
173  static constexpr int isize () noexcept {
174  return dim;
175  }
176 
178 
183  template<int new_dim>
185  IndexTypeND<new_dim> shrink () const noexcept {
186  static_assert(new_dim <= dim);
187  IndexTypeND<new_dim> retval{};
188  retval.getBits() = itype & ((1U << new_dim) - 1);
189  return retval;
190  }
191 
196  template<int new_dim>
198  IndexTypeND<new_dim> expand (CellIndex fill_extra=CellIndex::CELL) const noexcept {
199  static_assert(new_dim >= dim);
200  IndexTypeND<new_dim> retval{};
201  retval.getBits() = itype;
202  if (fill_extra == CellIndex::NODE) {
203  retval.getBits() |= (1U << new_dim) - (1U << dim);
204  }
205  return retval;
206  }
207 
212  template<int new_dim>
214  IndexTypeND<new_dim> resize (CellIndex fill_extra=CellIndex::CELL) const noexcept {
215  if constexpr (new_dim > dim) {
216  return expand<new_dim>(fill_extra);
217  } else {
218  return shrink<new_dim>();
219  }
220  }
221 
223  [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
224  unsigned int& getBits () noexcept { return itype; }
225 
227  [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
228  const unsigned int& getBits () const noexcept { return itype; }
229 
230 private:
233  static constexpr unsigned int mask (int k) noexcept { return 1U<<k; }
235  unsigned int itype{0};
236 };
237 
238 using IndexType = IndexTypeND<AMREX_SPACEDIM>;
239 
240 // Template deduction guide for IndexTypeND
241 template<int dim>
242 AMREX_GPU_HOST_DEVICE // __device__ for HIP
244 
245 // Template deduction guide for IndexTypeND
246 template <class...Args,
247  std::enable_if_t<
249  int> = 0>
250 AMREX_GPU_HOST_DEVICE // __device__ for HIP
251 IndexTypeND(IndexType::CellIndex, Args...) -> IndexTypeND<sizeof...(Args)+1>;
252 
253 namespace detail {
254  std::ostream& index_type_write (std::ostream& os, const unsigned int& iv, int dim);
255  std::istream& index_type_read (std::istream& is, unsigned int& iv, int dim);
256 
257  template<class T, std::size_t...Ns>
258  [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
259  T IndexTypeSplit_imp (T& retval, std::index_sequence<Ns...>, unsigned int src) noexcept {
260  int dim_shift = 0;
261  (
262  (
263  amrex::get<Ns>(retval).getBits() =
264  (src >> dim_shift) & ((1U << amrex::get<Ns>(retval).isize()) - 1),
265  dim_shift += amrex::get<Ns>(retval).isize()
266  ), ...
267  );
268  return retval;
269  }
270 }
271 
273 template<int dim>
274 std::ostream& operator<< (std::ostream& os, const IndexTypeND<dim>& it) {
275  return detail::index_type_write(os, it.getBits(), dim);
276 }
278 template<int dim>
279 std::istream& operator>> (std::istream& is, IndexTypeND<dim>& it) {
280  return detail::index_type_read(is, it.getBits(), dim);
281 }
282 
287 template<int d, int...dims>
289 constexpr IndexTypeND<detail::get_sum<d, dims...>()>
290 IndexTypeCat (const IndexTypeND<d>& v, const IndexTypeND<dims>&...vects) noexcept {
291  IndexTypeND<detail::get_sum<d, dims...>()> retval{};
292  retval.getBits() |= v.getBits();
293  int dim_shift = v.isize();
294  (
295  (
296  retval.getBits() |= (vects.getBits() << dim_shift),
297  dim_shift += vects.isize()
298  ), ...
299  );
300  return retval;
301 }
302 
307 template<int d, int...dims>
309 constexpr GpuTuple<IndexTypeND<d>, IndexTypeND<dims>...>
310 IndexTypeSplit (const IndexTypeND<detail::get_sum<d, dims...>()>& v) noexcept {
312  return detail::IndexTypeSplit_imp(retval,
313  std::make_index_sequence<1 + sizeof...(dims)>(),
314  v.getBits());
315 }
316 
321 template<int new_dim, int old_dim>
323 constexpr IndexTypeND<new_dim>
325  return v.template shrink<new_dim>();
326 }
327 
332 template<int new_dim, int old_dim>
334 constexpr IndexTypeND<new_dim>
336  IndexType::CellIndex fill_extra=IndexType::CellIndex::CELL) noexcept {
337  return v.template expand<new_dim>(fill_extra);
338 }
339 
344 template<int new_dim, int old_dim>
346 constexpr IndexTypeND<new_dim>
348  IndexType::CellIndex fill_extra=IndexType::CellIndex::CELL) noexcept {
349  return v.template resize<new_dim>(fill_extra);
350 }
351 
352 } // namespace amrex
353 
354 // Spcialize std::tuple_size for IndexTypeND. Used by structured bindings.
355 template<int dim>
356 struct std::tuple_size<amrex::IndexTypeND<dim>> {
357  static constexpr std::size_t value = dim;
358 };
359 
360 // Spcialize std::tuple_element for IndexTypeND. Used by structured bindings.
361 template<std::size_t s, int dim>
362 struct std::tuple_element<s, amrex::IndexTypeND<dim>> {
364 };
365 
366 #endif /*BL_INDEXTYPE_H*/
#define AMREX_FORCE_INLINE
Definition: AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
@ NODE
Definition: amrex_iparser.tab.h:65
Definition: AMReX_Tuple.H:93
Cell-Based or Node-Based Indices.
Definition: AMReX_IndexType.H:33
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool cellCentered() const noexcept
True if the IndexTypeND is CELL based in all directions.
Definition: AMReX_IndexType.H:101
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int operator[](int dir) const noexcept
Return an integer representing the IndexTypeND in direction dir.
Definition: AMReX_IndexType.H:119
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void flip(int i) noexcept
Change from CELL to NODE or NODE to CELL in direction dir.
Definition: AMReX_IndexType.H:90
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool operator!=(const IndexTypeND &t) const noexcept
True if IndexTypeNDs are not identical.
Definition: AMReX_IndexType.H:96
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool operator<(const IndexTypeND &t) const noexcept
Definition: AMReX_IndexType.H:98
AMREX_GPU_HOST_DEVICE static constexpr AMREX_FORCE_INLINE std::size_t size() noexcept
Return the size of this&#160;IndexTypeND.
Definition: AMReX_IndexType.H:167
unsigned int itype
An integer holding the CellIndex in bits 0 - dim-1.
Definition: AMReX_IndexType.H:235
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void unset(int dir) noexcept
Set IndexTypeND to be CELL based in direction dir.
Definition: AMReX_IndexType.H:72
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IntVectND< dim > toIntVect() const noexcept
Fill an IntVectND of size dim with IndexTypeNDs.
Definition: AMReX_IndexType.H:135
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE const unsigned int & getBits() const noexcept
Return the bit field representing the underlying data.
Definition: AMReX_IndexType.H:228
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IntVectND< dim > ixType() const noexcept
Fill an IntVectND of size dim with IndexTypeNDs.
Definition: AMReX_IndexType.H:126
AMREX_GPU_HOST_DEVICE static constexpr AMREX_FORCE_INLINE int isize() noexcept
Return the size of this&#160;IndexTypeND.
Definition: AMReX_IndexType.H:173
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE void setall() noexcept
Set NODE based in all directions.
Definition: AMReX_IndexType.H:78
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE CellIndex get() const noexcept
Returns the i'th CellIndex of the IndexTypeND. Used by structured bindings.
Definition: AMReX_IndexType.H:123
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void clear() noexcept
Set CELL based in all directions.
Definition: AMReX_IndexType.H:81
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IndexTypeND< new_dim > shrink() const noexcept
Returns a new IndexTypeND of size new_dim and assigns the first new_dim values of this IndexTypeND to...
Definition: AMReX_IndexType.H:185
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool cellCentered(int dir) const noexcept
True if the IndexTypeND is CELL based in dir-direction.
Definition: AMReX_IndexType.H:104
constexpr AMREX_GPU_HOST_DEVICE IndexTypeND(CellIndex i, Args...js) noexcept
Construct an IndexTypeND given an explicit CellIndex for each direction. The inputs for this construc...
Definition: AMReX_IndexType.H:59
AMREX_GPU_HOST_DEVICE static constexpr AMREX_FORCE_INLINE IndexTypeND< dim > TheNodeType() noexcept
This static member function returns an IndexTypeND object of value IndexTypeND::NODE....
Definition: AMReX_IndexType.H:159
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool nodeCentered() const noexcept
True if the IndexTypeND is NODE based in all directions.
Definition: AMReX_IndexType.H:107
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void setType(int dir, CellIndex t) noexcept
Set IndexTypeND to CellIndex type t in direction dir.
Definition: AMReX_IndexType.H:113
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IndexTypeND< new_dim > expand(CellIndex fill_extra=CellIndex::CELL) const noexcept
Returns a new IndexTypeND of size new_dim and assigns all values of this IndexTypeND to it and&#160;fill_e...
Definition: AMReX_IndexType.H:198
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE IndexTypeND< new_dim > resize(CellIndex fill_extra=CellIndex::CELL) const noexcept
Returns a new IndexTypeND of size new_dim by either shrinking or expanding this IndexTypeND.
Definition: AMReX_IndexType.H:214
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool test(int dir) const noexcept
True if IndexTypeND is NODE based in direction dir.
Definition: AMReX_IndexType.H:75
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE unsigned int & getBits() noexcept
Return the bit field representing the underlying data.
Definition: AMReX_IndexType.H:224
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE CellIndex ixType(int dir) const noexcept
Returns the CellIndex in direction dir.
Definition: AMReX_IndexType.H:116
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool operator==(const IndexTypeND &t) const noexcept
True if IndexTypeNDs are identical.
Definition: AMReX_IndexType.H:93
constexpr AMREX_GPU_HOST_DEVICE IndexTypeND() noexcept=default
The default constructor.
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool ok() const noexcept
True if IndexTypeND is valid.
Definition: AMReX_IndexType.H:87
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void set(int dir) noexcept
Set IndexTypeND to be NODE based in direction dir.
Definition: AMReX_IndexType.H:69
AMREX_GPU_HOST_DEVICE static constexpr AMREX_FORCE_INLINE unsigned int mask(int k) noexcept
Returns 1<<k.
Definition: AMReX_IndexType.H:233
AMREX_GPU_HOST_DEVICE static constexpr AMREX_FORCE_INLINE IndexTypeND< dim > TheCellType() noexcept
This static member function returns an IndexTypeND object of value IndexTypeND::CELL....
Definition: AMReX_IndexType.H:149
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool any() const noexcept
True if this IndexTypeND is NODE based in any direction.
Definition: AMReX_IndexType.H:84
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool nodeCentered(int dir) const noexcept
True if the IndexTypeND is NODE based in dir-direction.
Definition: AMReX_IndexType.H:110
Definition: AMReX_IntVect.H:48
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE int get_sum()
Definition: AMReX_IntVect.H:1132
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE T IndexTypeSplit_imp(T &retval, std::index_sequence< Ns... >, unsigned int src) noexcept
Definition: AMReX_IndexType.H:259
std::ostream & index_type_write(std::ostream &os, const unsigned int &iv, int dim)
Definition: AMReX_IndexType.cpp:10
std::istream & index_type_read(std::istream &is, unsigned int &iv, int dim)
Definition: AMReX_IndexType.cpp:31
Definition: AMReX_Amr.cpp:49
AMREX_GPU_HOST_DEVICE IndexTypeND(const IntVectND< dim > &) -> IndexTypeND< dim >
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE IndexTypeND< new_dim > IndexTypeExpand(const IndexTypeND< old_dim > &v, IndexType::CellIndex fill_extra=IndexType::CellIndex::CELL) noexcept
Returns a new IndexTypeND of size new_dim and assigns all values of iv to it and&#160;fill_extra to the re...
Definition: AMReX_IndexType.H:335
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE IndexTypeND< detail::get_sum< d, dims... >)> IndexTypeCat(const IndexTypeND< d > &v, const IndexTypeND< dims > &...vects) noexcept
Returns a IndexTypeND obtained by concatenating the input IndexTypeNDs. The dimension of the return v...
Definition: AMReX_IndexType.H:290
constexpr bool IsConvertible_v
Definition: AMReX_TypeTraits.H:262
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE IndexTypeND< new_dim > IndexTypeShrink(const IndexTypeND< old_dim > &v) noexcept
Returns a new IndexTypeND of size new_dim and assigns the first new_dim values of v to it.
Definition: AMReX_IndexType.H:324
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE IndexTypeND< new_dim > IndexTypeResize(const IndexTypeND< old_dim > &v, IndexType::CellIndex fill_extra=IndexType::CellIndex::CELL) noexcept
Returns a new IndexTypeND of size new_dim by either shrinking or expanding iv.
Definition: AMReX_IndexType.H:347
AMREX_GPU_HOST_DEVICE IndexTypeND(IndexType::CellIndex, Args...) -> IndexTypeND< sizeof...(Args)+1 >
IndexTypeND< AMREX_SPACEDIM > IndexType
Definition: AMReX_BaseFwd.H:33
AMREX_GPU_HOST_DEVICE constexpr AMREX_FORCE_INLINE GpuTuple< IndexTypeND< d >, IndexTypeND< dims >... > IndexTypeSplit(const IndexTypeND< detail::get_sum< d, dims... >()> &v) noexcept
Returns a tuple of IndexTypeND obtained by splitting the input IndexTypeND according to the dimension...
Definition: AMReX_IndexType.H:310
std::ostream & operator<<(std::ostream &os, AmrMesh const &amr_mesh)
Definition: AMReX_AmrMesh.cpp:1236
std::istream & operator>>(std::istream &is, BoxND< dim > &bx)
Read from istream.
Definition: AMReX_Box.H:1700
Definition: AMReX_FabArrayCommI.H:896
Type for defining CellIndex so that all IndexTypeND with different dimensions have the same CellIndex...
Definition: AMReX_IndexType.H:18
CellIndex
The cell index type: one of CELL or NODE.
Definition: AMReX_IndexType.H:20
@ CELL
Definition: AMReX_IndexType.H:20
@ NODE
Definition: AMReX_IndexType.H:20
typename amrex::IndexTypeND< dim >::CellIndex type
Definition: AMReX_IndexType.H:363