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
CellDecomposer.hpp
1 /*
2  * CellDecomposer.hpp
3  *
4  * Created on: Apr 1, 2015
5  * Author: Pietro Incardona
6  */
7 
8 #ifndef CELLDECOMPOSER_HPP_
9 #define CELLDECOMPOSER_HPP_
10 
11 #include "Space/SpaceBox.hpp"
12 #include "Space/Matrix.hpp"
13 #include "util/copy_compare/meta_compare.hpp"
14 
15 // Shift transformation
16 template<unsigned int dim, typename T>
17 class shift
18 {
19  Point<dim,T> sh;
20 
21 public:
22 
29  shift(const Matrix<dim,T> & t, const Point<dim,T> & s)
30  :sh(s)
31  {
32  }
33 
42  inline T transform(const T(&s)[dim], const size_t i) const
43  {
44  return s[i] - sh.get(i);
45  }
46 
55  inline T transform(const Point<dim,T> & s, const size_t i) const
56  {
57  return s.get(i) - sh.get(i);
58  }
59 
68  template<typename Mem> inline T transform(const encapc<1,Point<dim,T>,Mem> & s, const size_t i) const
69  {
70  return s.get(i) - sh.get(i);
71  }
72 
79  inline void setTransform(const Matrix<dim,T> & mat, const Point<dim,T> & orig)
80  {
81  for (size_t i = 0 ; i < dim ; i++)
82  sh.get(i) = orig.get(i);
83  }
84 };
85 
86 // No transformation
87 template<unsigned int dim, typename T>
89 {
90 public:
91 
98  no_transform(const Matrix<dim,T> & t, const Point<dim,T> & s)
99  {
100  }
101 
110  inline T transform(const T(&s)[dim], const size_t i) const
111  {
112  return s[i];
113  }
114 
123  inline T transform(const Point<dim,T> & s, const size_t i) const
124  {
125  return s.get(i);
126  }
127 
136  template<typename Mem> inline T transform(const encapc<1,Point<dim,T>,Mem> & s, const size_t i) const
137  {
138  return s.template get<Point<dim,T>::x>()[i];
139  }
140 
147  inline void setTransform(const Matrix<dim,T> & mat, const Point<dim,T> & orig)
148  {
149 
150  }
151 
159  inline bool operator==(const no_transform<dim,T> & nt)
160  {
161  return true;
162  }
163 
171  inline bool operator!=(const no_transform<dim,T> & nt)
172  {
173  return false;
174  }
175 };
176 
177 
218 template<unsigned int dim,typename T, typename transform = no_transform<dim,T>>
219 class CellDecomposer_sm
220 {
221  // Point in the middle of a cell
222  //
223  // \verbatim
224  //
225  // C (0.1,0.1)
226  // +-----+
227  // | |
228  // | .P |
229  // | |
230  // +-----+
231  //
232  // \endverbatim
233  //
234  // C is the cell and P is the point inside the middle of the cell
235  // for example if the cell is (0.1,0.1) P is (0.05,0.05)
236  //
237  //
238  Point<dim,T> p_middle;
239 
240  // Point transformation before get the Cell object (useful for example to shift the cell list)
241  transform t;
242 
249  inline size_t ConvertToID(const T (&x)[dim] ,size_t s) const
250  {
251  size_t id = (size_t)(t.transform(x,s) / box_unit.getHigh(s)) + off[s];
252  id = (id >= (gr_cell.size(s) + off[0]))?(gr_cell.size(s)-1):id;
253  return id;
254  }
255 
262  inline size_t ConvertToID(const Point<dim,T> & x ,size_t s) const
263  {
264  size_t id = (size_t)(t.transform(x,s) / box_unit.getHigh(s)) + off[s];
265  id = (id >= (gr_cell.size(s) + off[0]))?(gr_cell.size(s)-1):id;
266  return id;
267  }
268 
275  template <typename Mem> inline size_t ConvertToID_(const encapc<1,Point<dim,T>,Mem> & x ,size_t s) const
276  {
277  size_t id = (size_t)(t.transform(x,s) / box_unit.getHigh(s)) + off[s];
278  id = (id >= (gr_cell.size(s) + off[0]))?(gr_cell.size(s)-1):id;
279  return id;
280  }
281 
282 protected:
283 
284  // Total number of cell
285  size_t tot_n_cell;
286 
287  // Domain of the cell list
288  SpaceBox<dim,T> box;
289 
290  // Unit box of the Cell list
291  SpaceBox<dim,T> box_unit;
292 
293  // Grid structure of the Cell list
294  grid_sm<dim,void> gr_cell;
295 
296  // cell padding on each dimension
297  size_t off[dim];
298 
299 
303  void Initialize(const size_t pad, const size_t (& div)[dim])
304  {
305 #ifdef DEBUG
306  for (size_t i = 0 ; i < dim ; i++)
307  {
308  if (div[i] == 0)
309  {
310  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " the number of cells on each dimension must be different from zero\n";
311  }
312  }
313 #endif
314 
315  // created a padded div
316  size_t div_p[dim];
317 
318  for (size_t i = 0 ; i < dim ; i++)
319  div_p[i] = div[i] + 2*pad;
320 
321  gr_cell.setDimensions(div_p);
322 
323  tot_n_cell = 1;
324 
325  // Total number of cells and calculate the unit cell size
326 
327  for (size_t i = 0 ; i < dim ; i++)
328  {
329  tot_n_cell *= gr_cell.size(i);
330 
331  // Cell are padded by
332  box_unit.setHigh(i,box.getHigh(i) / (gr_cell.size(i)- 2*pad) );
333  }
334 
335  for (size_t i = 0; i < dim ; i++)
336  off[i] = pad;
337 
338  // Initialize p_middle
339 
340  p_middle = box_unit.getP2();
341  p_middle = p_middle / 2;
342  }
343 
344 public:
345 
351  const grid_sm<dim,void> & getGrid() const
352  {
353 #ifdef DEBUG
354  if (tot_n_cell == 0)
355  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
356 #endif
357 
358  return gr_cell;
359  }
360 
370  inline grid_key_dx<dim> getCellGrid(const T (& pos)[dim]) const
371  {
372 #ifdef SE_CLASS1
373  if (tot_n_cell == 0)
374  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
375 #endif
376 
378  key.set_d(0,ConvertToID(pos,0));
379 
380  for (size_t s = 1 ; s < dim ; s++)
381  {
382 #ifdef SE_CLASS1
383  if ((size_t)(t.transform(pos,s) / box_unit.getHigh(s)) + off[s] < 0)
384  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point is not inside the cell space\n";
385 #endif
386  key.set_d(s,ConvertToID(pos,s));
387 
388  }
389 
390  return key;
391  }
392 
402  grid_key_dx<dim> getCellGrid(const Point<dim,T> pos) const
403  {
404 #ifdef SE_CLASS1
405  if (tot_n_cell == 0)
406  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer\n";
407 #endif
408 
409  grid_key_dx<dim> key;
410  key.set_d(0,ConvertToID(pos,0));
411 
412  for (size_t s = 1 ; s < dim ; s++)
413  {
414 #ifdef SE_CLASS1
415  if ((size_t)(t.transform(pos,s) / box_unit.getHigh(s)) + off[s] < 0)
416  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point is not inside the cell space\n";
417 #endif
418  key.set_d(s,ConvertToID(pos,s));
419  }
420 
421  return key;
422  }
423 
433  size_t getCell(const T (& pos)[dim]) const
434  {
435 #ifdef SE_CLASS1
436  if (tot_n_cell == 0)
437  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
438 
439  if (t.transform(pos,0) < box.getLow(0) || t.transform(pos,0) > box.getHigh(0))
440  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
441 #endif
442 
443  size_t cell_id = ConvertToID(pos,0);
444 
445  for (size_t s = 1 ; s < dim ; s++)
446  {
447 #ifdef SE_CLASS1
448  if (t.transform(pos,s) < box.getLow(s) || t.transform(pos,s) > box.getHigh(s))
449  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
450 #endif
451  cell_id += gr_cell.size_s(s-1) * ConvertToID(pos,s);
452  }
453 
454  return cell_id;
455  }
456 
466  size_t getCell(const Point<dim,T> & pos) const
467  {
468 #ifdef SE_CLASS1
469  if (tot_n_cell == 0)
470  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
471 
472  if (t.transform(pos,0) < box.getLow(0) || t.transform(pos,0) > box.getHigh(0))
473  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << pos.toPointString() << " is not inside the cell space";
474 #endif
475 
476  size_t cell_id = ConvertToID(pos,0);
477 
478  for (size_t s = 1 ; s < dim ; s++)
479  {
480 #ifdef DEBUG
481  if (t.transform(pos,s) < box.getLow(s) || t.transform(pos,s) > box.getHigh(s))
482  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << pos.toPointString() << " is not inside the cell space";
483 #endif
484  cell_id += gr_cell.size_s(s-1) * ConvertToID(pos,s);
485  }
486 
487  return cell_id;
488  }
489 
499  template<typename Mem> size_t getCell(const encapc<1,Point<dim,T>,Mem> & pos) const
500  {
501 
502 #ifdef SE_CLASS1
503  if (tot_n_cell == 0)
504  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
505 
506  if (t.transform(pos,0) < box.getLow(0) || t.transform(pos,0) > box.getHigh(0))
507  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
508 #endif
509 
510  size_t cell_id = ConvertToID_(pos,0);
511 
512  for (size_t s = 1 ; s < dim ; s++)
513  {
514 #ifdef SE_CLASS1
515  if (t.transform(pos,s) < box.getLow(s) || t.transform(pos,s) > box.getHigh(s))
516  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
517 #endif
518  cell_id += gr_cell.size_s(s-1) * ConvertToID_(pos,s);
519  }
520 
521  return cell_id;
522  }
523 
556  Box<dim,size_t> getGridPoints(const Box<dim,T> & s_box) const
557  {
558  // Box with inside grid
559  Box<dim,size_t> bx;
560 
561  // Point p2
562  Point<dim,T> p2 = s_box.getP2();
563  p2 = p2 - p_middle;
564 
565  // Point p1
566  Point<dim,T> p1 = s_box.getP1();
567  p1 = p1 + p_middle;
568 
569  bx.setP2(getCellGrid(p2));
570  bx.setP1(getCellGrid(p1));
571 
572  return bx;
573  }
574 
582  void setDimensions(const Box<dim,T> & box, const size_t (&div)[dim], const size_t pad)
583  {
584  this->box = box;
585  this->gr_cell.setDimensions(div);
586  Initialize(pad,div);
587  }
588 
598  void setDimensions(const Box<dim,T> & box, const size_t (&div)[dim], const Matrix<dim,T> & mat, const Point<dim,T> & orig, const size_t pad)
599  {
600  t.setTransform(mat,orig);
601  this->box = box;
602  this->gr_cell.setDimensions(div);
603  Initialize(pad,div);
604  }
605 
636  CellDecomposer_sm(const SpaceBox<dim,T> & box, const size_t (&div)[dim], Matrix<dim,T> & mat, Point<dim,T> & orig, const size_t pad)
637  :t(Matrix<dim,T>::identity(),Point<dim,T>::zero()),box(box),gr_cell()
638  {
639  Initialize(pad);
640  }
641 
672  CellDecomposer_sm(const SpaceBox<dim,T> & box, const size_t (&div)[dim], Point<dim,T> & orig, const size_t pad)
673  :t(Matrix<dim,T>::identity(),orig),box(box),gr_cell(div)
674  {
675  Initialize(pad,div);
676  }
677 
706  CellDecomposer_sm(const SpaceBox<dim,T> & box, const size_t (&div)[dim], const size_t pad)
707  :t(Matrix<dim,T>::identity(),Point<dim,T>::zero_p()),box(box),gr_cell()
708  {
709  Initialize(pad,div);
710  }
711 
712 
714  CellDecomposer_sm()
715  :t(Matrix<dim,T>::identity(),Point<dim,T>::zero_p()),tot_n_cell(0)
716  {
717 
718  }
719 
727  const Box<dim,T> & getCellBox() const
728  {
729  return box_unit;
730  }
731 
739 /* Box<dim,T> BoundaryFixation()
740  {
741 
742  }*/
743 
788  Box<dim,size_t> convertDomainSpaceIntoGridUnits(const Box<dim,T> & b_d) const
789  {
790  Box<dim,size_t> g_box;
791  Box<dim,T> b = b_d;
792 
793  // Convert b into grid units
794  b /= getCellBox().getP2();
795 
796  // Considering that we are interested in a box decomposition of the space
797  // where basically all the point are uniquely assigned we include the positive
798  // countour and exclude the negative one. So ceilP1 do the job for P1 while ceilP2 - 1
799  // do the job for P2
800 
801  b.ceilP1();
802  b.ceilP2();
803 
804  g_box = b;
805 
806  // on the other hand if we are at the positive (with non periodic boundary condition)
807  // we have to include also the positive border
808 
809  Point<dim,size_t> p_move;
810 
811  for (size_t i = 0 ; i < dim ; i++)
812  {
813  // we are at the positive border (We are assuming that there are not rounding error, check boundary Fixation)
814  if (b_d.getHigh(i) == box.getHigh(i))
815  {
816  p_move.get(i) = 0;
817  g_box.setHigh(i,gr_cell.size(i));
818  }
819  else
820  p_move.get(i) = 1;
821  }
822 
823  g_box.shrinkP2(p_move);
824 
825  return g_box;
826  }
827 
835  bool operator==(const CellDecomposer_sm<dim,T,transform> & cd)
836  {
837  if (meta_compare<Point<dim,T>>::meta_compare_f(p_middle,cd.p_middle) == false)
838  return false;
839 
840  if (t != cd.t)
841  return false;
842 
843  if (tot_n_cell != cd.tot_n_cell)
844  return false;
845 
846  if (box != cd.box)
847  return false;
848 
849  if (box_unit != cd.box_unit)
850  return false;
851 
852  if (gr_cell != cd.gr_cell)
853  return false;
854 
855  for (size_t i = 0 ; i < dim ; i++)
856  {
857  if (off[i] != cd.off[i])
858  return false;
859  }
860 
861  return true;
862  }
863 
871  bool operator!=(const CellDecomposer_sm<dim,T,transform> & cd)
872  {
873  return ! this->operator==(cd);
874  }
875 };
876 
877 
878 #endif /* CELLDECOMPOSER_HPP_ */
This class represent an N-dimensional box.
Definition: SpaceBox.hpp:26
void setP1(const grid_key_dx< dim > &p1)
Set the point P1 of the box.
Definition: Box.hpp:505
T transform(const Point< dim, T > &s, const size_t i) const
No transformation.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:495
bool operator==(const no_transform< dim, T > &nt)
It return always true true.
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:472
shift(const Matrix< dim, T > &t, const Point< dim, T > &s)
Constructor.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:20
void setTransform(const Matrix< dim, T > &mat, const Point< dim, T > &orig)
Set the transformation Matrix and shift.
void setTransform(const Matrix< dim, T > &mat, const Point< dim, T > &orig)
Set the transformation Matrix and shift.
T transform(const T(&s)[dim], const size_t i) const
Shift the point transformation.
T transform(const encapc< 1, Point< dim, T >, Mem > &s, const size_t i) const
No transformation.
void setP2(const grid_key_dx< dim > &p2)
Set the point P2 of the box.
Definition: Box.hpp:516
void ceilP1()
Translate P1 of a given vector P1.
Definition: Box.hpp:945
T get(int i) const
Get coordinate.
Definition: Point.hpp:42
no_transform(const Matrix< dim, T > &t, const Point< dim, T > &s)
Constructor.
void setDimensions(std::vector< size_t > &dims)
Reset the dimension of the grid.
Definition: grid_sm.hpp:205
This class implement an NxN (dense) matrix.
Definition: Matrix.hpp:32
this structure encapsulate an object of the grid
Definition: Encap.hpp:209
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:202
This class compare general objects.
T transform(const encapc< 1, Point< dim, T >, Mem > &s, const size_t i) const
Shift the point transformation.
T transform(const T(&s)[dim], const size_t i) const
Shift the point transformation.
T transform(const Point< dim, T > &s, const size_t i) const
Shift the point transformation.
void ceilP2()
Translate P1 of a unit vector on all directions.
Definition: Box.hpp:958
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_key.hpp:315
std::string toPointString() const
Convert the point into a string.
Definition: Point.hpp:282
void shrinkP2(T sh)
Shrink moving p2 of sh quantity (on each direction)
Definition: Box.hpp:776
bool operator!=(const no_transform< dim, T > &nt)
It return always true true.