OpenFPM  5.2.0
Project that contain the implementation of distributed structures
test_isolation.hpp
1 /*
2  * test_isolation.hpp
3  *
4  * Created on: Mar 11, 2016
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_TEST_ISOLATION_HPP_
9 #define SRC_TEST_ISOLATION_HPP_
10 
11 /*
12  * Test that are not test but more are isolated here
13  *
14  *
15  */
16 
17 BOOST_AUTO_TEST_SUITE( antoniol_test_isolation )
18 
19 
20 BOOST_AUTO_TEST_CASE( CartDecomposition_test_2D )
21 {
22  //size_t balance_values_4p_64[] = {2.86,2.86,2.86,6.7,7.43,4.9,8.07,1.82,1.82,4.47,5.3};
23 
24  // Vcluster
25  Vcluster & vcl = *global_v_cluster;
26 
27  // non-periodic boundary condition
28  size_t bc[2] = { NON_PERIODIC, NON_PERIODIC };
29 
30  // Initialize the global VCluster
31  init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);
32 
35 
36  // Init DLB tool
37  DLB dlb(vcl);
38 
39  // Physical domain
40  Box<2, float> box( { 0.0, 0.0 }, { 10.0, 10.0 });
41  size_t div[2];
42 
43  // Get the number of processor and calculate the number of sub-domain
44  // for each processor (SUB_UNIT_FACTOR=64)
45  size_t n_proc = vcl.getProcessingUnits();
46  size_t n_sub = n_proc * SUB_UNIT_FACTOR;
47 
48  // Set the number of sub-domains on each dimension (in a scalable way)
49  for (int i = 0; i < 2; i++)
50  {
51  div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/2));
52  }
53 
54  // Define ghost
55  Ghost<2, float> g(0.01);
56 
57  // Decompose
58  dec.setParameters(div, box, bc, g);
59 
60  // Set unbalance threshold
61  dlb.setHeurisitc(DLB::Heuristic::UNBALANCE_THRLD);
62  dlb.setThresholdLevel(DLB::ThresholdLevel::THRLD_MEDIUM);
63 
64  // Add weights to points
65 
66  // First create the center of the weights distribution, check it is coherent to the size of the domain
67  Point<2, float> center( { 2.0, 2.0 });
68 
69  // Radius of the weights distribution
70  float radius = 2.0;
71 
72  // Weight if the distribution (high)
73  size_t weight_h = 5, weight_l = 1;
74 
75  setComputationCosts(dec, dec.getNSubSubDomains(), center, radius, weight_h, weight_l);
76 
77  dec.getDistribution().write("DLB_test_graph_0.vtk");
78 
79  dec.decompose();
80 
81  dec.getDistribution().write("DLB_test_graph_1.vtk");
82 
83  float stime = 0.0, etime = 10.0, tstep = 0.1;
84 
85  for(float t = stime, i = 1; t < etime; t = t + tstep, i++)
86  {
87 
88  if(t < etime/2)
89  {
90  center.get(0) += tstep;
91  center.get(1) += tstep;
92  }
93  else
94  {
95  center.get(0) -= tstep;
96  center.get(1) -= tstep;
97  }
98 
99  setComputationCosts(dec, dec.getNSubSubDomains(), center, radius, weight_h, weight_l);
100 
101  dlb.endIteration();
102 
103  if(dec.rebalance(dlb))
104  dec.write("DLB_test_graph_cart_" + std::to_string(i+1) + "_");
105 
106  std::stringstream str;
107  str << "DLB_test_graph_" << i + 1 << ".vtk";
108  dec.getDistribution().write(str.str());
109  }
110 
111  // For each calculated ghost box
112  for (size_t i = 0; i < dec.getNIGhostBox(); i++)
113  {
114  Box<2,float> b = dec.getIGhostBox(i);
115  size_t proc = dec.getIGhostBoxProcessor(i);
116 
117  // sample one point inside the box
118  Point<2,float> p = b.rnd();
119 
120  // Check that ghost_processorsID return that processor number
121  const openfpm::vector<size_t> & pr = dec.template ghost_processorID<CartDecomposition<2,float>::processor_id>(p);
122 
123  bool found = false;
124 
125  for (size_t j = 0; j < pr.size(); j++)
126  {
127  if (pr.get(j) == proc)
128  { found = true; break;}
129  }
130 
131  if (found == false)
132  {
133  const openfpm::vector<size_t> pr2 = dec.template ghost_processorID<CartDecomposition<2,float>::processor_id>(p);
134  }
135 
136  BOOST_REQUIRE_EQUAL(found,true);
137  }
138 
139  // Check the consistency
140 
141  bool val = dec.check_consistency();
142  BOOST_REQUIRE_EQUAL(val,true);
143 }
144 
145 BOOST_AUTO_TEST_CASE( CartDecomposition_test_2D_sar)
146 {
147  // Vcluster
148  Vcluster & vcl = *global_v_cluster;
149 
150  // non-periodic boundary condition
151  size_t bc[2] = { NON_PERIODIC, NON_PERIODIC };
152 
153  // Initialize the global VCluster
154  init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);
155 
158 
159  // Init DLB tool
160  DLB dlb(vcl);
161 
162  // Physical domain
163  Box<2, float> box( { 0.0, 0.0 }, { 10.0, 10.0 });
164  size_t div[2];
165 
166  // Get the number of processor and calculate the number of sub-domain
167  // for each processor (SUB_UNIT_FACTOR=64)
168  size_t n_proc = vcl.getProcessingUnits();
169  size_t n_sub = n_proc * SUB_UNIT_FACTOR;
170 
171  // Set the number of sub-domains on each dimension (in a scalable way)
172  for (int i = 0; i < 2; i++)
173  {
174  div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/2));
175  }
176 
177  // Define ghost
178  Ghost<2, float> g(0.01);
179 
180  // Decompose
181  dec.setParameters(div, box, bc, g);
182 
183  // Set type of heuristic
184  dlb.setHeurisitc(DLB::Heuristic::SAR_HEURISTIC);
185 
186  // Add weights to points
187 
188  // First create the center of the weights distribution, check it is coherent to the size of the domain
189  Point<2, float> center( { 2.0, 2.0 });
190 
191  // Radius of the weights distribution
192  float radius = 2.0;
193 
194  // Weight if the distribution (high)
195  size_t weight_h = 5, weight_l = 1;
196 
197  size_t n_v = pow(div[0], 2);
198 
199  setComputationCosts(dec, n_v, center, radius, weight_h, weight_l);
200 
201  dec.decompose();
202 
203  dec.getDistribution().write("DLB_test_graph_0.vtk");
204 
205  float stime = 0.0, etime = 10.0, tstep = 0.1;
206 
207  dlb.setSimulationStartTime(0);
208  dlb.setSimulationEndTime(10);
209 
210  for(float t = stime, i = 1; t < etime; t = t + tstep, i++)
211  {
212  dlb.startIteration();
213 
214  if(t < etime/2)
215  {
216  center.get(0) += tstep;
217  center.get(1) += tstep;
218  }
219  else
220  {
221  center.get(0) -= tstep;
222  center.get(1) -= tstep;
223  }
224 
225  setComputationCosts(dec, n_v, center, radius, weight_h, weight_l);
226 
227  sleep((n_v/dec.getProcessorLoad())/vcl.getProcessingUnits());
228 
229  dlb.endIteration();
230 
231  if(dec.rebalance(dlb))
232  {
233  dec.write("DLB_test_graph_cart_" + std::to_string(i) + "_");
234  }
235 
236  std::stringstream str;
237  str << "DLB_test_graph_" << i << ".vtk";
238  dec.getDistribution().write(str.str());
239  }
240 
241  // For each calculated ghost box
242  for (size_t i = 0; i < dec.getNIGhostBox(); i++)
243  {
244  Box<2,float> b = dec.getIGhostBox(i);
245  size_t proc = dec.getIGhostBoxProcessor(i);
246 
247  // sample one point inside the box
248  Point<2,float> p = b.rnd();
249 
250  // Check that ghost_processorsID return that processor number
251  const openfpm::vector<size_t> & pr = dec.template ghost_processorID<CartDecomposition<2,float>::processor_id>(p);
252 
253  bool found = false;
254 
255  for (size_t j = 0; j < pr.size(); j++)
256  {
257  if (pr.get(j) == proc)
258  { found = true; break;}
259  }
260 
261  if (found == false)
262  {
263  const openfpm::vector<size_t> pr2 = dec.template ghost_processorID<CartDecomposition<2,float>::processor_id>(p);
264  }
265 
266  BOOST_REQUIRE_EQUAL(found,true);
267  }
268 
269  // Check the consistency
270 
271  bool val = dec.check_consistency();
272  BOOST_REQUIRE_EQUAL(val,true);
273 }
274 
275 BOOST_AUTO_TEST_CASE( CartDecomposition_test_3D)
276 {
277  // Vcluster
278  Vcluster & vcl = *global_v_cluster;
279 
280  // non-periodic boundary condition
281  size_t bc[3] = { NON_PERIODIC, NON_PERIODIC, NON_PERIODIC };
282 
283  // Initialize the global VCluster
284  init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);
285 
288 
289  // Init DLB tool
290  DLB dlb(vcl);
291 
292  // Physical domain
293  Box<3, float> box( { 0.0, 0.0, 0.0 }, { 10.0, 10.0, 10.0 });
294  size_t div[3];
295 
296  // Get the number of processor and calculate the number of sub-domain
297  // for each processor (SUB_UNIT_FACTOR=64)
298  size_t n_proc = vcl.getProcessingUnits();
299  size_t n_sub = n_proc * SUB_UNIT_FACTOR;
300 
301  // Set the number of sub-domains on each dimension (in a scalable way)
302  for (int i = 0; i < 3; i++)
303  {
304  div[i] = openfpm::math::round_big_2(pow(n_sub,1.0/3));
305  }
306 
307  // Define ghost
308  Ghost<3, float> g(0.01);
309 
310  // Decompose
311  dec.setParameters(div, box, bc, g);
312 
313  // Set unbalance threshold
314  dlb.setHeurisitc(DLB::Heuristic::UNBALANCE_THRLD);
315  dlb.setThresholdLevel(DLB::ThresholdLevel::THRLD_MEDIUM);
316 
317  // Add weights to points
318 
319  // First create the center of the weights distribution, check it is coherent to the size of the domain
320  Point<3, float> center( { 2.0, 2.0, 2.0 });
321 
322  // Radius of the weights distribution
323  float radius = 2.0;
324 
325  // Weight if the distribution (high)
326  size_t weight_h = 5, weight_l = 1;
327 
328  size_t n_v = pow(div[0], 3);
329 
330  setComputationCosts3D(dec, n_v, center, radius, weight_h, weight_l);
331 
332  dec.decompose();
333 
334  dec.getDistribution().write("DLB_test_graph_0.vtk");
335 
336  float stime = 0.0, etime = 10.0, tstep = 0.1;
337 
338  for(float t = stime, i = 1; t < etime; t = t + tstep, i++)
339  {
340 
341  if(t < etime/2)
342  {
343  center.get(0) += tstep;
344  center.get(1) += tstep;
345  center.get(2) += tstep;
346  }
347  else
348  {
349  center.get(0) -= tstep;
350  center.get(1) -= tstep;
351  center.get(2) -= tstep;
352  }
353 
354  setComputationCosts3D(dec, n_v, center, radius, weight_h, weight_l);
355 
356  dlb.endIteration();
357 
358  dec.rebalance(dlb);
359 
360  std::stringstream str;
361  str << "DLB_test_graph_" << i << ".vtk";
362  dec.getDistribution().write(str.str());
363  }
364 
365  // For each calculated ghost box
366  for (size_t i = 0; i < dec.getNIGhostBox(); i++)
367  {
368  Box<3,float> b = dec.getIGhostBox(i);
369  size_t proc = dec.getIGhostBoxProcessor(i);
370 
371  // sample one point inside the box
372  Point<3,float> p = b.rnd();
373 
374  // Check that ghost_processorsID return that processor number
375  const openfpm::vector<size_t> & pr = dec.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);
376 
377  bool found = false;
378 
379  for (size_t j = 0; j < pr.size(); j++)
380  {
381  if (pr.get(j) == proc)
382  { found = true; break;}
383  }
384 
385  if (found == false)
386  {
387  const openfpm::vector<size_t> pr2 = dec.template ghost_processorID<CartDecomposition<3,float>::processor_id>(p);
388  }
389 
390  BOOST_REQUIRE_EQUAL(found,true);
391  }
392 
393  // Check the consistency
394 
395  bool val = dec.check_consistency();
396  BOOST_REQUIRE_EQUAL(val,true);
397 }
398 
399 
400 BOOST_AUTO_TEST_CASE( dist_map_graph_use_cartesian)
401 {
403  Vcluster & vcl = *global_v_cluster;
404 
405 // if(vcl.getProcessingUnits() != 3)
406 // return;
407 
408  // non-periodic boundary condition
409  size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
410 
413 
414  // Physical domain
415  Box<3, float> box( { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 });
416  size_t div[3] = {8,8,8};
417 
418  // Grid size and info
419  size_t gsz[3] = {8,8,8};
420  grid_sm<3,void> g_sm(gsz);
421 
422  // Define ghost
423  Ghost<3, float> g(0.01);
424 
425  // Decompose
426  dec.setParameters(div, box, bc, g);
427  dec.decompose();
428 
430 
431  size_t cnt = 0;
432  while (it_dec.isNext())
433  {
434  cnt++;
435  ++it_dec;
436  }
437 
439 
440  // Sent and receive the size of each subgraph
441  vcl.allGather(cnt, v_cnt);
442  vcl.execute();
443 
444  cnt = 0;
445  for (long int i = 0; i <= ((long int)vcl.getProcessUnitID()) - 1 ; ++i)
446  cnt += v_cnt.get(i);
447 
448  // count the points
449 
452 
454  while (it_dec2.isNext())
455  {
456  auto key = it_dec2.get();
457 
459 
460  v.template get<0>()[0] = key.get(0);
461  v.template get<0>()[1] = key.get(1);
462  v.template get<0>()[2] = key.get(2);
463 
464  size_t gid = g_sm.LinId(key);
465  dg.add_vertex(v, gid, cnt);
466 
467  cnt++;
468  ++it_dec2;
469  }
470 
471  dg.init();
472 
473  // we ask for some random vertex
474 
475  std::default_random_engine rg;
476  std::uniform_int_distribution<size_t> d(0,g_sm.size()-1);
477 
479 
480 /* for (size_t i = 0 ; i < 16 ; i++)
481  {
482  size_t v = d(rg);*/
483 
484  if (vcl.getProcessUnitID() == 0)
485  {dg.reqVertex(450);}
486 
487 /* dg.reqVertex(v);
488  }*/
489 
490  dg.sync();
491 
492  if (vcl.getProcessUnitID() == 0)
493  {
494  grid_key_dx<3> key;
495  // get the position information
496  key.set_d(0,dg.getVertex(450).template get<0>()[0]);
497  key.set_d(1,dg.getVertex(450).template get<0>()[1]);
498  key.set_d(2,dg.getVertex(450).template get<0>()[2]);
499 
500  size_t lin_id = g_sm.LinId(key);
501 
502  // BOOST_REQUIRE_EQUAL(lin_id,v_req.get(i));
503 
504  std::cout << "Error: " << " " << lin_id << " " << key.to_string() << "\n";
505  }
506 
507 /* for (size_t i = 0 ; i < 16 ; i++)
508  {
509  grid_key_dx<3> key;
510  // get the position information
511  key.set_d(0,dg.getVertex(v_req.get(i)).template get<0>()[0]);
512  key.set_d(1,dg.getVertex(v_req.get(i)).template get<0>()[1]);
513  key.set_d(2,dg.getVertex(v_req.get(i)).template get<0>()[2]);
514 
515  size_t lin_id = g_sm.LinId(key);
516 
517  // BOOST_REQUIRE_EQUAL(lin_id,v_req.get(i));
518 
519  std::cout << "Error: " << i << " " << lin_id << " " << v_req.get(i) << "\n";
520  }*/
521 
522 /* if (vcl.getProcessUnitID() == 0)
523  std::cout << "Error: " << i << " " << lin_id << " " << v_req.get(i) << "\n";*/
524 }
525 
526 BOOST_AUTO_TEST_CASE( Parmetis_distribution_test_random_walk )
527 {
528  typedef Point<3,float> s;
529 
530  Vcluster & v_cl = *global_v_cluster;
531 
532  // set the seed
533  // create the random generator engine
534  std::srand(v_cl.getProcessUnitID());
535  std::default_random_engine eg;
536  std::uniform_real_distribution<float> ud(0.0f, 1.0f);
537 
538  size_t nsz[] = { 0, 32, 4 };
539  nsz[0] = 65536 * v_cl.getProcessingUnits();
540 
541  print_test_v( "Testing 3D random walk vector k<=",nsz[0]);
542 
543  // 3D test
544  for (size_t i = 0; i < 3; i++ )
545  {
546  size_t k = nsz[i];
547 
548  BOOST_TEST_CHECKPOINT( "Testing 3D random walk k=" << k );
549 
550  Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});
551 
552  // Grid info
553  grid_sm<3, void> info( { GS_SIZE, GS_SIZE, GS_SIZE });
554 
555  // Boundary conditions
556  size_t bc[3] = { NON_PERIODIC,NON_PERIODIC,NON_PERIODIC };
557 
558  // factor
559  float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/3.0f);
560 
561  // ghost
562  Ghost<3,float> ghost(0.01 / factor);
563 
564  // Distributed vector
566 
567  auto it = vd.getIterator();
568 
569  while (it.isNext())
570  {
571  auto key = it.get();
572 
573  vd.template getPos<s::x>(key)[0] = ud(eg);
574  vd.template getPos<s::x>(key)[1] = ud(eg);
575  vd.template getPos<s::x>(key)[2] = ud(eg);
576 
577  ++it;
578  }
579 
580  vd.map();
581 
582  vd.addComputationCosts();
583 
584  vd.getDecomposition().getDistribution().write("parmetis_random_walk_" + std::to_string(0) + ".vtk");
585 
586  // 10 step random walk
587 
588  for (size_t j = 0; j < 10; j++)
589  {
590  auto it = vd.getDomainIterator();
591 
592  while (it.isNext())
593  {
594  auto key = it.get();
595 
596  vd.template getPos<s::x>(key)[0] += 0.01 * ud(eg);
597  vd.template getPos<s::x>(key)[1] += 0.01 * ud(eg);
598  vd.template getPos<s::x>(key)[2] += 0.01 * ud(eg);
599 
600  ++it;
601  }
602 
603  vd.map();
604 
606 
607  //vd.ghost_get<>();
608  //vd.getDomainIterator;
609 
611 
612  vd.addComputationCosts();
613 
614  vd.getDecomposition().rebalance(10);
615 
616  vd.map();
617 
618  vd.getDecomposition().getDistribution().write("parmetis_random_walk_" + std::to_string(j+1) + ".vtk");
619 
620  size_t l = vd.size_local();
621  v_cl.sum(l);
622  v_cl.execute();
623 
624  // Count the local particles and check that the total number is consistent
625  size_t cnt = total_n_part_lc(vd,bc);
626 
627  //BOOST_REQUIRE_EQUAL((size_t)k,cnt);
628  }
629  }
630 }
631 
632 BOOST_AUTO_TEST_CASE( Parmetis_distribution_test_random_walk_2D )
633 {
634 
635  //Particle: position, type of poistion, type of animal (0 rabbit, 1 fox), dead or alive (0 or 1), time the fox stays alive without eating
636  typedef Point<2,float> s;
637 
638  Vcluster & v_cl = *global_v_cluster;
639 
640  size_t JUST_EATEN = 5;
641 
642  // set the seed
643  // create the random generator engine
644  std::srand(v_cl.getProcessUnitID());
645  std::default_random_engine eg;
646  std::uniform_real_distribution<float> ud(0.0f, 0.5f);
647 
648  size_t k = 100000;
649 
650  print_test_v( "Testing 2D random walk vector k<=",k);
651 
652  BOOST_TEST_CHECKPOINT( "Testing 2D random walk k=" << k );
653 
654  Box<2,float> box({0.0,0.0},{1.0,1.0});
655 
656  // Grid info
657  grid_sm<2, void> info( { GS_SIZE, GS_SIZE });
658 
659  // Boundary conditions
660  size_t bc[2] = { PERIODIC, PERIODIC };
661 
662  // factor
663  float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/3.0f);
664 
665  // ghost
666  Ghost<2,float> ghost(0.01 / factor);
667 
668  // Distributed vector
670 
671  // Init DLB tool
672  DLB dlb(v_cl);
673 
674  // Set unbalance threshold
675  dlb.setHeurisitc(DLB::Heuristic::UNBALANCE_THRLD);
676  dlb.setThresholdLevel(DLB::ThresholdLevel::THRLD_MEDIUM);
677 
678  auto it = vd.getIterator();
679 
680  size_t c = 0;
681  while (it.isNext())
682  {
683  auto key = it.get();
684  if(c % 5)
685  {
686  vd.template getPos<s::x>(key)[0] = ud(eg);
687  vd.template getPos<s::x>(key)[1] = ud(eg);
688  }else{
689  vd.template getPos<s::x>(key)[0] = ud(eg)*2;
690  vd.template getPos<s::x>(key)[1] = ud(eg)*2;
691  }
692  ++it;
693  ++c;
694  }
695 
696  vd.map();
697 
698  vd.addComputationCosts();
699 
700  vd.getDecomposition().rebalance(dlb);
701 
702  vd.map();
703 
704  vd.getDecomposition().write("dec_init");
705  vd.getDecomposition().getDistribution().write("parmetis_random_walk_" + std::to_string(0) + ".vtk");
706  vd.write("particles_", 0, NO_GHOST);
707 
708  // 10 step random walk
709  for (size_t j = 0; j < 50; j++)
710  {
711  std::cout << "Iteration " << (j+1) << "\n";
712 
713  auto it = vd.getDomainIterator();
714 
715  while (it.isNext())
716  {
717  auto key = it.get();
718 
719  vd.template getPos<s::x>(key)[0] += 0.01 * ud(eg);
720  vd.template getPos<s::x>(key)[1] += 0.01 * ud(eg);
721 
722  ++it;
723  }
724 
725  vd.map();
726 
727  vd.addComputationCosts();
728 
729  vd.getDecomposition().rebalance(dlb);
730 
731  vd.map();
732 
733  vd.getDecomposition().getDistribution().write("parmetis_random_walk_" + std::to_string(j+1) + ".vtk");
734  vd.write("particles_", j+1, NO_GHOST);
735  vd.getDecomposition().write("dec_");
736 
737  size_t l = vd.size_local();
738  v_cl.sum(l);
739  v_cl.execute();
740 
741  // Count the local particles and check that the total number is consistent
742  //size_t cnt = total_n_part_lc(vd,bc);
743 
744  //BOOST_REQUIRE_EQUAL((size_t)k,cnt);
745  }
746 
747 }
748 
749 
750 BOOST_AUTO_TEST_CASE( Parmetis_distribution_test_prey_and_predators )
751 {
752  Vcluster & v_cl = *global_v_cluster;
753 
754  //time the animal stays alive without eating or reproducing
755  size_t TIME_A = 5;
756 
757  size_t PREDATOR = 1, PREY = 0;
758  size_t ALIVE = 1, DEAD = 0;
759 
760  // Predators reproducing probability
761  float PRED_REPR = 0.1;
762 
763  // Predators eating probability
764  float PRED_EAT = 0.2;
765 
766  // Prey reproducing probability
767  float PREY_REPR = 0.1;
768 
769  // set the seed
770  // create the random generator engine
771  std::srand(v_cl.getProcessUnitID());
772  std::default_random_engine eg;
773  std::uniform_real_distribution<float> ud(0.0f, 1.0f);
774 
775  size_t k = 50000;
776 
777  print_test_v( "Testing 2D random walk vector k<=",k);
778 
779  BOOST_TEST_CHECKPOINT( "Testing 2D random walk k=" << k );
780 
781  Box<2,float> box({0.0,0.0},{1.0,1.0});
782 
783  // Grid info
784  grid_sm<2, void> info( { GS_SIZE, GS_SIZE });
785 
786  // Boundary conditions
787  size_t bc[2] = { PERIODIC, PERIODIC };
788 
789  // factor
790  float factor = pow(global_v_cluster->getProcessingUnits()/2.0f,1.0f/3.0f);
791 
792  // interaction radius
793  float r_cut = 0.01 / factor;
794 
795  // ghost
796  Ghost<2,float> ghost(0.01 / factor);
797 
798  // Distributed vector
800 
801  // Init DLB tool
802  DLB dlb(v_cl);
803 
804  // Set unbalance threshold
805  dlb.setHeurisitc(DLB::Heuristic::UNBALANCE_THRLD);
806  dlb.setThresholdLevel(DLB::ThresholdLevel::THRLD_MEDIUM);
807 
808  auto it = vd.getIterator();
809 
810  size_t c = 0;
811  while (it.isNext())
812  {
813  auto key = it.get();
814  if(c % 3)
815  {
816  vd.template getPos<animal::pos>(key)[0] = ud(eg);
817  vd.template getPos<animal::pos>(key)[1] = ud(eg);
818  vd.template getProp<animal::genre>(key) = 0; //prey
819  vd.template getProp<animal::status>(key) = 1; //alive
820  vd.template getProp<animal::time_a>(key) = TIME_A; //alive
821  }else{
822  vd.template getPos<animal::pos>(key)[0] = ud(eg);
823  vd.template getPos<animal::pos>(key)[1] = ud(eg);
824  vd.template getProp<animal::genre>(key) = 1; //predator
825  vd.template getProp<animal::status>(key) = 1; //alive
826  vd.template getProp<animal::time_a>(key) = TIME_A; //alive
827  }
828  ++it;
829  ++c;
830  }
831 
832  vd.map();
833 
834  vd.addComputationCosts();
835 
836  vd.getDecomposition().rebalance(dlb);
837 
838  vd.map();
839 
840  vd.getDecomposition().write("dec_init");
841  vd.getDecomposition().getDistribution().write("parmetis_random_walk_" + std::to_string(0) + ".vtk");
842  vd.write("particles_", 0, NO_GHOST);
843 
844  // 10 step random walk
845  for (size_t j = 0; j < 50; j++)
846  {
847  std::cout << "Iteration " << (j+1) << "\n";
848 
849  auto it = vd.getDomainIterator();
850 
851  while (it.isNext())
852  {
853  auto key = it.get();
854 
855  vd.template getPos<animal::pos>(key)[0] += 0.01 * ud(eg);
856  vd.template getPos<animal::pos>(key)[1] += 0.01 * ud(eg);
857 
858  ++it;
859  }
860 
861  vd.map();
862 
864 
865  vd.ghost_get<0>();
866 
868 
869  // get the cell list with a cutoff radius
870 
871  bool error = false;
872 
873  auto NN = vd.getCellList(0.01 / factor);
874 
875  // iterate across the domain particle
876 
877  auto it2 = vd.getDomainIterator();
878 
879  while (it2.isNext())
880  {
881  auto p = it2.get();
882 
883  Point<2,float> xp = vd.getPos<0>(p);
884 
885  size_t gp = vd.getProp<animal::genre>(p);
886  size_t sp = vd.getProp<animal::status>(p);
887 
888  auto Np = NN.getIterator(NN.getCell(vd.getPos<0>(p)));
889 
890  while (Np.isNext())
891  {
892  auto q = Np.get();
893 
894  size_t gq = vd.getProp<animal::genre>(q);
895  size_t sq = vd.getProp<animal::status>(q);
896 
897  // repulsive
898 
899  Point<2,float> xq = vd.getPos<0>(q);
900  Point<2,float> f = (xp - xq);
901 
902  float distance = f.norm();
903 
904  //if p is a fox and q a rabit and they are both alive then the fox eats the rabbit
905  if (distance < 2*r_cut*sqrt(2) && sp == ALIVE)
906  {
907  if(gp == PREDATOR && gq == PREY && sq == ALIVE)
908  {
909  vd.getProp<animal::status>(q) = DEAD;
910  vd.getProp<animal::time_a>(q) = TIME_A;
911  }
912  else if (gp == PREY && gq == PREY && sq != DEAD)
913  {
914  vd.add();
915  //vd.getLastPos<animal::pos>()[0] = ud(eg);
916  //vd.getLastPos<animal::pos>()[1] = ud(eg);
917  vd.getLastProp<animal::genre>() = 0;
918  }
919  }
920 
921  ++Np;
922  }
923 
924  if(vd.getProp<animal::status>(p) == DEAD)
925  {
926  deads.add(p.getKey());
927  }
928 
929  ++it2;
930  }
931 
932  vd.remove(deads, 0);
933  deads.resize(0);
934 
936 
937  vd.addComputationCosts();
938 
939  vd.getDecomposition().rebalance(dlb);
940 
941  vd.map();
942 
943  vd.getDecomposition().getDistribution().write("parmetis_random_walk_" + std::to_string(j+1) + ".vtk");
944  vd.write("particles_", j+1, NO_GHOST);
945  vd.getDecomposition().write("dec_");
946 
947  size_t l = vd.size_local();
948  v_cl.sum(l);
949  v_cl.execute();
950 
951  // Count the local particles and check that the total number is consistent
952  //size_t cnt = total_n_part_lc(vd,bc);
953 
954  //BOOST_REQUIRE_EQUAL((size_t)k,cnt);
955  }
956 
957 }
958 
959 BOOST_AUTO_TEST_SUITE_END()
960 
961 #endif /* SRC_TEST_ISOLATION_HPP_ */
This class represent an N-dimensional box.
Definition: Box.hpp:60
This class decompose a space into sub-sub-domains and distribute them across processors.
Definition: DLB.hpp:54
Structure that store a graph in CSR format or basically in compressed adjacency matrix format.
auto getVertex(size_t id) -> decltype(v.get(id))
Function to access the vertexes.
void init()
Once added all the vertices this function must be called to initialize all the properties,...
void sync()
Execute all vertex requests and add them as ghosts inside this graph, they will be available until a ...
void add_vertex(const V &vrt, size_t id, size_t gid)
Add vertex vrt with global id and id properties.
void reqVertex(size_t gid)
Put a vertex request in queue.
Definition: Ghost.hpp:40
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
void execute()
Execute all the requests.
void sum(T &num)
Sum the numbers across all processors and get the result.
size_t getProcessUnitID()
Get the process unit id.
size_t getProcessingUnits()
Get the total number of processors.
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
Implementation of VCluster class.
Definition: VCluster.hpp:59
Given the decomposition it create an iterator.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:19
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
std::string to_string() const
convert the information into a string
Definition: grid_key.hpp:444
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
Declaration grid_sm.
Definition: grid_sm.hpp:167
size_t size()
Stub size.
Definition: map_vector.hpp:212
Distributed vector.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:221
Definition: ids.hpp:149