1/*
2 * grid_dist_id_iterator_dec.hpp
3 *
4 * Created on: Jan 27, 2016
5 * Author: i-bird
6 */
7
8#ifndef SRC_GRID_GRID_DIST_ID_ITERATOR_DEC_HPP_
9#define SRC_GRID_GRID_DIST_ID_ITERATOR_DEC_HPP_
10
11#include "grid_dist_id_iterator.hpp"
12#include "Grid/grid_dist_util.hpp"
13#include "grid_dist_id_iterator_util.hpp"
14
15/*! \brief Given the decomposition it create an iterator
16 *
17 * Iterator across the local elements of the distributed grid
18 *
19 * \tparam dec Decomposition type
20 *
21 */
22template<typename Decomposition, bool ghost_or_domain = false>
23class grid_dist_id_iterator_dec
24{
25 //! grid list counter
26 size_t g_c;
27
28 //! Extension of each grid: domain and ghost + domain
29 openfpm::vector<GBoxes<Decomposition::dims>> gdb_ext;
30
31 //! Actual iterator
32 grid_key_dx_iterator_sub<Decomposition::dims> a_it;
33
34 //! start key
35 grid_key_dx<Decomposition::dims> start;
36
37 //! stop key
38 grid_key_dx<Decomposition::dims> stop;
39
40 //! Spacing
41 typename Decomposition::stype spacing[Decomposition::dims];
42
43 //! Domain
44 Box<Decomposition::dims,typename Decomposition::stype> domain;
45
46 /*! \brief from g_c increment g_c until you find a valid grid
47 *
48 */
49 void selectValidGrid()
50 {
51 // start and stop for the subset grid
52 grid_key_dx<Decomposition::dims> start_c;
53 grid_key_dx<Decomposition::dims> stop_c;
54
55 // When the grid has size 0 potentially all the other informations are garbage
56 while (g_c < gdb_ext.size() &&
57 (gdb_ext.get(g_c).Dbox.isValid() == false || compute_subset<Decomposition,ghost_or_domain>(gdb_ext,g_c,start,stop,start_c,stop_c) == false ))
58 {g_c++;}
59
60 // get the next grid iterator
61 if (g_c < gdb_ext.size())
62 {
63 // Calculate the resolution of the local grid
64 size_t sz[Decomposition::dims];
65 for (size_t i = 0 ; i < Decomposition::dims ; i++)
66 sz[i] = gdb_ext.get(g_c).GDbox.getP2()[i] + 1;
67
68 grid_sm<Decomposition::dims,void> g_sm(sz);
69 a_it.reinitialize(grid_key_dx_iterator_sub<Decomposition::dims>(g_sm,start_c,stop_c));
70 }
71 }
72
73 /*! \brief Get the actual key
74 *
75 * \return the actual key
76 *
77 */
78 inline grid_dist_key_dx<Decomposition::dims> get_int()
79 {
80 return grid_dist_key_dx<Decomposition::dims>(g_c,a_it.get());
81 }
82
83 public:
84
85 /*! \brief Copy operator=
86 *
87 * \param tmp iterator to copy
88 *
89 * \return itself
90 *
91 */
92 grid_dist_id_iterator_dec<Decomposition> & operator=(const grid_dist_id_iterator_dec<Decomposition> & tmp)
93 {
94 g_c = tmp.g_c;
95 gdb_ext = tmp.gdb_ext;
96 a_it.reinitialize(tmp.a_it);
97
98 start = tmp.start;
99 stop = tmp.stop;
100
101 domain = tmp.domain;
102
103 return *this;
104 }
105
106 /*! \brief Copy constructor
107 *
108 * \param tmp iterator to copy
109 *
110 */
111 grid_dist_id_iterator_dec(const grid_dist_id_iterator_dec<Decomposition> & tmp)
112 {
113 this->operator=(tmp);
114 }
115
116 /*! \brief Constructor of the distributed grid iterator
117 *
118 * \param dec Decomposition
119 * \param sz size of the grid
120 *
121 */
122 grid_dist_id_iterator_dec(Decomposition & dec, const size_t (& sz)[Decomposition::dims])
123 :g_c(0)
124 {
125 domain = dec.getDomain();
126
127 // Initialize start and stop
128 start.zero();
129 for (size_t i = 0 ; i < Decomposition::dims ; i++)
130 stop.set_d(i,sz[i]-1);
131
132 // From the decomposition construct gdb_ext
133 create_gdb_ext<Decomposition::dims,Decomposition>(gdb_ext,dec,sz,dec.getDomain(),spacing);
134
135 // Initialize the current iterator
136 // with the first grid
137 selectValidGrid();
138 }
139
140 /*! \brief Constructor of the distributed grid iterator
141 *
142 * \param dec Decomposition
143 * \param sz size of the grid
144 * \param start point
145 * \param stop point
146 *
147 */
148 grid_dist_id_iterator_dec(Decomposition & dec, const size_t (& sz)[Decomposition::dims], grid_key_dx<Decomposition::dims> start, grid_key_dx<Decomposition::dims> stop)
149 :g_c(0),start(start),stop(stop)
150 {
151 domain = dec.getDomain();
152
153 // From the decomposition construct gdb_ext
154 create_gdb_ext<Decomposition::dims,Decomposition>(gdb_ext,dec,sz,dec.getDomain(),spacing);
155
156 // Initialize the current iterator
157 // with the first grid
158 selectValidGrid();
159 }
160
161 // Destructor
162 ~grid_dist_id_iterator_dec()
163 {
164 }
165
166 /*! \brief Return true if we point to a valid grid
167 *
168 * \return true if valid grid
169 *
170 */
171 inline bool isNextGrid()
172 {
173 return g_c < gdb_ext.size();
174 }
175
176 /*! \brief Return the index of the grid in which we are iterating
177 *
178 *
179 */
180 inline size_t getGridId()
181 {
182 return g_c;
183 }
184
185 /*! \brief next grid
186 *
187 *
188 */
189 inline void nextGrid()
190 {
191 g_c++;
192 selectValidGrid();
193 }
194
195 /*! \brief Return the actual pointed grid
196 *
197 * \return the grid index
198 *
199 */
200 inline Box<Decomposition::dims,size_t> getGridBox()
201 {
202 Box<Decomposition::dims,size_t> bx;
203
204 auto start = a_it.getStart();
205 auto stop = a_it.getStop();
206
207 for (int i = 0 ; i < Decomposition::dims ; i++)
208 {
209 bx.setHigh(i,stop.get(i));
210 bx.setLow(i,start.get(i));
211 }
212
213 return bx;
214 }
215
216 /*! \brief Get the next element
217 *
218 * \return the next grid_key
219 *
220 */
221
222 inline grid_dist_id_iterator_dec<Decomposition,ghost_or_domain> & operator++()
223 {
224 ++a_it;
225
226 // check if a_it is at the end
227
228 if (a_it.isNext() == true)
229 {return *this;}
230 else
231 {
232 // switch to the new grid
233 g_c++;
234
235 selectValidGrid();
236 }
237
238 return *this;
239 }
240
241 /*! \brief Check if there is the next element
242 *
243 * \return true if there is the next, false otherwise
244 *
245 */
246 inline bool isNext()
247 {
248 // If there are no other grid stop
249
250 if (g_c >= gdb_ext.size())
251 return false;
252
253 return true;
254 }
255
256 /*! \brief Get the spacing of the grid
257 *
258 * \param i
259 *
260 */
261 inline typename Decomposition::stype getSpacing(size_t i)
262 {
263 return spacing[i];
264 }
265
266 /*! \brief Get the actual global key of the grid
267 *
268 *
269 * \return the global position in the grid
270 *
271 */
272 inline grid_key_dx<Decomposition::dims> get()
273 {
274 const grid_dist_key_dx<Decomposition::dims> k = get_int();
275
276 // Get the sub-domain id
277 size_t sub_id = k.getSub();
278
279 grid_key_dx<Decomposition::dims> k_glob = k.getKey();
280
281 // shift
282 k_glob = k_glob + gdb_ext.get(sub_id).origin;
283
284 return k_glob;
285 }
286
287 /*! \brief Return the point coordinates
288 *
289 * \return the point
290 *
291 */
292 inline Point<Decomposition::dims,typename Decomposition::stype> getPoint()
293 {
294 Point<Decomposition::dims,typename Decomposition::stype> p;
295 auto key = this->get();
296
297 for (int i = 0 ; i < Decomposition::dims ; i++)
298 {
299 p.get(i) = spacing[i] * key.get(i) + domain.getLow(i);
300 }
301
302 return p;
303 }
304
305 /*! \brief Get the actual grid key for a distributed grid
306 *
307 * \note if you are using this iterator and you need the position for grid_dist_id use this
308 * function to retrieve the grid point
309 *
310 * \return the grid point
311 *
312 */
313 inline grid_dist_key_dx<Decomposition::dims> get_dist()
314 {
315 return get_int();
316 }
317
318 /*! \brief Get the starting point of the sub-grid we are iterating
319 *
320 * \return the starting point
321 *
322 */
323 inline grid_key_dx<Decomposition::dims> getStart()
324 {
325 return start;
326 }
327
328 /*! \brief Get the starting point of the sub-grid we are iterating
329 *
330 * \return the stop point
331 *
332 */
333 inline grid_key_dx<Decomposition::dims> getStop()
334 {
335 return stop;
336 }
337};
338
339
340#endif /* SRC_GRID_GRID_DIST_ID_ITERATOR_DEC_HPP_ */
341