1 | /* |
2 | * vector_dist_unit_test.hpp |
3 | * |
4 | * Created on: Mar 6, 2015 |
5 | * Author: Pietro Incardona |
6 | */ |
7 | |
8 | #define BOOST_TEST_DYN_LINK |
9 | #include <boost/test/unit_test.hpp> |
10 | |
11 | #include "config.h" |
12 | |
13 | #include <random> |
14 | #include "Vector/vector_dist.hpp" |
15 | #include "data_type/aggregate.hpp" |
16 | #include "vector_dist_util_unit_tests.hpp" |
17 | #include "Point_test.hpp" |
18 | #include "Vector/performance/vector_dist_performance_common.hpp" |
19 | |
20 | /*! \brief Print a string about the test |
21 | * |
22 | * \param test string to print |
23 | * \param sz size |
24 | * |
25 | */ |
26 | void print_test_v(std::string test, size_t sz) |
27 | { |
28 | if (create_vcluster().getProcessUnitID() == 0) |
29 | std::cout << test << " " << sz << "\n" ; |
30 | } |
31 | |
32 | /*! \brief Get next testing step decrementing the size |
33 | * |
34 | * \param k actual size |
35 | * \param step |
36 | * |
37 | * \return the next step |
38 | * |
39 | */ |
40 | long int decrement(long int k, long int step) |
41 | { |
42 | if (k <= 32) |
43 | { |
44 | return 1; |
45 | } |
46 | else if (k - 2*step+1 <= 0) |
47 | { |
48 | return k - 32; |
49 | } |
50 | else |
51 | return step; |
52 | } |
53 | |
54 | /*! \brief Count the total number of particles |
55 | * |
56 | * \param vd distributed vector |
57 | * \param bc boundary conditions |
58 | * |
59 | */ |
60 | template<unsigned int dim, template <typename> class layout> |
61 | size_t total_n_part_lc(vector_dist<dim,float, Point_test<float>, CartDecomposition<dim,float>, HeapMemory, layout > & vd, size_t (& bc)[dim]) |
62 | { |
63 | Vcluster<> & v_cl = vd.getVC(); |
64 | auto it2 = vd.getDomainIterator(); |
65 | const CartDecomposition<3,float> & ct = vd.getDecomposition(); |
66 | |
67 | bool noOut = true; |
68 | |
69 | size_t cnt = 0; |
70 | while (it2.isNext()) |
71 | { |
72 | auto key = it2.get(); |
73 | |
74 | noOut &= ct.isLocal(vd.getPos(key)); |
75 | |
76 | cnt++; |
77 | |
78 | ++it2; |
79 | } |
80 | |
81 | BOOST_REQUIRE_EQUAL(noOut,true); |
82 | |
83 | // |
84 | v_cl.sum(cnt); |
85 | v_cl.execute(); |
86 | |
87 | return cnt; |
88 | } |
89 | |
90 | |
91 | BOOST_AUTO_TEST_SUITE( vector_dist_test ) |
92 | |
93 | void print_test(std::string test, size_t sz) |
94 | { |
95 | if (create_vcluster().getProcessUnitID() == 0) |
96 | std::cout << test << " " << sz << "\n" ; |
97 | } |
98 | |
99 | template<typename vector> |
100 | void Test2D_ghost(Box<2,float> & box) |
101 | { |
102 | // Communication object |
103 | Vcluster<> & v_cl = create_vcluster(); |
104 | |
105 | typedef Point_test<float> p; |
106 | |
107 | // Get the default minimum number of sub-sub-domain per processor (granularity of the decomposition) |
108 | size_t n_sub = 64 * v_cl.getProcessingUnits(); |
109 | // Convert the request of having a minimum n_sub number of sub-sub domain into grid decompsition of the space |
110 | size_t sz = CartDecomposition<2,float>::getDefaultGrid(n_sub); |
111 | |
112 | //! [Create a vector of elements distributed on a grid like way] |
113 | |
114 | size_t g_div[]= {sz,sz}; |
115 | |
116 | // number of particles |
117 | size_t np = sz * sz; |
118 | |
119 | // Calculate the number of elements this processor is going to obtain |
120 | size_t p_np = np / v_cl.getProcessingUnits(); |
121 | |
122 | // Get non divisible part |
123 | size_t r = np % v_cl.getProcessingUnits(); |
124 | |
125 | // Get the offset |
126 | size_t offset = v_cl.getProcessUnitID() * p_np + std::min(v_cl.getProcessUnitID(),r); |
127 | |
128 | // Distribute the remain elements |
129 | if (v_cl.getProcessUnitID() < r) |
130 | p_np++; |
131 | |
132 | // Create a grid info |
133 | grid_sm<2,void> g_info(g_div); |
134 | |
135 | // Calculate the grid spacing |
136 | Point<2,float> spacing = box.getP2() - box.getP1(); |
137 | spacing = spacing / g_div; |
138 | |
139 | // middle spacing |
140 | Point<2,float> m_spacing = spacing / 2.0; |
141 | |
142 | // set the ghost based on the radius cut off (make just a little bit smaller than the spacing) |
143 | Ghost<2,float> g(spacing.get(0) - spacing .get(0) * 0.0001); |
144 | |
145 | // Boundary conditions |
146 | size_t bc[2]={NON_PERIODIC,NON_PERIODIC}; |
147 | |
148 | // Vector of particles |
149 | vector vd(g_info.size(),box,bc,g); |
150 | |
151 | // size_t |
152 | size_t cobj = 0; |
153 | |
154 | grid_key_dx_iterator_sp<2> it(g_info,offset,offset+p_np-1); |
155 | auto v_it = vd.getIterator(); |
156 | |
157 | while (v_it.isNext() && it.isNext()) |
158 | { |
159 | auto key = it.get(); |
160 | auto key_v = v_it.get(); |
161 | |
162 | // set the particle position |
163 | |
164 | vd.getPos(key_v)[0] = key.get(0) * spacing[0] + m_spacing[0] + box.getLow(0); |
165 | vd.getPos(key_v)[1] = key.get(1) * spacing[1] + m_spacing[1] + box.getLow(1); |
166 | |
167 | cobj++; |
168 | |
169 | ++v_it; |
170 | ++it; |
171 | } |
172 | |
173 | //! [Create a vector of elements distributed on a grid like way] |
174 | |
175 | // Both iterators must signal the end, and the number of elements in the vector, must the equal to the |
176 | // predicted one |
177 | BOOST_REQUIRE_EQUAL(v_it.isNext(),false); |
178 | BOOST_REQUIRE_EQUAL(it.isNext(),false); |
179 | BOOST_REQUIRE_EQUAL(cobj,p_np); |
180 | |
181 | //! [Redistribute the particles and sync the ghost properties] |
182 | |
183 | // redistribute the particles according to the decomposition |
184 | vd.map(); |
185 | |
186 | auto v_it2 = vd.getIterator(); |
187 | |
188 | while (v_it2.isNext()) |
189 | { |
190 | auto key = v_it2.get(); |
191 | |
192 | // fill with the processor ID where these particle live |
193 | vd.template getProp<p::s>(key) = vd.getPos(key)[0] + vd.getPos(key)[1] * 16.0f; |
194 | vd.template getProp<p::v>(key)[0] = v_cl.getProcessUnitID(); |
195 | vd.template getProp<p::v>(key)[1] = v_cl.getProcessUnitID(); |
196 | vd.template getProp<p::v>(key)[2] = v_cl.getProcessUnitID(); |
197 | |
198 | ++v_it2; |
199 | } |
200 | |
201 | // do a ghost get |
202 | vd.template ghost_get<p::s,p::v>(); |
203 | |
204 | //! [Redistribute the particles and sync the ghost properties] |
205 | |
206 | // Get the decomposition |
207 | const auto & dec = vd.getDecomposition(); |
208 | |
209 | // Get the ghost external boxes |
210 | openfpm::vector<size_t> vb(dec.getNEGhostBox()); |
211 | |
212 | // Get the ghost iterator |
213 | auto g_it = vd.getGhostIterator(); |
214 | |
215 | size_t n_part = 0; |
216 | |
217 | // Check if the ghost particles contain the correct information |
218 | while (g_it.isNext()) |
219 | { |
220 | auto key = g_it.get(); |
221 | |
222 | // Check the received data |
223 | float prp = vd.template getProp<p::s>(key); |
224 | float prp2 = vd.getPos(key)[0] + vd.getPos(key)[1] * 16.0f; |
225 | BOOST_REQUIRE_EQUAL(prp2,prp); |
226 | |
227 | bool is_in = false; |
228 | size_t b = 0; |
229 | size_t lb = 0; |
230 | |
231 | // check if the received data are in one of the ghost boxes |
232 | for ( ; b < dec.getNEGhostBox() ; b++) |
233 | { |
234 | Point<2,float> xp = vd.getPos(key); |
235 | |
236 | if (dec.getEGhostBox(b).isInside(xp) == true ) |
237 | { |
238 | is_in = true; |
239 | |
240 | // Add |
241 | vb.get(b)++; |
242 | lb = b; |
243 | } |
244 | } |
245 | BOOST_REQUIRE_EQUAL(is_in,true); |
246 | |
247 | // Check that the particle come from the correct processor |
248 | BOOST_REQUIRE_EQUAL(vd.template getProp<p::v>(key)[0],dec.getEGhostBoxProcessor(lb)); |
249 | |
250 | n_part++; |
251 | ++g_it; |
252 | } |
253 | |
254 | if (v_cl.getProcessingUnits() > 1) |
255 | { |
256 | BOOST_REQUIRE(n_part != 0); |
257 | } |
258 | |
259 | CellDecomposer_sm<2,float,shift<2,float>> cd(SpaceBox<2,float>(box),g_div,0); |
260 | |
261 | for (size_t i = 0 ; i < vb.size() ; i++) |
262 | { |
263 | // Calculate how many particle should be in the box |
264 | size_t n_point = cd.getGridPoints(dec.getEGhostBox(i)).getVolumeKey(); |
265 | |
266 | BOOST_REQUIRE_EQUAL(n_point,vb.get(i)); |
267 | } |
268 | } |
269 | |
270 | BOOST_AUTO_TEST_CASE( vector_dist_ghost ) |
271 | { |
272 | typedef vector_dist<2,float, Point_test<float>> vector; |
273 | |
274 | Box<2,float> box({0.0,0.0},{1.0,1.0}); |
275 | Test2D_ghost<vector>(box); |
276 | |
277 | Box<2,float> box2({-1.0,-1.0},{2.5,2.5}); |
278 | Test2D_ghost<vector>(box2); |
279 | } |
280 | |
281 | BOOST_AUTO_TEST_CASE( vector_dist_ghost_inte ) |
282 | { |
283 | typedef vector_dist_soa<2,float, Point_test<float>> vector; |
284 | |
285 | Box<2,float> box({0.0,0.0},{1.0,1.0}); |
286 | Test2D_ghost<vector>(box); |
287 | |
288 | Box<2,float> box2({-1.0,-1.0},{2.5,2.5}); |
289 | Test2D_ghost<vector>(box2); |
290 | } |
291 | |
292 | |
293 | |
294 | BOOST_AUTO_TEST_CASE( vector_dist_iterator_test_use_2d ) |
295 | { |
296 | Vcluster<> & v_cl = create_vcluster(); |
297 | |
298 | // set the seed |
299 | // create the random generator engine |
300 | std::srand(v_cl.getProcessUnitID()); |
301 | std::default_random_engine eg; |
302 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
303 | |
304 | #ifdef TEST_COVERAGE_MODE |
305 | long int k = 24288 * v_cl.getProcessingUnits(); |
306 | #else |
307 | long int k = 524288 * v_cl.getProcessingUnits(); |
308 | #endif |
309 | |
310 | long int big_step = k / 4; |
311 | big_step = (big_step == 0)?1:big_step; |
312 | |
313 | print_test_v( "Testing 2D vector k<=" ,k); |
314 | |
315 | // 2D test |
316 | for ( ; k >= 2 ; k-= decrement(k,big_step) ) |
317 | { |
318 | BOOST_TEST_CHECKPOINT( "Testing 2D vector k=" << k ); |
319 | |
320 | //! [Create a vector of random elements on each processor 2D] |
321 | |
322 | Box<2,float> box({0.0,0.0},{1.0,1.0}); |
323 | |
324 | // Boundary conditions |
325 | size_t bc[2]={NON_PERIODIC,NON_PERIODIC}; |
326 | |
327 | vector_dist<2,float, Point_test<float> > vd(k,box,bc,Ghost<2,float>(0.0)); |
328 | |
329 | auto it = vd.getIterator(); |
330 | |
331 | while (it.isNext()) |
332 | { |
333 | auto key = it.get(); |
334 | |
335 | vd.getPos(key)[0] = ud(eg); |
336 | vd.getPos(key)[1] = ud(eg); |
337 | |
338 | ++it; |
339 | } |
340 | |
341 | vd.map(); |
342 | |
343 | //! [Create a vector of random elements on each processor 2D] |
344 | |
345 | // Check if we have all the local particles |
346 | size_t cnt = 0; |
347 | const CartDecomposition<2,float> & ct = vd.getDecomposition(); |
348 | auto it2 = vd.getIterator(); |
349 | |
350 | while (it2.isNext()) |
351 | { |
352 | auto key = it2.get(); |
353 | |
354 | // Check if local |
355 | BOOST_REQUIRE_EQUAL(ct.isLocal(vd.getPos(key)),true); |
356 | |
357 | cnt++; |
358 | |
359 | ++it2; |
360 | } |
361 | |
362 | // |
363 | v_cl.sum(cnt); |
364 | v_cl.execute(); |
365 | BOOST_REQUIRE_EQUAL((long int)cnt,k); |
366 | } |
367 | } |
368 | |
369 | BOOST_AUTO_TEST_CASE( vector_dist_iterator_test_use_3d ) |
370 | { |
371 | Vcluster<> & v_cl = create_vcluster(); |
372 | |
373 | // set the seed |
374 | // create the random generator engine |
375 | std::srand(v_cl.getProcessUnitID()); |
376 | std::default_random_engine eg; |
377 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
378 | |
379 | #ifdef TEST_COVERAGE_MODE |
380 | long int k = 24288 * v_cl.getProcessingUnits(); |
381 | #else |
382 | long int k = 524288 * v_cl.getProcessingUnits(); |
383 | #endif |
384 | |
385 | long int big_step = k / 4; |
386 | big_step = (big_step == 0)?1:big_step; |
387 | |
388 | print_test_v( "Testing 3D vector k<=" ,k); |
389 | |
390 | // 3D test |
391 | for ( ; k >= 2 ; k-= decrement(k,big_step) ) |
392 | { |
393 | BOOST_TEST_CHECKPOINT( "Testing 3D vector k=" << k ); |
394 | |
395 | //! [Create a vector of random elements on each processor 3D] |
396 | |
397 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
398 | |
399 | // Boundary conditions |
400 | size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
401 | |
402 | vector_dist<3,float, Point_test<float> > vd(k,box,bc,Ghost<3,float>(0.0)); |
403 | |
404 | auto it = vd.getIterator(); |
405 | |
406 | while (it.isNext()) |
407 | { |
408 | auto key = it.get(); |
409 | |
410 | vd.getPos(key)[0] = ud(eg); |
411 | vd.getPos(key)[1] = ud(eg); |
412 | vd.getPos(key)[2] = ud(eg); |
413 | |
414 | ++it; |
415 | } |
416 | |
417 | vd.map(); |
418 | |
419 | //! [Create a vector of random elements on each processor 3D] |
420 | |
421 | // Check if we have all the local particles |
422 | size_t cnt = 0; |
423 | const CartDecomposition<3,float> & ct = vd.getDecomposition(); |
424 | auto it2 = vd.getIterator(); |
425 | |
426 | while (it2.isNext()) |
427 | { |
428 | auto key = it2.get(); |
429 | |
430 | // Check if local |
431 | BOOST_REQUIRE_EQUAL(ct.isLocal(vd.getPos(key)),true); |
432 | |
433 | cnt++; |
434 | |
435 | ++it2; |
436 | } |
437 | |
438 | // |
439 | v_cl.sum(cnt); |
440 | v_cl.execute(); |
441 | BOOST_REQUIRE_EQUAL(cnt,(size_t)k); |
442 | } |
443 | } |
444 | |
445 | |
446 | BOOST_AUTO_TEST_CASE( vector_dist_iterator_fixed_dec_3d ) |
447 | { |
448 | Vcluster<> & v_cl = create_vcluster(); |
449 | |
450 | // set the seed |
451 | // create the random generator engine |
452 | std::srand(v_cl.getProcessUnitID()); |
453 | std::default_random_engine eg; |
454 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
455 | |
456 | #ifdef TEST_COVERAGE_MODE |
457 | long int k = 2428 * v_cl.getProcessingUnits(); |
458 | #else |
459 | long int k = 52428 * v_cl.getProcessingUnits(); |
460 | #endif |
461 | |
462 | long int big_step = k / 4; |
463 | big_step = (big_step == 0)?1:big_step; |
464 | |
465 | print_test_v( "Testing 3D vector copy decomposition k<=" ,k); |
466 | |
467 | // 3D test |
468 | for ( ; k >= 2 ; k-= decrement(k,big_step) ) |
469 | { |
470 | BOOST_TEST_CHECKPOINT( "Testing 3D vector copy decomposition k=" << k ); |
471 | |
472 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
473 | |
474 | // Boundary conditions |
475 | size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
476 | |
477 | vector_dist<3,float, aggregate<double,double> > vd(k,box,bc,Ghost<3,float>(0.05)); |
478 | vector_dist<3,float, aggregate<double,double> > vd2(vd.getDecomposition(),k); |
479 | |
480 | auto it = vd.getIterator(); |
481 | |
482 | while (it.isNext()) |
483 | { |
484 | auto key = it.get(); |
485 | |
486 | vd.getPos(key)[0] = ud(eg); |
487 | vd.getPos(key)[1] = ud(eg); |
488 | vd.getPos(key)[2] = ud(eg); |
489 | |
490 | vd2.getPos(key)[0] = vd.getPos(key)[0]; |
491 | vd2.getPos(key)[1] = vd.getPos(key)[1]; |
492 | vd2.getPos(key)[2] = vd.getPos(key)[2]; |
493 | |
494 | ++it; |
495 | } |
496 | |
497 | vd.map(); |
498 | vd2.map(); |
499 | |
500 | vd.ghost_get(); |
501 | vd2.ghost_get(); |
502 | |
503 | auto NN = vd.getCellList(0.05); |
504 | auto NN2 = vd2.getCellList(0.05); |
505 | |
506 | cross_calc<3,0>(NN,NN2,vd,vd2); |
507 | cross_calc<3,1>(NN,NN,vd,vd); |
508 | |
509 | |
510 | auto it3 = vd.getIterator(); |
511 | |
512 | while (it3.isNext()) |
513 | { |
514 | auto key = it3.get(); |
515 | |
516 | BOOST_REQUIRE_EQUAL(vd.getProp<0>(key),vd.getProp<1>(key)); |
517 | |
518 | ++it3; |
519 | } |
520 | } |
521 | } |
522 | |
523 | BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_use_2d ) |
524 | { |
525 | Vcluster<> & v_cl = create_vcluster(); |
526 | |
527 | // set the seed |
528 | // create the random generator engine |
529 | std::srand(v_cl.getProcessUnitID()); |
530 | std::default_random_engine eg; |
531 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
532 | |
533 | #ifdef TEST_COVERAGE_MODE |
534 | long int k = 24288 * v_cl.getProcessingUnits(); |
535 | #else |
536 | long int k = 524288 * v_cl.getProcessingUnits(); |
537 | #endif |
538 | |
539 | long int big_step = k / 4; |
540 | big_step = (big_step == 0)?1:big_step; |
541 | |
542 | print_test_v( "Testing 2D periodic vector k<=" ,k); |
543 | |
544 | // 2D test |
545 | for ( ; k >= 2 ; k-= decrement(k,big_step) ) |
546 | { |
547 | BOOST_TEST_CHECKPOINT( "Testing 2D periodic vector k=" << k ); |
548 | |
549 | Box<2,float> box({0.0,0.0},{1.0,1.0}); |
550 | |
551 | // Boundary conditions |
552 | size_t bc[2]={PERIODIC,PERIODIC}; |
553 | |
554 | // factor |
555 | float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f); |
556 | |
557 | // ghost |
558 | Ghost<2,float> ghost(0.01 / factor); |
559 | |
560 | // ghost2 (a little bigger because of round off error) |
561 | Ghost<2,float> ghost2(0.05001 / factor); |
562 | |
563 | // Distributed vector |
564 | vector_dist<2,float, Point_test<float> > vd(k,box,bc,ghost); |
565 | |
566 | auto it = vd.getIterator(); |
567 | |
568 | while (it.isNext()) |
569 | { |
570 | auto key = it.get(); |
571 | |
572 | vd.getPos(key)[0] = ud(eg); |
573 | vd.getPos(key)[1] = ud(eg); |
574 | |
575 | ++it; |
576 | } |
577 | |
578 | vd.map(); |
579 | |
580 | // sync the ghost, only the property zero |
581 | vd.ghost_get<0>(); |
582 | |
583 | // Domain + ghost box |
584 | Box<2,float> dom_ext = box; |
585 | dom_ext.enlarge(ghost2); |
586 | |
587 | // Iterate on all particles domain + ghost |
588 | size_t l_cnt = 0; |
589 | size_t nl_cnt = 0; |
590 | size_t n_out = 0; |
591 | |
592 | |
593 | auto it2 = vd.getIterator(); |
594 | count_local_n_local<2,vector_dist<2,float, Point_test<float> >>(vd,it2,bc,box,dom_ext,l_cnt,nl_cnt,n_out); |
595 | |
596 | // No particles should be out of domain + ghost |
597 | BOOST_REQUIRE_EQUAL(n_out,0ul); |
598 | |
599 | // Ghost must populated because we synchronized them |
600 | if (k > 524288) |
601 | { |
602 | BOOST_REQUIRE(nl_cnt != 0); |
603 | BOOST_REQUIRE(l_cnt > nl_cnt); |
604 | } |
605 | |
606 | // Sum all the particles inside the domain |
607 | v_cl.sum(l_cnt); |
608 | v_cl.execute(); |
609 | |
610 | // count that they are equal to the initial total number |
611 | BOOST_REQUIRE_EQUAL((long int)l_cnt,k); |
612 | |
613 | l_cnt = 0; |
614 | nl_cnt = 0; |
615 | |
616 | // Iterate only on the ghost particles |
617 | auto itg = vd.getGhostIterator(); |
618 | count_local_n_local<2,vector_dist<2,float, Point_test<float> > >(vd,itg,bc,box,dom_ext,l_cnt,nl_cnt,n_out); |
619 | |
620 | // No particle on the ghost must be inside the domain |
621 | BOOST_REQUIRE_EQUAL(l_cnt,0ul); |
622 | |
623 | // Ghost must be populated |
624 | if (k > 524288) |
625 | { |
626 | BOOST_REQUIRE(nl_cnt != 0); |
627 | } |
628 | } |
629 | } |
630 | |
631 | BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_use_3d ) |
632 | { |
633 | Vcluster<> & v_cl = create_vcluster(); |
634 | |
635 | // set the seed |
636 | // create the random generator engine |
637 | std::srand(v_cl.getProcessUnitID()); |
638 | std::default_random_engine eg; |
639 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
640 | |
641 | #ifdef TEST_COVERAGE_MODE |
642 | long int k = 24288 * v_cl.getProcessingUnits(); |
643 | #else |
644 | long int k = 524288 * v_cl.getProcessingUnits(); |
645 | #endif |
646 | |
647 | long int big_step = k / 4; |
648 | big_step = (big_step == 0)?1:big_step; |
649 | |
650 | print_test_v( "Testing 3D periodic vector k<=" ,k); |
651 | |
652 | // 3D test |
653 | for ( ; k >= 2 ; k-= decrement(k,big_step) ) |
654 | { |
655 | BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector k=" << k ); |
656 | |
657 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
658 | |
659 | // Boundary conditions |
660 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
661 | |
662 | // factor |
663 | float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f); |
664 | |
665 | // ghost |
666 | Ghost<3,float> ghost(0.05 / factor); |
667 | |
668 | // ghost2 (a little bigger because of round off error) |
669 | Ghost<3,float> ghost2(0.05001 / factor); |
670 | |
671 | // Distributed vector |
672 | vector_dist<3,float, Point_test<float> > vd(k,box,bc,ghost); |
673 | |
674 | auto it = vd.getIterator(); |
675 | |
676 | while (it.isNext()) |
677 | { |
678 | auto key = it.get(); |
679 | |
680 | vd.getPos(key)[0] = ud(eg); |
681 | vd.getPos(key)[1] = ud(eg); |
682 | vd.getPos(key)[2] = ud(eg); |
683 | |
684 | ++it; |
685 | } |
686 | |
687 | vd.map(); |
688 | |
689 | // sync the ghost |
690 | vd.ghost_get<0>(); |
691 | |
692 | // Domain + ghost |
693 | Box<3,float> dom_ext = box; |
694 | dom_ext.enlarge(ghost2); |
695 | |
696 | // Iterate on all particles domain + ghost |
697 | size_t l_cnt = 0; |
698 | size_t nl_cnt = 0; |
699 | size_t n_out = 0; |
700 | |
701 | auto it2 = vd.getIterator(); |
702 | count_local_n_local<3,vector_dist<3,float, Point_test<float> >>(vd,it2,bc,box,dom_ext,l_cnt,nl_cnt,n_out); |
703 | |
704 | // No particles should be out of domain + ghost |
705 | BOOST_REQUIRE_EQUAL(n_out,0ul); |
706 | |
707 | // Ghost must populated because we synchronized them |
708 | if (k > 524288) |
709 | { |
710 | BOOST_REQUIRE(nl_cnt != 0); |
711 | BOOST_REQUIRE(l_cnt > nl_cnt); |
712 | } |
713 | |
714 | // Sum all the particles inside the domain |
715 | v_cl.sum(l_cnt); |
716 | v_cl.execute(); |
717 | BOOST_REQUIRE_EQUAL(l_cnt,(size_t)k); |
718 | |
719 | l_cnt = 0; |
720 | nl_cnt = 0; |
721 | |
722 | // Iterate only on the ghost particles |
723 | auto itg = vd.getGhostIterator(); |
724 | count_local_n_local<3,vector_dist<3,float, Point_test<float> > >(vd,itg,bc,box,dom_ext,l_cnt,nl_cnt,n_out); |
725 | |
726 | // No particle on the ghost must be inside the domain |
727 | BOOST_REQUIRE_EQUAL(l_cnt,0ul); |
728 | |
729 | // Ghost must be populated |
730 | if (k > 524288) |
731 | { |
732 | BOOST_REQUIRE(nl_cnt != 0); |
733 | } |
734 | } |
735 | } |
736 | |
737 | void test_random_walk(size_t opt) |
738 | { |
739 | Vcluster<> & v_cl = create_vcluster(); |
740 | |
741 | // set the seed |
742 | // create the random generator engine |
743 | std::srand(v_cl.getProcessUnitID()); |
744 | std::default_random_engine eg; |
745 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
746 | |
747 | size_t nsz[] = {0,32,4}; |
748 | nsz[0] = 65536 * v_cl.getProcessingUnits(); |
749 | |
750 | print_test_v( "Testing 3D random walk vector k<=" ,nsz[0]); |
751 | |
752 | // 3D test |
753 | for (size_t i = 0 ; i < 3 ; i++ ) |
754 | { |
755 | size_t k = nsz[i]; |
756 | |
757 | BOOST_TEST_CHECKPOINT( "Testing 3D random walk vector k=" << k ); |
758 | |
759 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
760 | |
761 | // Boundary conditions |
762 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
763 | |
764 | // factor |
765 | float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f); |
766 | |
767 | // ghost |
768 | Ghost<3,float> ghost(0.01 / factor); |
769 | |
770 | // Distributed vector |
771 | vector_dist<3,float, Point_test<float> > vd(k,box,bc,ghost); |
772 | |
773 | auto it = vd.getIterator(); |
774 | |
775 | while (it.isNext()) |
776 | { |
777 | auto key = it.get(); |
778 | |
779 | vd.getPos(key)[0] = ud(eg); |
780 | vd.getPos(key)[1] = ud(eg); |
781 | vd.getPos(key)[2] = ud(eg); |
782 | |
783 | ++it; |
784 | } |
785 | |
786 | vd.map(); |
787 | |
788 | // 10 step random walk |
789 | |
790 | for (size_t j = 0 ; j < 4 ; j++) |
791 | { |
792 | auto it = vd.getDomainIterator(); |
793 | |
794 | while (it.isNext()) |
795 | { |
796 | auto key = it.get(); |
797 | |
798 | vd.getPos(key)[0] += 0.02 * ud(eg); |
799 | vd.getPos(key)[1] += 0.02 * ud(eg); |
800 | vd.getPos(key)[2] += 0.02 * ud(eg); |
801 | |
802 | ++it; |
803 | } |
804 | |
805 | vd.map(opt); |
806 | |
807 | vd.ghost_get<0>(); |
808 | |
809 | // Count the local particles and check that the total number is consistent |
810 | size_t cnt = total_n_part_lc(vd,bc); |
811 | |
812 | BOOST_REQUIRE_EQUAL((size_t)k,cnt); |
813 | } |
814 | } |
815 | } |
816 | |
817 | BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_random_walk ) |
818 | { |
819 | test_random_walk(NONE); |
820 | } |
821 | |
822 | BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_random_walk_local_map ) |
823 | { |
824 | test_random_walk(MAP_LOCAL); |
825 | } |
826 | |
827 | BOOST_AUTO_TEST_CASE( vector_dist_periodic_map ) |
828 | { |
829 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
830 | |
831 | // Boundary conditions |
832 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
833 | |
834 | // factor |
835 | float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f); |
836 | |
837 | // ghost |
838 | Ghost<3,float> ghost(0.05 / factor); |
839 | |
840 | // Distributed vector |
841 | vector_dist<3,float, Point_test<float> > vd(1,box,bc,ghost); |
842 | |
843 | // put particles al 1.0, check that they go to 0.0 |
844 | |
845 | auto it = vd.getIterator(); |
846 | |
847 | while (it.isNext()) |
848 | { |
849 | auto key = it.get(); |
850 | |
851 | vd.getPos(key)[0] = 1.0; |
852 | vd.getPos(key)[1] = 1.0; |
853 | vd.getPos(key)[2] = 1.0; |
854 | |
855 | ++it; |
856 | } |
857 | |
858 | vd.map(); |
859 | |
860 | auto it2 = vd.getIterator(); |
861 | |
862 | while (it2.isNext()) |
863 | { |
864 | auto key = it2.get(); |
865 | |
866 | float f = vd.getPos(key)[0]; |
867 | BOOST_REQUIRE_EQUAL(f, 0.0); |
868 | f = vd.getPos(key)[1]; |
869 | BOOST_REQUIRE_EQUAL(f, 0.0); |
870 | f = vd.getPos(key)[2]; |
871 | BOOST_REQUIRE_EQUAL(f, 0.0); |
872 | |
873 | ++it2; |
874 | } |
875 | } |
876 | |
877 | |
878 | BOOST_AUTO_TEST_CASE( vector_dist_not_periodic_map ) |
879 | { |
880 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
881 | |
882 | // Boundary conditions |
883 | size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
884 | |
885 | // factor |
886 | float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f); |
887 | |
888 | // ghost |
889 | Ghost<3,float> ghost(0.05 / factor); |
890 | |
891 | // Distributed vector |
892 | vector_dist<3,float, Point_test<float> > vd(1,box,bc,ghost); |
893 | |
894 | // put particles al 1.0, check that they go to 0.0 |
895 | |
896 | auto it = vd.getIterator(); |
897 | |
898 | while (it.isNext()) |
899 | { |
900 | auto key = it.get(); |
901 | |
902 | vd.getPos(key)[0] = 1.0; |
903 | vd.getPos(key)[1] = 1.0; |
904 | vd.getPos(key)[2] = 1.0; |
905 | |
906 | ++it; |
907 | } |
908 | |
909 | vd.map(); |
910 | |
911 | auto it2 = vd.getIterator(); |
912 | |
913 | while (it2.isNext()) |
914 | { |
915 | auto key = it2.get(); |
916 | |
917 | float f = vd.getPos(key)[0]; |
918 | BOOST_REQUIRE_EQUAL(f, 1.0); |
919 | f = vd.getPos(key)[1]; |
920 | BOOST_REQUIRE_EQUAL(f, 1.0); |
921 | f = vd.getPos(key)[2]; |
922 | BOOST_REQUIRE_EQUAL(f, 1.0); |
923 | |
924 | ++it2; |
925 | } |
926 | } |
927 | |
928 | BOOST_AUTO_TEST_CASE( vector_dist_out_of_bound_policy ) |
929 | { |
930 | Vcluster<> & v_cl = create_vcluster(); |
931 | |
932 | if (v_cl.getProcessingUnits() > 8) |
933 | return; |
934 | |
935 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
936 | |
937 | // Boundary conditions |
938 | size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
939 | |
940 | // factor |
941 | float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f); |
942 | |
943 | // ghost |
944 | Ghost<3,float> ghost(0.05 / factor); |
945 | |
946 | // Distributed vector |
947 | vector_dist<3,float, Point_test<float> > vd(100,box,bc,ghost); |
948 | |
949 | // put particles at out of the boundary, they must be detected and and killed |
950 | |
951 | auto it = vd.getIterator(); |
952 | |
953 | size_t cnt = 0; |
954 | |
955 | while (it.isNext()) |
956 | { |
957 | auto key = it.get(); |
958 | |
959 | if (cnt < 1) |
960 | { |
961 | vd.getPos(key)[0] = -0.06; |
962 | vd.getPos(key)[1] = -0.06; |
963 | vd.getPos(key)[2] = -0.06; |
964 | } |
965 | else |
966 | { |
967 | vd.getPos(key)[0] = 0.06; |
968 | vd.getPos(key)[1] = 0.06; |
969 | vd.getPos(key)[2] = 0.06; |
970 | } |
971 | |
972 | cnt++; |
973 | ++it; |
974 | } |
975 | |
976 | vd.map(); |
977 | |
978 | // Particles out of the boundary are killed |
979 | |
980 | size_t cnt_l = vd.size_local(); |
981 | |
982 | v_cl.sum(cnt_l); |
983 | v_cl.execute(); |
984 | |
985 | BOOST_REQUIRE_EQUAL(cnt_l,100-v_cl.getProcessingUnits()); |
986 | } |
987 | |
988 | void Test_interacting(Box<3,float> & box) |
989 | { |
990 | Vcluster<> & v_cl = create_vcluster(); |
991 | |
992 | if (v_cl.getProcessingUnits() > 8) |
993 | return; |
994 | |
995 | // set the seed |
996 | // create the random generator engine |
997 | std::srand(v_cl.getProcessUnitID()); |
998 | std::default_random_engine eg; |
999 | std::uniform_real_distribution<float> ud(-0.5f, 0.5f); |
1000 | |
1001 | size_t nsz[] = {0,32,4}; |
1002 | |
1003 | #ifdef TEST_COVERAGE_MODE |
1004 | nsz[0] = 5536 * v_cl.getProcessingUnits(); |
1005 | #else |
1006 | nsz[0] = 65536 * v_cl.getProcessingUnits(); |
1007 | #endif |
1008 | |
1009 | print_test_v("Testing 3D random walk interacting particles vector k=" , nsz[0]); |
1010 | |
1011 | // 3D test |
1012 | for (size_t i = 0 ; i < 3 ; i++ ) |
1013 | { |
1014 | size_t k = nsz[i]; |
1015 | |
1016 | BOOST_TEST_CHECKPOINT( "Testing 3D random walk interacting particles vector k=" << k ); |
1017 | |
1018 | // Boundary conditions |
1019 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
1020 | |
1021 | // factor |
1022 | float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f); |
1023 | |
1024 | // interaction radius |
1025 | float r_cut = 0.01 / factor; |
1026 | |
1027 | // ghost |
1028 | Ghost<3,float> ghost(r_cut); |
1029 | |
1030 | // Distributed vector |
1031 | vector_dist<3,float, Point_test<float> > vd(k,box,bc,ghost); |
1032 | |
1033 | auto it = vd.getIterator(); |
1034 | |
1035 | while (it.isNext()) |
1036 | { |
1037 | auto key = it.get(); |
1038 | |
1039 | vd.getPos(key)[0] = ud(eg); |
1040 | vd.getPos(key)[1] = ud(eg); |
1041 | vd.getPos(key)[2] = ud(eg); |
1042 | |
1043 | ++it; |
1044 | } |
1045 | |
1046 | vd.map(); |
1047 | |
1048 | // 4 step random walk |
1049 | |
1050 | for (size_t j = 0 ; j < 4 ; j++) |
1051 | { |
1052 | auto it = vd.getDomainIterator(); |
1053 | |
1054 | // Move the particles |
1055 | |
1056 | while (it.isNext()) |
1057 | { |
1058 | auto key = it.get(); |
1059 | |
1060 | vd.getPos(key)[0] += 0.02 * ud(eg); |
1061 | vd.getPos(key)[1] += 0.02 * ud(eg); |
1062 | vd.getPos(key)[2] += 0.02 * ud(eg); |
1063 | |
1064 | ++it; |
1065 | } |
1066 | |
1067 | vd.map(); |
1068 | vd.ghost_get<0>(); |
1069 | |
1070 | // get the cell list with a cutoff radius |
1071 | |
1072 | bool error = false; |
1073 | |
1074 | auto NN = vd.getCellList(0.01 / factor); |
1075 | |
1076 | // iterate across the domain particle |
1077 | |
1078 | auto it2 = vd.getDomainIterator(); |
1079 | |
1080 | while (it2.isNext()) |
1081 | { |
1082 | auto p = it2.get(); |
1083 | |
1084 | Point<3,float> xp = vd.getPos(p); |
1085 | |
1086 | auto Np = NN.getCellIterator(NN.getCell(xp)); |
1087 | |
1088 | while (Np.isNext()) |
1089 | { |
1090 | auto q = Np.get(); |
1091 | |
1092 | // repulsive |
1093 | |
1094 | Point<3,float> xq = vd.getPos(q); |
1095 | Point<3,float> f = (xp - xq); |
1096 | |
1097 | float distance = f.norm(); |
1098 | |
1099 | // Particle should be inside 2 * r_cut range |
1100 | |
1101 | if (distance > 2*r_cut*sqrt(2)) |
1102 | error = true; |
1103 | |
1104 | ++Np; |
1105 | } |
1106 | |
1107 | ++it2; |
1108 | } |
1109 | |
1110 | // Error |
1111 | |
1112 | BOOST_REQUIRE_EQUAL(error,false); |
1113 | |
1114 | // Count the local particles and check that the total number is consistent |
1115 | size_t cnt = total_n_part_lc(vd,bc); |
1116 | |
1117 | BOOST_REQUIRE_EQUAL((size_t)k,cnt); |
1118 | } |
1119 | } |
1120 | } |
1121 | |
1122 | BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_interacting_particles ) |
1123 | { |
1124 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1125 | Test_interacting(box); |
1126 | |
1127 | Box<3,float> box2({-0.5,-0.5,-0.5},{0.5,0.5,0.5}); |
1128 | Test_interacting(box2); |
1129 | } |
1130 | |
1131 | BOOST_AUTO_TEST_CASE( vector_dist_grid_iterator ) |
1132 | { |
1133 | #ifdef TEST_COVERAGE_MODE |
1134 | long int k = 32*32*32*create_vcluster().getProcessingUnits(); |
1135 | #else |
1136 | long int k = 64*64*64*create_vcluster().getProcessingUnits(); |
1137 | #endif |
1138 | k = std::pow(k, 1/3.); |
1139 | |
1140 | long int big_step = k / 30; |
1141 | big_step = (big_step == 0)?1:big_step; |
1142 | long int small_step = 21; |
1143 | |
1144 | print_test( "Testing vector grid iterator list k<=" ,k); |
1145 | |
1146 | // 3D test |
1147 | for ( ; k > 8*big_step ; k-= (k > 2*big_step)?big_step:small_step ) |
1148 | { |
1149 | Vcluster<> & v_cl = create_vcluster(); |
1150 | |
1151 | const size_t Ng = k; |
1152 | |
1153 | // we create a 128x128x128 Grid iterator |
1154 | size_t sz[3] = {Ng,Ng,Ng}; |
1155 | |
1156 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1157 | |
1158 | // Boundary conditions |
1159 | size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
1160 | |
1161 | // ghost |
1162 | Ghost<3,float> ghost(1.0/(Ng-2)); |
1163 | |
1164 | // Distributed vector |
1165 | vector_dist<3,float, Point_test<float> > vd(0,box,bc,ghost); |
1166 | |
1167 | // Put particles on a grid creating a Grid iterator |
1168 | auto it = vd.getGridIterator(sz); |
1169 | |
1170 | while (it.isNext()) |
1171 | { |
1172 | vd.add(); |
1173 | |
1174 | auto key = it.get(); |
1175 | |
1176 | vd.getLastPos()[0] = key.get(0) * it.getSpacing(0); |
1177 | vd.getLastPos()[1] = key.get(1) * it.getSpacing(1); |
1178 | vd.getLastPos()[2] = key.get(2) * it.getSpacing(2); |
1179 | |
1180 | ++it; |
1181 | } |
1182 | |
1183 | BOOST_REQUIRE_EQUAL(it.getSpacing(0),1.0f/(Ng-1)); |
1184 | BOOST_REQUIRE_EQUAL(it.getSpacing(1),1.0f/(Ng-1)); |
1185 | BOOST_REQUIRE_EQUAL(it.getSpacing(2),1.0f/(Ng-1)); |
1186 | |
1187 | // distribute particles and sync ghost |
1188 | vd.map(); |
1189 | |
1190 | |
1191 | // Check that the sum of all the particles is the grid size |
1192 | size_t total = vd.size_local(); |
1193 | v_cl.sum(total); |
1194 | v_cl.execute(); |
1195 | |
1196 | BOOST_REQUIRE_EQUAL(total,(Ng) * (Ng) * (Ng)); |
1197 | } |
1198 | } |
1199 | |
1200 | BOOST_AUTO_TEST_CASE( vector_dist_cell_verlet_test ) |
1201 | { |
1202 | #ifdef TEST_COVERAGE_MODE |
1203 | long int k = 16*16*16*create_vcluster().getProcessingUnits(); |
1204 | #else |
1205 | long int k = 64*64*64*create_vcluster().getProcessingUnits(); |
1206 | #endif |
1207 | k = std::pow(k, 1/3.); |
1208 | |
1209 | long int big_step = k / 30; |
1210 | big_step = (big_step == 0)?1:big_step; |
1211 | long int small_step = 21; |
1212 | |
1213 | print_test( "Testing cell and verlet list k<=" ,k); |
1214 | |
1215 | // 3D test |
1216 | for ( ; k > 8*big_step ; k-= (k > 2*big_step)?big_step:small_step ) |
1217 | { |
1218 | Vcluster<> & v_cl = create_vcluster(); |
1219 | |
1220 | const size_t Ng = k; |
1221 | |
1222 | // we create a 128x128x128 Grid iterator |
1223 | size_t sz[3] = {Ng,Ng,Ng}; |
1224 | |
1225 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1226 | |
1227 | // Boundary conditions |
1228 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
1229 | |
1230 | float spacing = 1.0/Ng; |
1231 | float first_dist = spacing; |
1232 | float second_dist = sqrt(2.0*spacing*spacing); |
1233 | float third_dist = sqrt(3.0 * spacing*spacing); |
1234 | |
1235 | // ghost |
1236 | Ghost<3,float> ghost(third_dist*1.1); |
1237 | |
1238 | // Distributed vector |
1239 | vector_dist<3,float, Point_test<float> > vd(0,box,bc,ghost); |
1240 | |
1241 | // Put particles on a grid creating a Grid iterator |
1242 | auto it = vd.getGridIterator(sz); |
1243 | |
1244 | while (it.isNext()) |
1245 | { |
1246 | vd.add(); |
1247 | |
1248 | auto key = it.get(); |
1249 | |
1250 | vd.getLastPos()[0] = key.get(0) * it.getSpacing(0); |
1251 | vd.getLastPos()[1] = key.get(1) * it.getSpacing(1); |
1252 | vd.getLastPos()[2] = key.get(2) * it.getSpacing(2); |
1253 | |
1254 | ++it; |
1255 | } |
1256 | |
1257 | BOOST_REQUIRE_EQUAL(it.getSpacing(0),1.0f/Ng); |
1258 | BOOST_REQUIRE_EQUAL(it.getSpacing(1),1.0f/Ng); |
1259 | BOOST_REQUIRE_EQUAL(it.getSpacing(2),1.0f/Ng); |
1260 | |
1261 | // distribute particles and sync ghost |
1262 | vd.map(); |
1263 | |
1264 | // Check that the sum of all the particles is the grid size |
1265 | size_t total = vd.size_local(); |
1266 | v_cl.sum(total); |
1267 | v_cl.execute(); |
1268 | |
1269 | BOOST_REQUIRE_EQUAL(total,(Ng) * (Ng) * (Ng)); |
1270 | |
1271 | vd.ghost_get<0>(); |
1272 | |
1273 | // calculate the distance of the first, second and third neighborhood particle |
1274 | // Consider that they are on a regular grid |
1275 | |
1276 | // add a 5% to dist |
1277 | |
1278 | first_dist += first_dist * 0.05; |
1279 | second_dist += second_dist * 0.05; |
1280 | third_dist += third_dist * 0.05; |
1281 | |
1282 | // Create a verlet list for each particle |
1283 | |
1284 | VerletList<3,float,Mem_fast<>,shift<3,float>> verlet = vd.getVerlet(third_dist); |
1285 | |
1286 | bool correct = true; |
1287 | |
1288 | BOOST_REQUIRE_EQUAL(vd.size_local(),verlet.size()); |
1289 | |
1290 | // for each particle |
1291 | for (size_t i = 0 ; i < verlet.size() ; i++) |
1292 | { |
1293 | // first NN |
1294 | size_t first_NN = 0; |
1295 | size_t second_NN = 0; |
1296 | size_t third_NN = 0; |
1297 | |
1298 | Point<3,float> p = vd.getPos(i); |
1299 | |
1300 | // for each neighborhood particle |
1301 | for (size_t j = 0 ; j < verlet.getNNPart(i) ; j++) |
1302 | { |
1303 | Point<3,float> q = vd.getPos(verlet.get(i,j)); |
1304 | |
1305 | float dist = p.distance(q); |
1306 | |
1307 | if (dist <= first_dist) |
1308 | first_NN++; |
1309 | else if (dist <= second_dist) |
1310 | second_NN++; |
1311 | else |
1312 | third_NN++; |
1313 | } |
1314 | |
1315 | correct &= (first_NN == 7); |
1316 | correct &= (second_NN == 12); |
1317 | correct &= (third_NN == 8); |
1318 | } |
1319 | |
1320 | BOOST_REQUIRE_EQUAL(correct,true); |
1321 | } |
1322 | } |
1323 | |
1324 | |
1325 | BOOST_AUTO_TEST_CASE( vector_dist_periodic_map_list ) |
1326 | { |
1327 | Vcluster<> & v_cl = create_vcluster(); |
1328 | |
1329 | if (v_cl.getProcessingUnits() > 3) |
1330 | return; |
1331 | |
1332 | // set the seed |
1333 | // create the random generator engine |
1334 | std::srand(v_cl.getProcessUnitID()); |
1335 | std::default_random_engine eg; |
1336 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
1337 | |
1338 | #ifdef TEST_COVERAGE_MODE |
1339 | long int k = 24288 * v_cl.getProcessingUnits(); |
1340 | #else |
1341 | long int k = 524288 * v_cl.getProcessingUnits(); |
1342 | #endif |
1343 | |
1344 | long int big_step = k / 4; |
1345 | big_step = (big_step == 0)?1:big_step; |
1346 | |
1347 | print_test("Testing 3D periodic vector with map_list k=" ,k); |
1348 | BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector with map_list k=" << k ); |
1349 | |
1350 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1351 | |
1352 | // Boundary conditions |
1353 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
1354 | |
1355 | // factor |
1356 | float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f); |
1357 | |
1358 | // ghost |
1359 | Ghost<3,float> ghost(0.05 / factor); |
1360 | |
1361 | // ghost2 (a little bigger because of round off error) |
1362 | Ghost<3,float> ghost2(0.05001 / factor); |
1363 | |
1364 | typedef aggregate<float,float,std::list<int>,openfpm::vector<size_t>,openfpm::vector<Point_test<float>>> part_prop; |
1365 | |
1366 | // Distributed vector |
1367 | vector_dist<3,float, part_prop > vd(k,box,bc,ghost); |
1368 | |
1369 | auto it = vd.getIterator(); |
1370 | |
1371 | while (it.isNext()) |
1372 | { |
1373 | auto key = it.get(); |
1374 | |
1375 | vd.getPos(key)[0] = ud(eg); |
1376 | vd.getPos(key)[1] = ud(eg); |
1377 | vd.getPos(key)[2] = ud(eg); |
1378 | |
1379 | // Fill some properties randomly |
1380 | |
1381 | vd.getProp<2>(key).push_back(1); |
1382 | vd.getProp<2>(key).push_back(2); |
1383 | vd.getProp<2>(key).push_back(3); |
1384 | vd.getProp<2>(key).push_back(4); |
1385 | |
1386 | vd.getProp<3>(key).add(1); |
1387 | vd.getProp<3>(key).add(2); |
1388 | vd.getProp<3>(key).add(3); |
1389 | vd.getProp<3>(key).add(4); |
1390 | |
1391 | vd.getProp<4>(key).add(); |
1392 | vd.getProp<4>(key).add(); |
1393 | vd.getProp<4>(key).add(); |
1394 | vd.getProp<4>(key).add(); |
1395 | |
1396 | ++it; |
1397 | } |
1398 | |
1399 | vd.map_list<0,1>(); |
1400 | |
1401 | // sync the ghost |
1402 | vd.ghost_get<0>(); |
1403 | |
1404 | // Domain + ghost |
1405 | Box<3,float> dom_ext = box; |
1406 | dom_ext.enlarge(ghost2); |
1407 | |
1408 | // Iterate on all particles domain + ghost |
1409 | size_t l_cnt = 0; |
1410 | size_t nl_cnt = 0; |
1411 | size_t n_out = 0; |
1412 | |
1413 | auto it2 = vd.getIterator(); |
1414 | count_local_n_local<3,vector_dist<3,float, part_prop>>(vd,it2,bc,box,dom_ext,l_cnt,nl_cnt,n_out); |
1415 | |
1416 | // No particles should be out of domain + ghost |
1417 | BOOST_REQUIRE_EQUAL(n_out,0ul); |
1418 | |
1419 | // Ghost must populated because we synchronized them |
1420 | if (k > 524288) |
1421 | { |
1422 | BOOST_REQUIRE(nl_cnt != 0); |
1423 | BOOST_REQUIRE(l_cnt > nl_cnt); |
1424 | } |
1425 | |
1426 | // Sum all the particles inside the domain |
1427 | v_cl.sum(l_cnt); |
1428 | v_cl.execute(); |
1429 | BOOST_REQUIRE_EQUAL(l_cnt,(size_t)k); |
1430 | |
1431 | l_cnt = 0; |
1432 | nl_cnt = 0; |
1433 | |
1434 | // Iterate only on the ghost particles |
1435 | auto itg = vd.getGhostIterator(); |
1436 | count_local_n_local<3, vector_dist<3,float,part_prop> >(vd,itg,bc,box,dom_ext,l_cnt,nl_cnt,n_out); |
1437 | |
1438 | // No particle on the ghost must be inside the domain |
1439 | BOOST_REQUIRE_EQUAL(l_cnt,0ul); |
1440 | |
1441 | // Ghost must be populated |
1442 | if (k > 524288) |
1443 | { |
1444 | BOOST_REQUIRE(nl_cnt != 0); |
1445 | } |
1446 | } |
1447 | |
1448 | |
1449 | BOOST_AUTO_TEST_CASE( vector_dist_ghost_with_ghost_buffering ) |
1450 | { |
1451 | Vcluster<> & v_cl = create_vcluster(); |
1452 | |
1453 | if (v_cl.getProcessingUnits() > 3) |
1454 | return; |
1455 | |
1456 | // set the seed |
1457 | // create the random generator engine |
1458 | std::srand(v_cl.getProcessUnitID()); |
1459 | std::default_random_engine eg; |
1460 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
1461 | |
1462 | #ifdef TEST_COVERAGE_MODE |
1463 | long int k = 24288 * v_cl.getProcessingUnits(); |
1464 | #else |
1465 | long int k = 524288 * v_cl.getProcessingUnits(); |
1466 | #endif |
1467 | |
1468 | long int big_step = k / 4; |
1469 | big_step = (big_step == 0)?1:big_step; |
1470 | |
1471 | print_test("Testing 3D periodic vector with ghost buffering k=" ,k); |
1472 | BOOST_TEST_CHECKPOINT( "Testing 3D periodic with ghost buffering k=" << k ); |
1473 | |
1474 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1475 | |
1476 | // Boundary conditions |
1477 | size_t bc[3]={NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
1478 | |
1479 | // ghost |
1480 | Ghost<3,float> ghost(0.1); |
1481 | |
1482 | typedef aggregate<float,float,float> part_prop; |
1483 | |
1484 | // Distributed vector |
1485 | vector_dist<3,float, part_prop > vd(k,box,bc,ghost); |
1486 | |
1487 | auto it = vd.getIterator(); |
1488 | |
1489 | while (it.isNext()) |
1490 | { |
1491 | auto key = it.get(); |
1492 | |
1493 | vd.getPos(key)[0] = ud(eg); |
1494 | vd.getPos(key)[1] = ud(eg); |
1495 | vd.getPos(key)[2] = ud(eg); |
1496 | |
1497 | // Fill some properties randomly |
1498 | |
1499 | vd.getProp<0>(key) = 0.0; |
1500 | vd.getProp<1>(key) = vd.getPos(key)[0]; |
1501 | vd.getProp<2>(key) = vd.getPos(key)[0]*vd.getPos(key)[0]; |
1502 | |
1503 | ++it; |
1504 | } |
1505 | |
1506 | vd.map(); |
1507 | |
1508 | // sync the ghost |
1509 | vd.ghost_get<0,1,2>(); |
1510 | |
1511 | bool ret = true; |
1512 | auto it2 = vd.getGhostIterator(); |
1513 | while (it2.isNext()) |
1514 | { |
1515 | auto key = it2.get(); |
1516 | |
1517 | ret &= vd.getProp<1>(key) == vd.getPos(key)[0]; |
1518 | ret &= vd.getProp<2>(key) == vd.getPos(key)[0] * vd.getPos(key)[0]; |
1519 | |
1520 | ++it2; |
1521 | } |
1522 | |
1523 | BOOST_REQUIRE_EQUAL(ret,true); |
1524 | |
1525 | for (size_t i = 0 ; i < 10 ; i++) |
1526 | { |
1527 | auto it = vd.getDomainIterator(); |
1528 | |
1529 | while (it.isNext()) |
1530 | { |
1531 | auto key = it.get(); |
1532 | |
1533 | vd.getPos(key)[1] = ud(eg); |
1534 | vd.getPos(key)[2] = ud(eg); |
1535 | |
1536 | // Fill some properties randomly |
1537 | |
1538 | vd.getProp<0>(key) = i; |
1539 | |
1540 | ++it; |
1541 | } |
1542 | |
1543 | if (i % 2 == 0) |
1544 | vd.ghost_get<0>(SKIP_LABELLING); |
1545 | else |
1546 | vd.ghost_get<0>(SKIP_LABELLING | NO_CHANGE_ELEMENTS ); |
1547 | |
1548 | auto it2 = vd.getGhostIterator(); |
1549 | bool ret = true; |
1550 | |
1551 | while (it2.isNext()) |
1552 | { |
1553 | auto key = it2.get(); |
1554 | |
1555 | ret &= vd.getProp<0>(key) == i; |
1556 | ret &= vd.getProp<1>(key) == vd.getPos(key)[0]; |
1557 | ret &= vd.getProp<2>(key) == vd.getPos(key)[0] * vd.getPos(key)[0]; |
1558 | |
1559 | ++it2; |
1560 | } |
1561 | |
1562 | BOOST_REQUIRE_EQUAL(ret,true); |
1563 | } |
1564 | |
1565 | vd.map(); |
1566 | vd.ghost_get<0,1,2>(); |
1567 | |
1568 | // shift the particle position by 1.0 |
1569 | |
1570 | it = vd.getGhostIterator(); |
1571 | while (it.isNext()) |
1572 | { |
1573 | // Particle p |
1574 | auto p = it.get(); |
1575 | |
1576 | // we shift down he particles |
1577 | vd.getPos(p)[0] = 10.0; |
1578 | |
1579 | // we shift |
1580 | vd.getPos(p)[1] = 17.0; |
1581 | |
1582 | // next particle |
1583 | ++it; |
1584 | } |
1585 | |
1586 | for (size_t i = 0 ; i < 10 ; i++) |
1587 | { |
1588 | auto it = vd.getDomainIterator(); |
1589 | |
1590 | while (it.isNext()) |
1591 | { |
1592 | auto key = it.get(); |
1593 | |
1594 | vd.getPos(key)[1] = ud(eg); |
1595 | vd.getPos(key)[2] = ud(eg); |
1596 | |
1597 | // Fill some properties randomly |
1598 | |
1599 | vd.getProp<0>(key) = i; |
1600 | vd.getProp<1>(key) = vd.getPos(key)[0]; |
1601 | vd.getProp<2>(key) = vd.getPos(key)[0]*vd.getPos(key)[0]; |
1602 | |
1603 | ++it; |
1604 | } |
1605 | |
1606 | vd.ghost_get<0>(SKIP_LABELLING | NO_POSITION); |
1607 | |
1608 | auto it2 = vd.getGhostIterator(); |
1609 | bool ret = true; |
1610 | |
1611 | while (it2.isNext()) |
1612 | { |
1613 | // Particle p |
1614 | auto p = it.get(); |
1615 | |
1616 | ret &= vd.getPos(p)[0] == 10.0; |
1617 | |
1618 | // we shift |
1619 | ret &= vd.getPos(p)[1] == 17.0; |
1620 | |
1621 | // next particle |
1622 | ++it2; |
1623 | } |
1624 | |
1625 | BOOST_REQUIRE_EQUAL(ret,true); |
1626 | } |
1627 | } |
1628 | |
1629 | |
1630 | |
1631 | BOOST_AUTO_TEST_CASE( vector_dist_ghost_put ) |
1632 | { |
1633 | Vcluster<> & v_cl = create_vcluster(); |
1634 | |
1635 | long int k = 25*25*25*create_vcluster().getProcessingUnits(); |
1636 | k = std::pow(k, 1/3.); |
1637 | |
1638 | if (v_cl.getProcessingUnits() > 48) |
1639 | return; |
1640 | |
1641 | print_test("Testing 3D periodic ghost put k=" ,k); |
1642 | BOOST_TEST_CHECKPOINT( "Testing 3D periodic ghost put k=" << k ); |
1643 | |
1644 | long int big_step = k / 30; |
1645 | big_step = (big_step == 0)?1:big_step; |
1646 | long int small_step = 21; |
1647 | |
1648 | // 3D test |
1649 | for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step ) |
1650 | { |
1651 | float r_cut = 1.3 / k; |
1652 | float r_g = 1.5 / k; |
1653 | |
1654 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1655 | |
1656 | // Boundary conditions |
1657 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
1658 | |
1659 | // ghost |
1660 | Ghost<3,float> ghost(r_g); |
1661 | |
1662 | typedef aggregate<float> part_prop; |
1663 | |
1664 | // Distributed vector |
1665 | vector_dist<3,float, part_prop > vd(0,box,bc,ghost); |
1666 | |
1667 | auto it = vd.getGridIterator({(size_t)k,(size_t)k,(size_t)k}); |
1668 | |
1669 | while (it.isNext()) |
1670 | { |
1671 | auto key = it.get(); |
1672 | |
1673 | vd.add(); |
1674 | |
1675 | vd.getLastPosWrite()[0] = key.get(0)*it.getSpacing(0); |
1676 | vd.getLastPosWrite()[1] = key.get(1)*it.getSpacing(1); |
1677 | vd.getLastPosWrite()[2] = key.get(2)*it.getSpacing(2); |
1678 | |
1679 | // Fill some properties randomly |
1680 | |
1681 | vd.getLastPropWrite<0>() = 0.0; |
1682 | |
1683 | ++it; |
1684 | } |
1685 | |
1686 | vd.map(); |
1687 | |
1688 | // sync the ghost |
1689 | vd.ghost_get<0>(); |
1690 | |
1691 | { |
1692 | auto NN = vd.getCellList(r_cut); |
1693 | float a = 1.0f*k*k; |
1694 | |
1695 | // run trough all the particles + ghost |
1696 | |
1697 | auto it2 = vd.getDomainIterator(); |
1698 | |
1699 | while (it2.isNext()) |
1700 | { |
1701 | // particle p |
1702 | auto p = it2.get(); |
1703 | Point<3,float> xp = vd.getPos(p); |
1704 | |
1705 | // Get an iterator over the neighborhood particles of p |
1706 | auto Np = NN.getNNIterator<NO_CHECK>(NN.getCell(xp)); |
1707 | |
1708 | // For each neighborhood particle ... |
1709 | while (Np.isNext()) |
1710 | { |
1711 | auto q = Np.get(); |
1712 | Point<3,float> xq = vd.getPosRead(q); |
1713 | |
1714 | float dist = xp.distance(xq); |
1715 | |
1716 | if (dist < r_cut) |
1717 | vd.getPropWrite<0>(q) += a*(-dist*dist+r_cut*r_cut); |
1718 | |
1719 | ++Np; |
1720 | } |
1721 | |
1722 | ++it2; |
1723 | } |
1724 | |
1725 | vd.ghost_put<add_,0>(); |
1726 | |
1727 | bool ret = true; |
1728 | auto it3 = vd.getDomainIterator(); |
1729 | |
1730 | float constant = vd.getProp<0>(it3.get()); |
1731 | float eps = 0.001; |
1732 | |
1733 | while (it3.isNext()) |
1734 | { |
1735 | float constant2 = vd.getProp<0>(it3.get()); |
1736 | if (fabs(constant - constant2)/constant > eps) |
1737 | { |
1738 | Point<3,float> p = vd.getPosRead(it3.get()); |
1739 | |
1740 | std::cout << p.toString() << " " << constant2 << "/" << constant << " " << v_cl.getProcessUnitID() << std::endl; |
1741 | ret = false; |
1742 | break; |
1743 | } |
1744 | |
1745 | ++it3; |
1746 | } |
1747 | BOOST_REQUIRE_EQUAL(ret,true); |
1748 | } |
1749 | |
1750 | auto itp = vd.getDomainAndGhostIterator(); |
1751 | while (itp.isNext()) |
1752 | { |
1753 | auto key = itp.get(); |
1754 | |
1755 | vd.getPropWrite<0>(key) = 0.0; |
1756 | |
1757 | ++itp; |
1758 | } |
1759 | |
1760 | { |
1761 | auto NN = vd.getCellList(r_cut); |
1762 | float a = 1.0f*k*k; |
1763 | |
1764 | // run trough all the particles + ghost |
1765 | |
1766 | auto it2 = vd.getDomainIterator(); |
1767 | |
1768 | while (it2.isNext()) |
1769 | { |
1770 | // particle p |
1771 | auto p = it2.get(); |
1772 | Point<3,float> xp = vd.getPosRead(p); |
1773 | |
1774 | // Get an iterator over the neighborhood particles of p |
1775 | auto Np = NN.getNNIterator<NO_CHECK>(NN.getCell(xp)); |
1776 | |
1777 | // For each neighborhood particle ... |
1778 | while (Np.isNext()) |
1779 | { |
1780 | auto q = Np.get(); |
1781 | Point<3,float> xq = vd.getPosRead(q); |
1782 | |
1783 | float dist = xp.distance(xq); |
1784 | |
1785 | if (dist < r_cut) |
1786 | vd.getPropWrite<0>(q) += a*(-dist*dist+r_cut*r_cut); |
1787 | |
1788 | ++Np; |
1789 | } |
1790 | |
1791 | ++it2; |
1792 | } |
1793 | |
1794 | vd.ghost_put<add_,0>(); |
1795 | |
1796 | bool ret = true; |
1797 | auto it3 = vd.getDomainIterator(); |
1798 | |
1799 | float constant = vd.getPropRead<0>(it3.get()); |
1800 | float eps = 0.001; |
1801 | |
1802 | while (it3.isNext()) |
1803 | { |
1804 | float constant2 = vd.getPropRead<0>(it3.get()); |
1805 | if (fabs(constant - constant2)/constant > eps) |
1806 | { |
1807 | Point<3,float> p = vd.getPosRead(it3.get()); |
1808 | |
1809 | std::cout << p.toString() << " " << constant2 << "/" << constant << " " << v_cl.getProcessUnitID() << std::endl; |
1810 | ret = false; |
1811 | break; |
1812 | } |
1813 | |
1814 | ++it3; |
1815 | } |
1816 | BOOST_REQUIRE_EQUAL(ret,true); |
1817 | } |
1818 | } |
1819 | } |
1820 | |
1821 | BOOST_AUTO_TEST_CASE( vector_fixing_noposition_and_keep_prop ) |
1822 | { |
1823 | Vcluster<> & v_cl = create_vcluster(); |
1824 | |
1825 | if (v_cl.getProcessingUnits() > 48) |
1826 | return; |
1827 | |
1828 | // Boundary conditions |
1829 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
1830 | |
1831 | // Box |
1832 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1833 | |
1834 | // ghost |
1835 | Ghost<3,float> ghost(0.1); |
1836 | |
1837 | vector_dist<3,float, aggregate<double,double>> vd(4096,box,bc,ghost); |
1838 | |
1839 | auto it = vd.getDomainIterator(); |
1840 | |
1841 | while (it.isNext()) |
1842 | { |
1843 | auto key = it.get(); |
1844 | |
1845 | vd.getPos(key)[0] = ((double)rand())/RAND_MAX; |
1846 | vd.getPos(key)[1] = ((double)rand())/RAND_MAX; |
1847 | vd.getPos(key)[2] = ((double)rand())/RAND_MAX; |
1848 | |
1849 | ++it; |
1850 | } |
1851 | |
1852 | vd.map(); |
1853 | |
1854 | vd.ghost_get<>(); |
1855 | size_t local = vd.getPosVector().size(); |
1856 | |
1857 | vd.ghost_get<>(KEEP_PROPERTIES | NO_POSITION); |
1858 | |
1859 | size_t local2 = vd.getPosVector().size(); |
1860 | |
1861 | BOOST_REQUIRE_EQUAL(local,local2); |
1862 | |
1863 | // Check now that map reset |
1864 | |
1865 | vd.map(); |
1866 | |
1867 | local = vd.getPosVector().size(); |
1868 | BOOST_REQUIRE_EQUAL(local,vd.size_local()); |
1869 | vd.ghost_get<>(KEEP_PROPERTIES | NO_POSITION); |
1870 | |
1871 | local2 = vd.getPosVector().size(); |
1872 | |
1873 | BOOST_REQUIRE_EQUAL(local,local2); |
1874 | |
1875 | vd.ghost_get<>(KEEP_PROPERTIES); |
1876 | BOOST_REQUIRE_EQUAL(local,vd.getPosVector().size()); |
1877 | BOOST_REQUIRE_EQUAL(vd.getPropVector().size(),local); |
1878 | |
1879 | vd.ghost_get<0>(KEEP_PROPERTIES); |
1880 | BOOST_REQUIRE_EQUAL(local,vd.getPosVector().size()); |
1881 | BOOST_REQUIRE_EQUAL(vd.getPropVector().size(),local); |
1882 | } |
1883 | |
1884 | |
1885 | BOOST_AUTO_TEST_CASE( vector_of_vector_dist ) |
1886 | { |
1887 | Vcluster<> & v_cl = create_vcluster(); |
1888 | |
1889 | if (v_cl.getProcessingUnits() > 48) |
1890 | return; |
1891 | |
1892 | // Boundary conditions |
1893 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
1894 | |
1895 | // Box |
1896 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1897 | |
1898 | // ghost |
1899 | Ghost<3,float> ghost(0.1); |
1900 | |
1901 | openfpm::vector< vector_dist<3,float, aggregate<double,double>> > phases; |
1902 | |
1903 | // first phase |
1904 | phases.add( vector_dist<3,float, aggregate<double,double>>(4096,box,bc,ghost) ); |
1905 | |
1906 | // The other 3 phases |
1907 | phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),4096) ); |
1908 | phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),4096) ); |
1909 | phases.add( vector_dist<3,float, aggregate<double,double>>(phases.get(0).getDecomposition(),4096) ); |
1910 | |
1911 | phases.get(0).map(); |
1912 | phases.get(0).ghost_get<>(); |
1913 | phases.get(1).map(); |
1914 | phases.get(1).ghost_get<>(); |
1915 | phases.get(2).map(); |
1916 | phases.get(2).ghost_get<>(); |
1917 | phases.get(3).map(); |
1918 | phases.get(3).ghost_get<>(); |
1919 | |
1920 | size_t cnt = 0; |
1921 | |
1922 | for (size_t i = 0 ; i < phases.size() ; i++) |
1923 | cnt += phases.get(i).size_local(); |
1924 | |
1925 | v_cl.sum(cnt); |
1926 | v_cl.execute(); |
1927 | |
1928 | BOOST_REQUIRE_EQUAL(cnt,4*4096ul); |
1929 | } |
1930 | |
1931 | BOOST_AUTO_TEST_CASE( vector_high_dimension ) |
1932 | { |
1933 | // Here we define our domain a 2D box with internals from 0 to 1.0 for x and y |
1934 | Box<10,double> domain; |
1935 | |
1936 | for (size_t i = 0 ; i < 10 ; i++) |
1937 | { |
1938 | domain.setLow(i,0.0); |
1939 | domain.setHigh(i,1.0); |
1940 | } |
1941 | |
1942 | // Here we define the boundary conditions of our problem |
1943 | size_t bc[10]; |
1944 | for (size_t i = 0 ; i < 10 ; i++) |
1945 | {bc[i] = NON_PERIODIC;}; |
1946 | |
1947 | // extended boundary around the domain, and the processor domain |
1948 | Ghost<10,double> g(0.0); |
1949 | |
1950 | // we check if the constructor does not stuck |
1951 | vector_dist<10,double, aggregate<double,double[10]> > vd(16,domain,bc,g); |
1952 | } |
1953 | |
1954 | BOOST_AUTO_TEST_CASE ( vector_of_cell_list_compile_test ) |
1955 | { |
1956 | auto & v_cl = create_vcluster(); |
1957 | |
1958 | // set the seed |
1959 | // create the random generator engine |
1960 | std::srand(v_cl.getProcessUnitID()); |
1961 | std::default_random_engine eg; |
1962 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
1963 | |
1964 | Box<3,double> domain({0.0,0.0,0.0},{1.0,1.0,1.0}); |
1965 | Ghost<3,double> g(0.1); |
1966 | size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
1967 | |
1968 | vector_dist<3,double,aggregate<float,float[3]>> vd(100,domain,bc,g); |
1969 | |
1970 | auto it = vd.getIterator(); |
1971 | |
1972 | while (it.isNext()) |
1973 | { |
1974 | auto key = it.get(); |
1975 | |
1976 | vd.getPos(key)[0] = ud(eg); |
1977 | vd.getPos(key)[1] = ud(eg); |
1978 | vd.getPos(key)[2] = ud(eg); |
1979 | |
1980 | ++it; |
1981 | } |
1982 | |
1983 | vd.map(); |
1984 | |
1985 | std::vector<decltype(vd.getCellList(0.1))> vector_of_celllist; |
1986 | |
1987 | typedef vector_dist<3,double,aggregate<float,float[3]>> my_particles; |
1988 | std::vector<decltype(std::declval<my_particles>().getCellList(0.0))> vector_of_celllist2; |
1989 | |
1990 | vector_of_celllist.push_back(vd.getCellList(0.1)); |
1991 | |
1992 | vector_of_celllist2.push_back(vd.getCellList(0.1)); |
1993 | } |
1994 | |
1995 | |
1996 | BOOST_AUTO_TEST_SUITE_END() |
1997 | |
1998 | |