OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
grid_dist_id_unit_test.cpp
1 
2 #define BOOST_TEST_DYN_LINK
3 #include <boost/test/unit_test.hpp>
4 
5 #include "Point_test.hpp"
6 #include "Grid/grid_dist_id.hpp"
7 #include "data_type/aggregate.hpp"
8 #include "grid_dist_id_unit_test_ext_dom.hpp"
9 #include "grid_dist_id_unit_test_unb_ghost.hpp"
10 
11 extern void print_test_v(std::string test, size_t sz);
12 
13 BOOST_AUTO_TEST_SUITE( grid_dist_id_test )
14 
15 
16 BOOST_AUTO_TEST_CASE( grid_dist_id_domain_grid_unit_converter3D_test)
17 {
18  size_t bc[3] = {NON_PERIODIC, NON_PERIODIC, NON_PERIODIC};
19 
20  // Domain
21  Box<3,float> domain({-0.3,-0.3,-0.3},{1.0,1.0,1.0});
22 
23  Vcluster & v_cl = create_vcluster();
24 
25  // Skip this test on big scale
26  if (v_cl.getProcessingUnits() >= 32)
27  return;
28 
29  // Test several grid dimensions
30 
31  long int k = 293;
32  long int big_step = k / 30;
33  /* coverity[dead_error_line] */
34  big_step = (big_step == 0)?1:big_step;
35  long int small_step = 21;
36 
37  print_test_v( "Testing 3D grid converter k<=",k);
38 
39  // 3D test
40  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
41  {
42  BOOST_TEST_CHECKPOINT( "Testing 3D grid converter k=" << k );
43 
44  // grid size
45  size_t sz[3];
46  sz[0] = k;
47  sz[1] = k;
48  sz[2] = k;
49 
50  // Ghost
51  Ghost<3,float> g(0.01);
52 
53  // Distributed grid with id decomposition
55 
56  // get the decomposition
57  auto & dec = g_dist.getDecomposition();
58 
59  // check the consistency of the decomposition
60  bool val = dec.check_consistency();
61  BOOST_REQUIRE_EQUAL(val,true);
62 
63  // for each local volume
64  // Get the number of local grid needed
65  size_t n_grid = dec.getNSubDomain();
66 
67  size_t vol = 0;
68 
69  // vector of boxes
71 
72  // Allocate the grids
73  for (size_t i = 0 ; i < n_grid ; i++)
74  {
75  // Get the local hyper-cube
76  SpaceBox<3,float> sub = dec.getSubDomain(i);
77 // sub -= domain.getP1();
78 
79  Box<3,size_t> g_box = g_dist.getCellDecomposer().convertDomainSpaceIntoGridUnits(sub,bc);
80 
81  vb.add(g_box);
82 
83  vol += g_box.getVolumeKey();
84  }
85 
86  // Create a writer and write
87  VTKWriter<openfpm::vector<Box<3,size_t>>,VECTOR_BOX> vtk_box2;
88  vtk_box2.add(vb);
89  vtk_box2.write(std::to_string(v_cl.getProcessUnitID()) + "vtk_box_3D.vtk");
90 
91  v_cl.sum(vol);
92  v_cl.execute();
93 
94  BOOST_REQUIRE_EQUAL(vol,sz[0]*sz[1]*sz[2]);
95  }
96 }
97 
98 
99 BOOST_AUTO_TEST_CASE( grid_dist_id_domain_grid_unit_converter_test)
100 {
101  size_t bc[2] = {NON_PERIODIC, NON_PERIODIC};
102 
103  // Domain
104  Box<2,float> domain({0.0,0.0},{1.0,1.0});
105 
106  Vcluster & v_cl = create_vcluster();
107 
108  // Skip this test on big scale
109  if (v_cl.getProcessingUnits() >= 32)
110  return;
111 
112  for (size_t k = 1024 ; k >= 2 ; k--)
113  {
114  BOOST_TEST_CHECKPOINT( "Testing grid converter 3D k=" << k );
115 
116  // grid size
117  size_t sz[2];
118  sz[0] = k;
119  sz[1] = k;
120 
121  // Ghost
122  Ghost<2,float> g(0.01);
123 
124  // Distributed grid with id decomposition
126 
127  // get the decomposition
128  auto & dec = g_dist.getDecomposition();
129 
130  // check the consistency of the decomposition
131  bool val = dec.check_consistency();
132  BOOST_REQUIRE_EQUAL(val,true);
133 
134  // for each local volume
135  // Get the number of local grid needed
136  size_t n_grid = dec.getNSubDomain();
137 
138  size_t vol = 0;
139 
140  // Allocate the grids
141  for (size_t i = 0 ; i < n_grid ; i++)
142  {
143  // Get the local hyper-cube
144  SpaceBox<2,float> sub = dec.getSubDomain(i);
145 
146  Box<2,size_t> g_box = g_dist.getCellDecomposer().convertDomainSpaceIntoGridUnits(sub,bc);
147 
148  vol += g_box.getVolumeKey();
149  }
150 
151  v_cl.sum(vol);
152  v_cl.execute();
153 
154  BOOST_REQUIRE_EQUAL(vol,sz[0]*sz[1]);
155  }
156 }
157 
158 
159 void Test2D(const Box<2,float> & domain, long int k)
160 {
161  long int big_step = k / 30;
162  big_step = (big_step == 0)?1:big_step;
163  long int small_step = 21;
164 
165  print_test_v( "Testing 2D grid k<=",k);
166 
167  // 2D test
168  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
169  {
170  BOOST_TEST_CHECKPOINT( "Testing 2D grid k=" << k );
171 
173 
174  // grid size
175  size_t sz[2];
176  sz[0] = k;
177  sz[1] = k;
178 
179  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/2.0f);
180 
181  // Ghost
182  Ghost<2,float> g(0.01 / factor);
183 
184  // Distributed grid with id decomposition
185  grid_dist_id<2, float, aggregate<float>> g_dist(sz,domain,g);
186 
187  // check the consistency of the decomposition
188  bool val = g_dist.getDecomposition().check_consistency();
189  BOOST_REQUIRE_EQUAL(val,true);
190 
191  // Grid sm
192  grid_sm<2,void> info(sz);
193 
194  // get the domain iterator
195  size_t count = 0;
196 
197  auto dom = g_dist.getDomainIterator();
198 
199  while (dom.isNext())
200  {
201  auto key = dom.get();
202  auto key_g = g_dist.getGKey(key);
203 
204  g_dist.template get<0>(key) = info.LinId(key_g);
205 
206  // Count the point
207  count++;
208 
209  ++dom;
210  }
211 
213 
214  // Get the virtual cluster machine
215  Vcluster & vcl = g_dist.getVC();
216 
217  // reduce
218  vcl.sum(count);
219  vcl.execute();
220 
221  // Check
222  BOOST_REQUIRE_EQUAL(count,(size_t)k*k);
223 
224  auto dom2 = g_dist.getDomainIterator();
225 
226  grid_key_dx<2> start = dom2.getStart();
227  grid_key_dx<2> stop = dom2.getStop();
228 
229  BOOST_REQUIRE_EQUAL((long int)stop.get(0),(long int)g_dist.size(0)-1);
230  BOOST_REQUIRE_EQUAL((long int)stop.get(1),(long int)g_dist.size(1)-1);
231 
232  BOOST_REQUIRE_EQUAL(start.get(0),0);
233  BOOST_REQUIRE_EQUAL(start.get(1),0);
234 
235  bool match = true;
236 
237  // check that the grid store the correct information
238  while (dom2.isNext())
239  {
240  auto key = dom2.get();
241  auto key_g = g_dist.getGKey(key);
242 
243  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
244 
245  ++dom2;
246  }
247 
248  BOOST_REQUIRE_EQUAL(match,true);
249 
250  g_dist.template ghost_get<0>();
251 
252  // check that the communication is correctly completed
253 
254  auto domg = g_dist.getDomainGhostIterator();
255 
256  // check that the grid with the ghost past store the correct information
257  while (domg.isNext())
258  {
259  auto key = domg.get();
260  auto key_g = g_dist.getGKey(key);
261 
262  // In this case the boundary condition are non periodic
263  if (g_dist.isInside(key_g))
264  {
265  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
266  }
267 
268  ++domg;
269  }
270 
271  BOOST_REQUIRE_EQUAL(match,true);
272  }
273 }
274 
275 
276 void Test1D(const Box<1,float> & domain, long int k)
277 {
278  Vcluster & v_cl = create_vcluster();
279  long int big_step = k / 30;
280  big_step = (big_step == 0)?1:big_step;
281  long int small_step = 21;
282 
283  if (v_cl.getProcessingUnits() > 48)
284  return;
285 
286  print_test_v( "Testing 1D grid k<=",k);
287 
288  // 1D test
289  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
290  {
291  BOOST_TEST_CHECKPOINT( "Testing 1D grid k=" << k );
292 
294 
295  // grid size
296  size_t sz[1];
297  sz[0] = k;
298 
299  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f);
300 
301  // Ghost
302  Ghost<1,float> g(0.01 / factor);
303 
304  // Distributed grid with id decomposition
305  grid_dist_id<1, float, aggregate<float>> g_dist(sz,domain,g);
306 
307  // check the consistency of the decomposition
308  bool val = g_dist.getDecomposition().check_consistency();
309  BOOST_REQUIRE_EQUAL(val,true);
310 
311  // Grid sm
312  grid_sm<1,void> info(sz);
313 
314  // get the domain iterator
315  size_t count = 0;
316 
317  auto dom = g_dist.getDomainIterator();
318 
319  while (dom.isNext())
320  {
321  auto key = dom.get();
322  auto key_g = g_dist.getGKey(key);
323 
324  g_dist.template get<0>(key) = info.LinId(key_g);
325 
326  // Count the point
327  count++;
328 
329  ++dom;
330  }
331 
333 
334  // Get the virtual cluster machine
335  Vcluster & vcl = g_dist.getVC();
336 
337  // reduce
338  vcl.sum(count);
339  vcl.execute();
340 
341  // Check
342  BOOST_REQUIRE_EQUAL(count,(size_t)k);
343 
344  auto dom2 = g_dist.getDomainIterator();
345 
346  grid_key_dx<1> start = dom2.getStart();
347  grid_key_dx<1> stop = dom2.getStop();
348 
349  BOOST_REQUIRE_EQUAL((long int)stop.get(0),(long int)g_dist.size(0)-1);
350 
351  BOOST_REQUIRE_EQUAL(start.get(0),0);
352 
353  bool match = true;
354 
355  // check that the grid store the correct information
356  while (dom2.isNext())
357  {
358  auto key = dom2.get();
359  auto key_g = g_dist.getGKey(key);
360 
361  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
362 
363  ++dom2;
364  }
365 
366  BOOST_REQUIRE_EQUAL(match,true);
367 
368  g_dist.template ghost_get<0>();
369 
370  // check that the communication is correctly completed
371 
372  auto domg = g_dist.getDomainGhostIterator();
373 
374  // check that the grid with the ghost past store the correct information
375  while (domg.isNext())
376  {
377  auto key = domg.get();
378  auto key_g = g_dist.getGKey(key);
379 
380  // In this case the boundary condition are non periodic
381  if (g_dist.isInside(key_g))
382  {
383  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
384  }
385 
386  ++domg;
387  }
388 
389  BOOST_REQUIRE_EQUAL(match,true);
390  }
391 }
392 
393 void Test3D_sub(const Box<3,float> & domain, long int k)
394 {
395  long int big_step = k / 30;
396  big_step = (big_step == 0)?1:big_step;
397  long int small_step = 21;
398 
399  // this test is only performed when the number of processor is <= 32
400  if (create_vcluster().getProcessingUnits() > 32)
401  return;
402 
403  print_test_v( "Testing 3D grid sub k<=",k);
404 
405  // 3D test
406  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
407  {
408  BOOST_TEST_CHECKPOINT( "Testing 3D grid sub k=" << k );
409 
410  // grid size
411  size_t sz[3];
412  sz[0] = k;
413  sz[1] = k;
414  sz[2] = k;
415 
416  // factor
417  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
418 
419  // Ghost
420  Ghost<3,float> g(0.01 / factor);
421 
422  // Distributed grid with id decomposition
424 
425  // check the consistency of the decomposition
426  bool val = g_dist.getDecomposition().check_consistency();
427  BOOST_REQUIRE_EQUAL(val,true);
428 
429  // Grid sm
430  grid_sm<3,void> info(sz);
431 
432  // get the domain iterator
433  size_t count = 0;
434 
435  grid_key_dx<3> one(1,1,1);
436  grid_key_dx<3> one_end(k-2,k-2,k-2);
437 
438  // Sub-domain iterator
439  auto dom = g_dist.getSubDomainIterator(one,one_end);
440 
441  while (dom.isNext())
442  {
443  auto key = dom.get();
444  auto key_g = g_dist.getGKey(key);
445 
446  g_dist.template get<0>(key) = info.LinId(key_g);
447 
448  // Count the point
449  count++;
450 
451  ++dom;
452  }
453 
454  // Get the virtual cluster machine
455  Vcluster & vcl = g_dist.getVC();
456 
457  // reduce
458  vcl.sum(count);
459  vcl.execute();
460 
461  // Check
462  BOOST_REQUIRE_EQUAL(count,(size_t)(k-2)*(k-2)*(k-2));
463 
464  // check with a 1x1x1 square
465  {
466 
467  grid_key_dx<3> one(k/2,k/2,k/2);
468  grid_key_dx<3> one_end(k/2,k/2,k/2);
469 
470  count = 0;
471 
472  // get the sub-domain iterator
473  auto dom = g_dist.getSubDomainIterator(one,one_end);
474 
475  while (dom.isNext())
476  {
477  auto key = dom.get();
478  auto key_g = g_dist.getGKey(key);
479 
480  // key_g
481  BOOST_REQUIRE_EQUAL(key_g.get(0),k/2);
482  BOOST_REQUIRE_EQUAL(key_g.get(1),k/2);
483  BOOST_REQUIRE_EQUAL(key_g.get(2),k/2);
484 
485  auto key_s_it = dom.getGKey(key);
486 
487  BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0));
488  BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1));
489  BOOST_REQUIRE_EQUAL(key_g.get(2),key_s_it.get(2));
490 
491  // Count the point
492  count++;
493 
494  ++dom;
495  }
496 
497  // reduce
498  vcl.sum(count);
499  vcl.execute();
500 
501  BOOST_REQUIRE_EQUAL(count,1ul);
502  }
503  }
504 }
505 
506 void Test3D(const Box<3,float> & domain, long int k)
507 {
508  long int big_step = k / 30;
509  big_step = (big_step == 0)?1:big_step;
510  long int small_step = 21;
511 
512  print_test_v( "Testing 3D grid k<=",k);
513 
514  // 3D test
515  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
516  {
517  BOOST_TEST_CHECKPOINT( "Testing 3D grid k=" << k );
518 
519  // grid size
520  size_t sz[3];
521  sz[0] = k;
522  sz[1] = k;
523  sz[2] = k;
524 
525  // factor
526  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
527 
528  // Ghost
529  Ghost<3,float> g(0.01 / factor);
530 
531  // Distributed grid with id decomposition
533 
534  // check the consistency of the decomposition
535  bool val = g_dist.getDecomposition().check_consistency();
536  BOOST_REQUIRE_EQUAL(val,true);
537 
538  // Grid sm
539  grid_sm<3,void> info(sz);
540 
541  // get the domain iterator
542  size_t count = 0;
543 
544  auto dom = g_dist.getDomainIterator();
545 
546  while (dom.isNext())
547  {
548  auto key = dom.get();
549  auto key_g = g_dist.getGKey(key);
550 
551  g_dist.template get<0>(key) = info.LinId(key_g);
552 
553  // Count the point
554  count++;
555 
556  ++dom;
557  }
558 
559  // Get the virtual cluster machine
560  Vcluster & vcl = g_dist.getVC();
561 
562  // reduce
563  vcl.sum(count);
564  vcl.execute();
565 
566  // Check
567  BOOST_REQUIRE_EQUAL(count,(size_t)k*k*k);
568 
569  bool match = true;
570 
571  auto dom2 = g_dist.getDomainIterator();
572 
573  // check that the grid store the correct information
574  while (dom2.isNext())
575  {
576  auto key = dom2.get();
577  auto key_g = g_dist.getGKey(key);
578 
579  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
580 
581  ++dom2;
582  }
583 
584  BOOST_REQUIRE_EQUAL(match,true);
585 
587 
588  g_dist.template ghost_get<0>();
589 
590  // check that the communication is correctly completed
591 
592  auto domg = g_dist.getDomainGhostIterator();
593 
594  // check that the grid with the ghost past store the correct information
595  while (domg.isNext())
596  {
597  auto key = domg.get();
598  auto key_g = g_dist.getGKey(key);
599 
600  // In this case the boundary condition are non periodic
601  if (g_dist.isInside(key_g))
602  {
603  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
604  }
605 
606  ++domg;
607  }
608 
609  BOOST_REQUIRE_EQUAL(match,true);
610 
612  }
613 }
614 
615 
616 void Test3D_gg(const Box<3,float> & domain, long int k, long int gk)
617 {
618  long int big_step = k / 30;
619  big_step = (big_step == 0)?1:big_step;
620 
621  // this test is only performed when the number of processor is <= 32
622  if (create_vcluster().getProcessingUnits() > 32)
623  return;
624 
625  print_test_v( "Testing 3D grid k<=",k);
626 
627  // 3D test
628  for ( ; k > 64 ; k /= 2 )
629  {
630  BOOST_TEST_CHECKPOINT( "Testing 3D grid ghost integer k=" << k );
631 
632  // grid size
633  size_t sz[3];
634  sz[0] = k;
635  sz[1] = k;
636  sz[2] = k;
637 
638  // Ghost
639  Ghost<3,long int> g(gk);
640 
641  // Distributed grid with id decomposition
643 
644  // check the consistency of the decomposition
645  bool val = g_dist.getDecomposition().check_consistency();
646  BOOST_REQUIRE_EQUAL(val,true);
647 
648  auto lg = g_dist.getLocalGridsInfo();
649 
650  // for each local grid check that the border is 1 point
651  // (Warning this property can only be ensured with k is a multiple of 2)
652  // in the other case it will be mostly like that but cannot be ensured
653 
654  for (size_t i = 0 ; i < lg.size() ; i++)
655  {
656  for (size_t j = 0 ; j < 3 ; j++)
657  {
658  BOOST_REQUIRE(lg.get(i).Dbox.getLow(j) >= gk);
659  BOOST_REQUIRE((lg.get(i).GDbox.getHigh(j) - lg.get(i).Dbox.getHigh(j)) >= gk);
660  }
661  }
662  }
663 }
664 
670 void Test3D_domain(const Box<3,float> & domain, long int k, const periodicity<3> & pr)
671 {
672  long int big_step = k / 30;
673  big_step = (big_step == 0)?1:big_step;
674  long int small_step = 21;
675 
676  print_test_v( "Testing 3D grid shift domain k<=",k);
677 
678  // 3D test
679  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
680  {
681  BOOST_TEST_CHECKPOINT( "Testing 3D grid shift domain k=" << k );
682 
683  // grid size
684  size_t sz[3];
685  sz[0] = k;
686  sz[1] = k;
687  sz[2] = k;
688 
689  // factor
690  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
691 
692  // Ghost
693  Ghost<3,float> g(0.01 / factor);
694 
695  // Distributed grid with id decomposition
697 
698  auto & v_cl = create_vcluster();
699 
700  // check the consistency of the decomposition
701  bool val = g_dist.getDecomposition().check_consistency();
702  BOOST_REQUIRE_EQUAL(val,true);
703 
704  // Grid sm
705  grid_sm<3,void> info(sz);
706 
707  // get the domain iterator
708  size_t count = 0;
709 
710  auto dom = g_dist.getDomainIterator();
711 
712  while (dom.isNext())
713  {
714  auto key = dom.get();
715  auto key_g = g_dist.getGKey(key);
716 
717  g_dist.template get<0>(key) = count;
718  g_dist.template get<1>(key) = info.LinId(key_g);
719 
720  // Count the point
721  count++;
722 
723  ++dom;
724  }
725 
726  size_t count2 = count;
728 
729  // Get the total size of the local grids on each processors
730  // and the total size
731  v_cl.sum(count2);
732  v_cl.allGather(count,pnt);
733  v_cl.execute();
734  size_t s_pnt = 0;
735 
736  // calculate the starting point for this processor
737  for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
738  s_pnt += pnt.get(i);
739 
740  // Check
741  BOOST_REQUIRE_EQUAL(count2,(size_t)k*k*k);
742 
743  // sync the ghost
744  g_dist.template ghost_get<0,1>();
745 
746  bool match = true;
747 
748  // check that the communication is correctly completed
749 
750  auto domg = g_dist.getDomainGhostIterator();
751 
752  // check that the grid with the ghost past store the correct information
753  while (domg.isNext())
754  {
755  auto key = domg.get();
756  auto key_g = g_dist.getGKey(key);
757 
758  // In this case the boundary condition are non periodic
759  if (g_dist.isInside(key_g))
760  {
761  match &= (g_dist.template get<1>(key) == info.LinId(key_g))?true:false;
762  }
763 
764  ++domg;
765  }
766 
767  BOOST_REQUIRE_EQUAL(match,true);
768  }
769 }
770 
771 
772 
773 void Test2D_complex(const Box<2,float> & domain, long int k)
774 {
775  typedef Point_test<float> p;
776 
777  long int big_step = k / 30;
778  big_step = (big_step == 0)?1:big_step;
779  long int small_step = 21;
780 
781  print_test_v( "Testing 2D complex grid k<=",k);
782 
783  // 2D test
784  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
785  {
786  BOOST_TEST_CHECKPOINT( "Testing 2D complex grid k=" << k );
787 
789 
790  // grid size
791  size_t sz[2];
792  sz[0] = k;
793  sz[1] = k;
794 
795  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/2.0f);
796 
797  // Ghost
798  Ghost<2,float> g(0.01 / factor);
799 
800  // Distributed grid with id decomposition
801  grid_dist_id<2, float, Point_test<float>> g_dist(sz,domain,g);
802 
803  // check the consistency of the decomposition
804  bool val = g_dist.getDecomposition().check_consistency();
805  BOOST_REQUIRE_EQUAL(val,true);
806 
807  // Grid sm
808  grid_sm<2,void> info(sz);
809 
810  // get the domain iterator
811  size_t count = 0;
812 
813  auto dom = g_dist.getDomainIterator();
814 
815  while (dom.isNext())
816  {
817  auto key = dom.get();
818  auto key_g = g_dist.getGKey(key);
819 
820  size_t k = info.LinId(key_g);
821 
822  g_dist.template get<p::x>(key) = 1 + k;
823  g_dist.template get<p::y>(key) = 567 + k;
824  g_dist.template get<p::z>(key) = 341 + k;
825  g_dist.template get<p::s>(key) = 5670 + k;
826  g_dist.template get<p::v>(key)[0] = 921 + k;
827  g_dist.template get<p::v>(key)[1] = 5675 + k;
828  g_dist.template get<p::v>(key)[2] = 117 + k;
829  g_dist.template get<p::t>(key)[0][0] = 1921 + k;
830  g_dist.template get<p::t>(key)[0][1] = 25675 + k;
831  g_dist.template get<p::t>(key)[0][2] = 3117 + k;
832  g_dist.template get<p::t>(key)[1][0] = 4921 + k;
833  g_dist.template get<p::t>(key)[1][1] = 55675 + k;
834  g_dist.template get<p::t>(key)[1][2] = 6117 + k;
835  g_dist.template get<p::t>(key)[2][0] = 7921 + k;
836  g_dist.template get<p::t>(key)[2][1] = 85675 + k;
837  g_dist.template get<p::t>(key)[2][2] = 9117 + k;
838 
839  // Count the point
840  count++;
841 
842  ++dom;
843  }
844 
846 
847  // Get the virtual cluster machine
848  Vcluster & vcl = g_dist.getVC();
849 
850  // reduce
851  vcl.sum(count);
852  vcl.execute();
853 
854  // Check
855  BOOST_REQUIRE_EQUAL(count,(size_t)k*k);
856 
857  auto dom2 = g_dist.getDomainIterator();
858 
859  bool match = true;
860 
861  // check that the grid store the correct information
862  while (dom2.isNext())
863  {
864  auto key = dom2.get();
865  auto key_g = g_dist.getGKey(key);
866 
867  size_t k = info.LinId(key_g);
868 
869  match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
870  match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
871  match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
872  match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
873  match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
874  match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
875  match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
876  match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
877  match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
878  match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
879  match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
880  match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
881  match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
882  match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
883  match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
884  match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
885 
886  ++dom2;
887  }
888 
889  BOOST_REQUIRE_EQUAL(match,true);
890 
892 
893  g_dist.template ghost_get<p::x,p::y,p::z,p::s,p::v,p::t>();
894 
895  // check that the communication is correctly completed
896 
897  auto domg = g_dist.getDomainGhostIterator();
898 
899  // check that the grid with the ghost past store the correct information
900  while (domg.isNext())
901  {
902  auto key = domg.get();
903  auto key_g = g_dist.getGKey(key);
904 
905  // In this case the boundary condition are non periodic
906  if (g_dist.isInside(key_g))
907  {
908  size_t k = info.LinId(key_g);
909 
910  match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
911  match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
912  match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
913  match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
914 
915  match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
916  match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
917  match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
918 
919  match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
920  match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
921  match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
922  match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
923  match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
924  match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
925  match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
926  match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
927  match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
928  }
929 
930  ++domg;
931  }
932 
934  }
935 }
936 
937 void Test3D_complex(const Box<3,float> & domain, long int k)
938 {
939  typedef Point_test<float> p;
940 
941  long int big_step = k / 30;
942  big_step = (big_step == 0)?1:big_step;
943  long int small_step = 21;
944 
945  print_test_v( "Testing 3D grid complex k<=",k);
946 
947  // 2D test
948  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
949  {
950  BOOST_TEST_CHECKPOINT( "Testing 3D complex grid k=" << k );
951 
952  // grid size
953  size_t sz[3];
954  sz[0] = k;
955  sz[1] = k;
956  sz[2] = k;
957 
958  // factor
959  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
960 
961  // Ghost
962  Ghost<3,float> g(0.01 / factor);
963 
964  // Distributed grid with id decomposition
966 
967  // check the consistency of the decomposition
968  bool val = g_dist.getDecomposition().check_consistency();
969  BOOST_REQUIRE_EQUAL(val,true);
970 
971  // Grid sm
972  grid_sm<3,void> info(sz);
973 
974  // get the domain iterator
975  size_t count = 0;
976 
977  auto dom = g_dist.getDomainIterator();
978 
979  while (dom.isNext())
980  {
981  auto key = dom.get();
982  auto key_g = g_dist.getGKey(key);
983 
984  size_t k = info.LinId(key_g);
985 
986  g_dist.template get<p::x>(key) = 1 + k;
987  g_dist.template get<p::y>(key) = 567 + k;
988  g_dist.template get<p::z>(key) = 341 + k;
989  g_dist.template get<p::s>(key) = 5670 + k;
990  g_dist.template get<p::v>(key)[0] = 921 + k;
991  g_dist.template get<p::v>(key)[1] = 5675 + k;
992  g_dist.template get<p::v>(key)[2] = 117 + k;
993  g_dist.template get<p::t>(key)[0][0] = 1921 + k;
994  g_dist.template get<p::t>(key)[0][1] = 25675 + k;
995  g_dist.template get<p::t>(key)[0][2] = 3117 + k;
996  g_dist.template get<p::t>(key)[1][0] = 4921 + k;
997  g_dist.template get<p::t>(key)[1][1] = 55675 + k;
998  g_dist.template get<p::t>(key)[1][2] = 6117 + k;
999  g_dist.template get<p::t>(key)[2][0] = 7921 + k;
1000  g_dist.template get<p::t>(key)[2][1] = 85675 + k;
1001  g_dist.template get<p::t>(key)[2][2] = 9117 + k;
1002 
1003  // Count the point
1004  count++;
1005 
1006  ++dom;
1007  }
1008 
1009  // Get the virtual cluster machine
1010  Vcluster & vcl = g_dist.getVC();
1011 
1012  // reduce
1013  vcl.sum(count);
1014  vcl.execute();
1015 
1016  // Check
1017  BOOST_REQUIRE_EQUAL(count,(size_t)k*k*k);
1018 
1019  bool match = true;
1020 
1021  auto dom2 = g_dist.getDomainIterator();
1022 
1023  // check that the grid store the correct information
1024  while (dom2.isNext())
1025  {
1026  auto key = dom2.get();
1027  auto key_g = g_dist.getGKey(key);
1028 
1029  size_t k = info.LinId(key_g);
1030 
1031  match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
1032  match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
1033  match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
1034  match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
1035  match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
1036  match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
1037  match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
1038  match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
1039  match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
1040  match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
1041  match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
1042  match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
1043  match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
1044  match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
1045  match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
1046  match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
1047 
1048  ++dom2;
1049  }
1050 
1051  BOOST_REQUIRE_EQUAL(match,true);
1052 
1053  g_dist.template ghost_get<p::x,p::y,p::z,p::s,p::v,p::t>();
1054 
1055  // check that the communication is correctly completed
1056 
1057  auto domg = g_dist.getDomainGhostIterator();
1058 
1059  // check that the grid with the ghost past store the correct information
1060  while (domg.isNext())
1061  {
1062  auto key = domg.get();
1063  auto key_g = g_dist.getGKey(key);
1064 
1065  size_t k = info.LinId(key_g);
1066 
1067  // In this case the boundary condition are non periodic
1068  if (g_dist.isInside(key_g))
1069  {
1070  match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
1071  match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
1072  match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
1073  match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
1074 
1075  match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
1076  match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
1077  match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
1078 
1079  match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
1080  match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
1081  match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
1082  match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
1083  match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
1084  match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
1085  match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
1086  match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
1087  match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
1088  }
1089 
1090  ++domg;
1091  }
1092 
1093  BOOST_REQUIRE_EQUAL(match,true);
1094  }
1095 }
1096 
1097 // Test duplicated topology
1098 
1099 void Test3D_dup(const Box<3,float> & domain, long int k)
1100 {
1101  long int big_step = k / 30;
1102  big_step = (big_step == 0)?1:big_step;
1103  long int small_step = 21;
1104  long int k_old = k;
1105 
1106  Vcluster & v_cl = create_vcluster();
1107 
1108  if ( v_cl.getProcessingUnits() > 32 )
1109  return;
1110 
1111  print_test_v( "Testing 3D duplicate topology complex k<=",k);
1112 
1113  // 3D test
1114  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1115  {
1116  BOOST_TEST_CHECKPOINT( "Testing 3D copy decomposition grid k=" << k );
1117 
1118  // grid size
1119  size_t sz[3];
1120  sz[0] = k;
1121  sz[1] = k;
1122  sz[2] = k;
1123 
1124  // factor
1125  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1126 
1127  // Ghost
1128  Ghost<3,float> g(0.01 / factor);
1129 
1131 
1132  // Distributed grid with id decomposition (It work also without the third template parameter)
1133  // Here is given to show that the 2 grid MUST have the same decomposition strategy
1135 
1136  // another grid with the same decomposition
1137  grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> g_dist2(g_dist1.getDecomposition(),sz,g);
1138 
1140 
1141  bool ret = g_dist2.getDecomposition().check_consistency();
1142  BOOST_REQUIRE_EQUAL(ret,true);
1143  ret = g_dist2.getDecomposition().is_equal(g_dist2.getDecomposition());
1144  BOOST_REQUIRE_EQUAL(ret,true);
1145 
1146 
1147  auto dom_g1 = g_dist1.getDomainIterator();
1148  auto dom_g2 = g_dist2.getDomainIterator();
1149 
1150  bool check = true;
1151 
1152  while (dom_g1.isNext())
1153  {
1154  auto key1 = dom_g1.get();
1155  auto key2 = dom_g2.get();
1156 
1157  check &= (key1 == key2)?true:false;
1158 
1159  ++dom_g1;
1160  ++dom_g2;
1161  }
1162 
1163  BOOST_REQUIRE_EQUAL(check,true);
1164  }
1165 
1166  k = k_old;
1167 
1168  // 3D test
1169  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1170  {
1171  BOOST_TEST_CHECKPOINT( "Testing 3D copy decomposition grid k=" << k );
1172 
1173  // grid size
1174  size_t sz[3];
1175  sz[0] = k;
1176  sz[1] = k;
1177  sz[2] = k;
1178 
1179  // factor
1180  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1181 
1182  // Ghost
1183  Ghost<3,float> g(0.01 / factor);
1184 
1185  // Distributed grid with id decomposition
1187 
1188  // another grid with the same decomposition
1189  grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> * g_dist2 = new grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>>(g_dist1->getDecomposition(),sz,g);
1190 
1191  delete g_dist1;
1192 
1193  bool ret = g_dist2->getDecomposition().check_consistency();
1194  BOOST_REQUIRE_EQUAL(ret,true);
1195 
1196  delete g_dist2;
1197  }
1198 }
1199 
1200 
1201 // Test grid periodic
1202 
1203 void Test3D_periodic(const Box<3,float> & domain, long int k)
1204 {
1205  Vcluster & v_cl = create_vcluster();
1206 
1207  if ( v_cl.getProcessingUnits() > 32 )
1208  return;
1209 
1210  long int big_step = k / 30;
1211  big_step = (big_step == 0)?1:big_step;
1212  long int small_step = 21;
1213 
1214  print_test_v( "Testing grid periodic k<=",k);
1215 
1216  // 3D test
1217  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1218  {
1219  BOOST_TEST_CHECKPOINT( "Testing grid periodick<=" << k );
1220 
1221  // grid size
1222  size_t sz[3];
1223  sz[0] = k;
1224  sz[1] = k;
1225  sz[2] = k;
1226 
1227  // factor
1228  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1229 
1230  // Ghost
1231  Ghost<3,float> g(0.01 / factor);
1232 
1233  // periodicity
1234  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
1235 
1236  // Distributed grid with id decomposition
1238 
1239  // check the consistency of the decomposition
1240  bool val = g_dist.getDecomposition().check_consistency();
1241  BOOST_REQUIRE_EQUAL(val,true);
1242 
1243  // Grid sm
1244  grid_sm<3,void> info(sz);
1245 
1246  size_t count = 0;
1247 
1248  // Set to zero the full grid
1249 
1250  auto dom1 = g_dist.getDomainGhostIterator();
1251 
1252  while (dom1.isNext())
1253  {
1254  auto key = dom1.get();
1255 
1256  g_dist.template get<0>(key) = -1;
1257 
1258  ++dom1;
1259  }
1260 
1261  auto dom = g_dist.getDomainIterator();
1262 
1263  while (dom.isNext())
1264  {
1265  auto key = dom.get();
1266  auto key_g = g_dist.getGKey(key);
1267 
1268  g_dist.template get<0>(key) = info.LinId(key_g);
1269 
1270  // Count the points
1271  count++;
1272 
1273  ++dom;
1274  }
1275 
1276  // Get the virtual cluster machine
1277  Vcluster & vcl = g_dist.getVC();
1278 
1279  // reduce
1280  vcl.sum(count);
1281  vcl.execute();
1282 
1283  // Check
1284  BOOST_REQUIRE_EQUAL(count,(size_t)k*k*k);
1285 
1286  size_t tot = g_dist.getLocalDomainSize();
1287  // reduce
1288  vcl.sum(tot);
1289  vcl.execute();
1290 
1291  BOOST_REQUIRE_EQUAL(count,tot);
1292 
1293  // sync the ghosts
1294  g_dist.ghost_get<0>();
1295 
1296  bool match = true;
1297 
1298  // Domain + Ghost iterator
1299  auto dom_gi = g_dist.getDomainGhostIterator();
1300 
1301  size_t out_cnt = 0;
1302 
1303  while (dom_gi.isNext())
1304  {
1305  bool out_p = false;
1306 
1307  auto key = dom_gi.get();
1308  auto key_g = g_dist.getGKey(key);
1309 
1310  // Return the external boxes
1311  auto & gb = dom_gi.getGBoxes();
1312 
1313  // transform the key to be periodic
1314  for (size_t i = 0 ; i < 3 ; i++)
1315  {
1316  if (key_g.get(i) < 0)
1317  {key_g.set_d(i,key_g.get(i) + k);out_p = true;}
1318  else if (key_g.get(i) >= k)
1319  {key_g.set_d(i,key_g.get(i) - k);out_p = true;}
1320  }
1321 
1322  if (g_dist.template get<0>(key) != -1 && out_p == true)
1323  out_cnt++;
1324 
1325  // The last points can be invalid because of rounding off problems
1326  bool can_invalid = false;
1327  if (key.getKey().get(0) == 0 || key.getKey().get(1) == 0 || key.getKey().get(2) == 0)
1328  can_invalid = true;
1329  else if (key.getKey().get(0) == gb.get(key.getSub()).GDbox.getHigh(0) ||
1330  key.getKey().get(1) == gb.get(key.getSub()).GDbox.getHigh(1) ||
1331  key.getKey().get(2) == gb.get(key.getSub()).GDbox.getHigh(2))
1332  can_invalid = true;
1333 
1334  if (can_invalid == true)
1335  {
1336  if ( g_dist.template get<0>(key) != -1 && info.LinId(key_g) != g_dist.template get<0>(key) )
1337  match &= false;
1338  }
1339  else
1340  {
1341  if (info.LinId(key_g) != g_dist.template get<0>(key) )
1342  match &= false;
1343  }
1344 
1345  ++dom_gi;
1346  }
1347 
1348  BOOST_REQUIRE_EQUAL(match, true);
1349  if (k > 83)
1350  {
1351  vcl.sum(out_cnt);
1352  vcl.execute();
1353  BOOST_REQUIRE(out_cnt != 0ul);
1354  }
1355  }
1356 }
1357 
1358 // Test grid periodic
1359 
1360 void Test3D_periodic_put(const Box<3,float> & domain, long int k)
1361 {
1362  Vcluster & v_cl = create_vcluster();
1363 
1364  if ( v_cl.getProcessingUnits() > 32 )
1365  return;
1366 
1367  long int big_step = k / 30;
1368  big_step = (big_step == 0)?1:big_step;
1369  long int small_step = 21;
1370 
1371  print_test_v( "Testing grid periodic put k<=",k);
1372 
1373  // 3D test
1374  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1375  {
1376  BOOST_TEST_CHECKPOINT( "Testing grid periodick<=" << k );
1377 
1378  // grid size
1379  size_t sz[3];
1380  sz[0] = k;
1381  sz[1] = k;
1382  sz[2] = k;
1383 
1384  // Ghost
1385  Ghost<3,long int> g(1);
1386 
1387  // periodicity
1388  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
1389 
1390  // Distributed grid with id decomposition
1392 
1393  // check the consistency of the decomposition
1394  bool val = g_dist.getDecomposition().check_consistency();
1395  BOOST_REQUIRE_EQUAL(val,true);
1396 
1397  // Grid sm
1398  grid_sm<3,void> info(sz);
1399 
1400  size_t count = 0;
1401 
1402  {
1403  auto dom = g_dist.getDomainIterator();
1404 
1405  while (dom.isNext())
1406  {
1407  auto key = dom.get();
1408 
1409  g_dist.template get<0>(key) = -6.0;
1410 
1411  // Count the points
1412  count++;
1413 
1414  ++dom;
1415  }
1416  }
1417 
1418  // Set to zero the full grid
1419 
1420  {
1421  auto dom = g_dist.getDomainIterator();
1422 
1423  while (dom.isNext())
1424  {
1425  auto key = dom.get();
1426 
1427  g_dist.template get<0>(key.move(0,1)) += 1.0;
1428  g_dist.template get<0>(key.move(0,-1)) += 1.0;
1429  g_dist.template get<0>(key.move(1,1)) += 1.0;
1430  g_dist.template get<0>(key.move(1,-1)) += 1.0;
1431  g_dist.template get<0>(key.move(2,1)) += 1.0;
1432  g_dist.template get<0>(key.move(2,-1)) += 1.0;
1433 
1434  ++dom;
1435  }
1436  }
1437 
1438  bool correct = true;
1439 
1440  // Domain + Ghost iterator
1441  auto dom_gi = g_dist.getDomainIterator();
1442 
1443  while (dom_gi.isNext())
1444  {
1445  auto key = dom_gi.get();
1446 
1447  correct &= (g_dist.template get<0>(key) == 0);
1448 
1449  ++dom_gi;
1450  }
1451 
1452  g_dist.ghost_put<add_,0>();
1453 
1454  if (count != 0)
1455  BOOST_REQUIRE_EQUAL(correct, false);
1456 
1457  // sync the ghosts
1458  g_dist.ghost_get<0>();
1459 
1460  correct = true;
1461 
1462  // Domain + Ghost iterator
1463  auto dom_gi2 = g_dist.getDomainIterator();
1464 
1465  while (dom_gi2.isNext())
1466  {
1467  auto key = dom_gi2.get();
1468 
1469  correct &= (g_dist.template get<0>(key) == 0);
1470 
1471  ++dom_gi2;
1472  }
1473 
1474  BOOST_REQUIRE_EQUAL(correct, true);
1475  }
1476 }
1477 
1478 void Test_grid_copy(const Box<3,float> & domain, long int k)
1479 {
1480  typedef Point_test<float> p;
1481 
1482  Vcluster & v_cl = create_vcluster();
1483 
1484  if ( v_cl.getProcessingUnits() > 32 )
1485  return;
1486 
1487  long int big_step = k / 30;
1488  big_step = (big_step == 0)?1:big_step;
1489  long int small_step = 21;
1490 
1491  print_test_v( "Testing grid copy k<=",k);
1492 
1493  // 3D test
1494  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1495  {
1496  BOOST_TEST_CHECKPOINT( "Testing grid periodick<=" << k );
1497 
1498  // grid size
1499  size_t sz[3];
1500  sz[0] = k;
1501  sz[1] = k;
1502  sz[2] = k;
1503 
1504  // factor
1505  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1506 
1507  // Ghost
1508  Ghost<3,float> g(0.01 / factor);
1509 
1510  // periodicity
1511  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
1512 
1513  // Distributed grid with id decomposition
1514  grid_dist_id<3,float,Point_test<float>> g_dist(sz,domain,g,pr);
1515  grid_dist_id<3,float,Point_test<float>> g_dist2(g_dist.getDecomposition(),sz,g);
1516 
1517  // Grid sm
1518  grid_sm<3,void> info(sz);
1519 
1520  // Set to zero the full grid
1521  auto dom = g_dist.getDomainIterator();
1522 
1523  while (dom.isNext())
1524  {
1525  auto key = dom.get();
1526  auto key_g = g_dist.getGKey(key);
1527 
1528  size_t k = info.LinId(key_g);
1529 
1530  g_dist.template get<p::x>(key) = 1 + k;
1531  g_dist.template get<p::y>(key) = 567 + k;
1532  g_dist.template get<p::z>(key) = 341 + k;
1533  g_dist.template get<p::s>(key) = 5670 + k;
1534  g_dist.template get<p::v>(key)[0] = 921 + k;
1535  g_dist.template get<p::v>(key)[1] = 5675 + k;
1536  g_dist.template get<p::v>(key)[2] = 117 + k;
1537  g_dist.template get<p::t>(key)[0][0] = 1921 + k;
1538  g_dist.template get<p::t>(key)[0][1] = 25675 + k;
1539  g_dist.template get<p::t>(key)[0][2] = 3117 + k;
1540  g_dist.template get<p::t>(key)[1][0] = 4921 + k;
1541  g_dist.template get<p::t>(key)[1][1] = 55675 + k;
1542  g_dist.template get<p::t>(key)[1][2] = 6117 + k;
1543  g_dist.template get<p::t>(key)[2][0] = 7921 + k;
1544  g_dist.template get<p::t>(key)[2][1] = 85675 + k;
1545  g_dist.template get<p::t>(key)[2][2] = 9117 + k;
1546 
1547  ++dom;
1548  }
1549 
1550  g_dist2.copy(g_dist);
1551 
1552  auto dom2 = g_dist2.getDomainIterator();
1553 
1554  bool match = true;
1555 
1556  // check that the grid store the correct information
1557  while (dom2.isNext())
1558  {
1559  auto key = dom2.get();
1560  auto key_g = g_dist.getGKey(key);
1561 
1562  size_t k = info.LinId(key_g);
1563 
1564  match &= (g_dist2.template get<p::x>(key) == 1 + k)?true:false;
1565  match &= (g_dist2.template get<p::y>(key) == 567 + k)?true:false;
1566  match &= (g_dist2.template get<p::z>(key) == 341 + k)?true:false;
1567  match &= (g_dist2.template get<p::s>(key) == 5670 + k)?true:false;
1568  match &= (g_dist2.template get<p::v>(key)[0] == 921 + k)?true:false;
1569  match &= (g_dist2.template get<p::v>(key)[1] == 5675 + k)?true:false;
1570  match &= (g_dist2.template get<p::v>(key)[2] == 117 + k)?true:false;
1571  match &= (g_dist2.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
1572  match &= (g_dist2.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
1573  match &= (g_dist2.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
1574  match &= (g_dist2.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
1575  match &= (g_dist2.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
1576  match &= (g_dist2.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
1577  match &= (g_dist2.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
1578  match &= (g_dist2.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
1579  match &= (g_dist2.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
1580 
1581  ++dom2;
1582  }
1583 
1584  BOOST_REQUIRE_EQUAL(match,true);
1585  }
1586 }
1587 
1588 void Test_ghost_correction(Box<3,double> & domain, long int k, long int g_)
1589 {
1590  size_t sz[3] = {(size_t)k,(size_t)k,(size_t)k};
1591  periodicity<3> bc = {PERIODIC,PERIODIC,PERIODIC};
1592 
1593  Ghost<3,long int> g(g_);
1594 
1596 
1597  auto itg = grid.getDomainGhostIterator();
1598 
1599  while (itg.isNext())
1600  {
1601  auto key = itg.get();
1602 
1603  grid.template get<0>(key) = 0.0;
1604 
1605  ++itg;
1606  }
1607 
1608  // Fill everything with 5
1609 
1610  auto it = grid.getDomainIterator();
1611 
1612  while (it.isNext())
1613  {
1614  auto key = it.get();
1615  auto gkey = it.getGKey(key);
1616 
1617  if (gkey.get(0) == -4 && gkey.get(1) == 20 && gkey.get(2) == -4)
1618  {
1619  grid.template get<0>(key) = 20.0;
1620  }
1621  else
1622  {
1623  grid.template get<0>(key) = 5.0;
1624  }
1625 
1626  ++it;
1627  }
1628 
1629  grid.ghost_get<0>();
1630  auto it2 = grid.getDomainGhostIterator();
1631 
1632  bool is_inside = true;
1633 
1634  while (it2.isNext())
1635  {
1636  auto key = it2.get();
1637  auto gkey = it2.getGKey(key);
1638 
1639  if (grid.template get<0>(key) == 5.0)
1640  {
1641  // Here we check that the point is with in one stencil point
1642  // from one sub-domain
1643 
1644  bool is_inside_point = false;
1645  for (size_t i = 0 ; i < grid.getN_loc_grid() ; i++)
1646  {
1647  Box<3,long int> bx = grid.getLocalGridsInfo().get(i).Dbox;
1648  bx += grid.getLocalGridsInfo().get(i).origin;
1649 
1650  bx.enlarge(g);
1651 
1652  if (bx.isInside(gkey.toPoint()) == true)
1653  {
1654  is_inside_point |= true;
1655  }
1656  }
1657 
1658  is_inside &= is_inside_point;
1659  }
1660 
1661  ++it2;
1662  }
1663 
1664 
1665  grid.getDecomposition().write("dec_set_for_adj");
1666  grid.write("dec_for_adj");
1667 
1668  BOOST_REQUIRE_EQUAL(is_inside,true);
1669 }
1670 
1671 BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use)
1672 {
1673  // Domain
1674  Box<2,float> domain({0.0,0.0},{1.0,1.0});
1675 
1676 #ifdef TEST_COVERAGE_MODE
1677  long int k = 256*256*create_vcluster().getProcessingUnits();
1678 #else
1679  long int k = 1024*1024*create_vcluster().getProcessingUnits();
1680 #endif
1681  k = std::pow(k, 1/2.);
1682 
1683  Test2D(domain,k);
1684  Test2D_complex(domain,k);
1685  // Domain
1686  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1687 
1688  k = 128*128*128*create_vcluster().getProcessingUnits();
1689  k = std::pow(k, 1/3.);
1690  Test3D(domain3,k);
1691  Test3D_complex(domain3,k);
1692 }
1693 
1694 BOOST_AUTO_TEST_CASE( grid_dist_id_dup)
1695 {
1696  // Domain
1697  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1698 
1699  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1700  k = std::pow(k, 1/3.);
1701  Test3D_dup(domain3,k);
1702 }
1703 
1704 BOOST_AUTO_TEST_CASE( grid_dist_id_sub)
1705 {
1706  // Domain
1707  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1708 
1709  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1710  k = std::pow(k, 1/3.);
1711  Test3D_sub(domain3,k);
1712 }
1713 
1714 
1715 BOOST_AUTO_TEST_CASE( grid_dist_id_with_grid_unit_ghost )
1716 {
1717  // Domain
1718  Box<2,float> domain({0.0,0.0},{1.0,1.0});
1719 
1720  long int k = 1024*1024*create_vcluster().getProcessingUnits();
1721  k = std::pow(k, 1/2.);
1722 
1723  // Domain
1724  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1725 
1726  k = 128*128*128*create_vcluster().getProcessingUnits();
1727  k = std::pow(k, 1/3.);
1728  Test3D_gg(domain3,k,1);
1729 }
1730 
1731 
1732 BOOST_AUTO_TEST_CASE( grid_dist_id_domain_test_use)
1733 {
1734  // Domain
1735  Box<3,float> domain3({-0.3,-0.3,-0.3},{1.1,1.1,1.1});
1736 
1737  periodicity<3> np({{NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}});
1738  periodicity<3> p({{PERIODIC,PERIODIC,PERIODIC}});
1739 
1740  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1741  k = std::pow(k, 1/3.);
1742  Test3D_domain(domain3,k,np);
1743 
1744  auto & v_cl = create_vcluster();
1745  if (v_cl.getProcessingUnits() > 32)
1746  return;
1747 
1748  // We use a 128x128x128 and we move tha domain
1749 
1750  for (size_t i = 0 ; i < 10 ; i++)
1751  {
1752  Box<3,float> exp({0.0,0.0,0.0},{1.3,1.3,1.3});
1753  domain3.enlarge(exp);
1754  Test3D_domain(domain3,128,p);
1755  }
1756 }
1757 
1758 BOOST_AUTO_TEST_CASE( grid_dist_id_extended )
1759 {
1760  // Domain
1761  Box<3,float> domain3({0.1,0.1,0.1},{1.1,1.1,1.1});
1762 
1763  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1764  k = std::pow(k, 1/3.);
1765 
1766  Test3D_extended_grid(domain3,k);
1767 }
1768 
1769 BOOST_AUTO_TEST_CASE( grid_dist_id_periodic )
1770 {
1771  // Domain
1772  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1773 
1774  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1775  k = std::pow(k, 1/3.);
1776 
1777  Test3D_periodic(domain3,k);
1778 }
1779 
1780 BOOST_AUTO_TEST_CASE( grid_dist_id_unbound_ghost )
1781 {
1782  // Domain
1783  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1784 
1785  long int k = 28*28*28*create_vcluster().getProcessingUnits();
1786  k = std::pow(k, 1/3.);
1787 
1788  Test3D_unb_ghost(domain3,k);
1789 }
1790 
1791 BOOST_AUTO_TEST_CASE( grid_dist_id_unbound_ghost_periodic )
1792 {
1793  // Domain
1794  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1795 
1796  long int k = 25*25*25*create_vcluster().getProcessingUnits();
1797  k = std::pow(k, 1/3.);
1798 
1799  Test3D_unb_ghost_periodic(domain3,k);
1800 }
1801 
1802 BOOST_AUTO_TEST_CASE( grid_dist_id_copy )
1803 {
1804  // Domain
1805  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1806 
1807  long int k = 32*32*32*create_vcluster().getProcessingUnits();
1808  k = std::pow(k, 1/3.);
1809 
1810  Test_grid_copy(domain3,k);
1811 }
1812 
1813 BOOST_AUTO_TEST_CASE( grid_1d_test )
1814 {
1815  // Domain
1816  Box<1,float> domain1({-1.0},{1.0});
1817 
1818  long int k = 32*32*32*create_vcluster().getProcessingUnits();
1819 
1820  Test1D(domain1,k);
1821 }
1822 
1823 BOOST_AUTO_TEST_CASE( grid_dist_id_periodic_put_test )
1824 {
1825  // Domain
1826  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1827 
1828  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1829  k = std::pow(k, 1/3.);
1830 
1831  Test3D_periodic_put(domain3,k);
1832 }
1833 
1834 BOOST_AUTO_TEST_CASE ( grid_ghost_correction )
1835 {
1836  Box<3,double> domain({0.0,0.0,0.0},{2.5,2.5,2.5});
1837 
1838  long int k = 128;
1839 
1840  Test_ghost_correction(domain,k,1);
1841  Test_ghost_correction(domain,k,2);
1842  Test_ghost_correction(domain,k,3);
1843  Test_ghost_correction(domain,k,4);
1844 
1845  k = 64;
1846 
1847  Test_ghost_correction(domain,k,1);
1848  Test_ghost_correction(domain,k,2);
1849  Test_ghost_correction(domain,k,3);
1850  Test_ghost_correction(domain,k,4);
1851 
1852  k = 32;
1853 
1854  Test_ghost_correction(domain,k,1);
1855  Test_ghost_correction(domain,k,2);
1856  Test_ghost_correction(domain,k,3);
1857  Test_ghost_correction(domain,k,4);
1858 
1859  k = 16;
1860 
1861  Test_ghost_correction(domain,k,1);
1862  Test_ghost_correction(domain,k,2);
1863  Test_ghost_correction(domain,k,3);
1864  Test_ghost_correction(domain,k,4);
1865 }
1866 
1867 BOOST_AUTO_TEST_CASE ( grid_basic_functions )
1868 {
1869  auto & v_cl = create_vcluster();
1870 
1871  if (v_cl.getProcessingUnits() != 1)
1872  {return;}
1873 
1874  size_t sz[2] = {(size_t)8,(size_t)8};
1875  periodicity<2> bc = {PERIODIC,PERIODIC};
1876 
1877  Ghost<2,long int> g(1);
1878  Box<2,double> domain({-1.0,-1.0},{1.0,1.0});
1879 
1881 
1882  BOOST_REQUIRE_EQUAL(grid.getOffset(0)[0],-1.25);
1883  BOOST_REQUIRE_EQUAL(grid.getOffset(0)[1],-1.25);
1884 }
1885 
1886 BOOST_AUTO_TEST_CASE ( grid_overflow_round_off_error )
1887 {
1888  size_t numGridPoint = 100;
1889  const double domainSize = 20851.7;
1890  double domainLength = sqrt(domainSize);
1891 
1892  Box<2,double> domain({0.0,0.0},{domainLength,domainLength});
1893 
1894  size_t sz[2] = {numGridPoint,numGridPoint};
1895 
1896  periodicity<2> bc = {PERIODIC,PERIODIC};
1897 
1898  Ghost<2,double> g(3.0*(domain.getHigh(0) - domain.getLow(0))/numGridPoint + 0.001);
1899 
1901 
1902  auto & gs = grid.getGridInfo();
1903 
1904  auto it = grid.getDomainIterator();
1905 
1906  while (it.isNext())
1907  {
1908  auto p = it.get();
1909  auto gp = it.getGKey(p);
1910 
1911  grid.get<0>(p) = gs.LinId(gp);
1912 
1913  ++it;
1914  }
1915 
1916  grid.ghost_get<0>();
1917 
1918  // Now we check
1919 
1920  auto it2 = grid.getDomainIterator();
1921 
1922  bool match = true;
1923 
1924  while (it2.isNext())
1925  {
1926  auto p = it2.get();
1927  auto gp = it.getGKey(p);
1928 
1929  if (gs.LinId(gp) != grid.get<0>(p))
1930  {match = false;}
1931 
1932  // look around
1933 
1934  auto px = p.move(0,1);
1935  auto gpx = it.getGKey(px);
1936  auto mx = p.move(0,-1);
1937  auto gmx = it.getGKey(mx);
1938 
1939  auto py = p.move(1,1);
1940  auto gpy = it.getGKey(py);
1941  auto my = p.move(1,-1);
1942  auto gmy = it.getGKey(my);
1943 
1944  gpx.set_d(0,gpx.get(0) % gs.size(0));
1945  gpx.set_d(1,gpx.get(1) % gs.size(1));
1946 
1947  if (grid.template get<0>(px) != gs.LinId(gpx))
1948  {match = false;}
1949 
1950  gmx.set_d(0,(gmx.get(0) + gs.size(0)) % gs.size(0));
1951  gmx.set_d(1,(gmx.get(1) + gs.size(1)) % gs.size(1));
1952 
1953  if (grid.template get<0>(mx) != gs.LinId(gmx))
1954  {match = false;}
1955 
1956  gpy.set_d(0,gpy.get(0) % gs.size(0));
1957  gpy.set_d(1,gpy.get(1) % gs.size(1));
1958 
1959  if (grid.template get<0>(py) != gs.LinId(gpy))
1960  {match = false;}
1961 
1962  gmy.set_d(0,(gmy.get(0) + gs.size(0)) % gs.size(0));
1963  gmy.set_d(1,(gmy.get(1) + gs.size(1)) % gs.size(1));
1964 
1965  if (grid.template get<0>(my) != gs.LinId(gmy))
1966  {match = false;}
1967 
1968  ++it2;
1969  }
1970 
1971  BOOST_REQUIRE_EQUAL(match,true);
1972 }
1973 
1974 
1975 BOOST_AUTO_TEST_SUITE_END()
1976 
void sum(T &num)
Sum the numbers across all processors and get the result.
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
grid_dist_iterator< dim, device_grid, FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain) ...
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
size_t getProcessUnitID()
Get the process unit id.
void execute()
Execute all the requests.
bool isInside(const Point< dim, T > &p) const
Check if the point is inside the box.
Definition: Box.hpp:880
bool check_consistency()
function to check the consistency of the information of the decomposition
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
This structure define the operation add to use with copy general.
Definition: Ghost.hpp:39
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
Implementation of VCluster class.
Definition: VCluster.hpp:36
This class decompose a space into sub-sub-domains and distribute them across processors.
This is a distributed grid.
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:700
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > & copy(grid_dist_id< dim, St, T, Decomposition, Memory, device_grid > &g, bool use_memcpy=true)
Copy the give grid into this grid.
Declaration grid_sm.
Definition: grid_sm.hpp:71
Test structure used for several test.
Definition: Point_test.hpp:105
T getVolumeKey() const
Get the volume spanned by the Box P1 and P2 interpreted as grid key.
Definition: Box.hpp:1154
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
size_t getProcessingUnits()
Get the total number of processors.
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.