1#ifndef GRID_KEY_DX
2#define GRID_KEY_DX
3
4#include "Grid/comb.hpp"
5#include "Grid/grid_key_expression.hpp"
6#include "Space/Shape/Point.hpp"
7
8/*! \brief grid_key_dx is the key to access any element in the grid
9 *
10 * Given a grid in general a set of indexes define one element in the grid
11 * For example 2 indexes identify one element on a two dimensional grid,
12 * 3 indexes on a 3 dimensional grid ...
13 *
14 * \tparam dim dimensionality of the grid
15 *
16 */
17template<unsigned int dim, typename index_type>
18class grid_key_dx
19{
20public:
21
22 /*! \brief Constructor from expression
23 *
24 * \param exp grid_key_dx expression
25 *
26 */
27 template<typename exp1>
28 __device__ __host__ inline grid_key_dx(const grid_key_dx_expression<dim,exp1> & exp)
29 {
30 for (size_t i = 0 ; i < dim ; i++)
31 this->k[i] = exp.value(i);
32 }
33
34 //! Constructor
35 __device__ __host__ inline grid_key_dx()
36 {}
37
38 /*! \brief Constructor from initializer list
39 *
40 * \param p1 initializer list
41 *
42 */
43 __device__ __host__ inline grid_key_dx(std::initializer_list<long int> p1)
44 {
45 size_t i = 0;
46 for(long int x : p1)
47 {
48 set_d(i,x);
49 i++;
50 if (i >= dim)
51 break;
52 }
53 }
54
55 /*! \brief Constructor from an other key
56 *
57 * \param key copy constructor
58 *
59 */
60 __device__ __host__ inline grid_key_dx(const grid_key_dx<dim,index_type> & key)
61 :grid_key_dx(key.k)
62 {
63 }
64
65 /*! \brief Constructor from buffer reference
66 *
67 * \param k reference buffer
68 *
69 */
70 __device__ __host__ inline grid_key_dx(const size_t (&k)[dim])
71 {
72 for (size_t i = 0 ; i < dim ; i++)
73 this->k[i] = k[i];
74 }
75
76 /*! \brief Constructor from buffer reference
77 *
78 * \param k reference buffer
79 *
80 */
81 __device__ __host__ inline grid_key_dx(const long int (&k)[dim])
82 {
83 for (size_t i = 0 ; i < dim ; i++)
84 {this->k[i] = k[i];}
85 }
86
87 /*! \brief Constructor from buffer reference
88 *
89 * \param k reference buffer
90 *
91 */
92 __device__ __host__ inline grid_key_dx(const short (&k)[dim])
93 {
94 for (size_t i = 0 ; i < dim ; i++)
95 {this->k[i] = k[i];}
96 }
97
98 /*! \brief Constructor from buffer reference
99 *
100 * \param k reference buffer
101 *
102 */
103 __device__ __host__ inline grid_key_dx(const unsigned short (&k)[dim])
104 {
105 for (size_t i = 0 ; i < dim ; i++)
106 {this->k[i] = k[i];}
107 }
108
109 /*! \brief Constructor from buffer reference
110 *
111 * \param k reference buffer
112 *
113 */
114 __device__ __host__ inline grid_key_dx(const int (&k)[dim])
115 {
116 for (size_t i = 0 ; i < dim ; i++)
117 {this->k[i] = k[i];}
118 }
119
120 /*! \brief Constructor from buffer reference
121 *
122 * \param k reference buffer
123 *
124 */
125 __device__ __host__ inline grid_key_dx(const unsigned int (&k)[dim])
126 {
127 for (size_t i = 0 ; i < dim ; i++)
128 {this->k[i] = k[i];}
129 }
130
131 /*! \brief Construct a grid key from a list of numbers
132 *
133 * \param cmb combination
134 *
135 */
136 template<typename ...T> inline grid_key_dx(const comb<dim> & cmb)
137 {
138 for (size_t i = 0 ; i < dim ; i++)
139 k[i] = cmb[i];
140 }
141
142 /*! \brief Construct a grid key from a list of numbers
143 *
144 * \param v number
145 * \param t the other numbers
146 *
147 */
148 template<typename ...T> __device__ __host__ inline grid_key_dx(const size_t v,const T...t)
149 {
150#if defined(SE_CLASS1) && !defined(__NVCC__)
151 if (sizeof...(t) != dim -1)
152 {std::cerr << "Error grid_key: " << __FILE__ << " " << __LINE__ << " creating a key of dimension " << dim << " require " << dim << " numbers " << sizeof...(t) + 1 << " provided" << "\n";}
153#endif
154 k[dim-1] = v;
155 invert_assign(t...);
156 }
157
158 __device__ __host__ inline grid_key_dx<dim,index_type> move(int i, int m) const
159 {
160 grid_key_dx<dim,index_type> tmp = *this;
161
162 tmp.k[i] += m;
163
164 return tmp;
165 }
166
167 /*! \brief Set to zero the key
168 *
169 */
170 inline void zero()
171 {
172 for (size_t i = 0 ; i < dim ; i++)
173 k[i] = 0;
174 }
175
176 /*! \brief Set to one the key
177 *
178 */
179 inline void one()
180 {
181 for (size_t i = 0 ; i < dim ; i++)
182 k[i] = 1;
183 }
184
185 /*! \brief Set to invalid the key
186 *
187 */
188 inline void invalid()
189 {
190 for (size_t i = 0 ; i < dim ; i++)
191 k[i] = -1;
192 }
193
194 /*! \brief Check if the key is invalid (all components set to -1)
195 *
196 * \return true if it is valid
197 *
198 */
199 inline bool isValid()
200 {
201 for (size_t i = 0 ; i < dim ; i++)
202 {
203 if (k[i] != -1)
204 return true;
205 }
206
207 return false;
208 }
209
210 /*! \brief sum a grid_key
211 *
212 * \param p comb combination (or relative movement)
213 *
214 * \return a grid_key_dx_expression that encapsulate the expression
215 *
216 */
217 __device__ __host__
218 inline grid_key_dx<dim,index_type> & operator+=(const grid_key_dx<dim,index_type> & p)
219 {
220 for (size_t i = 0 ; i < dim ; i++)
221 k[i] += p.k[i];
222
223 return *this;
224 }
225
226 /*! \brief sum a grid_key
227 *
228 * \param p comb combination (or relative movement)
229 *
230 * \return a grid_key_dx_expression that encapsulate the expression
231 *
232 */
233 __device__ __host__
234 inline grid_key_dx<dim,index_type> & operator-=(const grid_key_dx<dim,index_type> & p)
235 {
236 for (size_t i = 0 ; i < dim ; i++)
237 k[i] -= p.k[i];
238
239 return *this;
240 }
241
242 /*! \brief sum a grid_key to the grid_key
243 *
244 * \param p grid_key to sum
245 *
246 * \return a grid_key_dx_expression that encapsulate the expression
247 *
248 */
249 __device__ __host__
250 inline grid_key_dx_sum<dim,grid_key_dx<dim,index_type>,grid_key_dx<dim,index_type>>
251 operator+(const grid_key_dx<dim,index_type> & p) const
252 {
253 grid_key_dx_sum<dim,grid_key_dx<dim,index_type>,grid_key_dx<dim,index_type>> exp_sum(*this,p);
254
255 return exp_sum;
256 }
257
258 /*! \brief sum a point to the grid_key
259 *
260 * \param p point (or relative movement)
261 *
262 * \return a grid_key_dx_expression that encapsulate the expression
263 *
264 */
265 __device__ __host__
266 inline grid_key_dx_sum<dim,grid_key_dx<dim>,Point<dim,long int>>
267 operator+(const Point<dim,long int> & p) const
268 {
269 grid_key_dx_sum<dim,grid_key_dx<dim>,Point<dim,long int>> exp_sum(*this,p);
270
271 return exp_sum;
272 }
273
274 /*! \brief sum an a combination to the grid_key
275 *
276 * \param cmb combination (or relative movement)
277 *
278 * \return a grid_key_dx_expression that encapsulate the expression
279 *
280 */
281 __device__ __host__
282 inline grid_key_dx_sum<dim,grid_key_dx<dim>,comb<dim>> operator+(const comb<dim> & cmb) const
283 {
284 grid_key_dx_sum<dim,grid_key_dx<dim>,comb<dim>> exp_sum(*this,cmb);
285
286 return exp_sum;
287 }
288
289 /*! \brief sum an a combination to the grid_key
290 *
291 * \param cmb combination (or relative movement)
292 *
293 * \return a grid_key_dx_expression that encapsulate the expression
294 *
295 */
296 __device__ __host__
297 inline grid_key_dx_sub<dim,grid_key_dx<dim,index_type>,grid_key_dx<dim,index_type>>
298 operator-(const grid_key_dx<dim,index_type> & cmb) const
299 {
300 grid_key_dx_sub<dim,grid_key_dx<dim,index_type>,grid_key_dx<dim,index_type>> exp_sum(*this,cmb);
301
302 return exp_sum;
303 }
304
305 /*! \brief sum this key to another grid expression
306 *
307 * \param cmb expression
308 *
309 * \return a grid_key_dx_expression that encapsulate the expression
310 *
311 */
312 template <typename T>
313 __device__ __host__ inline grid_key_dx_sub<dim,grid_key_dx<dim,index_type>,grid_key_dx_expression<dim,T>> operator-(const grid_key_dx_expression<dim,T> & cmb) const
314 {
315 grid_key_dx_sub<dim,grid_key_dx<dim,index_type>,grid_key_dx_expression<dim,T>> exp_sum(*this,cmb);
316
317 return exp_sum;
318 }
319
320 /*! \brief Check if two key are the same
321 *
322 * \param key_t key to check
323 *
324 * \return true if the two key are equal
325 *
326 */
327 template<unsigned int dim_t> bool operator==(const grid_key_dx<dim_t,index_type> & key_t) const
328 {
329 if (dim != dim_t)
330 {
331 return false;
332 }
333
334 // Check the two key index by index
335
336 for (size_t i = 0 ; i < dim ; i++)
337 {
338 if (k[i] != key_t.k[i])
339 {
340 return false;
341 }
342 }
343
344 // identical key
345 return true;
346 }
347
348
349 /*! \brief Check if two key are the same
350 *
351 * \param key_t key to check
352 *
353 * \return true if the two key are equal
354 *
355 */
356 template<unsigned int dim_t> bool operator!=(const grid_key_dx<dim_t,index_type> & key_t)
357 {
358 return !this->operator==(key_t);
359 }
360
361 /*! \brief Check order of two keys
362 *
363 * \param key_t key to check
364 *
365 * \return true if this is lexicographically less than other key
366 *
367 */
368 bool operator<(const grid_key_dx<dim,index_type> & key_t) const
369 {
370 // Check the two key index by index
371
372 for (long int i = dim-1 ; i >= 0; --i)
373 {
374 if (k[i] < key_t.k[i])
375 {
376 return true;
377 }
378 else if (k[i] > key_t.k[i])
379 {
380 return false;
381 }
382 }
383
384 // identical key
385 return false;
386 }
387
388 static bool noPointers()
389 {
390 return true;
391 }
392
393 /*! \brief set the Key from a list of numbers
394 *
395 * \param v list of number
396 * \param t list of number
397 *
398 */
399 template<typename a, typename ...T>
400 inline void set(a v, T...t)
401 {
402#ifdef SE_CLASS1
403 if (sizeof...(t) != dim -1)
404 std::cerr << "Error grid_key: " << __FILE__ << " " << __LINE__ << "setting a key of dimension " << dim << " require " << dim << " numbers " << sizeof...(t) + 1 << " provided" << std::endl;
405#endif
406 k[dim-1] = v;
407 invert_assign(t...);
408 }
409
410 /*! \brief Return the internal k structure
411 *
412 * \return k
413 *
414 */
415 const long int(& get_k() const)[dim]
416 {
417 return k;
418 }
419
420 /*! \brief Convert to a point the grid_key_dx
421 *
422 * \see toPoint
423 *
424 * \return a point long int
425 *
426 */
427 Point<dim,long int> toPointS() const
428 {
429 Point<dim,long int> p;
430
431 for (size_t i = 0; i < dim ; i++)
432 {
433 p.get(i) = get(i);
434 }
435
436 return p;
437 }
438
439 /*! \brief convert the information into a string
440 *
441 * \return a string
442 *
443 */
444 std::string to_string()
445 {
446 return this->toPointS().toString();
447 }
448
449 /*! \brief Convert to a point the grid_key_dx
450 *
451 * \see toPointS
452 *
453 * \return a point unsigned long int
454 *
455 */
456 template<typename typeT = size_t>
457 __host__ __device__ inline Point<dim,typeT> toPoint() const
458 {
459 Point<dim,typeT> p;
460
461 for (size_t i = 0; i < dim ; i++)
462 {
463 p.get(i) = get(i);
464 }
465
466 return p;
467 }
468
469
470 /*! \brief Get the i index
471 *
472 * \param i index to get
473 *
474 * \return the index value
475 *
476 */
477 __device__ __host__ inline mem_id value(size_t i) const
478 {
479 return k[i];
480 }
481
482 /*! \brief Get the i index
483 *
484 *
485 * \param i index to get
486 *
487 * \return the index value
488 *
489 */
490 __device__ __host__ index_type get(index_type i) const
491 {
492 return k[i];
493 }
494
495 /*! \brief Set the i index
496 *
497 * Set the i index
498 *
499 * \param i index to set
500 * \param id value to set
501 *
502 */
503 __device__ __host__ void set_d(index_type i, index_type id)
504 {
505#if defined(SE_CLASS1) && !defined(__NVCC__)
506
507 if (i >= dim)
508 std::cerr << "grid_key_dx error: " << __FILE__ << " " << __LINE__ << " try to access dimension " << i << " on a grid_key_dx of size " << dim << "\n";
509
510#endif
511 k[i] = id;
512 }
513
514private:
515
516 //! structure that store all the index
517 index_type k[dim];
518
519 /*! \brief Recursively invert the assignment
520 *
521 * Recursively invert the assignment at compile-time (hopefully)
522 *
523 * \param v list of numbers
524 * \param t list of numbers
525 *
526 */
527 template<typename a, typename ...T> __device__ __host__ void invert_assign(a v,T...t)
528 {
529 k[sizeof...(T)] = v;
530 invert_assign(t...);
531 }
532
533 /*! \brief assignment
534 *
535 * \param v list of number
536 *
537 */
538 template<typename a, typename ...T> __device__ __host__ void invert_assign(a v)
539 {
540 k[0] = v;
541 }
542
543 //! Constructor
544 __device__ __host__ void invert_assign()
545 {
546 }
547
548};
549
550
551/*! \brief grid_key_d is the key to access any element in the grid
552 *
553 * grid_key_d is the key to access any element in the grid
554 *
555 * \param dim dimensionality of the grid
556 * \param p object property to get from the element of the grid
557 *
558 */
559
560template<unsigned int dim, unsigned int p>
561class grid_key_d
562{
563public:
564
565
566 template<typename a, typename ...T>grid_key_d(a v,T...t)
567 {
568 k[dim-1] = v;
569 invert_assign(t...);
570 }
571
572 template<typename a, typename ...T>void invert_assign(a v,T...t)
573 {
574 k[sizeof...(T)] = v;
575 invert_assign(t...);
576 }
577
578 template<typename a, typename ...T>void invert_assign(a v)
579 {
580 k[0] = v;
581 }
582
583 mem_id k[dim];
584};
585
586
587#endif
588