OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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"
44
45#include <type_traits>
46
47#define DEC_GRAN(gr) ((size_t)gr << 32)
48
49#ifdef CUDA_GPU
50template<unsigned int dim,typename St> using CELLLIST_GPU_SPARSE = CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>,unsigned int,int,true>;
51#endif
52
53#define VECTOR_DIST_ERROR_OBJECT std::runtime_error("Runtime vector distributed error");
54
55#ifdef SE_CLASS3
56#include "se_class3_vector.hpp"
57#endif
58
59#ifdef SE_CLASS3
60 #define SE_CLASS3_VDIST_CONSTRUCTOR ,se3(getDecomposition(),*this)
61#else
62 #define SE_CLASS3_VDIST_CONSTRUCTOR
63#endif
64
65
66#define NO_ID false
67#define ID true
68
69// Perform a ghost get or a ghost put
70constexpr int GET = 1;
71constexpr int PUT = 2;
72
73// Write the particles with ghost
74constexpr int NO_GHOST = 0;
75constexpr int WITH_GHOST = 2;
76
77constexpr int GCL_NON_SYMMETRIC = 0;
78constexpr int GCL_SYMMETRIC = 1;
79constexpr int GCL_HILBERT = 2;
80
81template<bool is_gpu_celllist, unsigned int ... prp>
83{
84 template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl>
85 static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
86 {
87 return vd.template getCellList<CellL>(r_cut);
88 }
89};
90
91template<unsigned int ... prp>
93{
94 template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl>
95 static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
96 {
97 return vd.template getCellListGPU<CellL,prp...>(r_cut);
98 }
99};
100
102template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl, unsigned int ... prp>
103struct gcl
104{
114 static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
115 {
116 return gcl_standard_no_symmetric_impl<is_gpu_celllist<CellL>::value,prp ...>::template get<dim,St,CellL,Vector,impl>(vd,r_cut,g);
117 }
118};
119
121template<unsigned int dim, typename St, typename CellL, typename Vector>
122struct gcl<dim,St,CellL,Vector,GCL_HILBERT>
123{
133 static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
134 {
135 return vd.getCellList_hilb(r_cut,g);
136 }
137};
138
140template<unsigned int dim, typename St, typename CellL, typename Vector>
141struct gcl<dim,St,CellL,Vector,GCL_SYMMETRIC>
142{
152 static inline CellL get(Vector & vd, const St & r_cut, const Ghost<dim,St> & g)
153 {
154 return vd.getCellListSym(r_cut);
155 }
156};
157
159
161template<unsigned int dim, typename St, typename CellL, typename Vector, unsigned int impl>
162struct gcl_An
163{
173 static inline CellL get(Vector & vd, const size_t (& div)[dim], const size_t (& pad)[dim], const Ghost<dim,St> & g)
174 {
175 return vd.template getCellListSym<CellL>(div,pad);
176 }
177};
178
179#define CELL_MEMFAST(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St> >
180#define CELL_MEMBAL(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_bal<>, shift<dim, St> >
181#define CELL_MEMMW(dim,St) CellList_gen<dim, St, Process_keys_lin, Mem_mw<>, shift<dim, St> >
182
183#define CELL_MEMFAST_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_fast<>, shift<dim, St> >
184#define CELL_MEMBAL_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_bal<>, shift<dim, St> >
185#define CELL_MEMMW_HILB(dim,St) CellList_gen<dim, St, Process_keys_hilb, Mem_mw<>, shift<dim, St> >
186
187#define VERLET_MEMFAST(dim,St) VerletList<dim,St,Mem_fast<>,shift<dim,St> >
188#define VERLET_MEMBAL(dim,St) VerletList<dim,St,Mem_bal<>,shift<dim,St> >
189#define VERLET_MEMMW(dim,St) VerletList<dim,St,Mem_mw<>,shift<dim,St> >
190
191#define VERLET_MEMFAST_INT(dim,St) VerletList<dim,St,Mem_fast<HeapMemory,unsigned int>,shift<dim,St> >
192#define VERLET_MEMBAL_INT(dim,St) VerletList<dim,St,Mem_bal<unsigned int>,shift<dim,St> >
193#define VERLET_MEMMW_INT(dim,St) VerletList<dim,St,Mem_mw<unsigned int>,shift<dim,St> >
194
195enum reorder_opt
196{
197 NO_REORDER = 0,
198 HILBERT = 1,
199 LINEAR = 2
200};
201
202template<typename vector, unsigned int impl>
204{
205 typedef decltype(std::declval<vector>().getCellListGPU(0.0)) ctype;
206
207 static ctype get(vector & v,
208 typename vector::stype & r_cut)
209 {
210 return v.getCellListGPU(r_cut);
211 }
212};
213
214template<typename vector>
215struct cell_list_selector<vector,comp_host>
216{
217 typedef decltype(std::declval<vector>().getCellList(0.0)) ctype;
218
219 static ctype get(vector & v,
220 typename vector::stype & r_cut)
221 {
222 return v.getCellList(r_cut);
223 }
224};
225
226template<typename vector_type>
228{
231
232
241 :v(v)
242 {};
243
244
250 template<typename T>
251 inline void operator()(T& t) const
252 {
253 v.template getMemory<T::value>().decRef();
254 }
255};
256
291template<unsigned int dim,
292 typename St,
293 typename prop,
295 typename Memory = HeapMemory,
296 template<typename> class layout_base = memory_traits_lin,
297 typename vector_dist_pos = openfpm::vector<Point<dim, St>,Memory,layout_base>,
298 typename vector_dist_prop = openfpm::vector<prop,Memory,layout_base> >
299class vector_dist : public vector_dist_comm<dim,St,prop,Decomposition,Memory,layout_base>,
300#ifdef CUDA_GPU
301 private vector_dist_ker_list<vector_dist_ker<dim,St,prop,layout_base>>
302#else
303 private vector_dist_ker_list<int>
304#endif
305{
306
307public:
308
311
313 static const unsigned int dims = dim;
314 typedef St stype;
315 typedef prop value_type;
317 typedef Memory Memory_type;
318
319private:
320
322 size_t g_m = 0;
323
326 vector_dist_pos v_pos;
327
330 vector_dist_prop v_prp;
331
333 vector_dist_prop v_prp_out;
334
336 vector_dist_pos v_pos_out;
337
339 size_t opt = 0;
340
343
344#ifdef SE_CLASS3
345
347
348#endif
349
350#ifdef SE_CLASS1
351 int map_ctr=0;
352 //ghost check to be done.
353 int ghostget_ctr=0;
354#endif
355
361 void init_structures(size_t np)
362 {
363 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
364
365 // convert to a local number of elements
366 size_t p_np = np / v_cl.getProcessingUnits();
367
368 // Get non divisible part
369 size_t r = np % v_cl.getProcessingUnits();
370
371 // Distribute the remain particles
372 if (v_cl.getProcessUnitID() < r)
373 p_np++;
374
375 // resize the position vector
376 v_pos.resize(p_np);
377
378 // resize the properties vector
379 v_prp.resize(p_np);
380
381 g_m = p_np;
382 }
383
390 {
391 // if the box is not valid return an error
392 if (box.isValid() == false)
393 {
394 std::cerr << __FILE__ << ":" << __LINE__ << " Error the domain is not valid " << box.toString() << std::endl;
395 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
396 }
397
398 }
399
406 {
407 for (size_t i = 0 ; i < dim ; i++)
408 {
409 if (fabs(getDecomposition().getGhost().getLow(i)) < r_cut)
410 {
411 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;
412 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
413 }
414 }
415 }
416
425 template<typename CellL, typename sfc_it>
427 openfpm::vector<prop> & v_prp_dest,
428 sfc_it & h_it,
429 CellL & cell_list)
430 {
431 v_pos_dest.resize(v_pos.size());
432 v_prp_dest.resize(v_prp.size());
433
434 //Index for v_pos_dest
435 size_t count = 0;
436
437 grid_key_dx<dim> ksum;
438
439 for (size_t i = 0; i < dim ; i++)
440 {ksum.set_d(i,cell_list.getPadding(i));}
441
442 while (h_it.isNext())
443 {
444 auto key = h_it.get();
445 key += ksum;
446
447 size_t lin = cell_list.getGrid().LinId(key);
448
449 // for each particle in the Cell "lin"
450 for (size_t i = 0; i < cell_list.getNelements(lin); i++)
451 {
452 //reorder
453 auto v = cell_list.get(lin,i);
454 v_pos_dest.get(count) = v_pos.get(v);
455 v_prp_dest.get(count) = v_prp.get(v);
456
457 count++;
458 }
459 ++h_it;
460 }
461 }
462
463public:
464 typedef decltype(v_pos) internal_position_vector_type;
465
466 typedef CellList<dim, St, Mem_fast<>, shift<dim, St>, internal_position_vector_type > CellList_type;
467
470
472 typedef std::integral_constant<bool,false> is_it_a_subset;
473
474
484 {
486
487 g_m = v.g_m;
488 v_pos = v.v_pos;
489 v_prp = v.v_prp;
490
491#ifdef SE_CLASS3
492 se3 = v.se3;
493#endif
494
495 opt = v.opt;
496
497 return *this;
498 }
499
509 {
511
512 g_m = v.g_m;
513 v_pos.swap(v.v_pos);
514 v_prp.swap(v.v_prp);
515
516#ifdef SE_CLASS3
517 se3 = v.se3;
518#endif
519
520 opt = v.opt;
521
522 return *this;
523 }
524
525 // default constructor (structure contain garbage)
527 {}
528
529
536 :vector_dist_comm<dim,St,prop,Decomposition,Memory,layout_base>(v.getDecomposition()) SE_CLASS3_VDIST_CONSTRUCTOR
537 {
538#ifdef SE_CLASS2
539 check_new(this,8,VECTOR_DIST_EVENT,4);
540#endif
541
542 this->operator=(v);
543 }
544
551 {
552#ifdef SE_CLASS2
553 check_new(this,8,VECTOR_DIST_EVENT,4);
554#endif
555
556 this->operator=(v);
557
558#ifdef SE_CLASS3
559 se3.Initialize();
560#endif
561 }
562
569 vector_dist(const Decomposition & dec, size_t np) :
570 vector_dist_comm<dim,St,prop,Decomposition,Memory,layout_base>(dec) SE_CLASS3_VDIST_CONSTRUCTOR
571 {
572#ifdef SE_CLASS2
573 check_new(this,8,VECTOR_DIST_EVENT,4);
574#endif
575
576 init_structures(np);
577
578#ifdef SE_CLASS3
579 se3.Initialize();
580#endif
581 }
582
595 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)
596 :opt(0) SE_CLASS3_VDIST_CONSTRUCTOR
597 {
598 if (opt >> 32 != 0)
599 {this->setDecompositionGranularity(opt >> 32);}
600
601 check_parameters(box);
602
603 init_structures(np);
604
605 this->init_decomposition_gr_cell(box,bc,g,opt,gdist);
606
607
608#ifdef SE_CLASS3
609 se3.Initialize();
610#endif
611 }
612
625 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>())
626 :opt(opt) SE_CLASS3_VDIST_CONSTRUCTOR
627 {
628#ifdef SE_CLASS2
629 check_new(this,8,VECTOR_DIST_EVENT,4);
630#endif
631
632 if (opt >> 32 != 0)
633 {this->setDecompositionGranularity(opt >> 32);}
634
635 check_parameters(box);
636
637 init_structures(np);
638
639 this->init_decomposition(box,bc,g,opt,gdist);
640
641
642#ifdef SE_CLASS3
643 se3.Initialize();
644#endif
645 }
646
648 {
649#ifdef SE_CLASS2
650 check_delete(this);
651#endif
652 }
653
658 {
659 for (int i = 0 ; i < v_pos.template getMemory<0>().ref() - 1; i++)
660 {
661 v_pos.template getMemory<0>().decRef();
662 }
663
664 for (int i = 0 ; i < v_prp.template getMemory<0>().ref() - 1; i++)
665 {
666 decrement_memory<decltype(v_prp)> m(v_prp);
667
668 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,decltype(v_prp)::value_type::max_prop>>(m);
669 }
670 }
671
676 void clear()
677 {
678 resize(0);
679 }
680
686 size_t size_local() const
687 {
688 return g_m;
689 }
690
696 size_t size_local_orig() const
697 {
698 return g_m;
699 }
700
707 {
708 return v_pos.size();
709 }
710
711#ifndef ONLY_READWRITE_GETTER
712
722 inline auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
723 {
724#ifdef SE_CLASS3
725 check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
726#endif
727
728 return v_pos.template get<0>(vec_key.getKey());
729 }
730
740 inline auto getPos(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
741 {
742#ifdef SE_CLASS3
743 check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
744#endif
745 return v_pos.template get<0>(vec_key.getKey());
746 }
747
757 inline auto getPos(size_t vec_key) -> decltype(v_pos.template get<0>(vec_key))
758 {
759#ifdef SE_CLASS3
760 check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
761#endif
762 return v_pos.template get<0>(vec_key);
763 }
764
774 inline auto getPosOrig(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
775 {
776#ifdef SE_CLASS3
777 check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key.getKey());
778#endif
779 return v_pos.template get<0>(vec_key.getKey());
780 }
781
791 inline auto getPosOrig(size_t vec_key) -> decltype(v_pos.template get<0>(vec_key))
792 {
793#ifdef SE_CLASS3
794 check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
795#endif
796 return v_pos.template get<0>(vec_key);
797 }
798
808 inline auto getPos(size_t vec_key) const -> decltype(v_pos.template get<0>(vec_key))
809 {
810#ifdef SE_CLASS3
811 check_for_pos_nan_inf<prop::max_prop_real,prop::max_prop>(*this,vec_key);
812#endif
813 return v_pos.template get<0>(vec_key);
814 }
815
826 template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
827 {
828#ifdef SE_CLASS3
829 check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key.getKey());
830#endif
831 return v_prp.template get<id>(vec_key.getKey());
832 }
833
844 template<unsigned int id> inline auto getProp(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
845 {
846#ifdef SE_CLASS3
847 check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key.getKey());
848#endif
849 return v_prp.template get<id>(vec_key.getKey());
850 }
851
862 template<unsigned int id> inline auto getProp(size_t vec_key) -> decltype(v_prp.template get<id>(vec_key))
863 {
864#ifdef SE_CLASS3
865 check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key);
866#endif
867 return v_prp.template get<id>(vec_key);
868 }
869
880 template<unsigned int id> inline auto getProp(size_t vec_key) const -> decltype(v_prp.template get<id>(vec_key))
881 {
882#ifdef SE_CLASS3
883 check_for_prop_nan_inf<id,prop::max_prop+SE3_STATUS>(*this,vec_key);
884#endif
885 return v_prp.template get<id>(vec_key);
886 }
887
888#endif
889
891
901 inline auto getPosNC(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
902 {
903 return v_pos.template get<0>(vec_key.getKey());
904 }
905
915 inline auto getPosNC(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
916 {
917 return v_pos.template get<0>(vec_key.getKey());
918 }
919
929 inline auto getPosNC(size_t vec_key) -> decltype(v_pos.template get<0>(vec_key))
930 {
931 return v_pos.template get<0>(vec_key);
932 }
933
943 inline auto getPosNC(size_t vec_key) const -> decltype(v_pos.template get<0>(vec_key))
944 {
945 return v_pos.template get<0>(vec_key);
946 }
947
958 template<unsigned int id> inline auto getPropNC(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
959 {
960 return v_prp.template get<id>(vec_key.getKey());
961 }
962
973 template<unsigned int id> inline auto getPropNC(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
974 {
975 return v_prp.template get<id>(vec_key.getKey());
976 }
977
988 template<unsigned int id> inline auto getPropNC(size_t vec_key) -> decltype(v_prp.template get<id>(vec_key))
989 {
990 return v_prp.template get<id>(vec_key);
991 }
992
1003 template<unsigned int id> inline auto getPropNC(size_t vec_key) const -> decltype(v_prp.template get<id>(vec_key))
1004 {
1005 return v_prp.template get<id>(vec_key);
1006 }
1007
1009
1019 inline auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(v_pos.template get<0>(vec_key.getKey()))
1020 {
1021#ifdef SE_CLASS3
1022 se3.template write<prop::max_prop_real>(*this,vec_key.getKey());
1023#endif
1024
1025 return v_pos.template get<0>(vec_key.getKey());
1026 }
1027
1037 inline auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get<0>(vec_key.getKey()))
1038 {
1039#ifdef SE_CLASS3
1040 se3.template read<prop::max_prop_real>(*this,vec_key.getKey());
1041#endif
1042
1043 return v_pos.template get<0>(vec_key.getKey());
1044 }
1045
1056 template<unsigned int id> inline auto getPropWrite(vect_dist_key_dx vec_key) -> decltype(v_prp.template get<id>(vec_key.getKey()))
1057 {
1058#ifdef SE_CLASS3
1059 se3.template write<id>(*this,vec_key.getKey());
1060#endif
1061
1062 return v_prp.template get<id>(vec_key.getKey());
1063 }
1064
1075 template<unsigned int id> inline auto getPropRead(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get<id>(vec_key.getKey()))
1076 {
1077#ifdef SE_CLASS3
1078 se3.template read<id>(*this,vec_key.getKey());
1079#endif
1080
1081 return v_prp.template get<id>(vec_key.getKey());
1082 }
1083
1085
1094 void add()
1095 {
1096 v_prp.insert(g_m);
1097 v_pos.insert(g_m);
1098
1099 g_m++;
1100
1101#ifdef SE_CLASS3
1102 for (size_t i = 0 ; i < prop::max_prop_real+1 ; i++)
1103 v_prp.template get<prop::max_prop_real>(g_m-1)[i] = UNINITIALIZED;
1104#endif
1105 }
1106
1108
1118 {
1119 v_prp.add();
1120 v_pos.add();
1121 }
1122
1123#ifndef ONLY_READWRITE_GETTER
1124
1130 inline auto getLastPos() -> decltype(v_pos.template get<0>(0))
1131 {
1132 return v_pos.template get<0>(g_m - 1);
1133 }
1134
1135
1141 inline auto getLastPosEnd() -> decltype(v_pos.template get<0>(0))
1142 {
1143 return v_pos.template get<0>(v_pos.size() - 1);
1144 }
1145
1153 template<unsigned int id> inline auto getLastProp() -> decltype(v_prp.template get<id>(0))
1154 {
1155 return v_prp.template get<id>(g_m - 1);
1156 }
1157
1158#endif
1159
1161
1167 inline auto getLastPosRead() -> decltype(v_pos.template get<0>(0))
1168 {
1169#ifdef SE_CLASS3
1170 se3.template read<prop::max_prop_real>(*this,g_m-1);
1171#endif
1172
1173 return v_pos.template get<0>(g_m - 1);
1174 }
1175
1183 template<unsigned int id> inline auto getLastPropRead() -> decltype(v_prp.template get<id>(0))
1184 {
1185#ifdef SE_CLASS3
1186 se3.read<id>(*this,g_m-1);
1187#endif
1188
1189 return v_prp.template get<id>(g_m - 1);
1190 }
1191
1192
1198 inline auto getLastPosWrite() -> decltype(v_pos.template get<0>(0))
1199 {
1200#ifdef SE_CLASS3
1201 se3.template write<prop::max_prop_real>(*this,g_m-1);
1202#endif
1203
1204 return v_pos.template get<0>(g_m - 1);
1205 }
1206
1214 template<unsigned int id> inline auto getLastPropWrite() -> decltype(v_prp.template get<id>(0))
1215 {
1216#ifdef SE_CLASS3
1217 se3.template write<id>(*this,g_m-1);
1218#endif
1219
1220 return v_prp.template get<id>(g_m - 1);
1221 }
1222
1224
1225 vect_dist_key_dx getOriginKey(vect_dist_key_dx vec_key)
1226 {
1227 return vec_key;
1228 }
1229
1239 template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St>,internal_position_vector_type > >
1240 CellL getCellListSym(St r_cut)
1241 {
1242#ifdef SE_CLASS1
1243 if (!(opt & BIND_DEC_TO_GHOST))
1244 {
1245 if (getDecomposition().getGhost().getLow(dim-1) == 0.0)
1246 {
1247 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;
1248 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1249 }
1250 }
1251#endif
1252
1253 // Cell list
1254 CellL cell_list;
1255
1256 size_t pad = 0;
1257 CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
1258 cl_param_calculateSym(getDecomposition().getDomain(),cd_sm,getDecomposition().getGhost(),r_cut,pad);
1259
1260 // Processor bounding box
1261 Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1262
1263 // Ghost padding extension
1264 Ghost<dim,size_t> g_ext(0);
1265 cell_list.Initialize(cd_sm,pbox,pad);
1266 cell_list.set_ndec(getDecomposition().get_ndec());
1267
1268 updateCellListSym(cell_list);
1269
1270 return cell_list;
1271 }
1272
1282 template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > >
1283 CellL getCellListSym(const size_t (& div)[dim],
1284 const size_t (& pad)[dim])
1285 {
1286#ifdef SE_CLASS1
1287 if (!(opt & BIND_DEC_TO_GHOST))
1288 {
1289 if (getDecomposition().getGhost().getLow(dim-1) == 0.0)
1290 {
1291 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;
1292 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1293 }
1294 }
1295#endif
1296
1297 size_t pad_max = pad[0];
1298 for (size_t i = 1 ; i < dim ; i++)
1299 {if (pad[i] > pad_max) {pad_max = pad[i];}}
1300
1301 // Cell list
1302 CellL cell_list;
1303
1304 CellDecomposer_sm<dim,St,shift<dim,St>> cd_sm;
1305 cd_sm.setDimensions(getDecomposition().getDomain(),div,pad_max);
1306
1307 // Processor bounding box
1308 Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1309
1310 // Ghost padding extension
1311 Ghost<dim,size_t> g_ext(0);
1312 cell_list.Initialize(cd_sm,pbox,pad_max);
1313 cell_list.set_ndec(getDecomposition().get_ndec());
1314
1315 updateCellListSym(cell_list);
1316
1317 return cell_list;
1318 }
1319
1330 template<unsigned int impl>
1331 typename cell_list_selector<self,impl>::ctype getCellListDev(St r_cut)
1332 {
1333 return cell_list_selector<self,impl>::get(*this,r_cut);
1334 }
1335
1346 template<typename CellL = CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St>, decltype(v_pos) > >
1347 CellL getCellList(St r_cut, bool no_se3 = false)
1348 {
1349#ifdef SE_CLASS3
1350 if (no_se3 == false)
1351 {se3.getNN();}
1352#endif
1353#ifdef SE_CLASS1
1355#endif
1356
1357 // Get ghost and anlarge by 1%
1358 Ghost<dim,St> g = getDecomposition().getGhost();
1359 g.magnify(1.013);
1360
1361 return getCellList<CellL>(r_cut, g,no_se3);
1362 }
1363
1364#ifdef CUDA_GPU
1365
1373 template<typename CellType = CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>>,unsigned int ... prp>
1374 CellType getCellListGPU(St r_cut, bool no_se3 = false)
1375 {
1376#ifdef SE_CLASS3
1377 if (no_se3 == false)
1378 {se3.getNN();}
1379#endif
1380#ifdef SE_CLASS1
1382#endif
1383
1384 // Get ghost and anlarge by 1%
1385 Ghost<dim,St> g = getDecomposition().getGhost();
1386 g.magnify(1.013);
1387
1388 return getCellListGPU<CellType>(r_cut, g,no_se3);
1389 }
1390
1391
1407 template<typename CellType = CellList_gpu<dim,St,CudaMemory,shift_only<dim, St>>, unsigned int ... prp>
1408 CellType getCellListGPU(St r_cut, const Ghost<dim, St> & enlarge, bool no_se3 = false)
1409 {
1410#ifdef SE_CLASS3
1411 if (no_se3 == false)
1412 {se3.getNN();}
1413#endif
1414
1415 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1416
1417 // Division array
1418 size_t div[dim];
1419
1420 // get the processor bounding box
1421 Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1422
1423 // Processor bounding box
1424 cl_param_calculate(pbox, div, r_cut, enlarge);
1425
1426 CellType cell_list(pbox,div);
1427
1428 v_prp_out.resize(v_pos.size());
1429 v_pos_out.resize(v_pos.size());
1430
1431 cell_list.template construct<decltype(v_pos),decltype(v_prp),prp ...>(v_pos,v_pos_out,v_prp,v_prp_out,v_cl.getgpuContext(),g_m);
1432
1433 cell_list.set_ndec(getDecomposition().get_ndec());
1434 cell_list.set_gm(g_m);
1435
1436#ifdef CUDA_GPU
1437 this->update_sort(this->toKernel_sorted());
1438#endif
1439
1440 return cell_list;
1441 }
1442
1443
1444#endif
1445
1447
1448#ifdef CUDA_GPU
1449
1457 auto getCellListDevice(St r_cut, bool no_se3 = false) -> decltype(this->getCellListGPU(r_cut,no_se3))
1458 {
1459 return this->getCellListGPU(r_cut,no_se3);
1460 }
1461
1462
1463#else
1464
1472 auto getCellListDevice(St r_cut, bool no_se3 = false) -> decltype(this->getCellList(r_cut,no_se3))
1473 {
1474 return this->getCellList(r_cut,no_se3);
1475 }
1476
1477#endif
1478
1480
1490 template<typename CellL = CellList_gen<dim, St, Process_keys_hilb, Mem_fast<>, shift<dim, St> > >
1491 CellL getCellList_hilb(St r_cut)
1492 {
1493#ifdef SE_CLASS3
1494 se3.getNN();
1495#endif
1496#ifdef SE_CLASS1
1498#endif
1499
1500 // Get ghost and anlarge by 1%
1501 Ghost<dim,St> g = getDecomposition().getGhost();
1502 g.magnify(1.013);
1503
1504 return getCellList_hilb(r_cut, g);
1505 }
1506
1515 template<unsigned int ... prp,typename CellL>
1516 void updateCellList(CellL & cell_list, bool no_se3 = false, cl_construct_opt opt = cl_construct_opt::Full)
1517 {
1518#ifdef SE_CLASS3
1519 if (no_se3 == false)
1520 {se3.getNN();}
1521#endif
1522
1523 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1524
1525 // This function assume equal spacing in all directions
1526 // but in the worst case we take the maximum
1527 St r_cut = cell_list.getCellBox().getRcut();
1528
1529 // Here we have to check that the Cell-list has been constructed
1530 // from the same decomposition
1531 bool to_reconstruct = cell_list.get_ndec() != getDecomposition().get_ndec();
1532
1533 if (to_reconstruct == false)
1534 {
1535 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.getgpuContext(false),g_m,CL_NON_SYMMETRIC,opt);
1536
1537 cell_list.set_gm(g_m);
1538 }
1539 else
1540 {
1541 CellL cli_tmp = gcl<dim,St,CellL,self,GCL_NON_SYMMETRIC>::get(*this,r_cut,getDecomposition().getGhost());
1542
1543 cell_list.swap(cli_tmp);
1544 cell_list.re_setBoxNN();
1545 }
1546 }
1547
1555 template<typename CellL = CellList<dim, St, Mem_fast<>, shift<dim, St> > >
1556 void updateCellListSym(CellL & cell_list)
1557 {
1558#ifdef SE_CLASS3
1559 se3.getNN();
1560#endif
1561
1562 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
1563
1564 // Here we have to check that the Cell-list has been constructed
1565 // from the same decomposition
1566 bool to_reconstruct = cell_list.get_ndec() != getDecomposition().get_ndec();
1567
1568 if (to_reconstruct == false)
1569 {
1570 populate_cell_list(v_pos,v_pos_out,v_prp,v_prp_out,cell_list,v_cl.getgpuContext(),g_m,CL_SYMMETRIC,cl_construct_opt::Full);
1571
1572 cell_list.set_gm(g_m);
1573 }
1574 else
1575 {
1577 cell_list.getDivWP(),
1578 cell_list.getPadding(),
1579 getDecomposition().getGhost());
1580
1581 cell_list.swap(cli_tmp);
1582 }
1583 }
1584
1601 template<typename CellL = CellList_gen<dim, St, Process_keys_lin, Mem_fast<>, shift<dim, St> > >
1602 CellL getCellList(St r_cut, const Ghost<dim, St> & enlarge, bool no_se3 = false)
1603 {
1604#ifdef SE_CLASS3
1605 if (no_se3 == false)
1606 {se3.getNN();}
1607#endif
1608
1609 CellL cell_list;
1610
1611 // Division array
1612 size_t div[dim];
1613
1614 // get the processor bounding box
1615 Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1616
1617 // Processor bounding box
1618 cl_param_calculate(pbox, div, r_cut, enlarge);
1619
1620 cell_list.Initialize(pbox, div);
1621 cell_list.set_gm(g_m);
1622 cell_list.set_ndec(getDecomposition().get_ndec());
1623
1624 updateCellList(cell_list,no_se3);
1625
1626 return cell_list;
1627 }
1628
1644 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)
1645 {
1646#ifdef SE_CLASS3
1647 se3.getNN();
1648#endif
1649
1650 CellL cell_list;
1651
1652 // Division array
1653 size_t div[dim];
1654
1655 // get the processor bounding box
1656 Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1657
1658 // Processor bounding box
1659 cl_param_calculate(pbox,div, r_cut, enlarge);
1660
1661 cell_list.Initialize(pbox, div);
1662 cell_list.set_gm(g_m);
1663 cell_list.set_ndec(getDecomposition().get_ndec());
1664
1665 updateCellList(cell_list);
1666
1667 return cell_list;
1668 }
1669
1677 template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
1678 VerletL getVerletSym(St r_cut)
1679 {
1680#ifdef SE_CLASS3
1681 se3.getNN();
1682#endif
1683
1684 VerletL ver;
1685
1686 // Processor bounding box
1687 Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1688
1689 ver.InitializeSym(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,v_pos,g_m);
1690
1691 ver.set_ndec(getDecomposition().get_ndec());
1692
1693 return ver;
1694 }
1695
1703 template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St> >>
1704 VerletL getVerletCrs(St r_cut)
1705 {
1706#ifdef SE_CLASS1
1707 if (!(opt & BIND_DEC_TO_GHOST))
1708 {
1709 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;
1710 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1711 }
1712#endif
1713
1714#ifdef SE_CLASS3
1715 se3.getNN();
1716#endif
1717
1718 VerletL ver;
1719
1720 // Processor bounding box
1721 Box<dim, St> pbox = getDecomposition().getProcessorBounds();
1722
1723 // Initialize the verlet list
1724 ver.InitializeCrs(getDecomposition().getDomain(),pbox,getDecomposition().getGhost(),r_cut,v_pos,g_m);
1725
1726 // Get the internal cell list
1727 auto & NN = ver.getInternalCellList();
1728
1729 // Shift
1731
1732 // Add padding
1733 for (size_t i = 0 ; i < dim ; i++)
1734 shift.set_d(i,NN.getPadding(i));
1735
1736 grid_sm<dim,void> gs = NN.getInternalGrid();
1737
1738 getDecomposition().setNNParameters(shift,gs);
1739
1740 ver.createVerletCrs(r_cut,g_m,v_pos,
1741 getDecomposition().getCRSDomainCells(),
1742 getDecomposition().getCRSAnomDomainCells());
1743
1744 ver.set_ndec(getDecomposition().get_ndec());
1745
1746 return ver;
1747 }
1748
1756 template <typename VerletL = VerletList<dim,St,Mem_fast<>,shift<dim,St>,decltype(v_pos) >>
1757 VerletL getVerlet(St r_cut)
1758 {
1759#ifdef SE_CLASS3
1760 se3.getNN();
1761#endif
1762
1763 VerletL ver;
1764
1765 // get the processor bounding box
1766 Box<dim, St> bt = getDecomposition().getProcessorBounds();
1767
1768 // Get the ghost
1769 Ghost<dim,St> g = getDecomposition().getGhost();
1770 g.magnify(1.013);
1771
1772 // enlarge the box where the Verlet is defined
1773 bt.enlarge(g);
1774
1775 ver.Initialize(bt,getDecomposition().getProcessorBounds(),r_cut,v_pos,g_m,VL_NON_SYMMETRIC);
1776
1777 ver.set_ndec(getDecomposition().get_ndec());
1778
1779 return ver;
1780 }
1781
1790 template<typename Mem_type> void updateVerlet(VerletList<dim,St,Mem_type,shift<dim,St> > & ver, St r_cut, size_t opt = VL_NON_SYMMETRIC)
1791 {
1792#ifdef SE_CLASS3
1793 se3.getNN();
1794#endif
1795
1796 if (opt == VL_SYMMETRIC)
1797 {
1798 auto & NN = ver.getInternalCellList();
1799
1800 // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1801 // processor. if it is not like that we have to completely reconstruct from stratch
1802 bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1803
1804 if (to_reconstruct == false)
1805 ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
1806 else
1807 {
1809
1810 ver_tmp = getVerlet<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1811 ver.swap(ver_tmp);
1812 }
1813 }
1814 else if (opt == VL_CRS_SYMMETRIC)
1815 {
1816#ifdef SE_CLASS1
1817 if ((opt & BIND_DEC_TO_GHOST))
1818 {
1819 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;
1820 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
1821 }
1822#endif
1823
1824 auto & NN = ver.getInternalCellList();
1825
1826 // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1827 // processor. if it is not like that we have to completely reconstruct from stratch
1828 bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1829
1830 if (to_reconstruct == false)
1831 {
1832 // Shift
1834
1835 // Add padding
1836 for (size_t i = 0 ; i < dim ; i++)
1837 shift.set_d(i,NN.getPadding(i));
1838
1839 grid_sm<dim,void> gs = NN.getInternalGrid();
1840
1841 getDecomposition().setNNParameters(shift,gs);
1842
1843 ver.updateCrs(getDecomposition().getDomain(),r_cut,v_pos,g_m,
1844 getDecomposition().getCRSDomainCells(),
1845 getDecomposition().getCRSAnomDomainCells());
1846 }
1847 else
1848 {
1850
1851 ver_tmp = getVerletCrs<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1852 ver.swap(ver_tmp);
1853 }
1854 }
1855 else
1856 {
1857 auto & NN = ver.getInternalCellList();
1858
1859 // Here we have to check that the Box defined by the Cell-list is the same as the domain box of this
1860 // processor. if it is not like that we have to completely reconstruct from stratch
1861 bool to_reconstruct = NN.get_ndec() != getDecomposition().get_ndec();
1862
1863 if (to_reconstruct == false)
1864 ver.update(getDecomposition().getDomain(),r_cut,v_pos,g_m, opt);
1865 else
1866 {
1868
1869 ver_tmp = getVerlet<VerletList<dim,St,Mem_type,shift<dim,St> >>(r_cut);
1870 ver.swap(ver_tmp);
1871 }
1872 }
1873 }
1874
1875
1883 template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
1884 void reorder (int32_t m, reorder_opt opt = reorder_opt::HILBERT)
1885 {
1886 reorder<CellL>(m,getDecomposition().getGhost(),opt);
1887 }
1888
1889
1903 template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
1904 void reorder(int32_t m, const Ghost<dim,St> & enlarge, reorder_opt opt = reorder_opt::HILBERT)
1905 {
1906 // reset the ghost part
1907 v_pos.resize(g_m);
1908 v_prp.resize(g_m);
1909
1910
1911 CellL cell_list;
1912
1913 // calculate the parameters of the cell list
1914
1915 // get the processor bounding box
1916 Box<dim,St> pbox = getDecomposition().getProcessorBounds();
1917 // extend by the ghost
1918 pbox.enlarge(enlarge);
1919
1920 size_t div[dim];
1921
1922 // Calculate the division array and the cell box
1923 for (size_t i = 0 ; i < dim ; i++)
1924 {
1925 div[i] = 1 << m;
1926 }
1927
1928 cell_list.Initialize(pbox,div);
1929 cell_list.set_gm(g_m);
1930
1931 // for each particle add the particle to the cell list
1932
1933 auto it = getIterator();
1934
1935 while (it.isNext())
1936 {
1937 auto key = it.get();
1938
1939 Point<dim,St> xp = this->getPos(key);
1940
1941 cell_list.add(xp,key.getKey());
1942
1943 ++it;
1944 }
1945
1946 // Use cell_list to reorder v_pos
1947
1948 //destination vector
1950 openfpm::vector<prop> v_prp_dest;
1951
1952 if (opt == reorder_opt::HILBERT)
1953 {
1955
1956 reorder_sfc<CellL,grid_key_dx_iterator_hilbert<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
1957 }
1958 else if (opt == reorder_opt::LINEAR)
1959 {
1960 grid_sm<dim,void> gs(div);
1962
1963 reorder_sfc<CellL,grid_key_dx_iterator<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
1964 }
1965 else
1966 {
1967 // We do nothing, we second swap nullify the first
1968 v_pos.swap(v_pos_dest);
1969 v_prp.swap(v_prp_dest);
1970 }
1971
1972 v_pos.swap(v_pos_dest);
1973 v_prp.swap(v_prp_dest);
1974 }
1975
1989 template<typename CellL=CellList_gen<dim,St,Process_keys_lin,Mem_bal<>,shift<dim,St> > >
1990 void reorder_rcut(St r_cut)
1991 {
1992 // reset the ghost part
1993 v_pos.resize(g_m);
1994 v_prp.resize(g_m);
1995
1996 auto cell_list = getCellList<CellL>(r_cut);
1997
1998 // Use cell_list to reorder v_pos
1999
2000 //destination vector
2002 openfpm::vector<prop> v_prp_dest;
2003
2004 size_t div[dim];
2005 for (size_t i = 0 ; i < dim ; i++)
2006 {div[i] = cell_list.getGrid().size(i) - 2*cell_list.getPadding()[i];}
2007
2008 grid_sm<dim,void> gs(div);
2010
2011 reorder_sfc<CellL,grid_key_dx_iterator<dim>>(v_pos_dest,v_prp_dest,h_it,cell_list);
2012
2013 v_pos.swap(v_pos_dest);
2014 v_prp.swap(v_prp_dest);
2015 }
2016
2032 size_t init_size_accum(size_t np)
2033 {
2034 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2035
2036 size_t accum = 0;
2037
2038 // convert to a local number of elements
2039 size_t p_np = np / v_cl.getProcessingUnits();
2040
2041 // Get non divisible part
2042 size_t r = np % v_cl.getProcessingUnits();
2043
2044 accum = p_np * v_cl.getProcessUnitID();
2045
2046 // Distribute the remain particles
2047 if (v_cl.getProcessUnitID() <= r)
2048 accum += v_cl.getProcessUnitID();
2049 else
2050 accum += r;
2051
2052 return accum;
2053 }
2054
2061 {
2062#ifdef SE_CLASS3
2063 se3.getIterator();
2064#endif
2065 return vector_dist_iterator(0, v_pos.size());
2066 }
2067
2076 vector_dist_iterator getIterator(size_t start, size_t stop)
2077 {
2078#ifdef SE_CLASS3
2079 se3.getIterator();
2080#endif
2081 return vector_dist_iterator(start, stop);
2082 }
2083
2094 {
2095 grid_key_dx<dim> start;
2096 grid_key_dx<dim> stop;
2097 for (size_t i = 0; i < dim; i++)
2098 {
2099 start.set_d(i, 0);
2100 stop.set_d(i, sz[i] - 1);
2101 }
2102
2104 return it_dec;
2105 }
2106
2113 {
2114#ifdef SE_CLASS3
2115 se3.getIterator();
2116#endif
2117
2118 return vector_dist_iterator(g_m, v_pos.size());
2119 }
2120
2127 {
2128 return vector_dist_iterator(g_m, v_pos.size());
2129 }
2130
2139 template<typename CellList> ParticleIt_Cells<dim,CellList>
2141 {
2142#ifdef SE_CLASS3
2143 se3.getIterator();
2144#endif
2145
2146 // Shift
2148
2149 // Add padding
2150 for (size_t i = 0 ; i < dim ; i++)
2151 shift.set_d(i,NN.getPadding(i));
2152
2153 grid_sm<dim,void> gs = NN.getInternalGrid();
2154
2155 getDecomposition().setNNParameters(shift,gs);
2156
2157 return ParticleIt_Cells<dim,CellList>(NN,getDecomposition().getDomainCells(),g_m);
2158 }
2159
2166 {
2167#ifdef SE_CLASS3
2168 se3.getIterator();
2169#endif
2170
2171 return vector_dist_iterator(0, g_m);
2172 }
2173
2174#ifdef CUDA_GPU
2175
2181 ite_gpu<1> getDomainIteratorGPU(size_t n_thr = default_kernel_wg_threads_) const
2182 {
2183#ifdef SE_CLASS3
2184 se3.getIterator();
2185#endif
2186
2187 return v_pos.getGPUIteratorTo(g_m-1,n_thr);
2188 }
2189
2195 ite_gpu<1> getDomainAndGhostIteratorGPU(size_t n_thr = default_kernel_wg_threads_) const
2196 {
2197#ifdef SE_CLASS3
2198 se3.getIterator();
2199#endif
2200
2201 return v_pos.getGPUIteratorTo(v_pos.size()-1,n_thr);
2202 }
2203
2209 template<unsigned int ... prp,typename id_1, typename id_2, bool is_sparse>
2210 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_)
2211 {
2212#if defined(__NVCC__)
2213
2214 auto ite = v_pos.getGPUIteratorTo(g_m-1,n_thr);
2215 bool has_work = has_work_gpu(ite);
2216
2217 if (has_work == true)
2218 {
2219 CUDA_LAUNCH((merge_sort_part<false,decltype(v_pos.toKernel()),decltype(v_prp.toKernel()),decltype(cl.getNonSortToSort().toKernel()),prp...>),
2220 ite,
2221 v_pos.toKernel(),v_prp.toKernel(),v_pos_out.toKernel(),v_prp_out.toKernel(),cl.getNonSortToSort().toKernel());
2222 }
2223
2224#endif
2225 }
2226
2234 template<unsigned int prp>
2235 void debugPrintVector(bool print_sorted = false)
2236 {
2237 if (print_sorted == false)
2238 {this->v_prp.template deviceToHost<prp>();}
2239 else
2240 {this->v_prp_out.template deviceToHost<prp>();}
2241
2242 auto it = this->getDomainIterator();
2243
2244 while(it.isNext())
2245 {
2246 auto p = it.get();
2247
2248 for (size_t i = 0 ; i < std::extent<typename boost::mpl::at<typename prop::type,boost::mpl::int_<prp>>::type>::value ; i++)
2249 {
2250 if (print_sorted == false)
2251 {std::cout << v_prp.template get<prp>(p.getKey())[i] << " ";}
2252 else
2253 {std::cout << v_prp_out.template get<prp>(p.getKey())[i] << " ";}
2254 }
2255
2256 std::cout << std::endl;
2257
2258 ++it;
2259 }
2260 }
2261
2269 template<unsigned int prp>
2270 void debugPrintScalar(bool print_sorted = false)
2271 {
2272 if (print_sorted == false)
2273 {this->v_prp.template deviceToHost<prp>();}
2274 else
2275 {this->v_prp_out.template deviceToHost<prp>();}
2276
2277 auto it = this->getDomainIterator();
2278
2279 while(it.isNext())
2280 {
2281 auto p = it.get();
2282
2283 if (print_sorted == false)
2284 {std::cout << v_prp_out.template get<prp>(p.getKey()) << " " << std::endl;}
2285 else
2286 {std::cout << v_prp_out.template get<prp>(p.getKey()) << " " << std::endl;}
2287
2288 ++it;
2289 }
2290 }
2291
2297 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_)
2298 {
2299#if defined(__NVCC__)
2300
2301 auto ite = v_pos.getGPUIteratorTo(g_m-1,n_thr);
2302
2303 CUDA_LAUNCH((merge_sort_part<true,decltype(v_pos.toKernel()),decltype(v_prp.toKernel()),decltype(cl.getNonSortedToSorted().toKernel()),prp...>),
2304 ite,
2305 v_pos.toKernel(),v_prp.toKernel(),v_pos_out.toKernel(),v_prp_out.toKernel(),cl.getNonSortedToSorted().toKernel());
2306
2307#endif
2308 }
2309
2310#endif
2311
2312#ifdef CUDA_GPU
2313
2319 auto getDomainIteratorDevice(size_t n_thr = default_kernel_wg_threads_) const -> decltype(this->getDomainIteratorGPU(n_thr))
2320 {
2321 return this->getDomainIteratorGPU(n_thr);
2322 }
2323
2324
2325#else
2326
2332 auto getDomainIteratorDevice(size_t n_thr = default_kernel_wg_threads_) const -> decltype(this->getDomainIterator())
2333 {
2334 return this->getDomainIterator();
2335 }
2336
2337
2338#endif
2339
2346 {
2347 return vector_dist_iterator(0, g_m);
2348 }
2349
2356 {
2357#ifdef SE_CLASS3
2358 se3.getIterator();
2359#endif
2360
2361 return vector_dist_iterator(0, v_pos.size());
2362 }
2363
2370 {
2371 return vector_dist_iterator(0, v_pos.size());
2372 }
2373
2380 {
2382 }
2383
2389 inline const Decomposition & getDecomposition() const
2390 {
2392 }
2393
2407 template<unsigned int ... prp> void map_list(size_t opt = NONE)
2408 {
2409#ifdef SE_CLASS3
2410 se3.map_pre();
2411#endif
2412
2413 this->template map_list_<prp...>(v_pos,v_prp,g_m,opt);
2414
2415#ifdef CUDA_GPU
2416 this->update(this->toKernel());
2417#endif
2418
2419#ifdef SE_CLASS3
2420 se3.map_post();
2421#endif
2422 }
2423
2424
2436 template<typename obp = KillParticle> void map(size_t opt = NONE)
2437 {
2438#ifdef SE_CLASS3
2439 se3.map_pre();
2440#endif
2441#ifdef SE_CLASS1
2442 map_ctr++;
2443#endif
2444
2445 this->template map_<obp>(v_pos,v_prp,g_m,opt);
2446
2447#ifdef CUDA_GPU
2448 this->update(this->toKernel());
2449#endif
2450
2451#ifdef SE_CLASS3
2452 se3.map_post();
2453#endif
2454 }
2455#ifdef SE_CLASS1
2456 int getMapCtr() const
2457 {
2458 return map_ctr;
2459 }
2460#endif
2461
2462
2467 {
2468 /* #ifdef SE_CLASS1
2469 This is not a ghost get on subset.
2470 std::cerr<<__FILE__<<":"<<__LINE__<<":You Used a ghost_get on a subset. This does not do anything. Please use ghostget on the entire set.";
2471 #endif */
2472 }
2473
2481 template<int ... prp> inline void ghost_get(size_t opt = WITH_POSITION)
2482 {
2483#ifdef SE_CLASS1
2484 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2485
2486 if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2487 {
2488 std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2489 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2490 }
2491#endif
2492
2493#ifdef SE_CLASS3
2494 se3.template ghost_get_pre<prp...>(opt);
2495#endif
2496
2497 this->template ghost_get_<GHOST_SYNC,prp...>(v_pos,v_prp,g_m,opt);
2498
2499#ifdef CUDA_GPU
2500 this->update(this->toKernel());
2501#endif
2502
2503#ifdef SE_CLASS3
2504
2505 this->template ghost_get_<prop::max_prop_real>(v_pos,v_prp,g_m,opt | KEEP_PROPERTIES);
2506
2507 se3.template ghost_get_post<prp...>(opt);
2508#endif
2509 }
2510
2511
2519 template<int ... prp> inline void Ighost_get(size_t opt = WITH_POSITION)
2520 {
2521#ifdef SE_CLASS1
2522 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2523
2524 if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2525 {
2526 std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2527 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2528 }
2529#endif
2530
2531#ifdef SE_CLASS3
2532 se3.template ghost_get_pre<prp...>(opt);
2533#endif
2534
2535 this->template ghost_get_<GHOST_ASYNC,prp...>(v_pos,v_prp,g_m,opt);
2536 }
2537
2545 template<int ... prp> inline void ghost_wait(size_t opt = WITH_POSITION)
2546 {
2547#ifdef SE_CLASS1
2548 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2549
2550 if (getDecomposition().getProcessorBounds().isValid() == false && size_local() != 0)
2551 {
2552 std::cerr << __FILE__ << ":" << __LINE__ << " Error the processor " << v_cl.getProcessUnitID() << " has particles, but is supposed to be unloaded" << std::endl;
2553 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
2554 }
2555#endif
2556
2557 this->template ghost_wait_<prp...>(v_pos,v_prp,g_m,opt);
2558
2559#ifdef CUDA_GPU
2560 this->update(this->toKernel());
2561#endif
2562
2563#ifdef SE_CLASS3
2564
2565 this->template ghost_get_<prop::max_prop_real>(v_pos,v_prp,g_m,opt | KEEP_PROPERTIES);
2566
2567 se3.template ghost_get_post<prp...>(opt);
2568#endif
2569 }
2570
2582 template<template<typename,typename> class op, int ... prp> inline void ghost_put(size_t opt_ = NONE)
2583 {
2584#ifdef SE_CLASS3
2585 se3.template ghost_put<prp...>();
2586#endif
2587 this->template ghost_put_<op,prp...>(v_pos,v_prp,g_m,opt_);
2588 }
2589
2598 void remove(openfpm::vector<size_t> & keys, size_t start = 0)
2599 {
2600 v_pos.remove(keys, start);
2601 v_prp.remove(keys, start);
2602
2603 g_m -= keys.size();
2604 }
2605
2614 void remove(openfpm::vector<aggregate<int>> & keys, size_t start = 0)
2615 {
2616 v_pos.remove(keys, start);
2617 v_prp.remove(keys, start);
2618
2619 g_m -= keys.size();
2620 }
2621
2627 void remove(size_t key)
2628 {
2629 v_pos.remove(key);
2630 v_prp.remove(key);
2631
2632 g_m--;
2633 }
2634
2642 template <typename Model=ModelLin>inline void addComputationCosts(const self & vd, Model md=Model())
2643 {
2644 CellDecomposer_sm<dim, St, shift<dim,St>> cdsm;
2645
2647
2648 cdsm.setDimensions(dec.getDomain(), dec.getDistGrid().getSize(), 0);
2649
2650 auto it = vd.getDomainIterator();
2651
2652 while (it.isNext())
2653 {
2654 Point<dim,St> p = vd.getPos(it.get());
2655 size_t v = cdsm.getCell(p);
2656
2657 md.addComputation(dec,vd,v,it.get().getKey());
2658
2659 ++it;
2660 }
2661 }
2662
2671 template <typename Model=ModelLin> void finalizeComputationCosts(Model md=Model(), size_t ts = 1)
2672 {
2674 auto & dist = getDecomposition().getDistribution();
2675
2676 dec.computeCommunicationAndMigrationCosts(ts);
2677
2678 // Go throught all the sub-sub-domains and apply the model
2679
2680 for (size_t i = 0 ; i < dist.getNOwnerSubSubDomains(); i++)
2681 {md.applyModel(dec,dist.getOwnerSubSubDomain(i));}
2682
2683 dist.setDistTol(md.distributionTol());
2684 }
2685
2690 {
2692 auto & dist = getDecomposition().getDistribution();
2693
2694 for (size_t i = 0; i < dist.getNOwnerSubSubDomains() ; i++)
2695 {dec.setSubSubDomainComputationCost(dist.getOwnerSubSubDomain(i) , 1);}
2696 }
2697
2706 template <typename Model=ModelLin>inline void addComputationCosts(Model md=Model(), size_t ts = 1)
2707 {
2709
2710 addComputationCosts(*this,md);
2711
2713 }
2714
2720 inline void save(const std::string & filename) const
2721 {
2723
2724 h5s.save(filename,v_pos,v_prp);
2725 }
2726
2732 inline void load(const std::string & filename)
2733 {
2735
2736 h5l.load(filename,v_pos,v_prp,g_m);
2737 }
2738
2744 void setCapacity(unsigned int ns)
2745 {
2746 v_pos.reserve(ns);
2747 v_prp.reserve(ns);
2748 }
2749
2759 inline bool write(std::string out ,int opt = VTK_WRITER)
2760 {
2761 return write(out,"",opt);
2762 }
2763
2774 inline bool write(std::string out, std::string meta_info ,int opt = VTK_WRITER)
2775 {
2776 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2777
2778 if ((opt & 0x0FFF0000) == CSV_WRITER)
2779 {
2780 // CSVWriter test
2781 CSVWriter<vector_dist_pos,
2782 vector_dist_prop > csv_writer;
2783
2784 std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".csv"));
2785
2786 // Write the CSV
2787 return csv_writer.write(output,v_pos,v_prp);
2788 }
2789 else
2790 {
2791 file_type ft = file_type::ASCII;
2792
2793 if (opt & FORMAT_BINARY)
2794 ft = file_type::BINARY;
2795
2796 // VTKWriter for a set of points
2797 VTKWriter<boost::mpl::pair<vector_dist_pos,
2798 vector_dist_prop>,
2799 VECTOR_POINTS> vtk_writer;
2800 vtk_writer.add(v_pos,v_prp,g_m);
2801
2802 std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + std::to_string(".vtp"));
2803 //Create Directory for VTP files and write the PVTP metadata
2804 if(v_cl.rank()==0)
2805 {
2806 create_directory_if_not_exist("VTPDATA",1);
2807 vtk_writer.write_pvtp(out,prp_names,v_cl.size());
2808 }
2809 v_cl.barrier();
2810 // Write the VTK file
2811 bool ret=vtk_writer.write(output,prp_names,"particles",meta_info,ft);
2812 return ret;
2813 }
2814 }
2815
2821 {
2822 v_pos.resize(g_m);
2823 v_prp.resize(g_m);
2824 }
2825
2833 void resize(size_t rs)
2834 {
2835 deleteGhost();
2836
2837 v_pos.resize(rs);
2838 v_prp.resize(rs);
2839
2840 g_m = rs;
2841
2842#ifdef CUDA_GPU
2843 this->update(this->toKernel());
2844#endif
2845 }
2846
2854 void resizeAtEnd(size_t rs)
2855 {
2856 v_pos.resize(rs);
2857 v_prp.resize(rs);
2858#ifdef CUDA_GPU
2859 this->update(this->toKernel());
2860#endif
2861 }
2862
2874 inline bool write_frame(std::string out, size_t iteration, int opt = VTK_WRITER)
2875 {
2876 return write_frame(out,iteration,"",opt);
2877 }
2878
2890 inline bool write_frame(std::string out, size_t iteration, std::string meta_info, int opt = VTK_WRITER)
2891 {
2892 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2893
2894 if ((opt & 0x0FFF0000) == CSV_WRITER)
2895 {
2896 // CSVWriter test
2897 CSVWriter<vector_dist_pos,
2898 vector_dist_prop > csv_writer;
2899
2900 std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".csv"));
2901
2902 // Write the CSV
2903 return csv_writer.write(output, v_pos, v_prp);
2904 }
2905 else
2906 {
2907 file_type ft = file_type::ASCII;
2908
2909 if (opt & FORMAT_BINARY)
2910 ft = file_type::BINARY;
2911
2912 // VTKWriter for a set of points
2913 VTKWriter<boost::mpl::pair<vector_dist_pos,
2914 vector_dist_prop>, VECTOR_POINTS> vtk_writer;
2915 vtk_writer.add(v_pos,v_prp,g_m);
2916
2917 std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".vtp"));
2918
2919 //Create Directory for VTP files and write the PVTP metadata
2920 if(v_cl.rank()==0)
2921 {
2922 create_directory_if_not_exist("VTPDATA",1);
2923 vtk_writer.write_pvtp(out,prp_names,v_cl.size(),iteration);
2924 }
2925 v_cl.barrier();
2926
2927 // Write the VTK file
2928 bool ret=vtk_writer.write(output,prp_names,"particles",meta_info,ft);
2929
2930 return ret;
2931 }
2932 }
2933
2945 inline bool write_frame(std::string out, size_t iteration, double time, int opt = VTK_WRITER)
2946 {
2947 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
2948
2949 if ((opt & 0x0FFF0000) == CSV_WRITER)
2950 {
2951 // CSVWriter test
2952 CSVWriter<vector_dist_pos,
2953 vector_dist_prop > csv_writer;
2954
2955 std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".csv"));
2956
2957 // Write the CSV
2958 return csv_writer.write(output, v_pos, v_prp);
2959 }
2960 else
2961 {
2962 file_type ft = file_type::ASCII;
2963
2964 if (opt & FORMAT_BINARY)
2965 ft = file_type::BINARY;
2966
2967 // VTKWriter for a set of points
2968 VTKWriter<boost::mpl::pair<vector_dist_pos,
2969 vector_dist_prop>, VECTOR_POINTS> vtk_writer;
2970 vtk_writer.add(v_pos,v_prp,g_m);
2971
2972 std::string output = std::to_string(out + "_" + std::to_string(v_cl.getProcessUnitID()) + "_" + std::to_string(iteration) + std::to_string(".vtp"));
2973
2974 //Create Directory for VTP files and write the PVTP metadata
2975 if(v_cl.rank()==0)
2976 {
2977 create_directory_if_not_exist("VTPDATA",1);
2978 vtk_writer.write_pvtp(out,prp_names,v_cl.size(),iteration,time);
2979 }
2980 v_cl.barrier();
2981 // Write the VTK file
2982 bool ret=vtk_writer.write(output,prp_names,"particles","",ft);
2983 return ret;
2984 }
2985 }
2986
2996 void getCellListParams(St r_cut, size_t (&div)[dim],Box<dim, St> & box, Ghost<dim,St> enlarge = Ghost<dim,St>(0.0))
2997 {
2998 // get the processor bounding box
2999 Box<dim, St> pbox = getDecomposition().getProcessorBounds();
3000
3001 // enlarge the processor bounding box by the ghost
3002 Ghost<dim,St> g = getDecomposition().getGhost();
3003 pbox.enlarge(g);
3004
3005 cl_param_calculate(pbox, div,r_cut,enlarge);
3006
3007 // output the fixed domain
3008 box = pbox;
3009 }
3010
3018 long int who()
3019 {
3020#ifdef SE_CLASS2
3021 return check_whoami(this,8);
3022#else
3023 return -1;
3024#endif
3025 }
3026
3034 {
3035#ifdef SE_CLASS2
3036 check_valid(this,8);
3037#endif
3038 return create_vcluster<Memory>();;
3039 }
3040
3046 const vector_dist_pos & getPosVector() const
3047 {
3048 return v_pos;
3049 }
3050
3056 vector_dist_pos & getPosVector()
3057 {
3058 return v_pos;
3059 }
3060
3066 const vector_dist_prop & getPropVector() const
3067 {
3068 return v_prp;
3069 }
3070
3076 vector_dist_prop & getPropVector()
3077 {
3078 return v_prp;
3079 }
3080
3086 const vector_dist_pos & getPosVectorSort() const
3087 {
3088 return v_pos_out;
3089 }
3090
3096 vector_dist_pos & getPosVectorSort()
3097 {
3098 return v_pos_out;
3099 }
3100
3106 const vector_dist_prop & getPropVectorSort() const
3107 {
3108 return v_prp_out;
3109 }
3110
3116 vector_dist_prop & getPropVectorSort()
3117 {
3118 return v_prp_out;
3119 }
3120
3126 size_t accum()
3127 {
3128 Vcluster<Memory> & v_cl = create_vcluster<Memory>();
3129
3131
3132 size_t sz = size_local();
3133
3134 v_cl.allGather(sz,accu);
3135 v_cl.execute();
3136
3137 sz = 0;
3138
3139 for (size_t i = 0 ; i < v_cl.getProcessUnitID() ; i++)
3140 {sz += accu.get(i);}
3141
3142 return sz;
3143 }
3144
3153 template<typename cli> ParticleItCRS_Cells<dim,cli,decltype(v_pos)> getParticleIteratorCRS_Cell(cli & NN)
3154 {
3155#ifdef SE_CLASS3
3156 se3.getIterator();
3157#endif
3158
3159#ifdef SE_CLASS1
3160 if (!(opt & BIND_DEC_TO_GHOST))
3161 {
3162 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;
3163 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
3164 }
3165#endif
3166
3167 // Shift
3169
3170 // Add padding
3171 for (size_t i = 0 ; i < dim ; i++)
3172 shift.set_d(i,NN.getPadding(i));
3173
3174 grid_sm<dim,void> gs = NN.getInternalGrid();
3175
3176 getDecomposition().setNNParameters(shift,gs);
3177
3178 // First we check that
3179 return ParticleItCRS_Cells<dim,cli,decltype(v_pos)>(NN,getDecomposition().getCRSDomainCells(),
3180 getDecomposition().getCRSAnomDomainCells(),
3181 NN.getNNc_sym());
3182 }
3183
3192 {
3193 prp_names = names;
3194 }
3195
3202 {
3203 return prp_names;
3204 }
3205
3206
3216 {
3217#ifdef SE_CLASS1
3218 if (!(opt & BIND_DEC_TO_GHOST))
3219 {
3220 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;
3221 ACTION_ON_ERROR(VECTOR_DIST_ERROR_OBJECT);
3222 }
3223#endif
3224
3225 // First we check that
3227 }
3228
3237 template<typename Celllist> grid_key_dx<dim> getCRSStart(Celllist & NN)
3238 {
3239 return NN.getStartDomainCell();
3240 }
3241
3250 template<typename Celllist> grid_key_dx<dim> getCRSStop(Celllist & NN)
3251 {
3252 grid_key_dx<dim> key = NN.getStopDomainCell();
3253
3254 for (size_t i = 0 ; i < dim ; i++)
3255 key.set_d(i,key.get(i) + 1);
3256 return key;
3257 }
3258
3264 bool isSubset() const
3265 {
3266 return false;
3267 }
3268
3269#ifdef CUDA_GPU
3270
3278 template<unsigned int ... prp> vector_dist_ker<dim,St,prop,layout_base> toKernel()
3279 {
3280 vector_dist_ker<dim,St,prop,layout_base> v(g_m,v_pos.toKernel(), v_prp.toKernel());
3281
3282 return v;
3283 }
3284
3291 vector_dist_ker_list<vector_dist_ker<dim,St,prop,layout_base>> & private_get_vector_dist_ker_list()
3292 {
3293 return *this;
3294 }
3295
3303 template<unsigned int ... prp> vector_dist_ker<dim,St,prop,layout_base> toKernel_sorted()
3304 {
3305 vector_dist_ker<dim,St,prop,layout_base> v(g_m,v_pos_out.toKernel(), v_prp_out.toKernel());
3306
3307 return v;
3308 }
3309
3315 template<unsigned int ... prp> void deviceToHostProp()
3316 {
3317 v_prp.template deviceToHost<prp ...>();
3318 }
3319
3328 template<unsigned int ... prp> void deviceToHostProp(size_t start, size_t stop)
3329 {
3330 v_prp.template deviceToHost<prp ...>(start,stop);
3331 }
3332
3338 void deviceToHostPos()
3339 {
3340 v_pos.template deviceToHost<0>();
3341 }
3342
3348 template<unsigned int ... prp> void hostToDeviceProp()
3349 {
3350 v_prp.template hostToDevice<prp ...>();
3351 }
3352
3358 void hostToDevicePos()
3359 {
3360 v_pos.template hostToDevice<0>();
3361 }
3362
3363 void set_g_m(size_t g_m)
3364 {
3365 this->g_m = g_m;
3366 }
3367
3375 template<typename CellList_type>
3376 void make_sort(CellList_type & NN)
3377 {
3378 deleteGhost();
3379
3380 updateCellList(NN,false,cl_construct_opt::Only_reorder);
3381
3382 // construct a cell-list forcing to create a sorted version without ghost
3383
3384 // swap the sorted with the non-sorted
3385 v_pos.swap(v_pos_out);
3386 v_prp.swap(v_prp_out);
3387 }
3388
3396 template<typename CellList_type>
3397 void make_sort_from(CellList_type & cl)
3398 {
3399#if defined(__NVCC__)
3400
3401 auto ite = v_pos.getGPUIteratorTo(g_m-1);
3402
3403 CUDA_LAUNCH((merge_sort_all<decltype(v_pos.toKernel()),decltype(v_prp.toKernel()),decltype(cl.getNonSortToSort().toKernel())>),
3404 ite,
3405 v_pos_out.toKernel(),v_prp_out.toKernel(),v_pos.toKernel(),v_prp.toKernel(),cl.getNonSortToSort().toKernel());
3406
3407 v_pos.swap(v_pos_out);
3408 v_prp.swap(v_prp_out);
3409
3410#endif
3411 }
3412
3420 bool compareHostAndDevicePos(St tol, St near = -1.0, bool silent = false)
3421 {
3422 return compare_host_device<Point<dim,St>,0>::compare(v_pos,tol,near,silent);
3423 }
3424
3425
3433 template<unsigned int prp>
3434 bool compareHostAndDeviceProp(St tol, St near = -1.0, bool silent = false)
3435 {
3436 return compare_host_device<typename boost::mpl::at<typename prop::type,
3437 boost::mpl::int_<prp> >::type,prp>::compare(v_prp,tol,near,silent);
3438 }
3439
3440#else
3441
3447 template<unsigned int ... prp> void deviceToHostProp()
3448 {}
3449
3456 {}
3457
3463 template<unsigned int ... prp> void hostToDeviceProp()
3464 {}
3465
3472 {}
3473
3474#endif
3475
3476
3477#ifdef SE_CLASS3
3478
3480 {
3481 return se3;
3482 }
3483
3484#endif
3485};
3486
3487
3488template<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>;
3489template<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>;
3490template<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>;
3491
3492#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.
This class represent an N-dimensional box.
Definition Box.hpp:61
std::string toString() const
Produce a string from the object.
Definition Box.hpp:1409
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition Box.hpp:823
bool isValid() const
Check if the Box is a valid box P2 >= P1.
Definition Box.hpp:1180
void magnify(T mg)
Magnify the box.
Definition Box.hpp:889
CSV Writer.
This class decompose a space into sub-sub-domains and distribute them across processors.
Class for FAST cell list implementation.
Definition CellList.hpp:357
size_t getPadding(size_t i) const
Return the number of padding cells of the Cell decomposer.
This class define the domain decomposition interface.
This class allocate, and destroy CPU memory.
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
Implementation of VCluster class.
Definition VCluster.hpp:59
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support.
Definition Vector.hpp:40
Class for Verlet list implementation.
void swap(VerletList< dim, T, Mem_type, transform, vector_pos_type, CellListImpl > &vl)
Swap the memory.
Given the decomposition it create an iterator.
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
__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
Declaration grid_sm.
Definition grid_sm.hpp:167
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
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.
Decomposition dec
Domain decomposition.
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.
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.
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.
Vcluster< Memory > & v_cl
VCluster.
Decomposition & getDecomposition()
Get the decomposition.
void setDecompositionGranularity(size_t n_sub)
Set the minimum number of sub-domain per processor.
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.
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.
auto getLastPropWrite() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
size_t g_m
Ghost marker, all the particle with id > g_m are ghost all with g_m < are real particle.
vector_dist_prop v_prp
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 getPropWrite(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
grid_key_dx< dim > getCRSStart(Celllist &NN)
Return from which cell we have to start in case of CRS interation scheme.
size_t size_local() const
return the local size of the vector
CellL getCellListSym(const size_t(&div)[dim], const size_t(&pad)[dim])
Construct a cell list symmetric based on a cut of radius.
auto getDomainIteratorDevice(size_t n_thr=default_kernel_wg_threads_) const -> decltype(this->getDomainIterator())
Get an iterator that traverse the particles in the domain.
auto getLastPosRead() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
void remove(openfpm::vector< size_t > &keys, size_t start=0)
Remove a set of elements from the distributed vector.
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(v_prp.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
vector_dist_prop & getPropVectorSort()
return the property vector of all the particles
grid_dist_id_iterator_dec< Decomposition > getGridIterator(const size_t(&sz)[dim])
grid_key_dx< dim > getCRSStop(Celllist &NN)
Return from which cell we have to stop in case of CRS interation scheme.
auto getLastProp() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
static const unsigned int dims
template parameters typedefs
vector_dist< dim, St, prop, Decomposition, Memory, layout_base > self
Self type.
auto getPropNC(size_t vec_key) -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
auto getPosRead(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
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.
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
auto getProp(size_t vec_key) -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
void deviceToHostPos()
Move the memory from the device to host memory.
auto getPosOrig(size_t vec_key) -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
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 getPos(size_t vec_key) const -> 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.
int yes_i_am_vector_dist
yes I am vector dist
void setCapacity(unsigned int ns)
Reserve space for the internal vectors.
vector_dist_pos & getPosVector()
return the position vector of all 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.
vector_dist_iterator getDomainAndGhostIterator_no_se3() const
Get an iterator that traverse the particles in the domain.
auto getPosNC(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void setPropNames(const openfpm::vector< std::string > &names)
Set the properties names.
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.
VerletL getVerlet(St r_cut)
for each particle get the verlet list
cell_list_selector< self, impl >::ctype getCellListDev(St r_cut)
Construct a cell list starting from the stored particles.
vector_dist_iterator getGhostIterator() const
Get the iterator across the position of the ghost particles.
auto getPos(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
CellL getCellList(St r_cut, const Ghost< dim, St > &enlarge, bool no_se3=false)
Construct a cell list starting from the stored particles.
auto getCellListDevice(St r_cut, bool no_se3=false) -> decltype(this->getCellList(r_cut, no_se3))
Construct a cell list from the stored particles.
long int who()
It return the id of structure in the allocation list.
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.
CellL getCellList_hilb(St r_cut, const Ghost< dim, St > &enlarge)
Construct an hilbert cell list starting from the stored particles.
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_prop & getPropVector()
return the property vector of all the particles
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 getProp(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, 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...
void addAtEnd()
Add at the END of local and ghost particle.
openfpm::vector< std::string > prp_names
Name of the properties.
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 getPropNC(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
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.
CellL getCellList(St r_cut, bool no_se3=false)
Construct a 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.
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 getPropNC(vect_dist_key_dx vec_key) -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
void setReferenceCounterToOne()
CellL getCellList_hilb(St r_cut)
Construct an hilbert cell list starting from the stored particles.
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.
auto getLastPosWrite() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
void hostToDevicePos()
Move the memory from the device to host memory.
void map(size_t opt=NONE)
It move all the particles that does not belong to the local processor to the respective processor.
auto getLastPosEnd() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element after ghost.
void ghost_put(size_t opt_=NONE)
It synchronize the properties and position of the ghost particles.
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.
auto getPos(size_t vec_key) -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
auto getPosNC(size_t vec_key) -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
const vector_dist_pos & getPosVector() const
return the position vector of all the particles
ParticleIt_Cells< dim, CellList > getDomainIteratorCells(CellList &NN)
Get an iterator that traverse the particles in the domain using a cell list.
CellL getCellListSym(St r_cut)
Construct a cell list symmetric based on a cut of radius.
void initializeComputationCosts()
Initialize the computational cost.
bool write_frame(std::string out, size_t iteration, std::string meta_info, int opt=VTK_WRITER)
Output particle position and properties.
const vector_dist_prop & getPropVectorSort() const
return the property vector of all the particles
void clear()
remove all the elements
const vector_dist_pos & getPosVectorSort() const
return the position vector of all the particles
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...
VerletL getVerletSym(St r_cut)
for each particle get the symmetric verlet list
auto getLastPos() -> decltype(v_pos.template get< 0 >(0))
Get the position of the last element.
VerletL getVerletCrs(St r_cut)
for each particle get the symmetric verlet list
openfpm::vector< std::string > & getPropNames()
Get the properties names.
auto getPosOrig(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position 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 deviceToHostProp()
Move the memory from the device to host memory.
auto getProp(size_t vec_key) const -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
auto getPosWrite(vect_dist_key_dx vec_key) -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
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.
Vcluster< Memory > & getVC()
Get the Virtual Cluster machine.
vector_dist_iterator getGhostIterator_no_se3() const
Get the iterator across the position of the ghost 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.
vector_dist(const vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &v)
Copy Constructor.
void add()
Add local particle.
vector_dist_prop v_prp_out
reordered v_pos buffer
void hostToDeviceProp()
Move the memory from the device to host memory.
vector_dist_pos v_pos
const Decomposition & getDecomposition() const
Get the decomposition.
void addComputationCosts(Model md=Model(), size_t ts=1)
Add the computation cost on the decomposition coming from the particles.
auto getPos(vect_dist_key_dx vec_key) const -> decltype(v_pos.template get< 0 >(vec_key.getKey()))
Get the position of an element.
void load(const std::string &filename)
Load the distributed vector from an HDF5 file.
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 getPosNC(size_t vec_key) const -> decltype(v_pos.template get< 0 >(vec_key))
Get the position of an element.
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_pos v_pos_out
reordered v_prp buffer
vector_dist(vector_dist< dim, St, prop, Decomposition, Memory, layout_base > &&v) noexcept
Copy constructor.
vector_dist_pos & getPosVectorSort()
return the position vector of all the particles
void remove(openfpm::vector< aggregate< int > > &keys, size_t start=0)
Remove a set of elements from the distributed 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.
void ghost_get_subset()
Stub does not do anything.
void deleteGhost()
Delete the particles on the ghost.
auto getPropRead(vect_dist_key_dx vec_key) const -> decltype(v_prp.template get< id >(vec_key.getKey()))
Get the property of an element.
size_t size_local_orig() const
return the local size of the vector
void updateCellListSym(CellL &cell_list)
Update a cell list using the stored particles.
auto getPropNC(size_t vec_key) const -> decltype(v_prp.template get< id >(vec_key))
Get the property of an element.
auto getLastPropRead() -> decltype(v_prp.template get< id >(0))
Get the property of the last element.
Decomposition & getDecomposition()
Get the decomposition.
void resizeAtEnd(size_t rs)
Resize the vector at the end of the ghost (locally)
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...
boost::fusion::vector< list... > type
internal type containing the data
decrement_memory(vector_type &v)
constructor
void operator()(T &t) const
It call the copy function for each property.
vector_type & v
vector
static CellL get(Vector &vd, const St &r_cut, const Ghost< dim, St > &g)
Get the Cell list based on the type.
static CellL get(Vector &vd, const St &r_cut, const Ghost< dim, St > &g)
Get the Cell list based on the type.
General function t get a cell-list.
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.
General function t get a cell-list.
static CellL get(Vector &vd, const St &r_cut, const Ghost< dim, St > &g)
Get the Cell list based on the type.
Check this is a gpu or cpu type cell-list.
Definition util.hpp:74
Transform the boost::fusion::vector into memory specification (memory_traits)