Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_Array4.H
Go to the documentation of this file.
1#ifndef AMREX_ARRAY4_H_
2#define AMREX_ARRAY4_H_
3#include <AMReX_Config.H>
4
5#include <AMReX.H>
6#include <AMReX_IntVect.H>
7#include <AMReX_GpuPrint.H>
8
9#include <iostream>
10#include <sstream>
11
12namespace amrex {
13
14 template <typename T>
15 struct CellData // Data in a single cell
16 {
17 T* AMREX_RESTRICT p = nullptr;
18 Long stride = 0;
19 int ncomp = 0;
20
22 constexpr CellData (T* a_p, Long a_stride, int a_ncomp)
23 : p(a_p), stride(a_stride), ncomp(a_ncomp)
24 {}
25
26 template <class U=T,
27 std::enable_if_t<std::is_const_v<U>,int> = 0>
29 constexpr CellData (CellData<std::remove_const_t<T>> const& rhs) noexcept
30 : p(rhs.p), stride(rhs.stride), ncomp(rhs.ncomp)
31 {}
32
34 explicit operator bool() const noexcept { return p != nullptr; }
35
36 [[nodiscard]] AMREX_GPU_HOST_DEVICE
37 int nComp() const noexcept { return ncomp; }
38
39 template <class U=T,
40 std::enable_if_t<!std::is_void_v<U>,int> = 0>
42 U& operator[] (int n) const noexcept {
43#if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
44 if (n < 0 || n >= ncomp) {
46 AMREX_DEVICE_PRINTF(" %d is out of bound (0:%d)", n, ncomp-1);
47 ))
49 std::stringstream ss;
50 ss << " " << n << " is out of bound: (0:" << ncomp-1 << ")";
51 amrex::Abort(ss.str());
52 ))
53 }
54#endif
55 return p[n*stride];
56 }
57 };
58
59 template <typename T>
60 struct Array4
61 {
63 Long jstride = 0;
64 Long kstride = 0;
65 Long nstride = 0;
66 Dim3 begin{1,1,1};
67 Dim3 end{0,0,0}; // end is hi + 1
68 int ncomp=0;
69
71 constexpr Array4 () noexcept : p(nullptr) {}
72
73 template <class U=T, std::enable_if_t<std::is_const_v<U>,int> = 0>
75 constexpr Array4 (Array4<std::remove_const_t<T>> const& rhs) noexcept
76 : p(rhs.p),
77 jstride(rhs.jstride),
78 kstride(rhs.kstride),
79 nstride(rhs.nstride),
80 begin(rhs.begin),
81 end(rhs.end),
82 ncomp(rhs.ncomp)
83 {}
84
86 constexpr Array4 (T* a_p, Dim3 const& a_begin, Dim3 const& a_end, int a_ncomp) noexcept
87 : p(a_p),
88 jstride(a_end.x-a_begin.x),
89 kstride(jstride*(a_end.y-a_begin.y)),
90 nstride(kstride*(a_end.z-a_begin.z)),
91 begin(a_begin),
92 end(a_end),
93 ncomp(a_ncomp)
94 {}
95
96 template <class U,
97 std::enable_if_t
98 <std::is_same_v<std::remove_const_t<T>,
99 std::remove_const_t<U>>,int> = 0>
101 constexpr Array4 (Array4<U> const& rhs, int start_comp) noexcept
102 : p((T*)(rhs.p+start_comp*rhs.nstride)),
103 jstride(rhs.jstride),
104 kstride(rhs.kstride),
105 nstride(rhs.nstride),
106 begin(rhs.begin),
107 end(rhs.end),
108 ncomp(rhs.ncomp-start_comp)
109 {}
110
111 template <class U,
112 std::enable_if_t
113 <std::is_same_v<std::remove_const_t<T>,
114 std::remove_const_t<U>>,int> = 0>
116 constexpr Array4 (Array4<U> const& rhs, int start_comp, int num_comps) noexcept
117 : p((T*)(rhs.p+start_comp*rhs.nstride)),
118 jstride(rhs.jstride),
119 kstride(rhs.kstride),
120 nstride(rhs.nstride),
121 begin(rhs.begin),
122 end(rhs.end),
123 ncomp(num_comps)
124 {}
125
127 explicit operator bool() const noexcept { return p != nullptr; }
128
129 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
131 U& operator() (int i, int j, int k) const noexcept {
132#if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
133 index_assert(i,j,k,0);
134#endif
135 return p[(i-begin.x)+(j-begin.y)*jstride+(k-begin.z)*kstride];
136 }
137
138 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
140 U& operator() (int i, int j, int k, int n) const noexcept {
141#if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
142 index_assert(i,j,k,n);
143#endif
144 return p[(i-begin.x)+(j-begin.y)*jstride+(k-begin.z)*kstride+n*nstride];
145 }
146
147 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
149 T* ptr (int i, int j, int k) const noexcept {
150#if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
151 index_assert(i,j,k,0);
152#endif
153 return p + ((i-begin.x)+(j-begin.y)*jstride+(k-begin.z)*kstride);
154 }
155
156 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
158 T* ptr (int i, int j, int k, int n) const noexcept {
159#if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
160 index_assert(i,j,k,0);
161#endif
162 return p + ((i-begin.x)+(j-begin.y)*jstride+(k-begin.z)*kstride+n*nstride);
163 }
164
165 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
167 U& operator() (IntVect const& iv) const noexcept {
168#if (AMREX_SPACEDIM == 1)
169 return this->operator()(iv[0],0,0);
170#elif (AMREX_SPACEDIM == 2)
171 return this->operator()(iv[0],iv[1],0);
172#else
173 return this->operator()(iv[0],iv[1],iv[2]);
174#endif
175 }
176
177 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
179 U& operator() (IntVect const& iv, int n) const noexcept {
180#if (AMREX_SPACEDIM == 1)
181 return this->operator()(iv[0],0,0,n);
182#elif (AMREX_SPACEDIM == 2)
183 return this->operator()(iv[0],iv[1],0,n);
184#else
185 return this->operator()(iv[0],iv[1],iv[2],n);
186#endif
187 }
188
189 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
191 T* ptr (IntVect const& iv) const noexcept {
192#if (AMREX_SPACEDIM == 1)
193 return this->ptr(iv[0],0,0);
194#elif (AMREX_SPACEDIM == 2)
195 return this->ptr(iv[0],iv[1],0);
196#else
197 return this->ptr(iv[0],iv[1],iv[2]);
198#endif
199 }
200
201 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
203 T* ptr (IntVect const& iv, int n) const noexcept {
204#if (AMREX_SPACEDIM == 1)
205 return this->ptr(iv[0],0,0,n);
206#elif (AMREX_SPACEDIM == 2)
207 return this->ptr(iv[0],iv[1],0,n);
208#else
209 return this->ptr(iv[0],iv[1],iv[2],n);
210#endif
211 }
212
213 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
215 U& operator() (Dim3 const& cell) const noexcept {
216 return this->operator()(cell.x,cell.y,cell.z);
217 }
218
219 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
221 U& operator() (Dim3 const& cell, int n) const noexcept {
222 return this->operator()(cell.x,cell.y,cell.z,n);
223 }
224
225 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
227 T* ptr (Dim3 const& cell) const noexcept {
228 return this->ptr(cell.x,cell.y,cell.z);
229 }
230
231 template <class U=T, std::enable_if_t<!std::is_void_v<U>,int> = 0>
233 T* ptr (Dim3 const& cell, int n) const noexcept {
234 return this->ptr(cell.x,cell.y,cell.z,n);
235 }
236
238 T* dataPtr () const noexcept {
239 return this->p;
240 }
241
243 std::size_t size () const noexcept {
244 return this->nstride * this->ncomp;
245 }
246
248 int nComp () const noexcept { return ncomp; }
249
251 bool contains (int i, int j, int k) const noexcept {
252 return (i>=begin.x && i<end.x && j>=begin.y && j<end.y && k>=begin.z && k<end.z);
253 }
254
256 bool contains (IntVect const& iv) const noexcept {
257 return AMREX_D_TERM( iv[0]>=begin.x && iv[0]<end.x,
258 && iv[1]>=begin.y && iv[1]<end.y,
259 && iv[2]>=begin.z && iv[2]<end.z);
260 }
261
263 bool contains (Dim3 const& cell) const noexcept {
264 return this->contains(cell.x,cell.y,cell.z);
265 }
266
267#if defined(AMREX_DEBUG) || defined(AMREX_BOUND_CHECK)
269 void index_assert (int i, int j, int k, int n) const
270 {
271 if (i<begin.x || i>=end.x || j<begin.y || j>=end.y || k<begin.z || k>=end.z
272 || n < 0 || n >= ncomp) {
274 AMREX_DEVICE_PRINTF(" (%d,%d,%d,%d) is out of bound (%d:%d,%d:%d,%d:%d,0:%d)\n",
275 i, j, k, n, begin.x, end.x-1, begin.y, end.y-1,
276 begin.z, end.z-1, ncomp-1);
277 amrex::Abort();
278 ))
280 std::stringstream ss;
281 ss << " (" << i << "," << j << "," << k << "," << n
282 << ") is out of bound ("
283 << begin.x << ":" << end.x-1 << ","
284 << begin.y << ":" << end.y-1 << ","
285 << begin.z << ":" << end.z-1 << ","
286 << "0:" << ncomp-1 << ")";
287 amrex::Abort(ss.str());
288 ))
289 }
290 }
291#endif
292
294 CellData<T> cellData (int i, int j, int k) const noexcept {
295 return CellData<T>{this->ptr(i,j,k), nstride, ncomp};
296 }
297 };
298
299 template <class Tto, class Tfrom>
300 [[nodiscard]] AMREX_GPU_HOST_DEVICE
301 Array4<Tto> ToArray4 (Array4<Tfrom> const& a_in) noexcept
302 {
303 return Array4<Tto>((Tto*)(a_in.p), a_in.begin, a_in.end, a_in.ncomp);
304 }
305
306 template <class T>
308 Dim3 lbound (Array4<T> const& a) noexcept
309 {
310 return a.begin;
311 }
312
313 template <class T>
315 Dim3 ubound (Array4<T> const& a) noexcept
316 {
317 return Dim3{a.end.x-1,a.end.y-1,a.end.z-1};
318 }
319
320 template <class T>
322 Dim3 length (Array4<T> const& a) noexcept
323 {
324 return Dim3{a.end.x-a.begin.x,a.end.y-a.begin.y,a.end.z-a.begin.z};
325 }
326
327 template <typename T>
328 std::ostream& operator<< (std::ostream& os, const Array4<T>& a) {
329 os << "((" << lbound(a) << ',' << ubound(a) << ")," << a.ncomp << ')';
330 return os;
331 }
332
333 //
334 // Type traits for detecting if a class has a size() constexpr function.
335 //
336 template <class A, class Enable = void> struct HasMultiComp : std::false_type {};
337 //
338 template <class B>
339 struct HasMultiComp<B, std::enable_if_t<B().size() >= 1>>
340 : std::true_type {};
341
342 //
343 // PolymorphicArray4 can be used to access both AoS and SoA with
344 // (i,j,k,n). Here SoA refers multi-component BaseFab, and AoS refers
345 // to single-component BaseFab of multi-component GpuArray.
346 //
347 template <typename T>
349 : public Array4<T>
350 {
353 : Array4<T>{a} {}
354
356 T& operator() (int i, int j, int k) const noexcept {
357 return this->Array4<T>::operator()(i,j,k);
358 }
359
360 template <class U=T, std::enable_if_t< amrex::HasMultiComp<U>::value,int> = 0>
362 typename U::reference_type
363 operator() (int i, int j, int k, int n) const noexcept {
364 return this->Array4<T>::operator()(i,j,k,0)[n];
365 }
366
367 template <class U=T, std::enable_if_t<!amrex::HasMultiComp<U>::value,int> = 0>
369 U& operator() (int i, int j, int k, int n) const noexcept {
370 return this->Array4<T>::operator()(i,j,k,n);
371 }
372 };
373
374 template <typename T>
375 [[nodiscard]] PolymorphicArray4<T>
377 {
378 return PolymorphicArray4<T>(a);
379 }
380}
381
382#endif
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_RESTRICT
Definition AMReX_Extension.H:37
#define AMREX_DEVICE_PRINTF(...)
Definition AMReX_GpuPrint.H:21
#define AMREX_IF_ON_DEVICE(CODE)
Definition AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition AMReX_GpuQualifiers.H:58
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:129
Definition AMReX_Amr.cpp:49
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 ubound(Array4< T > const &a) noexcept
Definition AMReX_Array4.H:315
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 lbound(Array4< T > const &a) noexcept
Definition AMReX_Array4.H:308
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 length(Array4< T > const &a) noexcept
Definition AMReX_Array4.H:322
PolymorphicArray4< T > makePolymorphic(Array4< T > const &a)
Definition AMReX_Array4.H:376
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
std::ostream & operator<<(std::ostream &os, AmrMesh const &amr_mesh)
Definition AMReX_AmrMesh.cpp:1236
AMREX_GPU_HOST_DEVICE Array4< Tto > ToArray4(Array4< Tfrom > const &a_in) noexcept
Definition AMReX_Array4.H:301
Definition AMReX_Array4.H:61
AMREX_GPU_HOST_DEVICE constexpr Array4(Array4< U > const &rhs, int start_comp) noexcept
Definition AMReX_Array4.H:101
AMREX_GPU_HOST_DEVICE constexpr Array4(T *a_p, Dim3 const &a_begin, Dim3 const &a_end, int a_ncomp) noexcept
Definition AMReX_Array4.H:86
Long kstride
Definition AMReX_Array4.H:64
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * dataPtr() const noexcept
Definition AMReX_Array4.H:238
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(IntVect const &iv) const noexcept
Definition AMReX_Array4.H:191
int ncomp
Definition AMReX_Array4.H:68
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE U & operator()(int i, int j, int k) const noexcept
Definition AMReX_Array4.H:131
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool contains(IntVect const &iv) const noexcept
Definition AMReX_Array4.H:256
AMREX_GPU_HOST_DEVICE constexpr Array4(Array4< std::remove_const_t< T > > const &rhs) noexcept
Definition AMReX_Array4.H:75
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(Dim3 const &cell, int n) const noexcept
Definition AMReX_Array4.H:233
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int nComp() const noexcept
Definition AMReX_Array4.H:248
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::size_t size() const noexcept
Definition AMReX_Array4.H:243
Dim3 begin
Definition AMReX_Array4.H:66
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE CellData< T > cellData(int i, int j, int k) const noexcept
Definition AMReX_Array4.H:294
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(Dim3 const &cell) const noexcept
Definition AMReX_Array4.H:227
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool contains(Dim3 const &cell) const noexcept
Definition AMReX_Array4.H:263
AMREX_GPU_HOST_DEVICE constexpr Array4(Array4< U > const &rhs, int start_comp, int num_comps) noexcept
Definition AMReX_Array4.H:116
Long jstride
Definition AMReX_Array4.H:63
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(IntVect const &iv, int n) const noexcept
Definition AMReX_Array4.H:203
AMREX_GPU_HOST_DEVICE constexpr Array4() noexcept
Definition AMReX_Array4.H:71
Dim3 end
Definition AMReX_Array4.H:67
Long nstride
Definition AMReX_Array4.H:65
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(int i, int j, int k, int n) const noexcept
Definition AMReX_Array4.H:158
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T * ptr(int i, int j, int k) const noexcept
Definition AMReX_Array4.H:149
T *AMREX_RESTRICT p
Definition AMReX_Array4.H:62
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool contains(int i, int j, int k) const noexcept
Definition AMReX_Array4.H:251
Definition AMReX_Array4.H:16
int ncomp
Definition AMReX_Array4.H:19
Long stride
Definition AMReX_Array4.H:18
AMREX_GPU_HOST_DEVICE constexpr CellData(CellData< std::remove_const_t< T > > const &rhs) noexcept
Definition AMReX_Array4.H:29
AMREX_GPU_HOST_DEVICE int nComp() const noexcept
Definition AMReX_Array4.H:37
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE U & operator[](int n) const noexcept
Definition AMReX_Array4.H:42
T *AMREX_RESTRICT p
Definition AMReX_Array4.H:17
AMREX_GPU_HOST_DEVICE constexpr CellData(T *a_p, Long a_stride, int a_ncomp)
Definition AMReX_Array4.H:22
Definition AMReX_Dim3.H:12
int x
Definition AMReX_Dim3.H:12
int z
Definition AMReX_Dim3.H:12
int y
Definition AMReX_Dim3.H:12
Definition AMReX_Array4.H:336
Definition AMReX_Array4.H:350
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE PolymorphicArray4(Array4< T > const &a)
Definition AMReX_Array4.H:352