1 | /* |
2 | * Domain_NN_calculator.hpp |
3 | * |
4 | * Created on: Nov 26, 2016 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef SRC_DECOMPOSITION_DOMAIN_NN_CALCULATOR_CART_HPP_ |
9 | #define SRC_DECOMPOSITION_DOMAIN_NN_CALCULATOR_CART_HPP_ |
10 | |
11 | #include <Vector/map_vector.hpp> |
12 | #include "NN/CellList/ParticleItCRS_Cells.hpp" |
13 | |
14 | /*! \brief This class calculate processor domains and neighborhood |
15 | * of each processor domain |
16 | * |
17 | * \param dim Dimensionality |
18 | * |
19 | */ |
20 | template<unsigned int dim> |
21 | class domain_nn_calculator_cart |
22 | { |
23 | //! True if domain and anomalous domain cells are computed |
24 | bool are_domain_anom_computed; |
25 | |
26 | /////////////////////////////// CRS ////////////////////// |
27 | |
28 | //! anomalous cell neighborhood for CRS |
29 | openfpm::vector<subsub<dim>> anom; |
30 | |
31 | //! Set of anomalous CRS domain cells linearized |
32 | openfpm::vector<subsub_lin<dim>> anom_lin; |
33 | |
34 | //! Set of normal domain cells for CRS |
35 | openfpm::vector<grid_key_dx<dim>> dom; |
36 | |
37 | //! Set of normal CRS domain cells linearized |
38 | openfpm::vector<size_t> dom_lin; |
39 | |
40 | ////////////////////////////////// DOMAIN CELLS /////////////////////// |
41 | |
42 | //! Set of domain cells |
43 | openfpm::vector<grid_key_dx<dim>> dom_cells; |
44 | |
45 | //! Set of linearized domain cells |
46 | openfpm::vector<size_t> dom_cells_lin; |
47 | |
48 | ////////////////////////////////////////////////////////////// |
49 | |
50 | //! Processor box |
51 | Box<dim,long int> proc_box; |
52 | |
53 | //! Processor cells-grid |
54 | grid_sm<dim,void> gs; |
55 | |
56 | //! key with all coordinates set to one |
57 | grid_key_dx<dim> one; |
58 | |
59 | /*! \brief Calculate the subdomain that are in the skin part of the domain |
60 | * |
61 | \verbatim |
62 | |
63 | +---+---+---+---+---+---+ |
64 | | 1 | 2 | 3 | 4 | 5 | 6 | |
65 | +---+---+---+---+---+---+ |
66 | |27 | | 7 | |
67 | +---+ +---+ |
68 | |26 | | 8 | |
69 | +---+ +---+ |
70 | |25 | | 9 | |
71 | +---+ DOM1 +---+ |
72 | |24 | |10 | |
73 | +---+ +---+ |
74 | |23 | |11 | |
75 | +---+ +---+ |
76 | |22 | |12 | |
77 | +---+-----------+---+---+ |
78 | |21 | |13 | |
79 | +---+ +---+ |
80 | |20 | DOM2 |14 | |
81 | +---+---+---+---+---+ |
82 | |19 |18 |17 | 16|15 | |
83 | +---+---+---+---+---+ <----- Domain end here |
84 | | |
85 | ^ | |
86 | |_____________| |
87 | |
88 | |
89 | \endverbatim |
90 | * |
91 | * In some cases like symmetric with CRS Scheme The cells indicated with numbers has a non straigh-forward |
92 | * neighborhood. This function calculate the list of the domain cells with normal symmetric neighborhood type |
93 | * and compute a list of cells with more complex neighboring cells. |
94 | * |
95 | * \param sub_keys array that contain the position of the sub-sub-domains indicated with numbers |
96 | * in grid coordinates + for each its neighboring cells |
97 | * |
98 | * \param dom_cells list of all the domain cells |
99 | * |
100 | * \param dom_subsub cells with normal neighborhood |
101 | * |
102 | * \param loc_box array of local sub-sub-domain in grid coordinates |
103 | * |
104 | * \param proc_box Processor bounding box in local coordinates |
105 | * |
106 | * |
107 | */ |
108 | void CalculateDomAndAnomCells(openfpm::vector<subsub<dim>> & sub_keys, |
109 | openfpm::vector<grid_key_dx<dim>> & dom_subsub, |
110 | openfpm::vector<grid_key_dx<dim>> & dom_cells, |
111 | const ::Box<dim,long int> & proc_box, |
112 | const openfpm::vector<::Box<dim, size_t>> & loc_box) |
113 | { |
114 | // Reset dom and dom_subsub |
115 | sub_keys.clear(); |
116 | dom_subsub.clear(); |
117 | |
118 | size_t sz[dim]; |
119 | |
120 | // ----Grid size = proc_box.getHigh(j) - proc_box.getLow(j) |
121 | // +2 is padding |
122 | |
123 | for (size_t j = 0 ; j < dim ; j++) |
124 | {sz[j] = proc_box.getHigh(j) - proc_box.getLow(j) + 2 + 1;} |
125 | |
126 | gs.setDimensions(sz); |
127 | |
128 | // Set the grid |
129 | grid_cpu<dim, aggregate<openfpm::vector<grid_key_dx<dim>> >> g(sz); |
130 | g.setMemory(); |
131 | |
132 | for (size_t i = 0 ; i < dim ; i++) |
133 | {one.set_d(i,1);} |
134 | |
135 | // Calculate the csr neighborhood |
136 | openfpm::vector<std::pair<grid_key_dx<dim>,grid_key_dx<dim>>> csr; |
137 | NNcalc_csr(csr); |
138 | |
139 | // Draw the domain on this grid |
140 | for (size_t i = 0 ; i < loc_box.size() ; i++) |
141 | { |
142 | grid_key_dx<dim> start; |
143 | grid_key_dx<dim> stop; |
144 | |
145 | for (size_t j = 0 ; j < dim ; j++) |
146 | { |
147 | start.set_d(j,loc_box.template get<0>(i)[j] - proc_box.getLow(j) + 1); |
148 | stop.set_d(j,loc_box.template get<1>(i)[j] - proc_box.getLow(j) + 1); |
149 | } |
150 | |
151 | grid_key_dx_iterator_sub<dim> sub(g.getGrid(),start,stop); |
152 | |
153 | while (sub.isNext()) |
154 | { |
155 | auto key = sub.get(); |
156 | |
157 | for (size_t j = 0 ; j < csr.size() ; j++) |
158 | { |
159 | grid_key_dx<dim> src = key + csr.get(j).first; |
160 | grid_key_dx<dim> dst = key + csr.get(j).second; |
161 | g.template get<0>(src).add(dst); |
162 | } |
163 | |
164 | dom_cells.add(key - one); |
165 | |
166 | ++sub; |
167 | } |
168 | } |
169 | |
170 | // Span all the grid point and take all the sub-sub-domains that has a |
171 | // neighborhood non-consistent to the normal symmetric NN, and the one that |
172 | // are consistent to NN symmetric |
173 | grid_key_dx_iterator<dim> it(g.getGrid()); |
174 | |
175 | while (it.isNext()) |
176 | { |
177 | auto key = it.get(); |
178 | |
179 | // Adding in the list of the non-normal neighborhood cells |
180 | if (g.template get<0>(key).size() == openfpm::math::pow(3,dim)/2+1) |
181 | { |
182 | // Add in the list of the normal neighborhood list |
183 | dom_subsub.add(key - one); |
184 | } |
185 | else if (g.template get<0>(key).size() != 0) |
186 | { |
187 | sub_keys.add(); |
188 | sub_keys.last().subsub = key - one; |
189 | // Adding the neighborhood of the cell |
190 | |
191 | sub_keys.last().NN_subsub.resize(g.template get<0>(key).size()); |
192 | |
193 | for (size_t i = 0 ; i < g.template get<0>(key).size() ; i++) |
194 | {sub_keys.last().NN_subsub.get(i) = g.template get<0>(key).get(i) - one;} |
195 | } |
196 | |
197 | ++it; |
198 | } |
199 | } |
200 | |
201 | /*! \brief Linearize the sub-sub-domains ids |
202 | * |
203 | * A subsub domain can be identified by a set of number (i,j). |
204 | * The linearization transform it into a number |
205 | * |
206 | * \param anom set of grid keys to linearize |
207 | * \param anom_lin linearized output |
208 | * \param shift shifting to add for the linearizaton |
209 | * \param gs information about the grid to linearize |
210 | * |
211 | */ |
212 | void linearize_subsub(const openfpm::vector<subsub<dim>> & anom, |
213 | openfpm::vector<subsub_lin<dim>> & anom_lin, |
214 | const grid_key_dx<dim> & shift, |
215 | const grid_sm<dim,void> & gs) |
216 | { |
217 | anom_lin.clear(); |
218 | for (size_t i = 0 ; i < anom.size() ; i++) |
219 | { |
220 | grid_key_dx<dim> tmp = anom.get(i).subsub + shift; |
221 | anom_lin.add(); |
222 | anom_lin.last().subsub = gs.LinId(tmp); |
223 | |
224 | long int self_cell = -1; |
225 | |
226 | for (size_t j = 0 ; j < anom.get(i).NN_subsub.size() ; j++) |
227 | { |
228 | grid_key_dx<dim> tmp = anom.get(i).NN_subsub.get(j) + shift; |
229 | anom_lin.get(i).NN_subsub.add((long int)gs.LinId(tmp) - anom_lin.get(i).subsub); |
230 | |
231 | // This indicate that for example in the neighborhood of one cell it-self is included in the list |
232 | // For example the cell 100 is in the neighborhood of the cell 100 |
233 | if (anom_lin.get(i).NN_subsub.last() == 0) |
234 | self_cell = anom_lin.get(i).NN_subsub.size() - 1; |
235 | } |
236 | |
237 | // if exist the self interacting cell (Example cell 100 neighborhood of cell 100), this cell MUST BE ALWAYS at the beginning |
238 | if (self_cell != -1) |
239 | { |
240 | // bring the self-cell into the beginning |
241 | size_t tmp = anom_lin.get(i).NN_subsub.get(0); |
242 | anom_lin.get(i).NN_subsub.get(0) = 0; |
243 | anom_lin.get(i).NN_subsub.get(self_cell) = tmp; |
244 | } |
245 | } |
246 | } |
247 | |
248 | public: |
249 | |
250 | domain_nn_calculator_cart() |
251 | :are_domain_anom_computed(false) |
252 | { |
253 | } |
254 | |
255 | /*! \brief Set parameters to calculate the cell neighborhood |
256 | * |
257 | * \param proc_box processor cells box |
258 | * |
259 | */ |
260 | void setParameters(const Box<dim,long int> & proc_box) |
261 | { |
262 | this->proc_box = proc_box; |
263 | } |
264 | |
265 | /*! \brief Set parameters to calculate the cell neighborhood |
266 | * |
267 | * \param loc_box set of local sub-domains |
268 | * \param shift to apply in the linearization |
269 | * \param gs grid of cells (for the processor domain) |
270 | * |
271 | */ |
272 | void setNNParameters(openfpm::vector<::Box<dim, size_t>> & loc_box, |
273 | const grid_key_dx<dim> & shift, |
274 | const grid_sm<dim,void> & gs) |
275 | { |
276 | if (are_domain_anom_computed == false) |
277 | { |
278 | CalculateDomAndAnomCells(anom,dom,dom_cells,proc_box,loc_box); |
279 | are_domain_anom_computed = true; |
280 | |
281 | dom_cells_lin.clear(); |
282 | for (size_t i = 0 ; i < dom_cells.size() ; i++) |
283 | { |
284 | grid_key_dx<dim> tmp = dom_cells.get(i) + shift; |
285 | dom_cells_lin.add(gs.LinId(tmp)); |
286 | } |
287 | |
288 | |
289 | dom_lin.clear(); |
290 | for (size_t i = 0 ; i < dom.size() ; i++) |
291 | { |
292 | grid_key_dx<dim> tmp = dom.get(i) + shift; |
293 | dom_lin.add(gs.LinId(tmp)); |
294 | } |
295 | |
296 | linearize_subsub(anom,anom_lin,shift,gs); |
297 | } |
298 | } |
299 | |
300 | /*! \brief Get the domain Cells |
301 | * |
302 | * |
303 | * \return The set of domain cells |
304 | * |
305 | */ |
306 | openfpm::vector<size_t> & getDomainCells() |
307 | { |
308 | return dom_cells_lin; |
309 | } |
310 | |
311 | /*! \brief Get the domain Cells |
312 | * |
313 | * |
314 | * \return The set of domain cells |
315 | * |
316 | */ |
317 | openfpm::vector<size_t> & getCRSDomainCells() |
318 | { |
319 | return dom_lin; |
320 | } |
321 | |
322 | /*! \brief Get the domain anomalous cells |
323 | * |
324 | * |
325 | * \return The set of anomalous cells |
326 | * |
327 | */ |
328 | openfpm::vector<subsub_lin<dim>> & getCRSAnomDomainCells() |
329 | { |
330 | return anom_lin; |
331 | } |
332 | |
333 | |
334 | /*! \brief In case you have to recompute the indexes |
335 | * |
336 | * |
337 | */ |
338 | void reset() |
339 | { |
340 | are_domain_anom_computed = false; |
341 | } |
342 | }; |
343 | |
344 | #endif /* SRC_DECOMPOSITION_DOMAIN_NN_CALCULATOR_CART_HPP_ */ |
345 | |