OpenFPM_data  0.1.0
Project that contain the implementation and interfaces for basic structure like vectors, grids, graph ... .
 All Data Structures Namespaces Functions Variables Typedefs Friends
CellListFast.hpp
1 /*
2  * CellListStandard.hpp
3  *
4  * Created on: Mar 22, 2015
5  * Author: Pietro Incardona
6  */
7 
8 #ifndef CELLLISTSTANDARD_HPP_
9 #define CELLLISTSTANDARD_HPP_
10 
11 #include "CellDecomposer.hpp"
12 #include "Space/SpaceBox.hpp"
13 #include "util/mathutil.hpp"
14 #include "CellNNIterator.hpp"
15 #include "Space/Shape/HyperCube.hpp"
16 
17 #include "util/common.hpp"
18 
66 template<unsigned int dim, typename T, typename transform, typename base>
67 class CellList<dim,T,FAST,transform,base> : public CellDecomposer_sm<dim,T,transform>
68 {
69  // The array contain the neighborhood of the cell-id in case of asymmetric interaction
70  //
71  // * * *
72  // * x *
73  // * * *
74 
75  long int NNc_full[openfpm::math::pow(3,dim)];
76 
77  // The array contain the neighborhood of the cell-id in case of symmetric interaction
78  //
79  // * * *
80  // x *
81  //
82  long int NNc_sym[openfpm::math::pow(3,dim)/2+1];
83 
84  // The array contain the neighborhood of the cell-id in case of symmetric interaction (Optimized)
85  //
86  // * *
87  // x *
88  //
89  long int NNc_cr[openfpm::math::pow(2,dim)];
90 
91  // Number of slot for each cell
92  size_t slot;
93 
94  // number of particle in each cell list
96 
97  // elements that each cell store (each cell can store a number
98  // of elements == slot )
99  base cl_base;
100 
101  //Origin point
102  Point<dim,T> orig;
103 
104  void realloc()
105  {
106  // we do not have enough slots reallocate the basic structure with more
107  // slots
108  base cl_base_(2*slot * cl_n.size());
109 
110  // copy cl_base
111  for (size_t i = 0 ; i < cl_n.size() ; i++)
112  {
113  for (size_t j = 0 ; j < cl_n.get(i) ; j++)
114  cl_base_.get(2*i*slot + j) = cl_base.get(slot * i + j);
115  }
116 
117  // Double the number of slots
118  slot *= 2;
119 
120  // swap the memory
121  cl_base.swap(cl_base_);
122  }
123 
124 public:
125 
126  // Object type that the structure store
127  typedef T value_type;
128 
135  {
136  return CellDecomposer_sm<dim,T,transform>::getGrid();
137  }
138 
148  void Initialize(const Box<dim,T> & box, const size_t (&div)[dim], const Point<dim,T> & orig, const size_t pad = 1, size_t slot=16)
149  {
150  SpaceBox<dim,T> sbox(box);
151 
152  // Initialize point transformation
153 
154  Initialize(sbox,div,orig,pad,slot);
155  }
156 
165  void Initialize(SpaceBox<dim,T> & box, const size_t (&div)[dim], const Point<dim,T> & orig , const size_t pad = 1, size_t slot=16)
166  {
167  Matrix<dim,T> mat;
168 
169  CellDecomposer_sm<dim,T,transform>::setDimensions(box,div, mat, orig, pad);
170  this->slot = slot;
171  this->orig = orig;
172 
173  // create the array that store the number of particle on each cell and se it to 0
174 
175  cl_n.resize(this->tot_n_cell);
176  cl_n.fill(0);
177 
178  // create the array that store the cell id
179 
180  cl_base.resize(this->tot_n_cell * slot);
181 
182  // Calculate the NNc_full array, it is a structure to get the neighborhood array
183 
184  // compile-time array {0,0,0,....} {2,2,2,...} {1,1,1,...}
185 
186  typedef typename generate_array<size_t,dim, Fill_zero>::result NNzero;
187  typedef typename generate_array<size_t,dim, Fill_two>::result NNtwo;
188  typedef typename generate_array<size_t,dim, Fill_one>::result NNone;
189 
190  // Generate the sub-grid iterator
191 
192  grid_key_dx_iterator_sub<dim> gr_sub3(this->gr_cell,NNzero::data,NNtwo::data);
193 
194  // Calculate the NNc array
195 
196  size_t middle = this->gr_cell.LinId(NNone::data);
197  size_t i = 0;
198  while (gr_sub3.isNext())
199  {
200  NNc_full[i] = (long int)this->gr_cell.LinId(gr_sub3.get()) - middle;
201 
202  ++gr_sub3;
203  i++;
204  }
205 
206  // Calculate the NNc_sym array
207 
208  i = 0;
209  gr_sub3.reset();
210  while (gr_sub3.isNext())
211  {
212  auto key = gr_sub3.get();
213 
214  size_t lin = this->gr_cell.LinId(key);
215 
216  // Only the first half is considered
217  if (lin < middle)
218  {
219  ++gr_sub3;
220  continue;
221  }
222 
223  NNc_sym[i] = lin - middle;
224 
225  ++gr_sub3;
226  i++;
227  }
228 
229  // Calculate the NNc_cross array
230 
231  i = 0;
232  grid_key_dx_iterator_sub<dim> gr_sub2(this->gr_cell,NNzero::data,NNone::data);
233 
234  while (gr_sub2.isNext())
235  {
236  auto key = gr_sub2.get();
237 
238  NNc_cr[i] = (long int)this->gr_cell.LinId(key);
239 
240  ++gr_sub2;
241  i++;
242  }
243  }
244 
247  :slot(16)
248  {};
249 
252  {
253  this->operator=(cell);
254  }
255 
258  {
259  this->operator=(cell);
260  }
261 
268  {
269  std::copy(&cell.NNc_full[0],&cell.NNc_full[openfpm::math::pow(3,dim)],&NNc_full[0]);
270  std::copy(&cell.NNc_sym[0],&cell.NNc_sym[openfpm::math::pow(3,dim)/2+1],&NNc_sym[0]);
271  std::copy(&cell.NNc_cr[0],&cell.NNc_cr[openfpm::math::pow(2,dim)],&NNc_cr[0]);
272 
273  size_t tslot = slot;
274  slot = cell.slot;
275  cell.slot = tslot;
276 
277  cl_n.swap(cell.cl_n);
278  cl_base.swap(cell.cl_base);
279 
280  Point<dim,T> torig = orig;
281  orig = cell.orig;
282  cell.orig = torig;
283 
284  return this;
285  }
286 
293  {
294  std::copy(&cell.NNc_full[0],&cell.NNc_full[openfpm::math::pow(3,dim)],&NNc_full[0]);
295  std::copy(&cell.NNc_sym[0],&cell.NNc_sym[openfpm::math::pow(3,dim)/2+1],&NNc_sym[0]);
296  std::copy(&cell.NNc_cr[0],&cell.NNc_cr[openfpm::math::pow(2,dim)],&NNc_cr[0]);
297 
298  slot = cell.slot;
299 
300  cl_n = cell.cl_n;
301  cl_base = cell.cl_base;
302 
303  orig = cell.orig;
304 
305  return *this;
306  }
307 
318  CellList(Box<dim,T> & box, const size_t (&div)[dim], Matrix<dim,T> mat, Point<dim,T> & orig, const size_t pad = 1, size_t slot=16)
319  :CellDecomposer_sm<dim,T,transform>(box,div,mat,orig,pad)
320  {
321  SpaceBox<dim,T> sbox(box);
322  Initialize(sbox,div,orig,pad,slot);
323  }
324 
334  CellList(Box<dim,T> & box, const size_t (&div)[dim], Point<dim,T> & orig, const size_t pad = 1, size_t slot=16)
335  {
336  SpaceBox<dim,T> sbox(box);
337  Initialize(sbox,div,orig,pad,slot);
338  }
339 
349  CellList(SpaceBox<dim,T> & box, const size_t (&div)[dim], Point<dim,T> & orig, const size_t pad = 1, size_t slot=16)
350  {
351  Initialize(box,div,orig,pad,slot);
352  }
353 
354 
361  inline void addCell(size_t cell_id, typename base::value_type ele)
362  {
363  // Get the number of element the cell is storing
364 
365  size_t nl = getNelements(cell_id);
366 
367  if (nl + 1 >= slot)
368  {
369  realloc();
370  }
371 
372  // we have enough slot to store another neighbor element
373 
374  cl_base.get(slot * cell_id + cl_n.get(cell_id)) = ele;
375  cl_n.get(cell_id)++;
376  }
377 
384  inline void add(const T (& pos)[dim], typename base::value_type ele)
385  {
386  // calculate the Cell id
387 
388  size_t cell_id = this->getCell(pos);
389 
390  // add the element to the cell
391 
392  addCell(cell_id,ele);
393  }
394 
401  inline void add(const Point<dim,T> & pos, typename base::value_type ele)
402  {
403  // calculate the Cell id
404 
405  size_t cell_id = this->getCell(pos);
406 
407  // add the element to the cell
408 
409  addCell(cell_id,ele);
410  }
411 
418  inline void remove(size_t cell, size_t ele)
419  {
420  cl_n.get(cell)--;
421  }
422 
430  inline size_t getNelements(const size_t cell_id) const
431  {
432  return cl_n.get(cell_id);
433  }
434 
445  inline auto get(size_t cell, size_t ele) -> decltype(cl_base.get(cell * slot + ele))
446  {
447  return cl_base.get(cell * slot + ele);
448  }
449 
460  template<unsigned int i> inline auto get(size_t cell, size_t ele) -> decltype(cl_base.get(cell * slot + ele))
461  {
462  return cl_base.template get<i>(cell * slot + ele);
463  }
464 
471  {
472  cl_n.swap(cl.cl_n);
473  cl_base.swap(cl.cl_base);
474  }
475 
484  {
486  }
487 
506  template<unsigned int impl> inline CellNNIterator<dim,CellList<dim,T,FAST,transform,base>,FULL,impl> getNNIterator(size_t cell)
507  {
508  CellNNIterator<dim,CellList<dim,T,FAST,transform,base>,FULL,impl> cln(cell,NNc_full,*this);
509 
510  return cln;
511  }
512 
513 
531  template<unsigned int impl> inline CellNNIterator<dim,CellList<dim,T,FAST,transform,base>,SYM,impl> getNNIteratorSym(size_t cell)
532  {
533  CellNNIterator<dim,CellList<dim,T,FAST,transform,base>,SYM,impl> cln(cell,NNc_sym,*this);
534 
535  return cln;
536  }
537 
538 
556  template<unsigned int impl> inline CellNNIterator<dim,CellList<dim,T,FAST,transform,base>,CRS,impl> getNNIteratorCross(size_t cell)
557  {
558  CellNNIterator<dim,CellList<dim,T,FAST,transform,base>,CRS,impl> cln(cell,NNc_cr,*this);
559 
560  return cln;
561  }
562 };
563 
564 
565 #endif /* CELLLISTSTANDARD_HPP_ */
Class for FAST cell list implementation.
CellNNIterator< dim, CellList< dim, T, FAST, transform, base >, CRS, impl > getNNIteratorCross(size_t cell)
Get the Neighborhood iterator.
CellNNIterator< dim, CellList< dim, T, FAST, transform, base >, FULL, impl > getNNIterator(size_t cell)
Get the Neighborhood iterator.
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
CellList(SpaceBox< dim, T > &box, const size_t(&div)[dim], Point< dim, T > &orig, const size_t pad=1, size_t slot=16)
Cell list constructor.
size_t getNelements(const size_t cell_id) const
Return the number of element in the cell.
CellList< dim, T, FAST, transform, base > & operator=(const CellList< dim, T, FAST, transform, base > &cell)
Constructor from a temporal object.
CellNNIterator< dim, CellList< dim, T, FAST, transform, base >, SYM, impl > getNNIteratorSym(size_t cell)
Get the Neighborhood iterator.
void addCell(size_t cell_id, typename base::value_type ele)
Add to the cell.
CellList(const CellList< dim, T, FAST, transform, base > &cell)
Copy constructor.
bool isNext()
Check if there is the next element.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:20
void add(const Point< dim, T > &pos, typename base::value_type ele)
Add an element in the cell list.
T get(int i) const
Get coordinate.
Definition: Point.hpp:42
const grid_sm< dim, void > & getGrid()
Return the underlying grid information of the cell list.
grid_key_dx< dim > get()
Return the actual grid key iterator.
void Initialize(SpaceBox< dim, T > &box, const size_t(&div)[dim], const Point< dim, T > &orig, const size_t pad=1, size_t slot=16)
This class implement an NxN (dense) matrix.
Definition: Matrix.hpp:32
it iterate through the elements of a cell
void reset()
Reset the iterator (it restart from the beginning)
CellIterator< CellList< dim, T, FAST, transform, base > > getIterator(size_t cell)
Get the Cell iterator.
This class represent an N-dimensional box.
Definition: Box.hpp:56
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:202
CellList< dim, T, FAST, transform, base > & operator=(CellList< dim, T, FAST, transform, base > &&cell)
Constructor from a temporal object.
CellList(Box< dim, T > &box, const size_t(&div)[dim], Matrix< dim, T > mat, Point< dim, T > &orig, const size_t pad=1, size_t slot=16)
Cell list constructor.
CellList(Box< dim, T > &box, const size_t(&div)[dim], Point< dim, T > &orig, const size_t pad=1, size_t slot=16)
Cell list constructor.
CellList(CellList< dim, T, FAST, transform, base > &&cell)
Copy constructor.
void Initialize(const Box< dim, T > &box, const size_t(&div)[dim], const Point< dim, T > &orig, const size_t pad=1, size_t slot=16)
Cell list structure.
Definition: CellList.hpp:40
Iterator for the neighborhood of the cell structures.
void swap(CellList< dim, T, FAST, transform, base > &cl)
Swap the memory.
void add(const T(&pos)[dim], typename base::value_type ele)
Add an element in the cell list.