Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
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
12namespace amrex {
13
21 enum CellIndex { CELL = 0, NODE = 1 };
22};
23
34template<int dim>
36{
37public:
38 static_assert(1 <= dim && dim <= 31, "The number of dimensions of IndexTypeND must be positive"
39 " and less than 32");
40
43 constexpr IndexTypeND () noexcept = default;
46 explicit IndexTypeND (const IntVectND<dim>& iv) noexcept {
47 for (int i=0; i<dim; ++i) {
48 itype |= (iv[i] ? 1U : 0U) << i;
49 }
50 }
56 template <class...Args>
57 requires ((sizeof...(Args)+1 == dim) &&
58 IsConvertible_v<CellIndex, Args...>)
60 constexpr IndexTypeND (CellIndex i, Args...js) noexcept {
61 CellIndex locarr[dim] = {i, static_cast<CellIndex>(js)...};
62 for (int s=0; s<dim; ++s) {
63 itype |= ((locarr[s] == CellIndex::NODE) ? 1U : 0U) << s;
64 }
65 }
66 // dtor, copy-ctor, copy-op=, move-ctor, and move-op= are compiler generated.
67
70 void set (int dir) noexcept { itype |= mask(dir); }
73 void unset (int dir) noexcept { itype &= ~mask(dir); }
76 bool test (int dir) const noexcept { return (itype & mask(dir)) != 0; }
79 void setall () noexcept { itype = (1U << dim) - 1; }
82 void clear () noexcept { itype = 0; }
85 bool any () const noexcept { return itype != 0; }
88 bool ok () const noexcept { return itype < (1U << dim); }
91 void flip (int i) noexcept { itype ^= mask(i); }
94 bool operator== (const IndexTypeND& t) const noexcept { return t.itype == itype; }
97 bool operator!= (const IndexTypeND& t) const noexcept { return t.itype != itype; }
99 bool operator< (const IndexTypeND& t) const noexcept { return itype < t.itype; }
102 bool cellCentered () const noexcept { return itype == 0; }
105 bool cellCentered (int dir) const noexcept { return (itype & mask(dir)) == 0; }
108 bool nodeCentered () const noexcept { return itype == (1U<<dim)-1; }
111 bool nodeCentered (int dir) const noexcept { return (itype & mask(dir)) != 0; }
114 void setType (int dir, CellIndex t) noexcept { t == CELL ? unset(dir) : set(dir); }
116 [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
117 CellIndex ixType (int dir) const noexcept { return (CellIndex) ((itype & (1U<<dir)) >> dir); }
120 int operator[] (int dir) const noexcept { return test(dir); }
122 template<std::size_t i>
123 [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
124 CellIndex get () const noexcept { static_assert(0<=i && i<dim); return ixType(i); }
127 IntVectND<dim> ixType () const noexcept {
128 IntVectND<dim> retval(0);
129 for (int i=0; i<dim; ++i) {
130 retval[i] = test(i);
131 }
132 return retval;
133 }
136 IntVectND<dim> toIntVect () const noexcept {
137 IntVectND<dim> retval(0);
138 for (int i=0; i<dim; ++i) {
139 retval[i] = test(i);
140 }
141 return retval;
142 }
150 static constexpr IndexTypeND<dim> TheCellType () noexcept {
151 return IndexTypeND<dim>{};
152 }
160 static constexpr IndexTypeND<dim> TheNodeType () noexcept {
161 IndexTypeND<dim> retval{};
162 retval.setall();
163 return retval;
164 }
165
168 static constexpr std::size_t size () noexcept {
169 return static_cast<std::size_t>(dim);
170 }
171
174 static constexpr int isize () noexcept {
175 return dim;
176 }
177
179
184 template<int new_dim>
186 IndexTypeND<new_dim> shrink () const noexcept {
187 static_assert(new_dim <= dim);
188 IndexTypeND<new_dim> retval{};
189 retval.getBits() = itype & ((1U << new_dim) - 1);
190 return retval;
191 }
192
197 template<int new_dim>
200 static_assert(new_dim >= dim);
201 IndexTypeND<new_dim> retval{};
202 retval.getBits() = itype;
203 if (fill_extra == CellIndex::NODE) {
204 retval.getBits() |= (1U << new_dim) - (1U << dim);
205 }
206 return retval;
207 }
208
213 template<int new_dim>
216 if constexpr (new_dim > dim) {
217 return expand<new_dim>(fill_extra);
218 } else {
219 return shrink<new_dim>();
220 }
221 }
222
224 [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
225 unsigned int& getBits () noexcept { return itype; }
226
228 [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
229 const unsigned int& getBits () const noexcept { return itype; }
230
231private:
234 static constexpr unsigned int mask (int k) noexcept { return 1U<<k; }
236 unsigned int itype{0};
237};
238
241using IndexType = IndexTypeND<AMREX_SPACEDIM>;
242
243// Template deduction guide for IndexTypeND
244template<int dim>
245AMREX_GPU_HOST_DEVICE // __device__ for HIP
247
248// Template deduction guide for IndexTypeND
249template <class...Args>
250requires (IsConvertible_v<IndexType::CellIndex, Args...>)
251AMREX_GPU_HOST_DEVICE // __device__ for HIP
252IndexTypeND(IndexType::CellIndex, Args...) -> IndexTypeND<sizeof...(Args)+1>;
253
255namespace detail {
256 std::ostream& index_type_write (std::ostream& os, const unsigned int& iv, int dim);
257 std::istream& index_type_read (std::istream& is, unsigned int& iv, int dim);
258
259 template<class T, std::size_t...Ns>
260 [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE constexpr
261 T IndexTypeSplit_imp (T& retval, std::index_sequence<Ns...>, unsigned int src) noexcept {
262 int dim_shift = 0;
263 (
264 (
265 amrex::get<Ns>(retval).getBits() =
266 (src >> dim_shift) & ((1U << amrex::get<Ns>(retval).isize()) - 1),
267 dim_shift += amrex::get<Ns>(retval).isize()
268 ), ...
269 );
270 return retval;
271 }
272}
274
276template<int dim>
277std::ostream& operator<< (std::ostream& os, const IndexTypeND<dim>& it) {
278 return detail::index_type_write(os, it.getBits(), dim);
279}
281template<int dim>
282std::istream& operator>> (std::istream& is, IndexTypeND<dim>& it) {
283 return detail::index_type_read(is, it.getBits(), dim);
284}
285
290template<int d, int...dims>
292constexpr IndexTypeND<detail::get_sum<d, dims...>()>
293IndexTypeCat (const IndexTypeND<d>& v, const IndexTypeND<dims>&...vects) noexcept {
294 IndexTypeND<detail::get_sum<d, dims...>()> retval{};
295 retval.getBits() |= v.getBits();
296 int dim_shift = v.isize();
297 (
298 (
299 retval.getBits() |= (vects.getBits() << dim_shift),
300 dim_shift += vects.isize()
301 ), ...
302 );
303 return retval;
304}
305
310template<int d, int...dims>
312constexpr GpuTuple<IndexTypeND<d>, IndexTypeND<dims>...>
313IndexTypeSplit (const IndexTypeND<detail::get_sum<d, dims...>()>& v) noexcept {
315 return detail::IndexTypeSplit_imp(retval,
316 std::make_index_sequence<1 + sizeof...(dims)>(),
317 v.getBits());
318}
319
324template<int new_dim, int old_dim>
326constexpr IndexTypeND<new_dim>
328 return v.template shrink<new_dim>();
329}
330
335template<int new_dim, int old_dim>
337constexpr IndexTypeND<new_dim>
340 return v.template expand<new_dim>(fill_extra);
341}
342
347template<int new_dim, int old_dim>
349constexpr IndexTypeND<new_dim>
352 return v.template resize<new_dim>(fill_extra);
353}
354
355} // namespace amrex
356
357// Spcialize std::tuple_size for IndexTypeND. Used by structured bindings.
358template<int dim>
359struct std::tuple_size<amrex::IndexTypeND<dim>> {
360 static constexpr std::size_t value = dim;
361};
362
363// Spcialize std::tuple_element for IndexTypeND. Used by structured bindings.
364template<std::size_t s, int dim>
365struct std::tuple_element<s, amrex::IndexTypeND<dim>> {
367};
368
369#endif /*BL_INDEXTYPE_H*/
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Array4< int const > mask
Definition AMReX_InterpFaceRegister.cpp:93
GPU-compatible tuple.
Definition AMReX_Tuple.H:98
Cell-Based or Node-Based Indices.
Definition AMReX_IndexType.H:36
__host__ __device__ constexpr CellIndex ixType(int dir) const noexcept
Returns the CellIndex in direction dir.
Definition AMReX_IndexType.H:117
__host__ __device__ bool operator==(const IndexTypeND &t) const noexcept
True if IndexTypeNDs are identical.
Definition AMReX_IndexType.H:94
__host__ __device__ bool test(int dir) const noexcept
True if IndexTypeND is NODE based in direction dir.
Definition AMReX_IndexType.H:76
__host__ __device__ bool cellCentered() const noexcept
True if the IndexTypeND is CELL based in all directions.
Definition AMReX_IndexType.H:102
__host__ __device__ 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 fill_e...
Definition AMReX_IndexType.H:199
__host__ __device__ void flip(int i) noexcept
Change from CELL to NODE or NODE to CELL in direction dir.
Definition AMReX_IndexType.H:91
__host__ static __device__ constexpr std::size_t size() noexcept
Return the size of this IndexTypeND.
Definition AMReX_IndexType.H:168
__host__ __device__ IntVectND< dim > toIntVect() const noexcept
Fill an IntVectND of size dim with IndexTypeNDs.
Definition AMReX_IndexType.H:136
__host__ static __device__ constexpr int isize() noexcept
Return the size of this IndexTypeND.
Definition AMReX_IndexType.H:174
__host__ __device__ IntVectND< dim > ixType() const noexcept
Fill an IntVectND of size dim with IndexTypeNDs.
Definition AMReX_IndexType.H:127
__host__ __device__ constexpr CellIndex get() const noexcept
Returns the i'th CellIndex of the IndexTypeND. Used by structured bindings.
Definition AMReX_IndexType.H:124
__host__ __device__ constexpr const unsigned int & getBits() const noexcept
Return the bit field representing the underlying data.
Definition AMReX_IndexType.H:229
__host__ __device__ void setType(int dir, CellIndex t) noexcept
Set IndexTypeND to CellIndex type t in direction dir.
Definition AMReX_IndexType.H:114
__host__ __device__ bool any() const noexcept
True if this IndexTypeND is NODE based in any direction.
Definition AMReX_IndexType.H:85
__host__ __device__ constexpr void setall() noexcept
Set NODE based in all directions.
Definition AMReX_IndexType.H:79
__host__ __device__ constexpr unsigned int & getBits() noexcept
Return the bit field representing the underlying data.
Definition AMReX_IndexType.H:225
__host__ __device__ bool ok() const noexcept
True if IndexTypeND is valid.
Definition AMReX_IndexType.H:88
__host__ __device__ bool cellCentered(int dir) const noexcept
True if the IndexTypeND is CELL based in dir-direction.
Definition AMReX_IndexType.H:105
__host__ __device__ 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:186
__host__ __device__ bool nodeCentered(int dir) const noexcept
True if the IndexTypeND is NODE based in dir-direction.
Definition AMReX_IndexType.H:111
__host__ __device__ void set(int dir) noexcept
Set IndexTypeND to be NODE based in direction dir.
Definition AMReX_IndexType.H:70
__host__ __device__ int operator[](int dir) const noexcept
Return an integer representing the IndexTypeND in direction dir.
Definition AMReX_IndexType.H:120
__host__ static __device__ constexpr IndexTypeND< dim > TheCellType() noexcept
This static member function returns an IndexTypeND object of value IndexTypeND::CELL....
Definition AMReX_IndexType.H:150
__host__ __device__ bool nodeCentered() const noexcept
True if the IndexTypeND is NODE based in all directions.
Definition AMReX_IndexType.H:108
__host__ __device__ 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:215
__host__ __device__ bool operator!=(const IndexTypeND &t) const noexcept
True if IndexTypeNDs are not identical.
Definition AMReX_IndexType.H:97
__host__ __device__ bool operator<(const IndexTypeND &t) const noexcept
Definition AMReX_IndexType.H:99
__host__ __device__ constexpr IndexTypeND() noexcept=default
The default constructor.
__host__ __device__ void clear() noexcept
Set CELL based in all directions.
Definition AMReX_IndexType.H:82
__host__ __device__ void unset(int dir) noexcept
Set IndexTypeND to be CELL based in direction dir.
Definition AMReX_IndexType.H:73
__host__ static __device__ constexpr IndexTypeND< dim > TheNodeType() noexcept
This static member function returns an IndexTypeND object of value IndexTypeND::NODE....
Definition AMReX_IndexType.H:160
An Integer Vector in dim-Dimensional Space.
Definition AMReX_IntVect.H:149
Definition AMReX_Amr.cpp:50
std::ostream & operator<<(std::ostream &os, AmrMesh const &amr_mesh)
Stream helper; forwards to the friend declared inside AmrMesh.
Definition AMReX_AmrMesh.cpp:1306
constexpr bool IsConvertible_v
Definition AMReX_TypeTraits.H:256
IndexTypeND< 3 > IndexType
IndexType is an alias for amrex::IndexTypeND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:36
__host__ __device__ constexpr 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:293
__host__ __device__ constexpr 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:327
__host__ __device__ constexpr 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:350
__host__ __device__ constexpr 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 fill_extra to the re...
Definition AMReX_IndexType.H:338
std::istream & operator>>(std::istream &is, BoxND< dim > &bx)
Read from istream.
Definition AMReX_Box.H:1834
__host__ __device__ constexpr 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:313
Type for defining CellIndex so that all IndexTypeND with different dimensions have the same CellIndex...
Definition AMReX_IndexType.H:19
CellIndex
The cell index type: one of CELL or NODE.
Definition AMReX_IndexType.H:21
@ CELL
Definition AMReX_IndexType.H:21
@ NODE
Definition AMReX_IndexType.H:21
typename amrex::IndexTypeND< dim >::CellIndex type
Definition AMReX_IndexType.H:366