OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
vector_dist.hpp
1 /*
2  * Vector.hpp
3  *
4  * Created on: Mar 5, 2015
5  * Author: Pietro Incardona
6  */
7 
8 #ifndef VECTOR_HPP_
9 #define VECTOR_HPP_
10 
11 #include "HDF5_wr/HDF5_wr.hpp"
12 #include "VCluster/VCluster.hpp"
13 #include "Space/Shape/Point.hpp"
14 #include "Vector/Iterators/vector_dist_iterator.hpp"
15 #include "Space/Shape/Box.hpp"
16 #include "Vector/vector_dist_key.hpp"
17 #include "memory/PtrMemory.hpp"
18 #include "NN/CellList/CellList.hpp"
19 #include "NN/CellList/CellListFast_gen.hpp"
20 #include "util/common.hpp"
21 #include "util/object_util.hpp"
22 #include "memory/ExtPreAlloc.hpp"
23 #include "CSVWriter/CSVWriter.hpp"
24 #include "VTKWriter/VTKWriter.hpp"
25 #include "Decomposition/common.hpp"
26 #include "Grid/Iterators/grid_dist_id_iterator_dec.hpp"
27 #include "Grid/grid_key_dx_iterator_hilbert.hpp"
28 #include "Vector/vector_dist_ofb.hpp"
29 #include "Decomposition/CartDecomposition.hpp"
30 #include "data_type/aggregate.hpp"
31 #include "NN/VerletList/VerletList.hpp"
32 #include "vector_dist_comm.hpp"
33 #include "DLB/LB_Model.hpp"
34 #include "Vector/vector_map_iterator.hpp"
35 #include "NN/CellList/ParticleIt_Cells.hpp"
36 #include "NN/CellList/ProcKeys.hpp"
37 
38 #define DEC_GRAN(gr) ((size_t)gr << 32)
39 
40 #define VECTOR_DIST_ERROR_OBJECT std::runtime_error("Runtime vector distributed error");
41 
42 #ifdef SE_CLASS3
43 #include "se_class3_vector.hpp"
44 #endif
45 
46 #ifdef SE_CLASS3
47  #define SE_CLASS3_VDIST_CONSTRUCTOR ,se3(getDecomposition(),*this)
48 #else
49  #define SE_CLASS3_VDIST_CONSTRUCTOR
50 #endif
51 
52 
53 #define NO_ID false
54 #define ID true
55 
56 // Perform a ghost get or a ghost put
57 #define GET 1
58 #define PUT 2
59 
60 // Write the particles with ghost
61 #define NO_GHOST 0
62 #define WITH_GHOST 2
63 
64 #define GCL_NON_SYMMETRIC 0
65 #define GCL_SYMMETRIC 1
66 #define GCL_HILBERT 2
67 
68 
70 template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl>
71 struct gcl
72 {
82  static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
83  {
84  return vd.template getCellList<CellL>(r_cut);
85  }
86 };
87 
89 template<unsigned int dim, typename St, typename CellL, typename Vector>
90 struct gcl<dim,St,CellL,Vector,GCL_HILBERT>
91 {
101  static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
102  {
103  return vd.getCellList_hilb(r_cut,g);
104  }
105 };
106 
108 template<unsigned int dim, typename St, typename CellL, typename Vector>
109 struct gcl<dim,St,CellL,Vector,GCL_SYMMETRIC>
110 {
120  static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
121  {
122  return vd.getCellListSym(r_cut);
123  }
124 };
125 
127 
129 template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl>
130 struct gcl_An
131 {
141  static inline CellL get(Vector & vd, const size_t (& div)[dim], const size_t (& pad)[dim], const Ghost<dim,St> & g)
142  {
143  return vd.template getCellListSym<CellL>(div,pad);
144  }
145 };
146 
147 #define CELL_MEMFAST(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St> >
148 #define CELL_MEMBAL(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_bal<>, shift<dim, St> >
149 #define CELL_MEMMW(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_mw<>, shift<dim, St> >
150 
151 #define CELL_MEMFAST_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_fast<>, shift<dim, St> >
152 #define CELL_MEMBAL_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_bal<>, shift<dim, St> >
153 #define CELL_MEMMW_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_mw<>, shift<dim, St> >
154 
155 #define VERLET_MEMFAST(dim,St) VerletList<dim,St,Mem_fast<>,shift<dim,St> >
156 #define VERLET_MEMBAL(dim,St) VerletList<dim,St,Mem_bal<>,shift<dim,St> >
157 #define VERLET_MEMMW(dim,St) VerletList<dim,St,Mem_mw<>,shift<dim,St> >
158 
159 #define VERLET_MEMFAST_INT(dim,St) VerletList<dim,St,Mem_fast<unsigned int>,shift<dim,St> >
160 #define VERLET_MEMBAL_INT(dim,St) VerletList<dim,St,Mem_bal<unsigned int>,shift<dim,St> >
161 #define VERLET_MEMMW_INT(dim,St) VerletList<dim,St,Mem_mw<unsigned int>,shift<dim,St> >
162 
163 enum reorder_opt
164 {
165  NO_REORDER = 0,
166  HILBERT = 1,
167  LINEAR = 2
168 };
169 
195 template<unsigned int dim,
196  typename St,
197  typename prop,
198  typename layout = typename memory_traits_lin<prop>::type,
199  template <typename> class layout_base = memory_traits_lin,
201  typename Memory = HeapMemory>
202 class vector_dist : public vector_dist_comm<dim,St,prop,layout,layout_base,Decomposition,Memory>
203 {
204 public:
205 
208 
210  typedef prop value_type;
211 
212 private:
213 
215  size_t g_m = 0;
216 
220 
224 
227 
229  size_t opt = 0;
230 
233 
234 #ifdef SE_CLASS3
235 
237 
238 #endif
239 
245  void init_structures(size_t np)
246  {
247  // convert to a local number of elements
248  size_t p_np = np / v_cl.getProcessingUnits();
249 
250  // Get non divisible part
251  size_t r = np % v_cl.getProcessingUnits();
252 
253  // Distribute the remain particles
254  if (v_cl.getProcessUnitID() < r)
255  p_np++;
256 
257  // resize the position vector
258  v_pos.resize(p_np);
259 
260  // resize the properties vector
261  v_prp.resize(p_np);
262 
263  g_m = p_np;
264  }
265 
272  {
273  // if the box is not valid return an error
274  if (box.isValid() == false)
275  {
276  std::cerr << __FILE__ << ":" << __LINE__ << " Error the domain is not valid " << box.toString() << std::endl;
277  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
278  }
279 
280  }
281 
288  {
289  for (size_t i = 0 ; i < dim ; i++)
290  {
291  if (fabs(getDecomposition().getGhost().getLow(i)) < r_cut)
292  {
293  std::cerr << __FILE__ << ":" << __LINE__ << " Error the cut off radius " << r_cut << " is bigger that the ghost layer on the dimension " << i << " lower=" << getDecomposition().getGhost().getLow(i) << std::endl;
294  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
295  }
296  }
297  }
298 
307  template<typename CellL, typename sfc_it>
309  openfpm::vector<prop> & v_prp_dest,
310  sfc_it & h_it,
311  CellL & cell_list)
312  {
313  v_pos_dest.resize(v_pos.size());
314  v_prp_dest.resize(v_prp.size());
315 
316  //Index for v_pos_dest
317  size_t count = 0;
318 
319  grid_key_dx<dim> ksum;
320 
321  for (size_t i = 0; i < dim ; i++)
322  {ksum.set_d(i,cell_list.getPadding(i));}
323 
324  while (h_it.isNext())
325  {
326  auto key = h_it.get();
327  key += ksum;
328 
329  size_t lin = cell_list.getGrid().LinId(key);
330 
331  // for each particle in the Cell "lin"
332  for (size_t i = 0; i < cell_list.getNelements(lin); i++)
333  {
334  //reorder
335  auto v = cell_list.get(lin,i);
336  v_pos_dest.get(count) = v_pos.get(v);
337  v_prp_dest.get(count) = v_prp.get(v);
338 
339  count++;
340  }
341  ++h_it;
342  }
343  }
344 
345 public:
346 
348  typedef St stype;
349 
351  static const unsigned int dims = dim;
352 
361  {
363 
364  g_m = v.g_m;
365  v_pos = v.v_pos;
366  v_prp = v.v_prp;
367 
368 #ifdef SE_CLASS3
369  se3 = v.se3;
370 #endif
371 
372  opt = v.opt;
373 
374  return *this;
375  }
376 
385  {
387 
388  g_m = v.g_m;
389  v_pos.swap(v.v_pos);
390  v_prp.swap(v.v_prp);
391 
392 #ifdef SE_CLASS3
393  se3 = v.se3;
394 #endif
395 
396  opt = v.opt;
397 
398  return *this;
399  }
400 
401 
408  :vector_dist_comm<dim,St,prop,layout,layout_base,Decomposition,Memory>(v.getDecomposition()),v_cl(v.v_cl) SE_CLASS3_VDIST_CONSTRUCTOR
409  {
410 #ifdef SE_CLASS2
411  check_new(this,8,VECTOR_DIST_EVENT,4);
412 #endif
413 
414  this->operator=(v);
415  }
416 
423  :v_cl(v.v_cl) SE_CLASS3_VDIST_CONSTRUCTOR
424  {
425 #ifdef SE_CLASS2
426  check_new(this,8,VECTOR_DIST_EVENT,4);
427 #endif
428 
429  this->operator=(v);
430 
431 #ifdef SE_CLASS3
432  se3.Initialize();
433 #endif
434  }
435 
442  vector_dist(const Decomposition & dec, size_t np) :
443  vector_dist_comm<dim,St,prop,layout,layout_base,Decomposition,Memory>(dec), v_cl(create_vcluster()) SE_CLASS3_VDIST_CONSTRUCTOR
444  {
445 #ifdef SE_CLASS2
446  check_new(this,8,VECTOR_DIST_EVENT,4);
447 #endif
448 
449  init_structures(np);
450 
451 #ifdef SE_CLASS3
452  se3.Initialize();
453 #endif
454  }
455 
456 
469  vector_dist(size_t np, Box<dim, St> box, const size_t (&bc)[dim], const Ghost<dim, St> & g, size_t opt = 0, const grid_sm<dim,void> & gdist = grid_sm<dim,void>())
470  :v_cl(create_vcluster()),opt(opt) SE_CLASS3_VDIST_CONSTRUCTOR
471  {
472 #ifdef SE_CLASS2
473  check_new(this,8,VECTOR_DIST_EVENT,4);
474 #endif
475 
476  if (opt >> 32 != 0)
477  this->setDecompositionGranularity(opt >> 32);
478 
479  check_parameters(box);
480 
481  init_structures(np);
482  this->init_decomposition(box,bc,g,opt,gdist);
483 
484 #ifdef SE_CLASS3
485  se3.Initialize();
486 #endif
487  }
488 
489  ~vector_dist()
490  {
491 #ifdef SE_CLASS2
492  check_delete(this);
493 #endif
494  }
495 
500  void clear()
501  {
502  resize(0);
503  }
504 
510  size_t size_local() const
511  {
512  return g_m;
513  }
514 
520  size_t size_local_with_ghost() const
521  {
522  return v_pos.size();
523  }
524 
525 #ifndef ONLY_READWRITE_GETTER
526 
536  inline auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
537  {
538 #ifdef SE_CLASS3
539  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
540 #endif
541 
542  return v_pos.template get<0>(vec_key.getKey());
543  }
544 
554  inline auto getPos(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
555  {
556 #ifdef SE_CLASS3
557  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
558 #endif
559  return v_pos.template get<0>(vec_key.getKey());
560  }
561 
571  inline auto getPos(size_t vec_key) -> decltype(v_pos.template get<0>(vec_key))
572  {
573 #ifdef SE_CLASS3
574  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
575 #endif
576  return v_pos.template get<0>(vec_key);
577  }
578 
588  inline auto getPos(size_t vec_key) const -> decltype(v_pos.template get<0>(vec_key))
589  {
590 #ifdef SE_CLASS3
591  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
592 #endif
593  return v_pos.template get<0>(vec_key);
594  }
595 
606  template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
607  {
608 #ifdef SE_CLASS3
609  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key.getKey());
610 #endif
611  return v_prp.template get<id>(vec_key.getKey());
612  }
613 
624  template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
625  {
626 #ifdef SE_CLASS3
627  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key.getKey());
628 #endif
629  return v_prp.template get<id>(vec_key.getKey());
630  }
631 
642  template<unsigned int id> inline auto getProp(size_t vec_key) -> decltype(v_prp.template get<id>(vec_key))
643  {
644 #ifdef SE_CLASS3
645  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key);
646 #endif
647  return v_prp.template get<id>(vec_key);
648  }
649 
660  template<unsigned int id> inline auto getProp(size_t vec_key) const -> decltype(v_prp.template get<id>(vec_key))
661  {
662 #ifdef SE_CLASS3
663  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key);
664 #endif
665  return v_prp.template get<id>(vec_key);
666  }
667 
668 #endif
669 
671 
681  inline auto getPosNC(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
682  {
683  return v_pos.template get<0>(vec_key.getKey());
684  }
685 
695  inline auto getPosNC(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
696  {
697  return v_pos.template get<0>(vec_key.getKey());
698  }
699 
709  inline auto getPosNC(size_t vec_key) -> decltype(v_pos.template get<0>(vec_key))
710  {
711  return v_pos.template get<0>(vec_key);
712  }
713 
723  inline auto getPosNC(size_t vec_key) const -> decltype(v_pos.template get<0>(vec_key))
724  {
725  return v_pos.template get<0>(vec_key);
726  }
727 
738  template<unsigned int id> inline auto getPropNC(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
739  {
740  return v_prp.template get<id>(vec_key.getKey());
741  }
742 
753  template<unsigned int id> inline auto getPropNC(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
754  {
755  return v_prp.template get<id>(vec_key.getKey());
756  }
757 
768  template<unsigned int id> inline auto getPropNC(size_t vec_key) -> decltype(v_prp.template get<id>(vec_key))
769  {
770  return v_prp.template get<id>(vec_key);
771  }
772 
783  template<unsigned int id> inline auto getPropNC(size_t vec_key) const -> decltype(v_prp.template get<id>(vec_key))
784  {
785  return v_prp.template get<id>(vec_key);
786  }
787 
789 
799  inline auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
800  {
801 #ifdef SE_CLASS3
802  se3.template write<prop::max_prop_real>(*this,vec_key.getKey());
803 #endif
804 
805  return v_pos.template get<0>(vec_key.getKey());
806  }
807 
817  inline auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
818  {
819 #ifdef SE_CLASS3
820  se3.template read<prop::max_prop_real>(*this,vec_key.getKey());
821 #endif
822 
823  return v_pos.template get<0>(vec_key.getKey());
824  }
825 
836  template<unsigned int id> inline auto getPropWrite(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
837  {
838 #ifdef SE_CLASS3
839  se3.template write<id>(*this,vec_key.getKey());
840 #endif
841 
842  return v_prp.template get<id>(vec_key.getKey());
843  }
844 
855  template<unsigned int id> inline auto getPropRead(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
856  {
857 #ifdef SE_CLASS3
858  se3.template read<id>(*this,vec_key.getKey());
859 #endif
860 
861  return v_prp.template get<id>(vec_key.getKey());
862  }
863 
865 
874  void add()
875  {
876  v_prp.insert(g_m);
877  v_pos.insert(g_m);
878 
879  g_m++;
880 
881 #ifdef SE_CLASS3
882  for (size_t i = 0 ; i < prop::max_prop_real+1 ; i++)
883  v_prp.template get<prop::max_prop_real>(g_m-1)[i] = UNINITIALIZED;
884 #endif
885  }
886 
887 #ifndef ONLY_READWRITE_GETTER
888 
894  inline auto getLastPos() -> decltype(v_pos.template get<0>(0))
895  {
896  return v_pos.template get<0>(g_m - 1);
897  }
898 
906  template<unsigned int id> inline auto getLastProp() -> decltype(v_prp.template get<id>(0))
907  {
908  return v_prp.template get<id>(g_m - 1);
909  }
910 
911 #endif
912 
914 
920  inline auto getLastPosRead() -> decltype(v_pos.template get<0>(0))
921  {
922 #ifdef SE_CLASS3
923  se3.template read<prop::max_prop_real>(*this,g_m-1);
924 #endif
925 
926  return v_pos.template get<0>(g_m - 1);
927  }
928 
936  template<unsigned int id> inline auto getLastPropRead() -> decltype(v_prp.template get<id>(0))
937  {
938 #ifdef SE_CLASS3
939  se3.read<id>(*this,g_m-1);
940 #endif
941 
942  return v_prp.template get<id>(g_m - 1);
943  }
944 
945 
951  inline auto getLastPosWrite() -> decltype(v_pos.template get<0>(0))
952  {
953 #ifdef SE_CLASS3
954  se3.template write<prop::max_prop_real>(*this,g_m-1);
955 #endif
956 
957  return v_pos.template get<0>(g_m - 1);
958  }
959 
967  template<unsigned int id> inline auto getLastPropWrite() -> decltype(v_prp.template get<id>(0))
968  {
969 #ifdef SE_CLASS3
970  se3.template write<id>(*this,g_m-1);
971 #endif
972 
973  return v_prp.template get<id>(g_m - 1);
974  }
975 
977 
987  template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > > CellL getCellListSym(St r_cut)
988  {
989 #ifdef SE_CLASS1
990  if (!(opt & BIND_DEC_TO_GHOST))
991  {
992  if (getDecomposition().getGhost().getLow(dim-1) == 0.0)
993  {
994  std::cerr << __FILE__ << ":" << __LINE__ << " Error the vector has been constructed without BIND_DEC_TO_GHOST, If you construct a vector without BIND_DEC_TO_GHOST the ghost must be full without reductions " << std::endl;
995  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
996  }
997  }
998 #endif
999 
1000  // Cell list
1001  CellL cell_list;
1002 
1003  size_t pad = 0;
1004  CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
1005  cl_param_calculateSym(getDecomposition().getDomain(),cd_sm,getDecomposition().getGhost(),r_cut,pad);
1006 
1007  // Processor bounding box
1008  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1009 
1010  // Ghost padding extension
1011  Ghost<dim,size_t> g_ext(0);
1012  cell_list.Initialize(cd_sm,pbox,pad);
1013  cell_list.set_ndec(getDecomposition().get_ndec());
1014 
1015  updateCellListSym(cell_list);
1016 
1017  return cell_list;
1018  }
1019 
1029  template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > >
1030  CellL getCellListSym(const size_t (& div)[dim],
1031  const size_t (& pad)[dim])
1032  {
1033 #ifdef SE_CLASS1
1034  if (!(opt & BIND_DEC_TO_GHOST))
1035  {
1036  if (getDecomposition().getGhost().getLow(dim-1) == 0.0)
1037  {
1038  std::cerr << __FILE__ << ":" << __LINE__ << " Error the vector has been constructed without BIND_DEC_TO_GHOST, If you construct a vector without BIND_DEC_TO_GHOST the ghost must be full without reductions " << std::endl;
1039  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1040  }
1041  }
1042 #endif
1043 
1044  size_t pad_max = pad[0];
1045  for (size_t i = 1 ; i < dim ; i++)
1046  {if (pad[i] > pad_max) {pad_max = pad[i];}}
1047 
1048  // Cell list
1049  CellL cell_list;
1050 
1051  CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
1052  cd_sm.setDimensions(getDecomposition().getDomain(),div,pad_max);
1053 
1054  // Processor bounding box
1055  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1056 
1057  // Ghost padding extension
1058  Ghost<dim,size_t> g_ext(0);
1059  cell_list.Initialize(cd_sm,pbox,pad_max);
1060  cell_list.set_ndec(getDecomposition().get_ndec());
1061 
1062  updateCellListSym(cell_list);
1063 
1064  return cell_list;
1065  }
1066 
1077  template<typename CellL = CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St> > >
1078  CellL getCellList(St r_cut, bool no_se3 = false)
1079  {
1080 #ifdef SE_CLASS3
1081  if (no_se3 == false)
1082  {se3.getNN();}
1083 #endif
1084 #ifdef SE_CLASS1
1086 #endif
1087 
1088  // Get ghost and anlarge by 1%
1089  Ghost<dim,St> g = getDecomposition().getGhost();
1090  g.magnify(1.013);
1091 
1092  return getCellList<CellL>(r_cut, g,no_se3);
1093  }
1094 
1104  template<typename CellL = CellList_gen<dim, St, Process_keys_hilb, Mem_fast<>, shift<dim, St> > >
1105  CellL getCellList_hilb(St r_cut)
1106  {
1107 #ifdef SE_CLASS3
1108  se3.getNN();
1109 #endif
1110 #ifdef SE_CLASS1
1112 #endif
1113 
1114  // Get ghost and anlarge by 1%
1115  Ghost<dim,St> g = getDecomposition().getGhost();
1116  g.magnify(1.013);
1117 
1118  return getCellList_hilb(r_cut, g);
1119  }
1120 
1129  template<typename CellL> void updateCellList(CellL & cell_list, bool no_se3 = false)
1130  {
1131 #ifdef SE_CLASS3
1132  if (no_se3 == false)
1133  {se3.getNN();}
1134 #endif
1135 
1136  // This function assume equal spacing in all directions
1137  // but in the worst case we take the maximum
1138  St r_cut = 0;
1139  for (size_t i = 0 ; i < dim ; i++)
1140  {r_cut = std::max(r_cut,cell_list.getCellBox().getHigh(i));}
1141 
1142  // Here we have to check that the Cell-list has been constructed
1143  // from the same decomposition
1144  bool to_reconstruct = cell_list.get_ndec() != getDecomposition().get_ndec();
1145 
1146  if (to_reconstruct == false)
1147  {
1148  populate_cell_list(v_pos,cell_list,g_m,CL_NON_SYMMETRIC);
1149 
1150  cell_list.set_gm(g_m);
1151  }
1152  else
1153  {
1154  CellL cli_tmp = gcl<dim,St,CellL,self,GCL_NON_SYMMETRIC>::get(*this,r_cut,getDecomposition().getGhost());
1155 
1156  cell_list.swap(cli_tmp);
1157  }
1158  }
1159 
1167  template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > >
1168  void updateCellListSym(CellL & cell_list)
1169  {
1170 #ifdef SE_CLASS3
1171  se3.getNN();
1172 #endif
1173 
1174  // Here we have to check that the Cell-list has been constructed
1175  // from the same decomposition
1176  bool to_reconstruct = cell_list.get_ndec() != getDecomposition().get_ndec();
1177 
1178  if (to_reconstruct == false)
1179  {
1180  populate_cell_list(v_pos,cell_list,g_m,CL_SYMMETRIC);
1181 
1182  cell_list.set_gm(g_m);
1183  }
1184  else
1185  {
1186  CellL cli_tmp = gcl_An<dim,St,CellL,self,GCL_SYMMETRIC>::get(*this,
1187  cell_list.getDivWP(),
1188  cell_list.getPadding(),
1189  getDecomposition().getGhost());
1190 
1191  cell_list.swap(cli_tmp);
1192  }
1193  }
1194 
1211  template<typename CellL = CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St> > >
1212  CellL getCellList(St r_cut, const Ghost<dim, St> & enlarge, bool no_se3 = false)
1213  {
1214 #ifdef SE_CLASS3
1215  if (no_se3 == false)
1216  {se3.getNN();}
1217 #endif
1218 
1219  CellL cell_list;
1220 
1221  // Division array
1222  size_t div[dim];
1223 
1224  // get the processor bounding box
1225  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1226 
1227  // Processor bounding box
1228  cl_param_calculate(pbox, div, r_cut, enlarge);
1229 
1230  cell_list.Initialize(pbox, div);
1231  cell_list.set_gm(g_m);
1232  cell_list.set_ndec(getDecomposition().get_ndec());
1233 
1234  updateCellList(cell_list,no_se3);
1235 
1236  return cell_list;
1237  }
1238 
1254  template<typename CellL = CellList_gen<dim, St, Process_keys_hilb, Mem_fast<>, shift<dim, St> > > CellL getCellList_hilb(St r_cut, const Ghost<dim, St> & enlarge)
1255  {
1256 #ifdef SE_CLASS3
1257  se3.getNN();
1258 #endif
1259 
1260  CellL cell_list;
1261 
1262  // Division array
1263  size_t div[dim];
1264 
1265  // get the processor bounding box
1266  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1267 
1268  // Processor bounding box
1269  cl_param_calculate(pbox,div, r_cut, enlarge);
1270 
1271  cell_list.Initialize(pbox, div);
1272  cell_list.set_gm(g_m);
1273  cell_list.set_ndec(getDecomposition().get_ndec());
1274 
1275  updateCellList(cell_list);
1276 
1277  return cell_list;
1278  }
1279 
1287  template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
1288  VerletL getVerletSym(St r_cut)
1289  {
1290 #ifdef SE_CLASS3
1291  se3.getNN();
1292 #endif
1293 
1294  VerletL ver;
1295 
1296  // Processor bounding box
1297  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1298 
1299  ver.InitializeSym(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,v_pos,g_m);
1300 
1301  ver.set_ndec(getDecomposition().get_ndec());
1302 
1303  return ver;
1304  }
1305 
1313  template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
1314  VerletL getVerletCrs(St r_cut)
1315  {
1316 #ifdef SE_CLASS1
1317  if (!(opt & BIND_DEC_TO_GHOST))
1318  {
1319  std::cerr << __FILE__ << ":" << __LINE__ << " Error the vector has been constructed without BIND_DEC_TO_GHOST, getVerletCrs require the vector to be constructed with BIND_DEC_TO_GHOST option " << std::endl;
1320  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1321  }
1322 #endif
1323 
1324 #ifdef SE_CLASS3
1325  se3.getNN();
1326 #endif
1327 
1328  VerletL ver;
1329 
1330  // Processor bounding box
1331  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1332 
1333  // Initialize the verlet list
1334  ver.InitializeCrs(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,v_pos,g_m);
1335 
1336  // Get the internal cell list
1337  auto & NN = ver.getInternalCellList();
1338 
1339  // Shift
1341 
1342  // Add padding
1343  for (size_t i = 0 ; i < dim ; i++)
1344  shift.set_d(i,NN.getPadding(i));
1345 
1346  grid_sm<dim,void> gs = NN.getInternalGrid();
1347 
1348  getDecomposition().setNNParameters(shift,gs);
1349 
1350  ver.createVerletCrs(r_cut,g_m,v_pos,
1351  getDecomposition().getCRSDomainCells(),
1352  getDecomposition().getCRSAnomDomainCells());
1353 
1354  ver.set_ndec(getDecomposition().get_ndec());
1355 
1356  return ver;
1357  }
1358 
1366  template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
1367  VerletL getVerlet(St r_cut)
1368  {
1369 #ifdef SE_CLASS3
1370  se3.getNN();
1371 #endif
1372 
1373  VerletL ver;
1374 
1375  // get the processor bounding box
1376  Box<dim, St> bt = getDecomposition().getProcessorBounds();
1377 
1378  // Get the ghost
1379  Ghost<dim,St> g = getDecomposition().getGhost();
1380  g.magnify(1.013);
1381 
1382  // enlarge the box where the Verlet is defined
1383  bt.enlarge(g);
1384 
1385  ver.Initialize(bt,getDecomposition().getProcessorBounds(),r_cut,v_pos,g_m,VL_NON_SYMMETRIC);
1386 
1387  ver.set_ndec(getDecomposition().get_ndec());
1388 
1389  return ver;
1390  }
1391 
1400  template<typename Mem_type> void updateVerlet(VerletList<dim,St,Mem_type,shift<dim,St> > & ver, St r_cut, size_t opt = VL_NON_SYMMETRIC)
1401  {
1402 #ifdef SE_CLASS3
1403  se3.getNN();
1404 #endif
1405 
1406  if (opt == VL_SYMMETRIC)
1407  {
1408  auto & NN = ver.getInternalCellList();
1409 
1410  // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1411  // processor. if it is not like that we have to completely reconstruct from stratch
1412  bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1413 
1414  if (to_reconstruct == false)
1415  ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
1416  else
1417  {
1419 
1420  ver_tmp = getVerlet<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1421  ver.swap(ver);
1422  }
1423  }
1424  else if (opt == VL_CRS_SYMMETRIC)
1425  {
1426 #ifdef SE_CLASS1
1427  if ((opt & BIND_DEC_TO_GHOST))
1428  {
1429  std::cerr << __FILE__ << ":" << __LINE__ << " Error the vector has been constructed without BIND_DEC_TO_GHOST, updateVerlet with the option VL_CRS_SYMMETRIC require the vector to be constructed with BIND_DEC_TO_GHOST option " << std::endl;
1430  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1431  }
1432 #endif
1433 
1434  auto & NN = ver.getInternalCellList();
1435 
1436  // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1437  // processor. if it is not like that we have to completely reconstruct from stratch
1438  bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1439 
1440  if (to_reconstruct == false)
1441  {
1442  // Shift
1444 
1445  // Add padding
1446  for (size_t i = 0 ; i < dim ; i++)
1447  shift.set_d(i,NN.getPadding(i));
1448 
1449  grid_sm<dim,void> gs = NN.getInternalGrid();
1450 
1451  getDecomposition().setNNParameters(shift,gs);
1452 
1453  ver.updateCrs(getDecomposition().getDomain(),r_cut,v_pos,g_m,
1454  getDecomposition().getCRSDomainCells(),
1455  getDecomposition().getCRSAnomDomainCells());
1456  }
1457  else
1458  {
1460 
1461  ver_tmp = getVerletCrs<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1462  ver.swap(ver_tmp);
1463  }
1464  }
1465  else
1466  {
1467  auto & NN = ver.getInternalCellList();
1468 
1469  // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1470  // processor. if it is not like that we have to completely reconstruct from stratch
1471  bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1472 
1473  if (to_reconstruct == false)
1474  ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
1475  else
1476  {
1478 
1479  ver_tmp = getVerlet<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1480  ver.swap(ver_tmp);
1481  }
1482  }
1483  }
1484 
1485 
1493  template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
1494  void reorder (int32_t m, reorder_opt opt = reorder_opt::HILBERT)
1495  {
1496  reorder<CellL>(m,getDecomposition().getGhost(),opt);
1497  }
1498 
1499 
1512  template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
1513  void reorder(int32_t m, const Ghost<dim,St> & enlarge, reorder_opt opt = reorder_opt::HILBERT)
1514  {
1515  // reset the ghost part
1516  v_pos.resize(g_m);
1517  v_prp.resize(g_m);
1518 
1519 
1520  CellL cell_list;
1521 
1522  // calculate the parameters of the cell list
1523 
1524  // get the processor bounding box
1525  Box<dim,St> pbox = getDecomposition().getProcessorBounds();
1526  // extend by the ghost
1527  pbox.enlarge(enlarge);
1528 
1529  size_t div[dim];
1530 
1531  // Calculate the division array and the cell box
1532  for (size_t i = 0 ; i < dim ; i++)
1533  {
1534  div[i] = 1 << m;
1535  }
1536 
1537  cell_list.Initialize(pbox,div);
1538  cell_list.set_gm(g_m);
1539 
1540  // for each particle add the particle to the cell list
1541 
1542  auto it = getIterator();
1543 
1544  while (it.isNext())
1545  {
1546  auto key = it.get();
1547 
1548  Point<dim,St> xp = this->getPos(key);
1549 
1550  cell_list.add(xp,key.getKey());
1551 
1552  ++it;
1553  }
1554 
1555  // Use cell_list to reorder v_pos
1556 
1557  //destination vector
1558  openfpm::vector<Point<dim,St>> v_pos_dest;
1559  openfpm::vector<prop> v_prp_dest;
1560 
1561  if (opt == reorder_opt::HILBERT)
1562  {
1564 
1565  reorder_sfc<CellL,grid_key_dx_iterator_hilbert<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
1566  }
1567  else if (opt == reorder_opt::LINEAR)
1568  {
1569  grid_sm<dim,void> gs(div);
1570  grid_key_dx_iterator<dim> h_it(gs);
1571 
1572  reorder_sfc<CellL,grid_key_dx_iterator<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
1573  }
1574  else
1575  {
1576  // We do nothing, we second swap nullify the first
1577  v_pos.swap(v_pos_dest);
1578  v_prp.swap(v_prp_dest);
1579  }
1580 
1581  v_pos.swap(v_pos_dest);
1582  v_prp.swap(v_prp_dest);
1583  }
1584 
1600  size_t init_size_accum(size_t np)
1601  {
1602  size_t accum = 0;
1603 
1604  // convert to a local number of elements
1605  size_t p_np = np / v_cl.getProcessingUnits();
1606 
1607  // Get non divisible part
1608  size_t r = np % v_cl.getProcessingUnits();
1609 
1610  accum = p_np * v_cl.getProcessUnitID();
1611 
1612  // Distribute the remain particles
1613  if (v_cl.getProcessUnitID() <= r)
1614  accum += v_cl.getProcessUnitID();
1615  else
1616  accum += r;
1617 
1618  return accum;
1619  }
1620 
1627  {
1628 #ifdef SE_CLASS3
1629  se3.getIterator();
1630 #endif
1631  return vector_dist_iterator(0, v_pos.size());
1632  }
1633 
1644  {
1645  grid_key_dx<dim> start;
1646  grid_key_dx<dim> stop;
1647  for (size_t i = 0; i < dim; i++)
1648  {
1649  start.set_d(i, 0);
1650  stop.set_d(i, sz[i] - 1);
1651  }
1652 
1654  return it_dec;
1655  }
1656 
1663  {
1664 #ifdef SE_CLASS3
1665  se3.getIterator();
1666 #endif
1667 
1668  return vector_dist_iterator(g_m, v_pos.size());
1669  }
1670 
1677  {
1678  return vector_dist_iterator(g_m, v_pos.size());
1679  }
1680 
1689  template<typename CellList> ParticleIt_Cells<dim,CellList>
1691  {
1692 #ifdef SE_CLASS3
1693  se3.getIterator();
1694 #endif
1695 
1696  // Shift
1698 
1699  // Add padding
1700  for (size_t i = 0 ; i < dim ; i++)
1701  shift.set_d(i,NN.getPadding(i));
1702 
1703  grid_sm<dim,void> gs = NN.getInternalGrid();
1704 
1705  getDecomposition().setNNParameters(shift,gs);
1706 
1707  return ParticleIt_Cells<dim,CellList>(NN,getDecomposition().getDomainCells(),g_m);
1708  }
1709 
1716  {
1717 #ifdef SE_CLASS3
1718  se3.getIterator();
1719 #endif
1720 
1721  return vector_dist_iterator(0, g_m);
1722  }
1723 
1730  {
1731  return vector_dist_iterator(0, g_m);
1732  }
1733 
1740  {
1741 #ifdef SE_CLASS3
1742  se3.getIterator();
1743 #endif
1744 
1745  return vector_dist_iterator(0, v_pos.size());
1746  }
1747 
1754  {
1755  return vector_dist_iterator(0, v_pos.size());
1756  }
1757 
1763  inline Decomposition & getDecomposition()
1764  {
1766  }
1767 
1773  inline const Decomposition & getDecomposition() const
1774  {
1776  }
1777 
1790  template<unsigned int ... prp> void map_list(size_t opt = NONE)
1791  {
1792 #ifdef SE_CLASS3
1793  se3.map_pre();
1794 #endif
1795 
1796  this->template map_list_<prp...>(v_pos,v_prp,g_m,opt);
1797 
1798 #ifdef SE_CLASS3
1799  se3.map_post();
1800 #endif
1801  }
1802 
1803 
1814  template<typename obp = KillParticle> void map(size_t opt = NONE)
1815  {
1816 #ifdef SE_CLASS3
1817  se3.map_pre();
1818 #endif
1819 
1820  this->template map_<obp>(v_pos,v_prp,g_m,opt);
1821 
1822 #ifdef SE_CLASS3
1823  se3.map_post();
1824 #endif
1825  }
1826 
1834  template<int ... prp> inline void ghost_get(size_t opt = WITH_POSITION)
1835  {
1836 #ifdef SE_CLASS1
1837  if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
1838  {
1839  std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
1840  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1841  }
1842 #endif
1843 
1844 #ifdef SE_CLASS3
1845  se3.template ghost_get_pre<prp...>(opt);
1846 #endif
1847 
1848  this->template ghost_get_<prp...>(v_pos,v_prp,g_m,opt);
1849 
1850 #ifdef SE_CLASS3
1851 
1852  this->template ghost_get_<prop::max_prop_real>(v_pos,v_prp,g_m,opt | KEEP_PROPERTIES);
1853 
1854  se3.template ghost_get_post<prp...>(opt);
1855 #endif
1856  }
1857 
1869  template<template<typename,typename> class op, int ... prp> inline void ghost_put(size_t opt_ = NONE)
1870  {
1871 #ifdef SE_CLASS3
1872  se3.template ghost_put<prp...>();
1873 #endif
1874  this->template ghost_put_<op,prp...>(v_pos,v_prp,g_m,opt_);
1875  }
1876 
1885  void remove(openfpm::vector<size_t> & keys, size_t start = 0)
1886  {
1887  v_pos.remove(keys, start);
1888  v_prp.remove(keys, start);
1889 
1890  g_m -= keys.size();
1891  }
1892 
1898  void remove(size_t key)
1899  {
1900  v_pos.remove(key);
1901  v_prp.remove(key);
1902 
1903  g_m--;
1904  }
1905 
1913  template <typename Model=ModelLin>inline void addComputationCosts(const self & vd, Model md=Model())
1914  {
1915  CellDecomposer_sm<dim, St, shift<dim,St>> cdsm;
1916 
1917  Decomposition & dec = getDecomposition();
1918 
1919  cdsm.setDimensions(dec.getDomain(), dec.getDistGrid().getSize(), 0);
1920 
1921  auto it = vd.getDomainIterator();
1922 
1923  while (it.isNext())
1924  {
1925  size_t v = cdsm.getCell(vd.getPos(it.get()));
1926 
1927  md.addComputation(dec,vd,v,it.get().getKey());
1928 
1929  ++it;
1930  }
1931  }
1932 
1941  template <typename Model=ModelLin> void finalizeComputationCosts(Model md=Model(), size_t ts = 1)
1942  {
1943  Decomposition & dec = getDecomposition();
1944  auto & dist = getDecomposition().getDistribution();
1945 
1946  dec.computeCommunicationAndMigrationCosts(ts);
1947 
1948  // Go throught all the sub-sub-domains and apply the model
1949 
1950  for (size_t i = 0 ; i < dist.getNOwnerSubSubDomains(); i++)
1951  {md.applyModel(dec,dist.getOwnerSubSubDomain(i));}
1952 
1953  dist.setDistTol(md.distributionTol());
1954  }
1955 
1960  {
1961  Decomposition & dec = getDecomposition();
1962  auto & dist = getDecomposition().getDistribution();
1963 
1964  for (size_t i = 0; i < dist.getNOwnerSubSubDomains() ; i++)
1965  {dec.setSubSubDomainComputationCost(dist.getOwnerSubSubDomain(i) , 1);}
1966  }
1967 
1976  template <typename Model=ModelLin>inline void addComputationCosts(Model md=Model(), size_t ts = 1)
1977  {
1979 
1980  addComputationCosts(*this,md);
1981 
1982  finalizeComputationCosts(md,ts);
1983  }
1984 
1990  inline void save(const std::string & filename) const
1991  {
1993 
1994  h5s.save(filename,v_pos,v_prp);
1995  }
1996 
2002  inline void load(const std::string & filename)
2003  {
2005 
2006  h5l.load(filename,v_pos,v_prp,g_m);
2007  }
2008 
2018  inline bool write(std::string out, int opt = VTK_WRITER)
2019  {
2020 
2021  if ((opt & 0x0FFF0000) == CSV_WRITER)
2022  {
2023  // CSVWriter test
2025 
2026  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".csv"));
2027 
2028  // Write the CSV
2029  return csv_writer.write(output,v_pos,v_prp);
2030  }
2031  else
2032  {
2033  file_type ft = file_type::ASCII;
2034 
2035  if (opt & FORMAT_BINARY)
2036  ft = file_type::BINARY;
2037 
2038  // VTKWriter for a set of points
2040  vtk_writer.add(v_pos,v_prp,g_m);
2041 
2042  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".vtk"));
2043 
2044  // Write the VTK file
2045  return vtk_writer.write(output,prp_names,"particles",ft);
2046  }
2047 
2048  return false;
2049  }
2050 
2056  {
2057  v_pos.resize(g_m);
2058  v_prp.resize(g_m);
2059  }
2060 
2068  void resize(size_t rs)
2069  {
2070  deleteGhost();
2071 
2072  v_pos.resize(rs);
2073  v_prp.resize(rs);
2074 
2075  g_m = rs;
2076  }
2077 
2088  inline bool write_frame(std::string out, size_t iteration, int opt = VTK_WRITER)
2089  {
2090  if ((opt & 0x0FFF0000) == CSV_WRITER)
2091  {
2092  // CSVWriter test
2094 
2095  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".csv"));
2096 
2097  // Write the CSV
2098  return csv_writer.write(output, v_pos, v_prp);
2099  }
2100  else
2101  {
2102  file_type ft = file_type::ASCII;
2103 
2104  if (opt & FORMAT_BINARY)
2105  ft = file_type::BINARY;
2106 
2107  // VTKWriter for a set of points
2109  vtk_writer.add(v_pos,v_prp,g_m);
2110 
2111  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".vtk"));
2112 
2113  // Write the VTK file
2114  return vtk_writer.write(output,prp_names,"particles",ft);
2115  }
2116  }
2117 
2127  void getCellListParams(St r_cut, size_t (&div)[dim],Box<dim, St> & box, Ghost<dim,St> enlarge = Ghost<dim,St>(0.0))
2128  {
2129  // get the processor bounding box
2130  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
2131 
2132  // enlarge the processor bounding box by the ghost
2133  Ghost<dim,St> g = getDecomposition().getGhost();
2134  pbox.enlarge(g);
2135 
2136  cl_param_calculate(pbox, div,r_cut,enlarge);
2137 
2138  // output the fixed domain
2139  box = pbox;
2140  }
2141 
2149  long int who()
2150  {
2151 #ifdef SE_CLASS2
2152  return check_whoami(this,8);
2153 #else
2154  return -1;
2155 #endif
2156  }
2157 
2165  {
2166 #ifdef SE_CLASS2
2167  check_valid(this,8);
2168 #endif
2169  return v_cl;
2170  }
2171 
2178  {
2179  return v_pos;
2180  }
2181 
2188  {
2189  return v_pos;
2190  }
2191 
2198  {
2199  return v_prp;
2200  }
2201 
2208  {
2209  return v_prp;
2210  }
2211 
2217  size_t accum()
2218  {
2220 
2221  size_t sz = size_local();
2222 
2223  v_cl.allGather(sz,accu);
2224  v_cl.execute();
2225 
2226  sz = 0;
2227 
2228  for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
2229  {sz += accu.get(i);}
2230 
2231  return sz;
2232  }
2233 
2243  {
2244 #ifdef SE_CLASS3
2245  se3.getIterator();
2246 #endif
2247 
2248 #ifdef SE_CLASS1
2249  if (!(opt & BIND_DEC_TO_GHOST))
2250  {
2251  std::cerr << __FILE__ << ":" << __LINE__ << " Error the vector has been constructed without BIND_DEC_TO_GHOST, getParticleIteratorCRS_Cell require the vector to be constructed with BIND_DEC_TO_GHOST option " << std::endl;
2252  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2253  }
2254 #endif
2255 
2256  // Shift
2258 
2259  // Add padding
2260  for (size_t i = 0 ; i < dim ; i++)
2261  shift.set_d(i,NN.getPadding(i));
2262 
2263  grid_sm<dim,void> gs = NN.getInternalGrid();
2264 
2265  getDecomposition().setNNParameters(shift,gs);
2266 
2267  // First we check that
2268  return ParticleItCRS_Cells<dim,cli>(NN,getDecomposition().getCRSDomainCells(),
2269  getDecomposition().getCRSAnomDomainCells(),
2270  NN.getNNc_sym());
2271  }
2272 
2281  {
2282  prp_names = names;
2283  }
2284 
2294  {
2295 #ifdef SE_CLASS1
2296  if (!(opt & BIND_DEC_TO_GHOST))
2297  {
2298  std::cerr << __FILE__ << ":" << __LINE__ << " Error the vector has been constructed without BIND_DEC_TO_GHOST, getParticleIteratorCRS_Cell require the vector to be constructed with BIND_DEC_TO_GHOST option " << std::endl;
2299  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2300  }
2301 #endif
2302 
2303  // First we check that
2305  }
2306 
2315  template<typename Celllist> grid_key_dx<dim> getCRSStart(Celllist & NN)
2316  {
2317  return NN.getStartDomainCell();
2318  }
2319 
2328  template<typename Celllist> grid_key_dx<dim> getCRSStop(Celllist & NN)
2329  {
2330  grid_key_dx<dim> key = NN.getStopDomainCell();
2331 
2332  for (size_t i = 0 ; i < dim ; i++)
2333  key.set_d(i,key.get(i) + 1);
2334  return key;
2335  }
2336 
2337 #ifdef SE_CLASS3
2338 
2340  {
2341  return se3;
2342  }
2343 
2344 #endif
2345 };
2346 
2347 
2348 #endif /* VECTOR_HPP_ */
size_t accum()
It return the sum of the particles in the previous processors.
openfpm::vector< prop > & getPropVector()
return the property vector of all the particles
VerletL getVerlet(St r_cut)
for each particle get the verlet list
openfpm::vector< prop, Memory, layout, layout_base > v_prp
auto getPropNC(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
Transform the boost::fusion::vector into memory specification (memory_traits)
Definition: memory_conf.hpp:93
auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
vector_dist_iterator getDomainAndGhostIterator() const
Get an iterator that traverse the particles in the domain.
auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
auto getPropNC(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
auto getPropNC(size_t vec_key) const -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
openfpm::vector_key_iterator_seq< typename vrl::Mem_type_type::loc_index > getParticleIteratorCRS(vrl &NN)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme...
bool isValid() const
Check if the Box is a valid box P2 >= P1.
Definition: Box.hpp:997
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
size_t getProcessUnitID()
Get the process unit id.
grid_key_dx< dim > getCRSStop(Celllist &NN)
Return from which cell we have to stop in case of CRS interation scheme.
void execute()
Execute all the requests.
void init_structures(size_t np)
Initialize the structures.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support...
Definition: Vector.hpp:39
Class for Verlet list implementation.
auto getLastProp() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
bool write_frame(std::string out, size_t iteration, int opt=VTK_WRITER)
Output particle position and properties.
auto getPosNC(size_t vec_key) const -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
auto getLastPropRead() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void init_decomposition(Box< dim, St > &box, const size_t(&bc)[dim], const Ghost< dim, St > &g, size_t opt, const grid_sm< dim, void > &gdist)
Initialize the decomposition.
auto getPropNC(size_t vec_key) -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
void magnify(T mg)
Magnify the box.
Definition: Box.hpp:766
size_t size_local_with_ghost() const
return the local size of the vector
CellL getCellList_hilb(St r_cut, const Ghost< dim, St > &enlarge)
Construct an hilbert cell list starting from the stored particles.
Given the decomposition it create an iterator.
CellL getCellList(St r_cut, bool no_se3=false)
Construct a cell list starting from the stored particles.
void setDecompositionGranularity(size_t n_sub)
Set the minimum number of sub-domain per processor.
Iterator that Iterate across particle indexes.
void check_ghost_compatible_rcut(St r_cut)
It check that the r_cut is not bugger than the ghost.
const Decomposition & getDecomposition() const
Get the decomposition.
size_t size()
Stub size.
Definition: map_vector.hpp:70
size_t g_m
Ghost marker, all the particle with id > g_m are ghost all with g_m < are real particle.
Decomposition & getDecomposition()
Get the decomposition.
VerletL getVerletCrs(St r_cut)
for each particle get the symmetric verlet list
CellL getCellList_hilb(St r_cut)
Construct an hilbert cell list starting from the stored particles.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
Grid key for a distributed grid.
openfpm::vector< Point< dim, St > > & getPosVector()
return the position vector of all the particles
vector_dist_iterator getGhostIterator() const
Get the iterator across the position of the ghost particles.
long int who()
It return the id of structure in the allocation list.
void deleteGhost()
Delete the particles on the ghost.
grid_key_dx< dim > getCRSStart(Celllist &NN)
Return from which cell we have to start in case of CRS interation scheme.
VerletL getVerletSym(St r_cut)
for each particle get the symmetric verlet list
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const size_t(&sz)[dim])
CSV Writer.
Definition: CSVWriter.hpp:163
Decomposition dec
Domain decomposition.
This class allocate, and destroy CPU memory.
Definition: HeapMemory.hpp:39
This iterator iterate across the particles of a Cell-list following the Cell structure.
vector_dist< dim, St, prop, layout, layout_base, Decomposition, Memory > & operator=(const vector_dist< dim, St, prop, layout, layout_base, Decomposition, Memory > &v)
Operator= for distributed vector.
void save(const std::string &filename) const
Save the distributed vector on HDF5 file.
void finalizeComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition coming from the particles.
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
void updateCellList(CellL &cell_list, bool no_se3=false)
Update a cell list using the stored particles.
Implementation of VCluster class.
Definition: VCluster.hpp:36
auto getProp(size_t vec_key) -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
auto getPropRead(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
This class define the domain decomposition interface.
size_t init_size_accum(size_t np)
It return the number of particles contained by the previous processors.
void reorder(int32_t m, reorder_opt opt=reorder_opt::HILBERT)
Construct a cell list starting from the stored particles and reorder a vector according to the Hilber...
void ghost_put(size_t opt_=NONE)
It synchronize the properties and position of the ghost particles.
vector_dist_iterator getDomainAndGhostIterator_no_se3() const
Get an iterator that traverse the particles in the domain.
auto getLastPosWrite() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
ParticleIt_Cells< dim, CellList > getDomainIteratorCells(CellList &NN)
Get an iterator that traverse the particles in the domain using a cell list.
bool write(std::string file, v_pos &v, v_prp &prp, size_t offset=0)
It write a CSV file.
Definition: CSVWriter.hpp:248
This class decompose a space into sub-sub-domains and distribute them across processors.
auto getLastPosRead() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
vector_dist(const vector_dist< dim, St, prop, layout, layout_base, Decomposition, Memory > &v)
Copy Constructor.
Decomposition & getDecomposition()
Get the decomposition.
auto getPosNC(size_t vec_key) -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
void initializeComputationCosts()
Initialize the computational cost.
auto getPos(size_t vec_key) const -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
CellL getCellListSym(const size_t(&div)[dim], const size_t(&pad)[dim])
Construct a cell list symmetric based on a cut of radius.
vector_dist_iterator getGhostIterator_no_se3() const
Get the iterator across the position of the ghost particles.
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:700
This class check for inconsistency access.
vector_dist(vector_dist< dim, St, prop, layout, layout_base, Decomposition, Memory > &&v) noexcept
Copy constructor.
void addComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition coming from the particles.
General function t get a cell-list.
vector_dist< dim, St, prop, layout, layout_base, Decomposition, Memory > & operator=(vector_dist< dim, St, prop, layout, layout_base, Decomposition, Memory > &&v)
Operator= for distributed vector.
void clear()
remove all the elements
size_t getPadding(size_t i) const
Return the number of padding cells of the Cell decomposer.
Definition: CellList.hpp:977
size_t size_local() const
return the local size of the vector
vector_dist(size_t np, Box< dim, St > box, const size_t(&bc)[dim], const Ghost< dim, St > &g, size_t opt=0, const grid_sm< dim, void > &gdist=grid_sm< dim, void >())
Constructor of a distributed vector.
openfpm::vector< Point< dim, St >, Memory > v_pos
void updateVerlet(VerletList< dim, St, Mem_type, shift< dim, St > > &ver, St r_cut, size_t opt=VL_NON_SYMMETRIC)
for each particle get the verlet list
This class is an helper for the communication of vector_dist.
General function t get a cell-list.
Definition: vector_dist.hpp:71
void addComputationCosts(const self &vd, Model md=Model())
Add the computation cost on the decomposition coming from the particles.
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor...
auto getPosNC(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
bool write(std::string out, int opt=VTK_WRITER)
Output particle position and properties.
void add()
Add local particle.
vector_dist(const Decomposition &dec, size_t np)
Constructor with predefined decomposition.
auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
auto getLastPropWrite() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
CellL getCellList(St r_cut, const Ghost< dim, St > &enlarge, bool no_se3=false)
Construct a cell list starting from the stored particles.
ParticleItCRS_Cells< dim, cli > getParticleIteratorCRS_Cell(cli &NN)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme...
void map_list(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor...
auto getPos(size_t vec_key) -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
void map_list_(openfpm::vector< Point< dim, St >> &v_pos, openfpm::vector< prop > &v_prp, size_t &g_m, size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor...
auto getPos(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
prop value_type
property object
void updateCellListSym(CellL &cell_list)
Update a cell list using the stored particles.
const openfpm::vector< Point< dim, St > > & getPosVector() const
return the position vector of all the particles
This iterator iterate across the particles of a Cell-list following the Cell structure.
void setPropNames(const openfpm::vector< std::string > &names)
Set the properties names.
void swap(VerletList< dim, T, Mem_type, transform, CellListImpl > &vl)
Swap the memory.
static CellL get(Vector &vd, const St &r_cut, const Ghost< dim, St > &g)
Get the Cell list based on the type.
Definition: vector_dist.hpp:82
vector_dist_iterator getIterator()
Get an iterator that traverse domain and ghost particles.
std::string toString() const
Produce a string from the object.
Definition: Box.hpp:1212
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
openfpm::vector< std::string > prp_names
Name of the properties.
Distributed vector.
This class is a container for the memory interface like HeapMemory CudaMemory.
Definition: memory_c.hpp:31
St stype
space type
auto getPosNC(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void resize(size_t rs)
Resize the vector (locally)
void load(const std::string &filename)
Load the distributed vector from an HDF5 file.
auto getProp(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
void ghost_get_(openfpm::vector< Point< dim, St >> &v_pos, openfpm::vector< prop, Memory, typename layout_base< prop >::type, layout_base > &v_prp, size_t &g_m, size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
Vcluster & v_cl
Virtual cluster.
void check_parameters(Box< dim, St > &box)
Check if the parameters describe a valid vector. In case it does not report an error.
auto getLastPos() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_key.hpp:407
vector_dist_iterator getDomainIterator_no_se3() const
Get an iterator that traverse the particles in the domain.
static CellL get(Vector &vd, const size_t(&div)[dim], const size_t(&pad)[dim], const Ghost< dim, St > &g)
Get the Cell list based on the type.
auto getPropWrite(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
void ghost_put_(openfpm::vector< Point< dim, St >> &v_pos, openfpm::vector< prop > &v_prp, size_t &g_m, size_t opt)
Ghost put.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
Class for FAST cell list implementation.
Definition: CellList.hpp:269
size_t getProcessingUnits()
Get the total number of processors.
auto getProp(size_t vec_key) const -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
void getCellListParams(St r_cut, size_t(&div)[dim], Box< dim, St > &box, Ghost< dim, St > enlarge=Ghost< dim, St >(0.0))
Get the Celllist parameters.
Vcluster & getVC()
Get the Virtual Cluster machine.
static const unsigned int dims
dimensions of space
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
const openfpm::vector< prop > & getPropVector() const
return the property vector of all the particles
CellL getCellListSym(St r_cut)
Construct a cell list symmetric based on a cut of radius.
size_t opt
option used to create this vector
void reorder_sfc(openfpm::vector< Point< dim, St >> &v_pos_dest, openfpm::vector< prop > &v_prp_dest, sfc_it &h_it, CellL &cell_list)
Reorder based on hilbert space filling curve.
void reorder(int32_t m, const Ghost< dim, St > &enlarge, reorder_opt opt=reorder_opt::HILBERT)
Construct a cell list starting from the stored particles and reorder a vector according to the Hilber...