OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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 
42 #define CARTDEC_ERROR 2000lu
43 
55 template<unsigned int dim> static void nsub_to_div2(size_t (& div)[dim], size_t n_sub, size_t dim_r)
56 {
57  for (size_t i = 0; i < dim; i++)
58  {
59  if (i < dim_r)
60  {div[i] = openfpm::math::round_big_2(pow(n_sub, 1.0 / dim_r));}
61  else
62  {div[i] = 1;}
63  }
64 }
65 
77 template<unsigned int dim> static void nsub_to_div(size_t (& div)[dim], size_t n_sub, size_t dim_r)
78 {
79  for (size_t i = 0; i < dim; i++)
80  {
81  if (i < dim_r)
82  {div[i] = std::floor(pow(n_sub, 1.0 / dim_r));}
83  else
84  {div[i] = 1;}
85  }
86 }
87 
88 #define COMPUTE_SKIN_SUB 1
89 
131 template<unsigned int dim, typename T, typename Memory, typename Distribution>
132 class CartDecomposition: public ie_loc_ghost<dim, T>, public nn_prcs<dim, T>, public ie_ghost<dim, T>, public domain_nn_calculator_cart<dim>
133 {
134 
135 public:
136 
138  typedef T domain_type;
139 
142 
145 
148 
149 protected:
150 
152  bool commCostSet = false;
153 
156  typedef typename openfpm::vector<SpaceBox<dim, T>,
157  Memory,
158  typename memory_traits_lin<SpaceBox<dim, T>>::type,
162 
165 
168 
171 
175 
178 
181 
184  CellDecomposer_sm<dim, T, shift<dim,T>> cd;
185 
188 
190  T spacing[dim];
191 
194  size_t magn[dim];
195 
198 
200  Distribution dist;
201 
204 
206  long int ref_cnt;
207 
210 
212  size_t bc[dim];
213 
216 
219 
231  template<typename Memory_bx> SpaceBox<dim,T> convertDecBoxIntoSubDomain(encapc<1,::Box<dim,size_t>,Memory_bx> loc_box)
232  {
233  // A point with all coordinate to one
234  size_t one[dim];
235  for (size_t i = 0 ; i < dim ; i++) {one[i] = 1;}
236 
238  SpaceBox<dim, size_t> sub_dce = sub_dc;
239  sub_dce.expand(one);
240  sub_dce.mul(magn);
241 
242  // shrink by one
243  for (size_t i = 0 ; i < dim ; i++)
244  {
245  loc_box.template get<Box::p1>()[i] = sub_dce.getLow(i);
246  loc_box.template get<Box::p2>()[i] = sub_dce.getHigh(i) - 1;
247  }
248 
249  SpaceBox<dim, T> sub_d(sub_dce);
250  sub_d.mul(spacing);
251  sub_d += domain.getP1();
252 
253  // we add the
254 
255  // Fixing sub-domains to cover all the domain
256 
257  // Fixing sub_d
258  // if (loc_box) is at the boundary we have to ensure that the box span the full
259  // domain (avoiding rounding off error)
260  for (size_t i = 0; i < dim; i++)
261  {
262  if (sub_dc.getHigh(i) == gr.size(i) - 1)
263  {sub_d.setHigh(i, domain.getHigh(i));}
264 
265  if (sub_dc.getLow(i) == 0)
266  {sub_d.setLow(i,domain.getLow(i));}
267  }
268 
269  return sub_d;
270  }
271 
272 
273 public:
274 
282  void createSubdomains(Vcluster & v_cl, const size_t (& bc)[dim], size_t opt = 0)
283  {
284  int p_id = v_cl.getProcessUnitID();
285 
286  // Calculate the total number of box and and the spacing
287  // on each direction
288  // Get the box containing the domain
289  SpaceBox<dim, T> bs = domain.getBox();
290 
291  for (unsigned int i = 0; i < dim; i++)
292  {
293  // Calculate the spacing
294  spacing[i] = (bs.getHigh(i) - bs.getLow(i)) / gr.size(i);
295  }
296 
297  // fill the structure that store the processor id for each sub-domain
298  fine_s.resize(gr.size());
299 
300  // Optimize the decomposition creating bigger spaces
301  // And reducing Ghost over-stress
303 
304  // Ghost
306 
307  // Set the ghost
308  for (size_t i = 0 ; i < dim ; i++)
309  {
310  ghe.setLow(i,static_cast<long int>(ghost.getLow(i)/spacing[i]) - 1);
311  ghe.setHigh(i,static_cast<long int>(ghost.getHigh(i)/spacing[i]) + 1);
312  }
313 
314  // optimize the decomposition
315  d_o.template optimize<nm_v::sub_id, nm_v::proc_id>(dist.getGraph(), p_id, loc_box, box_nn_processor,ghe,bc);
316 
317  // Initialize
318  if (loc_box.size() > 0)
319  {
320  bbox = convertDecBoxIntoSubDomain(loc_box.get(0));
321  proc_box = loc_box.get(0);
322  sub_domains.add(bbox);
323  }
324  else
325  {
326  // invalidate all the boxes
327  for (size_t i = 0 ; i < dim ; i++)
328  {
329  proc_box.setLow(i,0.0);
330  proc_box.setHigh(i,0);
331 
332  bbox.setLow(i,0.0);
333  bbox.setHigh(i,0);
334  }
335  }
336 
337  // convert into sub-domain
338  for (size_t s = 1; s < loc_box.size(); s++)
339  {
340  SpaceBox<dim,T> sub_d = convertDecBoxIntoSubDomain(loc_box.get(s));
341 
342  // add the sub-domain
343  sub_domains.add(sub_d);
344 
345  // Calculate the bound box
346  bbox.enclose(sub_d);
347  proc_box.enclose(loc_box.get(s));
348  }
349 
350  nn_prcs<dim,T>::create(box_nn_processor, sub_domains);
352 
353  // fill fine_s structure
354  // fine_s structure contain the processor id for each sub-sub-domain
355  // with sub-sub-domain we mean the sub-domain decomposition before
356  // running dec_optimizer (before merging sub-domains)
357 
358 
360 
361  while (git.isNext())
362  {
363  auto key = git.get();
364  grid_key_dx<dim> key2;
365 
366  for (size_t i = 0 ; i < dim ; i++)
367  key2.set_d(i,key.get(i) / magn[i]);
368 
369  size_t lin = gr_dist.LinId(key2);
370  size_t lin2 = gr.LinId(key);
371 
372  fine_s.get(lin2) = dist.getGraph().template vertex_p<nm_v::proc_id>(lin);
373 
374  ++git;
375  }
376 
378  }
379 
386  {
387  // Get the processor bounding Box
389 
390  // Check if the box is valid
391  if (bound.isValidN() == true)
392  {
393  // Not necessary, but I prefer
394  bound.enlarge(ghost);
395 
396  // calculate the sub-divisions
397  size_t div[dim];
398  for (size_t i = 0; i < dim; i++)
399  {div[i] = (size_t) ((bound.getHigh(i) - bound.getLow(i)) / cd.getCellBox().getP2()[i]);}
400 
401  // Initialize the geo_cell structure
403 
404  // Initialize shift vectors
406  }
407  }
408 
414  {
415  float migration = 0;
416 
417  SpaceBox<dim, T> cellBox = cd.getCellBox();
418  float b_s = static_cast<float>(cellBox.getHigh(0));
419  float gh_s = static_cast<float>(ghost.getHigh(0));
420 
421  // compute the gh_area for 2 dim case
422  float gh_v = (gh_s * b_s);
423 
424  // multiply for sub-sub-domain side for each domain
425  for (size_t i = 2; i < dim; i++)
426  {
427  /* coverity[dead_error_line] */
428  gh_v *= b_s;
429  }
430 
431  size_t norm = (size_t) (1.0 / gh_v);
432 
433  migration = pow(b_s, dim);
434 
435  size_t prev = 0;
436 
437  for (size_t i = 0; i < dist.getNSubSubDomains(); i++)
438  {
439  dist.setMigrationCost(i, norm * migration /* * dist.getSubSubDomainComputationCost(i)*/ );
440 
441  for (size_t s = 0; s < dist.getNSubSubDomainNeighbors(i); s++)
442  {
443  // We have to remove dist.getSubSubDomainComputationCost(i) otherwise the graph is
444  // not directed
445  dist.setCommunicationCost(i, s, 1 * ts);
446  }
447  prev += dist.getNSubSubDomainNeighbors(i);
448  }
449 
450  commCostSet = true;
451  }
452 
457  {
458  // Create a grid where each point is a space
459  grid_sm<dim, void> g(div);
460 
461  // create a grid_key_dx iterator
462  grid_key_dx_iterator<dim> gk_it(g);
463 
464  // Divide the space into subspaces
465  while (gk_it.isNext())
466  {
468  grid_key_dx<dim> key = gk_it.get();
469 
471  SpaceBox<dim, T> tmp;
472 
474  for (int i = 0; i < dim; i++)
475  {
476  tmp.setHigh(i, (key.get(i) + 1) * spacing[i]);
477  tmp.setLow(i, key.get(i) * spacing[i]);
478  }
479 
481  sub_domains.add(tmp);
482 
483  // Next sub-domain
484  ++gk_it;
485  }
486  }
487 
488 
583  {
584  // Intersect all the local sub-domains with the sub-domains of the contiguous processors
585 
586  // create the internal structures that store ghost information
589 
591  }
592 
593 public:
594 
596  static constexpr int dims = dim;
597 
599  typedef T stype;
600 
602  void incRef()
603  {ref_cnt++;}
604 
606  void decRef()
607  {ref_cnt--;}
608 
610  long int ref()
611  {
612  return ref_cnt;
613  }
614 
621  :nn_prcs<dim, T>(v_cl), v_cl(v_cl), dist(v_cl),ref_cnt(0)
622  {
623  // Reset the box to zero
624  bbox.zero();
625  }
626 
633  :nn_prcs<dim,T>(cart.v_cl),v_cl(cart.v_cl),dist(v_cl),ref_cnt(0)
634  {
635  this->operator=(cart);
636  }
637 
644  :nn_prcs<dim,T>(cart.v_cl),v_cl(cart.v_cl),dist(v_cl),ref_cnt(0)
645  {
646  this->operator=(cart);
647  }
648 
651  {
652  }
653 
657  class box_id
658  {
659  public:
668  inline static size_t id(p_box<dim, T> & p, size_t b_id)
669  {
670  return b_id;
671  }
672  };
673 
678  {
679  public:
688  inline static size_t id(p_box<dim, T> & p, size_t b_id)
689  {
690  return p.proc;
691  }
692  };
693 
698  {
699  public:
708  inline static size_t id(p_box<dim, T> & p, size_t b_id)
709  {
710  return p.lc_proc;
711  }
712  };
713 
717  class shift_id
718  {
719  public:
728  inline static size_t id(p_box<dim,T> & p, size_t b_id)
729  {
730  return p.shift_id;
731  }
732  };
733 
743  void applyPointBC(float (& pt)[dim]) const
744  {
745  for (size_t i = 0 ; i < dim ; i++)
746  {
747  if (bc[i] == PERIODIC)
748  pt[i] = openfpm::math::periodic_l(pt[i],domain.getHigh(i),domain.getLow(i));
749  }
750  }
751 
761  void applyPointBC(Point<dim,T> & pt) const
762  {
763  for (size_t i = 0 ; i < dim ; i++)
764  {
765  if (bc[i] == PERIODIC)
766  pt.get(i) = openfpm::math::periodic_l(pt.get(i),domain.getHigh(i),domain.getLow(i));
767  }
768  }
769 
779  template<typename Mem> void applyPointBC(encapc<1,Point<dim,T>,Mem> && pt) const
780  {
781  for (size_t i = 0 ; i < dim ; i++)
782  {
783  if (bc[i] == PERIODIC)
784  pt.template get<0>()[i] = openfpm::math::periodic_l(pt.template get<0>()[i],domain.getHigh(i),domain.getLow(i));
785  }
786  }
787 
796  {
798 
800  cart.sub_domains = sub_domains;
801  cart.fine_s = fine_s;
802 
803  cart.gr = gr;
804  cart.cd = cd;
805  cart.domain = domain;
806  for (size_t i = 0 ; i < dim ; i++)
807  {cart.spacing[i] = spacing[i];};
808 
809  cart.bbox = bbox;
810  cart.ghost = g;
811 
812  cart.dist = dist;
813 
814  for (size_t i = 0 ; i < dim ; i++)
815  cart.bc[i] = bc[i];
816 
817  (static_cast<nn_prcs<dim,T> &>(cart)).create(box_nn_processor, sub_domains);
818  (static_cast<nn_prcs<dim,T> &>(cart)).applyBC(domain,ghost,bc);
819 
821  cart.calculateGhostBoxes();
822 
823  return cart;
824  }
825 
832  {
834 
835  (static_cast<ie_loc_ghost<dim,T>*>(&cart))->operator=(static_cast<ie_loc_ghost<dim,T>>(*this));
836  (static_cast<nn_prcs<dim,T>*>(&cart))->operator=(static_cast<nn_prcs<dim,T>>(*this));
837  (static_cast<ie_ghost<dim,T>*>(&cart))->operator=(static_cast<ie_ghost<dim,T>>(*this));
838 
839  cart.sub_domains = sub_domains;
841  cart.fine_s = fine_s;
842  cart.gr = gr;
843  cart.gr_dist = gr_dist;
844  cart.dist = dist;
845  cart.commCostSet = commCostSet;
846  cart.cd = cd;
847  cart.domain = domain;
848  for (size_t i = 0 ; i < dim ; i++)
849  {cart.spacing[i] = spacing[i];};
850 
851  cart.ghost = ghost;
852 
853  cart.bbox = bbox;
854 
855  for (size_t i = 0 ; i < dim ; i++)
856  cart.bc[i] = this->bc[i];
857 
858  return cart;
859  }
860 
869  {
870  static_cast<ie_loc_ghost<dim,T>*>(this)->operator=(static_cast<ie_loc_ghost<dim,T>>(cart));
871  static_cast<nn_prcs<dim,T>*>(this)->operator=(static_cast<nn_prcs<dim,T>>(cart));
872  static_cast<ie_ghost<dim,T>*>(this)->operator=(static_cast<ie_ghost<dim,T>>(cart));
873 
874  sub_domains = cart.sub_domains;
876  fine_s = cart.fine_s;
877  gr = cart.gr;
878  gr_dist = cart.gr_dist;
879  dist = cart.dist;
880  commCostSet = cart.commCostSet;
881  cd = cart.cd;
882  domain = cart.domain;
883 
884  for (size_t i = 0 ; i < dim ; i++)
885  {
886  spacing[i] = cart.spacing[i];
887  magn[i] = cart.magn[i];
888  };
889 
890  ghost = cart.ghost;
891 
892  bbox = cart.bbox;
893 
894  for (size_t i = 0 ; i < dim ; i++)
895  bc[i] = cart.bc[i];
896 
897  return *this;
898  }
899 
908  {
909  static_cast<ie_loc_ghost<dim,T>*>(this)->operator=(static_cast<ie_loc_ghost<dim,T>>(cart));
910  static_cast<nn_prcs<dim,T>*>(this)->operator=(static_cast<nn_prcs<dim,T>>(cart));
911  static_cast<ie_ghost<dim,T>*>(this)->operator=(static_cast<ie_ghost<dim,T>>(cart));
912 
913  sub_domains.swap(cart.sub_domains);
914  box_nn_processor.swap(cart.box_nn_processor);
915  fine_s.swap(cart.fine_s);
916  gr = cart.gr;
917  gr_dist = cart.gr_dist;
918  dist = cart.dist;
919  commCostSet = cart.commCostSet;
920  cd = cart.cd;
921  domain = cart.domain;
922  for (size_t i = 0 ; i < dim ; i++)
923  {
924  spacing[i] = cart.spacing[i];
925  magn[i] = cart.magn[i];
926  };
927 
928  ghost = cart.ghost;
929 
930  bbox = cart.bbox;
931 
932  for (size_t i = 0 ; i < dim ; i++)
933  bc[i] = cart.bc[i];
934 
935  return *this;
936  }
937 
949  static size_t getDefaultGrid(size_t n_sub)
950  {
951  // Calculate the number of sub-sub-domain on
952  // each dimension
953  return openfpm::math::round_big_2(pow(n_sub, 1.0 / dim));
954  }
955 
963  template<typename Mem> size_t inline processorID(const encapc<1, Point<dim,T>, Mem> & p) const
964  {
965  return fine_s.get(cd.template getCell(p));
966  }
967 
975  size_t inline processorID(const Point<dim,T> &p) const
976  {
977  return fine_s.get(cd.getCell(p));
978  }
979 
987  size_t inline processorID(const T (&p)[dim]) const
988  {
989  return fine_s.get(cd.getCell(p));
990  }
991 
1001  template<typename Mem> size_t inline processorIDBC(encapc<1, Point<dim,T>, Mem> p)
1002  {
1003  Point<dim,T> pt = p;
1004  applyPointBC(pt);
1005 
1006  return fine_s.get(cd.getCell(pt));
1007  }
1008 
1018  template<typename ofb> size_t inline processorIDBC(const Point<dim,T> &p) const
1019  {
1020  Point<dim,T> pt = p;
1021  applyPointBC(pt);
1022 
1023  return fine_s.get(cd.getCell(p));
1024  }
1025 
1035  template<typename ofb> size_t inline processorIDBC(const T (&p)[dim]) const
1036  {
1037  Point<dim,T> pt = p;
1038  applyPointBC(pt);
1039 
1040  return fine_s.get(cd.getCell(p));
1041  }
1042 
1050  inline size_t periodicity(size_t i) const
1051  {
1052  return bc[i];
1053  }
1054 
1061  inline const size_t (& periodicity() const) [dim]
1062  {
1063  return bc;
1064  }
1065 
1072  {
1073  if (gm.size() == 0)
1074  {
1075  for (size_t i = 0 ; i < dim ; i++)
1076  magn[i] = 1;
1077  }
1078  else
1079  {
1080  for (size_t i = 0 ; i < dim ; i++)
1081  {
1082  if (gr.size(i) % gm.size(i) != 0)
1083  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;
1084 
1085  magn[i] = gr.size(i) / gm.size(i);
1086  }
1087  }
1088  }
1089 
1105  const size_t (& bc)[dim],
1106  const Ghost<dim,T> & ghost,
1107  size_t dec_gran,
1108  const grid_sm<dim,void> & sec_dist = grid_sm<dim,void>())
1109  {
1110  size_t div[dim];
1111 
1112  // Create a valid decomposition of the space
1113  // Get the number of processor and calculate the number of sub-domain
1114  // for decomposition
1115  size_t n_proc = v_cl.getProcessingUnits();
1116  size_t n_sub = n_proc * dec_gran;
1117 
1118  // Calculate the maximum number (before merging) of sub-domain on
1119  // each dimension
1120 
1121  nsub_to_div2(div,n_sub,dim);
1122 
1123 /* for (size_t i = 0; i < dim; i++)
1124  {
1125  div[i] = openfpm::math::round_big_2(pow(n_sub, 1.0 / dim));
1126  }*/
1127 
1128  if (dim > 3)
1129  {
1130  long int dim_r = dim-1;
1131  do
1132  {
1133  // Check for adjustment
1134  size_t tot_size = 1;
1135  for (size_t i = 0 ; i < dim ; i++)
1136  {tot_size *= div[i];}
1137 
1138  // the granularity is too coarse increase the divisions
1139  if (tot_size / n_proc > 0.75*dec_gran )
1140  {break;}
1141 
1142  nsub_to_div(div,n_sub,dim_r);
1143 
1144  dim_r--;
1145  } while(dim_r > 0);
1146  }
1147 
1148  setParameters(div,domain_,bc,ghost,sec_dist);
1149  }
1150 
1156  void getParameters(size_t (& div_)[dim])
1157  {
1158  for (size_t i = 0 ; i < dim ; i++)
1159  {div_[i] = this->gr.size(i);}
1160  }
1161 
1173  void setParameters(const size_t (& div_)[dim],
1174  ::Box<dim,T> domain_,
1175  const size_t (& bc)[dim],
1176  const Ghost<dim,T> & ghost,
1177  const grid_sm<dim,void> & sec_dist = grid_sm<dim,void>())
1178  {
1179  // set the boundary conditions
1180  for (size_t i = 0 ; i < dim ; i++)
1181  this->bc[i] = bc[i];
1182 
1183  // set the ghost
1184  this->ghost = ghost;
1185 
1186  // Set the decomposition parameters
1187  gr.setDimensions(div_);
1188  domain = domain_;
1189  cd.setDimensions(domain, div_, 0);
1190 
1191  // We we have a secondary grid costruct a reduced graph
1192  if (sec_dist.size(0) != 0)
1193  {
1194  calculate_magn(sec_dist);
1195  gr_dist.setDimensions(sec_dist.getSize());
1196  }
1197  else
1198  {
1199  calculate_magn(sec_dist);
1200  gr_dist = gr;
1201  }
1202 
1203  // init distribution
1204  dist.createCartGraph(gr_dist, domain);
1205 
1206  }
1207 
1212  void reset()
1213  {
1214  sub_domains.clear();
1215  box_nn_processor.clear();
1216  fine_s.clear();
1217  loc_box.clear();
1221  }
1222 
1226  void decompose()
1227  {
1228  reset();
1229 
1230  if (commCostSet == false)
1232 
1233  dist.decompose();
1234 
1235  createSubdomains(v_cl,bc);
1236 
1238 
1241  }
1242 
1248  void refine(size_t ts)
1249  {
1250  reset();
1251 
1252  if (commCostSet == false)
1254 
1255  dist.refine();
1256 
1257  createSubdomains(v_cl,bc);
1258 
1260 
1263  }
1264 
1270  void redecompose(size_t ts)
1271  {
1272  reset();
1273 
1274  if (commCostSet == false)
1276 
1277  dist.redecompose();
1278 
1279  createSubdomains(v_cl,bc);
1280 
1282 
1285  }
1286 
1293  bool refine(DLB & dlb)
1294  {
1295  // if the DLB heuristic to use is the "Unbalance Threshold" get unbalance percentage
1296  if (dlb.getHeurisitc() == DLB::Heuristic::UNBALANCE_THRLD)
1297  {
1298  float unbalance = dist.getUnbalance();
1299  dlb.setUnbalance(unbalance);
1300  if (v_cl.getProcessUnitID() == 0)
1301  {
1302  std::cout << std::setprecision(3) << unbalance << "\n";
1303  }
1304  }
1305 
1306  if (dlb.rebalanceNeeded())
1307  {
1309 
1310  return true;
1311  }
1312  return false;
1313  }
1314 
1315 // size_t n_step = 0;
1316 
1322  {
1323  return dist.getUnbalance();
1324  }
1325 
1331  {
1332  return dist.getProcessorLoad();
1333  }
1334 
1341  inline void getSubSubDomainPosition(size_t id, T (&pos)[dim])
1342  {
1343  dist.getSubSubDomainPosition(id, pos);
1344  }
1345 
1346  //TODO fix in Parmetis distribution to get only the right amount of vertices
1352  {
1353  return dist.getNSubSubDomains();
1354  }
1355 
1362  inline void setSubSubDomainComputationCost(size_t id, size_t weight)
1363  {
1364  dist.setComputationCost(id, weight);
1365  }
1366 
1374  inline size_t getSubSubDomainComputationCost(size_t id)
1375  {
1376  return dist.getSubSubDomainComputationCost(id);
1377  }
1378 
1383  size_t subSize()
1384  {
1385  return dist.subSize();
1386  }
1387 
1393  size_t getNSubDomain()
1394  {
1395  return sub_domains.size();
1396  }
1397 
1406  {
1407  // Create a space box
1408  SpaceBox<dim, T> sp;
1409 
1410  // fill the space box
1411 
1412  for (size_t k = 0; k < dim; k++)
1413  {
1414  // create the SpaceBox Low and High
1415  sp.setLow(k, sub_domains.template get<Box::p1>(lc)[k]);
1416  sp.setHigh(k, sub_domains.template get<Box::p2>(lc)[k]);
1417  }
1418 
1419  return sp;
1420  }
1421 
1430  {
1431  // Create a space box
1432  SpaceBox<dim, T> sp = sub_domains.get(lc);
1433 
1434  // enlarge with ghost
1435  sp.enlarge(ghost);
1436 
1437  return sp;
1438  }
1439 
1445  const ::Box<dim,T> & getDomain() const
1446  {
1447  return domain;
1448  }
1449 
1450  openfpm::vector<SpaceBox<dim, T>> getSubDomains() const
1451  {
1452  return sub_domains;
1453  }
1454 
1455  openfpm::vector<openfpm::vector<SpaceBox<dim, T>>> & getSubDomainsGlobal()
1456  {
1457  return sub_domains_global;
1458  }
1459 
1469  template<typename Mem> bool isLocal(const encapc<1, Point<dim, T>, Mem> p) const
1470  {
1471  return processorID<Mem>(p) == v_cl.getProcessUnitID();
1472  }
1473 
1483  bool isLocal(const T (&pos)[dim]) const
1484  {
1485  return processorID(pos) == v_cl.getProcessUnitID();
1486  }
1487 
1497  bool isLocal(const Point<dim,T> & pos) const
1498  {
1499  return processorID(pos) == v_cl.getProcessUnitID();
1500  }
1501 
1514  template<typename Mem> bool isLocalBC(const encapc<1, Point<dim,T>, Mem> p, const size_t (& bc)[dim]) const
1515  {
1516  Point<dim,T> pt = p;
1517 
1518  for (size_t i = 0 ; i < dim ; i++)
1519  {
1520  if (bc[i] == PERIODIC)
1521  pt.get(i) = openfpm::math::periodic_l(p.template get<0>()[i],domain.getHigh(i),domain.getLow(i));
1522  }
1523 
1524  return processorID<Mem>(pt) == v_cl.getProcessUnitID();
1525  }
1526 
1535  {
1537  }
1538 
1562  {
1564  }
1565 
1573  {
1575  }
1576 
1586  {
1588  }
1589 
1601  bool isLocalBC(const T (&p)[dim], const size_t (& bc)[dim]) const
1602  {
1603  Point<dim,T> pt = p;
1604 
1605  for (size_t i = 0 ; i < dim ; i++)
1606  {
1607  if (bc[i] == PERIODIC)
1608  pt.get(i) = openfpm::math::periodic_l(p[i],domain.getHigh(i),domain.getLow(i));
1609  }
1610 
1611  return processorID(pt) == v_cl.getProcessUnitID();
1612  }
1613 
1614 
1621  {
1622  return bbox;
1623  }
1624 
1625 
1632  const Ghost<dim,T> & getGhost() const
1633  {
1634  return ghost;
1635  }
1636 
1642  {
1643  return gr;
1644  }
1645 
1651  {
1652  return gr_dist;
1653  }
1654 
1656 
1675  bool write(std::string output) const
1676  {
1678  VTKWriter<openfpm::vector<::SpaceBox<dim, T>>, VECTOR_BOX> vtk_box1;
1679  vtk_box1.add(sub_domains);
1680  vtk_box1.write(output + std::string("subdomains_") + std::to_string(v_cl.getProcessUnitID()) + std::string(".vtk"));
1681 
1682  nn_prcs<dim, T>::write(output);
1683  ie_ghost<dim, T>::write(output, v_cl.getProcessUnitID());
1685 
1686  return true;
1687  }
1688 
1694  Vcluster & getVC() const
1695  {
1696 #ifdef SE_CLASS2
1697  check_valid(this,8);
1698 #endif
1699  return v_cl;
1700  }
1701 
1708  {
1710  return false;
1711 
1712  return true;
1713  }
1714 
1718  void debugPrint()
1719  {
1720  std::cout << "Subdomains\n";
1721  for (size_t p = 0; p < sub_domains.size(); p++)
1722  {
1723  std::cout << ::SpaceBox<dim, T>(sub_domains.get(p)).toString() << "\n";
1724  }
1725 
1726  std::cout << "External ghost box\n";
1727 
1728  for (size_t p = 0; p<nn_prcs < dim, T>::getNNProcessors(); p++)
1729  {
1730  for (size_t i = 0; i<ie_ghost < dim, T>::getProcessorNEGhost(p); i++)
1731  {
1732  std::cout << ie_ghost<dim, T>::getProcessorEGhostBox(p, i).toString() << " prc=" << nn_prcs<dim, T>::IDtoProc(p) << " id=" << ie_ghost<dim, T>::getProcessorEGhostId(p, i) << "\n";
1733  }
1734  }
1735 
1736  std::cout << "Internal ghost box\n";
1737 
1738  for (size_t p = 0; p<nn_prcs < dim, T>::getNNProcessors(); p++)
1739  {
1740  for (size_t i = 0; i<ie_ghost < dim, T>::getProcessorNIGhost(p); i++)
1741  {
1742  std::cout << ie_ghost<dim, T>::getProcessorIGhostBox(p, i).toString() << " prc=" << nn_prcs<dim, T>::IDtoProc(p) << " id=" << ie_ghost<dim, T>::getProcessorIGhostId(p, i) << "\n";
1743  }
1744  }
1745  }
1746 
1755  {
1756  if (static_cast<ie_loc_ghost<dim,T>*>(this)->is_equal(static_cast<ie_loc_ghost<dim,T>&>(cart)) == false)
1757  return false;
1758 
1759  if (static_cast<nn_prcs<dim,T>*>(this)->is_equal(static_cast<nn_prcs<dim,T>&>(cart)) == false)
1760  return false;
1761 
1762  if (static_cast<ie_ghost<dim,T>*>(this)->is_equal(static_cast<ie_ghost<dim,T>&>(cart)) == false)
1763  return false;
1764 
1765  if (sub_domains != cart.sub_domains)
1766  return false;
1767 
1768  if (box_nn_processor != cart.box_nn_processor)
1769  return false;
1770 
1771  if (fine_s != cart.fine_s)
1772  return false;
1773 
1774  if (gr != cart.gr)
1775  return false;
1776 
1777  if (cd != cart.cd)
1778  return false;
1779 
1780  if (domain != cart.domain)
1781  return false;
1782 
1783  if (meta_compare<T[dim]>::meta_compare_f(cart.spacing,spacing) == false)
1784  return false;
1785 
1786  if (ghost != cart.ghost)
1787  return false;
1788 
1789  return true;
1790  }
1791 
1801  {
1802  if (static_cast<ie_loc_ghost<dim,T>*>(this)->is_equal_ng(static_cast<ie_loc_ghost<dim,T>&>(cart)) == false)
1803  return false;
1804 
1805  if (static_cast<nn_prcs<dim,T>*>(this)->is_equal(static_cast<nn_prcs<dim,T>&>(cart)) == false)
1806  return false;
1807 
1808  if (static_cast<ie_ghost<dim,T>*>(this)->is_equal_ng(static_cast<ie_ghost<dim,T>&>(cart)) == false)
1809  return false;
1810 
1811  if (sub_domains != cart.sub_domains)
1812  return false;
1813 
1814  if (box_nn_processor != cart.box_nn_processor)
1815  return false;
1816 
1817  if (fine_s != cart.fine_s)
1818  return false;
1819 
1820  if (gr != cart.gr)
1821  return false;
1822 
1823  if (cd != cart.cd)
1824  return false;
1825 
1826  if (domain != cart.domain)
1827  return false;
1828 
1829  if (meta_compare<T[dim]>::meta_compare_f(cart.spacing,spacing) == false)
1830  return false;
1831 
1832  return true;
1833  }
1834 
1840  Distribution & getDistribution()
1841  {
1842  return dist;
1843  }
1844 
1845 
1851  inline void addComputationCost(size_t gid, size_t i)
1852  {
1853  size_t c = dist.getSubSubDomainComputationCost(gid);
1854 
1855  dist.setComputationCost(gid, c + i);
1856  }
1857 
1863  size_t get_ndec()
1864  {
1865  return dist.get_ndec();
1866  }
1867 
1873  const CellDecomposer_sm<dim, T, shift<dim,T>> & getCellDecomposer()
1874  {
1875  return cd;
1876  }
1877 
1880 
1881 };
1882 
1883 
1884 #endif
openfpm::vector< size_t > fine_s
size_t getProcessorLoad()
Compute the processor load counting the total weights of its vertices.
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.
openfpm::vector< openfpm::vector< SpaceBox< dim, T > > > sub_domains_global
the global set of all sub-domains as vector of 'sub_domains' vectors
void redecompose(size_t ts)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call...
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
CellDecomposer_sm< dim, T, shift< dim, T > > cd
bool is_equal(CartDecomposition< dim, T, Memory > &cart)
Check if the CartDecomposition contain the same information.
size_t IDtoProc(size_t id) const
Return the processor id of the near processor list at place id.
mem_id LinId(const grid_key_dx< N > &gk, const char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:337
void applyPointBC(encapc< 1, Point< dim, T >, Mem > &&pt) const
Apply boundary condition to the point.
void getParameters(size_t(&div_)[dim])
return the parameters of the decomposition
void debugPrint()
Print subdomains, external and internal ghost boxes.
CartDecomposition(const CartDecomposition< dim, T, Memory, Distribution > &cart)
Cartesian decomposition copy constructor.
size_t processorIDBC(const T(&p)[dim]) const
Given a point return in which processor the particle should go.
Vcluster & v_cl
Runtime virtual cluster machine.
Transform the boost::fusion::vector into memory specification (memory_traits)
Definition: memory_conf.hpp:93
const grid_sm< dim, void > getGrid()
Decomposition grid.
Heuristic getHeurisitc()
Get the heuristic.
Definition: DLB.hpp:190
bool write(std::string output, size_t p_id) const
write the information about the ghost in vtk format
Definition: ie_ghost.hpp:959
void incRef()
Increment the reference counter.
This class decompose a space into sub-sub-domains and distribute them across processors.
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.
const size_t(& periodicity() const)[dim]
Get the periodicity.
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
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.
const CellDecomposer_sm< dim, T, shift< dim, T > > & getCellDecomposer()
Get the cell decomposer of the decomposition.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
size_t processorIDBC(const Point< dim, T > &p) const
Given a point return in which processor the particle should go.
const ::Box< dim, T > & getDomain() const
Return the box of the physical domain.
size_t getProcessUnitID()
Get the process unit id.
void generateShiftVectors(const Box< dim, T > &domain, size_t(&bc)[dim])
Here we generare the shift vectors.
Definition: ie_ghost.hpp:160
static size_t getDefaultGrid(size_t n_sub)
The default grid size.
CartDecomposition< dim, T, Memory, Distribution > & operator=(const CartDecomposition &cart)
Copy the element.
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.
::Box< dim, T > bbox
Processor bounding box.
void applyPointBC(float(&pt)[dim]) const
Apply boundary condition to the point.
bool commCostSet
Indicate the communication weight has been set.
void decompose()
Start decomposition.
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.
void mul(T(&sp)[dim])
multiply the space box with the coefficient defined in sp
Definition: SpaceBox.hpp:178
size_t subSize()
Operator to access the size of the sub-graph.
size_t getNSubSubDomains()
Get the number of sub-sub-domains in this sub-graph.
size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:572
void calculate_magn(const grid_sm< dim, void > &gm)
Calculate magnification.
bool check_consistency()
function to check the consistency of the information of the decomposition
T spacing[dim]
Box Spacing.
void create_box_nn_processor_ext(Vcluster &v_cl, Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >> &sub_domains, const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const nn_prcs< dim, T > &nn_p)
Create the box_nn_processor_int (bx part) structure.
Definition: ie_ghost.hpp:195
void addComputationCost(size_t gid, size_t i)
Add computation cost i to the subsubdomain with global id gid.
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
CartDecomposition_ext< dim, T, Memory, Distribution > extended_type
This class admit a class defined on an extended domain.
size_t processorID(const Point< dim, T > &p) const
Given a point return in which processor the particle should go.
SpaceBox< dim, T > getSubDomainWithGhost(size_t lc)
Get the local sub-domain enlarged with ghost extension.
grid_key_dx< dim > one
key with all coordinates set to one
SpaceBox< dim, T > Box
It simplify to access the SpaceBox element.
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:467
void refine(size_t ts)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call...
size_t size()
Stub size.
Definition: map_vector.hpp:70
grid_sm< dim, void > gr_dist
Structure that store the cartesian grid information.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
static bool check_valid(comb< dim > cmb, const size_t(&bc)[dim])
grow_policy_double vector_grow_policy_default
default grow policy
bool rebalanceNeeded()
check if a re-balance is needed using the selected heuristic
Definition: DLB.hpp:200
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.
bool write(std::string output) const
Write the decomposition as VTK file.
void getSubSubDomainPosition(size_t id, T(&pos)[dim])
function that return the position of the cell in the space
openfpm::vector< SpaceBox< dim, T >, Memory, typename memory_traits_lin< SpaceBox< dim, T > >::type, memory_traits_lin, openfpm::vector_grow_policy_default, openfpm::vect_isel< SpaceBox< dim, T > >::value >::access_key acc_key
void reset()
Reset the nn_prcs structure.
Definition: ie_ghost.hpp:1066
void expand(T(&exp)[dim])
expand the box by a vector
Definition: Box.hpp:670
Distribution & getDistribution()
Return the distribution object.
void computeCommunicationAndMigrationCosts(size_t ts)
Calculate communication and migration costs.
class to select the returned id by ghost_processorID
void applyPointBC(Point< dim, T > &pt) const
Apply boundary condition to the point.
Definition: Ghost.hpp:39
void reset()
Delete the decomposition and reset the data-structure.
Distribution dist
Create distribution.
openfpm::vector< size_t > & getCRSDomainCells()
Get the CRS domain Cells with normal neighborhood.
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
bool isLocal(const encapc< 1, Point< dim, T >, Mem > p) const
Check if the particle is local.
Implementation of VCluster class.
Definition: VCluster.hpp:36
const grid_sm< dim, void > getDistGrid()
Distribution grid.
static size_t id(p_box< dim, T > &p, size_t b_id)
Return the shift id.
void reset()
Reset the ie_loc_ghost.
static size_t id(p_box< dim, T > &p, size_t b_id)
Return the near processor id.
size_t lc_proc
local processor id
Definition: common.hpp:281
openfpm::vector< size_t > & getCRSDomainCells()
Get the domain Cells.
bool isLocal(const T(&pos)[dim]) const
Check if the particle is local.
size_t getNTimeStepSinceDLB()
Get how many time-steps have passed since the last re-balancing.
Definition: DLB.hpp:309
grid_sm< dim, void > gs
Processor cells-grid.
long int ref()
Return the reference counter.
This class decompose a space into sub-sub-domains and distribute them across processors.
openfpm::vector< subsub_lin< dim > > & getCRSAnomDomainCells()
Get the CRS anomalous cells.
void enclose(const Box< dim, T > &en)
Refine the box to enclose the given box and itself.
Definition: Box.hpp:812
::Box< dim, T > & getProcessorBounds()
Return the bounding box containing union of all the sub-domains for the local processor.
size_t getNSubDomain()
Get the number of local sub-domains.
CartDecomposition(Vcluster &v_cl)
Cartesian decomposition constructor.
bool refine(DLB &dlb)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call...
SpaceBox< dim, T > getSubDomain(size_t lc)
Get the local sub-domain.
It analyze the type given and it select correctly the implementation for vector.
Definition: vect_isel.hpp:36
structure that store and compute the internal and external local ghost box
Definition: ie_ghost.hpp:25
CartDecomposition< dim, T, Memory, Distribution > duplicate() const
It create another object that contain the same information and act in the same way.
void Initialize_geo_cell_lists()
Initialize geo_cell lists.
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:700
const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:677
size_t shift_id
shift vector id
Definition: common.hpp:286
void reset()
In case you have to recompute the indexes.
void create_box_nn_processor_int(Vcluster &v_cl, Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >> &sub_domains, const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const nn_prcs< dim, T > &nn_p)
Create the box_nn_processor_int (nbx part) structure, the geo_cell list and proc_int_box.
Definition: ie_ghost.hpp:296
class to select the returned id by ghost_processorID
void create(openfpm::vector< SpaceBox< dim, T >> &sub_domains, Box< dim, T > &domain, Ghost< dim, T > &ghost, const size_t(&bc)[dim])
Create external and internal local ghosts.
const grid_key_dx< dim > & get() const
Get the actual key.
Ghost< dim, T > ghost
ghost info
CartDecomposition< dim, T, Memory, Distribution > duplicate(const Ghost< dim, T > &g) const
It create another object that contain the same decomposition information but with different ghost box...
size_t bc[dim]
Boundary condition info.
::Box< dim, size_t > proc_box
Processor domain bounding box.
bool isValidN() const
Check if the Box is a valid box P2 > P1.
Definition: Box.hpp:1013
CartDecomposition< dim, T, Memory, Distribution > base_type
This class is base of itself.
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
openfpm::vector< size_t > & getDomainCells()
Get the domain Cells.
size_t proc
processor rank
Definition: common.hpp:283
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:456
static size_t id(p_box< dim, T > &p, size_t b_id)
Return the processor id.
bool isNext()
Check if there is the next element.
size_t periodicity(size_t i) const
Get the periodicity on i dimension.
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
This class compare general objects.
bool write(std::string output, size_t p_id) const
Write the decomposition as VTK file.
void Initialize_geo_cell(const Box< dim, T > &domain, const size_t(&div)[dim])
Initialize the geo cell list structure.
Definition: ie_ghost.hpp:174
Definition: DLB.hpp:53
bool write(std::string output) const
Write the decomposition as VTK file.
void decRef()
Decrement the reference counter.
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.
const Ghost< dim, T > & getGhost() const
Return the ghost.
structure that store and compute the internal and external local ghost box
size_t getProcessorEGhostId(size_t id, size_t j) const
Get the j External ghost box id.
Definition: ie_ghost.hpp:623
size_t processorID(const T(&p)[dim]) const
Given a point return in which processor the particle should go.
size_t getSubSubDomainComputationCost(size_t id)
function that return the computation cost of the sub-sub-domain id
bool isLocal(const Point< dim, T > &pos) const
Check if the particle is local.
static size_t id(p_box< dim, T > &p, size_t b_id)
Return the box id.
class to select the returned id by ghost_processorID
size_t getProcessorIGhostId(size_t id, size_t j) const
Get the j Internal ghost box id.
Definition: ie_ghost.hpp:607
void calculateGhostBoxes()
It calculate the internal ghost boxes.
size_t get_ndec()
Get the decomposition counter.
This class calculate processor domains and neighborhood of each processor domain. ...
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...
class to select the returned id by ghost_processorID
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_key.hpp:407
CartDecomposition< dim, T, Memory, Distribution > & operator=(CartDecomposition &&cart)
Copy the element, move semantic.
::Box< dim, T > domain
rectangular domain to decompose
Vcluster & getVC() const
Get the Virtual Cluster machine.
size_t processorID(const encapc< 1, Point< dim, T >, Mem > &p) const
Given a point return in which processor the particle should go.
It store all the boxes of the near processors in a linear array.
Definition: common.hpp:275
void setSubSubDomainComputationCost(size_t id, size_t weight)
Function that set the computational cost for a of a sub-sub domain.
openfpm::vector< SpaceBox< dim, T > > sub_domains
the set of all local sub-domain as vector
void applyBC(const Box< dim, T > &domain, const Ghost< dim, T > &ghost, const size_t(&bc)[dim])
Apply boundary conditions.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
CartDecomposition(CartDecomposition< dim, T, Memory, Distribution > &&cart)
Cartesian decomposition copy constructor.
bool isLocalBC(const T(&p)[dim], const size_t(&bc)[dim]) const
Check if the particle is local considering boundary conditions.
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.
Definition: ids.hpp:148
size_t processorIDBC(encapc< 1, Point< dim, T >, Mem > p)
Given a point return in which processor the point/particle should go.
long int ref_cnt
reference counter of the object in case is shared between object
size_t getProcessingUnits()
Get the total number of processors.
openfpm::vector< openfpm::vector< long unsigned int > > box_nn_processor
for each sub-domain, contain the list of the neighborhood processors
openfpm::vector<::Box< dim, size_t > > loc_box
set of Boxes produced by the decomposition optimizer
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition: grid_sm.hpp:229
void setNNParameters(grid_key_dx< dim > &shift, grid_sm< dim, void > &gs)
set NN parameters to calculate cell-list neighborhood
void reset()
Reset the nn_prcs structure.
openfpm::vector< size_t > & getDomainCells()
Get the domain Cells.
friend extended_type
friend classes
static constexpr int dims
Space dimensions.
void setUnbalance(float u)
Set un-balance value.
Definition: DLB.hpp:318
void CreateSubspaces()
Create the sub-domain that decompose your domain.
~CartDecomposition()
Cartesian decomposition destructor.
float getUnbalance()
Get the current un-balance value.
void create(const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const openfpm::vector< SpaceBox< dim, T >> &sub_domains)
Create the list of adjacent processors and the list of adjacent sub-domains.
This class store the adjacent processors and the adjacent sub_domains.