OpenFPM  5.2.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<Box<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  Box<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<Box<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  ::Box<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.getParticleInCellIterator(geo_cell.getCell(p));
929  }
930 
938  inline auto labelPoint(Point<dim,T> & p) -> decltype(geo_cell.getParticleInCellIterator(geo_cell.getCell(p)))
939  {
940  return geo_cell.getParticleInCellIterator(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  int cellID = geo_cell.getCell(p);
988 
989  if (cellID == -1)
990  return ids_p;
991 
992  auto cell_it = geo_cell.getParticleInCellIterator(cellID);
993 
994  // For each element in the cell, check if the point is inside the box
995  // if it is, store the processor id
996  while (cell_it.isNext())
997  {
998  size_t bid = cell_it.get();
999 
1000  if (Box<dim,T>(vb_int_box.get(bid)).isInsideNP_with_border(p,domain,bc) == true)
1001  {
1002  ids_p.add(std::pair<size_t,size_t>(id1::id(vb_int.get(bid),bid),id2::id(vb_int.get(bid),bid)));
1003  }
1004 
1005  ++cell_it;
1006  }
1007 
1008  // Make the id unique
1009  if (opt == UNIQUE)
1010  {
1011  ids_p.sort();
1012  ids_p.unique();
1013  }
1014 
1015  return ids_p;
1016  }
1017 
1035  template <typename id> inline const openfpm::vector<size_t> ghost_processorID(const Point<dim,T> & p, const int opt = MULTIPLE)
1036  {
1037  ids.clear();
1038 
1039  // Check with geo-cell if a particle is inside one Cell containing boxes
1040 
1041  int cellID = geo_cell.getCell(p);
1042 
1043  if (cellID == -1)
1044  return ids;
1045 
1046  auto cell_it = geo_cell.getParticleInCellIterator(cellID);
1047 
1048  // For each element in the cell, check if the point is inside the box
1049  // if it is, store the processor id
1050  while (cell_it.isNext())
1051  {
1052  size_t bid = cell_it.get();
1053 
1054  if (Box<dim,T>(vb_int_box.get(bid)).isInsideNP_with_border(p,domain,bc) == true)
1055  {
1056  ids.add(id::id(vb_int.get(bid),bid));
1057  }
1058 
1059  ++cell_it;
1060  }
1061 
1062  // Make the id unique
1063  if (opt == UNIQUE)
1064  {
1065  ids_p.sort();
1066  ids_p.unique();
1067  }
1068 
1069  return ids;
1070  }
1071 
1084  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)
1085  {
1086  ids_p.clear();
1087 
1088  // Check with geo-cell if a particle is inside one Cell containing boxes
1089 
1090  int cellID = geo_cell.getCell(p);
1091 
1092  if (cellID == -1)
1093  return ids_p;
1094 
1095  auto cell_it = geo_cell.getParticleInCellIterator(cellID);
1096 
1097  // For each element in the cell, check if the point is inside the box
1098  // if it is, store the processor id
1099  while (cell_it.isNext())
1100  {
1101  size_t bid = cell_it.get();
1102 
1103  if (Box<dim,T>(vb_int_box.get(bid)).isInsideNP_with_border(p,domain,bc) == true)
1104  {
1105  ids_p.add(std::pair<size_t,size_t>(id1::id(vb_int.get(bid),bid),id2::id(vb_int.get(bid),bid)));
1106  }
1107 
1108  ++cell_it;
1109  }
1110 
1111  // Make the id unique
1112  if (opt == UNIQUE)
1113  {
1114  ids_p.sort();
1115  ids_p.unique();
1116  }
1117 
1118  return ids_p;
1119  }
1120 
1132  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)
1133  {
1134  ids.clear();
1135 
1136  // Check with geo-cell if a particle is inside one Cell containing boxes
1137 
1138  int cellID = geo_cell.getCell(p);
1139 
1140  if (cellID == -1)
1141  return ids;
1142 
1143  auto cell_it = geo_cell.getParticleInCellIterator(cellID);
1144 
1145  // For each element in the cell, check if the point is inside the box
1146  // if it is, store the processor id
1147  while (cell_it.isNext())
1148  {
1149  size_t bid = cell_it.get();
1150 
1151  if (vb_int.get(bid).box.isInsideNP_with_border(p,bc,domain) == true)
1152  {
1153  ids.add(id::id(vb_int.get(bid),bid));
1154  }
1155 
1156  ++cell_it;
1157  }
1158 
1159  // Make the id unique
1160  if (opt == UNIQUE)
1161  {
1162  ids_p.sort();
1163  ids_p.unique();
1164  }
1165 
1166  return ids;
1167  }
1168 
1181  bool write(std::string output, size_t p_id) const
1182  {
1184  VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box3;
1185  for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++)
1186  {
1187  for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++)
1188  {
1189  vtk_box3.add(box_nn_processor_int.get(p).get(s).nbx);
1190  }
1191  }
1192  vtk_box3.write(output + std::string("internal_ghost_") + std::to_string(p_id) + std::string(".vtk"));
1193 
1195  VTKWriter<openfpm::vector<::Box<dim,T>>,VECTOR_BOX> vtk_box4;
1196  for (size_t p = 0 ; p < box_nn_processor_int.size() ; p++)
1197  {
1198  for (size_t s = 0 ; s < box_nn_processor_int.get(p).size() ; s++)
1199  {
1200  vtk_box4.add(box_nn_processor_int.get(p).get(s).bx);
1201  }
1202  }
1203  vtk_box4.write(output + std::string("external_ghost_") + std::to_string(p_id) + std::string(".vtk"));
1204 
1205  return true;
1206  }
1207 
1216  {
1217  if (getNEGhostBox() != ig.getNEGhostBox())
1218  return false;
1219 
1220  if (getNIGhostBox() != ig.getNIGhostBox())
1221  return false;
1222 
1223  for (size_t i = 0 ; i < getNIGhostBox() ; i++)
1224  {
1225  if (getIGhostBox(i) != ig.getIGhostBox(i))
1226  return false;
1228  return false;
1229  }
1230 
1231  for (size_t i = 0 ; i < proc_int_box.size() ; i++)
1232  {
1233  if (getProcessorNIGhost(i) != ig.getProcessorNIGhost(i))
1234  return false;
1235  for (size_t j = 0 ; j < getProcessorNIGhost(i) ; j++)
1236  {
1237  if (getProcessorIGhostBox(i,j) != ig.getProcessorIGhostBox(i,j))
1238  return false;
1239  if (getProcessorIGhostId(i,j) != ig.getProcessorIGhostId(i,j))
1240  return false;
1241  if (getProcessorIGhostSub(i,j) != ig.getProcessorIGhostSub(i,j))
1242  return false;
1243  }
1244  }
1245 
1246  for (size_t i = 0 ; i < getNEGhostBox() ; i++)
1247  {
1248  if (getEGhostBox(i) != ig.getEGhostBox(i))
1249  return false;
1251  return false;
1252  }
1253 
1254  for (size_t i = 0 ; i < proc_int_box.size() ; i++)
1255  {
1256  if (getProcessorNEGhost(i) != ig.getProcessorNEGhost(i))
1257  return false;
1258  for (size_t j = 0 ; j < getProcessorNEGhost(i) ; j++)
1259  {
1260  if (getProcessorEGhostBox(i,j) != ig.getProcessorEGhostBox(i,j))
1261  return false;
1262  if (getProcessorEGhostId(i,j) != ig.getProcessorEGhostId(i,j))
1263  return false;
1264  if (getProcessorEGhostSub(i,j) != ig.getProcessorEGhostSub(i,j))
1265  return false;
1266  }
1267  }
1268 
1269  if (domain != ig.domain)
1270  {return false;}
1271 
1272  for (int i = 0 ; i < dim ; i++)
1273  {
1274  if (bc[i] != ig.bc[i])
1275  {return false;}
1276  }
1277 
1278  return true;
1279  }
1280 
1290  {
1291  return true;
1292  }
1293 
1297  void reset()
1298  {
1299  box_nn_processor_int.clear();
1300  proc_int_box.clear();
1301  vb_ext.clear();
1302  vb_int.clear();
1303  vb_int_box.clear();
1304  geo_cell.clear();
1305  shifts.clear();
1306  ids_p.clear();
1307  ids.clear();
1308  }
1309 
1316  {
1317  return box_nn_processor_int;
1318  }
1319 
1326  {
1327  return box_nn_processor_int;
1328  }
1329 
1336  {
1337  return proc_int_box;
1338  }
1339 
1346  {
1347  return proc_int_box;
1348  }
1349 
1356  {
1357  return vb_ext;
1358  }
1359 
1366  {
1367  return vb_ext;
1368  }
1369 
1377  {
1378  return vb_int;
1379  }
1380 
1388  {
1389  return vb_int;
1390  }
1391 
1397  inline openfpm::vector<Box<dim,T>,Memory,layout_base> &
1399  {
1400  return vb_int_box;
1401  }
1402 
1408  inline const openfpm::vector<Box<dim,T>,Memory,layout_base> &
1410  {
1411  return vb_int_box;
1412  }
1413 
1421  {
1422  return geo_cell;
1423  }
1424 
1432  {
1433  return geo_cell;
1434  }
1435 
1441  inline openfpm::vector<Point<dim,T>,Memory,layout_base> &
1443  {
1444  return shifts;
1445  }
1446 
1452  inline const openfpm::vector<Point<dim,T>,Memory,layout_base> &
1454  {
1455  return shifts;
1456  }
1457 
1465  {
1466  return ids_p;
1467  }
1468 
1476  {
1477  return ids_p;
1478  }
1479 
1485  inline openfpm::vector<size_t> &
1487  {
1488  return ids;
1489  }
1490 
1496  inline const openfpm::vector<size_t> &
1498  {
1499  return ids;
1500  }
1501 
1507  inline Box<dim,T> &
1509  {
1510  return domain;
1511  }
1512 
1518  inline const Box<dim,T> &
1520  {
1521  return domain;
1522  }
1523 
1524  size_t private_get_bc(int i) const
1525  {
1526  return bc[i];
1527  }
1528 
1534  inline size_t (& private_get_bc())[dim]
1535  {
1536  return bc;
1537  }
1538 
1545  {
1546  if (host_dev_transfer == false)
1547  {
1548  geo_cell.hostToDevice();
1549  vb_int_box.template hostToDevice<0,1>();
1550  vb_int.template hostToDevice<0,1,2>();
1551  shifts.template hostToDevice<0>();
1552 
1553  host_dev_transfer = true;
1554  }
1555 
1557  vb_int_box.toKernel(),
1558  vb_int.toKernel());
1559 
1560  return igg;
1561  }
1562 
1568  {
1569  host_dev_transfer = false;
1570  }
1571 };
1572 
1573 
1574 #endif /* SRC_DECOMPOSITION_IE_GHOST_HPP_ */
This class represent an N-dimensional box.
Definition: Box.hpp:60
Point< dim, T > getP1() const
Get the point p1.
Definition: Box.hpp:707
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:94
Point< dim, T > getP2() const
Get the point p2.
Definition: Box.hpp:721
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:822
__device__ __host__ bool isInsideNP_with_border(const Point< dim, T > &p, const Box< dim, T > &border, const bc_type(&bc)[dim]) const
Check if the point is inside the region excluding the positive part.
Definition: Box.hpp:1077
Class for FAST cell list implementation.
Definition: CellList.hpp:558
size_t getNelements(const size_t cell_id) const
Return the number of elements in the cell.
Definition: CellList.hpp:1106
const grid_sm< dim, void > & getGrid()
Return the underlying grid information of the cell list.
Definition: CellList.hpp:713
auto get(size_t cell, size_t ele) -> decltype(this->Mem_type::get(cell, ele))
Get an element in the cell.
Definition: CellList.hpp:1121
void clear()
Clear the cell list.
Definition: CellList.hpp:1410
void destroy()
Litterary destroy the memory of the cell list, including the retained one.
Definition: CellList.hpp:1427
void swap(CellList< dim, T, Mem_type, transform, vector_pos_type > &cl)
Swap the memory.
Definition: CellList.hpp:1146
CellIterator< CellList< dim, T, Mem_type, transform > > getParticleInCellIterator(size_t cell)
Get the Cell iterator.
Definition: CellList.hpp:1171
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:731
Definition: Ghost.hpp:40
void addCell(local_index cell_id, local_index ele)
Add an element to the cell.
Definition: MemFast.hpp:248
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
size_t getProcessUnitID()
Get the process unit id.
size_t getProcessingUnits()
Get the total number of processors.
Implementation of VCluster class.
Definition: VCluster.hpp:59
bool isNext()
Check if there is the next element.
grid_key_dx< dim > get() const
Return the actual grid key iterator.
const grid_key_dx< dim > & get() const
Get the actual key.
bool isNext()
Check if there is the next element.
mem_id LinId(const grid_key_dx< N, ids_type > &gk, const signed char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:454
structure that store and compute the internal and external local ghost box. Version usable in kernel
structure that store and compute the internal and external local ghost box
Definition: ie_ghost.hpp:48
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 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
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
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:1475
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:1325
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:1035
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:1132
bool host_dev_transfer
host to device transfer
Definition: ie_ghost.hpp:85
void reset_host_dev_transfer()
Notify that the next toKernel() data-structures must be re-offloaded.
Definition: ie_ghost.hpp:1567
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:1431
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:1315
openfpm::vector< openfpm::vector< Box_proc< dim, T > > > box_nn_processor_int
Definition: ie_ghost.hpp:53
openfpm::vector< Box_dom< dim, T > > & private_get_proc_int_box()
Return the internal data structure proc_int_box.
Definition: ie_ghost.hpp:1335
size_t(& private_get_bc())[dim]
Return the internal data structure domain.
Definition: ie_ghost.hpp:1534
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
size_t getProcessorNEGhost(size_t id) const
Get the number of External ghost boxes for one processor id.
Definition: ie_ghost.hpp:724
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:1376
ie_ghost< dim, T, Memory2, layout_base2 > duplicate()
duplicate this structure changing layout and Memory
Definition: ie_ghost.hpp:613
openfpm::vector< std::pair< size_t, size_t > > & private_get_ids_p()
Return the internal data structure ids_p.
Definition: ie_ghost.hpp:1464
void free_geo_cell()
Deallocate structures that identify a point to which internal ghost is located.
Definition: ie_ghost.hpp:226
shift_vect_converter< dim, T, Memory, layout_base > sc_convert
shift converter
Definition: ie_ghost.hpp:82
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
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
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
openfpm::vector< Point< dim, T >, Memory, layout_base > shifts
shift vectors
Definition: ie_ghost.hpp:73
ie_ghost(const ie_ghost< dim, T, Memory, layout_base > &ie)
Copy constructor.
Definition: ie_ghost.hpp:529
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:1387
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:1409
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
ie_ghost< dim, T, Memory, layout_base > & operator=(ie_ghost< dim, T, Memory, layout_base > &&ie)
Copy operator.
Definition: ie_ghost.hpp:541
openfpm::vector< p_box< dim, T > > vb_ext
External ghost boxes for this processor.
Definition: ie_ghost.hpp:59
openfpm::vector< Box< dim, T >, Memory, layout_base > vb_int_box
Internal ghost boxes for this processor domain.
Definition: ie_ghost.hpp:65
void reset()
Reset the nn_prcs structure.
Definition: ie_ghost.hpp:1297
unsigned int ghost_processorID_N(const Point< dim, T > &p)
Get the number of processor a particle must sent.
Definition: ie_ghost.hpp:960
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:1084
openfpm::vector< p_box< dim, T > > & private_get_vb_ext()
Return the internal data structure vb_ext.
Definition: ie_ghost.hpp:1355
ie_ghost(ie_ghost< dim, T, Memory, layout_base > &&ie)
Copy constructor.
Definition: ie_ghost.hpp:535
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
bool write(std::string output, size_t p_id) const
write the information about the ghost in vtk format
Definition: ie_ghost.hpp:1181
void create_box_nn_processor_int(Vcluster<> &v_cl, Ghost< dim, T > &ghost, openfpm::vector< Box< 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
size_t bc[dim]
boundary conditions
Definition: ie_ghost.hpp:91
size_t getProcessorEGhostId(size_t id, size_t j) const
Get the j External ghost box id.
Definition: ie_ghost.hpp:804
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:1420
void generateShiftVectors(const Box< dim, T > &domain, size_t(&bc)[dim])
Here we generare the shift vectors.
Definition: ie_ghost.hpp:196
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
openfpm::vector< size_t > ids
Temporal buffers to return temporal information.
Definition: ie_ghost.hpp:79
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
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< Point< dim, T >, Memory, layout_base > & private_get_shifts()
Return the internal data structure shifts.
Definition: ie_ghost.hpp:1442
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
const Box< dim, T > & private_get_domain() const
Return the internal data structure domain.
Definition: ie_ghost.hpp:1519
const openfpm::vector< p_box< dim, T > > & private_get_vb_ext() const
Return the internal data structure vb_ext.
Definition: ie_ghost.hpp:1365
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
const openfpm::vector< size_t > & private_get_ids() const
Return the internal data structure ids_p.
Definition: ie_ghost.hpp:1497
size_t getProcessorNIGhost(size_t id) const
Get the number of Internal ghost boxes for one processor.
Definition: ie_ghost.hpp:713
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
openfpm::vector< size_t > & private_get_ids()
Return the internal data structure ids_p.
Definition: ie_ghost.hpp:1486
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:1215
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:1398
ie_ghost< dim, T, Memory, layout_base > & operator=(const ie_ghost< dim, T, Memory, layout_base > &ie)
Copy operator.
Definition: ie_ghost.hpp:563
ie_ghost()
Default constructor.
Definition: ie_ghost.hpp:526
const openfpm::vector< Point< dim, T >, Memory, layout_base > & getShiftVectors()
Definition: ie_ghost.hpp:683
auto labelPoint(Point< dim, T > &p) -> decltype(geo_cell.getParticleInCellIterator(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
ie_ghost_gpu< dim, T, Memory, layout_base > toKernel()
toKernel() Convert this data-structure into a kernel usable data-structure
Definition: ie_ghost.hpp:1544
const ::Box< dim, T > & getProcessorEGhostBox(size_t id, size_t j) const
Get the j External ghost box.
Definition: ie_ghost.hpp:748
size_t getNEGhostBox() const
Get the number of the calculated external ghost boxes.
Definition: ie_ghost.hpp:889
const comb< dim > & getProcessorEGhostPos(size_t id, size_t j) const
Get the j External ghost box sector.
Definition: ie_ghost.hpp:760
void create_box_nn_processor_ext(Vcluster<> &v_cl, Ghost< dim, T > &ghost, openfpm::vector< Box< 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< Box_dom< dim, T > > & private_get_proc_int_box() const
Return the internal data structure proc_int_box.
Definition: ie_ghost.hpp:1345
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
auto getInternalIDBoxes(Point< dim, T > &p) -> decltype(geo_cell.getParticleInCellIterator(geo_cell.getCell(p)))
Definition: ie_ghost.hpp:926
size_t convertShift(const comb< dim > &cmb)
Definition: ie_ghost.hpp:702
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
Box< dim, T > domain
domain
Definition: ie_ghost.hpp:88
size_t getNIGhostBox() const
Return the total number of the calculated internal ghost boxes.
Definition: ie_ghost.hpp:854
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
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:1289
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< Point< dim, T >, Memory, layout_base > & private_get_shifts() const
Return the internal data structure shifts.
Definition: ie_ghost.hpp:1453
Box< dim, T > & private_get_domain()
Return the internal data structure domain.
Definition: ie_ghost.hpp:1508
size_t getProcessorIGhostId(size_t id, size_t j) const
Get the j Internal ghost box id.
Definition: ie_ghost.hpp:788
This class store the adjacent processors and the adjacent sub_domains.
size_t ProctoID(size_t p) const
Convert the processor rank to the id in the list.
size_t getNearProcessor(size_t p_id) const
Get the near processor id.
size_t getNRealSubdomains(size_t p_id) const
Get the number of real sub-domains of a near processor.
const openfpm::vector< ::Box< dim, T > > & getNearSubdomains(size_t p_id) const
Get the sub-domains of a near processor.
size_t getNNProcessors() const
Get the number of Near processors.
const openfpm::vector< comb< dim > > & getNearSubdomainsPos(size_t p_id) const
Get the sub-domains sector position of a near processor.
const openfpm::vector< size_t > & getNearSubdomainsRealId(size_t p_id) const
Get the real-id of the sub-domains of a near processor.
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.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:204
size_t size()
Stub size.
Definition: map_vector.hpp:212
in case of high dimensions shift vector converter
Case for external ghost box.
Definition: common.hpp:174
openfpm::vector_std< Box_sub< dim, T > > ebx
Definition: common.hpp:177
openfpm::vector_std< Box_sub< dim, T > > ibx
Definition: common.hpp:181
size_t id
see ebx_ibx_form in ie_ghost for the meaning
Definition: common.hpp:98
size_t r_sub
see getNearSubdomainsRealId in nn_prcs
Definition: common.hpp:101
Box< dim, T > bx
Internal ghost box definition.
Definition: common.hpp:92
comb< dim > cmb
see ie_ghost follow sector explanation
Definition: common.hpp:104
size_t sub
Domain id.
Definition: common.hpp:95
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:35
void sign_flip()
Flip the sign of the combination.
Definition: comb.hpp:124
size_t lin() const
Linearization.
Definition: comb.hpp:376
It store all the boxes of the near processors in a linear array.
Definition: common.hpp:300
size_t shift_id
shift vector id
Definition: common.hpp:310
::Box< dim, T > box
Definition: common.hpp:303
size_t proc
processor rank
Definition: common.hpp:307
size_t lc_proc
local processor id
Definition: common.hpp:305
Processor id and box id.
Definition: ie_ghost.hpp:18
bool operator<(const proc_box_id &pbi) const
operator to reorder
Definition: ie_ghost.hpp:24