OpenFPM_pdata  5.2.0
Project that contain the implementation of distributed structures
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 
18 template<unsigned int opt> using VERLET_MEMFAST_OPT = VERLET_MEMFAST<3,float,opt>;
19 template<unsigned int opt> using VERLET_MEMBAL_OPT = VERLET_MEMBAL<3,float,opt>;
20 template<unsigned int opt> using VERLET_MEMMW_OPT = VERLET_MEMMW<3,float,opt>;
21 
22 template<unsigned int opt> using VERLET_MEMFAST_INT_OPT = VERLET_MEMFAST_INT<3,float,opt>;
23 template<unsigned int opt> using VERLET_MEMBAL_INT_OPT = VERLET_MEMBAL_INT<3,float,opt>;
24 template<unsigned int opt> using VERLET_MEMMW_INT_OPT = VERLET_MEMMW_INT<3,float,opt>;
25 
27 
28 void test_reorder_sfc(reorder_opt opt)
29 {
30  Vcluster<> & v_cl = create_vcluster();
31 
32  if (v_cl.getProcessingUnits() > 48)
33  return;
34 
35  // set the seed
36  // create the random generator engine
37  std::srand(v_cl.getProcessUnitID());
38  std::default_random_engine eg;
39  std::uniform_real_distribution<float> ud(0.0f, 1.0f);
40 
41 #ifdef TEST_COVERAGE_MODE
42  long int k = 24288 * v_cl.getProcessingUnits();
43 #else
44  long int k = 524288 * v_cl.getProcessingUnits();
45 #endif
46 
47  long int big_step = k / 4;
48  big_step = (big_step == 0)?1:big_step;
49 
50  print_test_v( "Testing 2D vector with sfc curve reordering k<=",k);
51 
52  // 2D test
53  for ( ; k >= 2 ; k-= decrement(k,big_step) )
54  {
55  BOOST_TEST_CHECKPOINT( "Testing 2D vector with sfc curve reordering k=" << k );
56 
57  Box<2,float> box({0.0,0.0},{1.0,1.0});
58 
59  // Boundary conditions
60  size_t bc[2]={NON_PERIODIC,NON_PERIODIC};
61 
63 
64  auto it = vd.getIterator();
65 
66  while (it.isNext())
67  {
68  auto key = it.get();
69 
70  vd.getPos(key)[0] = ud(eg);
71  vd.getPos(key)[1] = ud(eg);
72 
73  ++it;
74  }
75 
76  vd.map();
77 
78  // in case of SE_CLASS3 get a cell-list without ghost get is an error
79 
80  // Create first cell list
81 
82  auto NN1 = vd.getCellList(0.01, CL_NON_SYMMETRIC | CL_LINEAR_CELL_KEYS, true);
83 
84  //An order of a curve
85  int32_t m = 6;
86 
87  //Reorder a vector
88  vd.reorder(m,opt);
89 
90  // Create second cell list
91  auto NN2 = vd.getCellList(0.01, CL_NON_SYMMETRIC | CL_LINEAR_CELL_KEYS, true);
92 
93  //Check equality of cell sizes
94  for (size_t i = 0 ; i < NN1.getGrid().size() ; i++)
95  {
96  size_t n1 = NN1.getNelements(i);
97  size_t n2 = NN2.getNelements(i);
98 
99  BOOST_REQUIRE_EQUAL(n1,n2);
100  }
101  }
102 }
103 
105 
106 void test_reorder_cl()
107 {
108  Vcluster<> & v_cl = create_vcluster();
109 
110  if (v_cl.getProcessingUnits() > 48)
111  return;
112 
113  // set the seed
114  // create the random generator engine
115  std::srand(v_cl.getProcessUnitID());
116  std::default_random_engine eg;
117  std::uniform_real_distribution<float> ud(0.0f, 1.0f);
118 
119 #ifdef TEST_COVERAGE_MODE
120  long int k = 24288 * v_cl.getProcessingUnits();
121 #else
122  long int k = 524288 * v_cl.getProcessingUnits();
123 #endif
124 
125  long int big_step = k / 4;
126  big_step = (big_step == 0)?1:big_step;
127 
128  print_test_v( "Testing 2D vector with sfc curve reordering k<=",k);
129 
130  // 2D test
131  for ( ; k >= 2 ; k-= decrement(k,big_step) )
132  {
133  BOOST_TEST_CHECKPOINT( "Testing 2D vector with sfc curve reordering k=" << k );
134 
135  Box<2,float> box({0.0,0.0},{1.0,1.0});
136 
137  // Boundary conditions
138  size_t bc[2]={NON_PERIODIC,NON_PERIODIC};
139 
141 
142  auto it = vd.getIterator();
143 
144  while (it.isNext())
145  {
146  auto key = it.get();
147 
148  vd.getPos(key)[0] = ud(eg);
149  vd.getPos(key)[1] = ud(eg);
150 
151  ++it;
152  }
153 
154  vd.map();
155 
156  // in case of SE_CLASS3 get a cell-list without ghost get is an error
157 
158  // Create first cell list
159 
160  auto NN1 = vd.getCellList(0.01, CL_NON_SYMMETRIC | CL_LINEAR_CELL_KEYS, true);
161 
162  //Reorder a vector
163  vd.reorder_rcut(0.01);
164 
165  // Create second cell list
166  auto NN2 = vd.getCellList(0.01, CL_NON_SYMMETRIC | CL_LINEAR_CELL_KEYS, true);
167 
168  //Check equality of cell sizes
169  for (size_t i = 0 ; i < NN1.getGrid().size() ; i++)
170  {
171  size_t n1 = NN1.getNelements(i);
172  size_t n2 = NN2.getNelements(i);
173 
174  BOOST_REQUIRE_EQUAL(n1,n2);
175  }
176  }
177 }
178 
179 BOOST_AUTO_TEST_SUITE( vector_dist_cell_list_test_suite )
180 
181 BOOST_AUTO_TEST_CASE( vector_dist_reorder_2d_test )
182 {
183  test_reorder_sfc(reorder_opt::HILBERT);
184  test_reorder_sfc(reorder_opt::LINEAR);
185 }
186 
187 BOOST_AUTO_TEST_CASE( vector_dist_reorder_cl_test )
188 {
189  test_reorder_cl();
190 }
191 
192 BOOST_AUTO_TEST_CASE( vector_dist_cl_random_vs_hilb_forces_test )
193 {
194  Vcluster<> & v_cl = create_vcluster();
195 
196  if (v_cl.getProcessingUnits() > 48)
197  {return;}
198 
200 
201  // Dimensionality of the space
202  const size_t dim = 3;
203  // Cut-off radiuses. Can be put different number of values
204  openfpm::vector<float> cl_r_cutoff {0.05};
205  // The starting amount of particles (remember that this number is multiplied by number of processors you use for testing)
206  size_t cl_k_start = 10000;
207  // The lower threshold for number of particles
208  size_t cl_k_min = 1000;
209  // Ghost part of distributed vector
210  double ghost_part = 0.05;
211 
213 
214  //For different r_cut
215  for (size_t r = 0; r < cl_r_cutoff.size(); r++ )
216  {
217  //Cut-off radius
218  float r_cut = cl_r_cutoff.get(r);
219 
220  //Number of particles
221  size_t k = cl_k_start * v_cl.getProcessingUnits();
222 
223  std::string str("Testing " + std::to_string(dim) + "D vector's forces (random vs hilb celllist) k<=");
224 
225  print_test_v(str,k);
226 
227  //For different number of particles
228  for (size_t k_int = k ; k_int >= cl_k_min ; k_int/=2 )
229  {
230  BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector's forces (random vs hilb celllist) k<=" << k_int );
231 
232  Box<dim,float> box;
233 
234  for (size_t i = 0; i < dim; i++)
235  {
236  box.setLow(i,0.0);
237  box.setHigh(i,1.0);
238  }
239 
240  // Boundary conditions
241  size_t bc[dim];
242 
243  for (size_t i = 0; i < dim; i++)
244  bc[i] = PERIODIC;
245 
246  vector_dist<dim,float, aggregate<float[dim]> > vd(k_int,box,bc,Ghost<dim,float>(ghost_part));
247 
248  vector_dist<dim,float, aggregate<float[dim]> > vd2(k_int,box,bc,Ghost<dim,float>(ghost_part));
249 
250  // Initialize dist vectors
251  vd_initialize_double<dim>(vd, vd2, v_cl, k_int);
252 
253  vd.ghost_get<0>();
254  vd2.ghost_get<0>();
255 
256  //Get a cell list
257 
258  auto NN = vd.getCellList(r_cut);
259 
260  //Calculate forces
261 
262  calc_forces<dim>(NN,vd,r_cut);
263 
264  //Get a cell list hilb
265 
266  auto NN_hilb = vd2.getCellList_hilb(r_cut);
267 
268  //Calculate forces
269  calc_forces_hilb<dim>(NN_hilb,vd2,r_cut);
270 
271  // Calculate average
272  size_t count = 1;
273  Point<dim,float> avg;
274  for (size_t i = 0 ; i < dim ; i++) {avg.get(i) = 0.0;}
275 
276  auto it_v2 = vd.getIterator();
277  while (it_v2.isNext())
278  {
279  //key
280  vect_dist_key_dx key = it_v2.get();
281 
282  for (size_t i = 0; i < dim; i++)
283  {avg.get(i) += fabs(vd.getProp<0>(key)[i]);}
284 
285  ++count;
286  ++it_v2;
287  }
288 
289  for (size_t i = 0 ; i < dim ; i++) {avg.get(i) /= count;}
290 
291  auto it_v = vd.getIterator();
292  while (it_v.isNext())
293  {
294  //key
295  vect_dist_key_dx key = it_v.get();
296 
297  for (size_t i = 0; i < dim; i++)
298  {
299  auto a1 = vd.getProp<0>(key)[i];
300  auto a2 = vd2.getProp<0>(key)[i];
301 
302  //Check that the forces are (almost) equal
303  float per = 0.1;
304  if (a1 != 0.0)
305  per = fabs(0.1*avg.get(i)/a1);
306 
307  BOOST_REQUIRE_CLOSE((float)a1,(float)a2,per);
308  }
309 
310  ++it_v;
311  }
312  }
313  }
314 }
315 
316 BOOST_AUTO_TEST_CASE( vector_dist_cl_random_vs_reorder_forces_test )
317 {
318  Vcluster<> & v_cl = create_vcluster();
319 
320  if (v_cl.getProcessingUnits() > 48)
321  return;
322 
324 
325  // Dimensionality of the space
326  const size_t dim = 3;
327  // Cut-off radiuses. Can be put different number of values
328  openfpm::vector<float> cl_r_cutoff {0.01};
329  // The starting amount of particles (remember that this number is multiplied by number of processors you use for testing)
330  size_t cl_k_start = 10000;
331  // The lower threshold for number of particles
332  size_t cl_k_min = 1000;
333  // Ghost part of distributed vector
334  double ghost_part = 0.01;
335 
337 
338  //For different r_cut
339  for (size_t r = 0; r < cl_r_cutoff.size(); r++ )
340  {
341  //Cut-off radius
342  float r_cut = cl_r_cutoff.get(r);
343 
344  //Number of particles
345  size_t k = cl_k_start * v_cl.getProcessingUnits();
346 
347  std::string str("Testing " + std::to_string(dim) + "D vector's forces (random vs reorder) k<=");
348 
349  print_test_v(str,k);
350 
351  //For different number of particles
352  for (size_t k_int = k ; k_int >= cl_k_min ; k_int/=2 )
353  {
354  BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector's forces (random vs reorder) k<=" << k_int );
355 
356  Box<dim,float> box;
357 
358  for (size_t i = 0; i < dim; i++)
359  {
360  box.setLow(i,0.0);
361  box.setHigh(i,1.0);
362  }
363 
364  // Boundary conditions
365  size_t bc[dim];
366 
367  for (size_t i = 0; i < dim; i++)
368  bc[i] = PERIODIC;
369 
371 
372  // Initialize vd
373  vd_initialize<dim,decltype(vd)>(vd, v_cl);
374 
375  vd.ghost_get<0>();
376 
377  //Get a cell list
378 
379  auto NN1 = vd.getCellList(r_cut);
380 
381  //Calculate forces '0'
382 
383  calc_forces<dim>(NN1,vd,r_cut);
384 
385  //Reorder and get a cell list again
386 
387  vd.reorder(4);
388 
389  vd.ghost_get<0>();
390 
391  auto NN2 = vd.getCellList(r_cut);
392 
393  //Calculate forces '1'
394  calc_forces<dim,1>(NN2,vd,r_cut);
395 
396  // Calculate average (For Coverty scan we start from 1)
397  size_t count = 1;
398  Point<dim,float> avg;
399  for (size_t i = 0 ; i < dim ; i++) {avg.get(i) = 0.0;}
400 
401  auto it_v2 = vd.getIterator();
402  while (it_v2.isNext())
403  {
404  //key
405  vect_dist_key_dx key = it_v2.get();
406 
407  for (size_t i = 0; i < dim; i++)
408  avg.get(i) += fabs(vd.getProp<0>(key)[i]);
409 
410  ++count;
411  ++it_v2;
412  }
413 
414  for (size_t i = 0 ; i < dim ; i++) {avg.get(i) /= count;}
415 
416  //Test for equality of forces
417  auto it_v = vd.getDomainIterator();
418 
419  while (it_v.isNext())
420  {
421  //key
422  vect_dist_key_dx key = it_v.get();
423 
424  for (size_t i = 0; i < dim; i++)
425  {
426  float a1 = vd.getProp<0>(key)[i];
427  float a2 = vd.getProp<1>(key)[i];
428 
429  //Check that the forces are (almost) equal
430  float per = 0.1;
431  if (a1 != 0.0)
432  per = fabs(0.1*avg.get(i)/a1);
433 
434  BOOST_REQUIRE_CLOSE(a1,a2,per);
435  }
436 
437  ++it_v;
438  }
439  }
440  }
441 }
442 
443 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_cell_list )
444 {
445  Vcluster<> & v_cl = create_vcluster();
446 
447  if (v_cl.getProcessingUnits() > 24)
448  return;
449 
450  float L = 1000.0;
451 
452  // set the seed
453  // create the random generator engine
454  std::srand(0);
455  std::default_random_engine eg;
456  std::uniform_real_distribution<float> ud(-L,L);
457 
458  long int k = 4096 * v_cl.getProcessingUnits();
459 
460  long int big_step = k / 4;
461  big_step = (big_step == 0)?1:big_step;
462 
463  print_test_v("Testing 3D periodic vector symmetric cell-list k=",k);
464  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
465 
466  Box<3,float> box({-L,-L,-L},{L,L,L});
467 
468  // Boundary conditions
469  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
470 
471  float r_cut = 100.0;
472 
473  // ghost
474  Ghost<3,float> ghost(r_cut);
475 
476  // Point and global id
477  struct point_and_gid
478  {
479  size_t id;
480  Point<3,float> xq;
481 
482  bool operator<(const struct point_and_gid & pag) const
483  {
484  return (id < pag.id);
485  }
486  };
487 
489 
490  // Distributed vector
491  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
492  size_t start = vd.init_size_accum(k);
493 
494  auto it = vd.getIterator();
495 
496  while (it.isNext())
497  {
498  auto key = it.get();
499 
500  vd.getPosWrite(key)[0] = ud(eg);
501  vd.getPosWrite(key)[1] = ud(eg);
502  vd.getPosWrite(key)[2] = ud(eg);
503 
504  // Fill some properties randomly
505 
506  vd.getPropWrite<0>(key) = 0;
507  vd.getPropWrite<1>(key) = 0;
508  vd.getPropWrite<2>(key) = key.getKey() + start;
509 
510  ++it;
511  }
512 
513  vd.map();
514 
515  // sync the ghost
516  vd.ghost_get<0,2>();
517 
518  auto NN = vd.getCellList(r_cut);
519  auto p_it = vd.getDomainIterator();
520 
521  while (p_it.isNext())
522  {
523  auto p = p_it.get();
524 
525  Point<3,float> xp = vd.getPosRead(p);
526 
527  auto Np = NN.getNNIteratorBox(NN.getCell(xp));
528 
529  while (Np.isNext())
530  {
531  auto q = Np.get();
532 
533  if (p.getKey() == q)
534  {
535  ++Np;
536  continue;
537  }
538 
539  // repulsive
540 
541  Point<3,float> xq = vd.getPosRead(q);
542  Point<3,float> f = (xp - xq);
543 
544  float distance = f.norm();
545 
546  // Particle should be inside 2 * r_cut range
547 
548  if (distance < r_cut )
549  {
550  vd.getPropWrite<0>(p)++;
551  vd.getPropWrite<3>(p).add();
552  vd.getPropWrite<3>(p).last().xq = xq;
553  vd.getPropWrite<3>(p).last().id = vd.getPropWrite<2>(q);
554  }
555 
556  ++Np;
557  }
558 
559  ++p_it;
560  }
561 
562  auto NN2 = vd.getCellListSym(r_cut);
563 
564  auto p_it2 = vd.getDomainIterator();
565 
566  while (p_it2.isNext())
567  {
568  auto p = p_it2.get();
569 
570  Point<3,float> xp = vd.getPosRead(p);
571 
572  auto Np = NN2.getNNIteratorBoxSym(NN2.getCell(xp),p.getKey(),vd.getPosVector());
573 
574  while (Np.isNext())
575  {
576  auto q = Np.get();
577 
578  if (p.getKey() == q)
579  {
580  ++Np;
581  continue;
582  }
583 
584  // repulsive
585 
586  Point<3,float> xq = vd.getPosRead(q);
587  Point<3,float> f = (xp - xq);
588 
589  float distance = f.norm();
590 
591  // Particle should be inside r_cut range
592 
593  if (distance < r_cut )
594  {
595  vd.getPropWrite<1>(p)++;
596  vd.getPropWrite<1>(q)++;
597 
598  vd.getPropWrite<4>(p).add();
599  vd.getPropWrite<4>(q).add();
600 
601  vd.getPropWrite<4>(p).last().xq = xq;
602  vd.getPropWrite<4>(q).last().xq = xp;
603  vd.getPropWrite<4>(p).last().id = vd.getProp<2>(q);
604  vd.getPropWrite<4>(q).last().id = vd.getProp<2>(p);
605  }
606 
607  ++Np;
608  }
609 
610  ++p_it2;
611  }
612 
613  vd.ghost_put<add_,1>();
614  vd.ghost_put<merge_,4>();
615 
616  auto p_it3 = vd.getDomainIterator();
617 
618  bool ret = true;
619  while (p_it3.isNext())
620  {
621  auto p = p_it3.get();
622 
623  ret &= vd.getPropRead<1>(p) == vd.getPropRead<0>(p);
624 
625  vd.getPropWrite<3>(p).sort();
626  vd.getPropWrite<4>(p).sort();
627 
628  ret &= vd.getPropRead<3>(p).size() == vd.getPropRead<4>(p).size();
629 
630  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
631  ret &= vd.getPropRead<3>(p).get(i).id == vd.getPropRead<4>(p).get(i).id;
632 
633  if (ret == false)
634  {
635  std::cout << vd.getPropRead<3>(p).size() << " " << vd.getPropRead<4>(p).size() << std::endl;
636 
637  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
638  std::cout << vd.getPropRead<3>(p).get(i).id << " " << vd.getPropRead<4>(p).get(i).id << std::endl;
639 
640  std::cout << vd.getPropRead<1>(p) << " A " << vd.getPropRead<0>(p) << std::endl;
641 
642  break;
643  }
644 
645  ++p_it3;
646  }
647 
648  BOOST_REQUIRE_EQUAL(ret,true);
649 }
650 
651 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_local_cell_list )
652 {
653  Vcluster<> & v_cl = create_vcluster();
654 
655  if (v_cl.getProcessingUnits() > 24)
656  return;
657 
658  float L = 1000.0;
659 
660  // set the seed
661  // create the random generator engine
662  std::srand(0);
663  std::default_random_engine eg;
664  std::uniform_real_distribution<float> ud(-L,L);
665 
666  long int k = 4096 * v_cl.getProcessingUnits();
667 
668  long int big_step = k / 4;
669  big_step = (big_step == 0)?1:big_step;
670 
671  print_test_v("Testing 3D periodic vector symmetric cell-list k=",k);
672  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
673 
674  Box<3,float> box({-L,-L,-L},{L,L,L});
675 
676  // Boundary conditions
677  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
678 
679  float r_cut = 100.0;
680 
681  // ghost
682  Ghost<3,float> ghost(r_cut);
683 
684  // Point and global id
685  struct point_and_gid
686  {
687  size_t id;
688  Point<3,float> xq;
689 
690  bool operator<(const struct point_and_gid & pag) const
691  {
692  return (id < pag.id);
693  }
694  };
695 
697 
698  // Distributed vector
699  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
700  size_t start = vd.init_size_accum(k);
701 
702  auto it = vd.getIterator();
703 
704  while (it.isNext())
705  {
706  auto key = it.get();
707 
708  vd.getPosWrite(key)[0] = ud(eg);
709  vd.getPosWrite(key)[1] = ud(eg);
710  vd.getPosWrite(key)[2] = ud(eg);
711 
712  // Fill some properties randomly
713 
714  vd.getPropWrite<0>(key) = 0;
715  vd.getPropWrite<1>(key) = 0;
716  vd.getPropWrite<2>(key) = key.getKey() + start;
717 
718  ++it;
719  }
720 
721  vd.map();
722 
723  // sync the ghost
724  vd.ghost_get<0,2>();
725 
726 
727  auto NN = vd.getCellList(r_cut);
728  auto p_it = vd.getDomainIterator();
729 
730  while (p_it.isNext())
731  {
732  auto p = p_it.get();
733 
734  Point<3,float> xp = vd.getPosRead(p);
735 
736  auto Np = NN.getNNIteratorBox(NN.getCell(xp));
737 
738  while (Np.isNext())
739  {
740  auto q = Np.get();
741 
742  if (p.getKey() == q)
743  {
744  ++Np;
745  continue;
746  }
747 
748  // repulsive
749 
750  Point<3,float> xq = vd.getPosRead(q);
751  Point<3,float> f = (xp - xq);
752 
753  float distance = f.norm();
754 
755  // Particle should be inside 2 * r_cut range
756 
757  if (distance < r_cut )
758  {
759  vd.getPropWrite<0>(p)++;
760  vd.getPropWrite<3>(p).add();
761  vd.getPropWrite<3>(p).last().xq = xq;
762  vd.getPropWrite<3>(p).last().id = vd.getPropWrite<2>(q);
763  }
764 
765  ++Np;
766  }
767 
768  ++p_it;
769  }
770 
771  auto NN2 = vd.getCellListSymLocal(r_cut);
772 
773  auto p_it2 = vd.getDomainIterator();
774 
775  while (p_it2.isNext())
776  {
777  auto p = p_it2.get();
778 
779  Point<3,float> xp = vd.getPosRead(p);
780 
781  auto Np = NN2.getNNIteratorBoxSymLocal(NN2.getCell(xp),p.getKey(),vd.getPosVector());
782 
783  while (Np.isNext())
784  {
785  auto q = Np.get();
786 
787  if (p.getKey() == q)
788  {
789  ++Np;
790  continue;
791  }
792 
793  // repulsive
794 
795  Point<3,float> xq = vd.getPosRead(q);
796  Point<3,float> f = (xp - xq);
797 
798  float distance = f.norm();
799 
800  // Particle should be inside r_cut range
801 
802  if (distance < r_cut )
803  {
804  vd.getPropWrite<1>(p)++;
805  vd.getPropWrite<1>(q)++;
806 
807  vd.getPropWrite<4>(p).add();
808  vd.getPropWrite<4>(q).add();
809 
810  vd.getPropWrite<4>(p).last().xq = xq;
811  vd.getPropWrite<4>(q).last().xq = xp;
812  vd.getPropWrite<4>(p).last().id = vd.getProp<2>(q);
813  vd.getPropWrite<4>(q).last().id = vd.getProp<2>(p);
814 
815  }
816 
817  ++Np;
818  }
819 
820  ++p_it2;
821  }
822 
823  auto p_it3 = vd.getDomainIterator();
824 
825  bool ret = true;
826  while (p_it3.isNext())
827  {
828  auto p = p_it3.get();
829 
830  ret &= vd.getPropRead<1>(p) == vd.getPropRead<0>(p);
831 
832  vd.getPropWrite<3>(p).sort();
833  vd.getPropWrite<4>(p).sort();
834 
835  ret &= vd.getPropRead<3>(p).size() == vd.getPropRead<4>(p).size();
836 
837  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
838  ret &= vd.getPropRead<3>(p).get(i).id == vd.getPropRead<4>(p).get(i).id;
839 
840  if (ret == false)
841  {
842  std::cout << vd.getPropRead<3>(p).size() << " " << vd.getPropRead<4>(p).size() << std::endl;
843 
844  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
845  std::cout << vd.getPropRead<3>(p).get(i).id << " " << vd.getPropRead<4>(p).get(i).id << std::endl;
846 
847  std::cout << vd.getPropRead<1>(p) << " A " << vd.getPropRead<0>(p) << std::endl;
848 
849  break;
850  }
851 
852  ++p_it3;
853  }
854 
855  BOOST_REQUIRE_EQUAL(ret,true);
856 }
857 
858 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_cell_list )
859 {
860  Vcluster<> & v_cl = create_vcluster();
861 
862  if (v_cl.getProcessingUnits() > 24)
863  return;
864 
865  float L = 1000.0;
866 
867  // set the seed
868  // create the random generator engine
869  std::default_random_engine eg(1132312*v_cl.getProcessUnitID());
870  std::uniform_real_distribution<float> ud(-L,L);
871 
872  long int k = 4096 * v_cl.getProcessingUnits();
873 
874  long int big_step = k / 4;
875  big_step = (big_step == 0)?1:big_step;
876 
877  print_test_v("Testing 3D periodic vector symmetric crs cell-list k=",k);
878  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric crs cell-list k=" << k );
879 
880  Box<3,float> box({-L,-L,-L},{L,L,L});
881 
882  // Boundary conditions
883  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
884 
885  float r_cut = 100.0;
886 
887  // ghost
888  Ghost<3,float> ghost(r_cut);
889  Ghost<3,float> ghost2(r_cut);
890  ghost2.setLow(0,0.0);
891  ghost2.setLow(1,0.0);
892  ghost2.setLow(2,0.0);
893 
894  // Point and global id
895  struct point_and_gid
896  {
897  size_t id;
898  Point<3,float> xq;
899 
900  bool operator<(const struct point_and_gid & pag) const
901  {
902  return (id < pag.id);
903  }
904  };
905 
907 
908  // Distributed vector
909  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
910  vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST);
911  size_t start = vd.init_size_accum(k);
912 
913  auto it = vd.getIterator();
914 
915  while (it.isNext())
916  {
917  auto key = it.get();
918 
919  vd.getPosWrite(key)[0] = ud(eg);
920  vd.getPosWrite(key)[1] = ud(eg);
921  vd.getPosWrite(key)[2] = ud(eg);
922 
923  vd2.getPosWrite(key)[0] = vd.getPosRead(key)[0];
924  vd2.getPosWrite(key)[1] = vd.getPosRead(key)[1];
925  vd2.getPosWrite(key)[2] = vd.getPosRead(key)[2];
926 
927  // Fill some properties randomly
928 
929  vd.getPropWrite<0>(key) = 0;
930  vd.getPropWrite<1>(key) = 0;
931  vd.getPropWrite<2>(key) = key.getKey() + start;
932 
933  vd2.getPropWrite<0>(key) = 0;
934  vd2.getPropWrite<1>(key) = 0;
935  vd2.getPropWrite<2>(key) = key.getKey() + start;
936 
937  ++it;
938  }
939 
940  vd.map();
941  vd2.map();
942 
943  // sync the ghost
944  vd.ghost_get<0,2>();
945  vd2.ghost_get<0,2>();
946 
947  auto NN = vd.getCellList(r_cut);
948  auto p_it = vd.getDomainIterator();
949 
950  while (p_it.isNext())
951  {
952  auto p = p_it.get();
953 
954  Point<3,float> xp = vd.getPosRead(p);
955 
956  auto Np = NN.getNNIteratorBox(NN.getCell(xp));
957 
958  while (Np.isNext())
959  {
960  auto q = Np.get();
961 
962  if (p.getKey() == q)
963  {
964  ++Np;
965  continue;
966  }
967 
968  // repulsive
969 
970  Point<3,float> xq = vd.getPosRead(q);
971  Point<3,float> f = (xp - xq);
972 
973  float distance = f.norm();
974 
975  // Particle should be inside 2 * r_cut range
976 
977  if (distance < r_cut )
978  {
979  vd.getPropWrite<0>(p)++;
980  vd.getPropWrite<3>(p).add();
981  vd.getPropWrite<3>(p).last().xq = xq;
982  vd.getPropWrite<3>(p).last().id = vd.getPropRead<2>(q);
983  }
984 
985  ++Np;
986  }
987 
988  ++p_it;
989  }
990 
991  // We now try symmetric Cell-list
992 
993  auto NN2 = vd2.getCellListSym(r_cut);
994 
995  // In case of CRS we have to iterate particles within some cells
996  // here we define whichone
997  auto p_it2 = vd2.getParticleIteratorCRS_Cell(NN2);
998 
999  // For each particle
1000  while (p_it2.isNext())
1001  {
1002  auto p = p_it2.get();
1003 
1004  Point<3,float> xp = vd2.getPosRead(p);
1005 
1006  auto Np = p_it2.getNNIteratorCSR(vd2.getPosVector());
1007 
1008  while (Np.isNext())
1009  {
1010  auto q = Np.get();
1011 
1012  if (p == q)
1013  {
1014  ++Np;
1015  continue;
1016  }
1017 
1018  // repulsive
1019 
1020  Point<3,float> xq = vd2.getPosRead(q);
1021  Point<3,float> f = (xp - xq);
1022 
1023  float distance = f.norm();
1024 
1025  // Particle should be inside r_cut range
1026 
1027  if (distance < r_cut )
1028  {
1029  vd2.getPropWrite<1>(p)++;
1030  vd2.getPropWrite<1>(q)++;
1031 
1032  vd2.getPropWrite<4>(p).add();
1033  vd2.getPropWrite<4>(q).add();
1034 
1035  vd2.getPropWrite<4>(p).last().xq = xq;
1036  vd2.getPropWrite<4>(q).last().xq = xp;
1037  vd2.getPropWrite<4>(p).last().id = vd2.getPropRead<2>(q);
1038  vd2.getPropWrite<4>(q).last().id = vd2.getPropRead<2>(p);
1039  }
1040 
1041  ++Np;
1042  }
1043 
1044  ++p_it2;
1045  }
1046 
1047  vd2.ghost_put<add_,1>(NO_CHANGE_ELEMENTS);
1048  vd2.ghost_put<merge_,4>();
1049 
1050 #ifdef SE_CLASS3
1051  vd2.getDomainIterator();
1052 #endif
1053 
1054  auto p_it3 = vd.getDomainIterator();
1055 
1056  bool ret = true;
1057  while (p_it3.isNext())
1058  {
1059  auto p = p_it3.get();
1060 
1061  ret &= vd2.getPropRead<1>(p) == vd.getPropRead<0>(p);
1062 
1063 
1064  vd.getPropWrite<3>(p).sort();
1065  vd2.getPropWrite<4>(p).sort();
1066 
1067  ret &= vd.getPropRead<3>(p).size() == vd2.getPropRead<4>(p).size();
1068 
1069  for (size_t i = 0 ; i < vd.getPropRead<3>(p).size() ; i++)
1070  ret &= vd.getPropRead<3>(p).get(i).id == vd2.getPropRead<4>(p).get(i).id;
1071 
1072  if (ret == false)
1073  break;
1074 
1075  ++p_it3;
1076  }
1077 
1078  BOOST_REQUIRE_EQUAL(ret,true);
1079 }
1080 
1081 template<template <unsigned int> class VerletList>
1082 void test_vd_symmetric_verlet_list()
1083 {
1084  Vcluster<> & v_cl = create_vcluster();
1085 
1086  if (v_cl.getProcessingUnits() > 24)
1087  return;
1088 
1089  float L = 1000.0;
1090 
1091  // set the seed
1092  // create the random generator engine
1093  std::srand(0);
1094  std::default_random_engine eg;
1095  std::uniform_real_distribution<float> ud(-L,L);
1096 
1097  long int k = 4096 * v_cl.getProcessingUnits();
1098 
1099  long int big_step = k / 4;
1100  big_step = (big_step == 0)?1:big_step;
1101 
1102  print_test_v("Testing 3D periodic vector symmetric cell-list k=",k);
1103  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric verlet-list k=" << k );
1104 
1105  Box<3,float> box({-L,-L,-L},{L,L,L});
1106 
1107  // Boundary conditions
1108  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1109 
1110  float r_cut = 100.0;
1111 
1112  // ghost
1113  Ghost<3,float> ghost(r_cut);
1114 
1115  // Point and global id
1116  struct point_and_gid
1117  {
1118  size_t id;
1119  Point<3,float> xq;
1120 
1121  bool operator<(const struct point_and_gid & pag) const
1122  {
1123  return (id < pag.id);
1124  }
1125  };
1126 
1128 
1129  // Distributed vector
1130  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
1131  size_t start = vd.init_size_accum(k);
1132 
1133  auto it = vd.getIterator();
1134 
1135  while (it.isNext())
1136  {
1137  auto key = it.get();
1138 
1139  vd.getPosWrite(key)[0] = ud(eg);
1140  vd.getPosWrite(key)[1] = ud(eg);
1141  vd.getPosWrite(key)[2] = ud(eg);
1142 
1143  // Fill some properties randomly
1144 
1145  vd.template getPropWrite<0>(key) = 0;
1146  vd.template getPropWrite<1>(key) = 0;
1147  vd.template getPropWrite<2>(key) = key.getKey() + start;
1148 
1149  ++it;
1150  }
1151 
1152  vd.map();
1153 
1154  // sync the ghost
1155  vd.template ghost_get<0,2>();
1156 
1157  auto NN = vd.template getVerlet<VL_NON_SYMMETRIC, VerletList<VL_NON_SYMMETRIC>>(r_cut);
1158  auto p_it = vd.getDomainIterator();
1159 
1160  while (p_it.isNext())
1161  {
1162  auto p = p_it.get();
1163 
1164  Point<3,float> xp = vd.getPosRead(p);
1165 
1166  auto Np = NN.getNNIterator(p.getKey());
1167 
1168  while (Np.isNext())
1169  {
1170  auto q = Np.get();
1171 
1172  if (p.getKey() == q)
1173  {
1174  ++Np;
1175  continue;
1176  }
1177 
1178  // repulsive
1179 
1180  Point<3,float> xq = vd.getPosRead(q);
1181  Point<3,float> f = (xp - xq);
1182 
1183  float distance = f.norm();
1184 
1185  // Particle should be inside 2 * r_cut range
1186 
1187  if (distance < r_cut )
1188  {
1189  vd.template getPropWrite<0>(p)++;
1190  vd.template getPropWrite<3>(p).add();
1191  vd.template getPropWrite<3>(p).last().xq = xq;
1192  vd.template getPropWrite<3>(p).last().id = vd.template getPropRead<2>(q);
1193  }
1194 
1195  ++Np;
1196  }
1197 
1198  ++p_it;
1199  }
1200 
1201  // We now try symmetric Cell-list
1202 
1203  auto NN2 = vd.template getVerletSym<VerletList<VL_SYMMETRIC>>(r_cut);
1204 
1205  auto p_it2 = vd.getDomainIterator();
1206 
1207  while (p_it2.isNext())
1208  {
1209  auto p = p_it2.get();
1210 
1211  Point<3,float> xp = vd.getPosRead(p);
1212 
1213  auto Np = NN2.getNNIterator(p.getKey());
1214 
1215  while (Np.isNext())
1216  {
1217  auto q = Np.get();
1218 
1219  if (p.getKey() == q)
1220  {
1221  ++Np;
1222  continue;
1223  }
1224 
1225  // repulsive
1226 
1227  Point<3,float> xq = vd.getPosRead(q);
1228  Point<3,float> f = (xp - xq);
1229 
1230  float distance = f.norm();
1231 
1232  // Particle should be inside r_cut range
1233 
1234  if (distance < r_cut )
1235  {
1236  vd.template getPropWrite<1>(p)++;
1237  vd.template getPropWrite<1>(q)++;
1238 
1239  vd.template getPropWrite<4>(p).add();
1240  vd.template getPropWrite<4>(q).add();
1241 
1242  vd.template getPropWrite<4>(p).last().xq = xq;
1243  vd.template getPropWrite<4>(q).last().xq = xp;
1244  vd.template getPropWrite<4>(p).last().id = vd.template getPropRead<2>(q);
1245  vd.template getPropWrite<4>(q).last().id = vd.template getPropRead<2>(p);
1246  }
1247 
1248  ++Np;
1249  }
1250 
1251  ++p_it2;
1252  }
1253 
1254  vd.template ghost_put<add_,1>();
1255  vd.template ghost_put<merge_,4>();
1256 
1257  auto p_it3 = vd.getDomainIterator();
1258 
1259  bool ret = true;
1260  while (p_it3.isNext())
1261  {
1262  auto p = p_it3.get();
1263 
1264  ret &= vd.template getPropRead<1>(p) == vd.template getPropRead<0>(p);
1265 
1266  vd.template getPropWrite<3>(p).sort();
1267  vd.template getPropWrite<4>(p).sort();
1268 
1269  ret &= vd.template getPropRead<3>(p).size() == vd.template getPropRead<4>(p).size();
1270 
1271  for (size_t i = 0 ; i < vd.template getPropRead<3>(p).size() ; i++)
1272  ret &= vd.template getPropRead<3>(p).get(i).id == vd.template getPropRead<4>(p).get(i).id;
1273 
1274  if (ret == false)
1275  break;
1276 
1277  ++p_it3;
1278  }
1279 
1280  BOOST_REQUIRE_EQUAL(ret,true);
1281 }
1282 
1283 template<template <unsigned int> class VerletList>
1284 void test_vd_adaptive_verlet_list()
1285 {
1286  Vcluster<> & v_cl = create_vcluster();
1287 
1288  if (v_cl.getProcessingUnits() > 24)
1289  return;
1290 
1291  float L = 1000.0;
1292  float r_cut = 100.0;
1293 
1294  // set the seed
1295  // create the random generator engine
1296  std::srand(0);
1297  std::default_random_engine eg;
1298  std::uniform_real_distribution<float> ud(-L,L);
1299  std::uniform_real_distribution<float> rCutDistr(0,r_cut);
1300 
1301  long int k = 4096 * v_cl.getProcessingUnits();
1302 
1303  print_test_v("Testing 3D periodic vector adaptive verlet-list k=",k);
1304  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector adaptive verlet-list k=" << k );
1305 
1306  Box<3,float> box({-L,-L,-L},{L,L,L});
1307 
1308  // Boundary conditions
1309  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1310 
1311  // ghost
1312  Ghost<3,float> ghost(r_cut);
1313 
1314  // Point and global id
1315  struct point_and_gid
1316  {
1317  size_t id;
1318  Point<3,float> xq;
1319 
1320  bool operator<(const struct point_and_gid & pag) const
1321  {
1322  return (id < pag.id);
1323  }
1324  };
1325 
1327 
1328  // Distributed vector
1329  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
1330  size_t start = vd.init_size_accum(k);
1331 
1332  auto it = vd.getIterator();
1333 
1334  while (it.isNext())
1335  {
1336  auto key = it.get();
1337 
1338  vd.getPosWrite(key)[0] = ud(eg);
1339  vd.getPosWrite(key)[1] = ud(eg);
1340  vd.getPosWrite(key)[2] = ud(eg);
1341 
1342  // Fill some properties randomly
1343 
1344  vd.template getPropWrite<1>(key) = 0;
1345  vd.template getPropWrite<2>(key) = 0;
1346  vd.template getPropWrite<3>(key) = key.getKey() + start;
1347  // rCut is always stored in the first property
1348  vd.template getPropWrite<0>(key) = rCutDistr(eg);
1349 
1350  ++it;
1351  }
1352 
1353  vd.map();
1354 
1355  // sync the ghost
1356  vd.template ghost_get<1,3>();
1357 
1358  auto NN = vd.getVerletAdaptRCut();
1359  auto p_it = vd.getDomainIterator();
1360 
1361  while (p_it.isNext())
1362  {
1363  auto p = p_it.get();
1364 
1365  Point<3,float> xp = vd.getPosRead(p);
1366 
1367  auto Np = NN.getNNIterator(p.getKey());
1368 
1369  while (Np.isNext())
1370  {
1371  auto q = Np.get();
1372  float rCutP = vd.template getPropRead<0>(p);
1373 
1374  if (p.getKey() == q)
1375  {
1376  ++Np;
1377  continue;
1378  }
1379 
1380  // repulsive
1381 
1382  Point<3,float> xq = vd.getPosRead(q);
1383  Point<3,float> f = (xp - xq);
1384 
1385  float distance = f.norm();
1386 
1387  // Particle should be inside rCutP range
1388 
1389  if (distance < rCutP )
1390  {
1391  vd.template getPropWrite<1>(p)++;
1392  vd.template getPropWrite<4>(p).add();
1393  vd.template getPropWrite<4>(p).last().xq = xq;
1394  vd.template getPropWrite<4>(p).last().id = vd.template getPropRead<3>(q);
1395  }
1396 
1397  ++Np;
1398  }
1399 
1400  ++p_it;
1401  }
1402 
1403  auto p_it2 = vd.getDomainIterator();
1404 
1405  while (p_it2.isNext())
1406  {
1407  auto p = p_it2.get();
1408 
1409  Point<3,float> xp = vd.getPosRead(p);
1410 
1411  auto p_it3 = vd.getDomainAndGhostIterator();
1412  float rCutP = vd.template getPropRead<0>(p);
1413 
1414  while (p_it3.isNext())
1415  {
1416  auto q = p_it3.get().getKey();
1417 
1418  if (p.getKey() == q)
1419  {
1420  ++p_it3;
1421  continue;
1422  }
1423 
1424  // repulsive
1425 
1426  Point<3,float> xq = vd.getPosRead(q);
1427  Point<3,float> f = (xp - xq);
1428 
1429  float distance = f.norm();
1430 
1431  // Particle should be inside rCutP range
1432 
1433  if (distance < rCutP )
1434  {
1435  vd.template getPropWrite<2>(p)++;
1436 
1437  vd.template getPropWrite<5>(p).add();
1438 
1439  vd.template getPropWrite<5>(p).last().xq = xq;
1440  vd.template getPropWrite<5>(p).last().id = vd.template getPropRead<3>(q);
1441  }
1442 
1443  ++p_it3;
1444  }
1445 
1446  ++p_it2;
1447  }
1448 
1449  vd.template ghost_put<add_,2>();
1450  vd.template ghost_put<merge_,5>();
1451 
1452  auto p_it4 = vd.getDomainIterator();
1453 
1454  bool ret = true;
1455  while (p_it4.isNext())
1456  {
1457  auto p = p_it4.get();
1458 
1459  ret &= vd.template getPropRead<2>(p) == vd.template getPropRead<1>(p);
1460 
1461  vd.template getPropWrite<4>(p).sort();
1462  vd.template getPropWrite<5>(p).sort();
1463 
1464  ret &= vd.template getPropRead<4>(p).size() == vd.template getPropRead<5>(p).size();
1465  ret &= fabs(vd.template getPropRead<0>(p) - NN.getRCuts(p)) < 0.001;
1466 
1467  for (size_t i = 0 ; i < vd.template getPropRead<4>(p).size() ; i++) {
1468  ret &= vd.template getPropRead<4>(p).get(i).id == vd.template getPropRead<5>(p).get(i).id;
1469  auto xq = vd.template getPropRead<4>(p).get(i).xq;
1470  }
1471 
1472  if (ret == false)
1473  break;
1474 
1475  ++p_it4;
1476  }
1477 
1478  BOOST_REQUIRE_EQUAL(ret,true);
1479 }
1480 
1481 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_verlet_list )
1482 {
1483  test_vd_symmetric_verlet_list<VERLET_MEMFAST_OPT>();
1484  test_vd_symmetric_verlet_list<VERLET_MEMBAL_OPT>();
1485  test_vd_symmetric_verlet_list<VERLET_MEMMW_OPT>();
1486 }
1487 
1488 BOOST_AUTO_TEST_CASE( vector_dist_adaptive_verlet_list )
1489 {
1490  test_vd_adaptive_verlet_list<VERLET_MEMFAST_OPT>();
1491  test_vd_adaptive_verlet_list<VERLET_MEMBAL_OPT>();
1492  test_vd_adaptive_verlet_list<VERLET_MEMMW_OPT>();
1493 }
1494 
1495 template<template <unsigned int> class VerletList>
1496 void vector_sym_verlet_list_nb()
1497 {
1498  Vcluster<> & v_cl = create_vcluster();
1499 
1500  if (v_cl.getProcessingUnits() > 24)
1501  return;
1502 
1503  float L = 1000.0;
1504 
1505  // set the seed
1506  // create the random generator engine
1507  std::srand(0);
1508  std::default_random_engine eg;
1509  std::uniform_real_distribution<float> ud(-L,L);
1510 
1511  long int k = 4096 * v_cl.getProcessingUnits();
1512 
1513  long int big_step = k / 4;
1514  big_step = (big_step == 0)?1:big_step;
1515 
1516  print_test_v("Testing 3D periodic vector symmetric cell-list no bottom k=",k);
1517  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list no bottom k=" << k );
1518 
1519  Box<3,float> box({-L,-L,-L},{L,L,L});
1520 
1521  // Boundary conditions
1522  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1523 
1524  float r_cut = 100.0;
1525 
1526  // ghost
1527  Ghost<3,float> ghost(r_cut);
1528  Ghost<3,float> ghost2(r_cut);
1529  ghost2.setLow(2,0.0);
1530 
1531  // Point and global id
1532  struct point_and_gid
1533  {
1534  size_t id;
1535  Point<3,float> xq;
1536 
1537  bool operator<(const struct point_and_gid & pag) const
1538  {
1539  return (id < pag.id);
1540  }
1541  };
1542 
1544 
1545  // 3D test
1546  for (size_t s = 0 ; s < 8 ; s++)
1547  {
1548 
1549  // Distributed vector
1550  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
1551  vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST);
1552  size_t start = vd.init_size_accum(k);
1553 
1554  auto it = vd.getIterator();
1555 
1556  while (it.isNext())
1557  {
1558  auto key = it.get();
1559 
1560  vd.getPosWrite(key)[0] = ud(eg);
1561  vd.getPosWrite(key)[1] = ud(eg);
1562  vd.getPosWrite(key)[2] = ud(eg);
1563 
1564  vd2.getPosWrite(key)[0] = vd.getPosRead(key)[0];
1565  vd2.getPosWrite(key)[1] = vd.getPosRead(key)[1];
1566  vd2.getPosWrite(key)[2] = vd.getPosRead(key)[2];
1567 
1568  // Fill some properties randomly
1569 
1570  vd.template getPropWrite<0>(key) = 0;
1571  vd.template getPropWrite<1>(key) = 0;
1572  vd.template getPropWrite<2>(key) = key.getKey() + start;
1573 
1574  vd2.template getPropWrite<0>(key) = 0;
1575  vd2.template getPropWrite<1>(key) = 0;
1576  vd2.template getPropWrite<2>(key) = key.getKey() + start;
1577 
1578  ++it;
1579  }
1580 
1581  vd.map();
1582  vd2.map();
1583 
1584  // sync the ghost
1585  vd.template ghost_get<0,2>();
1586  vd2.template ghost_get<0,2>();
1587 
1588  auto NN = vd.template getVerlet<VL_NON_SYMMETRIC, VerletList<VL_NON_SYMMETRIC>>(r_cut);
1589  auto p_it = vd.getDomainIterator();
1590 
1591  while (p_it.isNext())
1592  {
1593  auto p = p_it.get();
1594 
1595  Point<3,float> xp = vd.getPosRead(p);
1596 
1597  auto Np = NN.getNNIterator(p.getKey());
1598 
1599  while (Np.isNext())
1600  {
1601  auto q = Np.get();
1602 
1603  if (p.getKey() == q)
1604  {
1605  ++Np;
1606  continue;
1607  }
1608 
1609  // repulsive
1610 
1611  Point<3,float> xq = vd.getPosRead(q);
1612  Point<3,float> f = (xp - xq);
1613 
1614  float distance = f.norm();
1615 
1616  // Particle should be inside 2 * r_cut range
1617 
1618  if (distance < r_cut )
1619  {
1620  vd.template getPropWrite<0>(p)++;
1621  vd.template getPropWrite<3>(p).add();
1622  vd.template getPropWrite<3>(p).last().xq = xq;
1623  vd.template getPropWrite<3>(p).last().id = vd.template getPropRead<2>(q);
1624  }
1625 
1626  ++Np;
1627  }
1628 
1629  ++p_it;
1630  }
1631 
1632  // We now try symmetric Cell-list
1633 
1634  auto NN2 = vd2.template getVerletSym<VerletList<VL_SYMMETRIC>>(r_cut);
1635 
1636  auto p_it2 = vd2.getDomainIterator();
1637 
1638  while (p_it2.isNext())
1639  {
1640  auto p = p_it2.get();
1641 
1642  Point<3,float> xp = vd2.getPosRead(p);
1643 
1644  auto Np = NN2.getNNIterator(p.getKey());
1645 
1646  while (Np.isNext())
1647  {
1648  auto q = Np.get();
1649 
1650  if (p.getKey() == q)
1651  {
1652  ++Np;
1653  continue;
1654  }
1655 
1656  // repulsive
1657 
1658  Point<3,float> xq = vd2.getPosRead(q);
1659  Point<3,float> f = (xp - xq);
1660 
1661  float distance = f.norm();
1662 
1663  // Particle should be inside r_cut range
1664 
1665  if (distance < r_cut )
1666  {
1667  vd2.template getPropWrite<1>(p)++;
1668  vd2.template getPropWrite<1>(q)++;
1669 
1670  vd2.template getPropWrite<4>(p).add();
1671  vd2.template getPropWrite<4>(q).add();
1672 
1673  vd2.template getPropWrite<4>(p).last().xq = xq;
1674  vd2.template getPropWrite<4>(q).last().xq = xp;
1675  vd2.template getPropWrite<4>(p).last().id = vd2.template getPropRead<2>(q);
1676  vd2.template getPropWrite<4>(q).last().id = vd2.template getPropRead<2>(p);
1677  }
1678 
1679  ++Np;
1680  }
1681 
1682 
1683  ++p_it2;
1684  }
1685 
1686  vd2.template ghost_put<add_,1>();
1687  vd2.template ghost_put<merge_,4>();
1688 
1689 #ifdef SE_CLASS3
1690  vd2.getDomainIterator();
1691 #endif
1692 
1693  auto p_it3 = vd.getDomainIterator();
1694 
1695  bool ret = true;
1696  while (p_it3.isNext())
1697  {
1698  auto p = p_it3.get();
1699 
1700  ret &= vd2.template getPropRead<1>(p) == vd.template getPropRead<0>(p);
1701 
1702  vd.template getPropWrite<3>(p).sort();
1703  vd2.template getPropWrite<4>(p).sort();
1704 
1705  ret &= vd.template getPropRead<3>(p).size() == vd2.template getPropRead<4>(p).size();
1706 
1707  for (size_t i = 0 ; i < vd.template getPropRead<3>(p).size() ; i++)
1708  ret &= vd.template getPropRead<3>(p).get(i).id == vd2.template getPropRead<4>(p).get(i).id;
1709 
1710  if (ret == false)
1711  break;
1712 
1713  ++p_it3;
1714  }
1715 
1716  BOOST_REQUIRE_EQUAL(ret,true);
1717  }
1718 }
1719 
1720 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_verlet_list_no_bottom )
1721 {
1722  vector_sym_verlet_list_nb<VERLET_MEMFAST_OPT>();
1723  vector_sym_verlet_list_nb<VERLET_MEMBAL_OPT>();
1724  vector_sym_verlet_list_nb<VERLET_MEMMW_OPT>();
1725 
1726  vector_sym_verlet_list_nb<VERLET_MEMFAST_INT_OPT>();
1727  vector_sym_verlet_list_nb<VERLET_MEMBAL_INT_OPT>();
1728  vector_sym_verlet_list_nb<VERLET_MEMMW_INT_OPT>();
1729 }
1730 
1731 template<template <unsigned int> class VerletList, typename part_prop>
1732 void test_crs_full(
1735  std::default_random_engine & eg,
1736  std::uniform_real_distribution<float> & ud,
1737  size_t start,
1738  float r_cut)
1739 {
1740  auto it = vd.getIterator();
1741 
1742  while (it.isNext())
1743  {
1744  auto key = it.get();
1745 
1746  vd.getPosWrite(key)[0] = ud(eg);
1747  vd.getPosWrite(key)[1] = ud(eg);
1748  vd.getPosWrite(key)[2] = ud(eg);
1749 
1750  vd2.getPosWrite(key)[0] = vd.getPosRead(key)[0];
1751  vd2.getPosWrite(key)[1] = vd.getPosRead(key)[1];
1752  vd2.getPosWrite(key)[2] = vd.getPosRead(key)[2];
1753 
1754  // Fill some properties randomly
1755 
1756  vd.template getPropWrite<0>(key) = 0;
1757  vd.template getPropWrite<1>(key) = 0;
1758  vd.template getPropWrite<2>(key) = key.getKey() + start;
1759 
1760  vd2.template getPropWrite<0>(key) = 0;
1761  vd2.template getPropWrite<1>(key) = 0;
1762  vd2.template getPropWrite<2>(key) = key.getKey() + start;
1763 
1764  ++it;
1765  }
1766 
1767  vd.map();
1768  vd2.map();
1769 
1770  // sync the ghost
1771  vd.template ghost_get<0,2>();
1772  vd2.template ghost_get<0,2>();
1773 
1774  auto NN = vd.template getVerlet<VL_NON_SYMMETRIC, VerletList<VL_NON_SYMMETRIC>>(r_cut);
1775  auto p_it = vd.getDomainIterator();
1776 
1777  while (p_it.isNext())
1778  {
1779  auto p = p_it.get();
1780 
1781  Point<3,float> xp = vd.getPosRead(p);
1782 
1783  auto Np = NN.getNNIterator(p.getKey());
1784 
1785  while (Np.isNext())
1786  {
1787  auto q = Np.get();
1788 
1789  if (p.getKey() == q)
1790  {
1791  ++Np;
1792  continue;
1793  }
1794 
1795  // repulsive
1796 
1797  Point<3,float> xq = vd.getPosRead(q);
1798  Point<3,float> f = (xp - xq);
1799 
1800  float distance = f.norm();
1801 
1802  // Particle should be inside 2 * r_cut range
1803 
1804  if (distance < r_cut )
1805  {
1806  vd.template getPropWrite<0>(p)++;
1807  vd.template getPropWrite<3>(p).add();
1808  vd.template getPropWrite<3>(p).last().xq = xq;
1809  vd.template getPropWrite<3>(p).last().id = vd.template getPropRead<2>(q);
1810  }
1811 
1812  ++Np;
1813  }
1814 
1815  ++p_it;
1816  }
1817 
1818  // We now try symmetric Verlet-list Crs scheme
1819 
1820  auto NN2 = vd2.template getVerletCrs<VerletList<VL_CRS_SYMMETRIC>>(r_cut);
1821 
1822  // Because iterating across particles in the CSR scheme require a Cell-list
1823  auto p_it2 = vd2.getParticleIteratorCRS_Cell(NN2.getInternalCellList());
1824 
1825  while (p_it2.isNext())
1826  {
1827  auto p = p_it2.get();
1828 
1829  Point<3,float> xp = vd2.getPosRead(p);
1830 
1831  auto Np = NN2.getNNIterator(p);
1832 
1833  while (Np.isNext())
1834  {
1835  auto q = Np.get();
1836 
1837  if (p == q)
1838  {
1839  ++Np;
1840  continue;
1841  }
1842 
1843  // repulsive
1844 
1845  Point<3,float> xq = vd2.getPosRead(q);
1846  Point<3,float> f = (xp - xq);
1847 
1848  float distance = f.norm();
1849 
1850  if (distance < r_cut )
1851  {
1852  vd2.template getPropWrite<1>(p)++;
1853  vd2.template getPropWrite<1>(q)++;
1854 
1855  vd2.template getPropWrite<4>(p).add();
1856  vd2.template getPropWrite<4>(q).add();
1857 
1858  vd2.template getPropWrite<4>(p).last().xq = xq;
1859  vd2.template getPropWrite<4>(q).last().xq = xp;
1860  vd2.template getPropWrite<4>(p).last().id = vd2.template getPropRead<2>(q);
1861  vd2.template getPropWrite<4>(q).last().id = vd2.template getPropRead<2>(p);
1862  }
1863 
1864  ++Np;
1865  }
1866 
1867  ++p_it2;
1868  }
1869 
1870  vd2.template ghost_put<add_,1>();
1871  vd2.template ghost_put<merge_,4>();
1872 
1873 #ifdef SE_CLASS3
1874  vd2.getDomainIterator();
1875 #endif
1876 
1877  auto p_it3 = vd.getDomainIterator();
1878 
1879  bool ret = true;
1880  while (p_it3.isNext())
1881  {
1882  auto p = p_it3.get();
1883 
1884  ret &= vd2.template getPropRead<1>(p) == vd.template getPropRead<0>(p);
1885 
1886  if (ret == false)
1887  {
1888  Point<3,float> xp = vd2.getPosRead(p);
1889  std::cout << "ERROR " << vd2.template getPropWrite<1>(p) << " " << vd.template getPropWrite<0>(p) << " " << xp.toString() << std::endl;
1890  }
1891 
1892  vd.template getPropWrite<3>(p).sort();
1893  vd2.template getPropWrite<4>(p).sort();
1894 
1895  ret &= vd.template getPropRead<3>(p).size() == vd2.template getPropRead<4>(p).size();
1896 
1897  for (size_t i = 0 ; i < vd.template getPropRead<3>(p).size() ; i++)
1898  ret &= vd.template getPropRead<3>(p).get(i).id == vd2.template getPropRead<4>(p).get(i).id;
1899 
1900  if (ret == false)
1901  break;
1902 
1903  ++p_it3;
1904  }
1905 
1906  BOOST_REQUIRE_EQUAL(ret,true);
1907 }
1908 
1909 template<template <unsigned int> class VerletList>
1910 void test_csr_verlet_list()
1911 {
1912  Vcluster<> & v_cl = create_vcluster();
1913 
1914  if (v_cl.getProcessingUnits() > 24)
1915  return;
1916 
1917  float L = 1000.0;
1918 
1919  // set the seed
1920  // create the random generator engine
1921  std::srand(0);
1922  std::default_random_engine eg;
1923  std::uniform_real_distribution<float> ud(-L,L);
1924 
1925  long int k = 4096 * v_cl.getProcessingUnits();
1926 
1927  long int big_step = k / 4;
1928  big_step = (big_step == 0)?1:big_step;
1929 
1930  print_test_v("Testing 3D periodic vector symmetric cell-list k=",k);
1931  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
1932 
1933  Box<3,float> box({-L,-L,-L},{L,L,L});
1934 
1935  // Boundary conditions
1936  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1937 
1938  float r_cut = 100.0;
1939 
1940  // ghost
1941  Ghost<3,float> ghost(r_cut);
1942  Ghost<3,float> ghost2(r_cut);
1943  ghost2.setLow(0,0.0);
1944  ghost2.setLow(1,0.0);
1945  ghost2.setLow(2,0.0);
1946 
1947  // Point and global id
1948  struct point_and_gid
1949  {
1950  size_t id;
1951  Point<3,float> xq;
1952 
1953  bool operator<(const struct point_and_gid & pag) const
1954  {
1955  return (id < pag.id);
1956  }
1957  };
1958 
1960 
1961  // Distributed vector
1962  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
1963  vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST);
1964  size_t start = vd.init_size_accum(k);
1965 
1966  test_crs_full<VerletList>(vd,vd2,eg,ud,start,r_cut);
1967 }
1968 
1969 template<template <unsigned int> class VerletList>
1970 void test_csr_verlet_list_override()
1971 {
1972  Vcluster<> & v_cl = create_vcluster();
1973 
1974  if (v_cl.getProcessingUnits() > 24)
1975  return;
1976 
1977  float L = 1000.0;
1978 
1979  // set the seed
1980  // create the random generator engine
1981  std::srand(0);
1982  std::default_random_engine eg;
1983  std::uniform_real_distribution<float> ud(-L,L);
1984 
1985  long int k = 4096 * v_cl.getProcessingUnits();
1986 
1987  long int big_step = k / 4;
1988  big_step = (big_step == 0)?1:big_step;
1989 
1990  print_test_v("Testing 3D periodic vector symmetric cell-list k=",k);
1991  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
1992 
1993  Box<3,float> box({-L,-L,-L},{L,L,L});
1994 
1995  // Boundary conditions
1996  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
1997 
1998  float r_cut = 100.0;
1999 
2000  // ghost
2001  Ghost<3,float> ghost(r_cut);
2002  Ghost<3,float> ghost2(r_cut);
2003  ghost2.setLow(0,0.0);
2004  ghost2.setLow(1,0.0);
2005  ghost2.setLow(2,0.0);
2006 
2007  // Point and global id
2008  struct point_and_gid
2009  {
2010  size_t id;
2011  Point<3,float> xq;
2012 
2013  bool operator<(const struct point_and_gid & pag) const
2014  {
2015  return (id < pag.id);
2016  }
2017  };
2018 
2020 
2021  size_t gdist_d[3];
2022  size_t gdist2_d[3];
2023 
2024  gdist_d[0] = 1;
2025  gdist_d[1] = 2;
2026  gdist_d[2] = 5;
2027 
2028  gdist2_d[0] = 1;
2029  gdist2_d[1] = 2;
2030  gdist2_d[2] = 5;
2031 
2032  grid_sm<3,void> gdist(gdist_d);
2033  grid_sm<3,void> gdist2(gdist2_d);
2034 
2035  // Distributed vector
2036  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST,gdist_d);
2037  vector_dist<3,float, part_prop > vd2(k,box,bc,ghost2,BIND_DEC_TO_GHOST,gdist2_d);
2038  size_t start = vd.init_size_accum(k);
2039 
2040  test_crs_full<VerletList>(vd,vd2,eg,ud,start,r_cut);
2041 }
2042 
2043 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list )
2044 {
2045  test_csr_verlet_list<VERLET_MEMFAST_OPT>();
2046  test_csr_verlet_list<VERLET_MEMBAL_OPT>();
2047  test_csr_verlet_list<VERLET_MEMMW_OPT>();
2048 }
2049 
2050 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list_dec_override )
2051 {
2052  test_csr_verlet_list_override<VERLET_MEMFAST_OPT>();
2053  test_csr_verlet_list_override<VERLET_MEMBAL_OPT>();
2054  test_csr_verlet_list_override<VERLET_MEMMW_OPT>();
2055 }
2056 
2057 template <template <unsigned int> class VerletList>
2058 void test_vd_symmetric_crs_verlet()
2059 {
2060  Vcluster<> & v_cl = create_vcluster();
2061 
2062  if (v_cl.getProcessingUnits() > 24)
2063  return;
2064 
2065  float L = 1000.0;
2066 
2067  bool ret = true;
2068 
2069  // set the seed
2070  // create the random generator engine
2071  std::srand(0);
2072  std::default_random_engine eg;
2073  std::uniform_real_distribution<float> ud(-L,L);
2074 
2075  long int k = 4096 * v_cl.getProcessingUnits();
2076 
2077  long int big_step = k / 4;
2078  big_step = (big_step == 0)?1:big_step;
2079 
2080  print_test_v("Testing 3D periodic vector symmetric cell-list k=",k);
2081  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
2082 
2083  Box<3,float> box({-L,-L,-L},{L,L,L});
2084 
2085  // Boundary conditions
2086  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
2087 
2088  float r_cut = 100.0;
2089 
2090  // ghost
2091  Ghost<3,float> ghost(r_cut);
2092  Ghost<3,float> ghost2(r_cut);
2093  ghost2.setLow(0,0.0);
2094  ghost2.setLow(1,0.0);
2095  ghost2.setLow(2,0.0);
2096 
2097 
2098  typedef aggregate<size_t> part_prop;
2099 
2100  // Distributed vector
2101  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
2102 
2103  auto it = vd.getIterator();
2104 
2105  while (it.isNext())
2106  {
2107  auto key = it.get();
2108 
2109  vd.getPos(key)[0] = ud(eg);
2110  vd.getPos(key)[1] = ud(eg);
2111  vd.getPos(key)[2] = ud(eg);
2112 
2113  // Fill some properties randomly
2114 
2115  vd.getProp<0>(key) = 0;
2116 
2117  ++it;
2118  }
2119 
2120  vd.map();
2121 
2122  // sync the ghost
2123  vd.ghost_get<0>();
2124 
2125  // We now try symmetric Verlet-list Crs scheme
2126 
2127  auto NN2 = vd.template getVerletCrs<VerletList<VL_CRS_SYMMETRIC>>(r_cut);
2128 
2129  // Because iterating across particles in the CSR scheme require a Cell-list
2130  auto p_it2 = vd.getParticleIteratorCRS_Cell(NN2.getInternalCellList());
2131  auto p_it3 = vd.getParticleIteratorCRS(NN2);
2132 
2133  while (p_it2.isNext())
2134  {
2135  auto p = p_it2.get();
2136  auto p2 = p_it3.get();
2137 
2138  ret &= (p == p2);
2139 
2140  if (ret == false)
2141  break;
2142 
2143  ++p_it2;
2144  ++p_it3;
2145  }
2146 
2147  BOOST_REQUIRE_EQUAL(ret,true);
2148 }
2149 
2150 BOOST_AUTO_TEST_CASE( vector_dist_symmetric_crs_verlet_list_partit )
2151 {
2152  test_vd_symmetric_crs_verlet<VERLET_MEMFAST_OPT>();
2153  test_vd_symmetric_crs_verlet<VERLET_MEMBAL_OPT>();
2154  test_vd_symmetric_crs_verlet<VERLET_MEMMW_OPT>();
2155 }
2156 
2157 BOOST_AUTO_TEST_CASE( vector_dist_checking_unloaded_processors )
2158 {
2159  Vcluster<> & v_cl = create_vcluster();
2160 
2161  if (v_cl.getProcessingUnits() > 24)
2162  return;
2163 
2164  float L = 200.0;
2165 
2166  // set the seed
2167  // create the random generator engine
2168  std::srand(0);
2169  std::default_random_engine eg;
2170  std::uniform_real_distribution<float> ud(0,L);
2171 
2172  long int k = 4096 * v_cl.getProcessingUnits();
2173 
2174  long int big_step = k / 4;
2175  big_step = (big_step == 0)?1:big_step;
2176 
2177  print_test_v("Testing 3D periodic vector symmetric cell-list (unload processors) k=",k);
2178  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list (unload processors) k=" << k );
2179 
2180  Box<3,float> box({0,0,0},{L,L,L});
2181 
2182  // Boundary conditions
2183  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
2184 
2185  float r_cut = 100.0;
2186 
2187  // ghost
2188  Ghost<3,float> ghost(r_cut);
2189  Ghost<3,float> ghost2(r_cut);
2190  ghost2.setLow(0,0.0);
2191  ghost2.setLow(1,0.0);
2192  ghost2.setLow(2,0.0);
2193 
2194 
2195  typedef aggregate<size_t> part_prop;
2196 
2197  // Distributed vector
2198  vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
2199 
2200  auto it = vd.getIterator();
2201 
2202  while (it.isNext())
2203  {
2204  auto key = it.get();
2205 
2206  vd.getPos(key)[0] = ud(eg);
2207  vd.getPos(key)[1] = ud(eg);
2208  vd.getPos(key)[2] = ud(eg);
2209 
2210  // Fill some properties randomly
2211 
2212  vd.getProp<0>(key) = 0;
2213 
2214  ++it;
2215  }
2216 
2217  vd.map();
2218 
2219  //
2220  if (v_cl.getProcessingUnits() >= 9)
2221  {
2222  size_t min = vd.size_local();
2223 
2224  v_cl.min(min);
2225  v_cl.execute();
2226 
2227  BOOST_REQUIRE_EQUAL(min,0ul);
2228  }
2229 
2230 
2231  // sync the ghost
2232  vd.ghost_get<0>();
2233 
2234  //
2235  if (v_cl.getProcessingUnits() >= 9)
2236  {
2237  size_t min = vd.size_local_with_ghost() - vd.size_local();
2238 
2239  v_cl.min(min);
2240  v_cl.execute();
2241 
2242  BOOST_REQUIRE_EQUAL(min,0ul);
2243  }
2244 }
2245 
2246 BOOST_AUTO_TEST_CASE( vector_dist_cell_list_multi_type )
2247 {
2248  Vcluster<> & v_cl = create_vcluster();
2249 
2250  if (v_cl.getProcessingUnits() > 24)
2251  return;
2252 
2253  float L = 1000.0;
2254 
2255  // set the seed
2256  // create the random generator engine
2257  std::srand(0);
2258  std::default_random_engine eg;
2259  std::uniform_real_distribution<float> ud(-L,L);
2260 
2261  long int k = 4096 * v_cl.getProcessingUnits();
2262 
2263  long int big_step = k / 4;
2264  big_step = (big_step == 0)?1:big_step;
2265 
2266  print_test_v("Testing 3D periodic vector symmetric cell-list k=",k);
2267  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
2268 
2269  Box<3,float> box({-L,-L,-L},{L,L,L});
2270 
2271  // Boundary conditions
2272  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
2273 
2274  float r_cut = 100.0;
2275 
2276  // ghost
2277  Ghost<3,float> ghost(r_cut);
2278 
2279  typedef aggregate<size_t> part_prop;
2280 
2281  // Distributed vector
2282  vector_dist<3,float, part_prop > vd(k,box,bc,ghost);
2283 
2284  auto it = vd.getIterator();
2285 
2286  while (it.isNext())
2287  {
2288  auto key = it.get();
2289 
2290  vd.getPos(key)[0] = ud(eg);
2291  vd.getPos(key)[1] = ud(eg);
2292  vd.getPos(key)[2] = ud(eg);
2293 
2294  ++it;
2295  }
2296 
2297  vd.map();
2298 
2299  // sync the ghost
2300  vd.ghost_get<0>();
2301 
2302 
2303  bool ret = true;
2304 
2305  // We take different type of Cell-list
2306  auto NN = vd.getCellList<CELL_MEMFAST<3,float>>(r_cut);
2307  auto NN2 = vd.getCellList<CELL_MEMBAL<3,float>>(r_cut);
2308  auto NN3 = vd.getCellList<CELL_MEMMW<3,float>>(r_cut);
2309 
2310  auto p_it = vd.getDomainIterator();
2311 
2312  while (p_it.isNext())
2313  {
2314  auto p = p_it.get();
2315 
2316  Point<3,float> xp = vd.getPos(p);
2317 
2318  auto Np = NN.getNNIteratorBox(NN.getCell(xp));
2319  auto Np2 = NN2.getNNIteratorBox(NN2.getCell(xp));
2320  auto Np3 = NN3.getNNIteratorBox(NN3.getCell(xp));
2321 
2322  while (Np.isNext())
2323  {
2324  // first all cell-list must agree
2325 
2326  ret &= (Np.isNext() == Np2.isNext()) && (Np3.isNext() == Np.isNext());
2327 
2328  if (ret == false)
2329  break;
2330 
2331  auto q = Np.get();
2332  auto q2 = Np2.get();
2333  auto q3 = Np3.get();
2334 
2335  ret &= (q == q2) && (q == q3);
2336 
2337  if (ret == false)
2338  break;
2339 
2340  ++Np;
2341  ++Np2;
2342  ++Np3;
2343  }
2344 
2345  ret &= (Np.isNext() == Np2.isNext()) && (Np.isNext() == Np3.isNext());
2346 
2347  if (ret == false)
2348  break;
2349 
2350  ++p_it;
2351  }
2352 
2353  BOOST_REQUIRE_EQUAL(ret,true);
2354 }
2355 
2356 // Point and global id
2358 {
2359  size_t id;
2360  Point<3,float> xq;
2361 
2362  bool operator<(const struct point_and_gid & pag) const
2363  {
2364  return (id < pag.id);
2365  }
2366 };
2367 
2368 template<typename vector_dist_mp>
2369 void test_vector_dist_particle_NN_MP_iteration()
2370 {
2371  Vcluster<> & v_cl = create_vcluster();
2372 
2373  if (v_cl.getProcessingUnits() > 24)
2374  {return;}
2375 
2376  float L = 1000.0;
2377 
2378  // set the seed
2379  // create the random generator engine
2380  std::default_random_engine eg;
2381  eg.seed(v_cl.rank()*4533);
2382  std::uniform_real_distribution<float> ud(-L,L);
2383 
2384  long int k = 4096 * v_cl.getProcessingUnits();
2385 
2386  long int big_step = k / 4;
2387  big_step = (big_step == 0)?1:big_step;
2388 
2389  print_test_v("Testing 3D periodic vector symmetric cell-list k=",k);
2390  BOOST_TEST_CHECKPOINT( "Testing 3D periodic vector symmetric cell-list k=" << k );
2391 
2392  Box<3,float> box({-L,-L,-L},{L,L,L});
2393 
2394  // Boundary conditions
2395  size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};
2396 
2397  float r_cut = 100.0;
2398 
2399  // ghost
2400  Ghost<3,float> ghost(r_cut);
2401 
2402 // typedef aggregate<size_t,size_t,size_t,openfpm::vector<point_and_gid>,openfpm::vector<point_and_gid>> part_prop;
2403 
2404  // Distributed vector
2405  vector_dist_mp vd(k,box,bc,ghost,BIND_DEC_TO_GHOST);
2406  size_t start = vd.init_size_accum(k);
2407 
2408  auto it = vd.getIterator();
2409 
2410  while (it.isNext())
2411  {
2412  auto key = it.get();
2413 
2414  vd.getPosWrite(key)[0] = ud(eg);
2415  vd.getPosWrite(key)[1] = ud(eg);
2416  vd.getPosWrite(key)[2] = ud(eg);
2417 
2418  // Fill some properties randomly
2419 
2420  vd.template getPropWrite<0>(key) = 0;
2421  vd.template getPropWrite<1>(key) = 0;
2422  vd.template getPropWrite<2>(key) = key.getKey() + start;
2423 
2424  ++it;
2425  }
2426 
2427  vd.map();
2428 
2429  // sync the ghost
2430  vd.template ghost_get<0,2>();
2431 
2432  auto NN = vd.getCellList(r_cut);
2433  auto p_it = vd.getDomainIterator();
2434 
2435  while (p_it.isNext())
2436  {
2437  auto p = p_it.get();
2438 
2439  Point<3,float> xp = vd.getPosRead(p);
2440 
2441  auto Np = NN.getNNIteratorBox(NN.getCell(xp));
2442 
2443  while (Np.isNext())
2444  {
2445  auto q = Np.get();
2446 
2447  if (p.getKey() == q)
2448  {
2449  ++Np;
2450  continue;
2451  }
2452 
2453  // repulsive
2454 
2455  Point<3,float> xq = vd.getPosRead(q);
2456  Point<3,float> f = (xp - xq);
2457 
2458  float distance = f.norm();
2459 
2460  // Particle should be inside 2 * r_cut range
2461 
2462  if (distance < r_cut )
2463  {
2464  vd.template getPropWrite<0>(p)++;
2465  vd.template getPropWrite<3>(p).add();
2466  vd.template getPropWrite<3>(p).last().xq = xq;
2467  vd.template getPropWrite<3>(p).last().id = vd.template getPropWrite<2>(q);
2468  }
2469 
2470  ++Np;
2471  }
2472 
2473  ++p_it;
2474  }
2475 
2476  // We now divide the particles on 4 phases
2477 
2479  phases.add( vector_dist_mp(vd.getDecomposition(),0));
2480  phases.add( vector_dist_mp(phases.get(0).getDecomposition(),0));
2481  phases.add( vector_dist_mp(phases.get(0).getDecomposition(),0));
2482  phases.add( vector_dist_mp(phases.get(0).getDecomposition(),0));
2483 
2484  auto it2 = vd.getDomainIterator();
2485 
2486  while (it2.isNext())
2487  {
2488  auto p = it2.get();
2489 
2490  if (p.getKey() % 4 == 0)
2491  {
2492  phases.get(0).add();
2493  phases.get(0).getLastPos()[0] = vd.getPos(p)[0];
2494  phases.get(0).getLastPos()[1] = vd.getPos(p)[1];
2495  phases.get(0).getLastPos()[2] = vd.getPos(p)[2];
2496 
2497  phases.get(0).template getLastProp<1>() = 0;
2498 
2499  phases.get(0).template getLastProp<2>() = vd.template getProp<2>(p);
2500  }
2501  else if (p.getKey() % 4 == 1)
2502  {
2503  phases.get(1).add();
2504  phases.get(1).getLastPos()[0] = vd.getPos(p)[0];
2505  phases.get(1).getLastPos()[1] = vd.getPos(p)[1];
2506  phases.get(1).getLastPos()[2] = vd.getPos(p)[2];
2507 
2508  phases.get(1).template getLastProp<1>() = 0;
2509 
2510  phases.get(1).template getLastProp<2>() = vd.template getProp<2>(p);
2511  }
2512  else if (p.getKey() % 4 == 2)
2513  {
2514  phases.get(2).add();
2515  phases.get(2).getLastPos()[0] = vd.getPos(p)[0];
2516  phases.get(2).getLastPos()[1] = vd.getPos(p)[1];
2517  phases.get(2).getLastPos()[2] = vd.getPos(p)[2];
2518 
2519  phases.get(2).template getLastProp<1>() = 0;
2520 
2521  phases.get(2).template getLastProp<2>() = vd.template getProp<2>(p);
2522  }
2523  else
2524  {
2525  phases.get(3).add();
2526  phases.get(3).getLastPos()[0] = vd.getPos(p)[0];
2527  phases.get(3).getLastPos()[1] = vd.getPos(p)[1];
2528  phases.get(3).getLastPos()[2] = vd.getPos(p)[2];
2529 
2530  phases.get(3).template getLastProp<1>() = 0;
2531 
2532  phases.get(3).template getLastProp<2>() = vd.template getProp<2>(p);
2533  }
2534 
2535  ++it2;
2536  }
2537 
2538  // now we get all the Cell-lists
2539 
2540  for (size_t i = 0 ; i < phases.size() ; i++)
2541  {
2542  phases.get(i).template ghost_get<0,1,2>();
2543  }
2544 
2546 
2547  for (size_t i = 0 ; i < phases.size() ; i++)
2548  {
2549  NN_ptr.add(phases.get(i).getCellListSym(r_cut));
2550  }
2551 
2552  // We now interact all the phases
2553 
2554  for (size_t i = 0 ; i < phases.size() ; i++)
2555  {
2556  for (size_t j = 0 ; j < phases.size() ; j++)
2557  {
2558  auto p_it2 = phases.get(i).getDomainIterator();
2559 
2560  while (p_it2.isNext())
2561  {
2562  auto p = p_it2.get();
2563 
2564  Point<3,float> xp = phases.get(i).getPosRead(p);
2565 
2566  auto Np = NN_ptr.get(j).getNNIteratorBoxSymMP(NN_ptr.get(j).getCell(xp),p.getKey(),phases.get(i).getPosVector(),phases.get(j).getPosVector());
2567 
2568  while (Np.isNext())
2569  {
2570  auto q = Np.get();
2571 
2572  if (p.getKey() == q && i == j)
2573  {
2574  ++Np;
2575  continue;
2576  }
2577 
2578  // repulsive
2579 
2580  Point<3,float> xq = phases.get(j).getPosRead(q);
2581  Point<3,float> f = (xp - xq);
2582 
2583  float distance = f.norm();
2584 
2585  // Particle should be inside r_cut range
2586 
2587  if (distance < r_cut )
2588  {
2589  phases.get(i).template getPropWrite<1>(p)++;
2590  phases.get(j).template getPropWrite<1>(q)++;
2591 
2592  phases.get(i).template getPropWrite<4>(p).add();
2593  phases.get(j).template getPropWrite<4>(q).add();
2594 
2595  phases.get(i).template getPropWrite<4>(p).last().xq = xq;
2596  phases.get(j).template getPropWrite<4>(q).last().xq = xp;
2597  phases.get(i).template getPropWrite<4>(p).last().id = phases.get(j).template getProp<2>(q);
2598  phases.get(j).template getPropWrite<4>(q).last().id = phases.get(i).template getProp<2>(p);
2599  }
2600 
2601  ++Np;
2602  }
2603 
2604  ++p_it2;
2605  }
2606  }
2607  }
2608 
2609  for (size_t i = 0 ; i < phases.size() ; i++)
2610  {
2611  phases.get(i).template ghost_put<add_,1>();
2612  phases.get(i).template ghost_put<merge_,4>();
2613  }
2614 
2615  auto p_it3 = vd.getDomainIterator();
2616 
2617  bool ret = true;
2618  while (p_it3.isNext())
2619  {
2620  auto p = p_it3.get();
2621 
2622  int ph;
2623 
2624  if (p.getKey() % 4 == 0)
2625  {ph = 0;}
2626  else if (p.getKey() % 4 == 1)
2627  {ph = 1;}
2628  else if (p.getKey() % 4 == 2)
2629  {ph = 2;}
2630  else
2631  {ph = 3;}
2632 
2633  size_t pah = p.getKey()/4;
2634  ret &= phases.get(ph).template getPropRead<1>(pah) == vd.template getPropRead<0>(p);
2635 
2636  vd.template getPropWrite<3>(p).sort();
2637  phases.get(ph).template getPropWrite<4>(pah).sort();
2638 
2639  ret &= vd.template getPropRead<3>(p).size() == phases.get(ph).template getPropRead<4>(pah).size();
2640 
2641  for (size_t i = 0 ; i < vd.template getPropRead<3>(p).size() ; i++)
2642  ret &= vd.template getPropRead<3>(p).get(i).id == phases.get(ph).template getPropRead<4>(pah).get(i).id;
2643 
2644  if (ret == false)
2645  {
2646  std::cout << "Error on particle: " << vd.template getPropRead<2>(p) << " " << v_cl.rank() << std::endl;
2647 
2648  std::cout << vd.template getPropRead<3>(p).size() << " " << phases.get(ph).template getPropRead<4>(pah).size() << " " << v_cl.rank() << std::endl;
2649 
2650  for (size_t i = 0 ; i < vd.template getPropRead<3>(p).size() ; i++)
2651  std::cout << vd.template getPropRead<3>(p).get(i).id << " " << phases.get(ph).template getPropRead<4>(pah).get(i).id << " " << v_cl.rank() << std::endl;
2652 
2653  std::cout << phases.get(ph).template getPropRead<1>(pah) << " A " << vd.template getPropRead<0>(p) << std::endl;
2654 
2655  break;
2656  }
2657 
2658  ++p_it3;
2659  }
2660 
2661  BOOST_REQUIRE_EQUAL(ret,true);
2662 }
2663 
2664 BOOST_AUTO_TEST_CASE( vector_dist_particle_NN_MP_iteration )
2665 {
2667 
2668  test_vector_dist_particle_NN_MP_iteration<vector_dist<3,float, part_prop >>();
2669 }
2670 
2671 BOOST_AUTO_TEST_SUITE_END()
add_
This structure define the operation add to use with copy general.
Definition: copy_general.hpp:69
vector_dist::getCellList
CellList_type getCellList(St r_cut, size_t opt=CL_NON_SYMMETRIC|CL_LINEAR_CELL_KEYS, bool no_se3=false, float ghostEnlargeFactor=1.013)
Construct a cell list starting from the stored particles.
Definition: vector_dist.hpp:1094
Vcluster_base< HeapMemory >::getProcessingUnits
size_t getProcessingUnits()
Get the total number of processors.
Definition: VCluster_base.hpp:501
grid_sm
Declaration grid_sm.
Definition: grid_sm.hpp:147
Vcluster_base< HeapMemory >::rank
size_t rank()
Get the process unit id.
Definition: VCluster_base.hpp:571
vector_dist::getProp
auto getProp(vect_dist_key_dx vec_key) -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
Definition: vector_dist.hpp:655
vector_dist::map
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
Definition: vector_dist.hpp:2158
vector_dist::getPosWrite
auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
Definition: vector_dist.hpp:848
openfpm::vector::size
size_t size()
Stub size.
Definition: map_vector.hpp:212
aggregate
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:220
Point::get
__device__ const __host__ T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
vector_dist::size_local_with_ghost
size_t size_local_with_ghost() const
return the local size of the vector
Definition: vector_dist.hpp:569
openfpm::vector
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:203
CellList
Class for FAST cell list implementation.
Definition: CellList.hpp:557
vect_dist_key_dx
Grid key for a distributed grid.
Definition: vector_dist_key.hpp:19
Point::toString
std::string toString() const
Return the string with the point coordinate.
Definition: Point.hpp:413
vector_dist::getParticleIteratorCRS
openfpm::vector_key_iterator_seq< typename VerletList_type::Mem_type_type::local_index_type > getParticleIteratorCRS(VerletList_type &cellList)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme.
Definition: vector_dist.hpp:2898
Vcluster_base< HeapMemory >::min
void min(T &num)
Get the minimum number across all processors (or reduction with insinity norm)
Definition: VCluster_base.hpp:623
Vcluster_base< HeapMemory >::execute
void execute()
Execute all the requests.
Definition: VCluster_base.hpp:1779
vect_dist_key_dx::getKey
__device__ __host__ size_t getKey() const
Get the key.
Definition: vector_dist_key.hpp:42
vector_dist::size_local
size_t size_local() const
return the local size of the vector
Definition: vector_dist.hpp:559
merge_
This structure define the operation add to use with copy general.
Definition: copy_general.hpp:142
Box
This class represent an N-dimensional box.
Definition: Box.hpp:59
vector_dist::getParticleIteratorCRS_Cell
ParticleItCRS_Cells< dim, cli, decltype(vPos)> getParticleIteratorCRS_Cell(cli &cellList)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme.
Definition: vector_dist.hpp:2833
vector_dist::init_size_accum
size_t init_size_accum(size_t np)
It return the number of particles contained by the previous processors.
Definition: vector_dist.hpp:1809
CellList::get
auto get(size_t cell, size_t ele) -> decltype(this->Mem_type::get(cell, ele))
Get an element in the cell.
Definition: CellList.hpp:1121
point_and_gid
Definition: vector_dist_cell_list_tests.cpp:2357
shift
Definition: CellDecomposer.hpp:27
vector_dist::ghost_get
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
Definition: vector_dist.hpp:2203
VerletList
Class for Verlet list implementation.
Definition: VerletList.hpp:268
Box::setHigh
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:543
vector_dist::add
void add()
Add local particle.
Definition: vector_dist.hpp:923
vector_dist
Distributed vector.
Definition: vector_dist.hpp:170
Point
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
vector_dist::getDomainIterator
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
Definition: vector_dist.hpp:1942
Vcluster_base< HeapMemory >::getProcessUnitID
size_t getProcessUnitID()
Get the process unit id.
Definition: VCluster_base.hpp:557
Box::setLow
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:532
vector_dist::getPosRead
auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
Definition: vector_dist.hpp:866
Ghost
Definition: Ghost.hpp:39
vector_dist::getPos
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
Definition: vector_dist.hpp:585
vector_dist::getIterator
vector_dist_iterator getIterator()
Get an iterator that traverse domain and ghost particles.
Definition: vector_dist.hpp:1837
vector_dist::getDecomposition
Decomposition & getDecomposition()
Get the decomposition.
Definition: vector_dist.hpp:2101
Vcluster
Implementation of VCluster class.
Definition: VCluster.hpp:58