1 | /* |
2 | * VerletListFast.hpp |
3 | * |
4 | * Created on: Aug 16, 2016 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef OPENFPM_DATA_SRC_NN_VERLETLIST_VERLETLISTFAST_HPP_ |
9 | #define OPENFPM_DATA_SRC_NN_VERLETLIST_VERLETLISTFAST_HPP_ |
10 | |
11 | #include "VerletNNIterator.hpp" |
12 | #include "NN/CellList/CellList_util.hpp" |
13 | #include "NN/Mem_type/MemFast.hpp" |
14 | #include "NN/Mem_type/MemBalanced.hpp" |
15 | #include "NN/Mem_type/MemMemoryWise.hpp" |
16 | |
17 | #define VERLET_STARTING_NSLOT 128 |
18 | |
19 | |
20 | #define WITH_RADIUS 3 |
21 | |
22 | /*! \brief Get the neighborhood iterator based on type |
23 | * |
24 | * \tparam dim dimensionality |
25 | * \tparam T type of space |
26 | * \tparam CellListImpl Cell-list implementation |
27 | * \tparam type of neighborhood |
28 | * \tparam PartIt Particle iterator |
29 | * |
30 | */ |
31 | template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, int type, typename local_index> |
32 | struct NNType |
33 | { |
34 | /*! \brief Get the neighborhood |
35 | * |
36 | * \param v particle positions |
37 | * \param xp Position of the particle p |
38 | * \param p id of the particle p |
39 | * \param cl Cell-list type implementation |
40 | * \param r_cut Cutoff radius |
41 | * |
42 | * \return the NN iterator |
43 | * |
44 | */ |
45 | template<typename vector_pos_type> |
46 | static inline auto get(const PartIt & it, |
47 | const vector_pos_type & v, |
48 | Point<dim,T> & xp, |
49 | size_t p, |
50 | CellListImpl & cl, |
51 | T r_cut) -> decltype(cl.template getNNIterator<NO_CHECK>(0)) |
52 | { |
53 | return cl.template getNNIterator<NO_CHECK>(cl.getCell(xp)); |
54 | } |
55 | |
56 | /*! \brief Add particle in the list of the domain particles |
57 | * |
58 | * \param p particle id |
59 | * \param pc domain particle sequence |
60 | * |
61 | */ |
62 | static inline void add(local_index p, openfpm::vector<local_index> & pc) |
63 | { |
64 | } |
65 | }; |
66 | |
67 | |
68 | /*! \brief Get the neighborhood iterator based on type |
69 | * |
70 | * specialization for the case with NN with radius |
71 | * |
72 | * \tparam dim dimensionality |
73 | * \tparam T type of space |
74 | * \tparam CellListImpl Cell-list implementation |
75 | * \tparam PartIt Particle iterator |
76 | * |
77 | */ |
78 | template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, typename local_index> |
79 | struct NNType<dim,T,CellListImpl,PartIt,WITH_RADIUS,local_index> |
80 | { |
81 | /*! \brief Get the neighborhood |
82 | * |
83 | * \param v particle position vector |
84 | * \param xp Position of the particle p |
85 | * \param p id of the particle p |
86 | * \param cl Cell-list type implementation |
87 | * \param r_cut Cutoff radius |
88 | * |
89 | * \return the NN iterator |
90 | * |
91 | */ |
92 | template<typename vector_pos_type> |
93 | static inline auto get(const PartIt & it, |
94 | const vector_pos_type & v, |
95 | Point<dim,T> & xp, |
96 | size_t p, |
97 | CellListImpl & cl, |
98 | T r_cut) -> decltype(cl.template getNNIteratorRadius<NO_CHECK>(0,0.0)) |
99 | { |
100 | return cl.template getNNIteratorRadius<NO_CHECK>(cl.getCell(xp),r_cut); |
101 | } |
102 | |
103 | /*! \brief Add particle in the list of the domain particles |
104 | * |
105 | * \param p particle id |
106 | * \param pc domain particle sequence |
107 | * |
108 | */ |
109 | static inline void add(local_index p, openfpm::vector<local_index> & pc) |
110 | { |
111 | } |
112 | }; |
113 | |
114 | |
115 | /*! \brief Get the neighborhood iterator based on type |
116 | * |
117 | * specialization for the case with NN symmetric |
118 | * |
119 | * \tparam dim dimensionality |
120 | * \tparam T type of space |
121 | * \tparam CellListImpl Cell-list implementation |
122 | * \tparam PartIt particle iterator |
123 | * |
124 | */ |
125 | template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, typename local_index> |
126 | struct NNType<dim,T,CellListImpl,PartIt,VL_SYMMETRIC,local_index> |
127 | { |
128 | /*! \brief Get the neighborhood |
129 | * |
130 | * \param v vector of the particles positions |
131 | * \param xp Position of the particle p |
132 | * \param p id of the particle p |
133 | * \param cl Cell-list type implementation |
134 | * \param r_cut Cutoff radius |
135 | * |
136 | * \return the NN iterator |
137 | * |
138 | */ |
139 | template<typename vector_pos_type> |
140 | static inline auto get(const PartIt & it, |
141 | const vector_pos_type & v, |
142 | Point<dim,T> & xp, |
143 | size_t p, |
144 | CellListImpl & cl, |
145 | T r_cut) -> decltype(cl.template getNNIteratorSym<NO_CHECK>(0,0,vector_pos_type())) |
146 | { |
147 | return cl.template getNNIteratorSym<NO_CHECK>(cl.getCell(xp),p,v); |
148 | } |
149 | |
150 | /*! \brief Add particle in the list of the domain particles |
151 | * |
152 | * \param p particle id |
153 | * \param pc domain particle sequence |
154 | * |
155 | */ |
156 | static inline void add(local_index p, openfpm::vector<local_index> & pc) |
157 | { |
158 | } |
159 | }; |
160 | |
161 | |
162 | /*! \brief Get the neighborhood iterator based on type |
163 | * |
164 | * specialization for the case with NN CRS symmetric |
165 | * |
166 | * \tparam dim dimensionality |
167 | * \tparam T type of space |
168 | * \tparam CellListImpl Cell-list implementation |
169 | * \tparam PartIt Particle iterator |
170 | * |
171 | */ |
172 | template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, typename local_index> |
173 | struct NNType<dim,T,CellListImpl,PartIt,VL_CRS_SYMMETRIC,local_index> |
174 | { |
175 | /*! \brief Get the neighborhood |
176 | * |
177 | * \param it particle iterator |
178 | * \param v vector of the particles positions |
179 | * \param xp Position of the particle p |
180 | * \param p id of the particle p |
181 | * \param cl Cell-list type implementation |
182 | * \param r_cut Cutoff radius |
183 | * |
184 | * \return the NN iterator |
185 | * |
186 | */ |
187 | template<typename vector_pos_type> |
188 | static inline auto get(const PartIt & it, |
189 | const vector_pos_type & v, |
190 | Point<dim,T> & xp, |
191 | size_t p, |
192 | CellListImpl & cl, |
193 | T r_cut) -> decltype(it.getNNIteratorCSR(v)) |
194 | { |
195 | return it.getNNIteratorCSR(v); |
196 | } |
197 | |
198 | |
199 | /*! \brief Add particle in the list of the domain particles |
200 | * |
201 | * \param p particle id |
202 | * \param pc domain particle sequence |
203 | * |
204 | */ |
205 | static inline void add(local_index p, openfpm::vector<local_index> & pc) |
206 | { |
207 | pc.add(p); |
208 | } |
209 | }; |
210 | |
211 | /*! \brief In general different NN scheme like full symmetric or CRS require different |
212 | * iterators over particles this class select the proper one |
213 | * |
214 | * This is the full or symmetric case |
215 | * |
216 | */ |
217 | template<unsigned int type, unsigned int dim, typename vector, typename CellList> |
218 | class PartItNN |
219 | { |
220 | public: |
221 | |
222 | /*! \brief It return the particle iterator |
223 | * |
224 | * \param pos vector with position of the particles |
225 | * \param dom list of cells with normal neighborhood |
226 | * \param anom list of cells with not-normal neighborhood |
227 | * \param cli Cell-list used for Verlet-list construction |
228 | * \param g_m ghost marker |
229 | * \param end final particle id |
230 | * |
231 | * \return the particle iterator |
232 | * |
233 | */ |
234 | static inline auto get(const vector & pos, const openfpm::vector<size_t> & dom, const openfpm::vector<subsub_lin<dim>> & anom, CellList & cli, size_t g_m, size_t & end) -> decltype(pos.getIteratorTo(0)) |
235 | { |
236 | end = g_m; |
237 | return pos.getIteratorTo(end); |
238 | } |
239 | }; |
240 | |
241 | /*! \brief In general different NN scheme like full symmetric or CRS require different |
242 | * iterators over particles this class select the proper one |
243 | * |
244 | * This is the CRS scheme |
245 | * |
246 | */ |
247 | template<unsigned int dim, typename vector, typename CellList> |
248 | class PartItNN<VL_CRS_SYMMETRIC,dim,vector,CellList> |
249 | { |
250 | public: |
251 | |
252 | /*! \brief It return the particle iterator |
253 | * |
254 | * \param pos vector with position of the particles |
255 | * \param dom list of cells with normal neighborhood |
256 | * \param anom list of cells with not-normal neighborhood |
257 | * \param cli Cell-list used for Verlet-list construction |
258 | * \param g_m ghost marker |
259 | * \param end final particle id |
260 | * |
261 | * \return the particle iterator |
262 | * |
263 | */ |
264 | static inline ParticleItCRS_Cells<dim,CellList,vector> get(const vector & pos, const openfpm::vector<size_t> & dom, const openfpm::vector<subsub_lin<dim>> & anom, CellList & cli, size_t g_m, size_t & end) |
265 | { |
266 | end = pos.size(); |
267 | return ParticleItCRS_Cells<dim,CellList,vector>(cli,dom,anom,cli.getNNc_sym()); |
268 | } |
269 | }; |
270 | |
271 | /*! \brief Class for Verlet list implementation |
272 | * |
273 | * * M = number of particles |
274 | * * N_nn_max = maximum number of neighborhood |
275 | * * ele = element the structure is storing |
276 | * |
277 | * \tparam dim Dimensionality of the space |
278 | * \tparam T type of the space float, double ... |
279 | * \tparam base Base structure that store the information |
280 | * |
281 | * ### Declaration of a Verlet list [VerS == VerletList<3,double,FAST>] |
282 | * \snippet VerletList_test.hpp create verlet |
283 | * ### Declaration of a Verlet list from external Cell-list [VerS == CellList<3,double,FAST>] |
284 | * \snippet VerletList_test.hpp Fill external cell list |
285 | * \snippet VerletList_test.hpp create verlet cell |
286 | * ### Usage of Verlet-list |
287 | * \snippet VerletList_test.hpp usage of verlet |
288 | * |
289 | */ |
290 | template<unsigned int dim, |
291 | typename T, |
292 | typename Mem_type = Mem_fast<HeapMemory,local_index_>, |
293 | typename transform = no_transform<dim,T>, |
294 | typename vector_pos_type = openfpm::vector<Point<dim,T>>, |
295 | typename CellListImpl = CellList<dim,T,Mem_fast<HeapMemory,typename Mem_type::local_index_type>,transform,vector_pos_type> > |
296 | class VerletList: public Mem_type |
297 | { |
298 | protected: |
299 | |
300 | //! Number of slot for each particle. Or maximum number of particles for each particle |
301 | typename Mem_type::local_index_type slot; |
302 | |
303 | //! Domain particles |
304 | openfpm::vector<typename Mem_type::local_index_type> dp; |
305 | |
306 | private: |
307 | |
308 | //! decomposition counter |
309 | size_t n_dec; |
310 | |
311 | //! Interlal cell-list |
312 | CellListImpl cli; |
313 | |
314 | |
315 | /*! \brief Fill the cell-list with data |
316 | * |
317 | * \param cli Cell-list |
318 | * \param pos vector of positions |
319 | * \param g_m marker |
320 | * \param opt VL_SYMMETRIC or VL_NON_SYMMETRIC |
321 | * |
322 | */ |
323 | void initCl(CellListImpl & cli, vector_pos_type & pos, size_t g_m, size_t opt) |
324 | { |
325 | mgpu::ofp_context_t context(mgpu::gpu_context_opt::dummy); |
326 | if (opt & VL_SYMMETRIC || opt & VL_CRS_SYMMETRIC) |
327 | {populate_cell_list(pos,cli,context,g_m,CL_SYMMETRIC,cl_construct_opt::Full);} |
328 | else |
329 | {populate_cell_list(pos,cli,context,g_m,CL_NON_SYMMETRIC,cl_construct_opt::Full);} |
330 | } |
331 | |
332 | /*! \brief Create the Verlet list from a given cell-list |
333 | * |
334 | * \param pos vector of positions |
335 | * \param pos2 vector of positions of neighborhood particles |
336 | * \param r_cut cut-off radius to get the neighborhood particles |
337 | * \param g_m Indicate form which particles to construct the verlet list. For example |
338 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
339 | * 100 particles |
340 | * \param cl Cell-list elements to use to construct the verlet list |
341 | * \param opt options to create the verlet list like VL_SYMMETRIC or VL_NON_SYMMETRIC |
342 | * |
343 | */ |
344 | inline void create(const vector_pos_type & pos, const vector_pos_type & pos2, const openfpm::vector<size_t> & dom, const openfpm::vector<subsub_lin<dim>> & anom, T r_cut, size_t g_m, CellListImpl & cl, size_t opt) |
345 | { |
346 | if (opt == VL_CRS_SYMMETRIC) |
347 | { |
348 | create_<CellNNIteratorSym<dim,CellListImpl,vector_pos_type,RUNTIME,NO_CHECK>,VL_CRS_SYMMETRIC>(pos,pos2,dom,anom,r_cut,g_m,cl,opt); |
349 | } |
350 | else if (opt == VL_SYMMETRIC) |
351 | { |
352 | create_<decltype(cl.template getNNIteratorSym<NO_CHECK>(0,0,pos)),VL_SYMMETRIC>(pos,pos2,dom,anom,r_cut,g_m,cl,opt); |
353 | } |
354 | else |
355 | { |
356 | create_<decltype(cl.template getNNIterator<NO_CHECK>(0)),VL_NON_SYMMETRIC>(pos,pos2,dom,anom,r_cut,g_m,cl,opt); |
357 | } |
358 | } |
359 | |
360 | /*! \brief Create the Verlet list from a given cell-list |
361 | * |
362 | * \param pos vector of positions |
363 | * \param pos2 vector of position for the neighborhood |
364 | * \param r_cut cut-off radius to get the neighborhood particles |
365 | * \param g_m Indicate form which particles to construct the verlet list. For example |
366 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
367 | * 100 particles |
368 | * \param cli Cell-list elements to use to construct the verlet list |
369 | * \param dom list of domain cells with normal neighborhood |
370 | * \param anom list of domain cells with non-normal neighborhood |
371 | * \param opt options |
372 | * |
373 | */ |
374 | template<typename NN_type, int type> inline void create_(const vector_pos_type & pos, const vector_pos_type & pos2 , const openfpm::vector<size_t> & dom, const openfpm::vector<subsub_lin<dim>> & anom, T r_cut, size_t g_m, CellListImpl & cli, size_t opt) |
375 | { |
376 | size_t end; |
377 | |
378 | auto it = PartItNN<type,dim,vector_pos_type,CellListImpl>::get(pos,dom,anom,cli,g_m,end); |
379 | |
380 | Mem_type::init_to_zero(slot,end); |
381 | |
382 | dp.clear(); |
383 | |
384 | // square of the cutting radius |
385 | T r_cut2 = r_cut * r_cut; |
386 | |
387 | // iterate the particles |
388 | while (it.isNext()) |
389 | { |
390 | typename Mem_type::local_index_type i = it.get(); |
391 | Point<dim,T> xp = pos.template get<0>(i); |
392 | |
393 | // Get the neighborhood of the particle |
394 | auto NN = NNType<dim,T,CellListImpl,decltype(it),type,typename Mem_type::local_index_type>::get(it,pos,xp,i,cli,r_cut); |
395 | NNType<dim,T,CellListImpl,decltype(it),type,typename Mem_type::local_index_type>::add(i,dp); |
396 | |
397 | while (NN.isNext()) |
398 | { |
399 | auto nnp = NN.get(); |
400 | |
401 | Point<dim,T> xq = pos2.template get<0>(nnp); |
402 | |
403 | if (xp.distance2(xq) < r_cut2) |
404 | addPart(i,nnp); |
405 | |
406 | // Next particle |
407 | ++NN; |
408 | } |
409 | |
410 | ++it; |
411 | } |
412 | } |
413 | |
414 | /*! \brief Create the Verlet list from a given cell-list with a particular cut-off radius |
415 | * |
416 | * \param pos vector of positions of particles |
417 | * \param r_cut cut-off radius to get the neighborhood particles |
418 | * \param g_m Indicate form which particles to construct the verlet list. For example |
419 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
420 | * 100 particles |
421 | * \param cl Cell-list elements to use to construct the verlet list |
422 | * |
423 | */ |
424 | inline void createR(openfpm::vector<Point<dim,T>> & pos, T r_cut, size_t g_m, CellListImpl & cl) |
425 | { |
426 | |
427 | Mem_type::init_to_zero(slot,g_m); |
428 | |
429 | // square of the cutting radius |
430 | T r_cut2 = r_cut * r_cut; |
431 | |
432 | // iterate the particles |
433 | for (size_t i = 0 ; i < g_m ; i++) |
434 | { |
435 | Point<dim,T> p = pos.template get<0>(i); |
436 | |
437 | // Get the neighborhood of the particle |
438 | auto NN = cl.template getNNIteratorRadius<NO_CHECK>(cl.getCell(p),r_cut); |
439 | while (NN.isNext()) |
440 | { |
441 | auto nnp = NN.get(); |
442 | |
443 | Point<dim,T> q = pos.template get<0>(nnp); |
444 | |
445 | if (p.distance2(q) < r_cut2) |
446 | addPart(i,nnp); |
447 | |
448 | // Next particle |
449 | ++NN; |
450 | } |
451 | } |
452 | } |
453 | |
454 | public: |
455 | |
456 | //! type for the local index |
457 | typedef Mem_type Mem_type_type; |
458 | |
459 | //! Object type that the structure store |
460 | typedef size_t value_type; |
461 | |
462 | //! CellList implementation used for Verlet list construction |
463 | typedef CellListImpl CellListImpl_; |
464 | |
465 | /*! \brief Return for how many particles has been constructed this verlet list |
466 | * |
467 | * \return number of particles |
468 | * |
469 | */ |
470 | size_t size() |
471 | { |
472 | return Mem_type::size(); |
473 | } |
474 | |
475 | /*! \brief Add a neighborhood particle to a particle |
476 | * |
477 | * \param part_id part id where to add |
478 | * \param ele element to add |
479 | * |
480 | */ |
481 | inline void addPart(size_t part_id, size_t ele) |
482 | { |
483 | Mem_type::addCell(part_id,ele); |
484 | } |
485 | |
486 | /*! Initialize the verlet list |
487 | * |
488 | * \param box Domain where this cell list is living |
489 | * \param dom Processor domain |
490 | * \param r_cut cut-off radius |
491 | * \param pos vector of particle positions |
492 | * \param g_m Indicate form which particles to construct the verlet list. For example |
493 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
494 | * 100 particles |
495 | * \param opt option to generate Verlet list |
496 | * |
497 | */ |
498 | void Initialize(const Box<dim,T> & box, const Box<dim,T> & dom, T r_cut, vector_pos_type & pos, size_t g_m, size_t opt = VL_NON_SYMMETRIC) |
499 | { |
500 | // Number of divisions |
501 | size_t div[dim]; |
502 | |
503 | Box<dim,T> bt = box; |
504 | |
505 | // Calculate the divisions for the Cell-lists |
506 | cl_param_calculate(bt,div,r_cut,Ghost<dim,T>(0.0)); |
507 | |
508 | // Initialize a cell-list |
509 | cli.Initialize(bt,div); |
510 | |
511 | initCl(cli,pos,g_m,opt); |
512 | |
513 | // Unuseful empty vector |
514 | openfpm::vector<subsub_lin<dim>> anom_c; |
515 | openfpm::vector<size_t> dom_c; |
516 | |
517 | // create verlet |
518 | create(pos, pos,dom_c,anom_c,r_cut,g_m,cli,opt); |
519 | } |
520 | |
521 | /*! \brief Initialize the symmetric Verlet-list |
522 | * |
523 | * \param box Simulation domain |
524 | * \param dom Processor domain |
525 | * \param g ghost size |
526 | * \param r_cut cut-off radius |
527 | * \param pos vector of particle positions |
528 | * \param g_m Indicate form which particles to construct the verlet list. For example |
529 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
530 | * 100 particles |
531 | * |
532 | */ |
533 | void InitializeSym(const Box<dim,T> & box, const Box<dim,T> & dom, const Ghost<dim,T> & g, T r_cut, openfpm::vector<Point<dim,T>> & pos, size_t g_m) |
534 | { |
535 | // Padding |
536 | size_t pad = 0; |
537 | |
538 | // Cell decomposer |
539 | CellDecomposer_sm<dim,T,shift<dim,T>> cd_sm; |
540 | |
541 | // Calculate the divisions for the Cell-lists |
542 | cl_param_calculateSym<dim,T>(box,cd_sm,g,r_cut,pad); |
543 | |
544 | // Initialize a cell-list |
545 | cli.Initialize(cd_sm,dom,pad); |
546 | initCl(cli,pos,g_m,VL_SYMMETRIC); |
547 | |
548 | // Unused |
549 | openfpm::vector<subsub_lin<dim>> anom_c; |
550 | openfpm::vector<size_t> dom_c; |
551 | |
552 | // create verlet |
553 | create(pos, pos,dom_c,anom_c,r_cut,g_m,cli,VL_SYMMETRIC); |
554 | } |
555 | |
556 | |
557 | /*! \brief Initialize the symmetric Verlet-list CRS scheme |
558 | * |
559 | * \param box Simulation domain |
560 | * \param dom Processor domain |
561 | * \param g ghost size |
562 | * \param r_cut cut-off radius |
563 | * \param pos vector of particle positions |
564 | * \param g_m Indicate form which particles to construct the verlet list. For example |
565 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
566 | * 100 particles |
567 | * |
568 | */ |
569 | void InitializeCrs(const Box<dim,T> & box, const Box<dim,T> & dom, const Ghost<dim,T> & g, T r_cut, openfpm::vector<Point<dim,T>> & pos, size_t g_m) |
570 | { |
571 | // Padding |
572 | size_t pad = 0; |
573 | |
574 | // Cell decomposer |
575 | CellDecomposer_sm<dim,T,shift<dim,T>> cd_sm; |
576 | |
577 | // Calculate the divisions for the Cell-lists |
578 | cl_param_calculateSym<dim,T>(box,cd_sm,g,r_cut,pad); |
579 | |
580 | // Initialize a cell-list |
581 | cli.Initialize(cd_sm,dom,pad); |
582 | initCl(cli,pos,g_m,VL_SYMMETRIC); |
583 | } |
584 | |
585 | /*! \brief Create the Verlet-list with the crossing scheme |
586 | * |
587 | * \param pos vector with the particle positions |
588 | * \param g_m ghost marker |
589 | * \param pos vector with the particle positions |
590 | * \param r_cut cut-off radius |
591 | * \param dom_c domain cells |
592 | * \param anom_c cells with anomalos neighborhood |
593 | * |
594 | */ |
595 | void createVerletCrs(T r_cut, size_t g_m, openfpm::vector<Point<dim,T>> & pos, openfpm::vector<size_t> & dom_c, openfpm::vector<subsub_lin<dim>> & anom_c) |
596 | { |
597 | // create verlet |
598 | create(pos, pos,dom_c,anom_c,r_cut,g_m,cli,VL_CRS_SYMMETRIC); |
599 | } |
600 | |
601 | /*! \brief update the Verlet list |
602 | * |
603 | * \param r_cut cutoff radius |
604 | * \param dom Processor domain |
605 | * \param pos vector of particle positions |
606 | * \param g_m ghost marker |
607 | * \param opt option to create the Verlet list |
608 | * |
609 | */ |
610 | void update(const Box<dim,T> & dom, T r_cut, openfpm::vector<Point<dim,T>> & pos, size_t & g_m, size_t opt) |
611 | { |
612 | initCl(cli,pos,g_m,opt); |
613 | |
614 | // Unused |
615 | openfpm::vector<subsub_lin<dim>> anom_c; |
616 | openfpm::vector<size_t> dom_c; |
617 | |
618 | create(pos, pos,dom_c,anom_c,r_cut,g_m,cli,opt); |
619 | } |
620 | |
621 | /*! \brief update the Verlet list |
622 | * |
623 | * \param r_cut cutoff radius |
624 | * \param dom Processor domain |
625 | * \param pos vector of particle positions |
626 | * \param g_m ghost marker |
627 | * \param dom_c list of cells with normal neighborhood |
628 | * \param anom_c list of cells with anormal neighborhood |
629 | * |
630 | */ |
631 | void updateCrs(const Box<dim,T> & dom, T r_cut, openfpm::vector<Point<dim,T>> & pos, size_t & g_m, const openfpm::vector<size_t> & dom_c, const openfpm::vector<subsub_lin<dim>> & anom_c) |
632 | { |
633 | initCl(cli,pos,g_m,VL_CRS_SYMMETRIC); |
634 | |
635 | create(pos,pos,dom_c,anom_c,r_cut,g_m,cli,VL_CRS_SYMMETRIC); |
636 | } |
637 | |
638 | /*! Initialize the verlet list from an already filled cell-list |
639 | * |
640 | * \param cli external Cell-list |
641 | * \param r_cut cutoff-radius |
642 | * \param pos vector of particle positions |
643 | * \param pos2 vector of particle position for the neighborhood |
644 | * \param g_m Indicate form which particles to construct the verlet list. For example |
645 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
646 | * 100 particles |
647 | * \param opt options for the Verlet-list creation |
648 | * |
649 | */ |
650 | void Initialize(CellListImpl & cli, |
651 | T r_cut, |
652 | const vector_pos_type & pos, |
653 | const vector_pos_type & pos2, |
654 | size_t g_m, size_t opt = VL_NON_SYMMETRIC) |
655 | { |
656 | Point<dim,T> spacing = cli.getCellBox().getP2(); |
657 | |
658 | // Create with radius or not |
659 | bool wr = true; |
660 | |
661 | for (size_t i = 0 ; i < dim ; i++) |
662 | wr &= r_cut <= spacing.get(i); |
663 | |
664 | if (wr == true || opt == VL_SYMMETRIC) |
665 | { |
666 | openfpm::vector<subsub_lin<dim>> anom_c; |
667 | openfpm::vector<size_t> dom_c; |
668 | |
669 | create(pos,pos2,dom_c,anom_c,r_cut,g_m,cli,opt); |
670 | } |
671 | else |
672 | { |
673 | openfpm::vector<subsub_lin<dim>> anom_c; |
674 | openfpm::vector<size_t> dom_c; |
675 | |
676 | create_<decltype(cli.template getNNIteratorRadius<NO_CHECK>(0,0.0)),WITH_RADIUS>(pos,pos2,dom_c,anom_c,r_cut,g_m,cli,VL_NON_SYMMETRIC); |
677 | } |
678 | } |
679 | |
680 | //! Default Constructor |
681 | VerletList() |
682 | :Mem_type(VERLET_STARTING_NSLOT),slot(VERLET_STARTING_NSLOT),n_dec(0) |
683 | {}; |
684 | |
685 | //! Copy constructor |
686 | VerletList(const VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl> & cell) |
687 | :Mem_type(VERLET_STARTING_NSLOT),slot(VERLET_STARTING_NSLOT) |
688 | { |
689 | this->operator=(cell); |
690 | } |
691 | |
692 | //! Copy constructor |
693 | VerletList(VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl> && cell) |
694 | :Mem_type(VERLET_STARTING_NSLOT),slot(VERLET_STARTING_NSLOT),n_dec(0) |
695 | { |
696 | this->operator=(cell); |
697 | } |
698 | |
699 | |
700 | /*! \brief Verlet-list constructor |
701 | * |
702 | * \param box Domain where this verlet-list is living |
703 | * \param r_cut cutoff radius |
704 | * \param mat Matrix transformation |
705 | * \param pad padding for the internal Cell-list padding |
706 | * \param slot maximum number of slots or maximum number of neighborhood per particle |
707 | * |
708 | */ |
709 | VerletList(Box<dim,T> & box, T r_cut, Matrix<dim,T> mat, const size_t pad = 1, size_t slot=STARTING_NSLOT) |
710 | :slot(VERLET_STARTING_NSLOT),CellDecomposer_sm<dim,T,transform>(box,div,mat,box.getP1(),pad) |
711 | { |
712 | SpaceBox<dim,T> sbox(box); |
713 | Initialize(sbox,r_cut,pad,slot); |
714 | } |
715 | |
716 | /*! \brief Verlet-list constructor |
717 | * |
718 | * \param box Domain where this cell list is living |
719 | * \param r_cut cut-off radius |
720 | * \param pos vector position of particles |
721 | * \param g_m Indicate form which particles to construct the verlet list. For example |
722 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
723 | * 100 particles |
724 | * \param slot maximum number of slots (or maximum number each particle can have) |
725 | * |
726 | * \note the maximum number of particle per slot if just an indication for performance |
727 | * |
728 | */ |
729 | VerletList(Box<dim,T> & box, T r_cut, openfpm::vector<Point<dim,T>> & pos, size_t g_m, size_t slot=VERLET_STARTING_NSLOT) |
730 | :slot(slot) |
731 | { |
732 | SpaceBox<dim,T> sbox(box); |
733 | Initialize(sbox,r_cut,pos,g_m); |
734 | } |
735 | |
736 | /*! \brief Cell list constructor |
737 | * |
738 | * \param box Domain where this cell list is living |
739 | * \param dom Simulation domain |
740 | * \param r_cut cut-off radius |
741 | * \param pos vector position of particles |
742 | * \param g_m Indicate form which particles to construct the verlet list. For example |
743 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
744 | * 100 particles |
745 | * \param slot maximum number of slots (or maximum number each particle can have) |
746 | * |
747 | * \note the maximum number of particle per slot if just an indication for performance |
748 | * |
749 | */ |
750 | VerletList(SpaceBox<dim,T> & box, Box<dim,T> & dom, T r_cut, openfpm::vector<Point<dim,T>> & pos, size_t g_m, size_t slot=VERLET_STARTING_NSLOT) |
751 | :slot(slot) |
752 | { |
753 | Initialize(box,r_cut,pos); |
754 | } |
755 | |
756 | /*! \brief Destructor |
757 | * |
758 | * |
759 | */ |
760 | ~VerletList() |
761 | {} |
762 | |
763 | /*! \brief Copy the verlet list |
764 | * |
765 | * \param vl verlet list to copy |
766 | * |
767 | * \return itself |
768 | * |
769 | */ |
770 | VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl> & |
771 | operator=(VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl> && vl) |
772 | { |
773 | slot = vl.slot; |
774 | |
775 | Mem_type::operator=(vl); |
776 | dp.swap(vl.dp); |
777 | |
778 | n_dec = vl.n_dec; |
779 | |
780 | return *this; |
781 | } |
782 | |
783 | /*! \brief Copy a verlet list |
784 | * |
785 | * \param vl verlet-list to copy |
786 | * |
787 | * \return itself |
788 | * |
789 | */ |
790 | VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl> & |
791 | operator=(const VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl> & vl) |
792 | { |
793 | slot = vl.slot; |
794 | |
795 | Mem_type::operator=(vl); |
796 | |
797 | cli = vl.cli; |
798 | |
799 | dp = vl.dp; |
800 | n_dec = vl.n_dec; |
801 | |
802 | return *this; |
803 | } |
804 | |
805 | /*! \brief Return the number of neighborhood particles for the particle id |
806 | * |
807 | * \param part_id id of the particle |
808 | * |
809 | * \return number of neighborhood particles for a particular particle id |
810 | * |
811 | */ |
812 | inline size_t getNNPart(size_t part_id) const |
813 | { |
814 | return Mem_type::getNelements(part_id); |
815 | } |
816 | |
817 | /*! \brief Get the neighborhood element j for the particle i |
818 | * |
819 | * \param i particle id |
820 | * \param j neighborhood j |
821 | * |
822 | * \return The element value |
823 | * |
824 | */ |
825 | inline size_t get(size_t i, size_t j) const |
826 | { |
827 | return Mem_type::get(i,j); |
828 | } |
829 | |
830 | /*! \brief Swap the memory |
831 | * |
832 | * \param vl Verlet list with witch you swap the memory |
833 | * |
834 | */ |
835 | inline void swap(VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl> & vl) |
836 | { |
837 | Mem_type::swap(vl); |
838 | dp.swap(vl.dp); |
839 | |
840 | size_t vl_slot_tmp = vl.slot; |
841 | vl.slot = slot; |
842 | slot = vl_slot_tmp; |
843 | |
844 | cli.swap(vl.cli); |
845 | |
846 | size_t n_dec_tmp = vl.n_dec; |
847 | vl.n_dec = n_dec; |
848 | n_dec = n_dec_tmp; |
849 | } |
850 | |
851 | /*! \brief Get the Neighborhood iterator |
852 | * |
853 | * It iterate across all the neighborhood particles of a selected particle |
854 | * |
855 | * \param part_id particle id |
856 | * |
857 | * \return an interator across the neighborhood particles |
858 | * |
859 | */ |
860 | template<unsigned int impl=NO_CHECK> |
861 | inline VerletNNIterator<dim,VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl>> |
862 | getNNIterator(size_t part_id) |
863 | { |
864 | VerletNNIterator<dim,VerletList<dim,T,Mem_type,transform,vector_pos_type,CellListImpl>> vln(part_id,*this); |
865 | |
866 | return vln; |
867 | } |
868 | |
869 | /*! \brief Clear the cell list |
870 | * |
871 | */ |
872 | void clear() |
873 | { |
874 | Mem_type::clear(); |
875 | } |
876 | |
877 | /*! \brief Return the starting point of the neighborhood for the particle p |
878 | * |
879 | * \param part_id particle id |
880 | * |
881 | * \return the index |
882 | * |
883 | */ |
884 | inline const typename Mem_type::local_index_type & |
885 | getStart(typename Mem_type::local_index_type part_id) |
886 | { |
887 | return Mem_type::getStartId(part_id); |
888 | } |
889 | |
890 | /*! \brief Return the end point of the neighborhood for the particle p |
891 | * |
892 | * \param part_id particle id |
893 | * |
894 | * \return the stop index |
895 | * |
896 | */ |
897 | inline const typename Mem_type::local_index_type & |
898 | getStop(typename Mem_type::local_index_type part_id) |
899 | { |
900 | return Mem_type::getStopId(part_id); |
901 | } |
902 | |
903 | /*! \brief Return the neighborhood id |
904 | * |
905 | * \param part_id particle id |
906 | * |
907 | * \return the neighborhood id |
908 | * |
909 | */ |
910 | inline const typename Mem_type::local_index_type & |
911 | get_lin(const typename Mem_type::local_index_type * part_id) |
912 | { |
913 | return Mem_type::get_lin(part_id); |
914 | } |
915 | |
916 | /*! \brief Get the internal cell-list used to construct the Verlet-list |
917 | * |
918 | * \return the internal Cell-list |
919 | * |
920 | */ |
921 | CellListImpl & getInternalCellList() |
922 | { |
923 | return cli; |
924 | } |
925 | |
926 | /*! \brief Set the n_dec number |
927 | * |
928 | * \param n_dec |
929 | * |
930 | */ |
931 | void set_ndec(size_t n_dec) |
932 | { |
933 | this->n_dec = n_dec; |
934 | |
935 | cli.set_ndec(n_dec); |
936 | } |
937 | |
938 | /*! \brief Set the n_dec number |
939 | * |
940 | * \return n_dec |
941 | * |
942 | */ |
943 | size_t get_ndec() |
944 | { |
945 | return n_dec; |
946 | } |
947 | |
948 | /*! \brief Return the domain particle sequence |
949 | * |
950 | * \return the particle sequence |
951 | * |
952 | */ |
953 | openfpm::vector<typename Mem_type::local_index_type> & getParticleSeq() |
954 | { |
955 | return dp; |
956 | } |
957 | }; |
958 | |
959 | |
960 | |
961 | #endif /* OPENFPM_DATA_SRC_NN_VERLETLIST_VERLETLISTFAST_HPP_ */ |
962 | |