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 | */ |
23 | template<typename Decomposition> |
24 | class 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 | |