1 | /* |
2 | * grid_dist_id_iterator_sub.hpp |
3 | * |
4 | * Created on: Oct 14, 2015 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef SRC_GRID_GRID_DIST_ID_ITERATOR_SUB_HPP_ |
9 | #define SRC_GRID_GRID_DIST_ID_ITERATOR_SUB_HPP_ |
10 | |
11 | |
12 | /*! \brief Distributed grid iterator |
13 | * |
14 | * Iterator across the local elements of the distributed grid |
15 | * |
16 | * \tparam dim dimensionality of the grid |
17 | * \tparam device_grid type of basic grid |
18 | * \tparam impl implementation |
19 | * |
20 | */ |
21 | template<unsigned int dim, typename device_grid> |
22 | class grid_dist_iterator_sub |
23 | { |
24 | // sub_set of the grid where to iterate |
25 | struct sub_set |
26 | { |
27 | //! start point where iterate |
28 | grid_key_dx<dim> start; |
29 | //! stop point where iterate |
30 | grid_key_dx<dim> stop; |
31 | }; |
32 | |
33 | //! grid list counter |
34 | size_t g_c; |
35 | |
36 | //! List of the grids we are going to iterate |
37 | const openfpm::vector<device_grid> & gList; |
38 | |
39 | //! Extension of each grid: domain and ghost + domain |
40 | const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext; |
41 | |
42 | //! Actual iterator |
43 | decltype(device_grid::type_of_subiterator()) a_it; |
44 | |
45 | //! start key |
46 | grid_key_dx<dim> start; |
47 | |
48 | //! stop key |
49 | grid_key_dx<dim> stop; |
50 | |
51 | /*! \brief compute the subset where it has to iterate |
52 | * |
53 | * \param gc Actual grid |
54 | * \param start_c adjusted start point for the grid g_c |
55 | * \param stop_c adjusted stop point for the grid g_c |
56 | * |
57 | * \return false if the sub-set does not contain points |
58 | * |
59 | */ |
60 | bool compute_subset(size_t gc, grid_key_dx<dim> & start_c, grid_key_dx<dim> & stop_c) |
61 | { |
62 | // Intersect the grid keys |
63 | |
64 | for (size_t i = 0 ; i < dim ; i++) |
65 | { |
66 | long int start_p = gdb_ext.get(g_c).Dbox.getP1().get(i) + gdb_ext.get(g_c).origin.get(i); |
67 | long int stop_p = gdb_ext.get(g_c).Dbox.getP2().get(i) + gdb_ext.get(g_c).origin.get(i); |
68 | if (start.get(i) <= start_p) |
69 | start_c.set_d(i,gdb_ext.get(g_c).Dbox.getP1().get(i)); |
70 | else if (start.get(i) <= stop_p) |
71 | start_c.set_d(i,start.get(i) - gdb_ext.get(g_c).origin.get(i)); |
72 | else |
73 | return false; |
74 | |
75 | if (stop.get(i) >= stop_p) |
76 | stop_c.set_d(i,gdb_ext.get(g_c).Dbox.getP2().get(i)); |
77 | else if (stop.get(i) >= start_p) |
78 | stop_c.set_d(i,stop.get(i) - gdb_ext.get(g_c).origin.get(i)); |
79 | else |
80 | return false; |
81 | } |
82 | |
83 | return true; |
84 | } |
85 | |
86 | /*! \brief from g_c increment g_c until you find a valid grid |
87 | * |
88 | */ |
89 | void selectValidGrid() |
90 | { |
91 | // start and stop for the subset grid |
92 | grid_key_dx<dim> start_c; |
93 | grid_key_dx<dim> stop_c; |
94 | |
95 | do |
96 | { |
97 | // When the grid has size 0 potentially all the other informations are garbage |
98 | while (g_c < gList.size() && |
99 | (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false || compute_subset(g_c,start_c,stop_c) == false )) |
100 | {g_c++;} |
101 | |
102 | // get the next grid iterator |
103 | if (g_c < gList.size()) |
104 | { |
105 | a_it.reinitialize(gList.get(g_c).getIterator(start_c,stop_c)); |
106 | if (a_it.isNext() == false) {g_c++;} |
107 | } |
108 | } while (g_c < gList.size() && a_it.isNext() == false); |
109 | } |
110 | |
111 | public: |
112 | |
113 | /*! \brief Copy operator= |
114 | * |
115 | * \param tmp iterator to copy |
116 | * |
117 | */ |
118 | grid_dist_iterator_sub<dim,device_grid> & |
119 | operator=(const grid_dist_iterator_sub<dim,device_grid> & tmp) |
120 | { |
121 | g_c = tmp.g_c; |
122 | gList = tmp.gList; |
123 | gdb_ext = tmp.gdb_ext; |
124 | start = tmp.start; |
125 | stop = tmp.stop; |
126 | a_it.reinitialize(tmp.a_it); |
127 | |
128 | return *this; |
129 | } |
130 | |
131 | /*! \brief Copy constructor |
132 | * |
133 | * \param tmp iterator to copy |
134 | * |
135 | */ |
136 | grid_dist_iterator_sub(const grid_dist_iterator_sub<dim,device_grid> & tmp) |
137 | :g_c(tmp.g_c),gList(tmp.gList),gdb_ext(tmp.gdb_ext),start(tmp.start),stop(tmp.stop) |
138 | { |
139 | // get the next grid iterator |
140 | if (g_c < gList.size()) |
141 | { |
142 | a_it.reinitialize(tmp.a_it); |
143 | } |
144 | } |
145 | |
146 | /*! \brief Constructor of the distributed grid iterator |
147 | * |
148 | * \param start position |
149 | * \param stop position |
150 | * \param gk std::vector of the local grid |
151 | * \param gdb_ext information about the local grids |
152 | * |
153 | */ |
154 | grid_dist_iterator_sub(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop ,const openfpm::vector<device_grid> & gk, const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext) |
155 | :g_c(0),gList(gk),gdb_ext(gdb_ext),start(start),stop(stop) |
156 | { |
157 | // Initialize the current iterator |
158 | // with the first grid |
159 | selectValidGrid(); |
160 | } |
161 | |
162 | // Destructor |
163 | ~grid_dist_iterator_sub() |
164 | { |
165 | } |
166 | |
167 | /*! \brief Get the next element |
168 | * |
169 | * \return the next grid_key |
170 | * |
171 | */ |
172 | |
173 | inline grid_dist_iterator_sub<dim,device_grid> & operator++() |
174 | { |
175 | ++a_it; |
176 | |
177 | // check if a_it is at the end |
178 | |
179 | if (a_it.isNext() == true) |
180 | return *this; |
181 | else |
182 | { |
183 | // switch to the new grid |
184 | g_c++; |
185 | |
186 | selectValidGrid(); |
187 | } |
188 | |
189 | return *this; |
190 | } |
191 | |
192 | /*! \brief Check if there is the next element |
193 | * |
194 | * \return true if there is the next, false otherwise |
195 | * |
196 | */ |
197 | inline bool isNext() |
198 | { |
199 | // If there are no other grid stop |
200 | |
201 | if (g_c >= gList.size()) |
202 | return false; |
203 | |
204 | return true; |
205 | } |
206 | |
207 | /*! \brief Get the actual key |
208 | * |
209 | * \return the actual key |
210 | * |
211 | */ |
212 | inline grid_dist_key_dx<dim,typename device_grid::base_key> get() |
213 | { |
214 | return grid_dist_key_dx<dim,typename device_grid::base_key>(g_c,a_it.get()); |
215 | } |
216 | |
217 | /*! \brief Convert a g_dist_key_dx into a global key |
218 | * |
219 | * \see grid_dist_key_dx |
220 | * \see grid_dist_iterator |
221 | * |
222 | * \return the global position in the grid |
223 | * |
224 | */ |
225 | inline grid_key_dx<dim> getGKey(const grid_dist_key_dx<dim> & k) |
226 | { |
227 | // Get the sub-domain id |
228 | size_t sub_id = k.getSub(); |
229 | |
230 | grid_key_dx<dim> k_glob = k.getKey(); |
231 | |
232 | // shift |
233 | k_glob = k_glob + gdb_ext.get(sub_id).origin; |
234 | |
235 | return k_glob; |
236 | } |
237 | |
238 | /* \brief Get the starting point of the grid iterator |
239 | * |
240 | * \return the starting point |
241 | * |
242 | */ |
243 | inline grid_key_dx<dim> getStart() const |
244 | { |
245 | return start; |
246 | } |
247 | |
248 | /* \brief Get the stop point of the grid iterator |
249 | * |
250 | * \return the stop point |
251 | * |
252 | */ |
253 | inline grid_key_dx<dim> getStop() const |
254 | { |
255 | return stop; |
256 | } |
257 | |
258 | /*! \brief Return the number of local grids |
259 | * |
260 | * |
261 | */ |
262 | inline size_t N_loc_grid() |
263 | { |
264 | return gList.size(); |
265 | } |
266 | |
267 | /*! \brief Return the component j of the starting point (P1) of the domain part |
268 | * for the local grid i |
269 | * |
270 | * \param i local grid |
271 | * \param j dimension |
272 | * |
273 | * |
274 | */ |
275 | inline size_t loc_grid_info_start(size_t i,size_t j) |
276 | { |
277 | return gdb_ext.get(i).DBox.getLow(i); |
278 | } |
279 | |
280 | /*! \brief Return the component j of the stop point (P2) of the domain part |
281 | * for the local grid i |
282 | * |
283 | * \param i local grid |
284 | * \param j dimension |
285 | * |
286 | * |
287 | */ |
288 | inline size_t loc_grid_info_size(size_t i,size_t j) |
289 | { |
290 | return gdb_ext.get(i).GDBox.getHigh(i); |
291 | } |
292 | }; |
293 | |
294 | |
295 | //////// MACRO in 3D |
296 | |
297 | #define WHILE_M(grid,stencil) auto & ginfo = grid.getLocalGridsInfo();\ |
298 | for (size_t s = 0 ; s < grid.getN_loc_grid() ; s++)\ |
299 | {\ |
300 | auto it = grid.get_loc_grid_iterator_stencil(s,stencil);\ |
301 | \ |
302 | int lo[3] = {(int)ginfo.get(s).Dbox.getLow(0),(int)ginfo.get(s).Dbox.getLow(1),(int)ginfo.get(s).Dbox.getLow(2)};\ |
303 | int hi[3] = {(int)ginfo.get(s).Dbox.getHigh(0),(int)ginfo.get(s).Dbox.getHigh(1),(int)ginfo.get(s).Dbox.getHigh(2)};\ |
304 | \ |
305 | int uhi[3] = {(int)ginfo.get(s).GDbox.getHigh(0),(int)ginfo.get(s).GDbox.getHigh(1),(int)ginfo.get(s).GDbox.getHigh(2)};\ |
306 | \ |
307 | int sx = uhi[0]+1;\ |
308 | int sxsy = (uhi[0]+1)*(uhi[1]+1); |
309 | |
310 | #define ITERATE_3D_M(n_pt) int i = lo[2];\ |
311 | for ( ; i <= hi[2] ; i+=1)\ |
312 | {\ |
313 | int j = lo[1];\ |
314 | for ( ; j <= hi[1] ; j+=1)\ |
315 | {\ |
316 | int k = lo[0];\ |
317 | for ( ; k <= hi[0] ; k+=n_pt)\ |
318 | { |
319 | |
320 | |
321 | #define GET_GRID_M(grid) grid.get_loc_grid(s); |
322 | |
323 | |
324 | #define END_LOOP_M(n_pt) it.private_sum<n_pt>();\ |
325 | }\ |
326 | it.private_adjust( - k + sx + lo[0]);\ |
327 | }\ |
328 | it.private_adjust(- j*sx + sxsy + lo[1]*sx);\ |
329 | }\ |
330 | } |
331 | |
332 | #endif /* SRC_GRID_GRID_DIST_ID_ITERATOR_SUB_HPP_ */ |
333 | |