OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
ie_ghost.hpp
1 /*
2  * ie_ghost.hpp
3  *
4  * Created on: Aug 8, 2015
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_DECOMPOSITION_IE_GHOST_HPP_
9 #define SRC_DECOMPOSITION_IE_GHOST_HPP_
10 
11 #include "common.hpp"
12 #include "nn_processor.hpp"
13 #include "Decomposition/shift_vect_converter.hpp"
14 #include "Decomposition/cuda/ie_ghost_gpu.cuh"
15 
18 {
19  size_t proc_id;
20  size_t box_id;
21  size_t shift_id;
22 
24  bool operator<(const proc_box_id & pbi) const
25  {
26  if (proc_id < pbi.proc_id)
27  {return true;}
28  else if (proc_id == pbi.proc_id)
29  {
30  return shift_id < pbi.shift_id;
31  }
32 
33  return false;
34  }
35 };
36 
37 
46 template<unsigned int dim, typename T, typename Memory, template<typename> class layout_base >
47 class ie_ghost
48 {
54 
57 
60 
63 
66 
69 
70  typedef openfpm::vector<Box<dim,T>,Memory,layout_base> proc_boxes;
71 
73  openfpm::vector<Point<dim,T>,Memory,layout_base> shifts;
74 
77 
80 
83 
85  bool host_dev_transfer = false;
86 
89 
91  size_t bc[dim];
92 
109  inline size_t link_ebx_ibx(const nn_prcs<dim,T,layout_base,Memory> & nn_p, size_t p_id, size_t i)
110  {
111  // Search for the correct id
112  size_t k = 0;
113  size_t p_idp = nn_p.ProctoID(p_id);
114  for (k = 0 ; k < nn_p.getSentSubdomains(p_idp).size() ; k++)
115  {
116  if (nn_p.getSentSubdomains(p_idp).get(k) == i)
117  break;
118  }
119  if (k == nn_p.getSentSubdomains(p_idp).size())
120  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " sub-domain not found\n";
121 
122  return k;
123  }
124 
179  inline size_t ebx_ibx_form(size_t k, size_t b, size_t p_id, const comb<dim> & c ,size_t N_b, Vcluster<> & v_cl, const bool ei)
180  {
181  comb<dim> cext = c;
182 
183  if (ei == true)
184  cext.sign_flip();
185 
186  return ((k * N_b + b) * v_cl.getProcessingUnits() + p_id) * openfpm::math::pow(3,dim) + cext.lin();
187  }
188 
189 protected:
190 
196  void generateShiftVectors(const Box<dim,T> & domain, size_t (& bc)[dim])
197  {
198  sc_convert.generateShiftVectors(domain,bc,shifts);
199 
200  this->domain = domain;
201 
202  for (int i = 0 ; i < dim ; i++)
203  {
204  this->bc[i] = bc[i];
205  }
206  }
207 
217  void Initialize_geo_cell(const Box<dim,T> & domain, const size_t (&div)[dim])
218  {
219  // Initialize the geo_cell structure
220  geo_cell.Initialize(domain,div,1);
221  }
222 
227  {
228  geo_cell.destroy();
229  }
230 
247  Ghost<dim,T> & ghost,
248  openfpm::vector<SpaceBox<dim,T>,Memory,layout_base> & sub_domains,
249  const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processor,
251  {
252  box_nn_processor_int.resize(sub_domains.size());
253  proc_int_box.resize(nn_p.getNNProcessors());
254 
255  // For each sub-domain
256  for (size_t i = 0 ; i < sub_domains.size() ; i++)
257  {
258  SpaceBox<dim,T> sub_with_ghost = sub_domains.get(i);
259 
260  // enlarge the sub-domain with the ghost
261  sub_with_ghost.enlarge(ghost);
262 
263  // resize based on the number of near processors
264  box_nn_processor_int.get(i).resize(box_nn_processor.get(i).size());
265 
266  // For each processor near to this sub-domain
267  for (size_t j = 0 ; j < box_nn_processor.get(i).size() ; j++)
268  {
269  // near processor
270  size_t p_id = box_nn_processor.get(i).get(j);
271 
272  // used later
273  Box_dom<dim,T> & proc_int_box_g = proc_int_box.get(nn_p.ProctoID(p_id));
274 
275  // Number of received sub-domains
276  size_t n_r_sub = nn_p.getNRealSubdomains(p_id);
277 
278  // get the set of sub-domains, sector position, and real sub-domain id of the near processor p_id
279  const openfpm::vector< ::Box<dim,T> > & nn_processor_subdomains_g = nn_p.getNearSubdomains(p_id);
280  const openfpm::vector< comb<dim> > & nnpsg_pos = nn_p.getNearSubdomainsPos(p_id);
281  const openfpm::vector< size_t > & r_sub = nn_p.getNearSubdomainsRealId(p_id);
282 
283  // used later
284  openfpm::vector< ::Box<dim,T> > & box_nn_processor_int_gg = box_nn_processor_int.get(i).get(j).bx;
285 
286  // for each near processor sub-domain intersect with the enlarged local sub-domain and store it
287  for (size_t b = 0 ; b < nn_processor_subdomains_g.size() ; b++)
288  {
289  ::Box<dim,T> bi;
290  ::Box<dim,T> sub_bb(nn_processor_subdomains_g.get(b));
291 
292  bool intersect = sub_with_ghost.Intersect(sub_bb,bi);
293 
294  if (intersect == true)
295  {
296  struct p_box<dim,T> pb;
297 
298  pb.box = bi;
299  pb.proc = p_id;
300  pb.lc_proc = nn_p.ProctoID(p_id);
301  pb.shift_id = (size_t)-1;
302 
303  //
304  // Updating
305  //
306  // vb_ext
307  // box_nn_processor_int
308  // proc_int_box
309  //
310  // They all store the same information but organized in different ways
311  // read the description of each for more information
312  //
313 
314  vb_ext.add(pb);
315  box_nn_processor_int_gg.add(bi);
316  proc_int_box_g.ebx.add();
317  proc_int_box_g.ebx.last().bx = bi;
318  proc_int_box_g.ebx.last().sub = i;
319  proc_int_box_g.ebx.last().cmb = nnpsg_pos.get(b);
320 
321  // Search where the sub-domain i is in the sent list for processor p_id
322  size_t k = link_ebx_ibx(nn_p,p_id,i);
323 
324  proc_int_box_g.ebx.last().id = ebx_ibx_form(k,r_sub.get(b),p_id,nnpsg_pos.get(b),n_r_sub,v_cl,true);
325  }
326  }
327  }
328  }
329  }
330 
331 
349  Ghost<dim,T> & ghost,
350  openfpm::vector<SpaceBox<dim,T>,Memory,layout_base> & sub_domains,
351  const openfpm::vector<openfpm::vector<long unsigned int> > & box_nn_processor,
353  {
354  box_nn_processor_int.resize(sub_domains.size());
355  proc_int_box.resize(nn_p.getNNProcessors());
356 
357  // For each sub-domain
358  for (size_t i = 0 ; i < sub_domains.size() ; i++)
359  {
360  // For each processor contiguous to this sub-domain
361  for (size_t j = 0 ; j < box_nn_processor.get(i).size() ; j++)
362  {
363  // Near processor
364  size_t p_id = box_nn_processor.get(i).get(j);
365 
366  // get the set of sub-domains of the near processor p_id
367  const openfpm::vector< ::Box<dim,T> > & nn_p_box = nn_p.getNearSubdomains(p_id);
368 
369  // get the sector position for each sub-domain in the list
370  const openfpm::vector< comb<dim> > nn_p_box_pos = nn_p.getNearSubdomainsPos(p_id);
371 
372  // get the real sub-domain id for each sub-domain
373  const openfpm::vector<size_t> r_sub = nn_p.getNearSubdomainsRealId(p_id);
374 
375  // get the local processor id
376  size_t lc_proc = nn_p.getNearProcessor(p_id);
377 
378  // For each near processor sub-domains enlarge and intersect with the local sub-domain and store the result
379  for (size_t k = 0 ; k < nn_p_box.size() ; k++)
380  {
381  // enlarge the near-processor sub-domain
382  ::Box<dim,T> n_sub = nn_p_box.get(k);
383 
384  // local sub-domain
385  ::SpaceBox<dim,T> l_sub = sub_domains.get(i);
386 
387  // Create a margin of ghost size around the near processor sub-domain
388  n_sub.enlarge(ghost);
389 
390  // Intersect with the local sub-domain
391  Box<dim,T> b_int;
392  bool intersect = n_sub.Intersect(l_sub,b_int);
393 
394  // store if it intersect
395  if (intersect == true)
396  {
397  vb_int.add();
398 
399  size_t last = vb_int.size() - 1;
400 
401  // the box fill with the processor id
402  vb_int.template get<proc_>(last) = p_id;
403 
404  // fill the local processor id
405  vb_int.template get<lc_proc_>(last) = lc_proc;
406 
407  // fill the shift id
408  vb_int.template get<shift_id_>(last) = convertShift(nn_p_box_pos.get(k));
409 
410  //
411  // Updating
412  //
413  // vb_int
414  // box_nn_processor_int
415  // proc_int_box
416  //
417  // They all store the same information but organized in different ways
418  // read the description of each for more information
419  //
420 
421  // add the box to the near processor sub-domain intersections
422  openfpm::vector< ::Box<dim,T> > & p_box_int = box_nn_processor_int.get(i).get(j).nbx;
423  p_box_int.add(b_int);
424  vb_int_box.add(b_int);
425 
426  // store the box in proc_int_box storing from which sub-domain they come from
427  Box_sub<dim,T> sb;
428  sb.bx = b_int;
429  sb.sub = i;
430  sb.r_sub = r_sub.get(k);
431  sb.cmb = nn_p_box_pos.get(k);
432 
433  size_t p_idp = nn_p.ProctoID(p_id);
434 
435  // Search where the sub-domain i is in the sent list for processor p_id
436  size_t s = link_ebx_ibx(nn_p,p_id,i);
437 
438  // calculate the id of the internal box
439  sb.id = ebx_ibx_form(r_sub.get(k),s,v_cl.getProcessUnitID(),nn_p_box_pos.get(k),nn_p.getSentSubdomains(p_idp).size(),v_cl,false);
440 
441  Box_dom<dim,T> & pr_box_int = proc_int_box.get(nn_p.ProctoID(p_id));
442  pr_box_int.ibx.add(sb);
443 
444  // update the geo_cell list
445 
446  // get the cells this box span
447  const grid_key_dx<dim> p1 = geo_cell.getCellGrid_me(b_int.getP1());
448  const grid_key_dx<dim> p2 = geo_cell.getCellGrid_pe(b_int.getP2());
449 
450  // Get the grid and the sub-iterator
451  auto & gi = geo_cell.getGrid();
452  grid_key_dx_iterator_sub<dim> g_sub(gi,p1,p2);
453 
454  // add the box-id to the cell list
455  while (g_sub.isNext())
456  {
457  auto key = g_sub.get();
458  size_t cell = gi.LinId(key);
459 
460  geo_cell.addCell(cell,vb_int.size()-1);
461 
462  ++g_sub;
463  }
464  }
465  }
466  }
467  }
468 
470  }
471 
487  {
489 
490  size_t div[dim];
491 
492  for (size_t i = 0 ; i < dim ; i++) {div[i] = geo_cell.getDiv()[i];}
493 
494  grid_sm<dim,void> gs(div);
495 
497 
498  while (it.isNext())
499  {
500  size_t cell = gs.LinId(it.get());
501 
502  size_t sz = geo_cell.getNelements(cell);
503  tmp_sort.resize(sz);
504 
505  for (size_t i = 0 ; i < sz ; i++)
506  {
507  tmp_sort.get(i).box_id = geo_cell.get(cell,i);
508  tmp_sort.get(i).proc_id = vb_int.template get<proc_>(tmp_sort.get(i).box_id);
509  tmp_sort.get(i).shift_id = vb_int.template get<shift_id_>(tmp_sort.get(i).box_id);
510  }
511 
512  tmp_sort.sort();
513 
514  // now we set again the cell in an ordered way
515 
516  for (size_t i = 0 ; i < sz ; i++)
517  {geo_cell.get(cell,i) = tmp_sort.get(i).box_id;}
518 
519  ++it;
520  }
521  }
522 
523 public:
524 
526  ie_ghost() {};
527 
530  {
531  this->operator=(ie);
532  }
533 
536  {
537  this->operator=(ie);
538  }
539 
542  {
543  box_nn_processor_int.swap(ie.box_nn_processor_int);
544  proc_int_box.swap(ie.proc_int_box);
545  vb_ext.swap(ie.vb_ext);
546  vb_int.swap(ie.vb_int);
547  vb_int_box.swap(ie.vb_int_box);
548  geo_cell.swap(ie.geo_cell);
549  shifts.swap(ie.shifts);
550  ids_p.swap(ie.ids_p);
551  ids.swap(ie.ids);
552 
553  // it die anyway we can avoid to swap
554  domain = ie.domain;
555 
556  for (int i = 0 ; i < dim ; i++)
557  {bc[i] = ie.bc[i];}
558 
559  return *this;
560  }
561 
564  {
567  vb_ext = ie.vb_ext;
568  vb_int = ie.vb_int;
569  vb_int_box = ie.vb_int_box;
570  geo_cell = ie.geo_cell;
571  shifts = ie.shifts;
572  ids_p = ie.ids_p;
573  ids = ie.ids;
574  domain = ie.domain;
575 
576  domain = ie.domain;
577 
578  for (int i = 0 ; i < dim ; i++)
579  {bc[i] = ie.bc[i];}
580 
581  return *this;
582  }
583 
585  template<typename Memory2, template<typename> class layout_base2>
587  {
590  vb_ext = ie.private_get_vb_ext();
591  vb_int = ie.private_get_vb_int();
593  geo_cell = ie.private_geo_cell();
594  shifts = ie.private_get_shifts();
595  ids_p = ie.private_get_ids_p();
596  ids = ie.private_get_ids();
597  domain = ie.private_get_domain();
598 
599  for (int i = 0 ; i < dim ; i++)
600  {bc[i] = ie.private_get_bc(i);}
601 
602  return *this;
603  }
604 
605 
606 
612  template<typename Memory2, template <typename> class layout_base2>
614  {
616 
619  tmp.private_get_vb_ext() = vb_ext;
620  tmp.private_get_vb_int() = vb_int;
622  tmp.private_geo_cell() = geo_cell;
623  tmp.private_get_shifts() = shifts;
624  tmp.private_get_ids_p() = ids_p;
625  tmp.private_get_ids() = ids;
626 
627  tmp.private_get_domain() = domain;
628 
629  for (int i = 0 ; i < dim ; i++)
630  {tmp.private_get_bc()[i] = bc[i];}
631 
632  return tmp;
633  }
634 
683  const openfpm::vector<Point<dim,T>,Memory,layout_base> & getShiftVectors()
684  {
685  if (host_dev_transfer == false)
686  {
687  shifts.template hostToDevice<0>();
688  }
689 
690  return shifts;
691  }
692 
702  size_t convertShift(const comb<dim> & cmb)
703  {
704  return sc_convert.linId(cmb);
705  }
706 
713  inline size_t getProcessorNIGhost(size_t id) const
714  {
715  return proc_int_box.get(id).ibx.size();
716  }
717 
724  inline size_t getProcessorNEGhost(size_t id) const
725  {
726  return proc_int_box.get(id).ebx.size();
727  }
728 
736  inline const ::Box<dim,T> & getProcessorIGhostBox(size_t id, size_t j) const
737  {
738  return proc_int_box.get(id).ibx.get(j).bx;
739  }
740 
748  inline const ::Box<dim,T> & getProcessorEGhostBox(size_t id, size_t j) const
749  {
750  return proc_int_box.get(id).ebx.get(j).bx;
751  }
752 
760  inline const comb<dim> & getProcessorEGhostPos(size_t id, size_t j) const
761  {
762  return proc_int_box.get(id).ebx.get(j).cmb;
763  }
764 
772  inline const comb<dim> & getProcessorIGhostPos(size_t id, size_t j) const
773  {
774  return proc_int_box.get(id).ibx.get(j).cmb;
775  }
776 
788  inline size_t getProcessorIGhostId(size_t id, size_t j) const
789  {
790  return proc_int_box.get(id).ibx.get(j).id;
791  }
792 
804  inline size_t getProcessorEGhostId(size_t id, size_t j) const
805  {
806  return proc_int_box.get(id).ebx.get(j).id;
807  }
808 
820  inline size_t getProcessorIGhostSSub(size_t id, size_t j) const
821  {
822  return proc_int_box.get(id).ibx.get(j).r_sub;
823  }
824 
832  inline size_t getProcessorIGhostSub(size_t id, size_t j) const
833  {
834  return proc_int_box.get(id).ibx.get(j).sub;
835  }
836 
844  inline size_t getProcessorEGhostSub(size_t id, size_t j) const
845  {
846  return proc_int_box.get(id).ebx.get(j).sub;
847  }
848 
854  inline size_t getNIGhostBox() const
855  {
856  return vb_int.size();
857  }
858 
866  inline ::Box<dim,T> getIGhostBox(size_t b_id) const
867  {
868  return vb_int_box.get(b_id);
869  }
870 
879  inline size_t getIGhostBoxProcessor(size_t b_id) const
880  {
881  return vb_int.template get<proc_>(b_id);
882  }
883 
889  inline size_t getNEGhostBox() const
890  {
891  return vb_ext.size();
892  }
893 
901  inline ::Box<dim,T> getEGhostBox(size_t b_id) const
902  {
903  return vb_ext.get(b_id).box;
904  }
905 
914  inline size_t getEGhostBoxProcessor(size_t b_id) const
915  {
916  return vb_ext.get(b_id).proc;
917  }
918 
927  {
928  return geo_cell.getCellIterator(geo_cell.getCell(p));
929  }
930 
938  inline auto labelPoint(Point<dim,T> & p) -> decltype(geo_cell.getCellIterator(geo_cell.getCell(p)))
939  {
940  return geo_cell.getCellIterator(geo_cell.getCell(p));
941  }
942 
948  template<typename output_type> inline void ghost_processor_ID(const Point<dim,T> & p, output_type & output, unsigned int base, unsigned int pi)
949  {
950  ID_operation<output_type> op(output);
951 
952  ghost_processorID_general_impl(p,base,pi,geo_cell,vb_int_box,vb_int,op);
953  }
954 
960  inline unsigned int ghost_processorID_N(const Point<dim,T> & p)
961  {
962  return ghost_processorID_N_impl(p,geo_cell,vb_int_box,vb_int);
963  }
964 
982  template <typename id1, typename id2> inline const openfpm::vector<std::pair<size_t,size_t>> ghost_processorID_pair(Point<dim,T> & p, const int opt = MULTIPLE)
983  {
984  ids_p.clear();
985 
986  // Check with geo-cell if a particle is inside one Cell containing boxes
987 
988  auto cell_it = geo_cell.getCellIterator(geo_cell.getCell(p));
989 
990  // For each element in the cell, check if the point is inside the box
991  // if it is, store the processor id
992  while (cell_it.isNext())
993  {
994  size_t bid = cell_it.get();
995 
996  if (Box<dim,T>(vb_int_box.get(bid)).isInsideNP_with_border(p,domain,bc) == true)
997  {
998  ids_p.add(std::pair<size_t,size_t>(id1::id(vb_int.get(bid),bid),id2::id(vb_int.get(bid),bid)));
999  }
1000 
1001  ++cell_it;
1002  }
1003 
1004  // Make the id unique
1005  if (opt == UNIQUE)
1006  {
1007  ids_p.sort();
1008  ids_p.unique();
1009  }
1010 
1011  return ids_p;
1012  }
1013 
1031  template <typename id> inline const openfpm::vector<size_t> ghost_processorID(const Point<dim,T> & p, const int opt = MULTIPLE)
1032  {
1033  ids.clear();
1034 
1035  // Check with geo-cell if a particle is inside one Cell containing boxes
1036 
1037  auto cell_it = geo_cell.getCellIterator(geo_cell.getCell(p));
1038 
1039  // For each element in the cell, check if the point is inside the box
1040  // if it is, store the processor id
1041  while (cell_it.isNext())
1042  {
1043  size_t bid = cell_it.get();
1044 
1045  if (Box<dim,T>(vb_int_box.get(bid)).isInsideNP_with_border(p,domain,bc) == true)
1046  {
1047  ids.add(id::id(vb_int.get(bid),bid));
1048  }
1049 
1050  ++cell_it;
1051  }
1052 
1053  // Make the id unique
1054  if (opt == UNIQUE)
1055  {
1056  ids_p.sort();
1057  ids_p.unique();
1058  }
1059 
1060  return ids;
1061  }
1062 
1075  template<typename id1, typename id2, typename Mem> inline const openfpm::vector<std::pair<size_t,size_t>> & ghost_processorID_pair(const encapc<1,Point<dim,T>,Mem> & p, const int opt = MULTIPLE)
1076  {
1077  ids_p.clear();
1078 
1079  // Check with geo-cell if a particle is inside one Cell containing boxes
1080 
1081  auto cell_it = geo_cell.getCellIterator(geo_cell.getCell(p));
1082 
1083  // For each element in the cell, check if the point is inside the box
1084  // if it is, store the processor id
1085  while (cell_it.isNext())
1086  {
1087  size_t bid = cell_it.get();
1088 
1089  if (Box<dim,T>(vb_int_box.get(bid)).isInsideNP_with_border(p,domain,bc) == true)
1090  {
1091  ids_p.add(std::pair<size_t,size_t>(id1::id(vb_int.get(bid),bid),id2::id(vb_int.get(bid),bid)));
1092  }
1093 
1094  ++cell_it;
1095  }
1096 
1097  // Make the id unique
1098  if (opt == UNIQUE)
1099  {
1100  ids_p.sort();
1101  ids_p.unique();
1102  }
1103 
1104  return ids_p;
1105  }
1106 
1118  template<typename id, typename Mem> inline const openfpm::vector<size_t> & ghost_processorID(const encapc<1,Point<dim,T>,Mem> & p, const int opt = MULTIPLE)
1119  {
1120  ids.clear();
1121 
1122  // Check with geo-cell if a particle is inside one Cell containing boxes
1123 
1124  auto cell_it = geo_cell.getCellIterator(geo_cell.getCell(p));
1125 
1126  // For each element in the cell, check if the point is inside the box
1127  // if it is, store the processor id
1128  while (cell_it.isNext())
1129  {
1130  size_t bid = cell_it.get();
1131 
1132  if (vb_int.get(bid).box.isInsideNP_with_border(p,bc,domain) == true)
1133  {
1134  ids.add(id::id(vb_int.get(bid),bid));
1135  }
1136 
1137  ++cell_it;
1138  }
1139 
1140  // Make the id unique
1141  if (opt == UNIQUE)
1142  {
1143  ids_p.sort();
1144  ids_p.unique();
1145  }
1146 
1147  return ids;
1148  }
1149 
1162  bool write(std::string output, size_t p_id) const
1163  {
1165  VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box3;
1166  for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++)
1167  {
1168  for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++)
1169  {
1170  vtk_box3.add(box_nn_processor_int.get(p).get(s).nbx);
1171  }
1172  }
1173  vtk_box3.write(output + std::string("internal_ghost_") + std::to_string(p_id) + std::string(".vtk"));
1174 
1176  VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box4;
1177  for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++)
1178  {
1179  for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++)
1180  {
1181  vtk_box4.add(box_nn_processor_int.get(p).get(s).bx);
1182  }
1183  }
1184  vtk_box4.write(output + std::string("external_ghost_") + std::to_string(p_id) + std::string(".vtk"));
1185 
1186  return true;
1187  }
1188 
1197  {
1198  if (getNEGhostBox() != ig.getNEGhostBox())
1199  return false;
1200 
1201  if (getNIGhostBox() != ig.getNIGhostBox())
1202  return false;
1203 
1204  for (size_t i = 0 ; i < getNIGhostBox() ; i++)
1205  {
1206  if (getIGhostBox(i) != ig.getIGhostBox(i))
1207  return false;
1209  return false;
1210  }
1211 
1212  for (size_t i = 0 ; i < proc_int_box.size() ; i++)
1213  {
1214  if (getProcessorNIGhost(i) != ig.getProcessorNIGhost(i))
1215  return false;
1216  for (size_t j = 0 ; j < getProcessorNIGhost(i) ; j++)
1217  {
1218  if (getProcessorIGhostBox(i,j) != ig.getProcessorIGhostBox(i,j))
1219  return false;
1220  if (getProcessorIGhostId(i,j) != ig.getProcessorIGhostId(i,j))
1221  return false;
1222  if (getProcessorIGhostSub(i,j) != ig.getProcessorIGhostSub(i,j))
1223  return false;
1224  }
1225  }
1226 
1227  for (size_t i = 0 ; i < getNEGhostBox() ; i++)
1228  {
1229  if (getEGhostBox(i) != ig.getEGhostBox(i))
1230  return false;
1232  return false;
1233  }
1234 
1235  for (size_t i = 0 ; i < proc_int_box.size() ; i++)
1236  {
1237  if (getProcessorNEGhost(i) != ig.getProcessorNEGhost(i))
1238  return false;
1239  for (size_t j = 0 ; j < getProcessorNEGhost(i) ; j++)
1240  {
1241  if (getProcessorEGhostBox(i,j) != ig.getProcessorEGhostBox(i,j))
1242  return false;
1243  if (getProcessorEGhostId(i,j) != ig.getProcessorEGhostId(i,j))
1244  return false;
1245  if (getProcessorEGhostSub(i,j) != ig.getProcessorEGhostSub(i,j))
1246  return false;
1247  }
1248  }
1249 
1250  if (domain != ig.domain)
1251  {return false;}
1252 
1253  for (int i = 0 ; i < dim ; i++)
1254  {
1255  if (bc[i] != ig.bc[i])
1256  {return false;}
1257  }
1258 
1259  return true;
1260  }
1261 
1271  {
1272  return true;
1273  }
1274 
1278  void reset()
1279  {
1280  box_nn_processor_int.clear();
1281  proc_int_box.clear();
1282  vb_ext.clear();
1283  vb_int.clear();
1284  vb_int_box.clear();
1285  geo_cell.clear();
1286  shifts.clear();
1287  ids_p.clear();
1288  ids.clear();
1289  }
1290 
1297  {
1298  return box_nn_processor_int;
1299  }
1300 
1307  {
1308  return box_nn_processor_int;
1309  }
1310 
1317  {
1318  return proc_int_box;
1319  }
1320 
1327  {
1328  return proc_int_box;
1329  }
1330 
1337  {
1338  return vb_ext;
1339  }
1340 
1347  {
1348  return vb_ext;
1349  }
1350 
1358  {
1359  return vb_int;
1360  }
1361 
1369  {
1370  return vb_int;
1371  }
1372 
1378  inline openfpm::vector<Box<dim,T>,Memory,layout_base> &
1380  {
1381  return vb_int_box;
1382  }
1383 
1389  inline const openfpm::vector<Box<dim,T>,Memory,layout_base> &
1391  {
1392  return vb_int_box;
1393  }
1394 
1402  {
1403  return geo_cell;
1404  }
1405 
1413  {
1414  return geo_cell;
1415  }
1416 
1422  inline openfpm::vector<Point<dim,T>,Memory,layout_base> &
1424  {
1425  return shifts;
1426  }
1427 
1433  inline const openfpm::vector<Point<dim,T>,Memory,layout_base> &
1435  {
1436  return shifts;
1437  }
1438 
1446  {
1447  return ids_p;
1448  }
1449 
1457  {
1458  return ids_p;
1459  }
1460 
1466  inline openfpm::vector<size_t> &
1468  {
1469  return ids;
1470  }
1471 
1477  inline const openfpm::vector<size_t> &
1479  {
1480  return ids;
1481  }
1482 
1488  inline Box<dim,T> &
1490  {
1491  return domain;
1492  }
1493 
1499  inline const Box<dim,T> &
1501  {
1502  return domain;
1503  }
1504 
1505  size_t private_get_bc(int i) const
1506  {
1507  return bc[i];
1508  }
1509 
1515  inline size_t (& private_get_bc())[dim]
1516  {
1517  return bc;
1518  }
1519 
1526  {
1527  if (host_dev_transfer == false)
1528  {
1529  geo_cell.hostToDevice();
1530  vb_int_box.template hostToDevice<0,1>();
1531  vb_int.template hostToDevice<0,1,2>();
1532  shifts.template hostToDevice<0>();
1533 
1534  host_dev_transfer = true;
1535  }
1536 
1538  vb_int_box.toKernel(),
1539  vb_int.toKernel());
1540 
1541  return igg;
1542  }
1543 
1549  {
1550  host_dev_transfer = false;
1551  }
1552 };
1553 
1554 
1555 #endif /* SRC_DECOMPOSITION_IE_GHOST_HPP_ */
const openfpm::vector< Box_dom< dim, T > > & private_get_proc_int_box() const
Return the internal data structure proc_int_box.
Definition: ie_ghost.hpp:1326
const openfpm::vector< p_box< dim, T > > & private_get_vb_ext() const
Return the internal data structure vb_ext.
Definition: ie_ghost.hpp:1346
void ghost_processor_ID(const Point< dim, T > &p, output_type &output, unsigned int base, unsigned int pi)
Get the number of processor a particle must sent.
Definition: ie_ghost.hpp:948
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
void addCell(size_t cell_id, typename Mem_type::local_index_type ele)
Add to the cell.
Definition: CellList.hpp:715
const openfpm::vector< comb< dim > > & getNearSubdomainsPos(size_t p_id) const
Get the sub-domains sector position of a near processor.
size_t getProcessUnitID()
Get the process unit id.
bool isNext()
Check if there is the next element.
size_t getProcessorEGhostId(size_t id, size_t j) const
Get the j External ghost box id.
Definition: ie_ghost.hpp:804
size_t ProctoID(size_t p) const
Convert the processor rank to the id in the list.
size_t(& private_get_bc())[dim]
Return the internal data structure domain.
Definition: ie_ghost.hpp:1515
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
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:34
void reorder_geo_cell()
in this function we reorder the list in each cells by processor id
Definition: ie_ghost.hpp:486
const openfpm::vector< size_t > & getSentSubdomains(size_t p_id) const
For each near processor it give a vector with the id of the local sub-domain sent to that processor.
openfpm::vector< aggregate< unsigned int, unsigned int, unsigned int >, Memory, layout_base > & private_get_vb_int()
Return the internal data structure vb_int.
Definition: ie_ghost.hpp:1357
const openfpm::vector< Point< dim, T >, Memory, layout_base > & private_get_shifts() const
Return the internal data structure shifts.
Definition: ie_ghost.hpp:1434
const openfpm::vector< Point< dim, T >, Memory, layout_base > & getShiftVectors()
Definition: ie_ghost.hpp:683
const openfpm::vector< size_t > ghost_processorID(const Point< dim, T > &p, const int opt=MULTIPLE)
Given a position it return if the position belong to any neighborhood processor ghost (Internal ghost...
Definition: ie_ghost.hpp:1031
const openfpm::vector< openfpm::vector< Box_proc< dim, T > > > & private_get_box_nn_processor_int() const
Return the internal data structure box_nn_processor_int.
Definition: ie_ghost.hpp:1296
void clear()
Clear the cell list.
Definition: CellList.hpp:1100
openfpm::vector< Box_dom< dim, T > > & private_get_proc_int_box()
Return the internal data structure proc_int_box.
Definition: ie_ghost.hpp:1316
const openfpm::vector< size_t > & private_get_ids() const
Return the internal data structure ids_p.
Definition: ie_ghost.hpp:1478
size_t link_ebx_ibx(const nn_prcs< dim, T, layout_base, Memory > &nn_p, size_t p_id, size_t i)
Given a local sub-domain i, it give the id of such sub-domain in the sent list for the processor p_id...
Definition: ie_ghost.hpp:109
Point< dim, T > getP2() const
Get the point p2.
Definition: Box.hpp:722
size_t getNearProcessor(size_t p_id) const
Get the near processor id.
size_t getNNProcessors() const
Get the number of Near processors.
size_t sub
Domain id.
Definition: common.hpp:95
void destroy()
Litterary destroy the memory of the cell list, including the retained one.
Definition: CellList.hpp:1108
size_t getNIGhostBox() const
Return the total number of the calculated internal ghost boxes.
Definition: ie_ghost.hpp:854
void sign_flip()
Flip the sign of the combination.
Definition: comb.hpp:124
const CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > & private_geo_cell() const
Return the internal data structure proc_int_box.
Definition: ie_ghost.hpp:1412
ie_ghost()
Default constructor.
Definition: ie_ghost.hpp:526
bool operator<(const proc_box_id &pbi) const
operator to reorder
Definition: ie_ghost.hpp:24
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
const openfpm::vector< std::pair< size_t, size_t > > & ghost_processorID_pair(const encapc< 1, Point< dim, T >, Mem > &p, const int opt=MULTIPLE)
Given a position it return if the position belong to any neighborhood processor ghost (Internal ghost...
Definition: ie_ghost.hpp:1075
size_t size()
Stub size.
Definition: map_vector.hpp:211
Processor id and box id.
Definition: ie_ghost.hpp:17
Case for external ghost box.
Definition: common.hpp:173
const Box< dim, T > & private_get_domain() const
Return the internal data structure domain.
Definition: ie_ghost.hpp:1500
openfpm::vector< std::pair< size_t, size_t > > ids_p
Temporal buffers to return temporal information for ghost_processorID.
Definition: ie_ghost.hpp:76
openfpm::vector< p_box< dim, T > > vb_ext
External ghost boxes for this processor.
Definition: ie_ghost.hpp:59
size_t getProcessorEGhostSub(size_t id, size_t j) const
Get the local sub-domain at witch belong the external ghost box.
Definition: ie_ghost.hpp:844
size_t getNelements(const size_t cell_id) const
Return the number of elements in the cell.
Definition: CellList.hpp:852
const grid_sm< dim, void > & getGrid()
Return the underlying grid information of the cell list.
Definition: CellList.hpp:447
CellIterator< CellList< dim, T, Mem_type, transform > > getCellIterator(size_t cell)
Get the Cell iterator.
Definition: CellList.hpp:912
size_t ebx_ibx_form(size_t k, size_t b, size_t p_id, const comb< dim > &c, size_t N_b, Vcluster<> &v_cl, const bool ei)
This is the external and internal ghost box link formula.
Definition: ie_ghost.hpp:179
Definition: Ghost.hpp:39
size_t convertShift(const comb< dim > &cmb)
Definition: ie_ghost.hpp:702
bool host_dev_transfer
host to device transfer
Definition: ie_ghost.hpp:85
size_t getEGhostBoxProcessor(size_t b_id) const
Given the external ghost box id, it return the near processor at witch belong or the near processor t...
Definition: ie_ghost.hpp:914
const comb< dim > & getProcessorEGhostPos(size_t id, size_t j) const
Get the j External ghost box sector.
Definition: ie_ghost.hpp:760
Implementation of VCluster class.
Definition: VCluster.hpp:58
openfpm::vector< aggregate< unsigned int, unsigned int, unsigned int >, Memory, layout_base > vb_int
Internal ghost boxes for this processor domain.
Definition: ie_ghost.hpp:62
const openfpm::vector< size_t > & ghost_processorID(const encapc< 1, Point< dim, T >, Mem > &p, const int opt=MULTIPLE)
Given a position it return if the position belong to any neighborhood processor ghost (Internal ghost...
Definition: ie_ghost.hpp:1118
size_t getProcessorNIGhost(size_t id) const
Get the number of Internal ghost boxes for one processor.
Definition: ie_ghost.hpp:713
mem_id LinId(const grid_key_dx< N, ids_type > &gk, const char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:434
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 free_geo_cell()
Deallocate structures that identify a point to which internal ghost is located.
Definition: ie_ghost.hpp:226
const openfpm::vector< size_t > & getNearSubdomainsRealId(size_t p_id) const
Get the real-id of the sub-domains of a near processor.
size_t lc_proc
local processor id
Definition: common.hpp:305
size_t getNEGhostBox() const
Get the number of the calculated external ghost boxes.
Definition: ie_ghost.hpp:889
const openfpm::vector< std::pair< size_t, size_t > > & private_get_ids_p() const
Return the internal data structure ids_p.
Definition: ie_ghost.hpp:1456
void generateShiftVectors(const Box< dim, T > &domain, size_t(&bc)[dim])
Here we generare the shift vectors.
Definition: ie_ghost.hpp:196
size_t lin() const
Linearization.
Definition: comb.hpp:376
Box< dim, T > domain
domain
Definition: ie_ghost.hpp:88
bool write(std::string output, size_t p_id) const
write the information about the ghost in vtk format
Definition: ie_ghost.hpp:1162
inline ::Box< dim, T > getIGhostBox(size_t b_id) const
Given the internal ghost box id, it return the internal ghost box.
Definition: ie_ghost.hpp:866
CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > & private_geo_cell()
Return the internal data structure proc_int_box.
Definition: ie_ghost.hpp:1401
Box< dim, T > bx
Internal ghost box definition.
Definition: common.hpp:92
bool is_equal_ng(ie_ghost< dim, T, Memory, layout_base > &ig)
Check if the ie_loc_ghosts contain the same information with the exception of the ghost part It is an...
Definition: ie_ghost.hpp:1270
comb< dim > cmb
see ie_ghost follow sector explanation
Definition: common.hpp:104
ie_ghost< dim, T, Memory, layout_base > & operator=(const ie_ghost< dim, T, Memory, layout_base > &ie)
Copy operator.
Definition: ie_ghost.hpp:563
const openfpm::vector< Box< dim, T >, Memory, layout_base > & private_get_vb_int_box() const
Return the internal data structure vb_int_box.
Definition: ie_ghost.hpp:1390
size_t bc[dim]
boundary conditions
Definition: ie_ghost.hpp:91
const openfpm::vector< aggregate< unsigned int, unsigned int, unsigned int >, Memory, layout_base > & private_get_vb_int() const
Return the internal data structure vb_int.
Definition: ie_ghost.hpp:1368
const grid_key_dx< dim > & get() const
Get the actual key.
::Box< dim, T > box
Definition: common.hpp:303
grid_key_dx< dim > get() const
Return the actual grid key iterator.
structure that store and compute the internal and external local ghost box
Definition: ie_ghost.hpp:47
openfpm::vector< Box< dim, T >, Memory, layout_base > vb_int_box
Internal ghost boxes for this processor domain.
Definition: ie_ghost.hpp:65
const ::Box< dim, T > & getProcessorEGhostBox(size_t id, size_t j) const
Get the j External ghost box.
Definition: ie_ghost.hpp:748
ie_ghost< dim, T, Memory2, layout_base2 > duplicate()
duplicate this structure changing layout and Memory
Definition: ie_ghost.hpp:613
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:823
size_t shift_id
shift vector id
Definition: common.hpp:310
size_t id
see ebx_ibx_form in ie_ghost for the meaning
Definition: common.hpp:98
void reset_host_dev_transfer()
Notify that the next toKernel() data-structures must be re-offloaded.
Definition: ie_ghost.hpp:1548
size_t getProcessingUnits()
Get the total number of processors.
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 proc
processor rank
Definition: common.hpp:307
size_t getProcessorIGhostSSub(size_t id, size_t j) const
Get the sub-domain send-id at witch belong the internal ghost box.
Definition: ie_ghost.hpp:820
This class represent an N-dimensional box.
Definition: Box.hpp:60
size_t r_sub
see getNearSubdomainsRealId in nn_prcs
Definition: common.hpp:101
size_t getIGhostBoxProcessor(size_t b_id) const
Given the internal ghost box id, it return the near processor at witch belong or the near processor t...
Definition: ie_ghost.hpp:879
ie_ghost< dim, T, Memory, layout_base > & operator=(ie_ghost< dim, T, Memory, layout_base > &&ie)
Copy operator.
Definition: ie_ghost.hpp:541
size_t getProcessorIGhostId(size_t id, size_t j) const
Get the j Internal ghost box id.
Definition: ie_ghost.hpp:788
structure that store and compute the internal and external local ghost box. Version usable in kernel
openfpm::vector< std::pair< size_t, size_t > > & private_get_ids_p()
Return the internal data structure ids_p.
Definition: ie_ghost.hpp:1445
openfpm::vector< openfpm::vector< Box_proc< dim, T > > > & private_get_box_nn_processor_int()
Return the internal data structure box_nn_processor_int.
Definition: ie_ghost.hpp:1306
unsigned int ghost_processorID_N(const Point< dim, T > &p)
Get the number of processor a particle must sent.
Definition: ie_ghost.hpp:960
CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > geo_cell
Cell-list that store the geometrical information of the internal ghost boxes.
Definition: ie_ghost.hpp:68
openfpm::vector< Point< dim, T >, Memory, layout_base > shifts
shift vectors
Definition: ie_ghost.hpp:73
in case of high dimensions shift vector converter
openfpm::vector< size_t > & private_get_ids()
Return the internal data structure ids_p.
Definition: ie_ghost.hpp:1467
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:95
openfpm::vector< openfpm::vector< Box_proc< dim, T > > > box_nn_processor_int
Definition: ie_ghost.hpp:53
void swap(CellList< dim, T, Mem_type, transform, vector_pos_type > &cl)
Swap the memory.
Definition: CellList.hpp:892
Box< dim, T > & private_get_domain()
Return the internal data structure domain.
Definition: ie_ghost.hpp:1489
openfpm::vector< Box_dom< dim, T > > proc_int_box
It store the same information of box_nn_processor_int organized by processor id.
Definition: ie_ghost.hpp:56
size_t getNRealSubdomains(size_t p_id) const
Get the number of real sub-domains of a near processor.
openfpm::vector< p_box< dim, T > > & private_get_vb_ext()
Return the internal data structure vb_ext.
Definition: ie_ghost.hpp:1336
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 openfpm::vector< std::pair< size_t, size_t > > ghost_processorID_pair(Point< dim, T > &p, const int opt=MULTIPLE)
Given a position it return if the position belong to any neighborhood processor ghost (Internal ghost...
Definition: ie_ghost.hpp:982
bool is_equal(ie_ghost< dim, T, Memory, layout_base > &ig)
Check if the ie_ghosts contain the same information.
Definition: ie_ghost.hpp:1196
const ::Box< dim, T > & getProcessorIGhostBox(size_t id, size_t j) const
Get the j Internal ghost box for one processor.
Definition: ie_ghost.hpp:736
const openfpm::vector< ::Box< dim, T > > & getNearSubdomains(size_t p_id) const
Get the sub-domains of a near processor.
It store all the boxes of the near processors in a linear array.
Definition: common.hpp:299
openfpm::vector_std< Box_sub< dim, T > > ebx
Definition: common.hpp:177
ie_ghost< dim, T, Memory, layout_base > & operator=(const ie_ghost< dim, T, Memory2, layout_base2 > &ie)
Copy operator.
Definition: ie_ghost.hpp:586
size_t getProcessorNEGhost(size_t id) const
Get the number of External ghost boxes for one processor id.
Definition: ie_ghost.hpp:724
const comb< dim > & getProcessorIGhostPos(size_t id, size_t j) const
Get the ghost box sector of the external ghost box linked with the j internal ghost box.
Definition: ie_ghost.hpp:772
size_t getProcessorIGhostSub(size_t id, size_t j) const
Get the local sub-domain at witch belong the internal ghost box.
Definition: ie_ghost.hpp:832
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
Class for FAST cell list implementation.
Definition: CellList.hpp:356
ie_ghost(ie_ghost< dim, T, Memory, layout_base > &&ie)
Copy constructor.
Definition: ie_ghost.hpp:535
bool isNext()
Check if there is the next element.
auto get(size_t cell, size_t ele) -> decltype(this->Mem_type::get(cell, ele))
Get an element in the cell.
Definition: CellList.hpp:867
auto labelPoint(Point< dim, T > &p) -> decltype(geo_cell.getCellIterator(geo_cell.getCell(p)))
if the point fall into the ghost of some near processor it return the processors id's in which it fal...
Definition: ie_ghost.hpp:938
shift_vect_converter< dim, T, Memory, layout_base > sc_convert
shift converter
Definition: ie_ghost.hpp:82
Point< dim, T > getP1() const
Get the point p1.
Definition: Box.hpp:708
inline ::Box< dim, T > getEGhostBox(size_t b_id) const
Given the external ghost box id, it return the external ghost box.
Definition: ie_ghost.hpp:901
openfpm::vector< Box< dim, T >, Memory, layout_base > & private_get_vb_int_box()
Return the internal data structure vb_int_box.
Definition: ie_ghost.hpp:1379
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
openfpm::vector< size_t > ids
Temporal buffers to return temporal information.
Definition: ie_ghost.hpp:79
ie_ghost(const ie_ghost< dim, T, Memory, layout_base > &ie)
Copy constructor.
Definition: ie_ghost.hpp:529
openfpm::vector< Point< dim, T >, Memory, layout_base > & private_get_shifts()
Return the internal data structure shifts.
Definition: ie_ghost.hpp:1423
void reset()
Reset the nn_prcs structure.
Definition: ie_ghost.hpp:1278
auto getInternalIDBoxes(Point< dim, T > &p) -> decltype(geo_cell.getCellIterator(geo_cell.getCell(p)))
Definition: ie_ghost.hpp:926
This class store the adjacent processors and the adjacent sub_domains.