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 */
31template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, int type, typename local_index>
32struct 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 */
78template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, typename local_index>
79struct 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 */
125template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, typename local_index>
126struct 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 */
172template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, typename local_index>
173struct 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 */
217template<unsigned int type, unsigned int dim, typename vector, typename CellList>
218class PartItNN
219{
220public:
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 */
247template<unsigned int dim, typename vector, typename CellList>
248class PartItNN<VL_CRS_SYMMETRIC,dim,vector,CellList>
249{
250public:
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 */
290template<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> >
296class VerletList: public Mem_type
297{
298protected:
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
306private:
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
454public:
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