OpenFPM_pdata  1.0.0
Project that contain the implementation of distributed structures
 All Data Structures Functions Variables Typedefs Enumerations Friends Pages
vector_dist_cell_list_tests.hpp
1 /*
2  * vector_dist_cell_list_tests.hpp
3  *
4  * Created on: Aug 16, 2016
5  * Author: i-bird
6  */
7 
8 #include "config.h"
9 
10 #ifndef SRC_VECTOR_VECTOR_DIST_CELL_LIST_TESTS_HPP_
11 #define SRC_VECTOR_VECTOR_DIST_CELL_LIST_TESTS_HPP_
12 
13 
15 
16 BOOST_AUTO_TEST_CASE( vector_dist_reorder_2d_test )
17 {
18  Vcluster & v_cl = create_vcluster();
19 
20  if (v_cl.getProcessingUnits() > 48)
21  return;
22 
23  // set the seed
24  // create the random generator engine
25  std::srand(v_cl.getProcessUnitID());
26  std::default_random_engine eg;
27  std::uniform_real_distribution<float> ud(0.0f, 1.0f);
28 
29 #ifdef TEST_COVERAGE_MODE
30  long int k = 24288 * v_cl.getProcessingUnits();
31 #else
32  long int k = 524288 * v_cl.getProcessingUnits();
33 #endif
34 
35  long int big_step = k / 4;
36  big_step = (big_step == 0)?1:big_step;
37 
38  print_test_v( "Testing 2D vector with hilbert curve reordering k<=",k);
39 
40  // 2D test
41  for ( ; k >= 2 ; k-= decrement(k,big_step) )
42  {
43  BOOST_TEST_CHECKPOINT( "Testing 2D vector with hilbert curve reordering k=" << k );
44 
45  Box<2,float> box({0.0,0.0},{1.0,1.0});
46 
47  // Boundary conditions
48  size_t bc[2]={NON_PERIODIC,NON_PERIODIC};
49 
51 
52  auto it = vd.getIterator();
53 
54  while (it.isNext())
55  {
56  auto key = it.get();
57 
58  vd.getPos(key)[0] = ud(eg);
59  vd.getPos(key)[1] = ud(eg);
60 
61  ++it;
62  }
63 
64  vd.map();
65 
66  // in case of SE_CLASS3 get a cell-list without ghost get is an error
67 
68  // Create first cell list
69 
70  auto NN1 = vd.getCellList(0.01,true);
71 
72  //An order of a curve
73  int32_t m = 6;
74 
75  //Reorder a vector
76  vd.reorder(m);
77 
78  // Create second cell list
79  auto NN2 = vd.getCellList(0.01,true);
80 
81  //Check equality of cell sizes
82  for (size_t i = 0 ; i < NN1.getGrid().size() ; i++)
83  {
84  size_t n1 = NN1.getNelements(i);
85  size_t n2 = NN2.getNelements(i);
86 
87  BOOST_REQUIRE_EQUAL(n1,n2);
88  }
89  }
90 }
91 
92 BOOST_AUTO_TEST_CASE( vector_dist_cl_random_vs_hilb_forces_test )
93 {
94  Vcluster & v_cl = create_vcluster();
95 
96  if (v_cl.getProcessingUnits() > 48)
97  return;
98 
100 
101  // Dimensionality of the space
102  const size_t dim = 3;
103  // Cut-off radiuses. Can be put different number of values
104  openfpm::vector<float> cl_r_cutoff {0.05};
105  // The starting amount of particles (remember that this number is multiplied by number of processors you use for testing)
106  size_t cl_k_start = 10000;
107  // The lower threshold for number of particles
108  size_t cl_k_min = 1000;
109  // Ghost part of distributed vector
110  double ghost_part = 0.05;
111 
113 
114  //For different r_cut
115  for (size_t r = 0; r < cl_r_cutoff.size(); r++ )
116  {
117  //Cut-off radius
118  float r_cut = cl_r_cutoff.get(r);
119 
120  //Number of particles
121  size_t k = cl_k_start * v_cl.getProcessingUnits();
122 
123  std::string str("Testing " + std::to_string(dim) + "D vector's forces (random vs hilb celllist) k<=");
124 
125  vector_dist_test::print_test_v(str,k);
126 
127  //For different number of particles
128  for (size_t k_int = k ; k_int >= cl_k_min ; k_int/=2 )
129  {
130  BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector's forces (random vs hilb celllist) k<=" << k_int );
131 
132  Box<dim,float> box;
133 
134  for (size_t i = 0; i < dim; i++)
135  {
136  box.setLow(i,0.0);
137  box.setHigh(i,1.0);
138  }
139 
140  // Boundary conditions
141  size_t bc[dim];
142 
143  for (size_t i = 0; i < dim; i++)
144  bc[i] = PERIODIC;
145 
147 
149 
150  // Initialize dist vectors
151  vd_initialize_double<dim>(vd, vd2, v_cl, k_int);
152 
153  vd.ghost_get<0>();
154  vd2.ghost_get<0>();
155 
156  //Get a cell list
157 
158  auto NN = vd.getCellList(r_cut);
159 
160  //Calculate forces
161 
162  calc_forces<dim>(NN,vd,r_cut);
163 
164  //Get a cell list hilb
165 
166  auto NN_hilb = vd2.getCellList_hilb(r_cut);
167 
168  //Calculate forces
169  calc_forces_hilb<dim>(NN_hilb,vd2,r_cut);
170 
171  // Calculate average
172  size_t count = 1;
173  Point<dim,float> avg;
174  for (size_t i = 0 ; i < dim ; i++) {avg.get(i) = 0.0;}
175 
176  auto it_v2 = vd.getIterator();
177  while (it_v2.isNext())
178  {
179  //key
180  vect_dist_key_dx key = it_v2.get();
181 
182  for (size_t i = 0; i < dim; i++)
183  avg.get(i) += fabs(vd.getProp<0>(key)[i]);
184 
185  ++count;
186  ++it_v2;
187  }
188 
189  for (size_t i = 0 ; i < dim ; i++) {avg.get(i) /= count;}
190 
191  auto it_v = vd.getIterator();
192  while (it_v.isNext())
193  {
194  //key
195  vect_dist_key_dx key = it_v.get();
196 
197  for (size_t i = 0; i < dim; i++)
198  {
199  auto a1 = vd.getProp<0>(key)[i];
200  auto a2 = vd2.getProp<0>(key)[i];
201 
202  //Check that the forces are (almost) equal
203  float per = 0.1;
204  if (a1 != 0.0)
205  per = fabs(0.1*avg.get(i)/a1);
206 
207  BOOST_REQUIRE_CLOSE((float)a1,(float)a2,per);
208  }
209 
210  ++it_v;
211  }
212  }
213  }
214 }
215 
216 BOOST_AUTO_TEST_CASE( vector_dist_cl_random_vs_reorder_forces_test )
217 {
218  Vcluster & v_cl = create_vcluster();
219 
220  if (v_cl.getProcessingUnits() > 48)
221  return;
222 
224 
225  // Dimensionality of the space
226  const size_t dim = 3;
227  // Cut-off radiuses. Can be put different number of values
228  openfpm::vector<float> cl_r_cutoff {0.01};
229  // The starting amount of particles (remember that this number is multiplied by number of processors you use for testing)
230  size_t cl_k_start = 10000;
231  // The lower threshold for number of particles
232  size_t cl_k_min = 1000;
233  // Ghost part of distributed vector
234  double ghost_part = 0.01;
235 
237 
238  //For different r_cut
239  for (size_t r = 0; r < cl_r_cutoff.size(); r++ )
240  {
241  //Cut-off radius
242  float r_cut = cl_r_cutoff.get(r);
243 
244  //Number of particles
245  size_t k = cl_k_start * v_cl.getProcessingUnits();
246 
247  std::string str("Testing " + std::to_string(dim) + "D vector's forces (random vs reorder) k<=");
248 
249  vector_dist_test::print_test_v(str,k);
250 
251  //For different number of particles
252  for (size_t k_int = k ; k_int >= cl_k_min ; k_int/=2 )
253  {
254  BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector's forces (random vs reorder) k<=" << k_int );
255 
256  Box<dim,float> box;
257 
258  for (size_t i = 0; i < dim; i++)
259  {
260  box.setLow(i,0.0);
261  box.setHigh(i,1.0);
262  }
263 
264  // Boundary conditions
265  size_t bc[dim];
266 
267  for (size_t i = 0; i < dim; i++)
268  bc[i] = PERIODIC;
269 
271 
272  // Initialize vd
273  vd_initialize<dim,decltype(vd)>(vd, v_cl, k_int);
274 
275  vd.ghost_get<0>();
276 
277  //Get a cell list
278 
279  auto NN1 = vd.getCellList(r_cut);
280 
281  //Calculate forces '0'
282 
283  calc_forces<dim>(NN1,vd,r_cut);
284 
285  //Reorder and get a cell list again
286 
287  vd.reorder(4);
288 
289  vd.ghost_get<0>();
290 
291  auto NN2 = vd.getCellList(r_cut);
292 
293  //Calculate forces '1'
294  calc_forces<dim,1>(NN2,vd,r_cut);
295 
296  // Calculate average (For Coverty scan we start from 1)
297  size_t count = 1;
298  Point<dim,float> avg;
299  for (size_t i = 0 ; i < dim ; i++) {avg.get(i) = 0.0;}
300 
301  auto it_v2 = vd.getIterator();
302  while (it_v2.isNext())
303  {
304  //key
305  vect_dist_key_dx key = it_v2.get();
306 
307  for (size_t i = 0; i < dim; i++)
308  avg.get(i) += fabs(vd.getProp<0>(key)[i]);
309 
310  ++count;
311  ++it_v2;
312  }
313 
314  for (size_t i = 0 ; i < dim ; i++) {avg.get(i) /= count;}
315 
316  //Test for equality of forces
317  auto it_v = vd.getDomainIterator();
318 
319  while (it_v.isNext())
320  {
321  //key
322  vect_dist_key_dx key = it_v.get();
323 
324  for (size_t i = 0; i < dim; i++)
325  {
326  float a1 = vd.getProp<0>(key)[i];
327  float a2 = vd.getProp<1>(key)[i];
328 
329  //Check that the forces are (almost) equal
330  float per = 0.1;
331  if (a1 != 0.0)
332  per = fabs(0.1*avg.get(i)/a1);
333 
334  BOOST_REQUIRE_CLOSE(a1,a2,per);
335  }
336 
337  ++it_v;
338  }
339  }
340  }
341 }
342 
343 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_cell_list )
344 {
345  Vcluster & v_cl = create_vcluster();
346 
347  if (v_cl.getProcessingUnits() > 24)
348  return;
349 
350  float L = 1000.0;
351 
352  // set the seed
353  // create the random generator engine
354  std::srand(0);
355  std::default_random_engine eg;
356  std::uniform_real_distribution<float> ud(-L,L);
357 
358  long int k = 4096 * v_cl.getProcessingUnits();
359 
360  long int big_step = k / 4;
361  big_step = (big_step == 0)?1:big_step;
362 
363  print_test("Testing 3D periodic vector symmetric cell-list k=",k);
364  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
365 
366  Box<3,float> box({-L,-L,-L},{L,L,L});
367 
368  // Boundary conditions
369  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
370 
371  float r_cut = 100.0;
372 
373  // ghost
374  Ghost<3,float> ghost(r_cut);
375 
376  // Point and global id
377  struct point_and_gid
378  {
379  size_t id;
380  Point<3,float> xq;
381 
382  bool operator<(const struct point_and_gid & pag) const
383  {
384  return (id < pag.id);
385  }
386  };
387 
389 
390  // Distributed vector
391  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
392  size_t start = vd.init_size_accum(k);
393 
394  auto it = vd.getIterator();
395 
396  while (it.isNext())
397  {
398  auto key = it.get();
399 
400  vd.getPosWrite(key)[0] = ud(eg);
401  vd.getPosWrite(key)[1] = ud(eg);
402  vd.getPosWrite(key)[2] = ud(eg);
403 
404  // Fill some properties randomly
405 
406  vd.getPropWrite<0>(key) = 0;
407  vd.getPropWrite<1>(key) = 0;
408  vd.getPropWrite<2>(key) = key.getKey() + start;
409 
410  ++it;
411  }
412 
413  vd.map();
414 
415  // sync the ghost
416  vd.ghost_get<0,2>();
417 
418  auto NN = vd.getCellList(r_cut);
419  auto p_it = vd.getDomainIterator();
420 
421  while (p_it.isNext())
422  {
423  auto p = p_it.get();
424 
425  Point<3,float> xp = vd.getPosRead(p);
426 
427  auto Np = NN.getNNIterator(NN.getCell(xp));
428 
429  while (Np.isNext())
430  {
431  auto q = Np.get();
432 
433  if (p.getKey() == q)
434  {
435  ++Np;
436  continue;
437  }
438 
439  // repulsive
440 
441  Point<3,float> xq = vd.getPosRead(q);
442  Point<3,float> f = (xp - xq);
443 
444  float distance = f.norm();
445 
446  // Particle should be inside 2 * r_cut range
447 
448  if (distance < r_cut )
449  {
450  vd.getPropWrite<0>(p)++;
451  vd.getPropWrite<3>(p).add();
452  vd.getPropWrite<3>(p).last().xq = xq;
453  vd.getPropWrite<3>(p).last().id = vd.getPropWrite<2>(q);
454  }
455 
456  ++Np;
457  }
458 
459  ++p_it;
460  }
461 
462  // We now try symmetric Cell-list
463 
464  auto NN2 = vd.getCellListSym(r_cut);
465 
466  auto p_it2 = vd.getDomainIterator();
467 
468  while (p_it2.isNext())
469  {
470  auto p = p_it2.get();
471 
472  Point<3,float> xp = vd.getPosRead(p);
473 
474  auto Np = NN2.getNNIteratorSym<NO_CHECK>(NN2.getCell(xp),p.getKey(),vd.getPosVector());
475 
476  while (Np.isNext())
477  {
478  auto q = Np.get();
479 
480  if (p.getKey() == q)
481  {
482  ++Np;
483  continue;
484  }
485 
486  // repulsive
487 
488  Point<3,float> xq = vd.getPosRead(q);
489  Point<3,float> f = (xp - xq);
490 
491  float distance = f.norm();
492 
493  // Particle should be inside r_cut range
494 
495  if (distance < r_cut )
496  {
497  vd.getPropWrite<1>(p)++;
498  vd.getPropWrite<1>(q)++;
499 
500  vd.getPropWrite<4>(p).add();
501  vd.getPropWrite<4>(q).add();
502 
503  vd.getPropWrite<4>(p).last().xq = xq;
504  vd.getPropWrite<4>(q).last().xq = xp;
505  vd.getPropWrite<4>(p).last().id = vd.getProp<2>(q);
506  vd.getPropWrite<4>(q).last().id = vd.getProp<2>(p);
507  }
508 
509  ++Np;
510  }
511 
512  ++p_it2;
513  }
514 
515  vd.ghost_put<add_,1>();
516  vd.ghost_put<merge_,4>();
517 
518  auto p_it3 = vd.getDomainIterator();
519 
520  bool ret = true;
521  while (p_it3.isNext())
522  {
523  auto p = p_it3.get();
524 
525  ret &= vd.getPropRead<1>(p) == vd.getPropRead<0>(p);
526 
527  vd.getPropRead<3>(p).sort();
528  vd.getPropRead<4>(p).sort();
529 
530  ret &= vd.getPropRead<3>(p).size() == vd.getPropRead<4>(p).size();
531 
532  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
533  ret &= vd.getPropRead<3>(p).get(i).id == vd.getPropRead<4>(p).get(i).id;
534 
535  if (ret == false)
536  {
537  std::cout << vd.getPropRead<3>(p).size() << " " << vd.getPropRead<4>(p).size() << std::endl;
538 
539  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
540  std::cout << vd.getPropRead<3>(p).get(i).id << " " << vd.getPropRead<4>(p).get(i).id << std::endl;
541 
542  std::cout << vd.getPropRead<1>(p) << " A " << vd.getPropRead<0>(p) << std::endl;
543 
544  break;
545  }
546 
547  ++p_it3;
548  }
549 
550  BOOST_REQUIRE_EQUAL(ret,true);
551 }
552 
553 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
554 {
555  Vcluster & v_cl = create_vcluster();
556 
557  if (v_cl.getProcessingUnits() > 24)
558  return;
559 
560  float L = 1000.0;
561 
562  // set the seed
563  // create the random generator engine
564  std::default_random_engine eg(1132312*v_cl.getProcessUnitID());
565  std::uniform_real_distribution<float> ud(-L,L);
566 
567  long int k = 4096 * v_cl.getProcessingUnits();
568 
569  long int big_step = k / 4;
570  big_step = (big_step == 0)?1:big_step;
571 
572  print_test("Testing 3D periodic vector symmetric crs cell-list k=",k);
573  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric crs cell-list k=" << k );
574 
575  Box<3,float> box({-L,-L,-L},{L,L,L});
576 
577  // Boundary conditions
578  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
579 
580  float r_cut = 100.0;
581 
582  // ghost
583  Ghost<3,float> ghost(r_cut);
584  Ghost<3,float> ghost2(r_cut);
585  ghost2.setLow(0,0.0);
586  ghost2.setLow(1,0.0);
587  ghost2.setLow(2,0.0);
588 
589  // Point and global id
590  struct point_and_gid
591  {
592  size_t id;
593  Point<3,float> xq;
594 
595  bool operator<(const struct point_and_gid & pag) const
596  {
597  return (id < pag.id);
598  }
599  };
600 
602 
603  // Distributed vector
604  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
605  vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST);
606  size_t start = vd.init_size_accum(k);
607 
608  auto it = vd.getIterator();
609 
610  while (it.isNext())
611  {
612  auto key = it.get();
613 
614  vd.getPosWrite(key)[0] = ud(eg);
615  vd.getPosWrite(key)[1] = ud(eg);
616  vd.getPosWrite(key)[2] = ud(eg);
617 
618  vd2.getPosWrite(key)[0] = vd.getPosRead(key)[0];
619  vd2.getPosWrite(key)[1] = vd.getPosRead(key)[1];
620  vd2.getPosWrite(key)[2] = vd.getPosRead(key)[2];
621 
622  // Fill some properties randomly
623 
624  vd.getPropWrite<0>(key) = 0;
625  vd.getPropWrite<1>(key) = 0;
626  vd.getPropWrite<2>(key) = key.getKey() + start;
627 
628  vd2.getPropWrite<0>(key) = 0;
629  vd2.getPropWrite<1>(key) = 0;
630  vd2.getPropWrite<2>(key) = key.getKey() + start;
631 
632  ++it;
633  }
634 
635  vd.map();
636  vd2.map();
637 
638  // sync the ghost
639  vd.ghost_get<0,2>();
640  vd2.ghost_get<0,2>();
641 
642  vd2.write("CRS_output");
643  vd2.getDecomposition().write("CRS_output_dec");
644 
645  auto NN = vd.getCellList(r_cut);
646  auto p_it = vd.getDomainIterator();
647 
648  while (p_it.isNext())
649  {
650  auto p = p_it.get();
651 
652  Point<3,float> xp = vd.getPosRead(p);
653 
654  auto Np = NN.getNNIterator(NN.getCell(xp));
655 
656  while (Np.isNext())
657  {
658  auto q = Np.get();
659 
660  if (p.getKey() == q)
661  {
662  ++Np;
663  continue;
664  }
665 
666  // repulsive
667 
668  Point<3,float> xq = vd.getPosRead(q);
669  Point<3,float> f = (xp - xq);
670 
671  float distance = f.norm();
672 
673  // Particle should be inside 2 * r_cut range
674 
675  if (distance < r_cut )
676  {
677  vd.getPropWrite<0>(p)++;
678  vd.getPropWrite<3>(p).add();
679  vd.getPropWrite<3>(p).last().xq = xq;
680  vd.getPropWrite<3>(p).last().id = vd.getPropRead<2>(q);
681  }
682 
683  ++Np;
684  }
685 
686  ++p_it;
687  }
688 
689  // We now try symmetric Cell-list
690 
691  auto NN2 = vd2.getCellListSym(r_cut);
692 
693  // In case of CRS we have to iterate particles within some cells
694  // here we define whichone
695  auto p_it2 = vd2.getParticleIteratorCRS_Cell(NN2);
696 
697  // For each particle
698  while (p_it2.isNext())
699  {
700  auto p = p_it2.get();
701 
702  Point<3,float> xp = vd2.getPosRead(p);
703 
704  auto Np = p_it2.getNNIteratorCSR(vd2.getPosVector());
705 
706  while (Np.isNext())
707  {
708  auto q = Np.get();
709 
710  if (p == q)
711  {
712  ++Np;
713  continue;
714  }
715 
716  // repulsive
717 
718  Point<3,float> xq = vd2.getPosRead(q);
719  Point<3,float> f = (xp - xq);
720 
721  float distance = f.norm();
722 
723  // Particle should be inside r_cut range
724 
725  if (distance < r_cut )
726  {
727  vd2.getPropWrite<1>(p)++;
728  vd2.getPropWrite<1>(q)++;
729 
730  vd2.getPropWrite<4>(p).add();
731  vd2.getPropWrite<4>(q).add();
732 
733  vd2.getPropWrite<4>(p).last().xq = xq;
734  vd2.getPropWrite<4>(q).last().xq = xp;
735  vd2.getPropWrite<4>(p).last().id = vd2.getPropRead<2>(q);
736  vd2.getPropWrite<4>(q).last().id = vd2.getPropRead<2>(p);
737  }
738 
739  ++Np;
740  }
741 
742  ++p_it2;
743  }
744 
745  vd2.ghost_put<add_,1>(NO_CHANGE_ELEMENTS);
746  vd2.ghost_put<merge_,4>();
747 
748 #ifdef SE_CLASS3
749  vd2.getDomainIterator();
750 #endif
751 
752  auto p_it3 = vd.getDomainIterator();
753 
754  bool ret = true;
755  while (p_it3.isNext())
756  {
757  auto p = p_it3.get();
758 
759  ret &= vd2.getPropRead<1>(p) == vd.getPropRead<0>(p);
760 
761 
762  vd.getPropWrite<3>(p).sort();
763  vd2.getPropWrite<4>(p).sort();
764 
765  ret &= vd.getPropRead<3>(p).size() == vd2.getPropRead<4>(p).size();
766 
767  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
768  ret &= vd.getPropRead<3>(p).get(i).id == vd2.getPropRead<4>(p).get(i).id;
769 
770  if (ret == false)
771  break;
772 
773  ++p_it3;
774  }
775 
776  BOOST_REQUIRE_EQUAL(ret,true);
777 }
778 
779 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_verlet_list )
780 {
781  Vcluster & v_cl = create_vcluster();
782 
783  if (v_cl.getProcessingUnits() > 24)
784  return;
785 
786  float L = 1000.0;
787 
788  // set the seed
789  // create the random generator engine
790  std::srand(0);
791  std::default_random_engine eg;
792  std::uniform_real_distribution<float> ud(-L,L);
793 
794  long int k = 4096 * v_cl.getProcessingUnits();
795 
796  long int big_step = k / 4;
797  big_step = (big_step == 0)?1:big_step;
798 
799  print_test("Testing 3D periodic vector symmetric cell-list k=",k);
800  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric verlet-list k=" << k );
801 
802  Box<3,float> box({-L,-L,-L},{L,L,L});
803 
804  // Boundary conditions
805  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
806 
807  float r_cut = 100.0;
808 
809  // ghost
810  Ghost<3,float> ghost(r_cut);
811 
812  // Point and global id
813  struct point_and_gid
814  {
815  size_t id;
816  Point<3,float> xq;
817 
818  bool operator<(const struct point_and_gid & pag) const
819  {
820  return (id < pag.id);
821  }
822  };
823 
825 
826  // Distributed vector
827  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
828  size_t start = vd.init_size_accum(k);
829 
830  auto it = vd.getIterator();
831 
832  while (it.isNext())
833  {
834  auto key = it.get();
835 
836  vd.getPosWrite(key)[0] = ud(eg);
837  vd.getPosWrite(key)[1] = ud(eg);
838  vd.getPosWrite(key)[2] = ud(eg);
839 
840  // Fill some properties randomly
841 
842  vd.getPropWrite<0>(key) = 0;
843  vd.getPropWrite<1>(key) = 0;
844  vd.getPropWrite<2>(key) = key.getKey() + start;
845 
846  ++it;
847  }
848 
849  vd.map();
850 
851  // sync the ghost
852  vd.ghost_get<0,2>();
853 
854  auto NN = vd.getVerlet(r_cut);
855  auto p_it = vd.getDomainIterator();
856 
857  while (p_it.isNext())
858  {
859  auto p = p_it.get();
860 
861  Point<3,float> xp = vd.getPosRead(p);
862 
863  auto Np = NN.getNNIterator(p.getKey());
864 
865  while (Np.isNext())
866  {
867  auto q = Np.get();
868 
869  if (p.getKey() == q)
870  {
871  ++Np;
872  continue;
873  }
874 
875  // repulsive
876 
877  Point<3,float> xq = vd.getPosRead(q);
878  Point<3,float> f = (xp - xq);
879 
880  float distance = f.norm();
881 
882  // Particle should be inside 2 * r_cut range
883 
884  if (distance < r_cut )
885  {
886  vd.getPropWrite<0>(p)++;
887  vd.getPropWrite<3>(p).add();
888  vd.getPropWrite<3>(p).last().xq = xq;
889  vd.getPropWrite<3>(p).last().id = vd.getPropRead<2>(q);
890  }
891 
892  ++Np;
893  }
894 
895  ++p_it;
896  }
897 
898  // We now try symmetric Cell-list
899 
900  auto NN2 = vd.getVerletSym(r_cut);
901 
902  auto p_it2 = vd.getDomainIterator();
903 
904  while (p_it2.isNext())
905  {
906  auto p = p_it2.get();
907 
908  Point<3,float> xp = vd.getPosRead(p);
909 
910  auto Np = NN2.getNNIterator<NO_CHECK>(p.getKey());
911 
912  while (Np.isNext())
913  {
914  auto q = Np.get();
915 
916  if (p.getKey() == q)
917  {
918  ++Np;
919  continue;
920  }
921 
922  // repulsive
923 
924  Point<3,float> xq = vd.getPosRead(q);
925  Point<3,float> f = (xp - xq);
926 
927  float distance = f.norm();
928 
929  // Particle should be inside r_cut range
930 
931  if (distance < r_cut )
932  {
933  vd.getPropWrite<1>(p)++;
934  vd.getPropWrite<1>(q)++;
935 
936  vd.getPropWrite<4>(p).add();
937  vd.getPropWrite<4>(q).add();
938 
939  vd.getPropWrite<4>(p).last().xq = xq;
940  vd.getPropWrite<4>(q).last().xq = xp;
941  vd.getPropWrite<4>(p).last().id = vd.getPropRead<2>(q);
942  vd.getPropWrite<4>(q).last().id = vd.getPropRead<2>(p);
943  }
944 
945  ++Np;
946  }
947 
948  ++p_it2;
949  }
950 
951  vd.ghost_put<add_,1>();
952  vd.ghost_put<merge_,4>();
953 
954  auto p_it3 = vd.getDomainIterator();
955 
956  bool ret = true;
957  while (p_it3.isNext())
958  {
959  auto p = p_it3.get();
960 
961  ret &= vd.getPropRead<1>(p) == vd.getPropRead<0>(p);
962 
963  vd.getPropWrite<3>(p).sort();
964  vd.getPropWrite<4>(p).sort();
965 
966  ret &= vd.getPropRead<3>(p).size() == vd.getPropRead<4>(p).size();
967 
968  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
969  ret &= vd.getPropRead<3>(p).get(i).id == vd.getPropRead<4>(p).get(i).id;
970 
971  if (ret == false)
972  break;
973 
974  ++p_it3;
975  }
976 
977  BOOST_REQUIRE_EQUAL(ret,true);
978 }
979 
980 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_verlet_list_no_bottom )
981 {
982  Vcluster & v_cl = create_vcluster();
983 
984  if (v_cl.getProcessingUnits() > 24)
985  return;
986 
987  float L = 1000.0;
988 
989  // set the seed
990  // create the random generator engine
991  std::srand(0);
992  std::default_random_engine eg;
993  std::uniform_real_distribution<float> ud(-L,L);
994 
995  long int k = 4096 * v_cl.getProcessingUnits();
996 
997  long int big_step = k / 4;
998  big_step = (big_step == 0)?1:big_step;
999 
1000  print_test("Testing 3D periodic vector symmetric cell-list no bottom k=",k);
1001  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list no bottom k=" << k );
1002 
1003  Box<3,float> box({-L,-L,-L},{L,L,L});
1004 
1005  // Boundary conditions
1006  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1007 
1008  float r_cut = 100.0;
1009 
1010  // ghost
1011  Ghost<3,float> ghost(r_cut);
1012  Ghost<3,float> ghost2(r_cut);
1013  ghost2.setLow(2,0.0);
1014 
1015  // Point and global id
1016  struct point_and_gid
1017  {
1018  size_t id;
1019  Point<3,float> xq;
1020 
1021  bool operator<(const struct point_and_gid & pag) const
1022  {
1023  return (id < pag.id);
1024  }
1025  };
1026 
1028 
1029  // 3D test
1030  for (size_t s = 0 ; s < 8 ; s++)
1031  {
1032 
1033  // Distributed vector
1034  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
1035  vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST);
1036  size_t start = vd.init_size_accum(k);
1037 
1038  auto it = vd.getIterator();
1039 
1040  while (it.isNext())
1041  {
1042  auto key = it.get();
1043 
1044  vd.getPosWrite(key)[0] = ud(eg);
1045  vd.getPosWrite(key)[1] = ud(eg);
1046  vd.getPosWrite(key)[2] = ud(eg);
1047 
1048  vd2.getPosWrite(key)[0] = vd.getPosRead(key)[0];
1049  vd2.getPosWrite(key)[1] = vd.getPosRead(key)[1];
1050  vd2.getPosWrite(key)[2] = vd.getPosRead(key)[2];
1051 
1052  // Fill some properties randomly
1053 
1054  vd.getPropWrite<0>(key) = 0;
1055  vd.getPropWrite<1>(key) = 0;
1056  vd.getPropWrite<2>(key) = key.getKey() + start;
1057 
1058  vd2.getPropWrite<0>(key) = 0;
1059  vd2.getPropWrite<1>(key) = 0;
1060  vd2.getPropWrite<2>(key) = key.getKey() + start;
1061 
1062  ++it;
1063  }
1064 
1065  vd.map();
1066  vd2.map();
1067 
1068  // sync the ghost
1069  vd.ghost_get<0,2>();
1070  vd2.ghost_get<0,2>();
1071 
1072  auto NN = vd.getVerlet(r_cut);
1073  auto p_it = vd.getDomainIterator();
1074 
1075  while (p_it.isNext())
1076  {
1077  auto p = p_it.get();
1078 
1079  Point<3,float> xp = vd.getPosRead(p);
1080 
1081  auto Np = NN.getNNIterator(p.getKey());
1082 
1083  while (Np.isNext())
1084  {
1085  auto q = Np.get();
1086 
1087  if (p.getKey() == q)
1088  {
1089  ++Np;
1090  continue;
1091  }
1092 
1093  // repulsive
1094 
1095  Point<3,float> xq = vd.getPosRead(q);
1096  Point<3,float> f = (xp - xq);
1097 
1098  float distance = f.norm();
1099 
1100  // Particle should be inside 2 * r_cut range
1101 
1102  if (distance < r_cut )
1103  {
1104  vd.getPropWrite<0>(p)++;
1105  vd.getPropWrite<3>(p).add();
1106  vd.getPropWrite<3>(p).last().xq = xq;
1107  vd.getPropWrite<3>(p).last().id = vd.getPropRead<2>(q);
1108  }
1109 
1110  ++Np;
1111  }
1112 
1113  ++p_it;
1114  }
1115 
1116  // We now try symmetric Cell-list
1117 
1118  auto NN2 = vd2.getVerletSym(r_cut);
1119 
1120  auto p_it2 = vd2.getDomainIterator();
1121 
1122  while (p_it2.isNext())
1123  {
1124  auto p = p_it2.get();
1125 
1126  Point<3,float> xp = vd2.getPosRead(p);
1127 
1128  auto Np = NN2.getNNIterator<NO_CHECK>(p.getKey());
1129 
1130  while (Np.isNext())
1131  {
1132  auto q = Np.get();
1133 
1134  if (p.getKey() == q)
1135  {
1136  ++Np;
1137  continue;
1138  }
1139 
1140  // repulsive
1141 
1142  Point<3,float> xq = vd2.getPosRead(q);
1143  Point<3,float> f = (xp - xq);
1144 
1145  float distance = f.norm();
1146 
1147  // Particle should be inside r_cut range
1148 
1149  if (distance < r_cut )
1150  {
1151  vd2.getPropWrite<1>(p)++;
1152  vd2.getPropWrite<1>(q)++;
1153 
1154  vd2.getPropWrite<4>(p).add();
1155  vd2.getPropWrite<4>(q).add();
1156 
1157  vd2.getPropWrite<4>(p).last().xq = xq;
1158  vd2.getPropWrite<4>(q).last().xq = xp;
1159  vd2.getPropWrite<4>(p).last().id = vd2.getPropRead<2>(q);
1160  vd2.getPropWrite<4>(q).last().id = vd2.getPropRead<2>(p);
1161  }
1162 
1163  ++Np;
1164  }
1165 
1166 
1167  ++p_it2;
1168  }
1169 
1170  vd2.ghost_put<add_,1>();
1171  vd2.ghost_put<merge_,4>();
1172 
1173 #ifdef SE_CLASS3
1174  vd2.getDomainIterator();
1175 #endif
1176 
1177  auto p_it3 = vd.getDomainIterator();
1178 
1179  bool ret = true;
1180  while (p_it3.isNext())
1181  {
1182  auto p = p_it3.get();
1183 
1184  ret &= vd2.getPropRead<1>(p) == vd.getPropRead<0>(p);
1185 
1186 
1187  vd.getPropWrite<3>(p).sort();
1188  vd2.getPropWrite<4>(p).sort();
1189 
1190  ret &= vd.getPropRead<3>(p).size() == vd2.getPropRead<4>(p).size();
1191 
1192  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
1193  ret &= vd.getPropRead<3>(p).get(i).id == vd2.getPropRead<4>(p).get(i).id;
1194 
1195  if (ret == false)
1196  break;
1197 
1198  ++p_it3;
1199  }
1200 
1201  BOOST_REQUIRE_EQUAL(ret,true);
1202  }
1203 }
1204 
1205 template<typename part_prop> void test_crs_full(vector_dist<3,float, part_prop > & vd,
1207  std::default_random_engine & eg,
1208  std::uniform_real_distribution<float> & ud,
1209  size_t start,
1210  float r_cut)
1211 {
1212  auto it = vd.getIterator();
1213 
1214  while (it.isNext())
1215  {
1216  auto key = it.get();
1217 
1218  vd.getPosWrite(key)[0] = ud(eg);
1219  vd.getPosWrite(key)[1] = ud(eg);
1220  vd.getPosWrite(key)[2] = ud(eg);
1221 
1222  vd2.getPosWrite(key)[0] = vd.getPosRead(key)[0];
1223  vd2.getPosWrite(key)[1] = vd.getPosRead(key)[1];
1224  vd2.getPosWrite(key)[2] = vd.getPosRead(key)[2];
1225 
1226  // Fill some properties randomly
1227 
1228  vd.template getPropWrite<0>(key) = 0;
1229  vd.template getPropWrite<1>(key) = 0;
1230  vd.template getPropWrite<2>(key) = key.getKey() + start;
1231 
1232  vd2.template getPropWrite<0>(key) = 0;
1233  vd2.template getPropWrite<1>(key) = 0;
1234  vd2.template getPropWrite<2>(key) = key.getKey() + start;
1235 
1236  ++it;
1237  }
1238 
1239  vd.map();
1240  vd2.map();
1241 
1242  // sync the ghost
1243  vd.template ghost_get<0,2>();
1244  vd2.template ghost_get<0,2>();
1245 
1246  auto NN = vd.getVerlet(r_cut);
1247  auto p_it = vd.getDomainIterator();
1248 
1249  while (p_it.isNext())
1250  {
1251  auto p = p_it.get();
1252 
1253  Point<3,float> xp = vd.getPosRead(p);
1254 
1255  auto Np = NN.getNNIterator(p.getKey());
1256 
1257  while (Np.isNext())
1258  {
1259  auto q = Np.get();
1260 
1261  if (p.getKey() == q)
1262  {
1263  ++Np;
1264  continue;
1265  }
1266 
1267  // repulsive
1268 
1269  Point<3,float> xq = vd.getPosRead(q);
1270  Point<3,float> f = (xp - xq);
1271 
1272  float distance = f.norm();
1273 
1274  // Particle should be inside 2 * r_cut range
1275 
1276  if (distance < r_cut )
1277  {
1278  vd.template getPropWrite<0>(p)++;
1279  vd.template getPropWrite<3>(p).add();
1280  vd.template getPropWrite<3>(p).last().xq = xq;
1281  vd.template getPropWrite<3>(p).last().id = vd.template getPropRead<2>(q);
1282  }
1283 
1284  ++Np;
1285  }
1286 
1287  ++p_it;
1288  }
1289 
1290  // We now try symmetric Verlet-list Crs scheme
1291 
1292  auto NN2 = vd2.getVerletCrs(r_cut);
1293 
1294  // Because iterating across particles in the CSR scheme require a Cell-list
1295  auto p_it2 = vd2.getParticleIteratorCRS_Cell(NN2.getInternalCellList());
1296 
1297  while (p_it2.isNext())
1298  {
1299  auto p = p_it2.get();
1300 
1301  Point<3,float> xp = vd2.getPosRead(p);
1302 
1303  auto Np = NN2.template getNNIterator<NO_CHECK>(p);
1304 
1305  while (Np.isNext())
1306  {
1307  auto q = Np.get();
1308 
1309  if (p == q)
1310  {
1311  ++Np;
1312  continue;
1313  }
1314 
1315  // repulsive
1316 
1317  Point<3,float> xq = vd2.getPosRead(q);
1318  Point<3,float> f = (xp - xq);
1319 
1320  float distance = f.norm();
1321 
1322  if (distance < r_cut )
1323  {
1324  vd2.template getPropWrite<1>(p)++;
1325  vd2.template getPropWrite<1>(q)++;
1326 
1327  vd2.template getPropWrite<4>(p).add();
1328  vd2.template getPropWrite<4>(q).add();
1329 
1330  vd2.template getPropWrite<4>(p).last().xq = xq;
1331  vd2.template getPropWrite<4>(q).last().xq = xp;
1332  vd2.template getPropWrite<4>(p).last().id = vd2.template getPropRead<2>(q);
1333  vd2.template getPropWrite<4>(q).last().id = vd2.template getPropRead<2>(p);
1334  }
1335 
1336  ++Np;
1337  }
1338 
1339  ++p_it2;
1340  }
1341 
1342  vd2.template ghost_put<add_,1>();
1343  vd2.template ghost_put<merge_,4>();
1344 
1345 #ifdef SE_CLASS3
1346  vd2.getDomainIterator();
1347 #endif
1348 
1349  auto p_it3 = vd.getDomainIterator();
1350 
1351  bool ret = true;
1352  while (p_it3.isNext())
1353  {
1354  auto p = p_it3.get();
1355 
1356  ret &= vd2.template getPropRead<1>(p) == vd.template getPropRead<0>(p);
1357 
1358  if (ret == false)
1359  {
1360  Point<3,float> xp = vd2.getPosRead(p);
1361  std::cout << "ERROR " << vd2.template getPropWrite<1>(p) << " " << vd.template getPropWrite<0>(p) << " " << xp.toString() << std::endl;
1362  }
1363 
1364  vd.template getPropWrite<3>(p).sort();
1365  vd2.template getPropWrite<4>(p).sort();
1366 
1367  ret &= vd.template getPropRead<3>(p).size() == vd2.template getPropRead<4>(p).size();
1368 
1369  for (size_t i = 0 ; i < vd.template getPropRead<3>(p).size() ; i++)
1370  ret &= vd.template getPropRead<3>(p).get(i).id == vd2.template getPropRead<4>(p).get(i).id;
1371 
1372  if (ret == false)
1373  break;
1374 
1375  ++p_it3;
1376  }
1377 
1378  BOOST_REQUIRE_EQUAL(ret,true);
1379 }
1380 
1381 
1382 void test_csr_verlet_list()
1383 {
1384  Vcluster & v_cl = create_vcluster();
1385 
1386  if (v_cl.getProcessingUnits() > 24)
1387  return;
1388 
1389  float L = 1000.0;
1390 
1391  // set the seed
1392  // create the random generator engine
1393  std::srand(0);
1394  std::default_random_engine eg;
1395  std::uniform_real_distribution<float> ud(-L,L);
1396 
1397  long int k = 4096 * v_cl.getProcessingUnits();
1398 
1399  long int big_step = k / 4;
1400  big_step = (big_step == 0)?1:big_step;
1401 
1402  print_test("Testing 3D periodic vector symmetric cell-list k=",k);
1403  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
1404 
1405  Box<3,float> box({-L,-L,-L},{L,L,L});
1406 
1407  // Boundary conditions
1408  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1409 
1410  float r_cut = 100.0;
1411 
1412  // ghost
1413  Ghost<3,float> ghost(r_cut);
1414  Ghost<3,float> ghost2(r_cut);
1415  ghost2.setLow(0,0.0);
1416  ghost2.setLow(1,0.0);
1417  ghost2.setLow(2,0.0);
1418 
1419  // Point and global id
1420  struct point_and_gid
1421  {
1422  size_t id;
1423  Point<3,float> xq;
1424 
1425  bool operator<(const struct point_and_gid & pag) const
1426  {
1427  return (id < pag.id);
1428  }
1429  };
1430 
1432 
1433  // Distributed vector
1434  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
1435  vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST);
1436  size_t start = vd.init_size_accum(k);
1437 
1438  test_crs_full(vd,vd2,eg,ud,start,r_cut);
1439 }
1440 
1441 void test_csr_verlet_list_override()
1442 {
1443  Vcluster & v_cl = create_vcluster();
1444 
1445  if (v_cl.getProcessingUnits() > 24)
1446  return;
1447 
1448  float L = 1000.0;
1449 
1450  // set the seed
1451  // create the random generator engine
1452  std::srand(0);
1453  std::default_random_engine eg;
1454  std::uniform_real_distribution<float> ud(-L,L);
1455 
1456  long int k = 4096 * v_cl.getProcessingUnits();
1457 
1458  long int big_step = k / 4;
1459  big_step = (big_step == 0)?1:big_step;
1460 
1461  print_test("Testing 3D periodic vector symmetric cell-list k=",k);
1462  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
1463 
1464  Box<3,float> box({-L,-L,-L},{L,L,L});
1465 
1466  // Boundary conditions
1467  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1468 
1469  float r_cut = 100.0;
1470 
1471  // ghost
1472  Ghost<3,float> ghost(r_cut);
1473  Ghost<3,float> ghost2(r_cut);
1474  ghost2.setLow(0,0.0);
1475  ghost2.setLow(1,0.0);
1476  ghost2.setLow(2,0.0);
1477 
1478  // Point and global id
1479  struct point_and_gid
1480  {
1481  size_t id;
1482  Point<3,float> xq;
1483 
1484  bool operator<(const struct point_and_gid & pag) const
1485  {
1486  return (id < pag.id);
1487  }
1488  };
1489 
1491 
1492  size_t gdist_d[3];
1493  size_t gdist2_d[3];
1494 
1495  gdist_d[0] = 1;
1496  gdist_d[1] = 2;
1497  gdist_d[2] = 5;
1498 
1499  gdist2_d[0] = 1;
1500  gdist2_d[1] = 2;
1501  gdist2_d[2] = 5;
1502 
1503  grid_sm<3,void> gdist(gdist_d);
1504  grid_sm<3,void> gdist2(gdist2_d);
1505 
1506  // Distributed vector
1507  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST,gdist_d);
1508  vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST,gdist2_d);
1509  size_t start = vd.init_size_accum(k);
1510 
1511  test_crs_full(vd,vd2,eg,ud,start,r_cut);
1512 }
1513 
1514 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list )
1515 {
1516  test_csr_verlet_list();
1517 }
1518 
1519 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list_dec_override )
1520 {
1521  test_csr_verlet_list_override();
1522 }
1523 
1524 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list_partit )
1525 {
1526  Vcluster & v_cl = create_vcluster();
1527 
1528  if (v_cl.getProcessingUnits() > 24)
1529  return;
1530 
1531  float L = 1000.0;
1532 
1533  bool ret = true;
1534 
1535  // set the seed
1536  // create the random generator engine
1537  std::srand(0);
1538  std::default_random_engine eg;
1539  std::uniform_real_distribution<float> ud(-L,L);
1540 
1541  long int k = 4096 * v_cl.getProcessingUnits();
1542 
1543  long int big_step = k / 4;
1544  big_step = (big_step == 0)?1:big_step;
1545 
1546  print_test("Testing 3D periodic vector symmetric cell-list k=",k);
1547  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
1548 
1549  Box<3,float> box({-L,-L,-L},{L,L,L});
1550 
1551  // Boundary conditions
1552  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1553 
1554  float r_cut = 100.0;
1555 
1556  // ghost
1557  Ghost<3,float> ghost(r_cut);
1558  Ghost<3,float> ghost2(r_cut);
1559  ghost2.setLow(0,0.0);
1560  ghost2.setLow(1,0.0);
1561  ghost2.setLow(2,0.0);
1562 
1563 
1564  typedef aggregate<size_t> part_prop;
1565 
1566  // Distributed vector
1567  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
1568 
1569  auto it = vd.getIterator();
1570 
1571  while (it.isNext())
1572  {
1573  auto key = it.get();
1574 
1575  vd.getPos(key)[0] = ud(eg);
1576  vd.getPos(key)[1] = ud(eg);
1577  vd.getPos(key)[2] = ud(eg);
1578 
1579  // Fill some properties randomly
1580 
1581  vd.getProp<0>(key) = 0;
1582 
1583  ++it;
1584  }
1585 
1586  vd.map();
1587 
1588  // sync the ghost
1589  vd.ghost_get<0>();
1590 
1591  // We now try symmetric Verlet-list Crs scheme
1592 
1593  auto NN2 = vd.getVerletCrs(r_cut);
1594 
1595  // Because iterating across particles in the CSR scheme require a Cell-list
1596  auto p_it2 = vd.getParticleIteratorCRS_Cell(NN2.getInternalCellList());
1597  auto p_it3 = vd.getParticleIteratorCRS(NN2);
1598 
1599  while (p_it2.isNext())
1600  {
1601  auto p = p_it2.get();
1602  auto p2 = p_it3.get();
1603 
1604  ret &= (p == p2);
1605 
1606  if (ret == false)
1607  break;
1608 
1609  ++p_it2;
1610  ++p_it3;
1611  }
1612 
1613  BOOST_REQUIRE_EQUAL(ret,true);
1614 }
1615 
1616 BOOST_AUTO_TEST_CASE( vector_dist_checking_unloaded_processors )
1617 {
1618  Vcluster & v_cl = create_vcluster();
1619 
1620  if (v_cl.getProcessingUnits() > 24)
1621  return;
1622 
1623  float L = 200.0;
1624 
1625  // set the seed
1626  // create the random generator engine
1627  std::srand(0);
1628  std::default_random_engine eg;
1629  std::uniform_real_distribution<float> ud(0,L);
1630 
1631  long int k = 4096 * v_cl.getProcessingUnits();
1632 
1633  long int big_step = k / 4;
1634  big_step = (big_step == 0)?1:big_step;
1635 
1636  print_test("Testing 3D periodic vector symmetric cell-list (unload processors) k=",k);
1637  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list (unload processors) k=" << k );
1638 
1639  Box<3,float> box({0,0,0},{L,L,L});
1640 
1641  // Boundary conditions
1642  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1643 
1644  float r_cut = 100.0;
1645 
1646  // ghost
1647  Ghost<3,float> ghost(r_cut);
1648  Ghost<3,float> ghost2(r_cut);
1649  ghost2.setLow(0,0.0);
1650  ghost2.setLow(1,0.0);
1651  ghost2.setLow(2,0.0);
1652 
1653 
1654  typedef aggregate<size_t> part_prop;
1655 
1656  // Distributed vector
1657  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
1658 
1659  auto it = vd.getIterator();
1660 
1661  while (it.isNext())
1662  {
1663  auto key = it.get();
1664 
1665  vd.getPos(key)[0] = ud(eg);
1666  vd.getPos(key)[1] = ud(eg);
1667  vd.getPos(key)[2] = ud(eg);
1668 
1669  // Fill some properties randomly
1670 
1671  vd.getProp<0>(key) = 0;
1672 
1673  ++it;
1674  }
1675 
1676  vd.map();
1677 
1678  //
1679  if (v_cl.getProcessingUnits() >= 9)
1680  {
1681  size_t min = vd.size_local();
1682 
1683  v_cl.min(min);
1684  v_cl.execute();
1685 
1686  BOOST_REQUIRE_EQUAL(min,0ul);
1687  }
1688 
1689 
1690  // sync the ghost
1691  vd.ghost_get<0>();
1692 
1693  //
1694  if (v_cl.getProcessingUnits() >= 9)
1695  {
1696  size_t min = vd.size_local_with_ghost() - vd.size_local();
1697 
1698  v_cl.min(min);
1699  v_cl.execute();
1700 
1701  BOOST_REQUIRE_EQUAL(min,0ul);
1702  }
1703 }
1704 
1705 BOOST_AUTO_TEST_CASE( vector_dist_cell_list_multi_type )
1706 {
1707  Vcluster & v_cl = create_vcluster();
1708 
1709  if (v_cl.getProcessingUnits() > 24)
1710  return;
1711 
1712  float L = 1000.0;
1713 
1714  // set the seed
1715  // create the random generator engine
1716  std::srand(0);
1717  std::default_random_engine eg;
1718  std::uniform_real_distribution<float> ud(-L,L);
1719 
1720  long int k = 4096 * v_cl.getProcessingUnits();
1721 
1722  long int big_step = k / 4;
1723  big_step = (big_step == 0)?1:big_step;
1724 
1725  print_test("Testing 3D periodic vector symmetric cell-list k=",k);
1726  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
1727 
1728  Box<3,float> box({-L,-L,-L},{L,L,L});
1729 
1730  // Boundary conditions
1731  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1732 
1733  float r_cut = 100.0;
1734 
1735  // ghost
1736  Ghost<3,float> ghost(r_cut);
1737 
1738  typedef aggregate<size_t> part_prop;
1739 
1740  // Distributed vector
1741  vector_dist<3,float, part_prop > vd(k,box,bc,ghost);
1742 
1743  auto it = vd.getIterator();
1744 
1745  while (it.isNext())
1746  {
1747  auto key = it.get();
1748 
1749  vd.getPos(key)[0] = ud(eg);
1750  vd.getPos(key)[1] = ud(eg);
1751  vd.getPos(key)[2] = ud(eg);
1752 
1753  ++it;
1754  }
1755 
1756  vd.map();
1757 
1758  // sync the ghost
1759  vd.ghost_get<0>();
1760 
1761 
1762  bool ret = true;
1763 
1764  // We take different type of Cell-list
1765  auto NN = vd.getCellList<CELL_MEMFAST(3,float)>(r_cut);
1766  auto NN2 = vd.getCellList<CELL_MEMBAL(3,float)>(r_cut);
1767  auto NN3 = vd.getCellList<CELL_MEMMW(3,float)>(r_cut);
1768 
1769  auto p_it = vd.getDomainIterator();
1770 
1771  while (p_it.isNext())
1772  {
1773  auto p = p_it.get();
1774 
1775  Point<3,float> xp = vd.getPos(p);
1776 
1777  auto Np = NN.getNNIterator(NN.getCell(xp));
1778  auto Np2 = NN2.getNNIterator(NN2.getCell(xp));
1779  auto Np3 = NN3.getNNIterator(NN3.getCell(xp));
1780 
1781  while (Np.isNext())
1782  {
1783  // first all cell-list must agree
1784 
1785  ret &= (Np.isNext() == Np2.isNext()) && (Np3.isNext() == Np.isNext());
1786 
1787  if (ret == false)
1788  break;
1789 
1790  auto q = Np.get();
1791  auto q2 = Np2.get();
1792  auto q3 = Np3.get();
1793 
1794  ret &= (q == q2) && (q == q3);
1795 
1796  if (ret == false)
1797  break;
1798 
1799  ++Np;
1800  ++Np2;
1801  ++Np3;
1802  }
1803 
1804  ret &= (Np.isNext() == Np2.isNext()) && (Np.isNext() == Np3.isNext());
1805 
1806  if (ret == false)
1807  break;
1808 
1809  ++p_it;
1810  }
1811 
1812  BOOST_REQUIRE_EQUAL(ret,true);
1813 }
1814 
1815 #endif /* SRC_VECTOR_VECTOR_DIST_CELL_LIST_TESTS_HPP_ */
auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
size_t getProcessUnitID()
Get the process unit id.
auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void execute()
Execute all the requests.
std::string toString() const
Return the string with the point coordinate.
Definition: Point.hpp:361
This structure define the operation add to use with copy general.
openfpm::vector_key_iterator_seq< typename vrl::local_index_t > getParticleIteratorCRS(vrl &NN)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme...
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:467
VerletList< dim, St, FAST, shift< dim, St > > getVerletCrs(St r_cut)
for each particle get the symmetric verlet list
This structure define the operation add to use with copy general.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
Grid key for a distributed grid.
vector_dist_iterator getIterator()
Get an iterator that traverse domain and ghost particles.
CellL getCellList(St r_cut, bool no_se3=false)
Construct a cell list starting from the stored particles.
size_t size_local_with_ghost() const
return the local size of the vector
Definition: Ghost.hpp:37
Implementation of VCluster class.
Definition: VCluster.hpp:36
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
This class decompose a space into sub-sub-domains and distribute them across processors.
ParticleItCRS_Cells< dim, cli > getParticleIteratorCRS_Cell(cli &NN)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme...
VerletList< dim, St, FAST, shift< dim, St > > getVerlet(St r_cut)
for each particle get the verlet list
const T & get(int i) const
Get coordinate.
Definition: Point.hpp:142
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:456
void map()
It move all the particles that does not belong to the local processor to the respective processor...
size_t getKey() const
Get the key.
This class represent an N-dimensional box.
Definition: Box.hpp:56
T norm()
norm of the vector
Definition: Point.hpp:202
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
size_t size_local() const
return the local size of the vector
auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
Declaration grid_sm.
Definition: grid_sm.hpp:71
Distributed vector.
void min(T &num)
Get the minimum number across all processors (or reduction with insinity norm)
size_t init_size_accum(size_t np)
It return the number of particles contained by the previous processors.
vect_dist_key_dx get()
Get the actual key.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:71
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
size_t getProcessingUnits()
Get the total number of processors.
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.