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