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