OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
grid_smb.hpp
1//
2// Created by tommaso on 17/06/19.
3//
4
5#ifndef OPENFPM_PDATA_BLOCKGEOMETRY_HPP
6#define OPENFPM_PDATA_BLOCKGEOMETRY_HPP
7
8#include <boost/mpl/size_t.hpp>
9#include <cstring>
10#include <Grid/grid_sm.hpp>
11#include "SparseGridGpu/TemplateUtils/mathUtils.hpp"
12
18template<unsigned int dim, unsigned int blockEdgeSize, typename indexT = long int>
20{
21private:
22
25
26 indexT blockSz[dim];
27 indexT sz[dim];
28
29protected:
30
31 constexpr static indexT blockSize = IntPow<blockEdgeSize, dim>::value;
32
33public:
34
35 grid_smb() {}
36
42 inline Box<dim,size_t> getBox() const
43 {
44 return box;
45 }
46
47 __host__ __device__ grid_smb(const size_t (& sz)[dim])
48 {
49 for (int d=0; d<dim; ++d)
50 {
51 this->sz[d] = sz[d];
52 blockSz[d] = sz[d] / blockEdgeSize + ((sz[d] % blockEdgeSize) != 0);
53
54 box.setHigh(d,sz[d]);
55 box.setLow(d,0);
56 }
57 }
58
59 __host__ __device__ grid_smb(const indexT (& sz)[dim])
60 {
61 for (int d=0; d<dim; ++d)
62 {
63 this->sz[d] = sz[d];
64 blockSz[d] = sz[d] / blockEdgeSize + ((sz[d] % blockEdgeSize) != 0);
65
66 box.setHigh(d,sz[d]);
67 box.setLow(d,0);
68 }
69 }
70
71 __host__ __device__ grid_smb(const size_t domainBlockEdgeSize)
72 {
73 for (int i = 0; i < dim; ++i)
74 {
75 blockSz[i] = (indexT)domainBlockEdgeSize;
76 sz[i] = (indexT)domainBlockEdgeSize * blockEdgeSize;
77
78 box.setHigh(i,domainBlockEdgeSize);
79 box.setLow(i,0);
80 }
81 }
82
83 template<typename T>
84 __host__ __device__ grid_smb(const grid_sm<dim, T> blockGrid)
85 {
86 for (int i = 0; i < dim; ++i)
87 {
88 blockSz[i] = blockGrid.size(i);
89 sz[i] = blockGrid.size(i) * blockEdgeSize;
90
91 box.setHigh(i,sz[i]);
92 box.setLow(i,0);
93 }
94 }
95
96 static bool noPointers() {return true;}
97
98#ifdef __NVCC__
99 //Constructors from dim3 and uint3 objects
100 __host__ __device__ grid_smb(const dim3 blockDimensions)
101 {
102 unsigned int i = 0;
103 assert(dim <= 3);
104 blockSz[i] = blockDimensions.x;
105 sz[i] = blockSz[i] * blockEdgeSize;
106
107 box.setHigh(i,sz[i]);
108 box.setLow(i,0);
109
110 if (dim > 1)
111 {
112 ++i;
113 blockSz[i] = blockDimensions.y;
114 sz[i] = blockSz[i] * blockEdgeSize;
115
116 box.setHigh(i,sz[i]);
117 box.setLow(i,0);
118
119 if (dim > 2)
120 {
121 ++i;
122 blockSz[i] = blockDimensions.z;
123 sz[i] = blockSz[i] * blockEdgeSize;
124
125 box.setHigh(i,sz[i]);
126 box.setLow(i,0);
127 }
128 }
129 }
130
131
132#endif // __NVCC__
133
134 __host__ __device__ grid_smb(const grid_smb<dim, blockEdgeSize> &other)
135 {
136 for (indexT i = 0 ; i < dim ; i++)
137 {
138 blockSz[i] = other.blockSz[i];
139 sz[i] = other.sz[i];
140 }
141 }
142
143 __host__ __device__ grid_smb &operator=(const grid_smb<dim, blockEdgeSize> &other)
144 {
145 for (indexT i = 0 ; i < dim ; i++)
146 {
147 blockSz[i] = other.blockSz[i];
148 sz[i] = other.sz[i];
149 }
150 return *this;
151 }
152
153 __host__ __device__ const indexT (& getSize() const)[dim]
154 {
155 return sz;
156 }
157
158 __host__ __device__ const indexT & size(int i) const
159 {
160 return sz[i];
161 }
162
175 template<typename indexT_>
176 inline __host__ __device__ indexT LinId(const grid_key_dx<dim, indexT_> coord) const
177 {
178 //todo: Check (in debug mode only) that the coordinates passed here are valid and not overflowing dimensions (???)
179 indexT blockLinId = coord.get(dim - 1) / blockEdgeSize;
180 indexT localLinId = coord.get(dim - 1) % blockEdgeSize;
181 for (int d = dim - 2; d >= 0; --d)
182 {
183 blockLinId *= blockSz[d];
184 localLinId *= blockEdgeSize;
185 blockLinId += coord.get(d) / blockEdgeSize;
186 localLinId += coord.get(d) % blockEdgeSize;
187 }
188 return blockLinId * blockSize + localLinId;
189 }
190
203 template<typename indexT_>
204 inline __host__ __device__ void LinId(const grid_key_dx<dim, indexT_> coord, indexT & blockLinId, int & localLinId) const
205 {
206 //todo: Check (in debug mode only) that the coordinates passed here are valid and not overflowing dimensions (???)
207 blockLinId = coord.get(dim - 1) / blockEdgeSize;
208 localLinId = coord.get(dim - 1) % blockEdgeSize;
209 for (int d = dim - 2; d >= 0; --d)
210 {
211 blockLinId *= blockSz[d];
212 localLinId *= blockEdgeSize;
213 blockLinId += coord.get(d) / blockEdgeSize;
214 localLinId += coord.get(d) % blockEdgeSize;
215 }
216 }
217
218 inline __host__ __device__ grid_key_dx<dim, int> InvLinId(const indexT linId) const
219 {
220 indexT blockLinId = linId / blockSize;
221 indexT localLinId = linId % blockSize;
222 return InvLinId(blockLinId, localLinId);
223 }
224
232 inline __host__ __device__ grid_key_dx<dim, int> LocalInvLinId(unsigned int localLinId) const
233 {
235 for (int d = 0; d < dim; ++d)
236 {
237 auto c = localLinId % blockEdgeSize;
238 coord.set_d(d, c);
239 localLinId /= blockEdgeSize;
240 }
241 return coord;
242 }
243
263 inline __host__ __device__ grid_key_dx<dim, int> InvLinId(indexT blockLinId, indexT localLinId) const
264 {
266 for (int d = 0; d < dim; ++d)
267 {
268 auto c = blockLinId % blockSz[d];
269 c *= blockEdgeSize;
270 c += localLinId % blockEdgeSize;
271 coord.set_d(d, c);
272 blockLinId /= blockSz[d];
273 localLinId /= blockEdgeSize;
274 }
275 return coord;
276 }
277
278 // Now methods to handle blockGrid coordinates (e.g. to load neighbouring blocks)
279 template<typename indexT_>
280 inline __host__ __device__ indexT BlockLinId(const grid_key_dx<dim, indexT_> & blockCoord) const
281 {
282 indexT blockLinId = blockCoord.get(dim - 1);
283 if (blockLinId >= blockSz[dim-1])
284 {return -1;}
285
286 for (int d = dim - 2; d >= 0; --d)
287 {
288 blockLinId *= blockSz[d];
289 indexT cur = blockCoord.get(d);
290 if (cur >= blockSz[d])
291 {
292 return -1;
293 }
294 blockLinId += cur;
295 }
296 return blockLinId;
297 }
298
299 // Now methods to handle blockGrid coordinates (e.g. to load neighbouring blocks)
300 template<typename indexT_>
301 inline __host__ __device__ grid_key_dx<dim,indexT> getGlobalCoord(const grid_key_dx<dim, indexT_> & blockCoord, unsigned int offset) const
302 {
304
305 for (unsigned int i = 0 ; i < dim ; i++)
306 {
307 k.set_d(i,blockCoord.get(i)*blockEdgeSize + offset%blockEdgeSize);
308 offset /= blockEdgeSize;
309 }
310 return k;
311 }
312
313 inline __host__ __device__ grid_key_dx<dim, int> BlockInvLinId(indexT blockLinId) const
314 {
315 grid_key_dx<dim, int> blockCoord;
316 for (int d = 0; d < dim; ++d)
317 {
318 auto c = blockLinId % blockSz[d];
319 blockCoord.set_d(d, c);
320 blockLinId /= blockSz[d];
321 }
322 return blockCoord;
323 }
324
325 inline indexT size_blocks() const
326 {
327 indexT sz = 1;
328
329 for (indexT i = 0 ; i < dim ; i++)
330 {sz *= blockSz[i];}
331
332 return sz;
333 }
334
335 inline indexT size() const
336 {
337 indexT sz = 1;
338
339 for (indexT i = 0 ; i < dim ; i++)
340 {sz *= this->sz[i];}
341
342 return sz;
343 }
344
345 __host__ __device__ inline indexT getBlockEgdeSize() const
346 {
347 return blockEdgeSize;
348 }
349
350 __host__ __device__ inline indexT getBlockSize() const
351 {
352 return blockSize;
353 }
354
355 __host__ __device__ inline void swap(grid_smb<dim, blockEdgeSize, indexT> &other)
356 {
357 indexT blockSz_tmp[dim];
358 indexT sz_tmp[dim];
359
360 for (indexT i = 0 ; i < dim ; i++)
361 {
362 blockSz_tmp[i] = blockSz[i];
363 blockSz[i] = other.blockSz[i];
364 other.blockSz[i] = blockSz_tmp[i];
365
366 sz_tmp[i] = sz[i];
367 sz[i] = other.sz[i];
368 other.sz[i] = sz_tmp[i];
369 }
370 }
371};
372
373#endif //OPENFPM_PDATA_BLOCKGEOMETRY_HPP
This class represent an N-dimensional box.
Definition Box.hpp:61
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition Box.hpp:544
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition Box.hpp:533
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition grid_key.hpp:516
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition grid_key.hpp:503
Declaration grid_sm.
Definition grid_sm.hpp:167
__device__ __host__ size_t size() const
Return the size of the grid.
Definition grid_sm.hpp:657
__host__ __device__ indexT LinId(const grid_key_dx< dim, indexT_ > coord) const
Linearize the coordinate index.
Definition grid_smb.hpp:176
Box< dim, size_t > getBox() const
Return the box enclosing the grid.
Definition grid_smb.hpp:42
Box< dim, size_t > box
Box enclosing the grid.
Definition grid_smb.hpp:24
__host__ __device__ grid_key_dx< dim, int > LocalInvLinId(unsigned int localLinId) const
Definition grid_smb.hpp:232
__host__ __device__ void LinId(const grid_key_dx< dim, indexT_ > coord, indexT &blockLinId, int &localLinId) const
Linearize the coordinate index.
Definition grid_smb.hpp:204
__host__ __device__ grid_key_dx< dim, int > InvLinId(indexT blockLinId, indexT localLinId) const
Invert from the linearized block id + local id to the position of the point in coordinates.
Definition grid_smb.hpp:263