OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
vector_dist_unit_test.cpp
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
26void print_test_v(std::string test, size_t sz)
27{
28 if (create_vcluster().getProcessUnitID() == 0)
29 std::cout << test << " " << sz << "\n";
30}
31
40long 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
60template<unsigned int dim, template <typename> class layout>
61size_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
91BOOST_AUTO_TEST_SUITE( vector_dist_test )
92
93void print_test(std::string test, size_t sz)
94{
95 if (create_vcluster().getProcessUnitID() == 0)
96 std::cout << test << " " << sz << "\n";
97}
98
99template<typename vector>
100void 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
111
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
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
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
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
270BOOST_AUTO_TEST_CASE( vector_dist_ghost )
271{
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
281BOOST_AUTO_TEST_CASE( vector_dist_ghost_inte )
282{
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
294BOOST_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
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
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
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
369BOOST_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
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
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
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
446BOOST_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
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
523BOOST_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
631BOOST_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
737void 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
817BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_random_walk )
818{
819 test_random_walk(NONE);
820}
821
822BOOST_AUTO_TEST_CASE( vector_dist_periodic_test_random_walk_local_map )
823{
824 test_random_walk(MAP_LOCAL);
825}
826
827BOOST_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
878BOOST_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
928BOOST_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
988void 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
1122BOOST_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
1131BOOST_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
1200BOOST_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
1325BOOST_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
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
1449BOOST_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
1631BOOST_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
1821BOOST_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
1885BOOST_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
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
1931BOOST_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
1952}
1953
1954BOOST_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
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
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
1996BOOST_AUTO_TEST_SUITE_END()
1997
This class represent an N-dimensional box.
Definition Box.hpp:61
Point< dim, T > getP2() const
Get the point p2.
Definition Box.hpp:722
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition Box.hpp:556
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition Box.hpp:823
Point< dim, T > getP1() const
Get the point p1.
Definition Box.hpp:708
This class decompose a space into sub-sub-domains and distribute them across processors.
static size_t getDefaultGrid(size_t n_sub)
The default grid size.
bool isLocal(const encapc< 1, Point< dim, T >, Mem > p) const
Check if the particle is local.
This class allocate, and destroy CPU memory.
Test structure used for several test.
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
__device__ __host__ T distance(const Point< dim, T > &q) const
It calculate the distance between 2 points.
Definition Point.hpp:250
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition Point.hpp:172
std::string toString() const
Return the string with the point coordinate.
Definition Point.hpp:398
This class represent an N-dimensional box.
Definition SpaceBox.hpp:27
void execute()
Execute all the requests.
void sum(T &num)
Sum the numbers across all processors and get the result.
size_t getProcessUnitID()
Get the process unit id.
size_t getProcessingUnits()
Get the total number of processors.
Implementation of VCluster class.
Definition VCluster.hpp:59
Class for Verlet list implementation.
size_t get(size_t i, size_t j) const
Get the neighborhood element j for the particle i.
size_t size()
Return for how many particles has been constructed this verlet list.
size_t getNNPart(size_t part_id) const
Return the number of neighborhood particles for the particle id.
Declaration grid_sm.
Definition grid_sm.hpp:167
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
Distributed vector.
CellL getCellList(St r_cut, bool no_se3=false)
Construct a cell list starting from the stored particles.
This structure define the operation add to use with copy general.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...