1 | /* |
2 | * vector_dist_MP_unit_tests.hpp |
3 | * |
4 | * Created on: Oct 14, 2016 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #define BOOST_TEST_DYN_LINK |
9 | #include <boost/test/unit_test.hpp> |
10 | |
11 | #include "Vector/vector_dist_multiphase_functions.hpp" |
12 | #include "VCluster/VCluster.hpp" |
13 | #include "Vector/vector_dist.hpp" |
14 | |
15 | BOOST_AUTO_TEST_SUITE( vector_dist_multiphase_test ) |
16 | |
17 | BOOST_AUTO_TEST_CASE( vector_dist_multiphase_cell_list_test ) |
18 | { |
19 | if (create_vcluster().getProcessingUnits() > 24) |
20 | return; |
21 | |
22 | size_t sz[3] = {60,60,40}; |
23 | |
24 | // The domain |
25 | Box<3,float> box({-1000.0,-1000.0,-1000.0},{2000.0,2000.0,1000.0}); |
26 | |
27 | // Boundary conditions |
28 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
29 | |
30 | int rank_test = create_vcluster().rank(); |
31 | float r_cut = 51.0; |
32 | |
33 | // ghost, big enough to contain the interaction radius |
34 | Ghost<3,float> ghost(r_cut); |
35 | |
36 | openfpm::vector< vector_dist<3,float, aggregate<double,double>> > phases; |
37 | |
38 | // first phase |
39 | phases.add( vector_dist<3,float, aggregate<double,double>>(0,box,bc,ghost) ); |
40 | |
41 | // The other 3 phases |
42 | phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),0) ); |
43 | phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),0) ); |
44 | phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),0) ); |
45 | |
46 | // Fill the phases with particles |
47 | |
48 | auto g_it = phases.get(0).getGridIterator(sz); |
49 | |
50 | while (g_it.isNext()) |
51 | { |
52 | auto key = g_it.get(); |
53 | |
54 | // Add a particle to all the phases |
55 | phases.get(0).add(); |
56 | phases.get(1).add(); |
57 | phases.get(2).add(); |
58 | phases.get(3).add(); |
59 | |
60 | phases.get(0).getLastPos()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0); |
61 | phases.get(0).getLastPos()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1); |
62 | phases.get(0).getLastPos()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2); |
63 | |
64 | phases.get(1).getLastPos()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0); |
65 | phases.get(1).getLastPos()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1); |
66 | phases.get(1).getLastPos()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2); |
67 | |
68 | phases.get(2).getLastPos()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0); |
69 | phases.get(2).getLastPos()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1); |
70 | phases.get(2).getLastPos()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2); |
71 | |
72 | phases.get(3).getLastPos()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0); |
73 | phases.get(3).getLastPos()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1); |
74 | phases.get(3).getLastPos()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2); |
75 | |
76 | ++g_it; |
77 | } |
78 | |
79 | // Sync all phases |
80 | for (size_t i = 0 ; i < 4 ; i++) |
81 | { |
82 | phases.get(i).map(); |
83 | } |
84 | |
85 | // randomize a little the particles |
86 | |
87 | for (size_t p = 0 ; p < phases.size() ; p++) |
88 | { |
89 | openfpm::vector<Point<3,float>> vt; |
90 | |
91 | for (size_t j = 0 ; j < phases.get(p).size_local() ; j++) |
92 | { |
93 | vt.add(phases.get(p).getPos((j + p*133) % phases.get(p).size_local())); |
94 | } |
95 | phases.get(p).getPosVector().swap(vt); |
96 | } |
97 | |
98 | // Sync all phases |
99 | for (size_t i = 0 ; i < 4 ; i++) |
100 | { |
101 | phases.get(i).ghost_get<>(); |
102 | } |
103 | |
104 | // Get the cell list of the phase 0 and 1 |
105 | auto CL_phase0 = phases.get(0).getCellList(r_cut); |
106 | auto CL_phase1 = phases.get(1).getCellList(r_cut); |
107 | |
108 | // This function create a Verlet-list between phases 0 and 1 |
109 | auto NN_ver01 = createVerlet(phases.get(0),phases.get(1),CL_phase1,r_cut); |
110 | |
111 | // Check NNver0_1 |
112 | |
113 | bool ret = true; |
114 | auto it = phases.get(0).getDomainIterator(); |
115 | |
116 | while (it.isNext()) |
117 | { |
118 | auto p = it.get(); |
119 | auto Np = NN_ver01.getNNIterator<NO_CHECK>(p.getKey()); |
120 | |
121 | size_t nn_count = 0; |
122 | |
123 | // For each neighborhood of the particle p |
124 | while (Np.isNext()) |
125 | { |
126 | // Count the number of particles |
127 | nn_count++; |
128 | |
129 | ++Np; |
130 | } |
131 | |
132 | ret &= nn_count == 7ul; |
133 | |
134 | ++it; |
135 | } |
136 | |
137 | BOOST_REQUIRE_EQUAL(ret,true); |
138 | |
139 | // Sync all phases |
140 | for (size_t i = 0 ; i < 4 ; i++) |
141 | { |
142 | phases.get(i).map(); |
143 | phases.get(i).ghost_get<>(); |
144 | } |
145 | |
146 | // NN_ver0_all |
147 | |
148 | // This function create an "Empty" Multiphase Cell List |
149 | auto CL_all = createCellListM<2>(phases,r_cut); |
150 | |
151 | // This create a Verlet-list between phase 0 and all the other phases |
152 | auto NNver0_all = createVerletM<2>(0,phases.get(0),phases,CL_all,r_cut); |
153 | |
154 | it = phases.get(0).getDomainIterator(); |
155 | |
156 | while (it.isNext()) |
157 | { |
158 | auto p = it.get(); |
159 | auto Np = NNver0_all.getNNIterator<NO_CHECK>(p.getKey()); |
160 | |
161 | size_t nn_cout[4] = {0,0,0,0}; |
162 | |
163 | // For each neighborhood of the particle p |
164 | while (Np.isNext()) |
165 | { |
166 | // Get from which phase it come from |
167 | auto ph_q = Np.getV(); |
168 | |
169 | nn_cout[ph_q]++; |
170 | |
171 | ++Np; |
172 | } |
173 | |
174 | ret &= nn_cout[0] == 7; |
175 | ret &= nn_cout[1] == 7; |
176 | ret &= nn_cout[2] == 7; |
177 | ret &= nn_cout[3] == 7; |
178 | |
179 | ++it; |
180 | } |
181 | |
182 | BOOST_REQUIRE_EQUAL(ret,true); |
183 | } |
184 | |
185 | |
186 | BOOST_AUTO_TEST_CASE( vector_dist_multiphase_cell_list_sym_test ) |
187 | { |
188 | if (create_vcluster().getProcessingUnits() > 24) |
189 | return; |
190 | |
191 | size_t sz[3] = {60,60,40}; |
192 | |
193 | // The domain |
194 | Box<3,float> box({-1000.0,-1000.0,-1000.0},{2000.0,2000.0,1000.0}); |
195 | |
196 | // Boundary conditions |
197 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
198 | |
199 | float r_cut = 51.0; |
200 | |
201 | // ghost, big enough to contain the interaction radius |
202 | Ghost<3,float> ghost(r_cut); |
203 | |
204 | openfpm::vector< vector_dist<3,float, aggregate<size_t>> > phases; |
205 | |
206 | // first phase |
207 | phases.add( vector_dist<3,float, aggregate<size_t>>(0,box,bc,ghost) ); |
208 | |
209 | // The other 3 phases |
210 | phases.add( vector_dist<3,float, aggregate<size_t>>(phases.get(0).getDecomposition(),0) ); |
211 | phases.add( vector_dist<3,float, aggregate<size_t>>(phases.get(0).getDecomposition(),0) ); |
212 | phases.add( vector_dist<3,float, aggregate<size_t>>(phases.get(0).getDecomposition(),0) ); |
213 | |
214 | // Fill the phases with particles |
215 | |
216 | auto g_it = phases.get(0).getGridIterator(sz); |
217 | |
218 | while (g_it.isNext()) |
219 | { |
220 | auto key = g_it.get(); |
221 | |
222 | // Add a particle to all the phases |
223 | phases.get(0).add(); |
224 | phases.get(1).add(); |
225 | phases.get(2).add(); |
226 | phases.get(3).add(); |
227 | |
228 | phases.get(0).getLastPosWrite()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0); |
229 | phases.get(0).getLastPosWrite()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1); |
230 | phases.get(0).getLastPosWrite()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2); |
231 | |
232 | phases.get(1).getLastPosWrite()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0); |
233 | phases.get(1).getLastPosWrite()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1); |
234 | phases.get(1).getLastPosWrite()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2); |
235 | |
236 | phases.get(2).getLastPosWrite()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0); |
237 | phases.get(2).getLastPosWrite()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1); |
238 | phases.get(2).getLastPosWrite()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2); |
239 | |
240 | phases.get(3).getLastPosWrite()[0] = key.get(0) * g_it.getSpacing(0) + box.getLow(0); |
241 | phases.get(3).getLastPosWrite()[1] = key.get(1) * g_it.getSpacing(1) + box.getLow(1); |
242 | phases.get(3).getLastPosWrite()[2] = key.get(2) * g_it.getSpacing(2) + box.getLow(2); |
243 | |
244 | ++g_it; |
245 | } |
246 | |
247 | // Sync all phases |
248 | for (size_t i = 0 ; i < 4 ; i++) |
249 | { |
250 | phases.get(i).map(); |
251 | } |
252 | |
253 | // randomize a little the particles |
254 | |
255 | for (size_t p = 0 ; p < phases.size() ; p++) |
256 | { |
257 | openfpm::vector<Point<3,float>> vt; |
258 | |
259 | for (size_t j = 0 ; j < phases.get(p).size_local() ; j++) |
260 | { |
261 | vt.add(phases.get(p).getPos((j + p*133) % phases.get(p).size_local())); |
262 | } |
263 | phases.get(p).getPosVector().swap(vt); |
264 | } |
265 | |
266 | // Sync all phases |
267 | for (size_t i = 0 ; i < 4 ; i++) |
268 | { |
269 | phases.get(i).ghost_get<>(); |
270 | } |
271 | |
272 | // Get the cell list of the phase 0 and 1 |
273 | auto CL_phase0 = phases.get(0).getCellListSym(r_cut); |
274 | auto CL_phase1 = phases.get(1).getCellListSym(r_cut); |
275 | |
276 | // This function create a Verlet-list between phases 0 and 1 |
277 | auto NN_ver01 = createVerletSym(phases.get(0),phases.get(1),CL_phase1,r_cut); |
278 | |
279 | // Check NNver0_1 |
280 | |
281 | bool ret = true; |
282 | auto it = phases.get(0).getDomainIterator(); |
283 | |
284 | while (it.isNext()) |
285 | { |
286 | auto p = it.get(); |
287 | auto Np = NN_ver01.getNNIterator<NO_CHECK>(p.getKey()); |
288 | |
289 | // For each neighborhood of the particle p |
290 | while (Np.isNext()) |
291 | { |
292 | // Neighborhood particle q |
293 | auto q = Np.get(); |
294 | |
295 | phases.get(0).getPropWrite<0>(p)++; |
296 | phases.get(1).getPropWrite<0>(q)++; |
297 | |
298 | ++Np; |
299 | } |
300 | |
301 | ++it; |
302 | } |
303 | |
304 | phases.get(0).ghost_put<add_,0>(); |
305 | phases.get(1).ghost_put<add_,0>(); |
306 | |
307 | #ifdef SE_CLASS3 |
308 | |
309 | phases.get(1).getDomainIterator(); |
310 | |
311 | #endif |
312 | |
313 | it = phases.get(0).getDomainIterator(); |
314 | while (it.isNext()) |
315 | { |
316 | auto p = it.get(); |
317 | |
318 | ret &= phases.get(0).getPropRead<0>(p) == 7; |
319 | ret &= phases.get(1).getPropRead<0>(p) == 7; |
320 | |
321 | ++it; |
322 | } |
323 | |
324 | BOOST_REQUIRE_EQUAL(ret,true); |
325 | |
326 | // Sync all phases |
327 | for (size_t i = 0 ; i < 4 ; i++) |
328 | { |
329 | phases.get(i).map(); |
330 | phases.get(i).ghost_get<>(); |
331 | } |
332 | |
333 | // Reset counter on all phases |
334 | |
335 | for (size_t i = 0 ; i < phases.size() ; i++) |
336 | { |
337 | it = phases.get(i).getDomainAndGhostIterator(); |
338 | while (it.isNext()) |
339 | { |
340 | auto p = it.get(); |
341 | |
342 | phases.get(i).getPropWrite<0>(p) = 0; |
343 | |
344 | ++it; |
345 | } |
346 | } |
347 | |
348 | // NN_ver0_all |
349 | |
350 | // This function create an "Empty" Multiphase Cell List |
351 | auto CL_all = createCellListSymM<2>(phases,r_cut); |
352 | |
353 | typedef decltype(createVerletSymM<2>(0,phases.get(0),phases,CL_all,r_cut)) verlet_type; |
354 | |
355 | verlet_type NNver_all[4]; |
356 | |
357 | // This create a Verlet-list between each phase to all the other phases |
358 | NNver_all[0] = createVerletSymM<2>(0,phases.get(0),phases,CL_all,r_cut); |
359 | NNver_all[1] = createVerletSymM<2>(1,phases.get(1),phases,CL_all,r_cut); |
360 | NNver_all[2] = createVerletSymM<2>(2,phases.get(2),phases,CL_all,r_cut); |
361 | NNver_all[3] = createVerletSymM<2>(3,phases.get(3),phases,CL_all,r_cut); |
362 | |
363 | // all phases to all phases |
364 | |
365 | for (size_t i = 0 ; i < phases.size() ; i++) |
366 | { |
367 | it = phases.get(i).getDomainIterator(); |
368 | |
369 | while (it.isNext()) |
370 | { |
371 | auto p = it.get(); |
372 | auto Np = NNver_all[i].getNNIterator<NO_CHECK>(p.getKey()); |
373 | |
374 | // For each neighborhood of the particle p |
375 | while (Np.isNext()) |
376 | { |
377 | // Get the particle q near to p |
378 | auto q = Np.getP(); |
379 | |
380 | // Get from which phase it come from |
381 | auto ph_q = Np.getV(); |
382 | |
383 | phases.get(i).getPropWrite<0>(p)++; |
384 | phases.get(ph_q).getPropWrite<0>(q)++; |
385 | |
386 | ++Np; |
387 | } |
388 | |
389 | ++it; |
390 | } |
391 | } |
392 | |
393 | phases.get(0).ghost_put<add_,0>(); |
394 | phases.get(1).ghost_put<add_,0>(); |
395 | phases.get(2).ghost_put<add_,0>(); |
396 | phases.get(3).ghost_put<add_,0>(); |
397 | |
398 | #ifdef SE_CLASS3 |
399 | |
400 | it = phases.get(1).getDomainIterator(); |
401 | it = phases.get(2).getDomainIterator(); |
402 | it = phases.get(3).getDomainIterator(); |
403 | |
404 | #endif |
405 | |
406 | it = phases.get(0).getDomainIterator(); |
407 | while (it.isNext()) |
408 | { |
409 | auto p = it.get(); |
410 | |
411 | ret &= phases.get(0).getPropRead<0>(p) == 32; |
412 | ret &= phases.get(1).getPropRead<0>(p) == 32; |
413 | ret &= phases.get(2).getPropRead<0>(p) == 32; |
414 | ret &= phases.get(3).getPropRead<0>(p) == 32; |
415 | |
416 | if (ret == false) |
417 | { |
418 | std::cout << phases.get(0).getPropRead<0>(p) << std::endl; |
419 | std::cout << phases.get(1).getPropRead<0>(p) << std::endl; |
420 | std::cout << phases.get(2).getPropRead<0>(p) << std::endl; |
421 | std::cout << phases.get(3).getPropRead<0>(p) << std::endl; |
422 | } |
423 | |
424 | ++it; |
425 | } |
426 | |
427 | BOOST_REQUIRE_EQUAL(ret,true); |
428 | } |
429 | |
430 | BOOST_AUTO_TEST_SUITE_END() |
431 | |
432 | |