1/*
2 * grid_dist_id_iterator_dec_skin.hpp
3 *
4 * Created on: Jan 4, 2017
5 * Author: i-bird
6 */
7
8#ifndef SRC_GRID_ITERATORS_GRID_DIST_ID_ITERATOR_DEC_SKIN_HPP_
9#define SRC_GRID_ITERATORS_GRID_DIST_ID_ITERATOR_DEC_SKIN_HPP_
10
11
12#include "grid_dist_id_iterator.hpp"
13#include "Grid/grid_dist_util.hpp"
14#include "grid_dist_id_iterator_util.hpp"
15
16/*! \brief Given the decomposition it create an iterator
17 *
18 * Iterator across the local elements of the distributed grid
19 *
20 * \tparam dec Decomposition type
21 *
22 */
23template<typename Decomposition>
24class grid_dist_id_iterator_dec_skin : protected grid_skin_iterator_bc<Decomposition::dims>
25{
26 //! a_its element in this moment selected
27 size_t a_its_p;
28
29 //! grid list counter
30 size_t g_c;
31
32 //! Extension of each grid: domain and ghost + domain
33 openfpm::vector<GBoxes<Decomposition::dims>> gdb_ext;
34
35 //! Internal grid sub-iterator
36 grid_key_dx_iterator_sub<Decomposition::dims> a_it;
37
38 //! Internal struct
39 struct gp_sub
40 {
41 //! from which grid this iterator come from
42 size_t gc;
43
44 //! Iterator
45 grid_key_dx_iterator_sub<Decomposition::dims> it;
46
47 /*! \brief constructor
48 *
49 * \param gc sub-domain
50 * \param it iterator
51 *
52 */
53 gp_sub(size_t gc, grid_key_dx_iterator_sub<Decomposition::dims> && it)
54 :gc(gc),it(it)
55 {}
56 };
57
58 //! Actual sub-iterators
59 openfpm::vector<gp_sub> a_its;
60
61 //! Spacing
62 typename Decomposition::stype spacing[Decomposition::dims];
63
64
65 /*! \brief from g_c increment g_c until you find a valid grid
66 *
67 */
68 void selectValidGrid()
69 {
70 if (a_its_p < a_its.size())
71 {
72 g_c = a_its.get(a_its_p).gc;
73
74 a_it.reinitialize(a_its.get(a_its_p).it);
75 }
76 else
77 g_c = gdb_ext.size();
78 }
79
80 /*! \brief construct sub-iterators
81 *
82 *
83 *
84 */
85 void construct_sub_it()
86 {
87 // Construct the sub iterators
88 for (size_t i = 0 ; i < 2*Decomposition::dims; i++)
89 {
90 for (size_t gc = 0 ; gc < gdb_ext.size() ; gc++)
91 {
92 grid_key_dx<Decomposition::dims> start = this->sub_it[i].getStart();
93 grid_key_dx<Decomposition::dims> stop = this->sub_it[i].getStop();
94
95 grid_key_dx<Decomposition::dims> start_c;
96 grid_key_dx<Decomposition::dims> stop_c;
97
98 if (compute_subset<Decomposition,false>(gdb_ext,gc,start,stop,start_c,stop_c) == true)
99 {
100 // Convert global coordinate start_c stop_c into local
101 // and calculate the grid sizes
102 size_t sz[Decomposition::dims];
103 for (size_t j = 0 ; j < Decomposition::dims ; j++)
104 {sz[j] = gdb_ext.get(gc).GDbox.getHigh(j) + 1;}
105
106 grid_sm<Decomposition::dims,void> g_sm(sz);
107
108 // Non empty sub-set
109 a_its.add(gp_sub(gc,grid_key_dx_iterator_sub<Decomposition::dims>(g_sm,start_c,stop_c)));
110 }
111 }
112 }
113 }
114
115
116 public:
117
118
119 /*! \brief Copy constructor
120 *
121 * \param tmp iterator to copy
122 *
123 */
124 grid_dist_id_iterator_dec_skin(const grid_dist_id_iterator_dec_skin<Decomposition> & tmp)
125 :grid_skin_iterator_bc<Decomposition::dims>(tmp),a_its_p(0)
126 {
127 this->operator=(tmp);
128 }
129
130 /*! \brief Copy constructor
131 *
132 * \param tmp iterator to copy
133 *
134 */
135 grid_dist_id_iterator_dec_skin(grid_dist_id_iterator_dec_skin<Decomposition> && tmp)
136 :grid_skin_iterator_bc<Decomposition::dims>(tmp),a_its_p(0)
137 {
138 this->operator=(tmp);
139 }
140
141 /*! \brief Constructor of the distributed grid iterator
142 *
143 * \param dec Decomposition
144 * \param g_sm grid size on each direction
145 * \param A box A (must be contained into B)
146 * \param B box B
147 * \param bc boundary conditions
148 *
149 */
150 grid_dist_id_iterator_dec_skin(Decomposition & dec,
151 const grid_sm<Decomposition::dims,void> & g_sm,
152 const Box<Decomposition::dims,size_t> & A,
153 const Box<Decomposition::dims,size_t> & B,
154 const size_t (& bc)[Decomposition::dims])
155 :grid_skin_iterator_bc<Decomposition::dims>(g_sm,A,B,bc),a_its_p(0),g_c(0)
156 {
157 // From the decomposition construct gdb_ext
158 create_gdb_ext<Decomposition::dims,Decomposition>(gdb_ext,dec,g_sm.getSize(),dec.getDomain(),spacing);
159
160 // This iterato only work if A is contained into B
161 if (A.isContained(B) == false)
162 std::cout << __FILE__ << ":" << __LINE__ << ", Error Box A must be contained into box B" << std::endl;
163
164 // construct sub_iterators
165 construct_sub_it();
166
167 // Initialize the current iterator
168 // with the first grid
169 selectValidGrid();
170 }
171
172 //! Destructor
173 ~grid_dist_id_iterator_dec_skin()
174 {
175 }
176
177 /*! \brief Get the next element
178 *
179 * \return itself
180 *
181 */
182 inline grid_dist_id_iterator_dec_skin<Decomposition> & operator++()
183 {
184 ++a_it;
185
186 // check if a_it is at the end
187
188 if (a_it.isNext() == true)
189 return *this;
190 else
191 {
192 // switch to the new grid
193 a_its_p++;
194
195 selectValidGrid();
196 }
197
198 return *this;
199 }
200
201 /*! \brief Check if there is the next element
202 *
203 * \return true if there is the next, false otherwise
204 *
205 */
206 inline bool isNext()
207 {
208 // If there are no other grid stop
209
210 if (a_its_p >= a_its.size())
211 {return false;}
212
213 return true;
214 }
215
216 /*! \brief Get the spacing of the grid
217 *
218 * \param i dimension
219 *
220 * \return the spacing
221 *
222 */
223 inline typename Decomposition::stype getSpacing(size_t i)
224 {
225 return spacing[i];
226 }
227
228 /*! \brief Get the actual global key of the grid
229 *
230 *
231 * \return the global position in the grid
232 *
233 */
234 inline grid_key_dx<Decomposition::dims> get()
235 {
236 const grid_dist_key_dx<Decomposition::dims> k = get_int();
237
238 // Get the sub-domain id
239 size_t sub_id = k.getSub();
240
241 grid_key_dx<Decomposition::dims> k_glob = k.getKey();
242
243 // shift
244 k_glob = k_glob + gdb_ext.get(sub_id).origin;
245
246 return k_glob;
247 }
248
249 /*! \brief Get the actual key
250 *
251 * \return the actual key
252 *
253 */
254 inline grid_dist_key_dx<Decomposition::dims> get_int()
255 {
256 return grid_dist_key_dx<Decomposition::dims>(g_c,a_it.get());
257 }
258
259 /*! \brief Copy operator=
260 *
261 * \param tmp iterator to copy
262 *
263 * \return itself
264 *
265 */
266 grid_dist_id_iterator_dec_skin<Decomposition> & operator=(const grid_dist_id_iterator_dec_skin<Decomposition> & tmp)
267 {
268 a_its_p = tmp.a_its_p;
269 g_c = tmp.g_c;
270 gdb_ext = tmp.gdb_ext;
271 a_its = tmp.a_its;
272
273 for (size_t i = 0 ; i < Decomposition::dims ; i++)
274 spacing[i] = tmp.spacing[i];
275
276 a_it.reinitialize(tmp.a_it);
277
278 return *this;
279 }
280
281 /*! \brief Copy operator=
282 *
283 * \param tmp iterator to copy
284 *
285 * \return itself
286 *
287 */
288 grid_dist_id_iterator_dec_skin<Decomposition> & operator=(grid_dist_id_iterator_dec_skin<Decomposition> && tmp)
289 {
290 a_its_p = tmp.a_its_p;
291 g_c = tmp.g_c;
292 gdb_ext = tmp.gdb_ext;
293 a_its = tmp.a_its;
294
295 for (size_t i = 0 ; i < Decomposition::dims ; i++)
296 spacing[i] = tmp.spacing[i];
297
298 a_it.reinitialize(tmp.a_it);
299
300 return *this;
301 }
302};
303
304
305#endif /* SRC_GRID_ITERATORS_GRID_DIST_ID_ITERATOR_DEC_SKIN_HPP_ */
306