1/*
2 * grid_key_dx_iterator_hilbert.hpp
3 *
4 * Created on: Feb 24, 2016
5 * Author: yaroslav
6 */
7
8#ifndef OPENFPM_DATA_SRC_GRID_GRID_KEY_DX_ITERATOR_HILBERT_HPP_
9#define OPENFPM_DATA_SRC_GRID_GRID_KEY_DX_ITERATOR_HILBERT_HPP_
10
11extern "C"
12{
13#include "hilbertKey.h"
14}
15
16
17/*
18 *
19 * Grid key class iterator, iterate through the grid elements following an
20 * hilbert space filling curve
21 *
22 * \param dim dimensionality of the grid
23 *
24 * ### Grid iterator declaration and usage
25 * \snippet grid_unit_tests.hpp Grid iterator test usage
26 *
27 */
28
29template<unsigned int dim>
30class grid_key_dx_iterator_hilbert
31{
32#ifdef SE_CLASS1
33 //! Actual status of the iterator, when the iterator is not initialized cannot be used
34 //! and reinitialize must be called
35 bool initialized = false;
36#endif
37
38 //! Actual position
39 uint64_t hkey = 0;
40
41 //! Order of a hilbert curve
42 size_t m;
43
44 //! Size of the hilbert grid in each dimension
45 grid_sm<dim,void> grid_base;
46
47protected:
48
49 //! Actual position in the grid
50 grid_key_dx<dim> gk;
51
52public:
53
54 /*! \brief Constructor
55 *
56 * m is the order of the hilber curve m=2 produce an hilber curve
57 * passing 2^(2) point in each direction so 4x4 points in 2D 4x4x4 in 3D
58 *
59 * \param m order of the hilber curve
60 *
61 */
62 grid_key_dx_iterator_hilbert(int32_t m)
63 :m(m)
64 {
65 // create from m the correct grid_sm
66
67 size_t dims[dim];
68
69 //Set the 2^m value to the each elements of dims[]
70 for (size_t i = 0 ; i < dim ; i++)
71 dims[i] = 1 << m;
72
73 //Set grid_sm dimensions
74 grid_base.setDimensions(dims);
75
76 reset();
77
78#ifdef SE_CLASS1
79 initialized = true;
80#endif
81 }
82
83 /*! \brief Get the next element
84 *
85 * \return the next grid_key
86 *
87 */
88
89 grid_key_dx_iterator_hilbert<dim> & operator++()
90 {
91 //An integer to handle errors
92 int err;
93
94 hkey++;
95
96 //Array to handle output
97 uint64_t nextCoord[dim];
98
99 //Get the coordinates of the next cell
100 getIntCoordFromHKey(nextCoord, m, dim, hkey, &err);
101
102 //Set the new coordinates
103 for (size_t i = 0; i < dim; i++)
104 gk.set_d(i, nextCoord[i]);
105
106 return *this;
107 }
108
109 /*! \brief Check if there is the next element
110 *
111 * Check if there is the next element
112 *
113 * \return true if there is the next, false otherwise
114 *
115 */
116
117 bool isNext()
118 {
119 if ( hkey < (size_t)1 << (m*dim))
120 {
121 //! we did not reach the end of the grid
122
123 return true;
124 }
125
126 //! we reach the end of the grid
127 return false;
128 }
129
130 /*! \brief Get the actual key
131 *
132 * Get the actual key
133 *
134 * \return the actual key
135 *
136 */
137 const grid_key_dx<dim> & get()
138 {
139 return gk;
140 }
141
142
143 /*! \brief Reset the iterator (it restart from the beginning)
144 *
145 */
146 void reset()
147 {
148 //! Initialize to 0 the index
149 for (size_t i = 0 ; i < dim ; i++)
150 gk.set_d(i,0);
151 }
152};
153
154
155#endif /* OPENFPM_DATA_SRC_GRID_GRID_KEY_DX_ITERATOR_HILBERT_HPP_ */
156