OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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  SpaceBox<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  SpaceBox<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  SpaceBox<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  {
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_ */
void sum(T &num)
Sum the numbers across all processors and get the result.
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
void add_vertex(const V &vrt, size_t id, size_t gid)
Add vertex vrt with global id and id properties.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
size_t getProcessUnitID()
Get the process unit id.
void execute()
Execute all the requests.
Given the decomposition it create an iterator.
void reqVertex(size_t gid)
Put a vertex request in queue.
size_t size()
Stub size.
Definition: map_vector.hpp:70
std::string to_string()
convert the information into a string
Definition: grid_key.hpp:349
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
Definition: Ghost.hpp:39
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
void sync()
Execute all vertex requests and add them as ghosts inside this graph, they will be available until a ...
Implementation of VCluster class.
Definition: VCluster.hpp:36
This class decompose a space into sub-sub-domains and distribute them across processors.
Structure that store a graph in CSR format or basically in compressed adjacency matrix format...
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
This class represent an N-dimensional box.
Definition: Box.hpp:56
T norm()
norm of the vector
Definition: Point.hpp:202
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
Definition: DLB.hpp:53
Declaration grid_sm.
Definition: grid_sm.hpp:71
Distributed vector.
auto getVertex(size_t id) -> decltype(v.get(id))
Function to access the vertexes.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:81
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_key.hpp:407
Definition: ids.hpp:148
size_t getProcessingUnits()
Get the total number of processors.
Point< dim, T > rnd()
Generate a random point inside the box.
Definition: SpaceBox.hpp:209
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
void init()
Once added all the vertices this function must be called to initialize all the properties, useless if a graph factory is used.