OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
CartDecomposition.hpp
1 /*
2  * CartDecomposition.hpp
3  *
4  * Created on: Oct 07, 2015
5  * Author: Pietro Incardona, Antonio Leo
6  */
7 
8 #ifndef CARTDECOMPOSITION_HPP
9 #define CARTDECOMPOSITION_HPP
10 
11 #include "config.h"
12 #include <cmath>
13 #include "VCluster/VCluster.hpp"
14 #include "Graph/CartesianGraphFactory.hpp"
15 #include "Decomposition.hpp"
16 #include "Vector/map_vector.hpp"
17 #include <vector>
18 #include <initializer_list>
19 #include "SubdomainGraphNodes.hpp"
20 #include "dec_optimizer.hpp"
21 #include "Space/Shape/Box.hpp"
22 #include "Space/Shape/Point.hpp"
23 #include "NN/CellList/CellDecomposer.hpp"
24 #include <unordered_map>
25 #include "NN/CellList/CellList.hpp"
26 #include "Space/Ghost.hpp"
27 #include "common.hpp"
28 #include "ie_loc_ghost.hpp"
29 #include "ie_ghost.hpp"
30 #include "nn_processor.hpp"
31 #include "GraphMLWriter/GraphMLWriter.hpp"
32 #include "Distribution/ParMetisDistribution.hpp"
33 #include "Distribution/DistParMetisDistribution.hpp"
34 #include "Distribution/MetisDistribution.hpp"
35 #include "DLB/DLB.hpp"
36 #include "util/se_util.hpp"
37 #include "util/mathutil.hpp"
38 #include "CartDecomposition_ext.hpp"
39 #include "data_type/aggregate.hpp"
40 #include "Domain_NN_calculator_cart.hpp"
41 #include "cuda/CartDecomposition_gpu.cuh"
42 #include "Domain_icells_cart.hpp"
43 
44 #define CARTDEC_ERROR 2000lu
45 
46 enum dec_options
47 {
48  DEC_NONE = 0,
49  DEC_SKIP_ICELL = 1
50 };
51 
63 template<unsigned int dim> static void nsub_to_div2(size_t (& div)[dim], size_t n_sub, size_t dim_r)
64 {
65  for (size_t i = 0; i < dim; i++)
66  {
67  if (i < dim_r)
68  {div[i] = openfpm::math::round_big_2(pow(n_sub, 1.0 / dim_r));}
69  else
70  {div[i] = 1;}
71  }
72 }
73 
85 template<unsigned int dim> static void nsub_to_div(size_t (& div)[dim], size_t n_sub, size_t dim_r)
86 {
87  for (size_t i = 0; i < dim; i++)
88  {
89  if (i < dim_r)
90  {div[i] = std::floor(pow(n_sub, 1.0 / dim_r));}
91  else
92  {div[i] = 1;}
93  }
94 }
95 
96 #define COMPUTE_SKIN_SUB 1
97 
139 template<unsigned int dim, typename T, typename Memory, template <typename> class layout_base, typename Distribution>
140 class CartDecomposition: public ie_loc_ghost<dim, T,layout_base, Memory>,
141  public nn_prcs<dim, T,layout_base,Memory>,
142  public ie_ghost<dim,T,Memory,layout_base>,
143  public domain_nn_calculator_cart<dim>,
144  public domain_icell_calculator<dim,T,layout_base,Memory>
145 {
146 public:
147 
149  typedef T domain_type;
150 
153 
156 
159 
161 
163 
165 
166 protected:
167 
169  bool host_dev_transfer = false;
170 
172  bool commCostSet = false;
173 
176  typedef typename openfpm::vector<SpaceBox<dim, T>,
177  Memory,
181 
184 
187 
190 
194 
197 
200 
203  CellDecomposer_sm<dim, T, shift<dim,T>> cd;
204 
207 
209  T spacing[dim];
210 
213  size_t magn[dim];
214 
217 
219  Distribution dist;
220 
223 
225  long int ref_cnt;
226 
229 
231  size_t bc[dim];
232 
235 
238 
250  template<typename Memory_bx> SpaceBox<dim,T> convertDecBoxIntoSubDomain(encapc<1,::Box<dim,size_t>,Memory_bx> loc_box)
251  {
252  // A point with all coordinate to one
253  size_t one[dim];
254  for (size_t i = 0 ; i < dim ; i++) {one[i] = 1;}
255 
257  SpaceBox<dim, size_t> sub_dce = sub_dc;
258  sub_dce.expand(one);
259  sub_dce.mul(magn);
260 
261  // shrink by one
262  for (size_t i = 0 ; i < dim ; i++)
263  {
264  loc_box.template get<Box::p1>()[i] = sub_dce.getLow(i);
265  loc_box.template get<Box::p2>()[i] = sub_dce.getHigh(i) - 1;
266  }
267 
268  SpaceBox<dim, T> sub_d(sub_dce);
269  sub_d.mul(spacing);
270  sub_d += domain.getP1();
271 
272  // we add the
273 
274  // Fixing sub-domains to cover all the domain
275 
276  // Fixing sub_d
277  // if (loc_box) is at the boundary we have to ensure that the box span the full
278  // domain (avoiding rounding off error)
279  for (size_t i = 0; i < dim; i++)
280  {
281  if (sub_dc.getHigh(i) == gr.size(i) - 1)
282  {sub_d.setHigh(i, domain.getHigh(i));}
283 
284  if (sub_dc.getLow(i) == 0)
285  {sub_d.setLow(i,domain.getLow(i));}
286  }
287 
288  return sub_d;
289  }
290 
291  void collect_all_sub_domains(openfpm::vector<Box_map<dim,T>,Memory,layout_base> & sub_domains_global)
292  {
293 #ifdef SE_CLASS2
294  check_valid(this,8);
295 #endif
296 
297  sub_domains_global.clear();
298  openfpm::vector<Box_map<dim,T>,Memory,layout_base> bm;
299 
300  for (size_t i = 0 ; i < sub_domains.size() ; i++)
301  {
302  bm.add();
303 
304  bm.template get<0>(bm.size()-1) = ::SpaceBox<dim,T>(sub_domains.get(i));
305  bm.template get<1>(bm.size()-1) = v_cl.rank();
306  }
307 
308  v_cl.SGather<decltype(bm),decltype(sub_domains_global),layout_base>(bm,sub_domains_global,0);
309 
310  size_t size = sub_domains_global.size();
311 
312  v_cl.max(size);
313  v_cl.execute();
314 
315  sub_domains_global.resize(size);
316 
318  v_cl.execute();
319  }
320 
321 public:
322 
323  void initialize_fine_s(const ::Box<dim,T> & domain)
324  {
325  fine_s.clear();
326  size_t div_g[dim];
327 
328  // We reduce the size of the cells by a factor 8 in 3d 4 in 2d
329  for (size_t i = 0 ; i < dim ; i++)
330  {div_g[i] = (gr.size(i) == 1)?1:gr.size(i)/2;}
331 
332  fine_s.Initialize(domain,div_g);
333  }
334 
335  void construct_fine_s()
336  {
337  collect_all_sub_domains(sub_domains_global);
338 
339  // now draw all sub-domains in fine-s
340 
341  for (size_t i = 0 ; i < sub_domains_global.size() ; i++)
342  {
343 
344  // get the cells this box span
345  const grid_key_dx<dim> p1 = fine_s.getCellGrid_me(sub_domains_global.template get<0>(i).getP1());
346  const grid_key_dx<dim> p2 = fine_s.getCellGrid_pe(sub_domains_global.template get<0>(i).getP2());
347 
348  // Get the grid and the sub-iterator
349  auto & gi = fine_s.getGrid();
350  grid_key_dx_iterator_sub<dim> g_sub(gi,p1,p2);
351 
352  // add the box-id to the cell list
353  while (g_sub.isNext())
354  {
355  auto key = g_sub.get();
356  fine_s.addCell(gi.LinId(key),i);
357 
358  ++g_sub;
359  }
360  }
361 
362  host_dev_transfer = false;
363  }
364 
372  void createSubdomains(Vcluster<> & v_cl, const size_t (& bc)[dim], size_t opt = 0)
373  {
374  int p_id = v_cl.getProcessUnitID();
375 
376  // Calculate the total number of box and and the spacing
377  // on each direction
378  // Get the box containing the domain
379  SpaceBox<dim, T> bs = domain.getBox();
380 
381  for (unsigned int i = 0; i < dim; i++)
382  {
383  // Calculate the spacing
384  spacing[i] = (bs.getHigh(i) - bs.getLow(i)) / gr.size(i);
385  }
386 
387  // fill the structure that store the processor id for each sub-domain
388  initialize_fine_s(domain);
389 
390  // Optimize the decomposition creating bigger spaces
391  // And reducing Ghost over-stress
393 
394  // Ghost
396 
397  // Set the ghost
398  for (size_t i = 0 ; i < dim ; i++)
399  {
400  ghe.setLow(i,static_cast<long int>(ghost.getLow(i)/spacing[i]) - 1);
401  ghe.setHigh(i,static_cast<long int>(ghost.getHigh(i)/spacing[i]) + 1);
402  }
403 
404  // optimize the decomposition or merge sub-sub-domain
405  d_o.template optimize<nm_v_sub_id, nm_v_proc_id>(dist.getGraph(), p_id, loc_box, box_nn_processor,ghe,bc);
406 
407  // Initialize
408  if (loc_box.size() > 0)
409  {
411  proc_box = loc_box.get(0);
412  sub_domains.add(bbox);
413  }
414  else
415  {
416  // invalidate all the boxes
417  for (size_t i = 0 ; i < dim ; i++)
418  {
419  proc_box.setLow(i,0.0);
420  proc_box.setHigh(i,0);
421 
422  bbox.setLow(i,0.0);
423  bbox.setHigh(i,0);
424  }
425  }
426 
427  // convert into sub-domain
428  for (size_t s = 1; s < loc_box.size(); s++)
429  {
431 
432  // add the sub-domain
433  sub_domains.add(sub_d);
434 
435  // Calculate the bound box
436  bbox.enclose(sub_d);
437  proc_box.enclose(loc_box.get(s));
438  }
439 
442 
443  // fill fine_s structure
444  // fine_s structure contain the processor id for each sub-sub-domain
445  // with sub-sub-domain we mean the sub-domain decomposition before
446  // running dec_optimizer (before merging sub-domains)
447 
449 
450  construct_fine_s();
451 
453  }
454 
461  {
462  // Get the processor bounding Box
464 
465  // Check if the box is valid
466  if (bound.isValidN() == true)
467  {
468  // calculate the sub-divisions
469  size_t div[dim];
470  for (size_t i = 0; i < dim; i++)
471  {div[i] = (size_t) ((bound.getHigh(i) - bound.getLow(i)) / cd.getCellBox().getP2()[i]);}
472 
473  // Initialize the geo_cell structure
475 
476  // Initialize shift vectors
478  }
479  }
480 
486  {
487  float migration = 0;
488 
489  SpaceBox<dim, T> cellBox = cd.getCellBox();
490  float b_s = static_cast<float>(cellBox.getHigh(0));
491  float gh_s = static_cast<float>(ghost.getHigh(0));
492 
493  // compute the gh_area for 2 dim case
494  float gh_v = (gh_s * b_s);
495 
496  // multiply for sub-sub-domain side for each domain
497  for (size_t i = 2; i < dim; i++)
498  {
499  /* coverity[dead_error_line] */
500  gh_v *= b_s;
501  }
502 
503  size_t norm = (size_t) (1.0 / gh_v);
504 
505  migration = pow(b_s, dim);
506 
507  size_t prev = 0;
508 
509  for (size_t i = 0; i < dist.getNSubSubDomains(); i++)
510  {
511  dist.setMigrationCost(i, norm * migration /* * dist.getSubSubDomainComputationCost(i)*/ );
512 
513  for (size_t s = 0; s < dist.getNSubSubDomainNeighbors(i); s++)
514  {
515  // We have to remove dist.getSubSubDomainComputationCost(i) otherwise the graph is
516  // not directed
517  dist.setCommunicationCost(i, s, 1 * ts);
518  }
519  prev += dist.getNSubSubDomainNeighbors(i);
520  }
521 
522  commCostSet = true;
523  }
524 
529  {
530  // Create a grid where each point is a space
531  grid_sm<dim, void> g(div);
532 
533  // create a grid_key_dx iterator
534  grid_key_dx_iterator<dim> gk_it(g);
535 
536  // Divide the space into subspaces
537  while (gk_it.isNext())
538  {
540  grid_key_dx<dim> key = gk_it.get();
541 
543  SpaceBox<dim, T> tmp;
544 
546  for (int i = 0; i < dim; i++)
547  {
548  tmp.setHigh(i, (key.get(i) + 1) * spacing[i]);
549  tmp.setLow(i, key.get(i) * spacing[i]);
550  }
551 
553  sub_domains.add(tmp);
554 
555  // Next sub-domain
556  ++gk_it;
557  }
558  }
559 
560 
655  {
656  // Intersect all the local sub-domains with the sub-domains of the contiguous processors
657 
658  // create the internal structures that store ghost information
661 
663 
664  // Ghost box information must be re-offloaded
665  host_dev_transfer = false;
667  }
668 
669 
670 public:
671 
673  static constexpr int dims = dim;
674 
676  typedef T stype;
677 
679  void incRef()
680  {ref_cnt++;}
681 
683  void decRef()
684  {ref_cnt--;}
685 
687  long int ref()
688  {
689  return ref_cnt;
690  }
691 
698  :nn_prcs<dim, T, layout_base,Memory>(v_cl), v_cl(v_cl), dist(v_cl),ref_cnt(0)
699  {
700  // Reset the box to zero
701  bbox.zero();
702  }
703 
710  :nn_prcs<dim,T,layout_base,Memory>(cart.v_cl),v_cl(cart.v_cl),dist(v_cl),ref_cnt(0)
711  {
712  this->operator=(cart);
713  }
714 
721  :nn_prcs<dim,T,layout_base,Memory>(cart.v_cl),v_cl(cart.v_cl),dist(v_cl),ref_cnt(0)
722  {
723  this->operator=(cart);
724  }
725 
728  {
729  }
730 
734  class box_id
735  {
736  public:
745  inline static size_t id(p_box<dim, T> & p, size_t b_id)
746  {
747  return b_id;
748  }
749  };
750 
755  {
756  public:
765  template<typename encap_type> inline static size_t id(const encap_type & p, size_t b_id)
766  {
767  return p.template get<proc_>();
768  }
769  };
770 
775  {
776  public:
785  template<typename encap_type> inline static size_t id(const encap_type & p, size_t b_id)
786  {
787  return p.template get<lc_proc_>();
788  }
789  };
790 
794  class shift_id
795  {
796  public:
805  template<typename encap_type> inline static size_t id(const encap_type & p, size_t b_id)
806  {
807  return p.template get<shift_id_>();
808  }
809  };
810 
820  void applyPointBC(float (& pt)[dim]) const
821  {
822  for (size_t i = 0 ; i < dim ; i++)
823  {
824  if (bc[i] == PERIODIC)
825  {pt[i] = openfpm::math::periodic_l(pt[i],domain.getHigh(i),domain.getLow(i));}
826  }
827  }
828 
838  void applyPointBC(Point<dim,T> & pt) const
839  {
840  for (size_t i = 0 ; i < dim ; i++)
841  {
842  if (bc[i] == PERIODIC)
843  {pt.get(i) = openfpm::math::periodic_l(pt.get(i),domain.getHigh(i),domain.getLow(i));}
844  }
845  }
846 
856  template<typename Mem> void applyPointBC(encapc<1,Point<dim,T>,Mem> && pt) const
857  {
858  for (size_t i = 0 ; i < dim ; i++)
859  {
860  if (bc[i] == PERIODIC)
861  {pt.template get<0>()[i] = openfpm::math::periodic_l(pt.template get<0>()[i],domain.getHigh(i),domain.getLow(i));}
862  }
863  }
864 
873  {
875 
877  cart.sub_domains = sub_domains;
878  cart.fine_s = fine_s;
879 
880  cart.gr = gr;
881  cart.cd = cd;
882  cart.domain = domain;
883  for (size_t i = 0 ; i < dim ; i++)
884  {
885  cart.spacing[i] = spacing[i];
886  cart.magn[i] = magn[i];
887  };
888 
889  cart.bbox = bbox;
890  cart.ghost = g;
891 
892  cart.dist = dist;
893 
894  for (size_t i = 0 ; i < dim ; i++)
895  cart.bc[i] = bc[i];
896 
897  (static_cast<nn_prcs<dim,T,layout_base,Memory> &>(cart)).create(box_nn_processor, sub_domains);
898  (static_cast<nn_prcs<dim,T,layout_base,Memory> &>(cart)).applyBC(domain,ghost,bc);
899 
901  cart.calculateGhostBoxes();
902 
903  cart.collect_all_sub_domains(cart.sub_domains_global);
904 
905  return cart;
906  }
907 
914  {
916 
917  (static_cast<ie_loc_ghost<dim,T, layout_base,Memory>*>(&cart))->operator=(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>>(*this));
918  (static_cast<nn_prcs<dim,T,layout_base,Memory>*>(&cart))->operator=(static_cast<nn_prcs<dim,T,layout_base,Memory>>(*this));
919  (static_cast<ie_ghost<dim,T,Memory,layout_base>*>(&cart))->operator=(static_cast<ie_ghost<dim,T,Memory,layout_base>>(*this));
920 
921  cart.sub_domains = sub_domains;
923  cart.fine_s = fine_s;
924  cart.gr = gr;
925  cart.gr_dist = gr_dist;
926  cart.dist = dist;
927  cart.commCostSet = commCostSet;
928  cart.cd = cd;
929  cart.domain = domain;
931  for (size_t i = 0 ; i < dim ; i++)
932  {
933  cart.spacing[i] = spacing[i];
934  cart.magn[i] = magn[i];
935  };
936 
937  cart.ghost = ghost;
938 
939  cart.bbox = bbox;
940 
941  for (size_t i = 0 ; i < dim ; i++)
942  {cart.bc[i] = this->bc[i];}
943 
944  return cart;
945  }
946 
952  template<typename Memory2, template <typename> class layout_base2>
954  {
956 
957  (static_cast<ie_loc_ghost<dim,T,layout_base2,Memory2>*>(&cart))->operator=(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>>(*this));
958  (static_cast<nn_prcs<dim,T,layout_base2,Memory2>*>(&cart))->operator=(static_cast<nn_prcs<dim,T,layout_base,Memory>>(*this));
960  (static_cast<ie_ghost<dim,T,Memory2,layout_base2>*>(&cart))->operator=(ptr->template duplicate<Memory2,layout_base2>());
961 
964  cart.private_get_fine_s() = fine_s;
965  cart.private_get_gr() = gr;
966  cart.private_get_gr_dist() = gr_dist;
967  cart.private_get_dist() = dist;
969  cart.private_get_cd() = cd;
970  cart.private_get_domain() = domain;
972  for (size_t i = 0 ; i < dim ; i++)
973  {cart.private_get_spacing(i) = spacing[i];};
974 
975  cart.private_get_ghost() = ghost;
976 
977  cart.private_get_bbox() = bbox;
978 
979  for (size_t i = 0 ; i < dim ; i++)
980  {cart.private_get_bc(i) = this->bc[i];}
981 
982  return cart;
983  }
984 
993  {
994  static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>>(cart));
995  static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<nn_prcs<dim,T,layout_base,Memory>>(cart));
996  static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->operator=(static_cast<ie_ghost<dim,T,Memory,layout_base>>(cart));
997 
998  sub_domains = cart.sub_domains;
1000  fine_s = cart.fine_s;
1001  gr = cart.gr;
1002  gr_dist = cart.gr_dist;
1003  dist = cart.dist;
1004  commCostSet = cart.commCostSet;
1005  cd = cart.cd;
1006  domain = cart.domain;
1008 
1009  for (size_t i = 0 ; i < dim ; i++)
1010  {
1011  spacing[i] = cart.spacing[i];
1012  magn[i] = cart.magn[i];
1013  };
1014 
1015  ghost = cart.ghost;
1016 
1017  bbox = cart.bbox;
1018 
1019  for (size_t i = 0 ; i < dim ; i++)
1020  bc[i] = cart.bc[i];
1021 
1022  return *this;
1023  }
1024 
1032  template<typename CartDecomposition2>
1034  {
1035  static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<typename CartDecomposition2::ie_loc_ghost_type>(cart));
1036  static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<typename CartDecomposition2::nn_prcs_type>(cart));
1037  static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->operator=(static_cast<typename CartDecomposition2::ie_ghost_type>(cart));
1038 
1039  sub_domains = cart.private_get_sub_domains();
1040  box_nn_processor = cart.private_get_box_nn_processor();
1041  fine_s = cart.private_get_fine_s();
1042  gr = cart.private_get_gr();
1043  gr_dist = cart.private_get_gr_dist();
1044  dist = cart.private_get_dist();
1045  commCostSet = cart.private_get_commCostSet();
1046  cd = cart.private_get_cd();
1047  domain = cart.private_get_domain();
1048  sub_domains_global = cart.private_get_sub_domains_global();
1049 
1050  for (size_t i = 0 ; i < dim ; i++)
1051  {
1052  spacing[i] = cart.private_get_spacing(i);
1053  magn[i] = cart.private_get_magn(i);
1054  };
1055 
1056  ghost = cart.private_get_ghost();
1057 
1058  bbox = cart.private_get_bbox();
1059 
1060  for (size_t i = 0 ; i < dim ; i++)
1061  {bc[i] = cart.private_get_bc(i);}
1062 
1063  return *this;
1064  }
1065 
1074  {
1075  static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>>(cart));
1076  static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<nn_prcs<dim,T,layout_base,Memory>>(cart));
1077  static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->operator=(static_cast<ie_ghost<dim,T,Memory,layout_base>>(cart));
1078 
1079  sub_domains.swap(cart.sub_domains);
1080  box_nn_processor.swap(cart.box_nn_processor);
1081  fine_s.swap(cart.fine_s);
1082  gr = cart.gr;
1083  gr_dist = cart.gr_dist;
1084  dist = cart.dist;
1085  commCostSet = cart.commCostSet;
1086  cd = cart.cd;
1087  gr_dist = cart.gr_dist;
1088  dist = cart.dist;
1089 
1090  domain = cart.domain;
1091  sub_domains_global.swap(cart.sub_domains_global);
1092 
1093  for (size_t i = 0 ; i < dim ; i++)
1094  {
1095  spacing[i] = cart.spacing[i];
1096  magn[i] = cart.magn[i];
1097  };
1098 
1099  ghost = cart.ghost;
1100 
1101  bbox = cart.bbox;
1102 
1103  for (size_t i = 0 ; i < dim ; i++)
1104  bc[i] = cart.bc[i];
1105 
1106  return *this;
1107  }
1108 
1120  static size_t getDefaultGrid(size_t n_sub)
1121  {
1122  // Calculate the number of sub-sub-domain on
1123  // each dimension
1124  return openfpm::math::round_big_2(pow(n_sub, 1.0 / dim));
1125  }
1126 
1134  template<typename Mem> size_t inline processorID(const encapc<1, Point<dim,T>, Mem> & p) const
1135  {
1136  return processorID_impl(p,fine_s,sub_domains_global,getDomain(),bc);
1137  }
1138 
1146  size_t inline processorID(const Point<dim,T> &p) const
1147  {
1148  return processorID_impl(p,fine_s,sub_domains_global,getDomain(),bc);
1149  }
1150 
1158  size_t inline processorID(const T (&p)[dim]) const
1159  {
1160  return processorID_impl(p,fine_s,sub_domains_global,getDomain(),bc);
1161  }
1162 
1172  template<typename Mem> size_t inline processorIDBC(encapc<1, Point<dim,T>, Mem> p)
1173  {
1174  Point<dim,T> pt = p;
1175  applyPointBC(pt);
1176 
1177 
1178  return processorID_impl(pt,fine_s,sub_domains_global,getDomain(),bc);
1179  }
1180 
1190  size_t inline processorIDBC(const Point<dim,T> &p) const
1191  {
1192  Point<dim,T> pt = p;
1193  applyPointBC(pt);
1194 
1195  // Get the number of elements in the cell
1196 
1197  return processorID_impl(pt,fine_s,sub_domains_global,getDomain(),bc);
1198  }
1199 
1209  size_t inline processorIDBC(const T (&p)[dim]) const
1210  {
1211  Point<dim,T> pt = p;
1212  applyPointBC(pt);
1213 
1214  return processorID_impl(pt,fine_s,sub_domains_global,getDomain(),bc);
1215  }
1216 
1224  inline size_t periodicity(size_t i) const
1225  {
1226  return bc[i];
1227  }
1228 
1235  inline const size_t (& periodicity() const) [dim]
1236  {
1237  return bc;
1238  }
1239 
1246  {
1247  if (gm.size() == 0)
1248  {
1249  for (size_t i = 0 ; i < dim ; i++)
1250  magn[i] = 1;
1251  }
1252  else
1253  {
1254  for (size_t i = 0 ; i < dim ; i++)
1255  {
1256  if (gr.size(i) % gm.size(i) != 0)
1257  std::cerr << __FILE__ << ":" << __LINE__ << ".Error the decomposition grid specified as gr.size(" << i << ")=" << gr.size(i) << " is not multiple of the distribution grid gm.size(" << i << ")=" << gm.size(i) << std::endl;
1258 
1259  magn[i] = gr.size(i) / gm.size(i);
1260  }
1261  }
1262  }
1263 
1278  void setGoodParameters(::Box<dim,T> & domain_,
1279  const size_t (& bc)[dim],
1280  const Ghost<dim,T> & ghost,
1281  size_t dec_gran,
1282  const grid_sm<dim,void> & sec_dist = grid_sm<dim,void>())
1283  {
1284  size_t div[dim];
1285 
1286  // Create a valid decomposition of the space
1287  // Get the number of processor and calculate the number of sub-domain
1288  // for decomposition
1289  size_t n_proc = v_cl.getProcessingUnits();
1290  size_t n_sub = n_proc * dec_gran;
1291 
1292  // Calculate the maximum number (before merging) of sub-domain on
1293  // each dimension
1294 
1295  nsub_to_div2(div,n_sub,dim);
1296 
1297 /* for (size_t i = 0; i < dim; i++)
1298  {
1299  div[i] = openfpm::math::round_big_2(pow(n_sub, 1.0 / dim));
1300  }*/
1301 
1302  if (dim > 3)
1303  {
1304  long int dim_r = dim-1;
1305  do
1306  {
1307  // Check for adjustment
1308  size_t tot_size = 1;
1309  for (size_t i = 0 ; i < dim ; i++)
1310  {tot_size *= div[i];}
1311 
1312  // the granularity is too coarse increase the divisions
1313  if (tot_size / n_proc > (unsigned int long)(0.75*dec_gran) )
1314  {break;}
1315 
1316  nsub_to_div(div,n_sub,dim_r);
1317 
1318  dim_r--;
1319  } while(dim_r > 0);
1320  }
1321 
1322  setParameters(div,domain_,bc,ghost,sec_dist);
1323  }
1324 
1330  void getParameters(size_t (& div_)[dim])
1331  {
1332  for (size_t i = 0 ; i < dim ; i++)
1333  {div_[i] = this->gr.size(i);}
1334  }
1335 
1347  void setParameters(const size_t (& div_)[dim],
1348  ::Box<dim,T> & domain_,
1349  const size_t (& bc)[dim],
1350  const Ghost<dim,T> & ghost,
1351  const grid_sm<dim,void> & sec_dist = grid_sm<dim,void>())
1352  {
1353  // set the boundary conditions
1354  for (size_t i = 0 ; i < dim ; i++)
1355  this->bc[i] = bc[i];
1356 
1357  // set the ghost
1358  this->ghost = ghost;
1359 
1360  // Set the decomposition parameters
1361  gr.setDimensions(div_);
1362  domain = domain_;
1363  cd.setDimensions(domain, div_, 0);
1364 
1365  // We we have a secondary grid costruct a reduced graph
1366  if (sec_dist.size(0) != 0)
1367  {
1368  calculate_magn(sec_dist);
1369  gr_dist.setDimensions(sec_dist.getSize());
1370  }
1371  else
1372  {
1373  calculate_magn(sec_dist);
1374  gr_dist = gr;
1375  }
1376 
1377  // init distribution
1378  dist.createCartGraph(gr_dist, domain);
1379 
1380  }
1381 
1386  void reset()
1387  {
1388  sub_domains.clear();
1389  box_nn_processor.clear();
1390  fine_s.clear();
1391  loc_box.clear();
1395  }
1396 
1400  void decompose(dec_options opt = dec_options::DEC_NONE)
1401  {
1402  reset();
1403 
1404  if (commCostSet == false)
1406 
1407  dist.decompose();
1408 
1410 
1412 
1415 
1416  if (opt != dec_options::DEC_SKIP_ICELL)
1417  {
1418 
1422  sub_domains,
1423  this->getProcessorBounds(),
1424  this->getGhost().getRcut(),
1425  this->getGhost());
1426  }
1427  }
1428 
1434  void refine(size_t ts)
1435  {
1436  reset();
1437 
1438  if (commCostSet == false)
1440 
1441  dist.refine();
1442 
1444 
1446 
1449  }
1450 
1456  void redecompose(size_t ts)
1457  {
1458  reset();
1459 
1460  if (commCostSet == false)
1462 
1463  dist.redecompose();
1464 
1466 
1468 
1471  }
1472 
1479  bool refine(DLB & dlb)
1480  {
1481  // if the DLB heuristic to use is the "Unbalance Threshold" get unbalance percentage
1482  if (dlb.getHeurisitc() == DLB::Heuristic::UNBALANCE_THRLD)
1483  {
1484  float unbalance = dist.getUnbalance();
1485  dlb.setUnbalance(unbalance);
1486  if (v_cl.getProcessUnitID() == 0)
1487  {
1488  std::cout << std::setprecision(3) << unbalance << "\n";
1489  }
1490  }
1491 
1492  if (dlb.rebalanceNeeded())
1493  {
1495 
1496  return true;
1497  }
1498  return false;
1499  }
1500 
1501 // size_t n_step = 0;
1502 
1508  {
1509  return dist.getUnbalance();
1510  }
1511 
1517  {
1518  return dist.getProcessorLoad();
1519  }
1520 
1527  inline void getSubSubDomainPosition(size_t id, T (&pos)[dim])
1528  {
1529  dist.getSubSubDomainPosition(id, pos);
1530  }
1531 
1532  //TODO fix in Parmetis distribution to get only the right amount of vertices
1538  {
1539  return dist.getNSubSubDomains();
1540  }
1541 
1548  inline void setSubSubDomainComputationCost(size_t id, size_t weight)
1549  {
1550  dist.setComputationCost(id, weight);
1551  }
1552 
1560  inline size_t getSubSubDomainComputationCost(size_t id)
1561  {
1562  return dist.getSubSubDomainComputationCost(id);
1563  }
1564 
1569  size_t subSize()
1570  {
1571  return dist.subSize();
1572  }
1573 
1579  size_t getNSubDomain()
1580  {
1581  return sub_domains.size();
1582  }
1583 
1592  {
1593  // Create a space box
1594  SpaceBox<dim, T> sp;
1595 
1596  // fill the space box
1597 
1598  for (size_t k = 0; k < dim; k++)
1599  {
1600  // create the SpaceBox Low and High
1601  sp.setLow(k, sub_domains.template get<Box::p1>(lc)[k]);
1602  sp.setHigh(k, sub_domains.template get<Box::p2>(lc)[k]);
1603  }
1604 
1605  return sp;
1606  }
1607 
1616  {
1617  // Create a space box
1618  SpaceBox<dim, T> sp = sub_domains.get(lc);
1619 
1620  // enlarge with ghost
1621  sp.enlarge(ghost);
1622 
1623  return sp;
1624  }
1625 
1631  const ::Box<dim,T> & getDomain() const
1632  {
1633  return domain;
1634  }
1635 
1636  const openfpm::vector<SpaceBox<dim, T>,Memory,layout_base> &
1637  getSubDomains() const
1638  {
1639  return sub_domains;
1640  }
1641 
1651  template<typename Mem> bool isLocal(const encapc<1, Point<dim, T>, Mem> p) const
1652  {
1653  return processorID<Mem>(p) == v_cl.getProcessUnitID();
1654  }
1655 
1665  bool isLocal(const T (&pos)[dim]) const
1666  {
1667  return processorID(pos) == v_cl.getProcessUnitID();
1668  }
1669 
1679  bool isLocal(const Point<dim,T> & pos) const
1680  {
1681  return processorID(pos) == v_cl.getProcessUnitID();
1682  }
1683 
1696  template<typename Mem> bool isLocalBC(const encapc<1, Point<dim,T>, Mem> p, const size_t (& bc)[dim]) const
1697  {
1698  Point<dim,T> pt = p;
1699 
1700  for (size_t i = 0 ; i < dim ; i++)
1701  {
1702  if (bc[i] == PERIODIC)
1703  pt.get(i) = openfpm::math::periodic_l(p.template get<0>()[i],domain.getHigh(i),domain.getLow(i));
1704  }
1705 
1706  return processorID<Mem>(pt) == v_cl.getProcessUnitID();
1707  }
1708 
1721  bool isLocalBC(const Point<dim,T> & p, const size_t (& bc)[dim]) const
1722  {
1723  Point<dim,T> pt = p;
1724 
1725  for (size_t i = 0 ; i < dim ; i++)
1726  {
1727  if (bc[i] == PERIODIC)
1728  pt.get(i) = openfpm::math::periodic_l(p[i],domain.getHigh(i),domain.getLow(i));
1729  }
1730 
1731  return processorID(pt) == v_cl.getProcessUnitID();
1732  }
1733 
1742  {
1744  }
1745 
1769  {
1771  }
1772 
1780  {
1782  }
1783 
1793  {
1795  }
1796 
1808  bool isLocalBC(const T (&p)[dim], const size_t (& bc)[dim]) const
1809  {
1810  Point<dim,T> pt = p;
1811 
1812  for (size_t i = 0 ; i < dim ; i++)
1813  {
1814  if (bc[i] == PERIODIC)
1815  pt.get(i) = openfpm::math::periodic_l(p[i],domain.getHigh(i),domain.getLow(i));
1816  }
1817 
1818  return processorID(pt) == v_cl.getProcessUnitID();
1819  }
1820 
1821 
1828  {
1829  return bbox;
1830  }
1831 
1832 
1839  const Ghost<dim,T> & getGhost() const
1840  {
1841  return ghost;
1842  }
1843 
1849  {
1850  return gr;
1851  }
1852 
1858  {
1859  return gr_dist;
1860  }
1861 
1863 
1882  bool write(std::string output) const
1883  {
1885  VTKWriter<openfpm::vector<SpaceBox<dim, T>,Memory,layout_base>, VECTOR_BOX> vtk_box1;
1886  vtk_box1.add(sub_domains);
1887  vtk_box1.write(output + std::string("subdomains_") + std::to_string(v_cl.getProcessUnitID()) + std::string(".vtk"));
1888 
1892 
1893  return true;
1894  }
1895 
1901  Vcluster<> & getVC() const
1902  {
1903 #ifdef SE_CLASS2
1904  check_valid(this,8);
1905 #endif
1906  return v_cl;
1907  }
1908 
1913  {
1915  }
1916 
1920  void free_fines()
1921  {
1922  fine_s.clear();
1923  fine_s.destroy();
1924  }
1925 
1932  {
1934  return false;
1935 
1936  return true;
1937  }
1938 
1942  void debugPrint()
1943  {
1944  std::cout << "Subdomains\n";
1945  for (size_t p = 0; p < sub_domains.size(); p++)
1946  {
1947  std::cout << ::SpaceBox<dim, T>(sub_domains.get(p)).toString() << "\n";
1948  }
1949 
1950  std::cout << "Subdomains global\n";
1951  for (size_t p = 0; p < sub_domains_global.size(); p++)
1952  {
1953  std::cout << ::SpaceBox<dim, T>(sub_domains_global.template get<0>(p)).toString() << " proc:" << sub_domains_global.template get<1>(p) << "\n";
1954  }
1955 
1956  std::cout << "External ghost box\n";
1957 
1958  for (size_t p = 0; p<nn_prcs < dim, T, layout_base, Memory>::getNNProcessors(); p++)
1959  {
1960  for (size_t i = 0; i<ie_ghost <dim,T,Memory,layout_base>::getProcessorNEGhost(p); i++)
1961  {
1962  std::cout << ie_ghost<dim,T,Memory,layout_base>::getProcessorEGhostBox(p, i).toString() << " prc=" << nn_prcs<dim, T, layout_base,Memory>::IDtoProc(p) << " id=" << ie_ghost<dim,T,Memory,layout_base>::getProcessorEGhostId(p, i) << "\n";
1963  }
1964  }
1965 
1966  std::cout << "Internal ghost box\n";
1967 
1968  for (size_t p = 0; p<nn_prcs < dim, T, layout_base, Memory>::getNNProcessors(); p++)
1969  {
1970  for (size_t i = 0; i<ie_ghost<dim,T,Memory,layout_base>::getProcessorNIGhost(p); i++)
1971  {
1972  std::cout << ie_ghost<dim,T,Memory,layout_base>::getProcessorIGhostBox(p, i).toString() << " prc=" << nn_prcs<dim, T, layout_base, Memory>::IDtoProc(p) << " id=" << ie_ghost<dim,T,Memory,layout_base>::getProcessorIGhostId(p, i) << "\n";
1973  }
1974  }
1975  }
1976 
1985  {
1986  if (static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->is_equal(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>&>(cart)) == false)
1987  return false;
1988 
1989  if (static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->is_equal(static_cast<nn_prcs<dim,T, layout_base,Memory>&>(cart)) == false)
1990  return false;
1991 
1992  if (static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->is_equal(static_cast<ie_ghost<dim,T,Memory,layout_base>&>(cart)) == false)
1993  return false;
1994 
1995  if (sub_domains != cart.sub_domains)
1996  return false;
1997 
1998  if (box_nn_processor != cart.box_nn_processor)
1999  return false;
2000 
2001  if (fine_s != cart.fine_s)
2002  return false;
2003 
2004  if (gr != cart.gr)
2005  return false;
2006 
2007  if (cd != cart.cd)
2008  return false;
2009 
2010  if (domain != cart.domain)
2011  return false;
2012 
2013  if (meta_compare<T[dim]>::meta_compare_f(cart.spacing,spacing) == false)
2014  return false;
2015 
2016  if (ghost != cart.ghost)
2017  return false;
2018 
2019  return true;
2020  }
2021 
2031  {
2032  if (static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->is_equal_ng(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>&>(cart)) == false)
2033  return false;
2034 
2035  if (static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->is_equal(static_cast<nn_prcs<dim,T,layout_base,Memory>&>(cart)) == false)
2036  return false;
2037 
2038  if (static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->is_equal_ng(static_cast<ie_ghost<dim,T,Memory,layout_base>&>(cart)) == false)
2039  return false;
2040 
2041  if (sub_domains != cart.sub_domains)
2042  return false;
2043 
2044  if (box_nn_processor != cart.box_nn_processor)
2045  return false;
2046 
2047  if (fine_s != cart.fine_s)
2048  return false;
2049 
2050  if (gr != cart.gr)
2051  return false;
2052 
2053  if (cd != cart.cd)
2054  return false;
2055 
2056  if (domain != cart.domain)
2057  return false;
2058 
2059  if (meta_compare<T[dim]>::meta_compare_f(cart.spacing,spacing) == false)
2060  return false;
2061 
2062  return true;
2063  }
2064 
2070  Distribution & getDistribution()
2071  {
2072  return dist;
2073  }
2074 
2075 
2081  inline void addComputationCost(size_t gid, size_t i)
2082  {
2083  size_t c = dist.getSubSubDomainComputationCost(gid);
2084 
2085  dist.setComputationCost(gid, c + i);
2086  }
2087 
2093  size_t get_ndec()
2094  {
2095  return dist.get_ndec();
2096  }
2097 
2103  const CellDecomposer_sm<dim, T, shift<dim,T>> & getCellDecomposer()
2104  {
2105  return cd;
2106  }
2107 
2108 
2115  {
2116  if (host_dev_transfer == false)
2117  {
2118  fine_s.hostToDevice();
2119  sub_domains_global.template hostToDevice<0,1>();
2120  host_dev_transfer = true;
2121  }
2122 
2123  int bc_[dim];
2124 
2125  for (int i = 0 ; i < dim ; i++) {bc_[i] = this->periodicity(i);}
2126 
2129  sub_domains_global.toKernel(),
2130  getDomain(),
2131  bc_);
2132 
2133  return cdg;
2134  }
2135 
2138 
2145  {
2146  return sub_domains;
2147  }
2148 
2155  {
2156  return sub_domains;
2157  }
2158 
2165  {
2166  return box_nn_processor;
2167  }
2168 
2175  {
2176  return box_nn_processor;
2177  }
2178 
2185  {
2186  return fine_s;
2187  }
2188 
2195  {
2196  return fine_s;
2197  }
2198 
2205  {
2206  return gr;
2207  }
2208 
2215  {
2216  return gr;
2217  }
2218 
2225  {
2226  return gr_dist;
2227  }
2228 
2235  {
2236  return gr_dist;
2237  }
2238 
2244  Distribution & private_get_dist()
2245  {
2246  return dist;
2247  }
2248 
2254  const Distribution & private_get_dist() const
2255  {
2256  return dist;
2257  }
2258 
2265  {
2266  return commCostSet;
2267  }
2268 
2274  const bool & private_get_commCostSet() const
2275  {
2276  return commCostSet;
2277  }
2278 
2284  CellDecomposer_sm<dim, T, shift<dim,T>> & private_get_cd()
2285  {
2286  return cd;
2287  }
2288 
2294  const CellDecomposer_sm<dim, T, shift<dim,T>> & private_get_cd() const
2295  {
2296  return cd;
2297  }
2298 
2305  {
2306  return domain;
2307  }
2308 
2314  const ::Box<dim,T> & private_get_domain() const
2315  {
2316  return domain;
2317  }
2318 
2325  {
2326  return sub_domains_global;
2327  }
2328 
2335  {
2336  return sub_domains_global;
2337  }
2338 
2345  {
2346  return spacing[i];
2347  }
2348 
2354  const T & private_get_spacing(int i) const
2355  {
2356  return spacing[i];
2357  }
2358 
2364  T & private_get_magn(int i)
2365  {
2366  return spacing[i];
2367  }
2368 
2374  const T & private_get_magn(int i) const
2375  {
2376  return spacing[i];
2377  }
2378 
2379 
2386  {
2387  return ghost;
2388  }
2389 
2396  {
2397  return ghost;
2398  }
2399 
2406  {
2407  return bbox;
2408  }
2409 
2415  const ::Box<dim,T> & private_get_bbox() const
2416  {
2417  return bbox;
2418  }
2419 
2425  size_t & private_get_bc(int i)
2426  {
2427  return bc[i];
2428  }
2429 
2435  const size_t & private_get_bc(int i) const
2436  {
2437  return bc[i];
2438  }
2439 };
2440 
2441 
2442 #endif
size_t getNSubDomain()
Get the number of local sub-domains.
size_t get_ndec()
Get the decomposition counter.
openfpm::vector< SpaceBox< dim, T >, Memory, memory_traits_lin, openfpm::vector_grow_policy_default, openfpm::vect_isel< SpaceBox< dim, T > >::value >::access_key acc_key
openfpm::vector< Box_map< dim, T >, Memory, layout_base > & private_get_sub_domains_global()
Return the internal data structure sub_domains_global.
openfpm::vector< openfpm::vector< long unsigned int > > & private_get_box_nn_processor()
Return the internal data structure box_nn_processor.
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
size_t & private_get_bc(int i)
Return the internal data structure bc.
void addCell(size_t cell_id, typename Mem_type::local_index_type ele)
Add to the cell.
Definition: CellList.hpp:715
static size_t id(const encap_type &p, size_t b_id)
Return the near processor id.
openfpm::vector< openfpm::vector< long unsigned int > > box_nn_processor
for each sub-domain, contain the list of the neighborhood processors
Ghost< dim, T > ghost
ghost info
CartDecomposition_ext< dim, T, Memory, layout_base, Distribution > extended_type
This class admit a class defined on an extended domain.
const openfpm::vector< Box_map< dim, T >, Memory, layout_base > & private_get_sub_domains_global() const
Return the internal data structure sub_domains_global.
const bool & private_get_commCostSet() const
Return the internal data structure commCostSet.
Transform the boost::fusion::vector into memory specification (memory_traits)
openfpm::vector< size_t > & getCRSDomainCells()
Get the CRS domain Cells with normal neighborhood.
SpaceBox< dim, T > convertDecBoxIntoSubDomain(encapc< 1,::Box< dim, size_t >, Memory_bx > loc_box)
It convert the box from the domain decomposition into sub-domain.
long int ref_cnt
reference counter of the object in case is shared between object
void getSubSubDomainPosition(size_t id, T(&pos)[dim])
function that return the position of the cell in the space
bool check_consistency()
function to check the consistency of the information of the decomposition
Heuristic getHeurisitc()
Get the heuristic.
Definition: DLB.hpp:190
size_t getProcessUnitID()
Get the process unit id.
bool write(std::string output) const
Write the decomposition as VTK file.
openfpm::vector< size_t > & getDomainCells()
Get the domain Cells.
size_t processorID(const encapc< 1, Point< dim, T >, Mem > &p) const
Given a point return in which processor the particle should go.
This class decompose a space into sub-sub-domains and distribute them across processors.
::Box< dim, T > & private_get_domain()
Return the internal data structure domain.
openfpm::vector< subsub_lin< dim > > & getCRSAnomDomainCells()
Get the domain anomalous cells.
void setParameters(const Box< dim, long int > &proc_box)
Set parameters to calculate the cell neighborhood.
Distribution & getDistribution()
Return the distribution object.
size_t getProcessorEGhostId(size_t id, size_t j) const
Get the j External ghost box id.
Definition: ie_ghost.hpp:804
bool is_equal_ng(CartDecomposition< dim, T, Memory > &cart)
Check if the CartDecomposition contain the same information with the exception of the ghost part It i...
void create_box_nn_processor_int(Vcluster<> &v_cl, Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const nn_prcs< dim, T, layout_base, Memory > &nn_p)
Create the box_nn_processor_int (nbx part) structure, the geo_cell list and proc_int_box.
Definition: ie_ghost.hpp:348
CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > & private_get_fine_s()
Return the internal data structure fine_s.
void setNNParameters(openfpm::vector<::Box< dim, size_t >> &loc_box, const grid_key_dx< dim > &shift, const grid_sm< dim, void > &gs)
Set parameters to calculate the cell neighborhood.
__device__ __host__ size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:637
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:556
Distribution & private_get_dist()
Return the internal data structure dist.
::Box< dim, T > bbox
Processor bounding box.
CartDecomposition< dim, T, Memory, layout_base, Distribution > & operator=(const CartDecomposition &cart)
Copy the element.
void mul(T(&sp)[dim])
multiply the space box with the coefficient defined in sp
Definition: SpaceBox.hpp:178
void Initialize_geo_cell_lists()
Initialize geo_cell lists.
T spacing[dim]
Box Spacing.
const CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > & private_get_fine_s() const
Return the internal data structure fine_s.
Ghost< dim, T > & private_get_ghost()
Return the internal data structure ghost.
void CreateSubspaces()
Create the sub-domain that decompose your domain.
void clear()
Clear the cell list.
Definition: CellList.hpp:1100
bool write(std::string output, size_t p_id) const
Write the decomposition as VTK file.
Vcluster & v_cl
Runtime virtual cluster machine.
friend extended_type
friend classes
const Ghost< dim, T > & private_get_ghost() const
Return the internal data structure ghost.
void computeCommunicationAndMigrationCosts(size_t ts)
Calculate communication and migration costs.
void reset()
Reset the nn_prcs structure.
void reset()
Delete the decomposition and reset the data-structure.
::Box< dim, T > domain
rectangular domain to decompose
size_t processorID(const Point< dim, T > &p) const
Given a point return in which processor the particle should go.
void create(openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, Box< dim, T > &domain, Ghost< dim, T > &ghost, const size_t(&bc)[dim])
Create external and internal local ghosts.
void destroy()
Litterary destroy the memory of the cell list, including the retained one.
Definition: CellList.hpp:1108
openfpm::vector< SpaceBox< dim, T > > & private_get_sub_domains()
Return the internal data structure sub_domains.
grid_key_dx< dim > one
key with all coordinates set to one
bool write(std::string output) const
Write the decomposition as VTK file.
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
SpaceBox< dim, T > getSubDomainWithGhost(size_t lc)
Get the local sub-domain enlarged with ghost extension.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
const grid_sm< dim, void > & private_get_gr_dist() const
Return the internal data structure gr_dist.
grow_policy_double vector_grow_policy_default
default grow policy
void free_geo_cell()
Deallocate structures that identify a point to which internal ghost is located.
size_t size()
Stub size.
Definition: map_vector.hpp:211
size_t getSubSubDomainComputationCost(size_t id)
function that return the computation cost of the sub-sub-domain id
CartDecomposition< dim, T, Memory, layout_base, Distribution > duplicate(const Ghost< dim, T > &g) const
It create another object that contain the same decomposition information but with different ghost box...
bool rebalanceNeeded()
check if a re-balance is needed using the selected heuristic
Definition: DLB.hpp:200
grid_sm< dim, void > & private_get_gr()
Return the internal data structure gr.
void setParameters(const size_t(&div_)[dim], ::Box< dim, T > &domain_, const size_t(&bc)[dim], const Ghost< dim, T > &ghost, const grid_sm< dim, void > &sec_dist=grid_sm< dim, void >())
Set the parameter of the decomposition.
const grid_sm< dim, void > & getGrid()
Return the underlying grid information of the cell list.
Definition: CellList.hpp:447
grid_sm< dim, void > & private_get_gr_dist()
Return the internal data structure gr_dist.
CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > fine_s
bool isLocal(const T(&pos)[dim]) const
Check if the particle is local.
const ::Box< dim, T > & getDomain() const
Return the box of the physical domain.
CartDecomposition< dim, T, Memory, layout_base, Distribution > duplicate() const
It create another object that contain the same information and act in the same way.
const openfpm::vector< openfpm::vector< long unsigned int > > & private_get_box_nn_processor() const
Return the internal data structure box_nn_processor.
void createSubdomains(Vcluster<> &v_cl, const size_t(&bc)[dim], size_t opt=0)
Constructor, it decompose and distribute the sub-domains across the processors.
void expand(T(&exp)[dim])
expand the box by a vector
Definition: Box.hpp:793
class to select the returned id by ghost_processorID
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
void decRef()
Decrement the reference counter.
Definition: Ghost.hpp:39
void setSubSubDomainComputationCost(size_t id, size_t weight)
Function that set the computational cost for a of a sub-sub domain.
Implementation of VCluster class.
Definition: VCluster.hpp:58
SpaceBox< dim, T > Box
It simplify to access the SpaceBox element.
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:544
CartDecomposition(const CartDecomposition< dim, T, Memory, layout_base, Distribution > &cart)
Cartesian decomposition copy constructor.
void Initialize_geo_cell(const Box< dim, T > &domain, const size_t(&div)[dim])
Initialize the geo cell list structure.
Definition: ie_ghost.hpp:217
void execute()
Execute all the requests.
const CellDecomposer_sm< dim, T, shift< dim, T > > & getCellDecomposer()
Get the cell decomposer of the decomposition.
Distribution dist
Create distribution.
void setNNParameters(grid_key_dx< dim > &shift, grid_sm< dim, void > &gs)
set NN parameters to calculate cell-list neighborhood
void free_geo_cell()
Deallocate structures that identify a point to which internal ghost is located.
Definition: ie_ghost.hpp:226
CellDecomposer_sm< dim, T, shift< dim, T > > cd
openfpm::vector< size_t > & getCRSDomainCells()
Get the domain Cells.
void generateShiftVectors(const Box< dim, T > &domain, size_t(&bc)[dim])
Here we generare the shift vectors.
Definition: ie_ghost.hpp:196
void reset()
Reset the ie_loc_ghost.
::Box< dim, T > & getProcessorBounds()
Return the bounding box containing union of all the sub-domains for the local processor.
void applyBC(const Box< dim, T > &domain, const Ghost< dim, T > &ghost, const size_t(&bc)[dim])
Apply boundary conditions.
static size_t id(const encap_type &p, size_t b_id)
Return the shift id.
size_t getNTimeStepSinceDLB()
Get how many time-steps have passed since the last re-balancing.
Definition: DLB.hpp:309
const size_t & private_get_bc(int i) const
Return the internal data structure bc.
grid_sm< dim, void > gs
Processor cells-grid.
size_t getProcessorLoad()
Compute the processor load counting the total weights of its vertices.
bool write(std::string output, size_t p_id) const
write the information about the ghost in vtk format
Definition: ie_ghost.hpp:1162
bool SGather(T &send, S &recv, size_t root)
Semantic Gather, gather the data from all processors into one node.
Definition: VCluster.hpp:450
T & private_get_spacing(int i)
Return the internal data structure spacing.
void calculate_magn(const grid_sm< dim, void > &gm)
Calculate magnification.
This class decompose a space into sub-sub-domains and distribute them across processors.
void enclose(const Box< dim, T > &en)
Refine the box to enclose the given box and itself.
Definition: Box.hpp:935
size_t processorID(const T(&p)[dim]) const
Given a point return in which processor the particle should go.
size_t getNSubSubDomains()
Get the number of sub-sub-domains in this sub-graph.
~CartDecomposition()
Cartesian decomposition destructor.
bool host_dev_transfer
bool that indicate whenever the buffer has been already transfer to device
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
void addComputationCost(size_t gid, size_t i)
Add computation cost i to the subsubdomain with global id gid.
sub-domain edge graph node
CartDecomposition< dim, T, Memory, layout_base, Distribution > base_type
This class is base of itself.
It analyze the type given and it select correctly the implementation for vector.
Definition: vect_isel.hpp:36
const grid_key_dx< dim > & get() const
Get the actual key.
size_t bc[dim]
Boundary condition info.
structure that store and compute the internal and external local ghost box
Definition: ie_ghost.hpp:47
const size_t(& periodicity() const)[dim]
Get the periodicity.
size_t rank()
Get the process unit id.
openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > sub_domains
the set of all local sub-domain as vector
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:533
const openfpm::vector< SpaceBox< dim, T > > & private_get_sub_domains() const
Return the internal data structure sub_domains.
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:823
const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:740
void CalculateInternalCells(VCluster_type &v_cl, openfpm::vector< Box< dim, T >, Memory, layout_base > &ig_box, openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &domain, Box< dim, T > &pbox, T r_cut, const Ghost< dim, T > &enlarge)
Calculate the subdomain that are in the skin part of the domain.
void reset()
In case you have to recompute the indexes.
void reset_host_dev_transfer()
Notify that the next toKernel() data-structures must be re-offloaded.
Definition: ie_ghost.hpp:1548
class to select the returned id by ghost_processorID
size_t processorIDBC(const T(&p)[dim]) const
Given a point return in which processor the particle should go.
::Box< dim, size_t > proc_box
Processor domain bounding box.
void applyPointBC(encapc< 1, Point< dim, T >, Mem > &&pt) const
Apply boundary condition to the point.
void debugPrint()
Print subdomains, external and internal ghost boxes.
bool isLocal(const encapc< 1, Point< dim, T >, Mem > p) const
Check if the particle is local.
size_t getProcessingUnits()
Get the total number of processors.
void redecompose(size_t ts)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call.
void Initialize(CellDecomposer_sm< dim, T, transform > &cd_sm, const Box< dim, T > &dom_box, const size_t pad=1, size_t slot=STARTING_NSLOT)
Definition: CellList.hpp:465
size_t IDtoProc(size_t id) const
Return the processor id of the near processor list at place id.
openfpm::vector< size_t > & getDomainCells()
Get the domain Cells.
void decompose(dec_options opt=dec_options::DEC_NONE)
Start decomposition.
void calculateGhostBoxes()
It calculate the internal ghost boxes.
T & private_get_magn(int i)
Return the internal data structure magn.
Vcluster & getVC() const
Get the Virtual Cluster machine.
void free_fines()
Deallocate structures that identify a point to which internal ghost is located.
const T & private_get_spacing(int i) const
Return the internal data structure spacing.
const T & private_get_magn(int i) const
Return the internal data structure magn.
This class compare general objects.
bool is_equal(CartDecomposition< dim, T, Memory > &cart)
Check if the CartDecomposition contain the same information.
size_t getProcessorIGhostId(size_t id, size_t j) const
Get the j Internal ghost box id.
Definition: ie_ghost.hpp:788
void create(const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains)
Create the list of adjacent processors and the list of adjacent sub-domains.
bool commCostSet
Indicate the communication weight has been set.
bool isLocalBC(const T(&p)[dim], const size_t(&bc)[dim]) const
Check if the particle is local considering boundary conditions.
size_t periodicity(size_t i) const
Get the periodicity on i dimension.
Definition: DLB.hpp:53
static constexpr int dims
Space dimensions.
openfpm::vector< Box_map< dim, T >, Memory, layout_base > sub_domains_global
the remote set of all sub-domains as vector of 'sub_domains' vectors
This class take a graph representing the space decomposition and produce a simplified version.
T domain_type
Type of the domain we are going to decompose.
structure that store and compute the internal and external local ghost box
void incRef()
Increment the reference counter.
bool & private_get_commCostSet()
Return the internal data structure commCostSet.
class to select the returned id by ghost_processorID
CartDecomposition< dim, T, Memory, layout_base, Distribution > & operator=(const CartDecomposition2 &cart)
Copy the element.
static size_t id(p_box< dim, T > &p, size_t b_id)
Return the box id.
size_t processorIDBC(const Point< dim, T > &p) const
Given a point return in which processor the particle should go.
void swap(CellList< dim, T, Mem_type, transform, vector_pos_type > &cl)
Swap the memory.
Definition: CellList.hpp:892
bool refine(DLB &dlb)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call.
grid_sm< dim, void > gr_dist
Structure that store the cartesian grid information.
CartDecomposition(Vcluster<> &v_cl)
Cartesian decomposition constructor.
bool Bcast(openfpm::vector< T, Mem, layout_base > &v, size_t root)
Broadcast the data to all processors.
const ::Box< dim, T > & private_get_domain() const
Return the internal data structure domain.
static size_t id(const encap_type &p, size_t b_id)
Return the processor id.
static bool check_valid(comb< dim > cmb, const size_t(&bc)[dim])
void applyPointBC(Point< dim, T > &pt) const
Apply boundary condition to the point.
This class calculate processor domains and neighborhood of each processor domain.
void create_box_nn_processor_ext(Vcluster<> &v_cl, Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const nn_prcs< dim, T, layout_base, Memory > &nn_p)
Create the box_nn_processor_int (bx part) structure.
Definition: ie_ghost.hpp:246
const grid_sm< dim, void > getGrid()
Decomposition grid.
const grid_sm< dim, void > getDistGrid()
Distribution grid.
bool isLocalBC(const encapc< 1, Point< dim, T >, Mem > p, const size_t(&bc)[dim]) const
Check if the particle is local considering boundary conditions.
const CellDecomposer_sm< dim, T, shift< dim, T > > & private_get_cd() const
Return the internal data structure cd.
void refine(size_t ts)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call.
openfpm::vector< subsub_lin< dim > > & getCRSAnomDomainCells()
Get the CRS anomalous cells.
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
CellDecomposer_sm< dim, T, shift< dim, T > > & private_get_cd()
Return the internal data structure cd.
size_t processorIDBC(encapc< 1, Point< dim, T >, Mem > p)
Given a point return in which processor the point/particle should go.
const ::Box< dim, T > & private_get_bbox() const
Return the internal data structure bbox.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:214
class to select the returned id by ghost_processorID
void getParameters(size_t(&div_)[dim])
return the parameters of the decomposition
float getUnbalance()
Get the current un-balance value.
It store all the boxes of the near processors in a linear array.
Definition: common.hpp:299
CartDecomposition< dim, T, Memory2, layout_base2, Distribution > duplicate_convert() const
It create another object that contain the same information and act in the same way.
SpaceBox< dim, T > getSubDomain(size_t lc)
Get the local sub-domain.
CartDecomposition< dim, T, Memory, layout_base, Distribution > & operator=(CartDecomposition &&cart)
Copy the element, move semantic.
CartDecomposition(CartDecomposition< dim, T, Memory, layout_base, Distribution > &&cart)
Cartesian decomposition copy constructor.
bool isLocal(const Point< dim, T > &pos) const
Check if the particle is local.
bool isValidN() const
Check if the Box is a valid box P2 > P1.
Definition: Box.hpp:1196
CartDecomposition_gpu< dim, T, Memory, layout_base > toKernel()
convert to a structure usable in a device kernel
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
size_t subSize()
Operator to access the size of the sub-graph.
long int ref()
Return the reference counter.
void setGoodParameters(::Box< dim, T > &domain_, const size_t(&bc)[dim], const Ghost< dim, T > &ghost, size_t dec_gran, const grid_sm< dim, void > &sec_dist=grid_sm< dim, void >())
Set the best parameters for the decomposition.
Class for FAST cell list implementation.
Definition: CellList.hpp:356
const grid_sm< dim, void > & private_get_gr() const
Return the internal data structure gr.
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567
Definition: ids.hpp:148
bool isNext()
Check if there is the next element.
::Box< dim, T > & private_get_bbox()
Return the internal data structure bbox.
const Ghost< dim, T > & getGhost() const
Return the ghost.
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition: grid_sm.hpp:326
void applyPointBC(float(&pt)[dim]) const
Apply boundary condition to the point.
const Distribution & private_get_dist() const
Return the internal data structure dist.
ie_ghost_gpu< dim, T, Memory, layout_base > toKernel()
toKernel() Convert this data-structure into a kernel usable data-structure
Definition: ie_ghost.hpp:1525
bool isLocalBC(const Point< dim, T > &p, const size_t(&bc)[dim]) const
Check if the particle is local considering boundary conditions.
static size_t getDefaultGrid(size_t n_sub)
The default grid size.
void setUnbalance(float u)
Set un-balance value.
Definition: DLB.hpp:318
void reset()
Reset the nn_prcs structure.
Definition: ie_ghost.hpp:1278
openfpm::vector<::Box< dim, size_t > > loc_box
set of Boxes produced by the decomposition optimizer
This class store the adjacent processors and the adjacent sub_domains.