OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
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 "config.h"
12 #include "util/cuda_launch.hpp"
13 #include "HDF5_wr/HDF5_wr.hpp"
14 #include "VCluster/VCluster.hpp"
15 #include "Space/Shape/Point.hpp"
16 #include "Vector/Iterators/vector_dist_iterator.hpp"
17 #include "Space/Shape/Box.hpp"
18 #include "Vector/vector_dist_key.hpp"
19 #include "memory/PtrMemory.hpp"
20 #include "NN/CellList/CellList.hpp"
21 #include "NN/CellList/CellListFast_gen.hpp"
22 #include "util/common.hpp"
23 #include "util/object_util.hpp"
24 #include "memory/ExtPreAlloc.hpp"
25 #include "CSVWriter/CSVWriter.hpp"
26 #include "VTKWriter/VTKWriter.hpp"
27 #include "Decomposition/common.hpp"
28 #include "Grid/Iterators/grid_dist_id_iterator_dec.hpp"
29 #include "Grid/grid_key_dx_iterator_hilbert.hpp"
30 #include "Vector/vector_dist_ofb.hpp"
31 #include "Decomposition/CartDecomposition.hpp"
32 #include "data_type/aggregate.hpp"
33 #include "NN/VerletList/VerletList.hpp"
34 #include "vector_dist_comm.hpp"
35 #include "DLB/LB_Model.hpp"
36 #include "Vector/vector_map_iterator.hpp"
37 #include "NN/CellList/ParticleIt_Cells.hpp"
38 #include "NN/CellList/ProcKeys.hpp"
39 #include "Vector/vector_dist_kernel.hpp"
40 #include "NN/CellList/cuda/CellList_gpu.hpp"
41 #include "lib/pdata.hpp"
42 #include "cuda/vector_dist_operators_list_ker.hpp"
43 #include <type_traits>
44 
45 #define DEC_GRAN(gr) ((size_t)gr << 32)
46 
47 #ifdef CUDA_GPU
48 template<unsigned int dim,typename St> using CELLLIST_GPU_SPARSE = CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>,unsigned int,int,true>;
49 #endif
50 
51 #define VECTOR_DIST_ERROR_OBJECT std::runtime_error("Runtime vector distributed error");
52 
53 #ifdef SE_CLASS3
54 #include "se_class3_vector.hpp"
55 #endif
56 
57 #ifdef SE_CLASS3
58  #define SE_CLASS3_VDIST_CONSTRUCTOR ,se3(getDecomposition(),*this)
59 #else
60  #define SE_CLASS3_VDIST_CONSTRUCTOR
61 #endif
62 
63 
64 #define NO_ID false
65 #define ID true
66 
67 // Perform a ghost get or a ghost put
68 constexpr int GET = 1;
69 constexpr int PUT = 2;
70 
71 // Write the particles with ghost
72 constexpr int NO_GHOST = 0;
73 constexpr int WITH_GHOST = 2;
74 
75 constexpr int GCL_NON_SYMMETRIC = 0;
76 constexpr int GCL_SYMMETRIC = 1;
77 constexpr int GCL_HILBERT = 2;
78 
79 template<bool is_gpu_celllist, unsigned int ... prp>
81 {
82  template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl>
83  static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
84  {
85  return vd.template getCellList<CellL>(r_cut);
86  }
87 };
88 
89 template<unsigned int ... prp>
90 struct gcl_standard_no_symmetric_impl<true,prp...>
91 {
92  template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl>
93  static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
94  {
95  return vd.template getCellListGPU<CellL,prp...>(r_cut);
96  }
97 };
98 
100 template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl, unsigned int ... prp>
101 struct gcl
102 {
112  static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
113  {
114  return gcl_standard_no_symmetric_impl<is_gpu_celllist<CellL>::value,prp ...>::template get<dim,St,CellL,Vector,impl>(vd,r_cut,g);
115  }
116 };
117 
119 template<unsigned int dim, typename St, typename CellL, typename Vector>
120 struct gcl<dim,St,CellL,Vector,GCL_HILBERT>
121 {
131  static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
132  {
133  return vd.getCellList_hilb(r_cut,g);
134  }
135 };
136 
138 template<unsigned int dim, typename St, typename CellL, typename Vector>
139 struct gcl<dim,St,CellL,Vector,GCL_SYMMETRIC>
140 {
150  static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
151  {
152  return vd.getCellListSym(r_cut);
153  }
154 };
155 
157 
159 template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl>
160 struct gcl_An
161 {
171  static inline CellL get(Vector & vd, const size_t (& div)[dim], const size_t (& pad)[dim], const Ghost<dim,St> & g)
172  {
173  return vd.template getCellListSym<CellL>(div,pad);
174  }
175 };
176 
177 #define CELL_MEMFAST(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St> >
178 #define CELL_MEMBAL(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_bal<>, shift<dim, St> >
179 #define CELL_MEMMW(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_mw<>, shift<dim, St> >
180 
181 #define CELL_MEMFAST_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_fast<>, shift<dim, St> >
182 #define CELL_MEMBAL_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_bal<>, shift<dim, St> >
183 #define CELL_MEMMW_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_mw<>, shift<dim, St> >
184 
185 #define VERLET_MEMFAST(dim,St) VerletList<dim,St,Mem_fast<>,shift<dim,St> >
186 #define VERLET_MEMBAL(dim,St) VerletList<dim,St,Mem_bal<>,shift<dim,St> >
187 #define VERLET_MEMMW(dim,St) VerletList<dim,St,Mem_mw<>,shift<dim,St> >
188 
189 #define VERLET_MEMFAST_INT(dim,St) VerletList<dim,St,Mem_fast<HeapMemory,unsigned int>,shift<dim,St> >
190 #define VERLET_MEMBAL_INT(dim,St) VerletList<dim,St,Mem_bal<unsigned int>,shift<dim,St> >
191 #define VERLET_MEMMW_INT(dim,St) VerletList<dim,St,Mem_mw<unsigned int>,shift<dim,St> >
192 
193 enum reorder_opt
194 {
195  NO_REORDER = 0,
196  HILBERT = 1,
197  LINEAR = 2
198 };
199 
200 template<typename vector, unsigned int impl>
202 {
203  typedef decltype(std::declval<vector>().getCellListGPU(0.0).toKernel()) ctype;
204 
205  static ctype get(vector & v,
206  typename vector::stype & r_cut)
207  {
208  return v.getCellListGPU(r_cut).toKernel();
209  }
210 };
211 
212 template<typename vector>
213 struct cell_list_selector<vector,comp_host>
214 {
215  typedef decltype(std::declval<vector>().getCellList(0.0)) ctype;
216 
217  static ctype get(vector & v,
218  typename vector::stype & r_cut)
219  {
220  return v.getCellList(r_cut);
221  }
222 };
223 
224 template<typename vector_type>
226 {
229 
230 
239  :v(v)
240  {};
241 
242 
248  template<typename T>
249  inline void operator()(T& t) const
250  {
251  v.template getMemory<T::value>().decRef();
252  }
253 };
254 
289 template<unsigned int dim,
290  typename St,
291  typename prop,
293  typename Memory = HeapMemory,
294  template<typename> class layout_base = memory_traits_lin,
295  typename vector_dist_pos = openfpm::vector<Point<dim, St>,Memory,layout_base>,
296  typename vector_dist_prop = openfpm::vector<prop,Memory,layout_base> >
297 class vector_dist : public vector_dist_comm<dim,St,prop,Decomposition,Memory,layout_base>,
298 #ifdef CUDA_GPU
299  private vector_dist_ker_list<vector_dist_ker<dim,St,prop,layout_base>>
300 #else
301  private vector_dist_ker_list<int>
302 #endif
303 {
304 
305 public:
306 
309 
310 private:
311 
313  size_t g_m = 0;
314 
317  vector_dist_pos v_pos;
318 
321  vector_dist_prop v_prp;
322 
324  vector_dist_prop v_prp_out;
325 
327  vector_dist_pos v_pos_out;
328 
330  size_t opt = 0;
331 
334 
335 #ifdef SE_CLASS3
336 
338 
339 #endif
340 
341 #ifdef SE_CLASS1
342  int map_ctr=0;
343  //ghost check to be done.
344  int ghostget_ctr=0;
345 #endif
346 
352  void init_structures(size_t np)
353  {
354  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
355 
356  // convert to a local number of elements
357  size_t p_np = np / v_cl.getProcessingUnits();
358 
359  // Get non divisible part
360  size_t r = np % v_cl.getProcessingUnits();
361 
362  // Distribute the remain particles
363  if (v_cl.getProcessUnitID() < r)
364  p_np++;
365 
366  // resize the position vector
367  v_pos.resize(p_np);
368 
369  // resize the properties vector
370  v_prp.resize(p_np);
371 
372  g_m = p_np;
373  }
374 
381  {
382  // if the box is not valid return an error
383  if (box.isValid() == false)
384  {
385  std::cerr << __FILE__ << ":" << __LINE__ << " Error the domain is not valid " << box.toString() << std::endl;
386  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
387  }
388 
389  }
390 
397  {
398  for (size_t i = 0 ; i < dim ; i++)
399  {
400  if (fabs(getDecomposition().getGhost().getLow(i)) < r_cut)
401  {
402  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;
403  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
404  }
405  }
406  }
407 
416  template<typename CellL, typename sfc_it>
418  openfpm::vector<prop> & v_prp_dest,
419  sfc_it & h_it,
420  CellL & cell_list)
421  {
422  v_pos_dest.resize(v_pos.size());
423  v_prp_dest.resize(v_prp.size());
424 
425  //Index for v_pos_dest
426  size_t count = 0;
427 
428  grid_key_dx<dim> ksum;
429 
430  for (size_t i = 0; i < dim ; i++)
431  {ksum.set_d(i,cell_list.getPadding(i));}
432 
433  while (h_it.isNext())
434  {
435  auto key = h_it.get();
436  key += ksum;
437 
438  size_t lin = cell_list.getGrid().LinId(key);
439 
440  // for each particle in the Cell "lin"
441  for (size_t i = 0; i < cell_list.getNelements(lin); i++)
442  {
443  //reorder
444  auto v = cell_list.get(lin,i);
445  v_pos_dest.get(count) = v_pos.get(v);
446  v_prp_dest.get(count) = v_prp.get(v);
447 
448  count++;
449  }
450  ++h_it;
451  }
452  }
453 
454 public:
455 
457  typedef prop value_type;
458 
460 
461  typedef decltype(v_pos) internal_position_vector_type;
462 
463  typedef CellList<dim, St, Mem_fast<>, shift<dim, St>, internal_position_vector_type > CellList_type;
464 
466  typedef St stype;
467 
469  static const unsigned int dims = dim;
470 
472  typedef int yes_i_am_vector_dist;
473 
475  typedef std::integral_constant<bool,false> is_it_a_subset;
476 
477 
478 
488  {
490 
491  g_m = v.g_m;
492  v_pos = v.v_pos;
493  v_prp = v.v_prp;
494 
495 #ifdef SE_CLASS3
496  se3 = v.se3;
497 #endif
498 
499  opt = v.opt;
500 
501  return *this;
502  }
503 
513  {
515 
516  g_m = v.g_m;
517  v_pos.swap(v.v_pos);
518  v_prp.swap(v.v_prp);
519 
520 #ifdef SE_CLASS3
521  se3 = v.se3;
522 #endif
523 
524  opt = v.opt;
525 
526  return *this;
527  }
528 
529  // default constructor (structure contain garbage)
530  vector_dist()
531  {}
532 
533 
540  :vector_dist_comm<dim,St,prop,Decomposition,Memory,layout_base>(v.getDecomposition()) SE_CLASS3_VDIST_CONSTRUCTOR
541  {
542 #ifdef SE_CLASS2
543  check_new(this,8,VECTOR_DIST_EVENT,4);
544 #endif
545 
546  this->operator=(v);
547  }
548 
555  {
556 #ifdef SE_CLASS2
557  check_new(this,8,VECTOR_DIST_EVENT,4);
558 #endif
559 
560  this->operator=(v);
561 
562 #ifdef SE_CLASS3
563  se3.Initialize();
564 #endif
565  }
566 
573  vector_dist(const Decomposition & dec, size_t np) :
574  vector_dist_comm<dim,St,prop,Decomposition,Memory,layout_base>(dec) SE_CLASS3_VDIST_CONSTRUCTOR
575  {
576 #ifdef SE_CLASS2
577  check_new(this,8,VECTOR_DIST_EVENT,4);
578 #endif
579 
580  init_structures(np);
581 
582 #ifdef SE_CLASS3
583  se3.Initialize();
584 #endif
585  }
586 
599  vector_dist(size_t np, Box<dim, St> box, const size_t (&bc)[dim], const Ghost<dim, St> & g, const grid_sm<dim,void> & gdist)
600  :opt(0) SE_CLASS3_VDIST_CONSTRUCTOR
601  {
602  if (opt >> 32 != 0)
603  {this->setDecompositionGranularity(opt >> 32);}
604 
605  check_parameters(box);
606 
607  init_structures(np);
608 
609  this->init_decomposition_gr_cell(box,bc,g,opt,gdist);
610 
611 
612 #ifdef SE_CLASS3
613  se3.Initialize();
614 #endif
615  }
616 
629  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>())
630  :opt(opt) SE_CLASS3_VDIST_CONSTRUCTOR
631  {
632 #ifdef SE_CLASS2
633  check_new(this,8,VECTOR_DIST_EVENT,4);
634 #endif
635 
636  if (opt >> 32 != 0)
637  {this->setDecompositionGranularity(opt >> 32);}
638 
639  check_parameters(box);
640 
641  init_structures(np);
642 
643  this->init_decomposition(box,bc,g,opt,gdist);
644 
645 
646 #ifdef SE_CLASS3
647  se3.Initialize();
648 #endif
649  }
650 
651  ~vector_dist()
652  {
653 #ifdef SE_CLASS2
654  check_delete(this);
655 #endif
656  }
657 
662  {
663  for (int i = 0 ; i < v_pos.template getMemory<0>().ref() - 1; i++)
664  {
665  v_pos.template getMemory<0>().decRef();
666  }
667 
668  for (int i = 0 ; i < v_prp.template getMemory<0>().ref() - 1; i++)
669  {
670  decrement_memory<decltype(v_prp)> m(v_prp);
671 
672  boost::mpl::for_each_ref<boost::mpl::range_c<int,0,decltype(v_prp)::value_type::max_prop>>(m);
673  }
674  }
675 
680  void clear()
681  {
682  resize(0);
683  }
684 
690  size_t size_local() const
691  {
692  return g_m;
693  }
694 
700  size_t size_local_orig() const
701  {
702  return g_m;
703  }
704 
710  size_t size_local_with_ghost() const
711  {
712  return v_pos.size();
713  }
714 
715 #ifndef ONLY_READWRITE_GETTER
716 
726  inline auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
727  {
728 #ifdef SE_CLASS3
729  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
730 #endif
731 
732  return v_pos.template get<0>(vec_key.getKey());
733  }
734 
744  inline auto getPos(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
745  {
746 #ifdef SE_CLASS3
747  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
748 #endif
749  return v_pos.template get<0>(vec_key.getKey());
750  }
751 
761  inline auto getPos(size_t vec_key) -> decltype(v_pos.template get<0>(vec_key))
762  {
763 #ifdef SE_CLASS3
764  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
765 #endif
766  return v_pos.template get<0>(vec_key);
767  }
768 
778  inline auto getPosOrig(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
779  {
780 #ifdef SE_CLASS3
781  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
782 #endif
783  return v_pos.template get<0>(vec_key.getKey());
784  }
785 
795  inline auto getPosOrig(size_t vec_key) -> decltype(v_pos.template get<0>(vec_key))
796  {
797 #ifdef SE_CLASS3
798  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
799 #endif
800  return v_pos.template get<0>(vec_key);
801  }
802 
812  inline auto getPos(size_t vec_key) const -> decltype(v_pos.template get<0>(vec_key))
813  {
814 #ifdef SE_CLASS3
815  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
816 #endif
817  return v_pos.template get<0>(vec_key);
818  }
819 
830  template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
831  {
832 #ifdef SE_CLASS3
833  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key.getKey());
834 #endif
835  return v_prp.template get<id>(vec_key.getKey());
836  }
837 
848  template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
849  {
850 #ifdef SE_CLASS3
851  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key.getKey());
852 #endif
853  return v_prp.template get<id>(vec_key.getKey());
854  }
855 
866  template<unsigned int id> inline auto getProp(size_t vec_key) -> decltype(v_prp.template get<id>(vec_key))
867  {
868 #ifdef SE_CLASS3
869  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key);
870 #endif
871  return v_prp.template get<id>(vec_key);
872  }
873 
884  template<unsigned int id> inline auto getProp(size_t vec_key) const -> decltype(v_prp.template get<id>(vec_key))
885  {
886 #ifdef SE_CLASS3
887  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key);
888 #endif
889  return v_prp.template get<id>(vec_key);
890  }
891 
892 #endif
893 
895 
905  inline auto getPosNC(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
906  {
907  return v_pos.template get<0>(vec_key.getKey());
908  }
909 
919  inline auto getPosNC(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
920  {
921  return v_pos.template get<0>(vec_key.getKey());
922  }
923 
933  inline auto getPosNC(size_t vec_key) -> decltype(v_pos.template get<0>(vec_key))
934  {
935  return v_pos.template get<0>(vec_key);
936  }
937 
947  inline auto getPosNC(size_t vec_key) const -> decltype(v_pos.template get<0>(vec_key))
948  {
949  return v_pos.template get<0>(vec_key);
950  }
951 
962  template<unsigned int id> inline auto getPropNC(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
963  {
964  return v_prp.template get<id>(vec_key.getKey());
965  }
966 
977  template<unsigned int id> inline auto getPropNC(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
978  {
979  return v_prp.template get<id>(vec_key.getKey());
980  }
981 
992  template<unsigned int id> inline auto getPropNC(size_t vec_key) -> decltype(v_prp.template get<id>(vec_key))
993  {
994  return v_prp.template get<id>(vec_key);
995  }
996 
1007  template<unsigned int id> inline auto getPropNC(size_t vec_key) const -> decltype(v_prp.template get<id>(vec_key))
1008  {
1009  return v_prp.template get<id>(vec_key);
1010  }
1011 
1013 
1023  inline auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
1024  {
1025 #ifdef SE_CLASS3
1026  se3.template write<prop::max_prop_real>(*this,vec_key.getKey());
1027 #endif
1028 
1029  return v_pos.template get<0>(vec_key.getKey());
1030  }
1031 
1041  inline auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
1042  {
1043 #ifdef SE_CLASS3
1044  se3.template read<prop::max_prop_real>(*this,vec_key.getKey());
1045 #endif
1046 
1047  return v_pos.template get<0>(vec_key.getKey());
1048  }
1049 
1060  template<unsigned int id> inline auto getPropWrite(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
1061  {
1062 #ifdef SE_CLASS3
1063  se3.template write<id>(*this,vec_key.getKey());
1064 #endif
1065 
1066  return v_prp.template get<id>(vec_key.getKey());
1067  }
1068 
1079  template<unsigned int id> inline auto getPropRead(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
1080  {
1081 #ifdef SE_CLASS3
1082  se3.template read<id>(*this,vec_key.getKey());
1083 #endif
1084 
1085  return v_prp.template get<id>(vec_key.getKey());
1086  }
1087 
1089 
1098  void add()
1099  {
1100  v_prp.insert(g_m);
1101  v_pos.insert(g_m);
1102 
1103  g_m++;
1104 
1105 #ifdef SE_CLASS3
1106  for (size_t i = 0 ; i < prop::max_prop_real+1 ; i++)
1107  v_prp.template get<prop::max_prop_real>(g_m-1)[i] = UNINITIALIZED;
1108 #endif
1109  }
1110 
1111 #ifndef ONLY_READWRITE_GETTER
1112 
1118  inline auto getLastPos() -> decltype(v_pos.template get<0>(0))
1119  {
1120  return v_pos.template get<0>(g_m - 1);
1121  }
1122 
1130  template<unsigned int id> inline auto getLastProp() -> decltype(v_prp.template get<id>(0))
1131  {
1132  return v_prp.template get<id>(g_m - 1);
1133  }
1134 
1135 #endif
1136 
1138 
1144  inline auto getLastPosRead() -> decltype(v_pos.template get<0>(0))
1145  {
1146 #ifdef SE_CLASS3
1147  se3.template read<prop::max_prop_real>(*this,g_m-1);
1148 #endif
1149 
1150  return v_pos.template get<0>(g_m - 1);
1151  }
1152 
1160  template<unsigned int id> inline auto getLastPropRead() -> decltype(v_prp.template get<id>(0))
1161  {
1162 #ifdef SE_CLASS3
1163  se3.read<id>(*this,g_m-1);
1164 #endif
1165 
1166  return v_prp.template get<id>(g_m - 1);
1167  }
1168 
1169 
1175  inline auto getLastPosWrite() -> decltype(v_pos.template get<0>(0))
1176  {
1177 #ifdef SE_CLASS3
1178  se3.template write<prop::max_prop_real>(*this,g_m-1);
1179 #endif
1180 
1181  return v_pos.template get<0>(g_m - 1);
1182  }
1183 
1191  template<unsigned int id> inline auto getLastPropWrite() -> decltype(v_prp.template get<id>(0))
1192  {
1193 #ifdef SE_CLASS3
1194  se3.template write<id>(*this,g_m-1);
1195 #endif
1196 
1197  return v_prp.template get<id>(g_m - 1);
1198  }
1199 
1201 
1202  vect_dist_key_dx getOriginKey(vect_dist_key_dx vec_key)
1203  {
1204  return vec_key;
1205  }
1206 
1216  template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St>,internal_position_vector_type > >
1217  CellL getCellListSym(St r_cut)
1218  {
1219 #ifdef SE_CLASS1
1220  if (!(opt & BIND_DEC_TO_GHOST))
1221  {
1222  if (getDecomposition().getGhost().getLow(dim-1) == 0.0)
1223  {
1224  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;
1225  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1226  }
1227  }
1228 #endif
1229 
1230  // Cell list
1231  CellL cell_list;
1232 
1233  size_t pad = 0;
1234  CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
1235  cl_param_calculateSym(getDecomposition().getDomain(),cd_sm,getDecomposition().getGhost(),r_cut,pad);
1236 
1237  // Processor bounding box
1238  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1239 
1240  // Ghost padding extension
1241  Ghost<dim,size_t> g_ext(0);
1242  cell_list.Initialize(cd_sm,pbox,pad);
1243  cell_list.set_ndec(getDecomposition().get_ndec());
1244 
1245  updateCellListSym(cell_list);
1246 
1247  return cell_list;
1248  }
1249 
1259  template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > >
1260  CellL getCellListSym(const size_t (& div)[dim],
1261  const size_t (& pad)[dim])
1262  {
1263 #ifdef SE_CLASS1
1264  if (!(opt & BIND_DEC_TO_GHOST))
1265  {
1266  if (getDecomposition().getGhost().getLow(dim-1) == 0.0)
1267  {
1268  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;
1269  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1270  }
1271  }
1272 #endif
1273 
1274  size_t pad_max = pad[0];
1275  for (size_t i = 1 ; i < dim ; i++)
1276  {if (pad[i] > pad_max) {pad_max = pad[i];}}
1277 
1278  // Cell list
1279  CellL cell_list;
1280 
1281  CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
1282  cd_sm.setDimensions(getDecomposition().getDomain(),div,pad_max);
1283 
1284  // Processor bounding box
1285  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1286 
1287  // Ghost padding extension
1288  Ghost<dim,size_t> g_ext(0);
1289  cell_list.Initialize(cd_sm,pbox,pad_max);
1290  cell_list.set_ndec(getDecomposition().get_ndec());
1291 
1292  updateCellListSym(cell_list);
1293 
1294  return cell_list;
1295  }
1296 
1307  template<unsigned int impl>
1309  {
1310  return cell_list_selector<self,impl>::get(*this,r_cut);
1311  }
1312 
1323  template<typename CellL = CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St>, decltype(v_pos) > >
1324  CellL getCellList(St r_cut, bool no_se3 = false)
1325  {
1326 #ifdef SE_CLASS3
1327  if (no_se3 == false)
1328  {se3.getNN();}
1329 #endif
1330 #ifdef SE_CLASS1
1332 #endif
1333 
1334  // Get ghost and anlarge by 1%
1335  Ghost<dim,St> g = getDecomposition().getGhost();
1336  g.magnify(1.013);
1337 
1338  return getCellList<CellL>(r_cut, g,no_se3);
1339  }
1340 
1341 #ifdef CUDA_GPU
1342 
1350  template<typename CellType = CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>>,unsigned int ... prp>
1351  CellType getCellListGPU(St r_cut, bool no_se3 = false)
1352  {
1353 #ifdef SE_CLASS3
1354  if (no_se3 == false)
1355  {se3.getNN();}
1356 #endif
1357 #ifdef SE_CLASS1
1359 #endif
1360 
1361  // Get ghost and anlarge by 1%
1362  Ghost<dim,St> g = getDecomposition().getGhost();
1363  g.magnify(1.013);
1364 
1365  return getCellListGPU<CellType>(r_cut, g,no_se3);
1366  }
1367 
1368 
1384  template<typename CellType = CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>>, unsigned int ... prp>
1385  CellType getCellListGPU(St r_cut, const Ghost<dim, St> & enlarge, bool no_se3 = false)
1386  {
1387 #ifdef SE_CLASS3
1388  if (no_se3 == false)
1389  {se3.getNN();}
1390 #endif
1391 
1392  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1393 
1394  // Division array
1395  size_t div[dim];
1396 
1397  // get the processor bounding box
1398  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1399 
1400  // Processor bounding box
1401  cl_param_calculate(pbox, div, r_cut, enlarge);
1402 
1403  CellType cell_list(pbox,div);
1404 
1405  v_prp_out.resize(v_pos.size());
1406  v_pos_out.resize(v_pos.size());
1407 
1408  cell_list.template construct<decltype(v_pos),decltype(v_prp),prp ...>(v_pos,v_pos_out,v_prp,v_prp_out,v_cl.getmgpuContext(),g_m);
1409 
1410  cell_list.set_ndec(getDecomposition().get_ndec());
1411  cell_list.set_gm(g_m);
1412 
1413 #ifdef CUDA_GPU
1414  this->update_sort(this->toKernel_sorted());
1415 #endif
1416 
1417  return cell_list;
1418  }
1419 
1420 
1421 #endif
1422 
1424 
1425 #ifdef CUDA_GPU
1426 
1434  auto getCellListDevice(St r_cut, bool no_se3 = false) -> decltype(this->getCellListGPU(r_cut,no_se3))
1435  {
1436  return this->getCellListGPU(r_cut,no_se3);
1437  }
1438 
1439 
1440 #else
1441 
1449  auto getCellListDevice(St r_cut, bool no_se3 = false) -> decltype(this->getCellList(r_cut,no_se3))
1450  {
1451  return this->getCellList(r_cut,no_se3);
1452  }
1453 
1454 #endif
1455 
1457 
1467  template<typename CellL = CellList_gen<dim, St, Process_keys_hilb, Mem_fast<>, shift<dim, St> > >
1468  CellL getCellList_hilb(St r_cut)
1469  {
1470 #ifdef SE_CLASS3
1471  se3.getNN();
1472 #endif
1473 #ifdef SE_CLASS1
1475 #endif
1476 
1477  // Get ghost and anlarge by 1%
1478  Ghost<dim,St> g = getDecomposition().getGhost();
1479  g.magnify(1.013);
1480 
1481  return getCellList_hilb(r_cut, g);
1482  }
1483 
1492  template<unsigned int ... prp,typename CellL>
1493  void updateCellList(CellL & cell_list, bool no_se3 = false, cl_construct_opt opt = cl_construct_opt::Full)
1494  {
1495 #ifdef SE_CLASS3
1496  if (no_se3 == false)
1497  {se3.getNN();}
1498 #endif
1499 
1500  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1501 
1502  // This function assume equal spacing in all directions
1503  // but in the worst case we take the maximum
1504  St r_cut = cell_list.getCellBox().getRcut();
1505 
1506  // Here we have to check that the Cell-list has been constructed
1507  // from the same decomposition
1508  bool to_reconstruct = cell_list.get_ndec() != getDecomposition().get_ndec();
1509 
1510  if (to_reconstruct == false)
1511  {
1512  populate_cell_list<dim,St,prop,Memory,layout_base,CellL,prp ...>(v_pos,v_pos_out,v_prp,v_prp_out,cell_list,v_cl.getmgpuContext(false),g_m,CL_NON_SYMMETRIC,opt);
1513 
1514  cell_list.set_gm(g_m);
1515  }
1516  else
1517  {
1518  CellL cli_tmp = gcl<dim,St,CellL,self,GCL_NON_SYMMETRIC>::get(*this,r_cut,getDecomposition().getGhost());
1519 
1520  cell_list.swap(cli_tmp);
1521  cell_list.re_setBoxNN();
1522  }
1523  }
1524 
1532  template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > >
1533  void updateCellListSym(CellL & cell_list)
1534  {
1535 #ifdef SE_CLASS3
1536  se3.getNN();
1537 #endif
1538 
1539  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1540 
1541  // Here we have to check that the Cell-list has been constructed
1542  // from the same decomposition
1543  bool to_reconstruct = cell_list.get_ndec() != getDecomposition().get_ndec();
1544 
1545  if (to_reconstruct == false)
1546  {
1547  populate_cell_list(v_pos,v_pos_out,v_prp,v_prp_out,cell_list,v_cl.getmgpuContext(),g_m,CL_SYMMETRIC,cl_construct_opt::Full);
1548 
1549  cell_list.set_gm(g_m);
1550  }
1551  else
1552  {
1553  CellL cli_tmp = gcl_An<dim,St,CellL,self,GCL_SYMMETRIC>::get(*this,
1554  cell_list.getDivWP(),
1555  cell_list.getPadding(),
1556  getDecomposition().getGhost());
1557 
1558  cell_list.swap(cli_tmp);
1559  }
1560  }
1561 
1578  template<typename CellL = CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St> > >
1579  CellL getCellList(St r_cut, const Ghost<dim, St> & enlarge, bool no_se3 = false)
1580  {
1581 #ifdef SE_CLASS3
1582  if (no_se3 == false)
1583  {se3.getNN();}
1584 #endif
1585 
1586  CellL cell_list;
1587 
1588  // Division array
1589  size_t div[dim];
1590 
1591  // get the processor bounding box
1592  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1593 
1594  // Processor bounding box
1595  cl_param_calculate(pbox, div, r_cut, enlarge);
1596 
1597  cell_list.Initialize(pbox, div);
1598  cell_list.set_gm(g_m);
1599  cell_list.set_ndec(getDecomposition().get_ndec());
1600 
1601  updateCellList(cell_list,no_se3);
1602 
1603  return cell_list;
1604  }
1605 
1621  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)
1622  {
1623 #ifdef SE_CLASS3
1624  se3.getNN();
1625 #endif
1626 
1627  CellL cell_list;
1628 
1629  // Division array
1630  size_t div[dim];
1631 
1632  // get the processor bounding box
1633  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1634 
1635  // Processor bounding box
1636  cl_param_calculate(pbox,div, r_cut, enlarge);
1637 
1638  cell_list.Initialize(pbox, div);
1639  cell_list.set_gm(g_m);
1640  cell_list.set_ndec(getDecomposition().get_ndec());
1641 
1642  updateCellList(cell_list);
1643 
1644  return cell_list;
1645  }
1646 
1654  template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
1655  VerletL getVerletSym(St r_cut)
1656  {
1657 #ifdef SE_CLASS3
1658  se3.getNN();
1659 #endif
1660 
1661  VerletL ver;
1662 
1663  // Processor bounding box
1664  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1665 
1666  ver.InitializeSym(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,v_pos,g_m);
1667 
1668  ver.set_ndec(getDecomposition().get_ndec());
1669 
1670  return ver;
1671  }
1672 
1680  template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
1681  VerletL getVerletCrs(St r_cut)
1682  {
1683 #ifdef SE_CLASS1
1684  if (!(opt & BIND_DEC_TO_GHOST))
1685  {
1686  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;
1687  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1688  }
1689 #endif
1690 
1691 #ifdef SE_CLASS3
1692  se3.getNN();
1693 #endif
1694 
1695  VerletL ver;
1696 
1697  // Processor bounding box
1698  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1699 
1700  // Initialize the verlet list
1701  ver.InitializeCrs(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,v_pos,g_m);
1702 
1703  // Get the internal cell list
1704  auto & NN = ver.getInternalCellList();
1705 
1706  // Shift
1708 
1709  // Add padding
1710  for (size_t i = 0 ; i < dim ; i++)
1711  shift.set_d(i,NN.getPadding(i));
1712 
1713  grid_sm<dim,void> gs = NN.getInternalGrid();
1714 
1715  getDecomposition().setNNParameters(shift,gs);
1716 
1717  ver.createVerletCrs(r_cut,g_m,v_pos,
1718  getDecomposition().getCRSDomainCells(),
1719  getDecomposition().getCRSAnomDomainCells());
1720 
1721  ver.set_ndec(getDecomposition().get_ndec());
1722 
1723  return ver;
1724  }
1725 
1733  template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St>,decltype(v_pos) >>
1734  VerletL getVerlet(St r_cut)
1735  {
1736 #ifdef SE_CLASS3
1737  se3.getNN();
1738 #endif
1739 
1740  VerletL ver;
1741 
1742  // get the processor bounding box
1743  Box<dim, St> bt = getDecomposition().getProcessorBounds();
1744 
1745  // Get the ghost
1746  Ghost<dim,St> g = getDecomposition().getGhost();
1747  g.magnify(1.013);
1748 
1749  // enlarge the box where the Verlet is defined
1750  bt.enlarge(g);
1751 
1752  ver.Initialize(bt,getDecomposition().getProcessorBounds(),r_cut,v_pos,g_m,VL_NON_SYMMETRIC);
1753 
1754  ver.set_ndec(getDecomposition().get_ndec());
1755 
1756  return ver;
1757  }
1758 
1767  template<typename Mem_type> void updateVerlet(VerletList<dim,St,Mem_type,shift<dim,St> > & ver, St r_cut, size_t opt = VL_NON_SYMMETRIC)
1768  {
1769 #ifdef SE_CLASS3
1770  se3.getNN();
1771 #endif
1772 
1773  if (opt == VL_SYMMETRIC)
1774  {
1775  auto & NN = ver.getInternalCellList();
1776 
1777  // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1778  // processor. if it is not like that we have to completely reconstruct from stratch
1779  bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1780 
1781  if (to_reconstruct == false)
1782  ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
1783  else
1784  {
1786 
1787  ver_tmp = getVerlet<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1788  ver.swap(ver_tmp);
1789  }
1790  }
1791  else if (opt == VL_CRS_SYMMETRIC)
1792  {
1793 #ifdef SE_CLASS1
1794  if ((opt & BIND_DEC_TO_GHOST))
1795  {
1796  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;
1797  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1798  }
1799 #endif
1800 
1801  auto & NN = ver.getInternalCellList();
1802 
1803  // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1804  // processor. if it is not like that we have to completely reconstruct from stratch
1805  bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1806 
1807  if (to_reconstruct == false)
1808  {
1809  // Shift
1811 
1812  // Add padding
1813  for (size_t i = 0 ; i < dim ; i++)
1814  shift.set_d(i,NN.getPadding(i));
1815 
1816  grid_sm<dim,void> gs = NN.getInternalGrid();
1817 
1818  getDecomposition().setNNParameters(shift,gs);
1819 
1820  ver.updateCrs(getDecomposition().getDomain(),r_cut,v_pos,g_m,
1821  getDecomposition().getCRSDomainCells(),
1822  getDecomposition().getCRSAnomDomainCells());
1823  }
1824  else
1825  {
1827 
1828  ver_tmp = getVerletCrs<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1829  ver.swap(ver_tmp);
1830  }
1831  }
1832  else
1833  {
1834  auto & NN = ver.getInternalCellList();
1835 
1836  // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1837  // processor. if it is not like that we have to completely reconstruct from stratch
1838  bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1839 
1840  if (to_reconstruct == false)
1841  ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
1842  else
1843  {
1845 
1846  ver_tmp = getVerlet<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1847  ver.swap(ver_tmp);
1848  }
1849  }
1850  }
1851 
1852 
1860  template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
1861  void reorder (int32_t m, reorder_opt opt = reorder_opt::HILBERT)
1862  {
1863  reorder<CellL>(m,getDecomposition().getGhost(),opt);
1864  }
1865 
1866 
1880  template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
1881  void reorder(int32_t m, const Ghost<dim,St> & enlarge, reorder_opt opt = reorder_opt::HILBERT)
1882  {
1883  // reset the ghost part
1884  v_pos.resize(g_m);
1885  v_prp.resize(g_m);
1886 
1887 
1888  CellL cell_list;
1889 
1890  // calculate the parameters of the cell list
1891 
1892  // get the processor bounding box
1893  Box<dim,St> pbox = getDecomposition().getProcessorBounds();
1894  // extend by the ghost
1895  pbox.enlarge(enlarge);
1896 
1897  size_t div[dim];
1898 
1899  // Calculate the division array and the cell box
1900  for (size_t i = 0 ; i < dim ; i++)
1901  {
1902  div[i] = 1 << m;
1903  }
1904 
1905  cell_list.Initialize(pbox,div);
1906  cell_list.set_gm(g_m);
1907 
1908  // for each particle add the particle to the cell list
1909 
1910  auto it = getIterator();
1911 
1912  while (it.isNext())
1913  {
1914  auto key = it.get();
1915 
1916  Point<dim,St> xp = this->getPos(key);
1917 
1918  cell_list.add(xp,key.getKey());
1919 
1920  ++it;
1921  }
1922 
1923  // Use cell_list to reorder v_pos
1924 
1925  //destination vector
1926  openfpm::vector<Point<dim,St>> v_pos_dest;
1927  openfpm::vector<prop> v_prp_dest;
1928 
1929  if (opt == reorder_opt::HILBERT)
1930  {
1932 
1933  reorder_sfc<CellL,grid_key_dx_iterator_hilbert<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
1934  }
1935  else if (opt == reorder_opt::LINEAR)
1936  {
1937  grid_sm<dim,void> gs(div);
1938  grid_key_dx_iterator<dim> h_it(gs);
1939 
1940  reorder_sfc<CellL,grid_key_dx_iterator<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
1941  }
1942  else
1943  {
1944  // We do nothing, we second swap nullify the first
1945  v_pos.swap(v_pos_dest);
1946  v_prp.swap(v_prp_dest);
1947  }
1948 
1949  v_pos.swap(v_pos_dest);
1950  v_prp.swap(v_prp_dest);
1951  }
1952 
1966  template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
1967  void reorder_rcut(St r_cut)
1968  {
1969  // reset the ghost part
1970  v_pos.resize(g_m);
1971  v_prp.resize(g_m);
1972 
1973  auto cell_list = getCellList<CellL>(r_cut);
1974 
1975  // Use cell_list to reorder v_pos
1976 
1977  //destination vector
1978  openfpm::vector<Point<dim,St>> v_pos_dest;
1979  openfpm::vector<prop> v_prp_dest;
1980 
1981  size_t div[dim];
1982  for (size_t i = 0 ; i < dim ; i++)
1983  {div[i] = cell_list.getGrid().size(i) - 2*cell_list.getPadding()[i];}
1984 
1985  grid_sm<dim,void> gs(div);
1986  grid_key_dx_iterator<dim> h_it(gs);
1987 
1988  reorder_sfc<CellL,grid_key_dx_iterator<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
1989 
1990  v_pos.swap(v_pos_dest);
1991  v_prp.swap(v_prp_dest);
1992  }
1993 
2009  size_t init_size_accum(size_t np)
2010  {
2011  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2012 
2013  size_t accum = 0;
2014 
2015  // convert to a local number of elements
2016  size_t p_np = np / v_cl.getProcessingUnits();
2017 
2018  // Get non divisible part
2019  size_t r = np % v_cl.getProcessingUnits();
2020 
2021  accum = p_np * v_cl.getProcessUnitID();
2022 
2023  // Distribute the remain particles
2024  if (v_cl.getProcessUnitID() <= r)
2026  else
2027  accum += r;
2028 
2029  return accum;
2030  }
2031 
2038  {
2039 #ifdef SE_CLASS3
2040  se3.getIterator();
2041 #endif
2042  return vector_dist_iterator(0, v_pos.size());
2043  }
2044 
2053  vector_dist_iterator getIterator(size_t start, size_t stop)
2054  {
2055 #ifdef SE_CLASS3
2056  se3.getIterator();
2057 #endif
2058  return vector_dist_iterator(start, stop);
2059  }
2060 
2071  {
2072  grid_key_dx<dim> start;
2073  grid_key_dx<dim> stop;
2074  for (size_t i = 0; i < dim; i++)
2075  {
2076  start.set_d(i, 0);
2077  stop.set_d(i, sz[i] - 1);
2078  }
2079 
2081  return it_dec;
2082  }
2083 
2090  {
2091 #ifdef SE_CLASS3
2092  se3.getIterator();
2093 #endif
2094 
2095  return vector_dist_iterator(g_m, v_pos.size());
2096  }
2097 
2104  {
2105  return vector_dist_iterator(g_m, v_pos.size());
2106  }
2107 
2116  template<typename CellList> ParticleIt_Cells<dim,CellList>
2118  {
2119 #ifdef SE_CLASS3
2120  se3.getIterator();
2121 #endif
2122 
2123  // Shift
2125 
2126  // Add padding
2127  for (size_t i = 0 ; i < dim ; i++)
2128  shift.set_d(i,NN.getPadding(i));
2129 
2130  grid_sm<dim,void> gs = NN.getInternalGrid();
2131 
2132  getDecomposition().setNNParameters(shift,gs);
2133 
2134  return ParticleIt_Cells<dim,CellList>(NN,getDecomposition().getDomainCells(),g_m);
2135  }
2136 
2143  {
2144 #ifdef SE_CLASS3
2145  se3.getIterator();
2146 #endif
2147 
2148  return vector_dist_iterator(0, g_m);
2149  }
2150 
2151 #ifdef CUDA_GPU
2152 
2158  ite_gpu<1> getDomainIteratorGPU(size_t n_thr = default_kernel_wg_threads_) const
2159  {
2160 #ifdef SE_CLASS3
2161  se3.getIterator();
2162 #endif
2163 
2164  return v_pos.getGPUIteratorTo(g_m-1,n_thr);
2165  }
2166 
2172  ite_gpu<1> getDomainAndGhostIteratorGPU(size_t n_thr = default_kernel_wg_threads_) const
2173  {
2174 #ifdef SE_CLASS3
2175  se3.getIterator();
2176 #endif
2177 
2178  return v_pos.getGPUIteratorTo(v_pos.size()-1,n_thr);
2179  }
2180 
2186  template<unsigned int ... prp,typename id_1, typename id_2, bool is_sparse>
2187  void merge_sort(CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>,id_1,id_2,is_sparse> & cl, size_t n_thr = default_kernel_wg_threads_)
2188  {
2189 #if defined(__NVCC__)
2190 
2191  auto ite = v_pos.getGPUIteratorTo(g_m-1,n_thr);
2192  bool has_work = has_work_gpu(ite);
2193 
2194  if (has_work == true)
2195  {
2196  CUDA_LAUNCH((merge_sort_part<false,decltype(v_pos.toKernel()),decltype(v_prp.toKernel()),decltype(cl.getNonSortToSort().toKernel()),prp...>),
2197  ite,
2198  v_pos.toKernel(),v_prp.toKernel(),v_pos_out.toKernel(),v_prp_out.toKernel(),cl.getNonSortToSort().toKernel());
2199  }
2200 
2201 #endif
2202  }
2203 
2211  template<unsigned int prp>
2212  void debugPrintVector(bool print_sorted = false)
2213  {
2214  if (print_sorted == false)
2215  {this->v_prp.template deviceToHost<prp>();}
2216  else
2217  {this->v_prp_out.template deviceToHost<prp>();}
2218 
2219  auto it = this->getDomainIterator();
2220 
2221  while(it.isNext())
2222  {
2223  auto p = it.get();
2224 
2225  for (size_t i = 0 ; i < std::extent<typename boost::mpl::at<typename prop::type,boost::mpl::int_<prp>>::type>::value ; i++)
2226  {
2227  if (print_sorted == false)
2228  {std::cout << v_prp.template get<prp>(p.getKey())[i] << " ";}
2229  else
2230  {std::cout << v_prp_out.template get<prp>(p.getKey())[i] << " ";}
2231  }
2232 
2233  std::cout << std::endl;
2234 
2235  ++it;
2236  }
2237  }
2238 
2246  template<unsigned int prp>
2247  void debugPrintScalar(bool print_sorted = false)
2248  {
2249  if (print_sorted == false)
2250  {this->v_prp.template deviceToHost<prp>();}
2251  else
2252  {this->v_prp_out.template deviceToHost<prp>();}
2253 
2254  auto it = this->getDomainIterator();
2255 
2256  while(it.isNext())
2257  {
2258  auto p = it.get();
2259 
2260  if (print_sorted == false)
2261  {std::cout << v_prp_out.template get<prp>(p.getKey()) << " " << std::endl;}
2262  else
2263  {std::cout << v_prp_out.template get<prp>(p.getKey()) << " " << std::endl;}
2264 
2265  ++it;
2266  }
2267  }
2268 
2274  template<unsigned int ... prp> void merge_sort_with_pos(CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>> & cl, size_t n_thr = default_kernel_wg_threads_)
2275  {
2276 #if defined(__NVCC__)
2277 
2278  auto ite = v_pos.getGPUIteratorTo(g_m-1,n_thr);
2279 
2280  CUDA_LAUNCH((merge_sort_part<true,decltype(v_pos.toKernel()),decltype(v_prp.toKernel()),decltype(cl.getNonSortedToSorted().toKernel()),prp...>),
2281  ite,
2282  v_pos.toKernel(),v_prp.toKernel(),v_pos_out.toKernel(),v_prp_out.toKernel(),cl.getNonSortedToSorted().toKernel());
2283 
2284 #endif
2285  }
2286 
2287 #endif
2288 
2289 #ifdef CUDA_GPU
2290 
2296  auto getDomainIteratorDevice(size_t n_thr = default_kernel_wg_threads_) const -> decltype(this->getDomainIteratorGPU(n_thr))
2297  {
2298  return this->getDomainIteratorGPU(n_thr);
2299  }
2300 
2301 
2302 #else
2303 
2309  auto getDomainIteratorDevice(size_t n_thr = default_kernel_wg_threads_) const -> decltype(this->getDomainIterator())
2310  {
2311  return this->getDomainIterator();
2312  }
2313 
2314 
2315 #endif
2316 
2323  {
2324  return vector_dist_iterator(0, g_m);
2325  }
2326 
2333  {
2334 #ifdef SE_CLASS3
2335  se3.getIterator();
2336 #endif
2337 
2338  return vector_dist_iterator(0, v_pos.size());
2339  }
2340 
2347  {
2348  return vector_dist_iterator(0, v_pos.size());
2349  }
2350 
2357  {
2359  }
2360 
2366  inline const Decomposition & getDecomposition() const
2367  {
2369  }
2370 
2384  template<unsigned int ... prp> void map_list(size_t opt = NONE)
2385  {
2386 #ifdef SE_CLASS3
2387  se3.map_pre();
2388 #endif
2389 
2390  this->template map_list_<prp...>(v_pos,v_prp,g_m,opt);
2391 
2392 #ifdef CUDA_GPU
2393  this->update(this->toKernel());
2394 #endif
2395 
2396 #ifdef SE_CLASS3
2397  se3.map_post();
2398 #endif
2399  }
2400 
2401 
2413  template<typename obp = KillParticle> void map(size_t opt = NONE)
2414  {
2415 #ifdef SE_CLASS3
2416  se3.map_pre();
2417 #endif
2418 #ifdef SE_CLASS1
2419  map_ctr++;
2420 #endif
2421 
2422  this->template map_<obp>(v_pos,v_prp,g_m,opt);
2423 
2424 #ifdef CUDA_GPU
2425  this->update(this->toKernel());
2426 #endif
2427 
2428 #ifdef SE_CLASS3
2429  se3.map_post();
2430 #endif
2431  }
2432 #ifdef SE_CLASS1
2433  int getMapCtr() const
2434  {
2435  return map_ctr;
2436  }
2437 #endif
2438 
2439 
2444  {
2445  #ifdef SE_CLASS1
2446  std::cerr<<__FILE__<<":"<<__LINE__<<":You Used a ghost_get on a subset. This does not do anything. Please use ghostget on the entire set.";
2447  #endif
2448  }
2449 
2457  template<int ... prp> inline void ghost_get(size_t opt = WITH_POSITION)
2458  {
2459 #ifdef SE_CLASS1
2460  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2461 
2462  if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2463  {
2464  std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2465  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2466  }
2467 #endif
2468 
2469 #ifdef SE_CLASS3
2470  se3.template ghost_get_pre<prp...>(opt);
2471 #endif
2472 
2473  this->template ghost_get_<GHOST_SYNC,prp...>(v_pos,v_prp,g_m,opt);
2474 
2475 #ifdef CUDA_GPU
2476  this->update(this->toKernel());
2477 #endif
2478 
2479 #ifdef SE_CLASS3
2480 
2481  this->template ghost_get_<prop::max_prop_real>(v_pos,v_prp,g_m,opt | KEEP_PROPERTIES);
2482 
2483  se3.template ghost_get_post<prp...>(opt);
2484 #endif
2485  }
2486 
2487 
2495  template<int ... prp> inline void Ighost_get(size_t opt = WITH_POSITION)
2496  {
2497 #ifdef SE_CLASS1
2498  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2499 
2500  if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2501  {
2502  std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2503  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2504  }
2505 #endif
2506 
2507 #ifdef SE_CLASS3
2508  se3.template ghost_get_pre<prp...>(opt);
2509 #endif
2510 
2511  this->template ghost_get_<GHOST_ASYNC,prp...>(v_pos,v_prp,g_m,opt);
2512  }
2513 
2521  template<int ... prp> inline void ghost_wait(size_t opt = WITH_POSITION)
2522  {
2523 #ifdef SE_CLASS1
2524  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2525 
2526  if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2527  {
2528  std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2529  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2530  }
2531 #endif
2532 
2533  this->template ghost_wait_<prp...>(v_pos,v_prp,g_m,opt);
2534 
2535 #ifdef CUDA_GPU
2536  this->update(this->toKernel());
2537 #endif
2538 
2539 #ifdef SE_CLASS3
2540 
2541  this->template ghost_get_<prop::max_prop_real>(v_pos,v_prp,g_m,opt | KEEP_PROPERTIES);
2542 
2543  se3.template ghost_get_post<prp...>(opt);
2544 #endif
2545  }
2546 
2558  template<template<typename,typename> class op, int ... prp> inline void ghost_put(size_t opt_ = NONE)
2559  {
2560 #ifdef SE_CLASS3
2561  se3.template ghost_put<prp...>();
2562 #endif
2563  this->template ghost_put_<op,prp...>(v_pos,v_prp,g_m,opt_);
2564  }
2565 
2574  void remove(openfpm::vector<size_t> & keys, size_t start = 0)
2575  {
2576  v_pos.remove(keys, start);
2577  v_prp.remove(keys, start);
2578 
2579  g_m -= keys.size();
2580  }
2581 
2590  void remove(openfpm::vector<aggregate<int>> & keys, size_t start = 0)
2591  {
2592  v_pos.remove(keys, start);
2593  v_prp.remove(keys, start);
2594 
2595  g_m -= keys.size();
2596  }
2597 
2603  void remove(size_t key)
2604  {
2605  v_pos.remove(key);
2606  v_prp.remove(key);
2607 
2608  g_m--;
2609  }
2610 
2618  template <typename Model=ModelLin>inline void addComputationCosts(const self & vd, Model md=Model())
2619  {
2620  CellDecomposer_sm<dim, St, shift<dim,St>> cdsm;
2621 
2623 
2624  cdsm.setDimensions(dec.getDomain(), dec.getDistGrid().getSize(), 0);
2625 
2626  auto it = vd.getDomainIterator();
2627 
2628  while (it.isNext())
2629  {
2630  Point<dim,St> p = vd.getPos(it.get());
2631  size_t v = cdsm.getCell(p);
2632 
2633  md.addComputation(dec,vd,v,it.get().getKey());
2634 
2635  ++it;
2636  }
2637  }
2638 
2647  template <typename Model=ModelLin> void finalizeComputationCosts(Model md=Model(), size_t ts = 1)
2648  {
2650  auto & dist = getDecomposition().getDistribution();
2651 
2652  dec.computeCommunicationAndMigrationCosts(ts);
2653 
2654  // Go throught all the sub-sub-domains and apply the model
2655 
2656  for (size_t i = 0 ; i < dist.getNOwnerSubSubDomains(); i++)
2657  {md.applyModel(dec,dist.getOwnerSubSubDomain(i));}
2658 
2659  dist.setDistTol(md.distributionTol());
2660  }
2661 
2666  {
2668  auto & dist = getDecomposition().getDistribution();
2669 
2670  for (size_t i = 0; i < dist.getNOwnerSubSubDomains() ; i++)
2671  {dec.setSubSubDomainComputationCost(dist.getOwnerSubSubDomain(i) , 1);}
2672  }
2673 
2682  template <typename Model=ModelLin>inline void addComputationCosts(Model md=Model(), size_t ts = 1)
2683  {
2685 
2686  addComputationCosts(*this,md);
2687 
2688  finalizeComputationCosts(md,ts);
2689  }
2690 
2696  inline void save(const std::string & filename) const
2697  {
2699 
2700  h5s.save(filename,v_pos,v_prp);
2701  }
2702 
2708  inline void load(const std::string & filename)
2709  {
2711 
2712  h5l.load(filename,v_pos,v_prp,g_m);
2713  }
2714 
2720  void setCapacity(unsigned int ns)
2721  {
2722  v_pos.reserve(ns);
2723  v_prp.reserve(ns);
2724  }
2725 
2735  inline bool write(std::string out ,int opt = VTK_WRITER)
2736  {
2737  return write(out,"",opt);
2738  }
2739 
2750  inline bool write(std::string out, std::string meta_info ,int opt = VTK_WRITER)
2751  {
2752  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2753 
2754  if ((opt & 0x0FFF0000) == CSV_WRITER)
2755  {
2756  // CSVWriter test
2757  CSVWriter<vector_dist_pos,
2758  vector_dist_prop > csv_writer;
2759 
2760  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".csv"));
2761 
2762  // Write the CSV
2763  return csv_writer.write(output,v_pos,v_prp);
2764  }
2765  else
2766  {
2767  file_type ft = file_type::ASCII;
2768 
2769  if (opt & FORMAT_BINARY)
2770  ft = file_type::BINARY;
2771 
2772  // VTKWriter for a set of points
2773  VTKWriter<boost::mpl::pair<vector_dist_pos,
2774  vector_dist_prop>,
2775  VECTOR_POINTS> vtk_writer;
2776  vtk_writer.add(v_pos,v_prp,g_m);
2777 
2778  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".vtp"));
2779 
2780  // Write the VTK file
2781  bool ret=vtk_writer.write(output,prp_names,"particles",meta_info,ft);
2782  if(v_cl.rank()==0)
2783  {vtk_writer.write_pvtp(out,prp_names,v_cl.size()) ;}
2784  return ret;
2785  }
2786  }
2787 
2793  {
2794  v_pos.resize(g_m);
2795  v_prp.resize(g_m);
2796  }
2797 
2805  void resize(size_t rs)
2806  {
2807  deleteGhost();
2808 
2809  v_pos.resize(rs);
2810  v_prp.resize(rs);
2811 
2812  g_m = rs;
2813 
2814 #ifdef CUDA_GPU
2815  this->update(this->toKernel());
2816 #endif
2817  }
2818 
2830  inline bool write_frame(std::string out, size_t iteration, int opt = VTK_WRITER)
2831  {
2832  return write_frame(out,iteration,"",opt);
2833  }
2834 
2846  inline bool write_frame(std::string out, size_t iteration, std::string meta_info, int opt = VTK_WRITER)
2847  {
2848  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2849 
2850  if ((opt & 0x0FFF0000) == CSV_WRITER)
2851  {
2852  // CSVWriter test
2853  CSVWriter<vector_dist_pos,
2854  vector_dist_prop > csv_writer;
2855 
2856  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".csv"));
2857 
2858  // Write the CSV
2859  return csv_writer.write(output, v_pos, v_prp);
2860  }
2861  else
2862  {
2863  file_type ft = file_type::ASCII;
2864 
2865  if (opt & FORMAT_BINARY)
2866  ft = file_type::BINARY;
2867 
2868  // VTKWriter for a set of points
2869  VTKWriter<boost::mpl::pair<vector_dist_pos,
2870  vector_dist_prop>, VECTOR_POINTS> vtk_writer;
2871  vtk_writer.add(v_pos,v_prp,g_m);
2872 
2873  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".vtp"));
2874 
2875  // Write the VTK file
2876  bool ret=vtk_writer.write(output,prp_names,"particles",meta_info,ft);
2877  if(v_cl.rank()==0)
2878  {vtk_writer.write_pvtp(out,prp_names,v_cl.size(),iteration);}
2879  return ret;
2880  }
2881  }
2882 
2892  void getCellListParams(St r_cut, size_t (&div)[dim],Box<dim, St> & box, Ghost<dim,St> enlarge = Ghost<dim,St>(0.0))
2893  {
2894  // get the processor bounding box
2895  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
2896 
2897  // enlarge the processor bounding box by the ghost
2898  Ghost<dim,St> g = getDecomposition().getGhost();
2899  pbox.enlarge(g);
2900 
2901  cl_param_calculate(pbox, div,r_cut,enlarge);
2902 
2903  // output the fixed domain
2904  box = pbox;
2905  }
2906 
2914  long int who()
2915  {
2916 #ifdef SE_CLASS2
2917  return check_whoami(this,8);
2918 #else
2919  return -1;
2920 #endif
2921  }
2922 
2930  {
2931 #ifdef SE_CLASS2
2932  check_valid(this,8);
2933 #endif
2934  return create_vcluster<Memory>();;
2935  }
2936 
2942  const vector_dist_pos & getPosVector() const
2943  {
2944  return v_pos;
2945  }
2946 
2952  vector_dist_pos & getPosVector()
2953  {
2954  return v_pos;
2955  }
2956 
2962  const vector_dist_prop & getPropVector() const
2963  {
2964  return v_prp;
2965  }
2966 
2972  vector_dist_prop & getPropVector()
2973  {
2974  return v_prp;
2975  }
2976 
2982  const vector_dist_pos & getPosVectorSort() const
2983  {
2984  return v_pos_out;
2985  }
2986 
2992  vector_dist_pos & getPosVectorSort()
2993  {
2994  return v_pos_out;
2995  }
2996 
3002  const vector_dist_prop & getPropVectorSort() const
3003  {
3004  return v_prp_out;
3005  }
3006 
3012  vector_dist_prop & getPropVectorSort()
3013  {
3014  return v_prp_out;
3015  }
3016 
3022  size_t accum()
3023  {
3024  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
3025 
3027 
3028  size_t sz = size_local();
3029 
3030  v_cl.allGather(sz,accu);
3031  v_cl.execute();
3032 
3033  sz = 0;
3034 
3035  for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
3036  {sz += accu.get(i);}
3037 
3038  return sz;
3039  }
3040 
3049  template<typename cli> ParticleItCRS_Cells<dim,cli,decltype(v_pos)> getParticleIteratorCRS_Cell(cli & NN)
3050  {
3051 #ifdef SE_CLASS3
3052  se3.getIterator();
3053 #endif
3054 
3055 #ifdef SE_CLASS1
3056  if (!(opt & BIND_DEC_TO_GHOST))
3057  {
3058  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;
3059  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
3060  }
3061 #endif
3062 
3063  // Shift
3065 
3066  // Add padding
3067  for (size_t i = 0 ; i < dim ; i++)
3068  shift.set_d(i,NN.getPadding(i));
3069 
3070  grid_sm<dim,void> gs = NN.getInternalGrid();
3071 
3072  getDecomposition().setNNParameters(shift,gs);
3073 
3074  // First we check that
3075  return ParticleItCRS_Cells<dim,cli,decltype(v_pos)>(NN,getDecomposition().getCRSDomainCells(),
3076  getDecomposition().getCRSAnomDomainCells(),
3077  NN.getNNc_sym());
3078  }
3079 
3088  {
3089  prp_names = names;
3090  }
3091 
3098  {
3099  return prp_names;
3100  }
3101 
3102 
3112  {
3113 #ifdef SE_CLASS1
3114  if (!(opt & BIND_DEC_TO_GHOST))
3115  {
3116  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;
3117  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
3118  }
3119 #endif
3120 
3121  // First we check that
3123  }
3124 
3133  template<typename Celllist> grid_key_dx<dim> getCRSStart(Celllist & NN)
3134  {
3135  return NN.getStartDomainCell();
3136  }
3137 
3146  template<typename Celllist> grid_key_dx<dim> getCRSStop(Celllist & NN)
3147  {
3148  grid_key_dx<dim> key = NN.getStopDomainCell();
3149 
3150  for (size_t i = 0 ; i < dim ; i++)
3151  key.set_d(i,key.get(i) + 1);
3152  return key;
3153  }
3154 
3160  bool isSubset() const
3161  {
3162  return false;
3163  }
3164 
3165 #ifdef CUDA_GPU
3166 
3174  template<unsigned int ... prp> vector_dist_ker<dim,St,prop,layout_base> toKernel()
3175  {
3176  vector_dist_ker<dim,St,prop,layout_base> v(g_m,v_pos.toKernel(), v_prp.toKernel());
3177 
3178  return v;
3179  }
3180 
3187  vector_dist_ker_list<vector_dist_ker<dim,St,prop,layout_base>> & private_get_vector_dist_ker_list()
3188  {
3189  return *this;
3190  }
3191 
3199  template<unsigned int ... prp> vector_dist_ker<dim,St,prop,layout_base> toKernel_sorted()
3200  {
3201  vector_dist_ker<dim,St,prop,layout_base> v(g_m,v_pos_out.toKernel(), v_prp_out.toKernel());
3202 
3203  return v;
3204  }
3205 
3211  template<unsigned int ... prp> void deviceToHostProp()
3212  {
3213  v_prp.template deviceToHost<prp ...>();
3214  }
3215 
3224  template<unsigned int ... prp> void deviceToHostProp(size_t start, size_t stop)
3225  {
3226  v_prp.template deviceToHost<prp ...>(start,stop);
3227  }
3228 
3234  void deviceToHostPos()
3235  {
3236  v_pos.template deviceToHost<0>();
3237  }
3238 
3244  template<unsigned int ... prp> void hostToDeviceProp()
3245  {
3246  v_prp.template hostToDevice<prp ...>();
3247  }
3248 
3254  void hostToDevicePos()
3255  {
3256  v_pos.template hostToDevice<0>();
3257  }
3258 
3259  void set_g_m(size_t g_m)
3260  {
3261  this->g_m = g_m;
3262  }
3263 
3271  template<typename CellList_type>
3272  void make_sort(CellList_type & NN)
3273  {
3274  deleteGhost();
3275 
3276  updateCellList(NN,false,cl_construct_opt::Only_reorder);
3277 
3278  // construct a cell-list forcing to create a sorted version without ghost
3279 
3280  // swap the sorted with the non-sorted
3281  v_pos.swap(v_pos_out);
3282  v_prp.swap(v_prp_out);
3283  }
3284 
3292  template<typename CellList_type>
3293  void make_sort_from(CellList_type & cl)
3294  {
3295 #if defined(__NVCC__)
3296 
3297  auto ite = v_pos.getGPUIteratorTo(g_m-1);
3298 
3299  CUDA_LAUNCH((merge_sort_all<decltype(v_pos.toKernel()),decltype(v_prp.toKernel()),decltype(cl.getNonSortToSort().toKernel())>),
3300  ite,
3301  v_pos_out.toKernel(),v_prp_out.toKernel(),v_pos.toKernel(),v_prp.toKernel(),cl.getNonSortToSort().toKernel());
3302 
3303  v_pos.swap(v_pos_out);
3304  v_prp.swap(v_prp_out);
3305 
3306 #endif
3307  }
3308 
3316  bool compareHostAndDevicePos(St tol, St near = -1.0, bool silent = false)
3317  {
3318  return compare_host_device<Point<dim,St>,0>::compare(v_pos,tol,near,silent);
3319  }
3320 
3321 
3329  template<unsigned int prp>
3330  bool compareHostAndDeviceProp(St tol, St near = -1.0, bool silent = false)
3331  {
3332  return compare_host_device<typename boost::mpl::at<typename prop::type,
3333  boost::mpl::int_<prp> >::type,prp>::compare(v_prp,tol,near,silent);
3334  }
3335 
3336 #else
3337 
3343  template<unsigned int ... prp> void deviceToHostProp()
3344  {}
3345 
3352  {}
3353 
3359  template<unsigned int ... prp> void hostToDeviceProp()
3360  {}
3361 
3368  {}
3369 
3370 #endif
3371 
3372 
3373 #ifdef SE_CLASS3
3374 
3376  {
3377  return se3;
3378  }
3379 
3380 #endif
3381 };
3382 
3383 
3384 template<unsigned int dim, typename St, typename prop, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte>> using vector_dist_gpu = vector_dist<dim,St,prop,Decomposition,CudaMemory,memory_traits_inte>;
3385 template<unsigned int dim, typename St, typename prop, typename Decomposition = CartDecomposition<dim,St,HeapMemory,memory_traits_inte>> using vector_dist_soa = vector_dist<dim,St,prop,Decomposition,HeapMemory,memory_traits_inte>;
3386 template<unsigned int dim, typename St, typename prop, typename Decomposition = CartDecomposition<dim,St,CudaMemory,memory_traits_inte>> using vector_dist_dev = vector_dist<dim,St,prop,Decomposition,CudaMemory,memory_traits_inte>;
3387 
3388 #endif /* VECTOR_HPP_ */
void setCapacity(unsigned int ns)
Reserve space for the internal vectors.
void reorder_rcut(St r_cut)
Construct a cell list starting from the stored particles and reorder a vector according to the Hilber...
auto getPosOrig(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
decrement_memory(vector_type &v)
constructor
auto getLastPropWrite() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
auto getPropNC(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
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 hostToDeviceProp()
Move the memory from the device to host memory.
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
auto getLastPosWrite() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
Decomposition & getDecomposition()
Get the decomposition.
Vcluster< Memory > & v_cl
VCluster.
auto getPosNC(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
Transform the boost::fusion::vector into memory specification (memory_traits)
bool write_frame(std::string out, size_t iteration, int opt=VTK_WRITER)
Output particle position and properties.
void check_parameters(Box< dim, St > &box)
Check if the parameters describe a valid vector. In case it does not report an error.
vector_dist_prop & getPropVector()
return the property vector of all the particles
size_t getProcessUnitID()
Get the process unit id.
void deviceToHostProp()
Move the memory from the device to host memory.
auto getPropNC(size_t vec_key) -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
vector_dist_prop v_prp
grid_key_dx< dim > getCRSStart(Celllist &NN)
Return from which cell we have to start in case of CRS interation scheme.
vector_dist_pos & getPosVectorSort()
return the position vector of all the particles
St stype
space type
void operator()(T &t) const
It call the copy function for each property.
const Decomposition & getDecomposition() const
Get the decomposition.
void update(const int &v)
Update the addresses of all vector_dist_kernels around.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Definition: Vector.hpp:39
Class for Verlet list implementation.
size_t size_local_with_ghost() const
return the local size of the vector
auto getPosOrig(size_t vec_key) -> decltype(v_pos.template get< 0 >(vec_key))
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.
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
void ghost_put(size_t opt_=NONE)
It synchronize the properties and position of the ghost particles.
void magnify(T mg)
Magnify the box.
Definition: Box.hpp:889
const vector_dist_pos & getPosVectorSort() const
return the position vector of all the particles
void ghost_get_(openfpm::vector< Point< dim, St >, Memory, layout_base > &v_pos, openfpm::vector< prop, Memory, layout_base > &v_prp, size_t &g_m, size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
void remove(size_t key)
Remove one element from the distributed vector.
CellL getCellList(St r_cut, const Ghost< dim, St > &enlarge, bool no_se3=false)
Construct a cell list starting from the stored particles.
void setPropNames(const openfpm::vector< std::string > &names)
Set the properties names.
VerletL getVerletSym(St r_cut)
for each particle get the symmetric verlet list
grid_key_dx< dim > getCRSStop(Celllist &NN)
Return from which cell we have to stop in case of CRS interation scheme.
void map_list_(openfpm::vector< Point< dim, St >> &v_pos, openfpm::vector< prop > &v_prp, size_t &g_m, size_t opt)
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) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
static CellL get(Vector &vd, const St &r_cut, const Ghost< dim, St > &g)
Get the Cell list based on the type.
VerletL getVerlet(St r_cut)
for each particle get the verlet list
vector_dist_iterator getDomainIterator_no_se3() const
Get an iterator that traverse the particles in the domain.
auto getPosNC(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
Iterator that Iterate across particle indexes.
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
std::integral_constant< bool, false > is_it_a_subset
yes I am vector subset dist
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
void init_structures(size_t np)
Initialize the structures.
Grid key for a distributed grid.
void finalizeComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition coming from the particles.
vector_type & v
vector
void setDecompositionGranularity(size_t n_sub)
Set the minimum number of sub-domain per processor.
size_t size()
Stub size.
Definition: map_vector.hpp:211
vector_dist_iterator getGhostIterator() const
Get the iterator across the position of the ghost particles.
auto getPos(size_t vec_key) -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
Decomposition & getDecomposition()
Get the decomposition.
vector_dist_iterator getDomainAndGhostIterator() const
Get an iterator that traverse the particles in the domain.
void addComputationCosts(const self &vd, Model md=Model())
Add the computation cost on the decomposition coming from the particles.
std::string toString() const
Produce a string from the object.
Definition: Box.hpp:1409
vector_dist_prop v_prp_out
reordered v_pos buffer
CSV Writer.
Definition: CSVWriter.hpp:163
void Ighost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
CellL getCellListSym(St r_cut)
Construct a cell list symmetric based on a cut of radius.
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.
void save(const std::string &filename) const
Save the distributed vector on HDF5 file.
CellL getCellList(St r_cut, bool no_se3=false)
Construct a cell list starting from the stored particles.
void remove(openfpm::vector< size_t > &keys, size_t start=0)
Remove a set of elements from the distributed vector.
auto getPropNC(size_t vec_key) const -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
void map_post()
Operation to do after map.
openfpm::vector_key_iterator_seq< typename vrl::Mem_type_type::local_index_type > getParticleIteratorCRS(vrl &NN)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme.
void resize(size_t rs)
Resize the vector (locally)
size_t getPadding(size_t i) const
Return the number of padding cells of the Cell decomposer.
Definition: CellList.hpp:1081
void execute()
Execute all the requests.
This class define the domain decomposition interface.
CellL getCellList_hilb(St r_cut)
Construct an hilbert cell list starting from the stored particles.
void ghost_wait(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
const vector_dist_prop & getPropVectorSort() const
return the property vector of all the particles
void deleteGhost()
Delete the particles on the ghost.
static CellL get(Vector &vd, const St &r_cut, const Ghost< dim, St > &g)
Get the Cell list based on the type.
void swap(VerletList< dim, T, Mem_type, transform, vector_pos_type, CellListImpl > &vl)
Swap the memory.
const vector_dist_prop & getPropVector() const
return the property vector of all the particles
vector_dist(size_t np, Box< dim, St > box, const size_t(&bc)[dim], const Ghost< dim, St > &g, const grid_sm< dim, void > &gdist)
Constructor of a distributed vector.
void initializeComputationCosts()
Initialize the computational cost.
auto getLastPos() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
vector_dist_iterator getIterator(size_t start, size_t stop)
Get an iterator that traverse domain and ghost particles.
bool write_frame(std::string out, size_t iteration, std::string meta_info, int opt=VTK_WRITER)
Output particle position and properties.
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.
prop value_type
property object
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
This class decompose a space into sub-sub-domains and distribute them across processors.
long int who()
It return the id of structure in the allocation list.
auto getLastPosRead() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
vector_dist_iterator getGhostIterator_no_se3() const
Get the iterator across the position of the ghost particles.
void hostToDevicePos()
Move the memory from the device to host memory.
void Initialize()
Initialize the se_class2 structure.
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const size_t(&sz)[dim])
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.
size_t rank()
Get the process unit id.
CellL getCellListSym(const size_t(&div)[dim], const size_t(&pad)[dim])
Construct a cell list symmetric based on a cut of radius.
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:823
This class check for inconsistency access.
General function t get a cell-list.
openfpm::vector< std::string > prp_names
Name of the properties.
auto getProp(size_t vec_key) const -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
size_t g_m
Ghost marker, all the particle with id > g_m are ghost all with g_m < are real particle.
Vcluster< Memory > & getVC()
Get the Virtual Cluster machine.
auto getLastProp() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
auto getPropWrite(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
void remove(openfpm::vector< aggregate< int >> &keys, size_t start=0)
Remove a set of elements from the distributed vector.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
vector_dist_pos & getPosVector()
return the position vector of all the particles
bool write(std::string out, int opt=VTK_WRITER)
Output particle position and properties.
void updateCellListSym(CellL &cell_list)
Update a cell list using the stored particles.
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.
openfpm::vector< std::string > & getPropNames()
Get the properties names.
size_t getProcessingUnits()
Get the total number of processors.
static CellL get(Vector &vd, const St &r_cut, const Ghost< dim, St > &g)
Get the Cell list based on the type.
This class is an helper for the communication of vector_dist.
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
General function t get a cell-list.
auto getLastPropRead() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
void add()
Add local particle.
void init_decomposition_gr_cell(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.
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...
size_t accum()
It return the sum of the particles in the previous processors.
void setReferenceCounterToOne()
auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
cell_list_selector< self, impl >::ctype getCellListDev(St r_cut)
Construct a cell list starting from the stored particles.
static const unsigned int dims
dimensions of space
auto getCellListDevice(St r_cut, bool no_se3=false) -> decltype(this->getCellList(r_cut, no_se3))
Construct a cell list from the stored particles.
int yes_i_am_vector_dist
yes I am vector dist
void check_ghost_compatible_rcut(St r_cut)
It check that the r_cut is not bugger than the ghost.
vector_dist_iterator getIterator()
Get an iterator that traverse domain and ghost particles.
vector_dist(const Decomposition &dec, size_t np)
Constructor with predefined decomposition.
mgpu::ofp_context_t & getmgpuContext(bool iw=true)
If nvidia cuda is activated return a mgpu context.
bool isValid() const
Check if the Box is a valid box P2 >= P1.
Definition: Box.hpp:1180
size_t init_size_accum(size_t np)
It return the number of particles contained by the previous processors.
void addComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition coming from the particles.
void updateCellList(CellL &cell_list, bool no_se3=false, cl_construct_opt opt=cl_construct_opt::Full)
Update a cell list using the stored particles.
void ghost_put_(openfpm::vector< Point< dim, St >, Memory, layout_base > &v_pos, openfpm::vector< prop, Memory, layout_base > &v_prp, size_t &g_m, size_t opt)
Ghost put.
vector_dist_pos v_pos_out
reordered v_prp buffer
This iterator iterate across the particles of a Cell-list following the Cell structure.
Check this is a gpu or cpu type cell-list.
Definition: util.hpp:74
VerletL getVerletCrs(St r_cut)
for each particle get the symmetric verlet list
size_t opt
option used to create this vector
bool write(std::string out, std::string meta_info, int opt=VTK_WRITER)
Output particle position and properties.
Decomposition dec
Domain decomposition.
Distributed vector.
bool isSubset() const
Indicate that this class is not a subset.
void ghost_wait_(openfpm::vector< Point< dim, St >, Memory, layout_base > &v_pos, openfpm::vector< prop, Memory, layout_base > &v_prp, size_t &g_m, size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
void deviceToHostPos()
Move the memory from the device to host memory.
size_t size()
Get the total number of processors.
auto getPropRead(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
auto getPos(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
vector_dist_pos v_pos
auto getPosNC(size_t vec_key) -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
vector_dist< dim, St, prop, Decomposition, Memory, layout_base > & operator=(const vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &v)
Operator= for distributed vector.
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
vector_dist< dim, St, prop, Decomposition, Memory, layout_base > & operator=(vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &&v)
Operator= for distributed vector.
vector_dist(const vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &v)
Copy Constructor.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:214
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.
vector_dist(vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &&v) noexcept
Copy constructor.
auto getPosNC(size_t vec_key) const -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
auto getProp(size_t vec_key) -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
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 getPos(size_t vec_key) const -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
CellL getCellList_hilb(St r_cut, const Ghost< dim, St > &enlarge)
Construct an hilbert cell list starting from the stored particles.
ParticleItCRS_Cells< dim, cli, decltype(v_pos)> getParticleIteratorCRS_Cell(cli &NN)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme.
This class contain a list of all tracked vector_dist_ker around.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
Class for FAST cell list implementation.
Definition: CellList.hpp:356
const vector_dist_pos & getPosVector() const
return the position vector of all the particles
auto getProp(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
ParticleIt_Cells< dim, CellList > getDomainIteratorCells(CellList &NN)
Get an iterator that traverse the particles in the domain using a cell list.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
auto getDomainIteratorDevice(size_t n_thr=default_kernel_wg_threads_) const -> decltype(this->getDomainIterator())
Get an iterator that traverse the particles in the domain.
void clear()
remove all the elements
size_t size_local_orig() const
return the local size of the vector
void load(const std::string &filename)
Load the distributed vector from an HDF5 file.
void ghost_get_subset()
Stub does not do anything.
void map_list(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
vector_dist_iterator getDomainAndGhostIterator_no_se3() const
Get an iterator that traverse the particles in the domain.
vector_dist_prop & getPropVectorSort()
return the property vector of all the particles
auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.