OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
grid_dist_id_unit_test.cpp
1 #define BOOST_TEST_DYN_LINK
2 #include <boost/test/unit_test.hpp>
3 
4 #include "Point_test.hpp"
5 #include "Grid/grid_dist_id.hpp"
6 #include "data_type/aggregate.hpp"
7 #include "grid_dist_id_unit_test_ext_dom.hpp"
8 #include "grid_dist_id_unit_test_unb_ghost.hpp"
9 #include "grid_dist_id_util_tests.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  auto ghost_start = g_dist.getLocalGridsInfo().get(0).Dbox.getKP1();
57 
58  // get the decomposition
59  auto & dec = g_dist.getDecomposition();
60 
61  // check the consistency of the decomposition
62  bool val = dec.check_consistency();
63  BOOST_REQUIRE_EQUAL(val,true);
64 
65  // for each local volume
66  // Get the number of local grid needed
67  size_t n_grid = dec.getNSubDomain();
68 
69  size_t vol = 0;
70 
71  // vector of boxes
73 
74  // Allocate the grids
75  for (size_t i = 0 ; i < n_grid ; i++)
76  {
77  // Get the local hyper-cube
78  SpaceBox<3,float> sub = dec.getSubDomain(i);
79 // sub -= domain.getP1();
80 
81  Box<3,size_t> g_box = g_dist.getCellDecomposer().convertDomainSpaceIntoGridUnits(sub,bc);
82 
83  vb.add(g_box);
84 
85  vol += g_box.getVolumeKey();
86  }
87 
88  // Create a writer and write
89  VTKWriter<openfpm::vector<Box<3,size_t>>,VECTOR_BOX> vtk_box2;
90  vtk_box2.add(vb);
91  vtk_box2.write(std::to_string(v_cl.getProcessUnitID()) + "vtk_box_3D.vtk");
92 
93  v_cl.sum(vol);
94  v_cl.execute();
95 
96  BOOST_REQUIRE_EQUAL(vol,sz[0]*sz[1]*sz[2]);
97 
98  // Check getPos
99 
100  auto it = g_dist.getDomainIterator();
101 
102  if (it.isNext())
103  {
104  auto key = it.get();
105  auto gkey = it.getGKey(key);
106 
107  auto pos = g_dist.getPos(key);
108 
109  if (gkey.get(0) == 0 && gkey.get(1) == 0 && gkey.get(2) == 0)
110  {
111  BOOST_REQUIRE_CLOSE(pos.get(0),-0.3f,0.0001);
112  BOOST_REQUIRE_CLOSE(pos.get(1),-0.3f,0.0001);
113  BOOST_REQUIRE_CLOSE(pos.get(2),-0.3f,0.0001);
114  }
115  }
116 
117  int check = 0;
118 
119  while (it.isNext())
120  {
121  auto key2 = it.get();
122 
123  auto pos = g_dist.getPos(key2);
124 
125  if (pos[0] >= 0.99999 && pos[0] <= 1.00001 &&
126  pos[1] >= 0.99999 && pos[1] <= 1.00001 &&
127  pos[2] >= 0.99999 && pos[2] <= 1.00001)
128  {
129  check = 1;
130  }
131 
132  ++it;
133  }
134 
135  v_cl.max(check);
136  v_cl.execute();
137 
138  BOOST_REQUIRE_EQUAL(check,1);
139  }
140 }
141 
142 
143 BOOST_AUTO_TEST_CASE( grid_dist_id_domain_grid_unit_converter_test)
144 {
145  size_t bc[2] = {NON_PERIODIC, NON_PERIODIC};
146 
147  // Domain
148  Box<2,float> domain({0.0,0.0},{1.0,1.0});
149 
150  Vcluster<> & v_cl = create_vcluster();
151 
152  // Skip this test on big scale
153  if (v_cl.getProcessingUnits() >= 32)
154  return;
155 
156  for (size_t k = 1024 ; k >= 2 ; k--)
157  {
158  BOOST_TEST_CHECKPOINT( "Testing grid converter 3D k=" << k );
159 
160  // grid size
161  size_t sz[2];
162  sz[0] = k;
163  sz[1] = k;
164 
165  // Ghost
166  Ghost<2,float> g(0.01);
167 
168  // Distributed grid with id decomposition
170 
171  // get the decomposition
172  auto & dec = g_dist.getDecomposition();
173 
174  // check the consistency of the decomposition
175  bool val = dec.check_consistency();
176  BOOST_REQUIRE_EQUAL(val,true);
177 
178  // for each local volume
179  // Get the number of local grid needed
180  size_t n_grid = dec.getNSubDomain();
181 
182  size_t vol = 0;
183 
184  // Allocate the grids
185  for (size_t i = 0 ; i < n_grid ; i++)
186  {
187  // Get the local hyper-cube
188  SpaceBox<2,float> sub = dec.getSubDomain(i);
189 
190  Box<2,size_t> g_box = g_dist.getCellDecomposer().convertDomainSpaceIntoGridUnits(sub,bc);
191 
192  if (g_box.isValid() == true)
193  {vol += g_box.getVolumeKey();}
194  }
195 
196  v_cl.sum(vol);
197  v_cl.execute();
198 
199  BOOST_REQUIRE_EQUAL(vol,sz[0]*sz[1]);
200  }
201 }
202 
203 
204 void Test2D(const Box<2,float> & domain, long int k)
205 {
206  long int big_step = k / 30;
207  big_step = (big_step == 0)?1:big_step;
208  long int small_step = 21;
209 
210  print_test_v( "Testing 2D grid k<=",k);
211 
212  // 2D test
213  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
214  {
215  BOOST_TEST_CHECKPOINT( "Testing 2D grid k=" << k );
216 
218 
219  // grid size
220  size_t sz[2];
221  sz[0] = k;
222  sz[1] = k;
223 
224  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/2.0f);
225 
226  // Ghost
227  Ghost<2,float> g(0.01 / factor);
228 
229  // Distributed grid with id decomposition
230  grid_dist_id<2, float, aggregate<double>> g_dist(sz,domain,g);
231 
232  Test2D_core(g_dist,sz,k);
233  }
234 }
235 
236 
237 void Test1D(const Box<1,float> & domain, long int k)
238 {
239  Vcluster<> & v_cl = create_vcluster();
240  long int big_step = k / 30;
241  big_step = (big_step == 0)?1:big_step;
242  long int small_step = 21;
243 
244  if (v_cl.getProcessingUnits() > 48)
245  return;
246 
247  print_test_v( "Testing 1D grid k<=",k);
248 
249  // 1D test
250  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
251  {
252  BOOST_TEST_CHECKPOINT( "Testing 1D grid k=" << k );
253 
254  // grid size
255  size_t sz[1];
256  sz[0] = k;
257 
258  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f);
259 
260  // Ghost
261  Ghost<1,float> g(0.01 / factor);
262 
263  // Distributed grid with id decomposition
264  grid_dist_id<1, float, aggregate<float>> g_dist(sz,domain,g);
265 
266  // check the consistency of the decomposition
267  bool val = g_dist.getDecomposition().check_consistency();
268  BOOST_REQUIRE_EQUAL(val,true);
269 
270  // Grid sm
271  grid_sm<1,void> info(sz);
272 
273  // get the domain iterator
274  size_t count = 0;
275 
276  auto dom = g_dist.getDomainIterator();
277 
278  while (dom.isNext())
279  {
280  auto key = dom.get();
281  auto key_g = g_dist.getGKey(key);
282 
283  g_dist.template get<0>(key) = info.LinId(key_g);
284 
285  // Count the point
286  count++;
287 
288  ++dom;
289  }
290 
291  // Get the virtual cluster machine
292  Vcluster<> & vcl = g_dist.getVC();
293 
294  // reduce
295  vcl.sum(count);
296  vcl.execute();
297 
298  // Check
299  BOOST_REQUIRE_EQUAL(count,(size_t)k);
300 
301  auto dom2 = g_dist.getDomainIterator();
302 
303  grid_key_dx<1> start = dom2.getStart();
304  grid_key_dx<1> stop = dom2.getStop();
305 
306  BOOST_REQUIRE_EQUAL((long int)stop.get(0),(long int)g_dist.size(0)-1);
307 
308  BOOST_REQUIRE_EQUAL(start.get(0),0);
309 
310  bool match = true;
311 
312  // check that the grid store the correct information
313  while (dom2.isNext())
314  {
315  auto key = dom2.get();
316  auto key_g = g_dist.getGKey(key);
317 
318  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
319 
320  ++dom2;
321  }
322 
323  BOOST_REQUIRE_EQUAL(match,true);
324 
325  g_dist.template ghost_get<0>();
326 
327  // check that the communication is correctly completed
328 
329  auto domg = g_dist.getDomainGhostIterator();
330 
331  // check that the grid with the ghost past store the correct information
332  while (domg.isNext())
333  {
334  auto key = domg.get();
335  auto key_g = g_dist.getGKey(key);
336 
337  // In this case the boundary condition are non periodic
338  if (g_dist.isInside(key_g))
339  {
340  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
341  }
342 
343  ++domg;
344  }
345 
346  BOOST_REQUIRE_EQUAL(match,true);
347  }
348 }
349 
350 void Test3D_sub(const Box<3,float> & domain, long int k)
351 {
352  long int big_step = k / 30;
353  big_step = (big_step == 0)?1:big_step;
354  long int small_step = 21;
355 
356  // this test is only performed when the number of processor is <= 32
357  if (create_vcluster().getProcessingUnits() > 32)
358  return;
359 
360  print_test_v( "Testing 3D grid sub k<=",k);
361 
362  // 3D test
363  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
364  {
365  BOOST_TEST_CHECKPOINT( "Testing 3D grid sub k=" << k );
366 
367  // grid size
368  size_t sz[3];
369  sz[0] = k;
370  sz[1] = k;
371  sz[2] = k;
372 
373  // factor
374  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
375 
376  // Ghost
377  Ghost<3,float> g(0.01 / factor);
378 
379  // Distributed grid with id decomposition
381 
382  // check the consistency of the decomposition
383  bool val = g_dist.getDecomposition().check_consistency();
384  BOOST_REQUIRE_EQUAL(val,true);
385 
386  // Grid sm
387  grid_sm<3,void> info(sz);
388 
389  // get the domain iterator
390  size_t count = 0;
391 
392  grid_key_dx<3> one(1,1,1);
393  grid_key_dx<3> one_end(k-2,k-2,k-2);
394 
395  // Sub-domain iterator
396  auto dom = g_dist.getSubDomainIterator(one,one_end);
397 
398  while (dom.isNext())
399  {
400  auto key = dom.get();
401  auto key_g = g_dist.getGKey(key);
402 
403  g_dist.template get<0>(key) = info.LinId(key_g);
404 
405  // Count the point
406  count++;
407 
408  ++dom;
409  }
410 
411  // Get the virtual cluster machine
412  Vcluster<> & vcl = g_dist.getVC();
413 
414  // reduce
415  vcl.sum(count);
416  vcl.execute();
417 
418  // Check
419  BOOST_REQUIRE_EQUAL(count,(size_t)(k-2)*(k-2)*(k-2));
420 
421  // check with a 1x1x1 square
422  {
423 
424  grid_key_dx<3> one(k/2,k/2,k/2);
425  grid_key_dx<3> one_end(k/2,k/2,k/2);
426 
427  count = 0;
428 
429  // get the sub-domain iterator
430  auto dom = g_dist.getSubDomainIterator(one,one_end);
431 
432  while (dom.isNext())
433  {
434  auto key = dom.get();
435  auto key_g = g_dist.getGKey(key);
436 
437  // key_g
438  BOOST_REQUIRE_EQUAL(key_g.get(0),k/2);
439  BOOST_REQUIRE_EQUAL(key_g.get(1),k/2);
440  BOOST_REQUIRE_EQUAL(key_g.get(2),k/2);
441 
442  auto key_s_it = dom.getGKey(key);
443 
444  BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0));
445  BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1));
446  BOOST_REQUIRE_EQUAL(key_g.get(2),key_s_it.get(2));
447 
448  // Count the point
449  count++;
450 
451  ++dom;
452  }
453 
454  // reduce
455  vcl.sum(count);
456  vcl.execute();
457 
458  BOOST_REQUIRE_EQUAL(count,1ul);
459  }
460  }
461 }
462 
463 void Test3D(const Box<3,float> & domain, long int k)
464 {
465  long int big_step = k / 30;
466  big_step = (big_step == 0)?1:big_step;
467  long int small_step = 21;
468 
469  print_test_v( "Testing 3D grid k<=",k);
470 
471  // 3D test
472  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
473  {
474  BOOST_TEST_CHECKPOINT( "Testing 3D grid k=" << k );
475 
476  // grid size
477  size_t sz[3];
478  sz[0] = k;
479  sz[1] = k;
480  sz[2] = k;
481 
482  // factor
483  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
484 
485  // Ghost
486  Ghost<3,float> g(0.01 / factor);
487 
488  // Distributed grid with id decomposition
490 
491  // check the consistency of the decomposition
492  bool val = g_dist.getDecomposition().check_consistency();
493  BOOST_REQUIRE_EQUAL(val,true);
494 
495  // Grid sm
496  grid_sm<3,void> info(sz);
497 
498  // get the domain iterator
499  size_t count = 0;
500 
501  auto dom = g_dist.getDomainIterator();
502 
503  while (dom.isNext())
504  {
505  auto key = dom.get();
506  auto key_g = g_dist.getGKey(key);
507 
508  g_dist.template get<0>(key) = info.LinId(key_g);
509 
510  // Count the point
511  count++;
512 
513  ++dom;
514  }
515 
516  // Get the virtual cluster machine
517  Vcluster<> & vcl = g_dist.getVC();
518 
519  // reduce
520  vcl.sum(count);
521  vcl.execute();
522 
523  // Check
524  BOOST_REQUIRE_EQUAL(count,(size_t)k*k*k);
525 
526  bool match = true;
527 
528  auto dom2 = g_dist.getDomainIterator();
529 
530  // check that the grid store the correct information
531  while (dom2.isNext())
532  {
533  auto key = dom2.get();
534  auto key_g = g_dist.getGKey(key);
535 
536  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
537 
538  ++dom2;
539  }
540 
541  BOOST_REQUIRE_EQUAL(match,true);
542 
544 
545  g_dist.template ghost_get<0>();
546 
547  // check that the communication is correctly completed
548 
549  auto domg = g_dist.getDomainGhostIterator();
550 
551  // check that the grid with the ghost part store the correct information
552  while (domg.isNext())
553  {
554  auto key = domg.get();
555  auto key_g = g_dist.getGKey(key);
556 
557  // In this case the boundary condition are non periodic
558  if (g_dist.isInside(key_g))
559  {
560  match &= (g_dist.template get<0>(key) == info.LinId(key_g))?true:false;
561  if (match == false)
562  {std::cout << "ERROR IN: " << key_g.to_string() << " " << info.LinId(key_g) << " != " << g_dist.template get<0>(key) << std::endl; break;}
563  }
564 
565  ++domg;
566  }
567 
568 // if (match == false)
569 // {
570  g_dist.write("Error_grid");
571 
572  g_dist.getDecomposition().write("Error_dec");
573 // }
574 
575  BOOST_REQUIRE_EQUAL(match,true);
576 
578  }
579 }
580 
581 
582 void Test3D_gg(const Box<3,float> & domain, long int k, long int gk)
583 {
584  long int big_step = k / 30;
585  big_step = (big_step == 0)?1:big_step;
586 
587  // this test is only performed when the number of processor is <= 32
588  if (create_vcluster().getProcessingUnits() > 32)
589  return;
590 
591  print_test_v( "Testing 3D grid k<=",k);
592 
593  // 3D test
594  for ( ; k > 64 ; k /= 2 )
595  {
596  BOOST_TEST_CHECKPOINT( "Testing 3D grid ghost integer k=" << k );
597 
598  // grid size
599  size_t sz[3];
600  sz[0] = k;
601  sz[1] = k;
602  sz[2] = k;
603 
604  // Ghost
605  Ghost<3,long int> g(gk);
606 
607  // Distributed grid with id decomposition
609 
610  // check the consistency of the decomposition
611  bool val = g_dist.getDecomposition().check_consistency();
612  BOOST_REQUIRE_EQUAL(val,true);
613 
614  auto lg = g_dist.getLocalGridsInfo();
615 
616  // for each local grid check that the border is 1 point
617  // (Warning this property can only be ensured with k is a multiple of 2)
618  // in the other case it will be mostly like that but cannot be ensured
619 
620  for (size_t i = 0 ; i < lg.size() ; i++)
621  {
622  for (size_t j = 0 ; j < 3 ; j++)
623  {
624  BOOST_REQUIRE(lg.get(i).Dbox.getLow(j) >= gk);
625  BOOST_REQUIRE((lg.get(i).GDbox.getHigh(j) - lg.get(i).Dbox.getHigh(j)) >= gk);
626  }
627  }
628  }
629 }
630 
636 void Test3D_domain(const Box<3,float> & domain, long int k, const periodicity<3> & pr)
637 {
638  long int big_step = k / 30;
639  big_step = (big_step == 0)?1:big_step;
640  long int small_step = 21;
641 
642  print_test_v( "Testing 3D grid shift domain k<=",k);
643 
644  // 3D test
645  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
646  {
647  BOOST_TEST_CHECKPOINT( "Testing 3D grid shift domain k=" << k );
648 
649  // grid size
650  size_t sz[3];
651  sz[0] = k;
652  sz[1] = k;
653  sz[2] = k;
654 
655  // factor
656  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
657 
658  // Ghost
659  Ghost<3,float> g(0.01 / factor);
660 
661  // Distributed grid with id decomposition
663 
664  auto & v_cl = create_vcluster();
665 
666  // check the consistency of the decomposition
667  bool val = g_dist.getDecomposition().check_consistency();
668  BOOST_REQUIRE_EQUAL(val,true);
669 
670  // Grid sm
671  grid_sm<3,void> info(sz);
672 
673  // get the domain iterator
674  size_t count = 0;
675 
676  auto dom = g_dist.getDomainIterator();
677 
678  while (dom.isNext())
679  {
680  auto key = dom.get();
681  auto key_g = g_dist.getGKey(key);
682 
683  g_dist.template get<0>(key) = count;
684  g_dist.template get<1>(key) = info.LinId(key_g);
685 
686  // Count the point
687  count++;
688 
689  ++dom;
690  }
691 
692  size_t count2 = count;
694 
695  // Get the total size of the local grids on each processors
696  // and the total size
697  v_cl.sum(count2);
698  v_cl.allGather(count,pnt);
699  v_cl.execute();
700  size_t s_pnt = 0;
701 
702  // calculate the starting point for this processor
703  for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
704  s_pnt += pnt.get(i);
705 
706  // Check
707  BOOST_REQUIRE_EQUAL(count2,(size_t)k*k*k);
708 
709  // sync the ghost
710  g_dist.template ghost_get<0,1>();
711 
712  bool match = true;
713 
714  // check that the communication is correctly completed
715 
716  auto domg = g_dist.getDomainGhostIterator();
717 
718  // check that the grid with the ghost past store the correct information
719  while (domg.isNext())
720  {
721  auto key = domg.get();
722  auto key_g = g_dist.getGKey(key);
723 
724  // In this case the boundary condition are non periodic
725  if (g_dist.isInside(key_g))
726  {
727  match &= (g_dist.template get<1>(key) == info.LinId(key_g))?true:false;
728  }
729 
730  ++domg;
731  }
732 
733  BOOST_REQUIRE_EQUAL(match,true);
734  }
735 }
736 
737 
738 
739 void Test2D_complex(const Box<2,float> & domain, long int k)
740 {
741  typedef Point_test<float> p;
742 
743  long int big_step = k / 30;
744  big_step = (big_step == 0)?1:big_step;
745  long int small_step = 21;
746 
747  print_test_v( "Testing 2D complex grid k<=",k);
748 
749  // 2D test
750  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
751  {
752  BOOST_TEST_CHECKPOINT( "Testing 2D complex grid k=" << k );
753 
755 
756  // grid size
757  size_t sz[2];
758  sz[0] = k;
759  sz[1] = k;
760 
761  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/2.0f);
762 
763  // Ghost
764  Ghost<2,float> g(0.01 / factor);
765 
766  // Distributed grid with id decomposition
767  grid_dist_id<2, float, Point_test<float>> g_dist(sz,domain,g);
768 
769  // check the consistency of the decomposition
770  bool val = g_dist.getDecomposition().check_consistency();
771  BOOST_REQUIRE_EQUAL(val,true);
772 
773  // Grid sm
774  grid_sm<2,void> info(sz);
775 
776  // get the domain iterator
777  size_t count = 0;
778 
779  auto dom = g_dist.getDomainIterator();
780 
781  while (dom.isNext())
782  {
783  auto key = dom.get();
784  auto key_g = g_dist.getGKey(key);
785 
786  size_t k = info.LinId(key_g);
787 
788  g_dist.template get<p::x>(key) = 1 + k;
789  g_dist.template get<p::y>(key) = 567 + k;
790  g_dist.template get<p::z>(key) = 341 + k;
791  g_dist.template get<p::s>(key) = 5670 + k;
792  g_dist.template get<p::v>(key)[0] = 921 + k;
793  g_dist.template get<p::v>(key)[1] = 5675 + k;
794  g_dist.template get<p::v>(key)[2] = 117 + k;
795  g_dist.template get<p::t>(key)[0][0] = 1921 + k;
796  g_dist.template get<p::t>(key)[0][1] = 25675 + k;
797  g_dist.template get<p::t>(key)[0][2] = 3117 + k;
798  g_dist.template get<p::t>(key)[1][0] = 4921 + k;
799  g_dist.template get<p::t>(key)[1][1] = 55675 + k;
800  g_dist.template get<p::t>(key)[1][2] = 6117 + k;
801  g_dist.template get<p::t>(key)[2][0] = 7921 + k;
802  g_dist.template get<p::t>(key)[2][1] = 85675 + k;
803  g_dist.template get<p::t>(key)[2][2] = 9117 + k;
804 
805  // Count the point
806  count++;
807 
808  ++dom;
809  }
810 
812 
813  // Get the virtual cluster machine
814  Vcluster<> & vcl = g_dist.getVC();
815 
816  // reduce
817  vcl.sum(count);
818  vcl.execute();
819 
820  // Check
821  BOOST_REQUIRE_EQUAL(count,(size_t)k*k);
822 
823  auto dom2 = g_dist.getDomainIterator();
824 
825  bool match = true;
826 
827  // check that the grid store the correct information
828  while (dom2.isNext())
829  {
830  auto key = dom2.get();
831  auto key_g = g_dist.getGKey(key);
832 
833  size_t k = info.LinId(key_g);
834 
835  match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
836  match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
837  match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
838  match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
839  match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
840  match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
841  match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
842  match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
843  match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
844  match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
845  match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
846  match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
847  match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
848  match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
849  match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
850  match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
851 
852  ++dom2;
853  }
854 
855  BOOST_REQUIRE_EQUAL(match,true);
856 
858 
859  g_dist.template ghost_get<p::x,p::y,p::z,p::s,p::v,p::t>();
860 
861  // check that the communication is correctly completed
862 
863  auto domg = g_dist.getDomainGhostIterator();
864 
865  // check that the grid with the ghost past store the correct information
866  while (domg.isNext())
867  {
868  auto key = domg.get();
869  auto key_g = g_dist.getGKey(key);
870 
871  // In this case the boundary condition are non periodic
872  if (g_dist.isInside(key_g))
873  {
874  size_t k = info.LinId(key_g);
875 
876  match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
877  match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
878  match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
879  match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
880 
881  match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
882  match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
883  match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
884 
885  match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
886  match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
887  match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
888  match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
889  match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
890  match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
891  match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
892  match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
893  match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
894  }
895 
896  ++domg;
897  }
898 
900  }
901 }
902 
903 void Test3D_complex(const Box<3,float> & domain, long int k)
904 {
905  typedef Point_test<float> p;
906 
907  long int big_step = k / 30;
908  big_step = (big_step == 0)?1:big_step;
909  long int small_step = 21;
910 
911  print_test_v( "Testing 3D grid complex k<=",k);
912 
913  // 2D test
914  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
915  {
916  BOOST_TEST_CHECKPOINT( "Testing 3D complex grid k=" << k );
917 
918  // grid size
919  size_t sz[3];
920  sz[0] = k;
921  sz[1] = k;
922  sz[2] = k;
923 
924  // factor
925  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
926 
927  // Ghost
928  Ghost<3,float> g(0.01 / factor);
929 
930  // Distributed grid with id decomposition
932 
933  // check the consistency of the decomposition
934  bool val = g_dist.getDecomposition().check_consistency();
935  BOOST_REQUIRE_EQUAL(val,true);
936 
937  // Grid sm
938  grid_sm<3,void> info(sz);
939 
940  // get the domain iterator
941  size_t count = 0;
942 
943  auto dom = g_dist.getDomainIterator();
944 
945  while (dom.isNext())
946  {
947  auto key = dom.get();
948  auto key_g = g_dist.getGKey(key);
949 
950  size_t k = info.LinId(key_g);
951 
952  g_dist.template get<p::x>(key) = 1 + k;
953  g_dist.template get<p::y>(key) = 567 + k;
954  g_dist.template get<p::z>(key) = 341 + k;
955  g_dist.template get<p::s>(key) = 5670 + k;
956  g_dist.template get<p::v>(key)[0] = 921 + k;
957  g_dist.template get<p::v>(key)[1] = 5675 + k;
958  g_dist.template get<p::v>(key)[2] = 117 + k;
959  g_dist.template get<p::t>(key)[0][0] = 1921 + k;
960  g_dist.template get<p::t>(key)[0][1] = 25675 + k;
961  g_dist.template get<p::t>(key)[0][2] = 3117 + k;
962  g_dist.template get<p::t>(key)[1][0] = 4921 + k;
963  g_dist.template get<p::t>(key)[1][1] = 55675 + k;
964  g_dist.template get<p::t>(key)[1][2] = 6117 + k;
965  g_dist.template get<p::t>(key)[2][0] = 7921 + k;
966  g_dist.template get<p::t>(key)[2][1] = 85675 + k;
967  g_dist.template get<p::t>(key)[2][2] = 9117 + k;
968 
969  // Count the point
970  count++;
971 
972  ++dom;
973  }
974 
975  // Get the virtual cluster machine
976  Vcluster<> & vcl = g_dist.getVC();
977 
978  // reduce
979  vcl.sum(count);
980  vcl.execute();
981 
982  // Check
983  BOOST_REQUIRE_EQUAL(count,(size_t)k*k*k);
984 
985  bool match = true;
986 
987  auto dom2 = g_dist.getDomainIterator();
988 
989  // check that the grid store the correct information
990  while (dom2.isNext())
991  {
992  auto key = dom2.get();
993  auto key_g = g_dist.getGKey(key);
994 
995  size_t k = info.LinId(key_g);
996 
997  match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
998  match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
999  match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
1000  match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
1001  match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
1002  match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
1003  match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
1004  match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
1005  match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
1006  match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
1007  match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
1008  match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
1009  match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
1010  match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
1011  match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
1012  match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
1013 
1014  ++dom2;
1015  }
1016 
1017  BOOST_REQUIRE_EQUAL(match,true);
1018 
1019  g_dist.template ghost_get<p::x,p::y,p::z,p::s,p::v,p::t>();
1020 
1021  // check that the communication is correctly completed
1022 
1023  auto domg = g_dist.getDomainGhostIterator();
1024 
1025  // check that the grid with the ghost past store the correct information
1026  while (domg.isNext())
1027  {
1028  auto key = domg.get();
1029  auto key_g = g_dist.getGKey(key);
1030 
1031  size_t k = info.LinId(key_g);
1032 
1033  // In this case the boundary condition are non periodic
1034  if (g_dist.isInside(key_g))
1035  {
1036  match &= (g_dist.template get<p::x>(key) == 1 + k)?true:false;
1037  match &= (g_dist.template get<p::y>(key) == 567 + k)?true:false;
1038  match &= (g_dist.template get<p::z>(key) == 341 + k)?true:false;
1039  match &= (g_dist.template get<p::s>(key) == 5670 + k)?true:false;
1040 
1041  match &= (g_dist.template get<p::v>(key)[0] == 921 + k)?true:false;
1042  match &= (g_dist.template get<p::v>(key)[1] == 5675 + k)?true:false;
1043  match &= (g_dist.template get<p::v>(key)[2] == 117 + k)?true:false;
1044 
1045  match &= (g_dist.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
1046  match &= (g_dist.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
1047  match &= (g_dist.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
1048  match &= (g_dist.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
1049  match &= (g_dist.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
1050  match &= (g_dist.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
1051  match &= (g_dist.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
1052  match &= (g_dist.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
1053  match &= (g_dist.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
1054  }
1055 
1056  ++domg;
1057  }
1058 
1059  BOOST_REQUIRE_EQUAL(match,true);
1060  }
1061 }
1062 
1063 // Test duplicated topology
1064 
1065 void Test3D_dup(const Box<3,float> & domain, long int k)
1066 {
1067  long int big_step = k / 30;
1068  big_step = (big_step == 0)?1:big_step;
1069  long int small_step = 21;
1070  long int k_old = k;
1071 
1072  Vcluster<> & v_cl = create_vcluster();
1073 
1074  if ( v_cl.getProcessingUnits() > 32 )
1075  return;
1076 
1077  print_test_v( "Testing 3D duplicate topology complex k<=",k);
1078 
1079  // 3D test
1080  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1081  {
1082  BOOST_TEST_CHECKPOINT( "Testing 3D copy decomposition grid k=" << k );
1083 
1084  // grid size
1085  size_t sz[3];
1086  sz[0] = k;
1087  sz[1] = k;
1088  sz[2] = k;
1089 
1090  // factor
1091  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1092 
1093  // Ghost
1094  Ghost<3,float> g(0.01 / factor);
1095 
1097 
1098  // Distributed grid with id decomposition (It work also without the third template parameter)
1099  // Here is given to show that the 2 grid MUST have the same decomposition strategy
1101 
1102  // another grid with the same decomposition
1103  grid_dist_id<3, float, Point_test<float>, CartDecomposition<3,float>> g_dist2(g_dist1.getDecomposition(),sz,g);
1104 
1106 
1107  bool ret = g_dist2.getDecomposition().check_consistency();
1108  BOOST_REQUIRE_EQUAL(ret,true);
1109  ret = g_dist2.getDecomposition().is_equal(g_dist2.getDecomposition());
1110  BOOST_REQUIRE_EQUAL(ret,true);
1111 
1112 
1113  auto dom_g1 = g_dist1.getDomainIterator();
1114  auto dom_g2 = g_dist2.getDomainIterator();
1115 
1116  bool check = true;
1117 
1118  while (dom_g1.isNext())
1119  {
1120  auto key1 = dom_g1.get();
1121  auto key2 = dom_g2.get();
1122 
1123  check &= (key1 == key2)?true:false;
1124 
1125  ++dom_g1;
1126  ++dom_g2;
1127  }
1128 
1129  BOOST_REQUIRE_EQUAL(check,true);
1130  }
1131 
1132  k = k_old;
1133 
1134  // 3D test
1135  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1136  {
1137  BOOST_TEST_CHECKPOINT( "Testing 3D copy decomposition grid k=" << k );
1138 
1139  // grid size
1140  size_t sz[3];
1141  sz[0] = k;
1142  sz[1] = k;
1143  sz[2] = k;
1144 
1145  // factor
1146  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1147 
1148  // Ghost
1149  Ghost<3,float> g(0.01 / factor);
1150 
1151  // Distributed grid with id decomposition
1153 
1154  // another grid with the same decomposition
1156 
1157  delete g_dist1;
1158 
1159  bool ret = g_dist2->getDecomposition().check_consistency();
1160  BOOST_REQUIRE_EQUAL(ret,true);
1161 
1162  delete g_dist2;
1163  }
1164 }
1165 
1166 
1167 // Test grid periodic
1168 
1169 void Test3D_periodic(const Box<3,float> & domain, long int k)
1170 {
1171  Vcluster<> & v_cl = create_vcluster();
1172 
1173  if ( v_cl.getProcessingUnits() > 32 )
1174  return;
1175 
1176  long int big_step = k / 30;
1177  big_step = (big_step == 0)?1:big_step;
1178  long int small_step = 21;
1179 
1180  print_test_v( "Testing grid periodic k<=",k);
1181 
1182  // 3D test
1183  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1184  {
1185  BOOST_TEST_CHECKPOINT( "Testing grid periodic k<=" << k );
1186 
1187  // grid size
1188  size_t sz[3];
1189  sz[0] = k;
1190  sz[1] = k;
1191  sz[2] = k;
1192 
1193  // factor
1194  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1195 
1196  // Ghost
1197  Ghost<3,float> g(0.01 / factor);
1198 
1199  // periodicity
1200  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
1201 
1202  // Distributed grid with id decomposition
1204 
1205  // check the consistency of the decomposition
1206  bool val = g_dist.getDecomposition().check_consistency();
1207  BOOST_REQUIRE_EQUAL(val,true);
1208 
1209  // Grid sm
1210  grid_sm<3,void> info(sz);
1211 
1212  size_t count = 0;
1213 
1214  // Set to zero the full grid
1215 
1216  auto dom1 = g_dist.getDomainGhostIterator();
1217 
1218  while (dom1.isNext())
1219  {
1220  auto key = dom1.get();
1221 
1222  g_dist.template get<0>(key) = -1;
1223 
1224  ++dom1;
1225  }
1226 
1227  auto dom = g_dist.getDomainIterator();
1228 
1229  while (dom.isNext())
1230  {
1231  auto key = dom.get();
1232  auto key_g = g_dist.getGKey(key);
1233 
1234  g_dist.template get<0>(key) = info.LinId(key_g);
1235 
1236  // Count the points
1237  count++;
1238 
1239  ++dom;
1240  }
1241 
1242  // Get the virtual cluster machine
1243  Vcluster<> & vcl = g_dist.getVC();
1244 
1245  // reduce
1246  vcl.sum(count);
1247  vcl.execute();
1248 
1249  // Check
1250  BOOST_REQUIRE_EQUAL(count,(size_t)k*k*k);
1251 
1252  size_t tot = g_dist.getLocalDomainSize();
1253  // reduce
1254  vcl.sum(tot);
1255  vcl.execute();
1256 
1257  BOOST_REQUIRE_EQUAL(count,tot);
1258 
1259  // sync the ghosts
1260  g_dist.ghost_get<0>();
1261 
1262  bool match = true;
1263 
1264  // Domain + Ghost iterator
1265  auto dom_gi = g_dist.getDomainGhostIterator();
1266 
1267  size_t out_cnt = 0;
1268 
1269  while (dom_gi.isNext())
1270  {
1271  bool out_p = false;
1272 
1273  auto key = dom_gi.get();
1274  auto key_g = g_dist.getGKey(key);
1275 
1276  // Return the external boxes
1277  auto & gb = dom_gi.getGBoxes();
1278 
1279  // transform the key to be periodic
1280  for (size_t i = 0 ; i < 3 ; i++)
1281  {
1282  if (key_g.get(i) < 0)
1283  {key_g.set_d(i,key_g.get(i) + k);out_p = true;}
1284  else if (key_g.get(i) >= k)
1285  {key_g.set_d(i,key_g.get(i) - k);out_p = true;}
1286  }
1287 
1288  if (g_dist.template get<0>(key) != -1 && out_p == true)
1289  out_cnt++;
1290 
1291  // The last points can be invalid because of rounding off problems
1292  bool can_invalid = false;
1293  if (key.getKey().get(0) == 0 || key.getKey().get(1) == 0 || key.getKey().get(2) == 0)
1294  can_invalid = true;
1295  else if (key.getKey().get(0) == gb.get(key.getSub()).GDbox.getHigh(0) ||
1296  key.getKey().get(1) == gb.get(key.getSub()).GDbox.getHigh(1) ||
1297  key.getKey().get(2) == gb.get(key.getSub()).GDbox.getHigh(2))
1298  can_invalid = true;
1299 
1300  if (can_invalid == true)
1301  {
1302  if ( g_dist.template get<0>(key) != -1 && info.LinId(key_g) != g_dist.template get<0>(key) )
1303  match &= false;
1304  }
1305  else
1306  {
1307  if (info.LinId(key_g) != g_dist.template get<0>(key) )
1308  match &= false;
1309  }
1310 
1311  ++dom_gi;
1312  }
1313 
1314  BOOST_REQUIRE_EQUAL(match, true);
1315  if (k > 83)
1316  {
1317  vcl.sum(out_cnt);
1318  vcl.execute();
1319  BOOST_REQUIRE(out_cnt != 0ul);
1320  }
1321  }
1322 }
1323 
1324 
1325 
1326 // Test grid periodic
1327 
1328 void Test3D_periodic_put(const Box<3,float> & domain, long int k)
1329 {
1330  Vcluster<> & v_cl = create_vcluster();
1331 
1332  if ( v_cl.getProcessingUnits() > 32 )
1333  {return;}
1334 
1335  long int big_step = k / 30;
1336  big_step = (big_step == 0)?1:big_step;
1337  long int small_step = 21;
1338 
1339  print_test_v( "Testing grid periodic put k<=",k);
1340 
1341  // 3D test
1342  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1343  {
1344  BOOST_TEST_CHECKPOINT( "Testing grid periodick<=" << k );
1345 
1346  // grid size
1347  size_t sz[3];
1348  sz[0] = k;
1349  sz[1] = k;
1350  sz[2] = k;
1351 
1352  // Ghost
1353  Ghost<3,long int> g(1);
1354 
1355  // periodicity
1356  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
1357 
1358  // Distributed grid with id decomposition
1360 
1361  // check the consistency of the decomposition
1362  bool val = g_dist.getDecomposition().check_consistency();
1363  BOOST_REQUIRE_EQUAL(val,true);
1364 
1365  // Grid sm
1366  grid_sm<3,void> info(sz);
1367 
1368  size_t count = 0;
1369 
1370  {
1371  auto dom = g_dist.getDomainIterator();
1372 
1373  while (dom.isNext())
1374  {
1375  auto key = dom.get();
1376 
1377  g_dist.template get<0>(key) = -6.0;
1378  g_dist.template get<1>(key) = -6.0;
1379 
1380  // Count the points
1381  count++;
1382 
1383  ++dom;
1384  }
1385  }
1386 
1387  // Set to zero the full grid
1388 
1389  {
1390  auto dom = g_dist.getDomainIterator();
1391 
1392  while (dom.isNext())
1393  {
1394  auto key = dom.get();
1395 
1396  g_dist.template get<0>(key.move(0,1)) += 1.0;
1397  g_dist.template get<0>(key.move(0,-1)) += 1.0;
1398  g_dist.template get<0>(key.move(1,1)) += 1.0;
1399  g_dist.template get<0>(key.move(1,-1)) += 1.0;
1400  g_dist.template get<0>(key.move(2,1)) += 1.0;
1401  g_dist.template get<0>(key.move(2,-1)) += 1.0;
1402 
1403 
1404  g_dist.template get<1>(key.move(0,1)) += 1.0;
1405  g_dist.template get<1>(key.move(0,-1)) += 1.0;
1406  g_dist.template get<1>(key.move(1,1)) += 1.0;
1407  g_dist.template get<1>(key.move(1,-1)) += 1.0;
1408  g_dist.template get<1>(key.move(2,1)) += 1.0;
1409  g_dist.template get<1>(key.move(2,-1)) += 1.0;
1410 
1411  ++dom;
1412  }
1413  }
1414 
1415  bool correct = true;
1416 
1417  // Domain + Ghost iterator
1418  auto dom_gi = g_dist.getDomainIterator();
1419 
1420  while (dom_gi.isNext())
1421  {
1422  auto key = dom_gi.get();
1423 
1424  correct &= (g_dist.template get<0>(key) == 0);
1425 
1426  ++dom_gi;
1427  }
1428 
1429  g_dist.ghost_put<add_,0>();
1430  g_dist.ghost_put<add_,1>();
1431 
1432 
1433  if (count != 0)
1434  BOOST_REQUIRE_EQUAL(correct, false);
1435 
1436  // sync the ghosts
1437  g_dist.ghost_get<0,1>();
1438 
1439  correct = true;
1440 
1441  // Domain + Ghost iterator
1442  auto dom_gi2 = g_dist.getDomainIterator();
1443 
1444  while (dom_gi2.isNext())
1445  {
1446  auto key = dom_gi2.get();
1447 
1448  correct &= (g_dist.template get<0>(key) == 0);
1449  correct &= (g_dist.template get<1>(key) == 0);
1450 
1451  ++dom_gi2;
1452  }
1453 
1454  BOOST_REQUIRE_EQUAL(correct, true);
1455  }
1456 }
1457 
1458 void Test_grid_copy(const Box<3,float> & domain, long int k)
1459 {
1460  typedef Point_test<float> p;
1461 
1462  Vcluster<> & v_cl = create_vcluster();
1463 
1464  if ( v_cl.getProcessingUnits() > 32 )
1465  return;
1466 
1467  long int big_step = k / 30;
1468  big_step = (big_step == 0)?1:big_step;
1469  long int small_step = 21;
1470 
1471  print_test_v( "Testing grid copy k<=",k);
1472 
1473  // 3D test
1474  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1475  {
1476  BOOST_TEST_CHECKPOINT( "Testing grid periodick<=" << k );
1477 
1478  // grid size
1479  size_t sz[3];
1480  sz[0] = k;
1481  sz[1] = k;
1482  sz[2] = k;
1483 
1484  // factor
1485  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1486 
1487  // Ghost
1488  Ghost<3,float> g(0.01 / factor);
1489 
1490  // periodicity
1491  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
1492 
1493  // Distributed grid with id decomposition
1494  grid_dist_id<3,float,Point_test<float>> g_dist(sz,domain,g,pr);
1495  grid_dist_id<3,float,Point_test<float>> g_dist2(g_dist.getDecomposition(),sz,g);
1496 
1497  // Grid sm
1498  grid_sm<3,void> info(sz);
1499 
1500  // Set to zero the full grid
1501  auto dom = g_dist.getDomainIterator();
1502 
1503  while (dom.isNext())
1504  {
1505  auto key = dom.get();
1506  auto key_g = g_dist.getGKey(key);
1507 
1508  size_t k = info.LinId(key_g);
1509 
1510  g_dist.template get<p::x>(key) = 1 + k;
1511  g_dist.template get<p::y>(key) = 567 + k;
1512  g_dist.template get<p::z>(key) = 341 + k;
1513  g_dist.template get<p::s>(key) = 5670 + k;
1514  g_dist.template get<p::v>(key)[0] = 921 + k;
1515  g_dist.template get<p::v>(key)[1] = 5675 + k;
1516  g_dist.template get<p::v>(key)[2] = 117 + k;
1517  g_dist.template get<p::t>(key)[0][0] = 1921 + k;
1518  g_dist.template get<p::t>(key)[0][1] = 25675 + k;
1519  g_dist.template get<p::t>(key)[0][2] = 3117 + k;
1520  g_dist.template get<p::t>(key)[1][0] = 4921 + k;
1521  g_dist.template get<p::t>(key)[1][1] = 55675 + k;
1522  g_dist.template get<p::t>(key)[1][2] = 6117 + k;
1523  g_dist.template get<p::t>(key)[2][0] = 7921 + k;
1524  g_dist.template get<p::t>(key)[2][1] = 85675 + k;
1525  g_dist.template get<p::t>(key)[2][2] = 9117 + k;
1526 
1527  ++dom;
1528  }
1529 
1530  g_dist2.copy(g_dist);
1531 
1532  auto dom2 = g_dist2.getDomainIterator();
1533 
1534  bool match = true;
1535 
1536  // check that the grid store the correct information
1537  while (dom2.isNext())
1538  {
1539  auto key = dom2.get();
1540  auto key_g = g_dist.getGKey(key);
1541 
1542  size_t k = info.LinId(key_g);
1543 
1544  match &= (g_dist2.template get<p::x>(key) == 1 + k)?true:false;
1545  match &= (g_dist2.template get<p::y>(key) == 567 + k)?true:false;
1546  match &= (g_dist2.template get<p::z>(key) == 341 + k)?true:false;
1547  match &= (g_dist2.template get<p::s>(key) == 5670 + k)?true:false;
1548  match &= (g_dist2.template get<p::v>(key)[0] == 921 + k)?true:false;
1549  match &= (g_dist2.template get<p::v>(key)[1] == 5675 + k)?true:false;
1550  match &= (g_dist2.template get<p::v>(key)[2] == 117 + k)?true:false;
1551  match &= (g_dist2.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
1552  match &= (g_dist2.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
1553  match &= (g_dist2.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
1554  match &= (g_dist2.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
1555  match &= (g_dist2.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
1556  match &= (g_dist2.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
1557  match &= (g_dist2.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
1558  match &= (g_dist2.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
1559  match &= (g_dist2.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
1560 
1561  ++dom2;
1562  }
1563 
1564  BOOST_REQUIRE_EQUAL(match,true);
1565  }
1566 }
1567 
1568 void Test_ghost_correction(Box<3,double> & domain, long int k, long int g_)
1569 {
1570  size_t sz[3] = {(size_t)k,(size_t)k,(size_t)k};
1571  periodicity<3> bc = {{PERIODIC,PERIODIC,PERIODIC}};
1572 
1573  Ghost<3,long int> g(g_);
1574 
1576 
1577  auto itg = grid.getDomainGhostIterator();
1578 
1579  while (itg.isNext())
1580  {
1581  auto key = itg.get();
1582 
1583  grid.template get<0>(key) = 0.0;
1584 
1585  ++itg;
1586  }
1587 
1588  // Fill everything with 5
1589 
1590  auto it = grid.getDomainIterator();
1591 
1592  while (it.isNext())
1593  {
1594  auto key = it.get();
1595  auto gkey = it.getGKey(key);
1596 
1597  if (gkey.get(0) == -4 && gkey.get(1) == 20 && gkey.get(2) == -4)
1598  {
1599  grid.template get<0>(key) = 20.0;
1600  }
1601  else
1602  {
1603  grid.template get<0>(key) = 5.0;
1604  }
1605 
1606  ++it;
1607  }
1608 
1609  grid.ghost_get<0>();
1610  auto it2 = grid.getDomainGhostIterator();
1611 
1612  bool is_inside = true;
1613 
1614  while (it2.isNext())
1615  {
1616  auto key = it2.get();
1617  auto gkey = it2.getGKey(key);
1618 
1619  if (grid.template get<0>(key) == 5.0)
1620  {
1621  // Here we check that the point is with in one stencil point
1622  // from one sub-domain
1623 
1624  bool is_inside_point = false;
1625  for (size_t i = 0 ; i < grid.getN_loc_grid() ; i++)
1626  {
1627  Box<3,long int> bx = grid.getLocalGridsInfo().get(i).Dbox;
1628  bx += grid.getLocalGridsInfo().get(i).origin;
1629 
1630  bx.enlarge(g);
1631 
1632  if (bx.isInside(gkey.toPoint()) == true)
1633  {
1634  is_inside_point |= true;
1635  }
1636  }
1637 
1638  is_inside &= is_inside_point;
1639  }
1640 
1641  ++it2;
1642  }
1643 
1644  BOOST_REQUIRE_EQUAL(is_inside,true);
1645 }
1646 
1647 void Test3D_copy(const Box<3,float> & domain, long int k)
1648 {
1649  typedef Point_test<float> p;
1650 
1651  Vcluster<> & v_cl = create_vcluster();
1652 
1653  if ( v_cl.getProcessingUnits() > 32 )
1654  return;
1655 
1656  long int big_step = k / 30;
1657  big_step = (big_step == 0)?1:big_step;
1658  long int small_step = 21;
1659 
1660  print_test( "Testing grid copy k<=",k);
1661 
1662  // 3D test
1663  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
1664  {
1665  BOOST_TEST_CHECKPOINT( "Testing grid periodick<=" << k );
1666 
1667  // grid size
1668  size_t sz[3];
1669  sz[0] = k;
1670  sz[1] = k;
1671  sz[2] = k;
1672 
1673  // factor
1674  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
1675 
1676  // Ghost
1677  Ghost<3,float> g(0.01 / factor);
1678 
1679  // periodicity
1680  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
1681 
1682  // Distributed grid with id decomposition
1683  grid_dist_id<3,float,Point_test<float>> g_dist(sz,domain,g,pr);
1684 
1685  // Grid sm
1686  grid_sm<3,void> info(sz);
1687 
1688  // Set to zero the full grid
1689  auto dom = g_dist.getDomainIterator();
1690 
1691  while (dom.isNext())
1692  {
1693  auto key = dom.get();
1694  auto key_g = g_dist.getGKey(key);
1695 
1696  size_t k = info.LinId(key_g);
1697 
1698  g_dist.template get<p::x>(key) = 1 + k;
1699  g_dist.template get<p::y>(key) = 567 + k;
1700  g_dist.template get<p::z>(key) = 341 + k;
1701  g_dist.template get<p::s>(key) = 5670 + k;
1702  g_dist.template get<p::v>(key)[0] = 921 + k;
1703  g_dist.template get<p::v>(key)[1] = 5675 + k;
1704  g_dist.template get<p::v>(key)[2] = 117 + k;
1705  g_dist.template get<p::t>(key)[0][0] = 1921 + k;
1706  g_dist.template get<p::t>(key)[0][1] = 25675 + k;
1707  g_dist.template get<p::t>(key)[0][2] = 3117 + k;
1708  g_dist.template get<p::t>(key)[1][0] = 4921 + k;
1709  g_dist.template get<p::t>(key)[1][1] = 55675 + k;
1710  g_dist.template get<p::t>(key)[1][2] = 6117 + k;
1711  g_dist.template get<p::t>(key)[2][0] = 7921 + k;
1712  g_dist.template get<p::t>(key)[2][1] = 85675 + k;
1713  g_dist.template get<p::t>(key)[2][2] = 9117 + k;
1714 
1715  ++dom;
1716  }
1717 
1718  grid_dist_id<3,float,Point_test<float>> g_dist2 = g_dist;
1719  g_dist2.template ghost_get<0>();
1720 
1721  auto dom2 = g_dist2.getDomainIterator();
1722 
1723  bool match = true;
1724 
1725  // check that the grid store the correct information
1726  while (dom2.isNext())
1727  {
1728  auto key = dom2.get();
1729  auto key_g = g_dist.getGKey(key);
1730 
1731  size_t k = info.LinId(key_g);
1732 
1733  match &= (g_dist2.template get<p::x>(key) == 1 + k)?true:false;
1734  match &= (g_dist2.template get<p::y>(key) == 567 + k)?true:false;
1735  match &= (g_dist2.template get<p::z>(key) == 341 + k)?true:false;
1736  match &= (g_dist2.template get<p::s>(key) == 5670 + k)?true:false;
1737  match &= (g_dist2.template get<p::v>(key)[0] == 921 + k)?true:false;
1738  match &= (g_dist2.template get<p::v>(key)[1] == 5675 + k)?true:false;
1739  match &= (g_dist2.template get<p::v>(key)[2] == 117 + k)?true:false;
1740  match &= (g_dist2.template get<p::t>(key)[0][0] == 1921 + k)?true:false;
1741  match &= (g_dist2.template get<p::t>(key)[0][1] == 25675 + k)?true:false;
1742  match &= (g_dist2.template get<p::t>(key)[0][2] == 3117 + k)?true:false;
1743  match &= (g_dist2.template get<p::t>(key)[1][0] == 4921 + k)?true:false;
1744  match &= (g_dist2.template get<p::t>(key)[1][1] == 55675 + k)?true:false;
1745  match &= (g_dist2.template get<p::t>(key)[1][2] == 6117 + k)?true:false;
1746  match &= (g_dist2.template get<p::t>(key)[2][0] == 7921 + k)?true:false;
1747  match &= (g_dist2.template get<p::t>(key)[2][1] == 85675 + k)?true:false;
1748  match &= (g_dist2.template get<p::t>(key)[2][2] == 9117 + k)?true:false;
1749 
1750  ++dom2;
1751  }
1752 
1753  BOOST_REQUIRE_EQUAL(match,true);
1754  }
1755 }
1756 
1757 
1758 BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use_2D)
1759 {
1760  // Domain
1761  Box<2,float> domain({0.0,0.0},{1.0,1.0});
1762 
1763 #ifdef TEST_COVERAGE_MODE
1764  long int k = 256*256*create_vcluster().getProcessingUnits();
1765 #else
1766  long int k = 1024*1024*create_vcluster().getProcessingUnits();
1767 #endif
1768  k = std::pow(k, 1/2.);
1769 
1770  Test2D(domain,k);
1771  Test2D_complex(domain,k);
1772 }
1773 
1774 BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_test_use_3D)
1775 {
1776  // Domain
1777  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1778 
1779  size_t k = 128*128*128*create_vcluster().getProcessingUnits();
1780  k = std::pow(k, 1/3.);
1781  Test3D(domain3,k);
1782  Test3D_complex(domain3,k);
1783 }
1784 
1785 BOOST_AUTO_TEST_CASE( grid_dist_id_dup)
1786 {
1787  // Domain
1788  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1789 
1790  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1791  k = std::pow(k, 1/3.);
1792  Test3D_dup(domain3,k);
1793 }
1794 
1795 BOOST_AUTO_TEST_CASE( grid_dist_id_sub)
1796 {
1797  // Domain
1798  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1799 
1800  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1801  k = std::pow(k, 1/3.);
1802  Test3D_sub(domain3,k);
1803 }
1804 
1805 
1806 BOOST_AUTO_TEST_CASE( grid_dist_id_with_grid_unit_ghost )
1807 {
1808  // Domain
1809  Box<2,float> domain({0.0,0.0},{1.0,1.0});
1810 
1811  long int k = 1024*1024*create_vcluster().getProcessingUnits();
1812  k = std::pow(k, 1/2.);
1813 
1814  // Domain
1815  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1816 
1817  k = 128*128*128*create_vcluster().getProcessingUnits();
1818  k = std::pow(k, 1/3.);
1819  Test3D_gg(domain3,k,1);
1820 }
1821 
1822 
1823 BOOST_AUTO_TEST_CASE( grid_dist_id_domain_test_use)
1824 {
1825  // Domain
1826  Box<3,float> domain3({-0.3,-0.3,-0.3},{1.1,1.1,1.1});
1827 
1828  periodicity<3> np({{NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}});
1829  periodicity<3> p({{PERIODIC,PERIODIC,PERIODIC}});
1830 
1831  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1832  k = std::pow(k, 1/3.);
1833  Test3D_domain(domain3,k,np);
1834 
1835  auto & v_cl = create_vcluster();
1836  if (v_cl.getProcessingUnits() > 32)
1837  return;
1838 
1839  // We use a 128x128x128 and we move tha domain
1840 
1841  for (size_t i = 0 ; i < 10 ; i++)
1842  {
1843  Box<3,float> exp({0.0,0.0,0.0},{1.3,1.3,1.3});
1844  domain3.enlarge(exp);
1845  Test3D_domain(domain3,128,p);
1846  }
1847 }
1848 
1849 BOOST_AUTO_TEST_CASE( grid_dist_id_extended )
1850 {
1851  // Domain
1852  Box<3,float> domain3({0.1,0.1,0.1},{1.1,1.1,1.1});
1853 
1854  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1855  k = std::pow(k, 1/3.);
1856 
1857  Test3D_extended_grid(domain3,k);
1858 }
1859 
1860 BOOST_AUTO_TEST_CASE( grid_dist_id_periodic )
1861 {
1862  // Domain
1863  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1864 
1865  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1866  k = std::pow(k, 1/3.);
1867 
1868  Test3D_periodic(domain3,k);
1869 }
1870 
1871 BOOST_AUTO_TEST_CASE( grid_dist_id_unbound_ghost )
1872 {
1873  // Domain
1874  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1875 
1876  long int k = 28*28*28*create_vcluster().getProcessingUnits();
1877  k = std::pow(k, 1/3.);
1878 
1879  Test3D_unb_ghost(domain3,k);
1880 }
1881 
1882 BOOST_AUTO_TEST_CASE( grid_dist_id_unbound_ghost_periodic )
1883 {
1884  // Domain
1885  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1886 
1887  long int k = 25*25*25*create_vcluster().getProcessingUnits();
1888  k = std::pow(k, 1/3.);
1889 
1890  Test3D_unb_ghost_periodic(domain3,k);
1891 }
1892 
1893 BOOST_AUTO_TEST_CASE( grid_dist_id_copy )
1894 {
1895  // Domain
1896  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1897 
1898  long int k = 32*32*32*create_vcluster().getProcessingUnits();
1899  k = std::pow(k, 1/3.);
1900 
1901  Test_grid_copy(domain3,k);
1902 }
1903 
1904 BOOST_AUTO_TEST_CASE( grid_1d_test )
1905 {
1906  // Domain
1907  Box<1,float> domain1({-1.0},{1.0});
1908 
1909  long int k = 32*32*32*create_vcluster().getProcessingUnits();
1910 
1911  Test1D(domain1,k);
1912 }
1913 
1914 BOOST_AUTO_TEST_CASE( grid_dist_id_periodic_put_test )
1915 {
1916  // Domain
1917  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
1918 
1919  long int k = 128*128*128*create_vcluster().getProcessingUnits();
1920  k = std::pow(k, 1/3.);
1921 
1922  Test3D_periodic_put(domain3,k);
1923 }
1924 
1925 BOOST_AUTO_TEST_CASE ( grid_ghost_correction )
1926 {
1927  Box<3,double> domain({0.0,0.0,0.0},{2.5,2.5,2.5});
1928 
1929  long int k = 128;
1930 
1931  Test_ghost_correction(domain,k,1);
1932  Test_ghost_correction(domain,k,2);
1933  Test_ghost_correction(domain,k,3);
1934  Test_ghost_correction(domain,k,4);
1935 
1936  k = 64;
1937 
1938  Test_ghost_correction(domain,k,1);
1939  Test_ghost_correction(domain,k,2);
1940  Test_ghost_correction(domain,k,3);
1941  Test_ghost_correction(domain,k,4);
1942 
1943  k = 32;
1944 
1945  Test_ghost_correction(domain,k,1);
1946  Test_ghost_correction(domain,k,2);
1947  Test_ghost_correction(domain,k,3);
1948  Test_ghost_correction(domain,k,4);
1949 
1950  k = 16;
1951 
1952  Test_ghost_correction(domain,k,1);
1953  Test_ghost_correction(domain,k,2);
1954  Test_ghost_correction(domain,k,3);
1955  Test_ghost_correction(domain,k,4);
1956 }
1957 
1958 BOOST_AUTO_TEST_CASE ( grid_basic_functions )
1959 {
1960  auto & v_cl = create_vcluster();
1961 
1962  if (v_cl.getProcessingUnits() != 1)
1963  {return;}
1964 
1965  size_t sz[2] = {(size_t)8,(size_t)8};
1966  periodicity<2> bc = {{PERIODIC,PERIODIC}};
1967 
1968  Ghost<2,long int> g(1);
1969  Box<2,double> domain({-1.0,-1.0},{1.0,1.0});
1970 
1972 
1973  BOOST_REQUIRE_EQUAL(grid.getOffset(0)[0],-1.25);
1974  BOOST_REQUIRE_EQUAL(grid.getOffset(0)[1],-1.25);
1975 }
1976 
1977 BOOST_AUTO_TEST_CASE ( grid_overflow_round_off_error )
1978 {
1979  size_t numGridPoint = 100;
1980  const double domainSize = 20851.7;
1981  double domainLength = sqrt(domainSize);
1982 
1983  Box<2,double> domain({0.0,0.0},{domainLength,domainLength});
1984 
1985  size_t sz[2] = {numGridPoint,numGridPoint};
1986 
1987  periodicity<2> bc = {{PERIODIC,PERIODIC}};
1988 
1989  Ghost<2,double> g(3.0*(domain.getHigh(0) - domain.getLow(0))/numGridPoint + 0.001);
1990 
1992 
1993  auto & gs = grid.getGridInfo();
1994 
1995  auto it = grid.getDomainIterator();
1996 
1997  while (it.isNext())
1998  {
1999  auto p = it.get();
2000  auto gp = it.getGKey(p);
2001 
2002  grid.get<0>(p) = gs.LinId(gp);
2003 
2004  ++it;
2005  }
2006 
2007  grid.ghost_get<0>();
2008 
2009  // Now we check
2010 
2011  auto it2 = grid.getDomainIterator();
2012 
2013  bool match = true;
2014 
2015  while (it2.isNext())
2016  {
2017  auto p = it2.get();
2018  auto gp = it.getGKey(p);
2019 
2020  if (gs.LinId(gp) != grid.get<0>(p))
2021  {match = false;}
2022 
2023  // look around
2024 
2025  auto px = p.move(0,1);
2026  auto gpx = it.getGKey(px);
2027  auto mx = p.move(0,-1);
2028  auto gmx = it.getGKey(mx);
2029 
2030  auto py = p.move(1,1);
2031  auto gpy = it.getGKey(py);
2032  auto my = p.move(1,-1);
2033  auto gmy = it.getGKey(my);
2034 
2035  gpx.set_d(0,gpx.get(0) % gs.size(0));
2036  gpx.set_d(1,gpx.get(1) % gs.size(1));
2037 
2038  if (grid.template get<0>(px) != gs.LinId(gpx))
2039  {match = false;}
2040 
2041  gmx.set_d(0,(gmx.get(0) + gs.size(0)) % gs.size(0));
2042  gmx.set_d(1,(gmx.get(1) + gs.size(1)) % gs.size(1));
2043 
2044  if (grid.template get<0>(mx) != gs.LinId(gmx))
2045  {match = false;}
2046 
2047  gpy.set_d(0,gpy.get(0) % gs.size(0));
2048  gpy.set_d(1,gpy.get(1) % gs.size(1));
2049 
2050  if (grid.template get<0>(py) != gs.LinId(gpy))
2051  {match = false;}
2052 
2053  gmy.set_d(0,(gmy.get(0) + gs.size(0)) % gs.size(0));
2054  gmy.set_d(1,(gmy.get(1) + gs.size(1)) % gs.size(1));
2055 
2056  if (grid.template get<0>(my) != gs.LinId(gmy))
2057  {match = false;}
2058 
2059  ++it2;
2060  }
2061 
2062  BOOST_REQUIRE_EQUAL(match,true);
2063 }
2064 
2065 BOOST_AUTO_TEST_CASE( grid_dist_id_copy_test )
2066 {
2067  // Domain
2068  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
2069 
2070  long int k = 128*128*128*create_vcluster().getProcessingUnits();
2071  k = std::pow(k, 1/3.);
2072 
2073  Test3D_copy(domain3,k);
2074 }
2075 
2076 
2077 template<typename grid_amr>
2078 void Test3D_ghost_put(grid_amr & g_dist_amr, long int k)
2079 {
2080  // check the consistency of the decomposition
2081  bool val = g_dist_amr.getDecomposition().check_consistency();
2082  BOOST_REQUIRE_EQUAL(val,true);
2083 
2084  size_t sz[3] = {(size_t)k,(size_t)k,(size_t)k};
2085 
2086  // Grid sm
2087  grid_sm<3,void> info(sz);
2088 
2089  size_t count = 0;
2090 
2091  auto dom = g_dist_amr.getGridIterator();
2092 
2093  while (dom.isNext())
2094  {
2095  auto key = dom.get_dist();
2096 
2097  g_dist_amr.template insert<0>(key) = -6.0;
2098 
2099  // Count the points
2100  count++;
2101 
2102  ++dom;
2103  }
2104 
2105  // Set to zero the full grid
2106 
2107  {
2108  auto dom = g_dist_amr.getDomainIterator();
2109 
2110  while (dom.isNext())
2111  {
2112  auto key = dom.get();
2113 
2114  g_dist_amr.template insert<0>(key.move(0,1)) += 1.0;
2115  g_dist_amr.template insert<0>(key.move(0,-1)) += 1.0;
2116  g_dist_amr.template insert<0>(key.move(1,1)) += 1.0;
2117  g_dist_amr.template insert<0>(key.move(1,-1)) += 1.0;
2118  g_dist_amr.template insert<0>(key.move(2,1)) += 1.0;
2119  g_dist_amr.template insert<0>(key.move(2,-1)) += 1.0;
2120 
2121  ++dom;
2122  }
2123  }
2124 
2125  bool correct = true;
2126 
2127  // Domain + Ghost iterator
2128  auto dom_gi = g_dist_amr.getDomainIterator();
2129 
2130  while (dom_gi.isNext())
2131  {
2132  auto key = dom_gi.get();
2133 
2134  correct &= (g_dist_amr.template get<0>(key) == 0);
2135 
2136  ++dom_gi;
2137  }
2138 
2139  g_dist_amr.template ghost_put<add_,0>();
2140 
2141  if (count != 0)
2142  {BOOST_REQUIRE_EQUAL(correct, false);}
2143 
2144  // sync the ghosts
2145  g_dist_amr.template ghost_get<0>();
2146 
2147  correct = true;
2148 
2149  // Domain + Ghost iterator
2150  auto dom_gi2 = g_dist_amr.getDomainIterator();
2151 
2152  while (dom_gi2.isNext())
2153  {
2154  auto key = dom_gi2.get();
2155 
2156  correct &= (g_dist_amr.template get<0>(key) == 0);
2157 
2158  ++dom_gi2;
2159  }
2160 
2161  BOOST_REQUIRE_EQUAL(correct, true);
2162 }
2163 
2164 BOOST_AUTO_TEST_CASE( grid_dist_domain_ghost_put_check )
2165 {
2166  // Test grid periodic
2167 
2168  Box<3,float> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
2169 
2170  Vcluster<> & v_cl = create_vcluster();
2171 
2172  if ( v_cl.getProcessingUnits() > 32 )
2173  {return;}
2174 
2175  long int k = 13;
2176 
2177  BOOST_TEST_CHECKPOINT( "Testing grid periodic k<=" << k );
2178 
2179  // grid size
2180  size_t sz[3];
2181  sz[0] = k;
2182  sz[1] = k;
2183  sz[2] = k;
2184 
2185  // Ghost
2186  Ghost<3,long int> g(1);
2187 
2188  // periodicity
2189  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
2190 
2191  // Distributed grid with id decomposition
2192  grid_dist_id<3, float, aggregate<long int>> g_dist(sz,domain,g,pr);
2193 
2194  Test3D_ghost_put(g_dist,k);
2195 
2196  // Distributed grid with id decomposition
2197  sgrid_dist_id<3, float, aggregate<long int>> sg_dist(sz,domain,g,pr);
2198 
2199  Test3D_ghost_put(sg_dist,k);
2200 }
2201 
2202 
2203 template<typename grid_amr>
2204 void TestXD_ghost_put_create(grid_amr & g_dist_amr, long int k)
2205 {
2206  // check the consistency of the decomposition
2207  bool val = g_dist_amr.getDecomposition().check_consistency();
2208  BOOST_REQUIRE_EQUAL(val,true);
2209 
2210  size_t count = 0;
2211 
2212  auto dom = g_dist_amr.getGridIterator();
2213 
2214  while (dom.isNext())
2215  {
2216  auto key = dom.get_dist();
2217 
2218  g_dist_amr.template insert<1>(key) = 1;
2219 
2220  // Count the points
2221  count++;
2222 
2223  ++dom;
2224  }
2225 
2226  // Fill the ghost
2227  g_dist_amr.template ghost_get<1>();
2228 
2229  // Now we count the ghost point
2230 
2231  size_t g_point = 0;
2232 
2233  auto itg = g_dist_amr.getDomainGhostIterator();
2234 
2235  while (itg.isNext())
2236  {
2237  g_point++;
2238 
2239  ++itg;
2240  }
2241 
2242  {
2243  auto it = g_dist_amr.getDomainIterator();
2244 
2245  while (it.isNext())
2246  {
2247  auto p = it.get();
2248 
2249  g_dist_amr.remove_no_flush(p);
2250  g_point--;
2251 
2252  ++it;
2253  }
2254 
2255  g_dist_amr.flush_remove();
2256  }
2257 
2258  // A domain iterator should not produce points
2259 
2260  {
2261 
2262  auto it = g_dist_amr.getDomainIterator();
2263 
2264  size_t cnt = 0;
2265  while (it.isNext())
2266  {
2267  cnt++;
2268 
2269  ++it;
2270  }
2271 
2272  BOOST_REQUIRE_EQUAL(cnt,0ul);
2273  }
2274 
2275  g_dist_amr.template ghost_put<add_,1>();
2276 
2277  {
2278  auto it = g_dist_amr.getDomainIterator();
2279 
2280  bool check = true;
2281 
2282  size_t cnt = 0;
2283  while (it.isNext())
2284  {
2285  auto p = it.get();
2286 
2287  cnt += g_dist_amr.template get<1>(p);
2288 
2289  check &= (g_dist_amr.template get<1>(p) >= 1);
2290 
2291  ++it;
2292  }
2293 
2294  // Sum all the points
2295  auto & v_cl = create_vcluster();
2296 
2297  v_cl.sum(g_point);
2298  v_cl.sum(cnt);
2299  v_cl.execute();
2300 
2301 
2302  BOOST_REQUIRE_EQUAL(g_point,cnt);
2303  BOOST_REQUIRE_EQUAL(check,true);
2304  }
2305 
2306  // We finally remove all domain points
2307 
2308  {
2309  auto it = g_dist_amr.getDomainIterator();
2310 
2311  while (it.isNext())
2312  {
2313  auto p = it.get();
2314 
2315  g_dist_amr.remove_no_flush(p);
2316 
2317  ++it;
2318  }
2319 
2320  g_dist_amr.flush_remove();
2321 
2322  size_t cnt = 0;
2323  auto it2 = g_dist_amr.getDomainGhostIterator();
2324 
2325  while (it2.isNext())
2326  {
2327 
2328  cnt++;
2329 
2330  ++it2;
2331  }
2332 
2333  BOOST_REQUIRE(cnt != 0);
2334 
2335  g_dist_amr.template ghost_get<1>();
2336 
2337  cnt = 0;
2338  auto it3 = g_dist_amr.getDomainGhostIterator();
2339 
2340  while (it3.isNext())
2341  {
2342  cnt++;
2343 
2344  ++it3;
2345  }
2346 
2347  BOOST_REQUIRE_EQUAL(cnt,0ul);
2348 
2349  }
2350 }
2351 
2352 BOOST_AUTO_TEST_CASE( grid_dist_domain_ghost_2D_put_create_check )
2353 {
2354  // Test grid periodic
2355 
2356  Box<2,float> domain({0.0,0.0},{1.0,1.0});
2357 
2358  Vcluster<> & v_cl = create_vcluster();
2359 
2360  if ( v_cl.getProcessingUnits() > 32 )
2361  {return;}
2362 
2363  long int k = 13;
2364 
2365  BOOST_TEST_CHECKPOINT( "Testing grid periodic k<=" << k );
2366 
2367  // grid size
2368  size_t sz[2];
2369  sz[0] = k;
2370  sz[1] = k;
2371 
2372  // Ghost
2373  Ghost<2,long int> g(1);
2374 
2375  // periodicity
2376  periodicity<2> pr = {{PERIODIC,PERIODIC}};
2377 
2378  // Distributed grid with id decomposition
2379  sgrid_dist_id<2, float, aggregate<long int, int>> sg_dist(sz,domain,g,pr);
2380 
2381  TestXD_ghost_put_create(sg_dist,k);
2382 
2383  k = 7;
2384  sz[0] = k;
2385  sz[1] = k;
2386 
2387  // Distributed grid with id decomposition
2388  sgrid_dist_id<2, float, aggregate<long int, int>> sg_dist2(sz,domain,g,pr);
2389 
2390  TestXD_ghost_put_create(sg_dist2,k);
2391 
2392  k = 23;
2393  sz[0] = k;
2394  sz[1] = k;
2395 
2396  // Distributed grid with id decomposition
2397  sgrid_dist_id<2, float, aggregate<long int, int>> sg_dist3(sz,domain,g,pr);
2398 
2399  TestXD_ghost_put_create(sg_dist3,k);
2400 }
2401 
2402 BOOST_AUTO_TEST_CASE( grid_dist_domain_ghost_3D_put_create_check )
2403 {
2404  // Test grid periodic
2405 
2406  Box<3,float> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
2407 
2408  Vcluster<> & v_cl = create_vcluster();
2409 
2410  if ( v_cl.getProcessingUnits() > 32 )
2411  {return;}
2412 
2413  long int k = 13;
2414 
2415  BOOST_TEST_CHECKPOINT( "Testing grid periodic k<=" << k );
2416 
2417  // grid size
2418  size_t sz[3];
2419  sz[0] = k;
2420  sz[1] = k;
2421  sz[2] = k;
2422 
2423  // Ghost
2424  Ghost<3,long int> g(1);
2425 
2426  // periodicity
2427  periodicity<3> pr = {{PERIODIC,PERIODIC,PERIODIC}};
2428 
2429  // Distributed grid with id decomposition
2430  sgrid_dist_id<3, float, aggregate<long int, int>> sg_dist(sz,domain,g,pr);
2431 
2432  TestXD_ghost_put_create(sg_dist,k);
2433 
2434  k = 7;
2435  sz[0] = k;
2436  sz[1] = k;
2437  sz[2] = k;
2438 
2439  // Distributed grid with id decomposition
2440  sgrid_dist_id<3, float, aggregate<long int, int>> sg_dist2(sz,domain,g,pr);
2441 
2442  TestXD_ghost_put_create(sg_dist2,k);
2443 
2444  k = 23;
2445  sz[0] = k;
2446  sz[1] = k;
2447  sz[2] = k;
2448 
2449  // Distributed grid with id decomposition
2450  sgrid_dist_id<3, float, aggregate<long int, int>> sg_dist3(sz,domain,g,pr);
2451 
2452  TestXD_ghost_put_create(sg_dist3,k);
2453 }
2454 
2455 
2456 BOOST_AUTO_TEST_CASE( grid_dist_ghost_zero_size )
2457 {
2458  // Test grid periodic
2459 
2460  Box<3,double> domain({0,0,0},{365.376,365.376,102});
2461 
2462  Vcluster<> & v_cl = create_vcluster();
2463 
2464  if ( v_cl.getProcessingUnits() > 32 )
2465  {return;}
2466 
2467  BOOST_TEST_CHECKPOINT( "Testing grid zero ghost");
2468 
2469  // grid size
2470  size_t sz[3];
2471  sz[0] = 53;
2472  sz[1] = 53;
2473  sz[2] = 10;
2474 
2475  // Ghost
2476  Ghost<3,long int> g(0);
2477 
2478  // periodicity
2479  periodicity<3> pr = {{NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}};
2480 
2481  // Distributed grid with id decomposition
2482  grid_dist_id<3, double, aggregate<long int, int>> g_dist(sz,domain,g,pr);
2483 
2484  auto it = g_dist.getDomainIterator();
2485 
2486  size_t count = 0;
2487 
2488  while (it.isNext())
2489  {
2490  auto k = it.get();
2491 
2492  ++count;
2493 
2494  ++it;
2495  }
2496 
2497  v_cl.sum(count);
2498  v_cl.execute();
2499 
2500  BOOST_REQUIRE_EQUAL(count,53*53*10);
2501 }
2502 
2503 
2504 BOOST_AUTO_TEST_CASE(grid_dist_id_smb_write_out_1_proc)
2505 {
2506  // Test grid periodic
2507  {
2508  Box<2,float> domain({-1.0,-1.0,-1.0},{1.0,1.0,1.0});
2509 
2510  Vcluster<> & v_cl = create_vcluster();
2511 
2512  if ( v_cl.getProcessingUnits() > 1 )
2513  {return;}
2514 
2515  // grid size
2516  size_t sz[2];
2517  sz[0] = 16;
2518  sz[1] = 16;
2519 
2520  // Ghost
2521  Ghost<2,long int> g(0);
2522 
2523  // periodicity
2524  periodicity<2> pr = {{NON_PERIODIC,NON_PERIODIC}};
2525 
2526  typedef grid_cpu<2, aggregate<int>, grid_smb<2,4> > devg;
2527 
2528  // Distributed grid with id decomposition
2529  grid_dist_id_devg<2, float, aggregate<int>,devg> g_smb(sz,domain,g,pr);
2530 
2531  auto it = g_smb.getDomainIterator();
2532 
2533  size_t count = 0;
2534 
2535  unsigned char * base = (unsigned char *)g_smb.get_loc_grid(0).getPointer<0>();
2536 
2537  while (it.isNext())
2538  {
2539  auto k = it.get();
2540 
2541  g_smb.template getProp<0>(k) = (unsigned char *)&g_smb.template getProp<0>(k) - base;
2542 
2543  ++count;
2544 
2545  ++it;
2546  }
2547 
2548  v_cl.sum(count);
2549  v_cl.execute();
2550 
2551  BOOST_REQUIRE_EQUAL(count,16*16);
2552 
2553  g_smb.write("g_smb_out");
2554  }
2555 }
2556 
2557 BOOST_AUTO_TEST_CASE(grid_dist_id_zmb_write_out_1_proc)
2558 {
2559  {
2560  // Test grid periodic
2561 
2562  Box<2,float> domain({-1.0,-1.0,-1.0},{1.0,1.0,1.0});
2563 
2564  Vcluster<> & v_cl = create_vcluster();
2565 
2566  if ( v_cl.getProcessingUnits() > 1 )
2567  {return;}
2568 
2569  // grid size
2570  size_t sz[2];
2571  sz[0] = 16;
2572  sz[1] = 16;
2573 
2574  // Ghost
2575  Ghost<2,long int> g(0);
2576 
2577  // periodicity
2578  periodicity<2> pr = {{NON_PERIODIC,NON_PERIODIC}};
2579 
2581 
2582  // Distributed grid with id decomposition
2583  grid_dist_id_devg<2, float, aggregate<int>,devg> g_smb(sz,domain,g,pr);
2584 
2585  auto it = g_smb.getDomainIterator();
2586 
2587  size_t count = 0;
2588 
2589  unsigned char * base = (unsigned char *)g_smb.get_loc_grid(0).getPointer<0>();
2590 
2591  while (it.isNext())
2592  {
2593  auto k = it.get();
2594 
2595  g_smb.template getProp<0>(k) = (unsigned char *)&g_smb.template getProp<0>(k) - base;
2596 
2597  ++count;
2598 
2599  ++it;
2600  }
2601 
2602  v_cl.sum(count);
2603  v_cl.execute();
2604 
2605  BOOST_REQUIRE_EQUAL(count,16*16);
2606 
2607  g_smb.write("g_zmb_out");
2608  }
2609 
2610  {
2611  Box<2,float> domain({-1.0,-1.0,-1.0},{1.0,1.0,1.0});
2612 
2613  Vcluster<> & v_cl = create_vcluster();
2614 
2615  if ( v_cl.getProcessingUnits() > 1 )
2616  {return;}
2617 
2618  // grid size
2619  size_t sz[2];
2620  sz[0] = 16;
2621  sz[1] = 16;
2622 
2623  // Ghost
2624  Ghost<2,long int> g(0);
2625 
2626  // periodicity
2627  periodicity<2> pr = {{NON_PERIODIC,NON_PERIODIC}};
2628 
2630 
2631  // Distributed grid with id decomposition
2632  grid_dist_id_devg<2, float, aggregate<int>,devg> g_smb(sz,domain,g,pr);
2633 
2634  auto it = g_smb.getDomainIterator();
2635 
2636  size_t count = 0;
2637 
2638  unsigned char * base = (unsigned char *)g_smb.get_loc_grid(0).getPointer<0>();
2639 
2640  while (it.isNext())
2641  {
2642  auto k = it.get();
2643 
2644  g_smb.template getProp<0>(k) = (unsigned char *)&g_smb.template getProp<0>(k) - base;
2645 
2646  ++count;
2647 
2648  ++it;
2649  }
2650 
2651  v_cl.sum(count);
2652  v_cl.execute();
2653 
2654  BOOST_REQUIRE_EQUAL(count,16*16);
2655 
2656  g_smb.write("g_zm_out");
2657  }
2658 
2659  {
2660  Box<2,float> domain({-1.0,-1.0,-1.0},{1.0,1.0,1.0});
2661 
2662  Vcluster<> & v_cl = create_vcluster();
2663 
2664  if ( v_cl.getProcessingUnits() > 1 )
2665  {return;}
2666 
2667  // grid size
2668  size_t sz[2];
2669  sz[0] = 16;
2670  sz[1] = 16;
2671 
2672  // Ghost
2673  Ghost<2,long int> g(0);
2674 
2675  // periodicity
2676  periodicity<2> pr = {{NON_PERIODIC,NON_PERIODIC}};
2677 
2678  typedef grid_base<2, aggregate<int>> devg;
2679 
2680  // Distributed grid with id decomposition
2681  grid_dist_id_devg<2, float, aggregate<int>,devg> g_smb(sz,domain,g,pr);
2682 
2683  auto it = g_smb.getDomainIterator();
2684 
2685  size_t count = 0;
2686 
2687  unsigned char * base = (unsigned char *)g_smb.get_loc_grid(0).getPointer<0>();
2688 
2689  while (it.isNext())
2690  {
2691  auto k = it.get();
2692 
2693  g_smb.template getProp<0>(k) = (unsigned char *)&g_smb.template getProp<0>(k) - base;
2694 
2695  ++count;
2696 
2697  ++it;
2698  }
2699 
2700  v_cl.sum(count);
2701  v_cl.execute();
2702 
2703  BOOST_REQUIRE_EQUAL(count,16*16);
2704 
2705  g_smb.write("g_sm_out");
2706  }
2707 }
2708 
2709 BOOST_AUTO_TEST_CASE( grid_dist_copy_construct )
2710 {
2711  // Test grid periodic
2712 
2713  Box<3,float> domain({-1.0,-1.0,-1.0},{1.0,1.0,1.0});
2714 
2715  Vcluster<> & v_cl = create_vcluster();
2716 
2717  if ( v_cl.getProcessingUnits() > 32 )
2718  {return;}
2719 
2720  BOOST_TEST_CHECKPOINT( "Testing grid zero ghost");
2721 
2722  // grid size
2723  size_t sz[3];
2724  sz[0] = 32;
2725  sz[1] = 32;
2726  sz[2] = 32;
2727 
2728  // Ghost
2729  Ghost<3,long int> g(1);
2730 
2731  // periodicity
2732  periodicity<3> pr = {{NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}};
2733 
2734  // Distributed grid with id decomposition
2735  grid_dist_id<3, float, aggregate<long int, int>> g_dist(sz,domain,g,pr);
2736 
2737 
2738  auto & gs = g_dist.getGridInfoVoid();
2739  auto it = g_dist.getDomainIterator();
2740 
2741  size_t count = 0;
2742 
2743  while (it.isNext())
2744  {
2745  auto k = it.get();
2746  auto gkey = it.getGKey(k);
2747 
2748  g_dist.get<0>(k) = gs.LinId(gkey);
2749 
2750  ++it;
2751  }
2752 
2753  g_dist.template ghost_get<0>();
2754 
2757 
2758  auto it2 = g_dist.getDomainIterator();
2759 
2760  while (it2.isNext())
2761  {
2762  auto k = it2.get();
2763  auto gkey = it2.getGKey(k);
2764 
2765  g_dist2.template get<0>(k) = g_dist.template get<0>(k) + 1;
2766  g_dist3.template get<0>(k) = g_dist.template get<0>(k) + 2;
2767 
2768  ++it2;
2769  }
2770 
2771  g_dist2.template ghost_get<0>();
2772  g_dist3.template ghost_get<0>();
2773 
2774  bool match = true;
2775 
2776  auto it3 = g_dist.getDomainIterator();
2777 
2778  while (it3.isNext())
2779  {
2780  auto k = it3.get();
2781  auto gkey = it3.getGKey(k);
2782 
2783  match &= g_dist2.template get<0>(k) == g_dist.template get<0>(k) + 1;
2784  match &= g_dist3.template get<0>(k) == g_dist.template get<0>(k) + 2;
2785 
2786  ++it3;
2787  }
2788 
2789  BOOST_REQUIRE_EQUAL(match,true);
2790 }
2791 
2792 BOOST_AUTO_TEST_SUITE_END()
2793 
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
bool check_consistency()
function to check the consistency of the information of the decomposition
size_t getProcessUnitID()
Get the process unit id.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:556
grid_key_dx< dim > getGKey(const grid_dist_key_dx< dim > &k) const
Convert a g_dist_key_dx into a global key.
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
This structure define the operation add to use with copy general.
auto get(const grid_dist_key_dx< dim, bg_key > &v1) const -> typename std::add_lvalue_reference< decltype(loc_grid.get(v1.getSub()).template get< p >(v1.getKey()))>::type
Get the reference of the selected element.
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
class that store the information of the grid like number of point on each direction and define the in...
Definition: grid_zm.hpp:21
__host__ __device__ bool isInside(const Point< dim, T > &p) const
Check if the point is inside the box.
Definition: Box.hpp:1004
T getVolumeKey() const
Get the volume spanned by the Box P1 and P2 interpreted as grid key.
Definition: Box.hpp:1351
Definition: Ghost.hpp:39
Implementation of VCluster class.
Definition: VCluster.hpp:58
void execute()
Execute all the requests.
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:823
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
size_t getProcessingUnits()
Get the total number of processors.
grid_dist_iterator< dim, device_grid, decltype(device_grid::type_of_subiterator()), FREE > getDomainIterator() const
It return an iterator that span the full grid domain (each processor span its local domain)
void sum(T &num)
Sum the numbers across all processors and get the result.
bool isValid() const
Check if the Box is a valid box P2 >= P1.
Definition: Box.hpp:1180
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.
Test structure used for several test.
Definition: Point_test.hpp:105
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567
Decomposition & getDecomposition()
Get the object that store the information about the decomposition.
Boundary conditions.
Definition: common.hpp:21