OpenFPM  5.2.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_util.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 "util/common.hpp"
22 #include "util/object_util.hpp"
23 #include "memory/ExtPreAlloc.hpp"
24 #include "CSVWriter/CSVWriter.hpp"
25 #include "VTKWriter/VTKWriter.hpp"
26 #include "Decomposition/common.hpp"
27 #include "Grid/Iterators/grid_dist_id_iterator_dec.hpp"
28 #include "Grid/grid_key_dx_iterator_hilbert.hpp"
29 #include "Vector/vector_dist_ofb.hpp"
30 #include "Decomposition/CartDecomposition.hpp"
31 #include "data_type/aggregate.hpp"
32 #include "NN/VerletList/VerletList.hpp"
33 #include "vector_dist_comm.hpp"
34 #include "DLB/LB_Model.hpp"
35 #include "Vector/vector_map_iterator.hpp"
36 #include "NN/CellList/ParticleIt_Cells.hpp"
37 #include "NN/CellList/SFCKeys.hpp"
38 #include "Vector/vector_dist_kernel.hpp"
39 #include "NN/CellList/cuda/CellList_gpu.hpp"
40 #include "lib/pdata.hpp"
41 #include "cuda/vector_dist_operators_list_ker.hpp"
42 #include "util/PathsAndFiles.hpp"
43 
44 #include <type_traits>
45 
46 #define DEC_GRAN(gr) ((size_t)gr << 32)
47 
48 #ifdef CUDA_GPU
49 template<unsigned int dim,typename St> using CELLLIST_GPU_SPARSE = CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>,true>;
50 #endif
51 
52 #define VECTOR_DIST_ERROR_OBJECT std::runtime_error("Runtime vector distributed error");
53 
54 #ifdef SE_CLASS3
55 #include "se_class3_vector.hpp"
56 #endif
57 
58 #ifdef SE_CLASS3
59  #define SE_CLASS3_VDIST_CONSTRUCTOR ,se3(getDecomposition(),*this)
60 #else
61  #define SE_CLASS3_VDIST_CONSTRUCTOR
62 #endif
63 
64 // Perform a ghost get or a ghost put
65 constexpr int GET = 1;
66 constexpr int PUT = 2;
67 
68 // Write the particles with ghost
69 constexpr int NO_GHOST = 0;
70 constexpr int WITH_GHOST = 2;
71 
72 enum reorder_opt
73 {
74  NO_REORDER = 0,
75  HILBERT = 1,
76  LINEAR = 2
77 };
78 
79 
80 template<typename vector_type>
82 {
85 
86 
95  :v(v)
96  {};
97 
98 
104  template<typename T>
105  inline void operator()(T& t) const
106  {
107  v.template getMemory<T::value>().decRef();
108  }
109 };
110 
111 /*
112  * SFINAE version of getProp function for vector_dist
113  * checks whether the property at the position 'id' is
114  * of the type T. Fails without compilation error if not
115  */
116 template<typename T, typename VectorType, unsigned id, typename = void>
118  static T get(VectorType const& vectorDist, unsigned p) { /*Default case*/ return 0.0; }
119 };
120 
121 template<typename T, typename VectorType, unsigned id>
122 
123 struct getPropSFINAE<T, VectorType, id, std::enable_if_t<std::is_same<typename std::remove_reference<typename boost::fusion::result_of::at_c<typename VectorType::value_type::type, id>::type>::type, T>::value>> {
124  static T get(VectorType const& vectorDist, unsigned p) { /*Special case for adaptive verlet list*/ return vectorDist.template getProp<id>(p); }
125 };
126 
127 
162 template<unsigned int dim,
163  typename St,
164  typename prop,
166  typename Memory = HeapMemory,
167  template<typename> class layout_base = memory_traits_lin,
168  typename vector_dist_pos = openfpm::vector<Point<dim, St>,Memory,layout_base>,
169  typename vector_dist_prop = openfpm::vector<prop,Memory,layout_base> >
170 class vector_dist : public vector_dist_comm<dim,St,prop,Decomposition,Memory,layout_base>,
171 #ifdef CUDA_GPU
172  private vector_dist_ker_list<vector_dist_ker<dim,St,prop,layout_base>>
173 #else
174  private vector_dist_ker_list<int>
175 #endif
176 {
177 
178 public:
179 
182 
184  static const unsigned int dims = dim;
185  typedef St stype;
186  typedef prop value_type;
188  typedef Memory Memory_type;
189 
190 private:
191 
193  size_t ghostMarker = 0;
194 
197  vector_dist_pos vPos;
198 
201  vector_dist_pos vPosReordered;
202 
205  vector_dist_prop vPrp;
206 
209  vector_dist_prop vPrpReordered;
210 
212  size_t opt = 0;
213 
216 
217 #ifdef SE_CLASS3
218 
220 
221 #endif
222 
223 #ifdef SE_CLASS1
224  int map_ctr=0;
225  //ghost check to be done.
226  int ghostget_ctr=0;
227 #endif
228 
234  void init_structures(size_t np)
235  {
236  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
237 
238  // convert to a local number of elements
239  size_t p_np = np / v_cl.getProcessingUnits();
240 
241  // Get non divisible part
242  size_t r = np % v_cl.getProcessingUnits();
243 
244  // Distribute the remain particles
245  if (v_cl.getProcessUnitID() < r)
246  p_np++;
247 
248  // resize the position vector
249  vPos.resize(p_np);
250 
251  // resize the properties vector
252  vPrp.resize(p_np);
253 
254  ghostMarker = p_np;
255  }
256 
263  {
264  // if the box is not valid return an error
265  if (box.isValid() == false)
266  {
267  std::cerr << __FILE__ << ":" << __LINE__ << " Error the domain is not valid " << box.toString() << std::endl;
268  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
269  }
270 
271  }
272 
279  {
280  for (size_t i = 0 ; i < dim ; i++)
281  {
282  if (fabs(getDecomposition().getGhost().getLow(i)) < r_cut)
283  {
284  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;
285  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
286  }
287  }
288  }
289 
298  template<typename CellL, typename sfc_it>
300  openfpm::vector<prop> & v_prp_dest,
301  sfc_it & h_it,
302  CellL & cellList)
303  {
304  v_pos_dest.resize(vPos.size());
305  v_prp_dest.resize(vPrp.size());
306 
307  //Index for v_pos_dest
308  size_t count = 0;
309 
310  grid_key_dx<dim> ksum;
311 
312  for (size_t i = 0; i < dim ; i++)
313  {ksum.set_d(i,cellList.getPadding(i));}
314 
315  while (h_it.isNext())
316  {
317  auto key = h_it.get();
318  key += ksum;
319 
320  size_t lin = cellList.getGrid().LinId(key);
321 
322  // for each particle in the Cell "lin"
323  for (size_t i = 0; i < cellList.getNelements(lin); i++)
324  {
325  //reorder
326  auto v = cellList.get(lin,i);
327  v_pos_dest.get(count) = vPos.get(v);
328  v_prp_dest.get(count) = vPrp.get(v);
329 
330  count++;
331  }
332  ++h_it;
333  }
334  }
335 
336 public:
337  typedef decltype(vPos) internal_position_vector_type;
338 
339  typedef CellList<dim, St, Mem_fast<>, shift<dim, St>, internal_position_vector_type > CellList_type;
340 
342  typedef int yes_i_am_vector_dist;
343 
345  typedef std::integral_constant<bool,false> is_it_a_subset;
346 
347 
357  {
359 
360  ghostMarker = v.ghostMarker;
361  vPos = v.vPos;
362  vPrp = v.vPrp;
363 
364 #ifdef SE_CLASS3
365  se3 = v.se3;
366 #endif
367 
368  opt = v.opt;
369 
370  return *this;
371  }
372 
382  {
384 
385  ghostMarker = v.ghostMarker;
386  vPos.swap(v.vPos);
387  vPrp.swap(v.vPrp);
388 
389 #ifdef SE_CLASS3
390  se3 = v.se3;
391 #endif
392 
393  opt = v.opt;
394 
395  return *this;
396  }
397 
398  // default constructor (structure contain garbage)
399  vector_dist()
400  {}
401 
402 
409  :vector_dist_comm<dim,St,prop,Decomposition,Memory,layout_base>(v.getDecomposition()) SE_CLASS3_VDIST_CONSTRUCTOR
410  {
411 #ifdef SE_CLASS2
412  check_new(this,8,VECTOR_DIST_EVENT,4);
413 #endif
414 
415  this->operator=(v);
416  }
417 
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,Decomposition,Memory,layout_base>(dec) 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 
468  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)
469  :opt(0) SE_CLASS3_VDIST_CONSTRUCTOR
470  {
471  if (opt >> 32 != 0)
472  {this->setDecompositionGranularity(opt >> 32);}
473 
474  check_parameters(box);
475 
476  init_structures(np);
477 
478  this->init_decomposition_gr_cell(box,bc,g,opt,gdist);
479 
480 
481 #ifdef SE_CLASS3
482  se3.Initialize();
483 #endif
484  }
485 
498  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>())
499  :opt(opt) SE_CLASS3_VDIST_CONSTRUCTOR
500  {
501 #ifdef SE_CLASS2
502  check_new(this,8,VECTOR_DIST_EVENT,4);
503 #endif
504 
505  if (opt >> 32 != 0)
506  {this->setDecompositionGranularity(opt >> 32);}
507 
508  check_parameters(box);
509 
510  init_structures(np);
511 
512  this->init_decomposition(box,bc,g,opt,gdist);
513 
514 
515 #ifdef SE_CLASS3
516  se3.Initialize();
517 #endif
518  }
519 
520  ~vector_dist()
521  {
522 #ifdef SE_CLASS2
523  check_delete(this);
524 #endif
525  }
526 
531  {
532  for (int i = 0 ; i < vPos.template getMemory<0>().ref() - 1; i++)
533  {
534  vPos.template getMemory<0>().decRef();
535  }
536 
537  for (int i = 0 ; i < vPrp.template getMemory<0>().ref() - 1; i++)
538  {
539  decrement_memory<decltype(vPrp)> m(vPrp);
540 
541  boost::mpl::for_each_ref<boost::mpl::range_c<int,0,decltype(vPrp)::value_type::max_prop>>(m);
542  }
543  }
544 
549  void clear()
550  {
551  resize(0);
552  }
553 
559  size_t size_local() const
560  {
561  return ghostMarker;
562  }
563 
569  size_t size_local_with_ghost() const
570  {
571  return vPos.size();
572  }
573 
574 #ifndef ONLY_READWRITE_GETTER
575 
585  inline auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get<0>(vec_key.getKey()))
586  {
587 #ifdef SE_CLASS3
588  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
589 #endif
590 
591  return vPos.template get<0>(vec_key.getKey());
592  }
593 
603  inline auto getPos(vect_dist_key_dx vec_key) const -> decltype(vPos.template get<0>(vec_key.getKey()))
604  {
605 #ifdef SE_CLASS3
606  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
607 #endif
608  return vPos.template get<0>(vec_key.getKey());
609  }
610 
620  inline auto getPos(size_t vec_key) -> decltype(vPos.template get<0>(vec_key))
621  {
622 #ifdef SE_CLASS3
623  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
624 #endif
625  return vPos.template get<0>(vec_key);
626  }
627 
637  inline auto getPos(size_t vec_key) const -> decltype(vPos.template get<0>(vec_key))
638  {
639 #ifdef SE_CLASS3
640  check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
641 #endif
642  return vPos.template get<0>(vec_key);
643  }
644 
655  template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) -> decltype(vPrp.template get<id>(vec_key.getKey()))
656  {
657 #ifdef SE_CLASS3
658  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key.getKey());
659 #endif
660  return vPrp.template get<id>(vec_key.getKey());
661  }
662 
673  template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) const -> decltype(vPrp.template get<id>(vec_key.getKey()))
674  {
675 #ifdef SE_CLASS3
676  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key.getKey());
677 #endif
678  return vPrp.template get<id>(vec_key.getKey());
679  }
680 
691  template<unsigned int id> inline auto getProp(size_t vec_key) -> decltype(vPrp.template get<id>(vec_key))
692  {
693 #ifdef SE_CLASS3
694  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key);
695 #endif
696  return vPrp.template get<id>(vec_key);
697  }
698 
709  template<unsigned int id> inline auto getProp(size_t vec_key) const -> decltype(vPrp.template get<id>(vec_key))
710  {
711 #ifdef SE_CLASS3
712  check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key);
713 #endif
714  return vPrp.template get<id>(vec_key);
715  }
716 
717 #endif
718 
720 
730  inline auto getPosNC(vect_dist_key_dx vec_key) -> decltype(vPos.template get<0>(vec_key.getKey()))
731  {
732  return vPos.template get<0>(vec_key.getKey());
733  }
734 
744  inline auto getPosNC(vect_dist_key_dx vec_key) const -> decltype(vPos.template get<0>(vec_key.getKey()))
745  {
746  return vPos.template get<0>(vec_key.getKey());
747  }
748 
758  inline auto getPosNC(size_t vec_key) -> decltype(vPos.template get<0>(vec_key))
759  {
760  return vPos.template get<0>(vec_key);
761  }
762 
772  inline auto getPosNC(size_t vec_key) const -> decltype(vPos.template get<0>(vec_key))
773  {
774  return vPos.template get<0>(vec_key);
775  }
776 
787  template<unsigned int id> inline auto getPropNC(vect_dist_key_dx vec_key) -> decltype(vPrp.template get<id>(vec_key.getKey()))
788  {
789  return vPrp.template get<id>(vec_key.getKey());
790  }
791 
802  template<unsigned int id> inline auto getPropNC(vect_dist_key_dx vec_key) const -> decltype(vPrp.template get<id>(vec_key.getKey()))
803  {
804  return vPrp.template get<id>(vec_key.getKey());
805  }
806 
817  template<unsigned int id> inline auto getPropNC(size_t vec_key) -> decltype(vPrp.template get<id>(vec_key))
818  {
819  return vPrp.template get<id>(vec_key);
820  }
821 
832  template<unsigned int id> inline auto getPropNC(size_t vec_key) const -> decltype(vPrp.template get<id>(vec_key))
833  {
834  return vPrp.template get<id>(vec_key);
835  }
836 
838 
848  inline auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(vPos.template get<0>(vec_key.getKey()))
849  {
850 #ifdef SE_CLASS3
851  se3.template write<prop::max_prop_real>(*this,vec_key.getKey());
852 #endif
853 
854  return vPos.template get<0>(vec_key.getKey());
855  }
856 
866  inline auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(vPos.template get<0>(vec_key.getKey()))
867  {
868 #ifdef SE_CLASS3
869  se3.template read<prop::max_prop_real>(*this,vec_key.getKey());
870 #endif
871 
872  return vPos.template get<0>(vec_key.getKey());
873  }
874 
885  template<unsigned int id> inline auto getPropWrite(vect_dist_key_dx vec_key) -> decltype(vPrp.template get<id>(vec_key.getKey()))
886  {
887 #ifdef SE_CLASS3
888  se3.template write<id>(*this,vec_key.getKey());
889 #endif
890 
891  return vPrp.template get<id>(vec_key.getKey());
892  }
893 
904  template<unsigned int id> inline auto getPropRead(vect_dist_key_dx vec_key) const -> decltype(vPrp.template get<id>(vec_key.getKey()))
905  {
906 #ifdef SE_CLASS3
907  se3.template read<id>(*this,vec_key.getKey());
908 #endif
909 
910  return vPrp.template get<id>(vec_key.getKey());
911  }
912 
914 
923  void add()
924  {
925  vPrp.insert(ghostMarker);
926  vPos.insert(ghostMarker);
927 
928  ghostMarker++;
929 
930 #ifdef SE_CLASS3
931  for (size_t i = 0 ; i < prop::max_prop_real+1 ; i++)
932  vPrp.template get<prop::max_prop_real>(ghostMarker-1)[i] = UNINITIALIZED;
933 #endif
934  }
935 
937 
946  void appendLocal()
947  {
948  vPos.add();
949  }
950 
951 #ifndef ONLY_READWRITE_GETTER
952 
958  inline auto getLastPos() -> decltype(vPos.template get<0>(0))
959  {
960  return vPos.template get<0>(ghostMarker - 1);
961  }
962 
963 
969  inline auto getLastPosEnd() -> decltype(vPos.template get<0>(0))
970  {
971  return vPos.template get<0>(vPos.size() - 1);
972  }
973 
981  template<unsigned int id> inline auto getLastProp() -> decltype(vPrp.template get<id>(0))
982  {
983  return vPrp.template get<id>(ghostMarker - 1);
984  }
985 
986 #endif
987 
989 
995  inline auto getLastPosRead() -> decltype(vPos.template get<0>(0))
996  {
997 #ifdef SE_CLASS3
998  se3.template read<prop::max_prop_real>(*this,ghostMarker-1);
999 #endif
1000 
1001  return vPos.template get<0>(ghostMarker - 1);
1002  }
1003 
1011  template<unsigned int id> inline auto getLastPropRead() -> decltype(vPrp.template get<id>(0))
1012  {
1013 #ifdef SE_CLASS3
1014  se3.read<id>(*this,ghostMarker-1);
1015 #endif
1016 
1017  return vPrp.template get<id>(ghostMarker - 1);
1018  }
1019 
1020 
1026  inline auto getLastPosWrite() -> decltype(vPos.template get<0>(0))
1027  {
1028 #ifdef SE_CLASS3
1029  se3.template write<prop::max_prop_real>(*this,ghostMarker-1);
1030 #endif
1031 
1032  return vPos.template get<0>(ghostMarker - 1);
1033  }
1034 
1042  template<unsigned int id> inline auto getLastPropWrite() -> decltype(vPrp.template get<id>(0))
1043  {
1044 #ifdef SE_CLASS3
1045  se3.template write<id>(*this,ghostMarker-1);
1046 #endif
1047 
1048  return vPrp.template get<id>(ghostMarker - 1);
1049  }
1050 
1052 
1062  template<typename CellList_type = CellList<dim, St, Mem_fast<>, shift<dim, St>,internal_position_vector_type > >
1063  CellList_type getCellListSym(St r_cut, size_t opt = CL_LINEAR_CELL_KEYS)
1064  {
1065  return getCellList(r_cut, opt | CL_SYMMETRIC);
1066  }
1067 
1077  template<typename CellList_type = CellList<dim, St, Mem_fast<>, shift<dim, St>,internal_position_vector_type > >
1078  CellList_type getCellListSymLocal(St r_cut, size_t opt = CL_LINEAR_CELL_KEYS)
1079  {
1080  return getCellList(r_cut, opt | CL_LOCAL_SYMMETRIC);
1081  }
1082 
1093  template<typename CellList_type = CellList<dim, St, Mem_fast<>, shift<dim, St>, decltype(vPos) > >
1094  CellList_type getCellList(St r_cut, size_t opt = CL_NON_SYMMETRIC | CL_LINEAR_CELL_KEYS, bool no_se3 = false, float ghostEnlargeFactor = 1.013)
1095  {
1096  if (opt & CL_SYMMETRIC || opt & CL_LOCAL_SYMMETRIC) {
1097 #ifdef SE_CLASS1
1098  if (!(opt & BIND_DEC_TO_GHOST))
1099  {
1100  if (getDecomposition().getGhost().getLow(dim-1) == 0.0)
1101  {
1102  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;
1103  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1104  }
1105  }
1106 #endif
1107  size_t pad = 0;
1108  CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
1109  cl_param_calculateSym(getDecomposition().getDomain(),cd_sm,getDecomposition().getGhost(),r_cut,pad);
1110 
1111  // Processor bounding box
1112  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1113 
1114  CellList_type cellList;
1115 
1116  cellList.setOpt(opt);
1117  cellList.Initialize(cd_sm,pbox,pad);
1118  cellList.set_ndec(getDecomposition().get_ndec());
1119  cellList.setGhostMarker(ghostMarker);
1120 
1121  cellList.fill(vPos, vPrp, ghostMarker);
1122 
1123  return cellList;
1124  }
1125 
1126  // CL_NON_SYMMETRIC
1127  else {
1128 #ifdef SE_CLASS3
1129  if (no_se3 == false)
1130  {se3.getNN();}
1131 #endif
1132 #ifdef SE_CLASS1
1134 #endif
1135  // Get ghost and anlarge by 1%
1136  Ghost<dim,St> ghostEnlarge = getDecomposition().getGhost();
1137  ghostEnlarge.magnify(ghostEnlargeFactor);
1138 
1139  // Division array
1140  size_t div[dim];
1141 
1142  // get the processor bounding box
1143  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1144 
1145  // Processor bounding box
1146  cl_param_calculate(pbox, div, r_cut, ghostEnlarge);
1147 
1148  CellList_type cellList;
1149 
1150  cellList.setOpt(opt);
1151  cellList.Initialize(pbox, div);
1152  cellList.setGhostMarker(ghostMarker);
1153  cellList.set_ndec(getDecomposition().get_ndec());
1154 
1155  cellList.fill(vPos, vPrp, ghostMarker);
1156 
1157  return cellList;
1158  }
1159  }
1160 
1161 
1172  template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > >
1174  const size_t (& div)[dim],
1175  const size_t (& pad)[dim],
1176  size_t opt = CL_LINEAR_CELL_KEYS)
1177  {
1178 #ifdef SE_CLASS1
1179  if (!(opt & BIND_DEC_TO_GHOST))
1180  {
1181  if (getDecomposition().getGhost().getLow(dim-1) == 0.0)
1182  {
1183  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;
1184  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1185  }
1186  }
1187 #endif
1188 
1189  size_t pad_max = pad[0];
1190  for (size_t i = 1 ; i < dim ; i++)
1191  if (pad[i] > pad_max) pad_max = pad[i];
1192 
1193 
1194  CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
1195  cd_sm.setDimensions(getDecomposition().getDomain(),div,pad_max);
1196 
1197  // Processor bounding box
1198  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1199 
1200  CellL cellList;
1201 
1202  cellList.setOpt(opt | CL_SYMMETRIC);
1203  cellList.Initialize(cd_sm,pbox,pad_max);
1204  cellList.set_ndec(getDecomposition().get_ndec());
1205 
1206  cellList.fill(vPos, vPrp, ghostMarker);
1207 
1208  return cellList;
1209  }
1210 
1211 
1212 #ifdef CUDA_GPU
1213 
1222  template<typename CellType = CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>>>
1223  CellType getCellListGPU(St r_cut, size_t opt = CL_NON_SYMMETRIC, size_t NNIteratorBox = 1, bool no_se3 = false, float ghostEnlargeFactor = 1.013)
1224  {
1225 #ifdef SE_CLASS3
1226  if (no_se3 == false)
1227  {se3.getNN();}
1228 #endif
1229 #ifdef SE_CLASS1
1231 #endif
1232 
1233  // Get ghost and anlarge by 1%
1234  Ghost<dim,St> ghostEnlarge = getDecomposition().getGhost();
1235  ghostEnlarge.magnify(ghostEnlargeFactor);
1236 
1237  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1238 
1239  // Division array
1240  size_t div[dim];
1241 
1242  // get the processor bounding box
1243  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1244 
1245  // Processor bounding box
1246  cl_param_calculate(pbox, div, r_cut, ghostEnlarge);
1247 
1248  CellType cellList(pbox,div);
1249 
1250  // getNNIteratorBox has to be set here compared to getNNIteratorRadius (could be set later)
1251  // As sparse cell list on gpu uses it in construct()
1252  // If not set, the dafault value of 1 would have been used by construct()
1253  cellList.setOpt(opt);
1254  cellList.setBoxNN(NNIteratorBox);
1255  cellList.set_ndec(getDecomposition().get_ndec());
1256  cellList.setGhostMarker(ghostMarker);
1257 
1258  return cellList;
1259 
1260  }
1261 
1262 #endif
1263 
1273  template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > >
1274  CellL getCellList_hilb(St r_cut, size_t opt = CL_NON_SYMMETRIC)
1275  {
1276  return getCellList(r_cut, opt | CL_HILBERT_CELL_KEYS);
1277  }
1278 
1287  template<unsigned int ... prp,typename CellL>
1288  void updateCellList(CellL & cellList, bool no_se3 = false)
1289  {
1290 #ifdef SE_CLASS3
1291  if (no_se3 == false)
1292  {se3.getNN();}
1293 #endif
1294 
1295  // Here we have to check that the Cell-list has been constructed
1296  // from the same decomposition
1297  bool to_reconstruct = cellList.get_ndec() != getDecomposition().get_ndec();
1298 
1299  if (to_reconstruct == false)
1300  {
1301  cellList.fill(vPos, vPrp, ghostMarker);
1302  cellList.setGhostMarker(ghostMarker);
1303  }
1304  else
1305  {
1306  // This function assume equal spacing in all directions
1307  // but in the worst case we take the maximum
1308  St r_cut = cellList.getCellBox().getRcut();
1309 
1310  if (cellList.getOpt() & CL_SYMMETRIC) {
1311  CellL cellListTmp = getCellListSym<CellL>(cellList.getDivWP(), cellList.getPadding());
1312  cellList.swap(cellListTmp);
1313  }
1314 
1315  else {
1316  CellL cellListTmp = getCellList<CellL>(r_cut, cellList.getOpt());
1317  cellList.swap(cellListTmp);
1318  }
1319 
1320  }
1321  }
1322 
1323 
1324 #ifdef CUDA_GPU
1325 
1334  template<unsigned int ... prp, typename CellList_type>
1335  void updateCellListGPU(CellList_type & cellList, bool no_se3 = false)
1336  {
1337 #ifdef SE_CLASS3
1338  if (no_se3 == false)
1339  {se3.getNN();}
1340 #endif
1341  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1342 
1343  if (cellList.getOpt() & CL_GPU_REORDER_POSITION)
1344  if (vPosReordered.size() != vPos.size()) vPosReordered.resize(vPos.size());
1345 
1346  if (cellList.getOpt() & CL_GPU_REORDER_PROPERTY)
1347  if (vPrpReordered.size() != vPrp.size()) vPrpReordered.resize(vPrp.size());
1348 
1349  // Here we have to check that the Cell-list has been constructed
1350  // from the same decomposition
1351  bool to_reconstruct = cellList.get_ndec() != getDecomposition().get_ndec();
1352 
1353  if (to_reconstruct == false)
1354  {
1355  if (cellList.getOpt() & CL_GPU_REORDER_POSITION || cellList.getOpt() & CL_GPU_REORDER_PROPERTY) {
1356 
1357  cellList.template construct<decltype(vPos),decltype(vPrp),prp ...>(
1358  vPos,
1359  vPrp,
1360  vPosReordered,
1361  vPrpReordered,
1362  v_cl.getGpuContext(),
1363  ghostMarker,
1364  0,
1365  vPos.size());
1366 
1367  if (cellList.getOpt() & CL_GPU_REORDER_POSITION) vPos.swap(vPosReordered);
1368  if (cellList.getOpt() & CL_GPU_REORDER_PROPERTY) vPrp.swap(vPrpReordered);
1369  }
1370  else
1371  cellList.construct(vPos,vPrp,v_cl.getGpuContext(),ghostMarker,0,vPos.size());
1372  }
1373 
1374  else
1375  {
1376  // This function assume equal spacing in all directions
1377  // but in the worst case we take the maximum
1378  St r_cut = cellList.getCellBox().getRcut();
1379 
1380  CellList_type cellListTmp = getCellListGPU<CellList_type>(r_cut, cellList.getOpt(), cellList.getBoxNN());
1381 
1382  if (cellList.getOpt() & CL_GPU_REORDER_POSITION || cellList.getOpt() & CL_GPU_REORDER_PROPERTY) {
1383  cellListTmp.template construct<decltype(vPos),decltype(vPrp),prp ...>(
1384  vPos,
1385  vPrp,
1386  vPosReordered,
1387  vPrpReordered,
1388  v_cl.getGpuContext(),
1389  ghostMarker,
1390  0,
1391  vPos.size());
1392 
1393  if (cellList.getOpt() & CL_GPU_REORDER_POSITION) vPos.swap(vPosReordered);
1394  if (cellList.getOpt() & CL_GPU_REORDER_PROPERTY) vPrp.swap(vPrpReordered);
1395  }
1396  else
1397  cellListTmp.construct(vPos,vPrp,v_cl.getGpuContext(),ghostMarker,0,vPos.size());
1398 
1399  cellList.swap(cellListTmp);
1400  }
1401  }
1402 
1403 #endif
1404 
1412  template <typename VerletList_type = VerletList<dim,St,VL_SYMMETRIC,Mem_fast<>,shift<dim,St>,decltype(vPos)>>
1413  VerletList_type getVerletSym(St r_cut)
1414  {
1415  return getVerlet<VL_SYMMETRIC, VerletList_type>(r_cut);
1416  }
1417 
1425  template <typename VerletList_type = VerletList<dim,St,VL_CRS_SYMMETRIC,Mem_fast<>,shift<dim,St>,decltype(vPos)>>
1426  VerletList_type getVerletCrs(St r_cut)
1427  {
1428 #ifdef SE_CLASS1
1429  if (!(opt & BIND_DEC_TO_GHOST))
1430  {
1431  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;
1432  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1433  }
1434 #endif
1435 
1436 #ifdef SE_CLASS3
1437  se3.getNN();
1438 #endif
1439 
1440  VerletList_type verletList;
1441 
1442  // Processor bounding box
1443  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1444 
1445  // Initialize the verlet list
1446  verletList.initializeCrs(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,vPos,ghostMarker);
1447 
1448  // Get the internal cell list
1449  auto & cellList = verletList.getInternalCellList();
1450 
1451  // Shift
1453 
1454  // Add padding
1455  for (size_t i = 0 ; i < dim ; i++)
1456  shift.set_d(i,cellList.getPadding(i));
1457 
1458  grid_sm<dim,void> gs = cellList.getInternalGrid();
1459 
1460  getDecomposition().setNNParameters(shift,gs);
1461 
1462  verletList.fillCRSSymmetric(vPos,r_cut,ghostMarker,
1463  getDecomposition().getCRSDomainCells(),
1464  getDecomposition().getCRSAnomDomainCells()
1465  );
1466 
1467  verletList.set_ndec(getDecomposition().get_ndec());
1468 
1469  return verletList;
1470  }
1471 
1479  template <typename VerletList_type = VerletList<dim,St,VL_NON_SYMMETRIC|VL_ADAPTIVE_RCUT,Mem_fast<>,shift<dim,St>,decltype(vPos)>>
1480  VerletList_type getVerletAdaptRCut()
1481  {
1482 #ifdef SE_CLASS3
1483  se3.getNN();
1484 #endif
1485  openfpm::vector<St> rCuts(vPos.size());
1486  // rCut is always stored in the first property
1487  for (int i = 0; i < vPos.size(); ++i)
1488  rCuts.get(i) = getPropSFINAE<St, self, 0>::get(*this, i);
1489 
1490  VerletList_type verletList;
1491 
1492  // get the processor bounding box
1493  Ghost<dim,St> g = getDecomposition().getGhost();
1494  g.magnify(1.013);
1495 
1496  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1497  // enlarge the box where the Verlet is defined
1498  pbox.enlarge(g);
1499 
1500  verletList.InitializeNonSymmAdaptive(pbox,rCuts,vPos,ghostMarker);
1501 
1502  return verletList;
1503  }
1504 
1514  template <unsigned int optVerlet=VL_NON_SYMMETRIC, typename VerletList_type = VerletList<dim,St,optVerlet,Mem_fast<>,shift<dim,St>,decltype(vPos)>>
1515  VerletList_type getVerlet(St r_cut, size_t neighborMaxNum = 0)
1516  {
1517 #ifdef SE_CLASS3
1518  se3.getNN();
1519 #endif
1520 
1521  VerletList_type verletList;
1522 
1523  if (neighborMaxNum)
1524  verletList.setNeighborMaxNum(neighborMaxNum);
1525 
1526  // get the processor bounding box
1527  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1528 
1529  if (verletList.getOpt() & VL_SYMMETRIC)
1530  {
1531  verletList.InitializeSym(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,vPos,ghostMarker);
1532  }
1533 
1534  else
1535  {
1536  Ghost<dim,St> g = getDecomposition().getGhost();
1537  g.magnify(1.013);
1538  // enlarge the box where the Verlet is defined
1539  pbox.enlarge(g);
1540 
1541  verletList.Initialize(pbox,r_cut,vPos,ghostMarker);
1542  }
1543 
1544  verletList.set_ndec(getDecomposition().get_ndec());
1545 
1546  return verletList;
1547  }
1548 
1555  template<unsigned int opt, typename Mem_type>
1556  void updateVerlet(VerletList<dim,St,opt,Mem_type,shift<dim,St> > & verletList, St r_cut)
1557  {
1558 #ifdef SE_CLASS3
1559  se3.getNN();
1560 #endif
1561  if ((opt & VL_SYMMETRIC) || (opt & VL_NON_SYMMETRIC))
1562  {
1563  auto & cellList = verletList.getInternalCellList();
1564 
1565  // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1566  // processor. if it is not like that we have to completely reconstruct from stratch
1567  bool to_reconstruct = cellList.get_ndec() != getDecomposition().get_ndec();
1568 
1569  if (to_reconstruct == false)
1570  {
1571  verletList.update(getDecomposition().getDomain(),r_cut,vPos,ghostMarker);
1572  }
1573 
1574  else
1575  {
1576  VerletList<dim,St,opt,Mem_type,shift<dim,St>> ver_tmp = getVerlet<opt, VerletList<dim,St,opt,Mem_type,shift<dim,St>>>(r_cut);
1577  verletList.swap(ver_tmp);
1578  }
1579  }
1580  else if (opt & VL_CRS_SYMMETRIC)
1581  {
1582 #ifdef SE_CLASS1
1583  if ((this->opt & BIND_DEC_TO_GHOST))
1584  {
1585  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;
1586  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1587  }
1588 #endif
1589 
1590  auto & cellList = verletList.getInternalCellList();
1591 
1592  // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1593  // processor. if it is not like that we have to completely reconstruct from stratch
1594  bool to_reconstruct = cellList.get_ndec() != getDecomposition().get_ndec();
1595 
1596  if (to_reconstruct == false)
1597  {
1598  // Shift
1600 
1601  // Add padding
1602  for (size_t i = 0 ; i < dim ; i++)
1603  shift.set_d(i,cellList.getPadding(i));
1604 
1605  grid_sm<dim,void> gs = cellList.getInternalGrid();
1606 
1607  getDecomposition().setNNParameters(shift,gs);
1608 
1609  verletList.updateCrs(vPos,r_cut,ghostMarker,
1610  getDecomposition().getCRSDomainCells(),
1611  getDecomposition().getCRSAnomDomainCells()
1612  );
1613  }
1614  else
1615  {
1616  VerletList<dim,St,opt,Mem_type,shift<dim,St>> ver_tmp = getVerletCrs<VerletList<dim,St,opt,Mem_type,shift<dim,St> >>(r_cut);
1617  verletList.swap(ver_tmp);
1618  }
1619  }
1620  }
1621 
1628  template<unsigned int opt, typename Mem_type>
1629  void updateVerletAdaptRCut(VerletList<dim,St,opt,Mem_type,shift<dim,St> > & verletList)
1630  {
1631 #ifdef SE_CLASS3
1632  se3.getNN();
1633 #endif
1634  // in this mode the Verlet list doesn't depend on the decomposition counter
1635  // has to be fully reconstructed on update
1636  openfpm::vector<St> rCuts(vPos.size());
1637  // rCut is always stored in the first property
1638  for (int i = 0; i < vPos.size(); ++i)
1639  rCuts.get(i) = getPropSFINAE<St, self, 0>::get(*this, i);
1640 
1641  // get the processor bounding box
1642  Ghost<dim,St> g = getDecomposition().getGhost();
1643  g.magnify(1.013);
1644 
1645  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1646  // enlarge the box where the Verlet is defined
1647  pbox.enlarge(g);
1648 
1649  verletList.InitializeNonSymmAdaptive(pbox,rCuts,vPos,ghostMarker);
1650  }
1651 
1652 
1660  template<typename CellL=CellList<dim,St,Mem_bal<>,shift<dim,St> > >
1661  void reorder (int32_t m, reorder_opt opt = reorder_opt::HILBERT)
1662  {
1663  reorder<CellL>(m,getDecomposition().getGhost(),opt);
1664  }
1665 
1666 
1680  template<typename CellL=CellList<dim,St,Mem_bal<>,shift<dim,St> > >
1681  void reorder(int32_t m, const Ghost<dim,St> & enlarge, reorder_opt opt = reorder_opt::HILBERT)
1682  {
1683  // reset the ghost part
1684  vPos.resize(ghostMarker);
1685  vPrp.resize(ghostMarker);
1686 
1687 
1688  CellL cellList;
1689 
1690  // calculate the parameters of the cell list
1691 
1692  // get the processor bounding box
1693  Box<dim,St> pbox = getDecomposition().getProcessorBounds();
1694  // extend by the ghost
1695  pbox.enlarge(enlarge);
1696 
1697  size_t div[dim];
1698 
1699  // Calculate the division array and the cell box
1700  for (size_t i = 0 ; i < dim ; i++)
1701  {
1702  div[i] = 1 << m;
1703  }
1704 
1705  cellList.Initialize(pbox,div);
1706  cellList.setGhostMarker(ghostMarker);
1707 
1708  // for each particle add the particle to the cell list
1709 
1710  auto it = getIterator();
1711 
1712  while (it.isNext())
1713  {
1714  auto key = it.get();
1715 
1716  Point<dim,St> xp = this->getPos(key);
1717 
1718  cellList.add(xp,key.getKey());
1719 
1720  ++it;
1721  }
1722 
1723  // Use cellList to reorder vPos
1724 
1725  //destination vector
1726  openfpm::vector<Point<dim,St>> v_pos_dest;
1727  openfpm::vector<prop> v_prp_dest;
1728 
1729  if (opt == reorder_opt::HILBERT)
1730  {
1732 
1733  reorder_sfc<CellL,grid_key_dx_iterator_hilbert<dim>>(v_pos_dest,v_prp_dest,h_it,cellList);
1734  }
1735  else if (opt == reorder_opt::LINEAR)
1736  {
1737  grid_sm<dim,void> gs(div);
1738  grid_key_dx_iterator<dim> h_it(gs);
1739 
1740  reorder_sfc<CellL,grid_key_dx_iterator<dim>>(v_pos_dest,v_prp_dest,h_it,cellList);
1741  }
1742  else
1743  {
1744  // We do nothing, we second swap nullify the first
1745  vPos.swap(v_pos_dest);
1746  vPrp.swap(v_prp_dest);
1747  }
1748 
1749  vPos.swap(v_pos_dest);
1750  vPrp.swap(v_prp_dest);
1751  }
1752 
1766  template<typename CellL=CellList<dim,St,Mem_bal<>,shift<dim,St> > >
1767  void reorder_rcut(St r_cut)
1768  {
1769  // reset the ghost part
1770  vPos.resize(ghostMarker);
1771  vPrp.resize(ghostMarker);
1772 
1773  auto cellList = getCellList<CellL>(r_cut);
1774 
1775  // Use cellList to reorder vPos
1776 
1777  //destination vector
1778  openfpm::vector<Point<dim,St>> vPosReorder;
1779  openfpm::vector<prop> vPrpReorder;
1780 
1781  size_t div[dim];
1782  for (size_t i = 0 ; i < dim ; i++)
1783  {div[i] = cellList.getGrid().size(i) - 2*cellList.getPadding()[i];}
1784 
1785  grid_sm<dim,void> gs(div);
1786  grid_key_dx_iterator<dim> h_it(gs);
1787 
1788  reorder_sfc<CellL,grid_key_dx_iterator<dim>>(vPosReorder,vPrpReorder,h_it,cellList);
1789 
1790  vPos.swap(vPosReorder);
1791  vPrp.swap(vPrpReorder);
1792  }
1793 
1809  size_t init_size_accum(size_t np)
1810  {
1811  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1812 
1813  size_t accum = 0;
1814 
1815  // convert to a local number of elements
1816  size_t p_np = np / v_cl.getProcessingUnits();
1817 
1818  // Get non divisible part
1819  size_t r = np % v_cl.getProcessingUnits();
1820 
1821  accum = p_np * v_cl.getProcessUnitID();
1822 
1823  // Distribute the remain particles
1824  if (v_cl.getProcessUnitID() <= r)
1826  else
1827  accum += r;
1828 
1829  return accum;
1830  }
1831 
1838  {
1839 #ifdef SE_CLASS3
1840  se3.getIterator();
1841 #endif
1842  return vector_dist_iterator(0, vPos.size());
1843  }
1844 
1853  vector_dist_iterator getIterator(size_t start, size_t stop)
1854  {
1855 #ifdef SE_CLASS3
1856  se3.getIterator();
1857 #endif
1858  return vector_dist_iterator(start, stop);
1859  }
1860 
1871  {
1872  grid_key_dx<dim> start;
1873  grid_key_dx<dim> stop;
1874  for (size_t i = 0; i < dim; i++)
1875  {
1876  start.set_d(i, 0);
1877  stop.set_d(i, sz[i] - 1);
1878  }
1879 
1881  return it_dec;
1882  }
1883 
1890  {
1891 #ifdef SE_CLASS3
1892  se3.getIterator();
1893 #endif
1894 
1895  return vector_dist_iterator(ghostMarker, vPos.size());
1896  }
1897 
1904  {
1905  return vector_dist_iterator(ghostMarker, vPos.size());
1906  }
1907 
1916  template<typename CellList> ParticleIt_Cells<dim,CellList>
1918  {
1919 #ifdef SE_CLASS3
1920  se3.getIterator();
1921 #endif
1922 
1923  // Shift
1925 
1926  // Add padding
1927  for (size_t i = 0 ; i < dim ; i++)
1928  shift.set_d(i,cellList.getPadding(i));
1929 
1930  grid_sm<dim,void> gs = cellList.getInternalGrid();
1931 
1932  getDecomposition().setNNParameters(shift,gs);
1933 
1934  return ParticleIt_Cells<dim,CellList>(cellList,getDecomposition().getDomainCells(),ghostMarker);
1935  }
1936 
1943  {
1944 #ifdef SE_CLASS3
1945  se3.getIterator();
1946 #endif
1947 
1948  return vector_dist_iterator(0, ghostMarker);
1949  }
1950 
1951 #ifdef CUDA_GPU
1952 
1958  ite_gpu<1> getDomainIteratorGPU(size_t n_thr = default_kernel_wg_threads_) const
1959  {
1960 #ifdef SE_CLASS3
1961  se3.getIterator();
1962 #endif
1963 
1964  return vPos.getGPUIteratorTo(ghostMarker-1,n_thr);
1965  }
1966 
1972  ite_gpu<1> getDomainAndGhostIteratorGPU(size_t n_thr = default_kernel_wg_threads_) const
1973  {
1974 #ifdef SE_CLASS3
1975  se3.getIterator();
1976 #endif
1977 
1978  return vPos.getGPUIteratorTo(vPos.size()-1,n_thr);
1979  }
1980 
1987  template<unsigned int prp>
1988  void debugPrintVector()
1989  {
1990  this->vPrp.template deviceToHost<prp>();
1991 
1992  auto it = this->getDomainIterator();
1993 
1994  while(it.isNext())
1995  {
1996  auto p = it.get();
1997 
1998  for (size_t i = 0 ; i < std::extent<typename boost::mpl::at<typename prop::type,boost::mpl::int_<prp>>::type>::value ; i++)
1999  {
2000  std::cout << vPrp.template get<prp>(p.getKey())[i] << " ";
2001  }
2002 
2003  std::cout << std::endl;
2004 
2005  ++it;
2006  }
2007  }
2008 
2015  template<unsigned int prp>
2016  void debugPrintScalar()
2017  {
2018  this->vPrp.template deviceToHost<prp>();
2019 
2020  auto it = this->getDomainIterator();
2021 
2022  while(it.isNext())
2023  {
2024  auto p = it.get();
2025 
2026  std::cout << vPrp.template get<prp>(p.getKey()) << " " << std::endl;
2027 
2028  ++it;
2029  }
2030  }
2031 
2032 #endif
2033 
2034 #ifdef CUDA_GPU
2035 
2041  auto getDomainIteratorDevice(size_t n_thr = default_kernel_wg_threads_) const -> decltype(this->getDomainIteratorGPU(n_thr))
2042  {
2043  return this->getDomainIteratorGPU(n_thr);
2044  }
2045 
2046 
2047 #else
2048 
2054  auto getDomainIteratorDevice(size_t n_thr = default_kernel_wg_threads_) const -> decltype(this->getDomainIterator())
2055  {
2056  return this->getDomainIterator();
2057  }
2058 
2059 
2060 #endif
2061 
2068  {
2069  return vector_dist_iterator(0, ghostMarker);
2070  }
2071 
2078  {
2079 #ifdef SE_CLASS3
2080  se3.getIterator();
2081 #endif
2082 
2083  return vector_dist_iterator(0, vPos.size());
2084  }
2085 
2092  {
2093  return vector_dist_iterator(0, vPos.size());
2094  }
2095 
2102  {
2104  }
2105 
2111  inline const Decomposition & getDecomposition() const
2112  {
2114  }
2115 
2129  template<unsigned int ... prp> void map_list(size_t opt = NONE)
2130  {
2131 #ifdef SE_CLASS3
2132  se3.map_pre();
2133 #endif
2134 
2135  this->template map_list_<prp...>(vPos,vPrp,ghostMarker,opt);
2136 
2137 #ifdef CUDA_GPU
2138  this->update(this->toKernel());
2139 #endif
2140 
2141 #ifdef SE_CLASS3
2142  se3.map_post();
2143 #endif
2144  }
2145 
2146 
2158  template<typename obp = KillParticle> void map(size_t opt = NONE)
2159  {
2160 #ifdef SE_CLASS3
2161  se3.map_pre();
2162 #endif
2163 #ifdef SE_CLASS1
2164  map_ctr++;
2165 #endif
2166 
2167  this->template map_<obp>(vPos,vPrp,ghostMarker,opt);
2168 
2169 #ifdef CUDA_GPU
2170  this->update(this->toKernel());
2171 #endif
2172 
2173 #ifdef SE_CLASS3
2174  se3.map_post();
2175 #endif
2176  }
2177 #ifdef SE_CLASS1
2178  int getMapCtr() const
2179  {
2180  return map_ctr;
2181  }
2182 #endif
2183 
2184 
2189  {
2190  /* #ifdef SE_CLASS1
2191  This is not a ghost get on subset.
2192  std::cerr<<__FILE__<<":"<<__LINE__<<":You Used a ghost_get on a subset. This does not do anything. Please use ghostget on the entire set.";
2193  #endif */
2194  }
2195 
2203  template<int ... prp> inline void ghost_get(size_t opt = WITH_POSITION)
2204  {
2205 #ifdef SE_CLASS1
2206  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2207 
2208  if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2209  {
2210  std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2211  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2212  }
2213 #endif
2214 
2215 #ifdef SE_CLASS3
2216  se3.template ghost_get_pre<prp...>(opt);
2217 #endif
2218 
2219  this->template ghost_get_<GHOST_SYNC,prp...>(vPos,vPrp,ghostMarker,opt);
2220 
2221 #ifdef CUDA_GPU
2222  this->update(this->toKernel());
2223 #endif
2224 
2225 #ifdef SE_CLASS3
2226 
2227  this->template ghost_get_<prop::max_prop_real>(vPos,vPrp,ghostMarker,opt | KEEP_PROPERTIES);
2228 
2229  se3.template ghost_get_post<prp...>(opt);
2230 #endif
2231  }
2232 
2233 
2241  template<int ... prp> inline void Ighost_get(size_t opt = WITH_POSITION)
2242  {
2243 #ifdef SE_CLASS1
2244  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2245 
2246  if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2247  {
2248  std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2249  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2250  }
2251 #endif
2252 
2253 #ifdef SE_CLASS3
2254  se3.template ghost_get_pre<prp...>(opt);
2255 #endif
2256 
2257  this->template ghost_get_<GHOST_ASYNC,prp...>(vPos,vPrp,ghostMarker,opt);
2258  }
2259 
2267  template<int ... prp> inline void ghost_wait(size_t opt = WITH_POSITION)
2268  {
2269 #ifdef SE_CLASS1
2270  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2271 
2272  if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2273  {
2274  std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2275  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2276  }
2277 #endif
2278 
2279  this->template ghost_wait_<prp...>(vPos,vPrp,ghostMarker,opt);
2280 
2281 #ifdef CUDA_GPU
2282  this->update(this->toKernel());
2283 #endif
2284 
2285 #ifdef SE_CLASS3
2286 
2287  this->template ghost_get_<prop::max_prop_real>(vPos,vPrp,ghostMarker,opt | KEEP_PROPERTIES);
2288 
2289  se3.template ghost_get_post<prp...>(opt);
2290 #endif
2291  }
2292 
2304  template<template<typename,typename> class op, int ... prp> inline void ghost_put(size_t opt_ = NONE)
2305  {
2306 #ifdef SE_CLASS3
2307  se3.template ghost_put<prp...>();
2308 #endif
2309  this->template ghost_put_<op,prp...>(vPos,vPrp,ghostMarker,opt_);
2310  }
2311 
2318  void remove(std::set<size_t> & keys)
2319  {
2320  openfpm::vector<size_t> v_keys; v_keys.reserve(keys.size());
2321 
2322  for (auto it = keys.begin(); it != keys.end(); ++it)
2323  v_keys.add(*it);
2324 
2325  // keys are sorted and unique
2326  this->remove(v_keys, 0);
2327  }
2328 
2337  void remove(openfpm::vector<size_t> & keys, size_t start = 0)
2338  {
2339  vPos.remove(keys, start);
2340  vPrp.remove(keys, start);
2341 
2342  ghostMarker -= keys.size();
2343  }
2344 
2353  void remove(openfpm::vector<aggregate<int>> & keys, size_t start = 0)
2354  {
2355  vPos.remove(keys, start);
2356  vPrp.remove(keys, start);
2357 
2358  ghostMarker -= keys.size();
2359  }
2360 
2366  void remove(size_t key)
2367  {
2368  vPos.remove(key);
2369  vPrp.remove(key);
2370 
2371  ghostMarker--;
2372  }
2373 
2381  template <typename Model=ModelLin>inline void addComputationCosts(const self & vd, Model md=Model())
2382  {
2383  CellDecomposer_sm<dim, St, shift<dim,St>> cdsm;
2384 
2386 
2387  cdsm.setDimensions(dec.getDomain(), dec.getDistGrid().getSize(), 0);
2388 
2389  auto it = vd.getDomainIterator();
2390 
2391  while (it.isNext())
2392  {
2393  Point<dim,St> p = vd.getPos(it.get());
2394  size_t v = cdsm.getCell(p);
2395 
2396  md.addComputation(dec,vd,v,it.get().getKey());
2397 
2398  ++it;
2399  }
2400  }
2401 
2410  template <typename Model=ModelLin> void finalizeComputationCosts(Model md=Model(), size_t ts = 1)
2411  {
2413  auto & dist = getDecomposition().getDistribution();
2414 
2416 
2417  // Go throught all the sub-sub-domains and apply the model
2418 
2419  for (size_t i = 0 ; i < dist.getNOwnerSubSubDomains(); i++)
2420  {md.applyModel(dec,dist.getOwnerSubSubDomain(i));}
2421 
2422  dist.setDistTol(md.distributionTol());
2423  }
2424 
2429  {
2431  auto & dist = getDecomposition().getDistribution();
2432 
2433  for (size_t i = 0; i < dist.getNOwnerSubSubDomains() ; i++)
2434  {dec.setSubSubDomainComputationCost(dist.getOwnerSubSubDomain(i) , 1);}
2435  }
2436 
2445  template <typename Model=ModelLin>inline void addComputationCosts(Model md=Model(), size_t ts = 1)
2446  {
2448 
2449  addComputationCosts(*this,md);
2450 
2451  finalizeComputationCosts(md,ts);
2452  }
2453 
2459  inline void save(const std::string & filename) const
2460  {
2462 
2463  h5s.save(filename,vPos,vPrp);
2464  }
2465 
2471  inline void load(const std::string & filename)
2472  {
2474 
2475  h5l.load(filename,vPos,vPrp,ghostMarker);
2476  }
2477 
2483  void setCapacity(unsigned int ns)
2484  {
2485  vPos.reserve(ns);
2486  vPrp.reserve(ns);
2487  }
2488 
2498  inline bool write(std::string out ,int opt = VTK_WRITER)
2499  {
2500  return write(out,"",opt);
2501  }
2502 
2513  inline bool write(std::string out, std::string meta_info ,int opt = VTK_WRITER)
2514  {
2515  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2516 
2517  if ((opt & 0x0FFF0000) == CSV_WRITER)
2518  {
2519  // CSVWriter test
2520  CSVWriter<vector_dist_pos,
2521  vector_dist_prop > csv_writer;
2522 
2523  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".csv"));
2524 
2525  // Write the CSV
2526  return csv_writer.write(output,vPos,vPrp);
2527  }
2528  else
2529  {
2530  file_type ft = file_type::ASCII;
2531 
2532  if (opt & FORMAT_BINARY)
2533  ft = file_type::BINARY;
2534 
2535  // VTKWriter for a set of points
2536  VTKWriter<boost::mpl::pair<vector_dist_pos,
2537  vector_dist_prop>,
2538  VECTOR_POINTS> vtk_writer;
2539  vtk_writer.add(vPos,vPrp,ghostMarker);
2540 
2541  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".vtp"));
2542  //Create Directory for VTP files and write the PVTP metadata
2543  if(v_cl.rank()==0)
2544  {
2545  create_directory_if_not_exist("VTPDATA",1);
2546  vtk_writer.write_pvtp(out,prp_names,v_cl.size());
2547  }
2548  v_cl.barrier();
2549  // Write the VTK file
2550  bool ret=vtk_writer.write(output,prp_names,"particles",meta_info,ft);
2551  return ret;
2552  }
2553  }
2554 
2560  {
2561  vPos.resize(ghostMarker);
2562  vPrp.resize(ghostMarker);
2563  }
2564 
2572  void resize(size_t rs)
2573  {
2574  deleteGhost();
2575 
2576  vPos.resize(rs);
2577  vPrp.resize(rs);
2578 
2579  ghostMarker = rs;
2580 
2581 #ifdef CUDA_GPU
2582  this->update(this->toKernel());
2583 #endif
2584  }
2585 
2593  void discardLocalAppend(size_t rs)
2594  {
2595  vPos.resize(rs);
2596 #ifdef CUDA_GPU
2597  this->update(this->toKernel());
2598 #endif
2599  }
2600 
2612  inline bool write_frame(std::string out, size_t iteration, int opt = VTK_WRITER)
2613  {
2614  return write_frame(out,iteration,"",opt);
2615  }
2616 
2628  inline bool write_frame(std::string out, size_t iteration, std::string meta_info, int opt = VTK_WRITER)
2629  {
2630  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2631 
2632  if ((opt & 0x0FFF0000) == CSV_WRITER)
2633  {
2634  // CSVWriter test
2635  CSVWriter<vector_dist_pos,
2636  vector_dist_prop > csv_writer;
2637 
2638  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".csv"));
2639 
2640  // Write the CSV
2641  return csv_writer.write(output, vPos, vPrp);
2642  }
2643  else
2644  {
2645  file_type ft = file_type::ASCII;
2646 
2647  if (opt & FORMAT_BINARY)
2648  ft = file_type::BINARY;
2649 
2650  // VTKWriter for a set of points
2651  VTKWriter<boost::mpl::pair<vector_dist_pos,
2652  vector_dist_prop>, VECTOR_POINTS> vtk_writer;
2653  vtk_writer.add(vPos,vPrp,ghostMarker);
2654 
2655  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".vtp"));
2656 
2657  //Create Directory for VTP files and write the PVTP metadata
2658  if(v_cl.rank()==0)
2659  {
2660  create_directory_if_not_exist("VTPDATA",1);
2661  vtk_writer.write_pvtp(out,prp_names,v_cl.size(),iteration);
2662  }
2663  v_cl.barrier();
2664 
2665  // Write the VTK file
2666  bool ret=vtk_writer.write(output,prp_names,"particles",meta_info,ft);
2667 
2668  return ret;
2669  }
2670  }
2671 
2683  inline bool write_frame(std::string out, size_t iteration, double time, int opt = VTK_WRITER)
2684  {
2685  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2686 
2687  if ((opt & 0x0FFF0000) == CSV_WRITER)
2688  {
2689  // CSVWriter test
2691 
2692  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".csv"));
2693 
2694  // Write the CSV
2695  return csv_writer.write(output, vPos, vPrp);
2696  }
2697  else
2698  {
2699  file_type ft = file_type::ASCII;
2700 
2701  if (opt & FORMAT_BINARY)
2702  ft = file_type::BINARY;
2703 
2704  // VTKWriter for a set of points
2706  vtk_writer.add(vPos,vPrp,ghostMarker);
2707 
2708  std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".vtp"));
2709 
2710  //Create Directory for VTP files and write the PVTP metadata
2711  if(v_cl.rank()==0)
2712  {
2713  create_directory_if_not_exist("VTPDATA",1);
2714  vtk_writer.write_pvtp(out,prp_names,v_cl.size(),iteration,time);
2715  }
2716  v_cl.barrier();
2717  // Write the VTK file
2718  bool ret=vtk_writer.write(output,prp_names,"particles","",ft);
2719  return ret;
2720  }
2721  }
2722 
2732  void getCellListParams(St r_cut, size_t (&div)[dim],Box<dim, St> & box, Ghost<dim,St> enlarge = Ghost<dim,St>(0.0))
2733  {
2734  // get the processor bounding box
2735  Box<dim, St> pbox = getDecomposition().getProcessorBounds();
2736 
2737  // enlarge the processor bounding box by the ghost
2738  Ghost<dim,St> g = getDecomposition().getGhost();
2739  pbox.enlarge(g);
2740 
2741  cl_param_calculate(pbox, div,r_cut,enlarge);
2742 
2743  // output the fixed domain
2744  box = pbox;
2745  }
2746 
2754  {
2755 #ifdef SE_CLASS2
2756  check_valid(this,8);
2757 #endif
2758  return create_vcluster<Memory>();;
2759  }
2760 
2766  const vector_dist_pos & getPosVector() const
2767  {
2768  return vPos;
2769  }
2770 
2776  vector_dist_pos & getPosVector()
2777  {
2778  return vPos;
2779  }
2780 
2786  const vector_dist_prop & getPropVector() const
2787  {
2788  return vPrp;
2789  }
2790 
2796  vector_dist_prop & getPropVector()
2797  {
2798  return vPrp;
2799  }
2800 
2806  size_t accum()
2807  {
2808  Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2809 
2811 
2812  size_t sz = size_local();
2813 
2814  v_cl.allGather(sz,accu);
2815  v_cl.execute();
2816 
2817  sz = 0;
2818 
2819  for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
2820  {sz += accu.get(i);}
2821 
2822  return sz;
2823  }
2824 
2833  template<typename cli> ParticleItCRS_Cells<dim,cli,decltype(vPos)> getParticleIteratorCRS_Cell(cli & cellList)
2834  {
2835 #ifdef SE_CLASS3
2836  se3.getIterator();
2837 #endif
2838 
2839 #ifdef SE_CLASS1
2840  if (!(opt & BIND_DEC_TO_GHOST))
2841  {
2842  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;
2843  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2844  }
2845 #endif
2846 
2847  // Shift
2849 
2850  // Add padding
2851  for (size_t i = 0 ; i < dim ; i++)
2852  shift.set_d(i,cellList.getPadding(i));
2853 
2854  grid_sm<dim,void> gs = cellList.getInternalGrid();
2855 
2856  getDecomposition().setNNParameters(shift,gs);
2857 
2858  // First we check that
2860  cellList,getDecomposition().getCRSDomainCells(),
2861  getDecomposition().getCRSAnomDomainCells(),
2862  cellList.getNNc_sym()
2863  );
2864  }
2865 
2874  {
2875  prp_names = names;
2876  }
2877 
2884  {
2885  return prp_names;
2886  }
2887 
2888 
2897  template<typename VerletList_type>
2899  {
2900 #ifdef SE_CLASS1
2901  if (!(opt & BIND_DEC_TO_GHOST))
2902  {
2903  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;
2904  ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2905  }
2906 #endif
2907 
2908  // First we check that
2910  }
2911 
2920  template<typename Celllist> grid_key_dx<dim> getCRSStart(Celllist & cellList)
2921  {
2922  return cellList.getStartDomainCell();
2923  }
2924 
2933  template<typename Celllist> grid_key_dx<dim> getCRSStop(Celllist & cellList)
2934  {
2935  grid_key_dx<dim> key = cellList.getStopDomainCell();
2936 
2937  for (size_t i = 0 ; i < dim ; i++)
2938  key.set_d(i,key.get(i) + 1);
2939  return key;
2940  }
2941 
2947  bool isSubset() const
2948  {
2949  return false;
2950  }
2951 
2952 #ifdef CUDA_GPU
2953 
2961  template<unsigned int ... prp> vector_dist_ker<dim,St,prop,layout_base> toKernel()
2962  {
2963  vector_dist_ker<dim,St,prop,layout_base> v(ghostMarker,vPos.toKernel(), vPrp.toKernel());
2964 
2965  return v;
2966  }
2967 
2974  vector_dist_ker_list<vector_dist_ker<dim,St,prop,layout_base>> & private_get_vector_dist_ker_list()
2975  {
2976  return *this;
2977  }
2978 
2984  template<unsigned int ... prp> void deviceToHostProp()
2985  {
2986  vPrp.template deviceToHost<prp ...>();
2987  }
2988 
2997  template<unsigned int ... prp> void deviceToHostProp(size_t start, size_t stop)
2998  {
2999  vPrp.template deviceToHost<prp ...>(start,stop);
3000  }
3001 
3007  void deviceToHostPos()
3008  {
3009  vPos.template deviceToHost<0>();
3010  }
3011 
3017  template<unsigned int ... prp> void hostToDeviceProp()
3018  {
3019  vPrp.template hostToDevice<prp ...>();
3020  }
3021 
3027  void hostToDevicePos()
3028  {
3029  vPos.template hostToDevice<0>();
3030  }
3031 
3032  void setGhostMarker(size_t ghostMarker)
3033  {
3034  this->ghostMarker = ghostMarker;
3035  }
3036 
3042  template<unsigned int ...prp, typename CellList_type>
3043  void restoreOrder(CellList_type & cellList)
3044  {
3045  if (cellList.getOpt() & CL_GPU_REORDER_POSITION) vPos.swap(vPosReordered);
3046  if (cellList.getOpt() & CL_GPU_REORDER_PROPERTY) vPrp.swap(vPrpReordered);
3047 
3048  cellList.template restoreOrder<vector_dist_pos, vector_dist_prop, prp...>(vPosReordered, vPrpReordered, vPos, vPrp);
3049  }
3050 
3058  bool compareHostAndDevicePos(St tol, St near = -1.0, bool silent = false)
3059  {
3060  return compare_host_device<Point<dim,St>,0>::compare(vPos,tol,near,silent);
3061  }
3062 
3063 
3071  template<unsigned int prp>
3072  bool compareHostAndDeviceProp(St tol, St near = -1.0, bool silent = false)
3073  {
3074  return compare_host_device<typename boost::mpl::at<typename prop::type,
3075  boost::mpl::int_<prp> >::type,prp>::compare(vPrp,tol,near,silent);
3076  }
3077 
3078 #else
3079 
3085  template<unsigned int ... prp> void deviceToHostProp()
3086  {}
3087 
3094  {}
3095 
3101  template<unsigned int ... prp> void hostToDeviceProp()
3102  {}
3103 
3110  {}
3111 
3112 #endif
3113 
3114 
3115 #ifdef SE_CLASS3
3116 
3118  {
3119  return se3;
3120  }
3121 
3122 #endif
3123 };
3124 
3125 
3126 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>;
3127 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>;
3128 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>;
3129 
3130 #endif /* VECTOR_HPP_ */
Header file containing functions for creating files and folders.
static void create_directory_if_not_exist(std::string path, bool silent=0)
Creates a directory if not already existent.
std::string toString() const
Produce a string from the object.
Definition: Box.hpp:1412
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition: Box.hpp:822
bool isValid() const
Check if the Box is a valid box P2 >= P1.
Definition: Box.hpp:1186
void magnify(T mg)
Magnify the box.
Definition: Box.hpp:888
CSV Writer.
Definition: CSVWriter.hpp:164
bool write(std::string file, v_pos &v, v_prp &prp, size_t offset=0)
It write a CSV file.
Definition: CSVWriter.hpp:248
const grid_sm< dim, void > getDistGrid()
Distribution grid.
const Box< dim, T > & getDomain() const
Return the box of the physical domain.
void computeCommunicationAndMigrationCosts(size_t ts)
Calculate communication and migration costs.
void setSubSubDomainComputationCost(size_t id, size_t weight)
Function that set the computational cost for a of a sub-sub domain.
Class for FAST cell list implementation.
Definition: CellList.hpp:558
void setGhostMarker(size_t ghostMarker)
Set the ghost marker.
Definition: CellList.hpp:1488
void set_ndec(size_t n_dec)
Set the n_dec number.
Definition: CellList.hpp:1615
void fill(vector_pos_type2 &vPos, vector_prp_type &vPrp, size_t ghostMarker)
Fill cell list with particles at positions vPos.
Definition: CellList.hpp:1639
size_t getPadding(size_t i) const
Return the number of padding cells of the Cell decomposer.
Definition: CellList.hpp:1391
void setOpt(size_t opt)
Sets the option flags that control the cell list.
Definition: CellList.hpp:1378
void Initialize(CellDecomposer_sm< dim, T, transform > &cd_sm, const Box< dim, T > &dom_box, const size_t pad=1, size_t slot=STARTING_NSLOT)
Definition: CellList.hpp:731
This class define the domain decomposition interface.
This class allocate, and destroy CPU memory.
Definition: HeapMemory.hpp:40
This iterator iterate across the particles of a Cell-list following the Cell structure.
This iterator iterate across the particles of a Cell-list following the Cell structure.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
void execute()
Execute all the requests.
size_t rank()
Get the process unit id.
size_t size()
Get the total number of processors.
size_t getProcessUnitID()
Get the process unit id.
gpu::ofp_context_t & getGpuContext(bool iw=true)
If nvidia cuda is activated return a gpu context.
size_t getProcessingUnits()
Get the total number of processors.
bool allGather(T &send, openfpm::vector< T, Mem, gr > &v)
Gather the data from all processors.
Implementation of VCluster class.
Definition: VCluster.hpp:59
void barrier()
Just a call to mpi_barrier.
Definition: VCluster.hpp:595
Class for Verlet list implementation.
Definition: VerletList.hpp:269
void swap(VerletList< dim, T, opt, Mem_type, transform, vPos_type, CellListImpl > &vl)
Swap the memory.
Given the decomposition it create an iterator.
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:760
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:204
size_t size()
Stub size.
Definition: map_vector.hpp:212
This class check for inconsistency access.
void map_post()
Operation to do after map.
void Initialize()
Initialize the se_class2 structure.
Grid key for a distributed grid.
This class is an helper for the communication of vector_dist.
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.
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 ghost_wait_(openfpm::vector< Point< dim, St >, HeapMemory, memory_traits_lin > &v_pos, openfpm::vector< prop, HeapMemory, memory_traits_lin > &v_prp, size_t &ghostMarker, size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
void ghost_get_(openfpm::vector< Point< dim, St >, HeapMemory, memory_traits_lin > &v_pos, openfpm::vector< prop, HeapMemory, memory_traits_lin > &v_prp, size_t &ghostMarker, size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
Decomposition & getDecomposition()
Get the decomposition.
void map_list_(openfpm::vector< Point< dim, St >> &v_pos, openfpm::vector< prop > &v_prp, size_t &ghostMarker, size_t opt)
It move all the particles that does not belong to the local processor to the respective processor.
void ghost_put_(openfpm::vector< Point< dim, St >, HeapMemory, memory_traits_lin > &v_pos, openfpm::vector< prop, HeapMemory, memory_traits_lin > &v_prp, size_t &ghostMarker, size_t opt)
Ghost put.
void setDecompositionGranularity(size_t n_sub)
Set the minimum number of sub-domain per processor.
Iterator that Iterate across particle indexes.
This class contain a list of all tracked vector_dist_ker around.
void update(const int &v)
Update the addresses of all vector_dist_kernels around.
Distributed vector.
void remove(size_t key)
Remove one element from the distributed vector.
Vcluster< Memory > & getVC()
Get the Virtual Cluster machine.
auto getPropNC(size_t vec_key) const -> decltype(vPrp.template get< id >(vec_key))
Get the property of an element.
size_t size_local() const
return the local size of the vector
VerletList_type getVerletSym(St r_cut)
for each particle get the symmetric verlet list
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 remove(openfpm::vector< size_t > &keys, size_t start=0)
Remove a set of elements from the distributed vector.
auto getPos(size_t vec_key) const -> decltype(vPos.template get< 0 >(vec_key))
Get the position of an element.
vector_dist_prop & getPropVector()
return the property vector of all the particles
bool write_frame(std::string out, size_t iteration, int opt=VTK_WRITER)
Output particle position and properties.
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.
void resize(size_t rs)
Resize the vector (locally)
auto getProp(vect_dist_key_dx vec_key) -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
auto getPos(vect_dist_key_dx vec_key) const -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
static const unsigned int dims
template parameters typedefs
void updateCellList(CellL &cellList, bool no_se3=false)
Update a cell list using the stored particles.
void Ighost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
size_t init_size_accum(size_t np)
It return the number of particles contained by the previous processors.
void check_parameters(Box< dim, St > &box)
Check if the parameters describe a valid vector. In case it does not report an error.
void appendLocal()
Add at the END of local and ghost particle.
vector_dist_prop vPrp
bool isSubset() const
Indicate that this class is not a subset.
size_t size_local_with_ghost() const
return the local size of the vector
void deviceToHostPos()
Move the memory from the device to host memory.
vector_dist_pos & getPosVector()
return the position vector of all the particles
void init_structures(size_t np)
Initialize the structures.
void check_ghost_compatible_rcut(St r_cut)
It check that the r_cut is not bugger than the ghost.
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) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
grid_key_dx< dim > getCRSStart(Celllist &cellList)
Return from which cell we have to start in case of CRS interation scheme.
auto getPropNC(vect_dist_key_dx vec_key) -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
const vector_dist_prop & getPropVector() const
return the property vector of all the particles
int yes_i_am_vector_dist
yes I am vector dist
void setCapacity(unsigned int ns)
Reserve space for the internal vectors.
CellList_type getCellListSym(St r_cut, size_t opt=CL_LINEAR_CELL_KEYS)
Construct a cell list symmetric based on a cut-off radius.
vector_dist_iterator getDomainAndGhostIterator_no_se3() const
Get an iterator that traverse the particles in the domain.
void updateVerletAdaptRCut(VerletList< dim, St, opt, Mem_type, shift< dim, St > > &verletList)
Update non-symmetric adaptive r-cut Verlet list.
Decomposition & getDecomposition()
Get the decomposition.
void setPropNames(const openfpm::vector< std::string > &names)
Set the properties names.
auto getLastPosWrite() -> decltype(vPos.template get< 0 >(0))
Get the position of the last element.
vector_dist_iterator getGhostIterator() const
Get the iterator across the position of the ghost particles.
VerletList_type getVerlet(St r_cut, size_t neighborMaxNum=0)
for each particle get the verlet list
auto getProp(vect_dist_key_dx vec_key) const -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const size_t(&sz)[dim])
vector_dist_pos vPosReordered
const Decomposition & getDecomposition() const
Get the decomposition.
openfpm::vector_key_iterator_seq< typename VerletList_type::Mem_type_type::local_index_type > getParticleIteratorCRS(VerletList_type &cellList)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme.
bool write_frame(std::string out, size_t iteration, double time, int opt=VTK_WRITER)
Output particle position and properties and add a time stamp to pvtp.
auto getPos(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void map_list(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
CellL getCellListSym(const size_t(&div)[dim], const size_t(&pad)[dim], size_t opt=CL_LINEAR_CELL_KEYS)
Construct a symmetric cell list based on a number of divisions and padding.
size_t opt
option used to create this vector
std::integral_constant< bool, false > is_it_a_subset
yes I am vector subset dist
auto getPropNC(vect_dist_key_dx vec_key) const -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
size_t ghostMarker
Ghost marker, all the particle with id > ghostMarker are ghost all with ghostMarker < are real partic...
auto getLastPropWrite() -> decltype(vPrp.template get< id >(0))
Get the property of the last element.
void remove(std::set< size_t > &keys)
Remove a set of elements from the distributed vector.
const vector_dist_pos & getPosVector() const
return the position vector of all the particles
vector_dist_pos vPos
void updateVerlet(VerletList< dim, St, opt, Mem_type, shift< dim, St > > &verletList, St r_cut)
for each particle get the verlet list
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...
openfpm::vector< std::string > prp_names
Name of the properties.
void ghost_wait(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
vector_dist_iterator getDomainIterator() const
Get an iterator that traverse the particles in the domain.
vector_dist(const Decomposition &dec, size_t np)
Constructor with predefined decomposition.
bool write(std::string out, std::string meta_info, int opt=VTK_WRITER)
Output particle position and properties.
void ghost_get(size_t opt=WITH_POSITION)
It synchronize the properties and position of the ghost particles.
auto getProp(size_t vec_key) const -> decltype(vPrp.template get< id >(vec_key))
Get the property of an element.
VerletList_type getVerletAdaptRCut()
Get Verlet list with unique cut-off radius for every particle.
void setReferenceCounterToOne()
vector_dist_iterator getIterator(size_t start, size_t stop)
Get an iterator that traverse domain and ghost particles.
void finalizeComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition coming from the particles.
void hostToDevicePos()
Move the memory from the device to host memory.
grid_key_dx< dim > getCRSStop(Celllist &cellList)
Return from which cell we have to stop in case of CRS interation scheme.
auto getPos(size_t vec_key) -> decltype(vPos.template get< 0 >(vec_key))
Get the position of an element.
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
void ghost_put(size_t opt_=NONE)
It synchronize the properties and position of the ghost particles.
auto getLastPropRead() -> decltype(vPrp.template get< id >(0))
Get the property of the last element.
vector_dist_iterator getIterator()
Get an iterator that traverse domain and ghost particles.
size_t accum()
It return the sum of the particles in the previous processors.
void reorder_sfc(openfpm::vector< Point< dim, St >> &v_pos_dest, openfpm::vector< prop > &v_prp_dest, sfc_it &h_it, CellL &cellList)
Reorder based on hilbert space filling curve.
CellL getCellList_hilb(St r_cut, size_t opt=CL_NON_SYMMETRIC)
Construct an hilbert cell list starting from the stored particles.
vector_dist< dim, St, prop, Decomposition, Memory, layout_base > & operator=(vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &&v)
Operator= for distributed vector.
void initializeComputationCosts()
Initialize the computational cost.
auto getPropRead(vect_dist_key_dx vec_key) const -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
bool write_frame(std::string out, size_t iteration, std::string meta_info, int opt=VTK_WRITER)
Output particle position and properties.
void clear()
remove all the elements
openfpm::vector< std::string > & getPropNames()
Get the properties names.
ParticleIt_Cells< dim, CellList > getDomainIteratorCells(CellList &cellList)
Get an iterator that traverse the particles in the domain using a cell list.
bool write(std::string out, int opt=VTK_WRITER)
Output particle position and properties.
void reorder_rcut(St r_cut)
Construct a cell list starting from the stored particles and reorder a vector according to the Hilber...
auto getLastPosRead() -> decltype(vPos.template get< 0 >(0))
Get the position of the last 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.
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...
auto getLastProp() -> decltype(vPrp.template get< id >(0))
Get the property of the last element.
void deviceToHostProp()
Move the memory from the device to host memory.
vector_dist_iterator getDomainAndGhostIterator() const
Get an iterator that traverse the particles in the domain.
void save(const std::string &filename) const
Save the distributed vector on HDF5 file.
vector_dist_iterator getGhostIterator_no_se3() const
Get the iterator across the position of the ghost particles.
auto getPosNC(size_t vec_key) -> decltype(vPos.template get< 0 >(vec_key))
Get the position of an element.
auto getLastPosEnd() -> decltype(vPos.template get< 0 >(0))
Get the position of the last element after ghost.
vector_dist_prop vPrpReordered
void remove(openfpm::vector< aggregate< int >> &keys, size_t start=0)
Remove a set of elements from the distributed vector.
vector_dist(const vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &v)
Copy Constructor.
void add()
Add local particle.
CellList_type getCellList(St r_cut, size_t opt=CL_NON_SYMMETRIC|CL_LINEAR_CELL_KEYS, bool no_se3=false, float ghostEnlargeFactor=1.013)
Construct a cell list starting from the stored particles.
VerletList_type getVerletCrs(St r_cut)
for each particle get the symmetric verlet list
ParticleItCRS_Cells< dim, cli, decltype(vPos)> getParticleIteratorCRS_Cell(cli &cellList)
Get a special particle iterator able to iterate across particles using symmetric crossing scheme.
void hostToDeviceProp()
Move the memory from the device to host memory.
CellList_type getCellListSymLocal(St r_cut, size_t opt=CL_LINEAR_CELL_KEYS)
Construct a local symmetric cell list based on a cut-off radius.
void addComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition coming from the particles.
void load(const std::string &filename)
Load the distributed vector from an HDF5 file.
auto getPropNC(size_t vec_key) -> decltype(vPrp.template get< id >(vec_key))
Get the property of an element.
auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
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 addComputationCosts(const self &vd, Model md=Model())
Add the computation cost on the decomposition coming from the particles.
auto getProp(size_t vec_key) -> decltype(vPrp.template get< id >(vec_key))
Get the property of an element.
vector_dist(vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &&v) noexcept
Copy constructor.
auto getPropWrite(vect_dist_key_dx vec_key) -> decltype(vPrp.template get< id >(vec_key.getKey()))
Get the property of an element.
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.
void ghost_get_subset()
Stub does not do anything.
void deleteGhost()
Delete the particles on the ghost.
auto getPosNC(vect_dist_key_dx vec_key) const -> decltype(vPos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void discardLocalAppend(size_t rs)
Resize the vector at the end of the ghost (locally)
auto getPosNC(size_t vec_key) const -> decltype(vPos.template get< 0 >(vec_key))
Get the position of an element.
auto getLastPos() -> decltype(vPos.template get< 0 >(0))
Get the position of the last element.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition: aggregate.hpp:221
boost::fusion::vector< list... > type
internal type containing the data
Definition: aggregate.hpp:223
decrement_memory(vector_type &v)
constructor
Definition: vector_dist.hpp:94
void operator()(T &t) const
It call the copy function for each property.
vector_type & v
vector
Definition: vector_dist.hpp:84
Transform the boost::fusion::vector into memory specification (memory_traits)