OpenFPM  5.2.0
Project that contain the implementation of distributed structures
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/Ghost.hpp"
12 #include "Space/Shape/Box.hpp"
13 #include "Space/Matrix.hpp"
14 #include "util/copy_compare/meta_compare.hpp"
15 #include "Grid/grid_sm.hpp"
16 
17 #define CELL_DECOMPOSER 8001lu
18 
19 
20 
21 
26 template<unsigned int dim, typename T>
27 class shift
28 {
31 
34 
35 public:
36 
43  __device__ __host__ shift(const Matrix<dim,T> & t, const Point<dim,T> & s)
44  :sh(s)
45  {
46  mat.identity();
47  }
48 
57  __device__ __host__ inline T transform(const T(&s)[dim], const size_t i) const
58  {
59  return s[i] - sh.get(i);
60  }
61 
70  __device__ __host__ inline T transform(const Point<dim,T> & s, const size_t i) const
71  {
72  return s.get(i) - sh.get(i);
73  }
74 
83  template<typename Mem> inline __device__ __host__ T transform(const encapc<1,Point<dim,T>,Mem> & s, const size_t i) const
84  {
85  return s.template get<0>()[i] - sh.get(i);
86  }
87 
94  __device__ __host__ inline void setTransform(const Matrix<dim,T> & mat, const Point<dim,T> & orig)
95  {
96  for (size_t i = 0 ; i < dim ; i++)
97  sh.get(i) = orig.get(i);
98  }
99 
105  inline const Point<dim,T> & getOrig() const
106  {
107  return sh;
108  }
109 
115  inline const Matrix<dim,T> & getMat() const
116  {
117  return mat;
118  }
119 
127  inline bool operator==(const shift<dim,T> & s)
128  {
129  return sh == s.sh;
130  }
131 
139  inline bool operator!=(const shift<dim,T> & s)
140  {
141  return !this->operator==(s);
142  }
143 };
144 
149 template<unsigned int dim, typename T>
151 {
154 
155 public:
156 
161  {
162  sh.zero();
163  }
164 
171  shift_only(const Matrix<dim,T> & t, const Point<dim,T> & s)
172  :sh(s)
173  {
174  }
175 
184  __device__ __host__ inline T transform(const T * s, const int i) const
185  {
186  return s[i] - sh.get(i);
187  }
188 
197  __device__ __host__ inline T transform(const T(&s)[dim], const int i) const
198  {
199  return s[i] - sh.get(i);
200  }
201 
210  __device__ __host__ inline T transform(const Point<dim,T> & s, const int i) const
211  {
212  return s.get(i) - sh.get(i);
213  }
214 
223  template<typename Mem> __device__ __host__ inline T transform(const encapc<1,Point<dim,T>,Mem> & s, const int i) const
224  {
225  return s.template get<0>()[i] - sh.get(i);
226  }
227 
234  inline void setTransform(const Matrix<dim,T> & mat, const Point<dim,T> & orig)
235  {
236  for (size_t i = 0 ; i < dim ; i++)
237  sh.get(i) = orig.get(i);
238  }
239 
245  __device__ __host__ inline const Point<dim,T> & getOrig() const
246  {
247  return sh;
248  }
249 
250 
258  inline bool operator==(const shift<dim,T> & s)
259  {
260  return sh == s.sh;
261  }
262 
270  inline bool operator!=(const shift<dim,T> & s)
271  {
272  return !this->operator==(s);
273  }
274 };
275 
277 template<unsigned int dim, typename T>
279 {
282 
285 
286 public:
287 
294  __device__ __host__ no_transform(const Matrix<dim,T> & t, const Point<dim,T> & s)
295  {
296  orig.zero();
297  mat.identity();
298  }
299 
308  __device__ __host__ inline T transform(const T(&s)[dim], const size_t i) const
309  {
310  return s[i];
311  }
312 
321  __device__ __host__ inline T transform(const Point<dim,T> & s, const size_t i) const
322  {
323  return s.get(i);
324  }
325 
334  template<typename Mem> __device__ __host__ inline T transform(const encapc<1,Point<dim,T>,Mem> & s, const size_t i) const
335  {
336  return s.template get<Point<dim,T>::x>()[i];
337  }
338 
345  inline void setTransform(const Matrix<dim,T> & mat, const Point<dim,T> & orig)
346  {
347 
348  }
349 
359  inline bool operator==(const no_transform<dim,T> & nt)
360  {
361  return true;
362  }
363 
373  inline bool operator!=(const no_transform<dim,T> & nt)
374  {
375  return false;
376  }
377 
383  inline const Point<dim,T> & getOrig() const
384  {
385  return orig;
386  }
387 
393  inline const Matrix<dim,T> & getMat() const
394  {
395  return mat;
396  }
397 };
398 
400 template<unsigned int dim, typename T>
402 {
403 
404 public:
405 
413  {
414  }
415 
424  __device__ __host__ inline T transform(const T * s, const int i) const
425  {
426  return s[i];
427  }
428 
437  __device__ __host__ inline T transform(const T(&s)[dim], const int i) const
438  {
439  return s[i];
440  }
441 
450  __device__ __host__ inline T transform(const Point<dim,T> & s, const int i) const
451  {
452  return s.get(i);
453  }
454 
463  template<typename Mem> __device__ __host__ inline T transform(const encapc<1,Point<dim,T>,Mem> & s, const int i) const
464  {
465  return s.template get<Point<dim,T>::x>()[i];
466  }
467 
474  inline void setTransform(const Matrix<dim,T> & mat, const Point<dim,T> & orig)
475  {
476 
477  }
478 
488  inline bool operator==(const no_transform<dim,T> & nt)
489  {
490  return true;
491  }
492 
502  inline bool operator!=(const no_transform<dim,T> & nt)
503  {
504  return false;
505  }
506 };
507 
548 template<unsigned int dim,typename T, typename transform_type = no_transform<dim,T>>
549 class CellDecomposer_sm
550 {
551  // Point in the middle of a cell
552  //
553  // \verbatim
554  //
555  // C (0.1,0.1)
556  // +-----+
557  // | |
558  // | .P |
559  // | |
560  // +-----+
561  //
562  // \endverbatim
563  //
564  // C is the cell and P is the point inside the middle of the cell
565  // for example if the cell is (0.1,0.1) P is (0.05,0.05)
566  //
567  //
568  Point<dim,T> p_middle;
569 
570  // Point transformation before get the Cell object (useful for example to shift the cell list)
571  transform_type pointTransform;
572 
579  inline size_t ConvertToID(const T (&x)[dim] ,size_t s) const
580  {
581  size_t id = openfpm::math::size_t_floor(pointTransform.transform(x,s) / unitCellSpaceBox.getHigh(s)) + off[s];
582  id = (id >= cellListGrid.size(s))?(cellListGrid.size(s)-1-cellShift.get(s)):id-cellShift.get(s);
583  return id;
584  }
585 
592  inline size_t ConvertToID(const Point<dim,T> & x ,size_t s, size_t sc = 0) const
593  {
594  size_t id = openfpm::math::size_t_floor(pointTransform.transform(x,s) / unitCellSpaceBox.getHigh(s)) + off[s];
595  id = (id >= cellListGrid.size(s))?(cellListGrid.size(s)-1-cellShift.get(s)):id-cellShift.get(s);
596  return id;
597  }
598 
605  inline size_t ConvertToID_me(const Point<dim,T> & x ,size_t s, size_t sc = 0) const
606  {
607  T cc = pointTransform.transform(x,s) / unitCellSpaceBox.getHigh(s) - 0.015625;
608  size_t id = openfpm::math::size_t_floor(cc) + off[s];
609  id = (id >= cellListGrid.size(s))?(cellListGrid.size(s)-1-cellShift.get(s)):id-cellShift.get(s);
610  return id;
611  }
612 
619  inline size_t ConvertToID_pe(const Point<dim,T> & x ,size_t s, size_t sc = 0) const
620  {
621  T cc = pointTransform.transform(x,s) / unitCellSpaceBox.getHigh(s) + 0.015625;
622  size_t id = openfpm::math::size_t_floor(cc) + off[s];
623  id = (id >= cellListGrid.size(s))?(cellListGrid.size(s)-1-cellShift.get(s)):id-cellShift.get(s);
624  return id;
625  }
626 
633  inline size_t ConvertToID_ns(const T (&x)[dim] ,size_t s) const
634  {
635  size_t id = openfpm::math::size_t_floor(pointTransform.transform(x,s) / unitCellSpaceBox.getHigh(s)) + off[s];
636  id = (id >= cellListGrid.size(s))?(cellListGrid.size(s)-1):id;
637  return id;
638  }
639 
646  inline size_t ConvertToID_ns(const Point<dim,T> & x ,size_t s, size_t sc = 0) const
647  {
648  size_t id = openfpm::math::size_t_floor(pointTransform.transform(x,s) / unitCellSpaceBox.getHigh(s)) + off[s];
649  id = (id >= cellListGrid.size(s))?(cellListGrid.size(s)-1):id;
650  return id;
651  }
652 
659  template <typename Mem> inline size_t ConvertToID_(const encapc<1,Point<dim,T>,Mem> & x ,size_t s, size_t sc = 0) const
660  {
661  size_t id = (size_t)(pointTransform.transform(x,s) / unitCellSpaceBox.getHigh(s)) + off[s];
662  id = (id >= cellListGrid.size(s))?(cellListGrid.size(s)-1-cellShift.get(s)):id-cellShift.get(s);
663  return id;
664  }
665 
672  template<typename Ele> inline void check_and_print_error(const Ele & pos ,size_t s) const
673  {
674 #ifdef SE_CLASS1
675  if (cellTotalCount == 0)
676  {
677  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
678  ACTION_ON_ERROR(CELL_DECOMPOSER);
679  }
680 
681  if (pos[s] < cellListSpaceBox.getLow(s) - off[s]*unitCellSpaceBox.getP2()[s] || pos[s] > cellListSpaceBox.getHigh(s) + off[s]*unitCellSpaceBox.getP2()[s])
682  {
683  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << Point<dim,T>(pos).toString() << " is not inside the cell space";
684  ACTION_ON_ERROR(CELL_DECOMPOSER);
685  }
686 #endif
687  }
688 
689 
690  template<typename Ele> inline size_t getCellDom_impl(const Ele & pos) const
691  {
692  check_and_print_error(pos,0);
693 
694  size_t cell_id = ConvertToID_ns(pos,0);
695 
696  cell_id = (cell_id == cellListGrid.size(0) - off[0])?cellListGrid.size(0) - off[0] - 1:cell_id;
697  cell_id = (cell_id == off[0]-1)?off[0]:cell_id;
698 
699  cell_id -= cellShift.get(0);
700 
701  for (size_t s = 1 ; s < dim ; s++)
702  {
703  check_and_print_error(pos,s);
704 
705  size_t cell_idt = ConvertToID_ns(pos,s);
706 
707  cell_idt = (cell_idt == cellListGrid.size(s) - off[s])?cellListGrid.size(s) - off[s] - 1:cell_idt;
708  cell_idt = (cell_idt == off[s]-1)?off[s]:cell_idt;
709 
710  cell_idt -= cellShift.get(s);
711 
712  cell_id += gr_cell2.size_s(s-1) * cell_idt;
713  }
714 
715  return cell_id;
716  }
717 
718  template<typename Ele> inline size_t getCellPad_impl(const Ele & pos) const
719  {
720  check_and_print_error(pos,0);
721 
722  size_t cell_id = ConvertToID_ns(pos,0);
723 
724  cell_id = (cell_id == off[0])?off[0]-1:cell_id;
725  cell_id = (cell_id == cellListGrid.size(0) - off[0] - 1)?cellListGrid.size(0) - off[0]:cell_id;
726 
727  cell_id -= cellShift.get(0);
728 
729  for (size_t s = 1 ; s < dim ; s++)
730  {
731  check_and_print_error(pos,s);
732 
733  size_t cell_idt = ConvertToID_ns(pos,s);
734  cell_idt = (cell_idt == off[s])?off[s]-1:cell_idt;
735  cell_idt = (cell_idt == cellListGrid.size(s) - off[s] - 1)?cellListGrid.size(s) - off[s]:cell_idt;
736 
737  cell_idt -= cellShift.get(s);
738 
739  cell_id += gr_cell2.size_s(s-1) * cell_idt;
740  }
741 
742  return cell_id;
743  }
744 
745 
746 protected:
747 
749  size_t cellTotalCount;
750 
752  Box<dim,T> cellListSpaceBox;
753 
755  Box<dim,T> unitCellSpaceBox;
756 
758  grid_sm<dim,void> cellListGrid;
759 
761  grid_sm<dim,void> gr_cell2;
762 
764  Box<dim,T> box_gr_cell2;
765 
767  size_t off[dim];
768 
770  Point<dim,long int> cellShift;
771 
772  // temporal buffer
773  mutable size_t div_wp[dim];
774 
778  void Initialize(const size_t pad, const size_t (& div)[dim])
779  {
780 #ifdef SE_CLASS1
781 
782  for (size_t i = 0 ; i < dim ; i++)
783  {
784  if (div[i] == 0)
785  {
786  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " the number of cells on each dimension must be different from zero\n";
787  ACTION_ON_ERROR(CELL_DECOMPOSER)
788  }
789  }
790 
791 #endif
792 
793  // set div_wp to zero
794  for (size_t i = 0 ; i < dim ; i++)
795  {div_wp[i] = 0;}
796 
797  // created a padded div
798  size_t div_p[dim];
799 
800  for (size_t i = 0 ; i < dim ; i++)
801  div_p[i] = div[i] + 2*pad;
802 
803  cellListGrid.setDimensions(div_p);
804  gr_cell2.setDimensions(div_p);
805 
806  cellTotalCount = 1;
807 
808  // Total number of cells and calculate the unit cell size
809 
810 
811  for (size_t i = 0 ; i < dim ; i++)
812  {
813  cellTotalCount *= cellListGrid.size(i);
814  unitCellSpaceBox.setHigh(i,(cellListSpaceBox.getHigh(i) - cellListSpaceBox.getLow(i)) / (cellListGrid.size(i)- 2*pad) );
815  }
816 
817  for (size_t i = 0; i < dim ; i++)
818  off[i] = pad;
819 
820  // Initialize p_middle
821 
822  p_middle = unitCellSpaceBox.getP2();
823  p_middle = p_middle / 2;
824  }
825 
826 public:
827 
833  const transform_type & getTransform()
834  {
835  return pointTransform;
836  }
837 
843  const grid_sm<dim,void> & getGrid() const
844  {
845 #ifdef DEBUG
846  if (cellTotalCount == 0)
847  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
848 #endif
849 
850  return cellListGrid;
851  }
852 
862  inline grid_key_dx<dim> getCellGrid(const T (& pos)[dim]) const
863  {
864 #ifdef SE_CLASS1
865  if (cellTotalCount == 0)
866  {
867  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
868  ACTION_ON_ERROR(CELL_DECOMPOSER);
869  }
870 #endif
871 
872  grid_key_dx<dim> key;
873  key.set_d(0,ConvertToID(pos,0));
874 
875  for (size_t s = 1 ; s < dim ; s++)
876  {
877 #ifdef SE_CLASS1
878  if ((size_t)(pointTransform.transform(pos,s) / unitCellSpaceBox.getHigh(s)) + off[s] < 0)
879  {
880  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point is not inside the cell space\n";
881  ACTION_ON_ERROR(CELL_DECOMPOSER);
882  }
883 #endif
884  key.set_d(s,ConvertToID(pos,s));
885 
886  }
887 
888  return key;
889  }
890 
900  inline size_t getCellLin(grid_key_dx<dim> && k) const
901  {
902 #ifdef SE_CLASS1
903  if (cellTotalCount == 0)
904  {
905  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
906  ACTION_ON_ERROR(CELL_DECOMPOSER);
907  }
908 
909  if (gr_cell2.size(0) < k.get(0) + off[0] - cellShift.get(0))
910  {
911  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " cell coordinate 0 = " << k.get(0) + off[0] - cellShift.get(0) << " bigger than cell space " << gr_cell2.size(0) << std::endl;
912  ACTION_ON_ERROR(CELL_DECOMPOSER);
913  }
914 #endif
915 
916  size_t cell_id = k.get(0) + off[0] - cellShift.get(0);
917 
918  for (size_t s = 1 ; s < dim ; s++)
919  {
920 #ifdef SE_CLASS1
921  if (gr_cell2.size(s) < k.get(s) + off[s] - cellShift.get(s))
922  {
923  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " cell coordinate 0 = " << k.get(0) + off[0] - cellShift.get(0) << " bigger than cell space " << gr_cell2.size(s) << std::endl;
924  ACTION_ON_ERROR(CELL_DECOMPOSER);
925  }
926 #endif
927  cell_id += gr_cell2.size_s(s-1) * (k.get(s) + off[s] -cellShift.get(s));
928  }
929 
930  return cell_id;
931  }
932 
942  inline size_t getCellLin(const grid_key_dx<dim> & k) const
943  {
944 #ifdef SE_CLASS1
945  if (cellTotalCount == 0)
946  {
947  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
948  ACTION_ON_ERROR(CELL_DECOMPOSER);
949  }
950 
951  if (gr_cell2.size(0) < k.get(0) + off[0] - cellShift.get(0))
952  {
953  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " cell coordinate 0 = " << k.get(0) + off[0] - cellShift.get(0) << " bigger than cell space " << gr_cell2.size(0) << std::endl;
954  ACTION_ON_ERROR(CELL_DECOMPOSER);
955  }
956 #endif
957 
958  size_t cell_id = k.get(0) + off[0] -cellShift.get(0);
959 
960  for (size_t s = 1 ; s < dim ; s++)
961  {
962 #ifdef SE_CLASS1
963  if (gr_cell2.size(s) < k.get(s) + off[s] - cellShift.get(s))
964  {
965  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " cell coordinate 0 = " << k.get(0) + off[0] - cellShift.get(0) << " bigger than cell space " << gr_cell2.size(s) << std::endl;
966  ACTION_ON_ERROR(CELL_DECOMPOSER);
967  }
968 #endif
969  cell_id += gr_cell2.size_s(s-1) * (k.get(s) + off[s] -cellShift.get(s));
970  }
971 
972  return cell_id;
973  }
974 
984  inline grid_key_dx<dim> getCellGrid_me(const Point<dim,T> & pos) const
985  {
986 #ifdef SE_CLASS1
987  if (cellTotalCount == 0)
988  {
989  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer" << std::endl;
990  ACTION_ON_ERROR(CELL_DECOMPOSER);
991  }
992 #endif
993 
994  grid_key_dx<dim> key;
995  key.set_d(0,ConvertToID_me(pos,0));
996 
997  for (size_t s = 1 ; s < dim ; s++)
998  {
999 #ifdef SE_CLASS1
1000  if ((size_t)(pointTransform.transform(pos,s) / unitCellSpaceBox.getHigh(s)) + off[s] < 0)
1001  {
1002  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point is not inside the cell space" << std::endl;
1003  ACTION_ON_ERROR(CELL_DECOMPOSER);
1004  }
1005 #endif
1006  /* coverity[dead_error_line] */
1007  key.set_d(s,ConvertToID_me(pos,s));
1008  }
1009 
1010  return key;
1011  }
1012 
1022  inline grid_key_dx<dim> getCellGrid_pe(const Point<dim,T> & pos) const
1023  {
1024 #ifdef SE_CLASS1
1025  if (cellTotalCount == 0)
1026  {
1027  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer" << std::endl;
1028  ACTION_ON_ERROR(CELL_DECOMPOSER);
1029  }
1030 #endif
1031 
1032  grid_key_dx<dim> key;
1033  key.set_d(0,ConvertToID_pe(pos,0));
1034 
1035  for (size_t s = 1 ; s < dim ; s++)
1036  {
1037 #ifdef SE_CLASS1
1038  if ((size_t)(pointTransform.transform(pos,s) / unitCellSpaceBox.getHigh(s)) + off[s] < 0)
1039  {
1040  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point is not inside the cell space" << std::endl;
1041  ACTION_ON_ERROR(CELL_DECOMPOSER);
1042  }
1043 #endif
1044  /* coverity[dead_error_line] */
1045  key.set_d(s,ConvertToID_pe(pos,s));
1046  }
1047 
1048  return key;
1049  }
1050 
1060  inline grid_key_dx<dim> getCellGrid(const Point<dim,T> & pos) const
1061  {
1062 #ifdef SE_CLASS1
1063  if (cellTotalCount == 0)
1064  {
1065  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer" << std::endl;
1066  ACTION_ON_ERROR(CELL_DECOMPOSER);
1067  }
1068 #endif
1069 
1070  grid_key_dx<dim> key;
1071  key.set_d(0,ConvertToID(pos,0));
1072 
1073  for (size_t s = 1 ; s < dim ; s++)
1074  {
1075 #ifdef SE_CLASS1
1076  if ((size_t)(pointTransform.transform(pos,s) / unitCellSpaceBox.getHigh(s)) + off[s] < 0)
1077  {
1078  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point is not inside the cell space" << std::endl;
1079  ACTION_ON_ERROR(CELL_DECOMPOSER);
1080  }
1081 #endif
1082  /* coverity[dead_error_line] */
1083  key.set_d(s,ConvertToID(pos,s));
1084  }
1085 
1086  return key;
1087  }
1088 
1100  inline size_t getCellDom(const Point<dim,T> & pos) const
1101  {
1102  return getCellDom_impl<Point<dim,T>>(pos);
1103  }
1104 
1105 
1117  inline size_t getCellDom(const T (& pos)[dim]) const
1118  {
1119  return getCellDom_impl<T[dim]>(pos);
1120  }
1121 
1133  inline size_t getCellPad(const Point<dim,T> & pos) const
1134  {
1135  return getCellPad_impl<Point<dim,T>>(pos);
1136  }
1137 
1149  inline size_t getCellPad(const T (& pos)[dim]) const
1150  {
1151  return getCellPad_impl<T[dim]>(pos);
1152  }
1153 
1164  inline size_t getCell(const T (& pos)[dim]) const
1165  {
1166 #ifdef SE_CLASS1
1167  if (cellTotalCount == 0)
1168  {
1169  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
1170  ACTION_ON_ERROR(CELL_DECOMPOSER);
1171  }
1172 
1173 #endif
1174  size_t cell_id = ConvertToID(pos,0);
1175 
1176  for (size_t s = 1 ; s < dim ; s++)
1177  {
1178 #ifdef SE_CLASS1
1179  if (pos[s] < cellListSpaceBox.getLow(s) - off[s]*unitCellSpaceBox.getP2()[s] || pos[s] > cellListSpaceBox.getHigh(s) + off[s]*unitCellSpaceBox.getP2()[s])
1180  {
1181  return -1;
1182  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
1183  ACTION_ON_ERROR(CELL_DECOMPOSER);
1184  }
1185 #endif
1186  cell_id += gr_cell2.size_s(s-1) * ConvertToID(pos,s);
1187  }
1188 
1189  return cell_id;
1190  }
1191 
1202  inline int getCell(const Point<dim,T> & pos) const
1203  {
1204 #ifdef SE_CLASS1
1205  if (cellTotalCount == 0)
1206  {
1207  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
1208  ACTION_ON_ERROR(CELL_DECOMPOSER);
1209  }
1210 
1211 #endif
1212  size_t cell_id = ConvertToID(pos,0);
1213 
1214  for (size_t s = 1 ; s < dim ; s++)
1215  {
1216 #ifdef SE_CLASS1
1217  if (pos.get(s) < cellListSpaceBox.getLow(s) - off[s]*unitCellSpaceBox.getP2()[s] || pos.get(s) > cellListSpaceBox.getHigh(s) + off[s]*unitCellSpaceBox.getP2()[s])
1218  {
1219  return -1;
1220  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << pos.toPointString() << " is not inside the cell space";
1221  ACTION_ON_ERROR(CELL_DECOMPOSER);
1222  }
1223 #endif
1224  /* coverity[dead_error_line] */
1225  cell_id += gr_cell2.size_s(s-1) * ConvertToID(pos,s);
1226  }
1227 
1228  return cell_id;
1229  }
1230 
1240  template<typename Mem> inline int getCell(const encapc<1,Point<dim,T>,Mem> & pos) const
1241  {
1242 
1243 #ifdef SE_CLASS1
1244  if (cellTotalCount == 0)
1245  {
1246  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
1247  ACTION_ON_ERROR(CELL_DECOMPOSER);
1248  }
1249 
1250 #endif
1251 
1252  size_t cell_id = ConvertToID_(pos,0);
1253 
1254  for (size_t s = 1 ; s < dim ; s++)
1255  {
1256 #ifdef SE_CLASS1
1257 
1258  if (pos.template get<0>()[s] < cellListSpaceBox.getLow(s) - off[s]*unitCellSpaceBox.getP2()[s] || pos.template get<0>()[s] > cellListSpaceBox.getHigh(s) + off[s]*unitCellSpaceBox.getP2()[s])
1259  {
1260  return -1;
1261  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
1262  ACTION_ON_ERROR(CELL_DECOMPOSER);
1263  }
1264 #endif
1265  cell_id += gr_cell2.size_s(s-1) * ConvertToID_(pos,s);
1266  }
1267 
1268  return cell_id;
1269  }
1270 
1303  inline Box<dim,size_t> getGridPoints(const Box<dim,T> & s_box) const
1304  {
1305  // Box with inside grid
1306  Box<dim,size_t> bx;
1307 
1308  // Point p2
1309  Point<dim,T> p2 = s_box.getP2();
1310  p2 = p2 - p_middle;
1311 
1312  // Point p1
1313  Point<dim,T> p1 = s_box.getP1();
1314  p1 = p1 + p_middle;
1315 
1316  bx.setP2(getCellGrid(p2));
1317  bx.setP1(getCellGrid(p1));
1318 
1319  return bx;
1320  }
1321 
1329  inline void setDimensions(const Box<dim,T> & box, const size_t (&div)[dim], const size_t (&div2)[dim], const size_t pad, Point<dim,long int> cellShift)
1330  {
1331  Matrix<dim,T> mat;
1332  mat.identity();
1333  pointTransform.setTransform(mat,box.getP1());
1334  this->cellListSpaceBox = box;
1335 
1336  Initialize(pad,div);
1337 
1338  size_t cells[dim];
1339 
1340  for (size_t i = 0 ; i < dim ; i++)
1341  cells[i] = div2[i] + 2*pad;
1342 
1343  gr_cell2.setDimensions(cells);
1344 
1345  for (size_t i = 0 ; i < dim ; i++)
1346  this->cellShift.get(i) = cellShift.get(i) - off[i];
1347  }
1348 
1356  inline void setDimensions(const Box<dim,T> & box, const size_t (&div)[dim], const size_t pad)
1357  {
1358  Matrix<dim,T> mat;
1359  mat.identity();
1360  pointTransform.setTransform(mat,box.getP1());
1361  this->cellListSpaceBox = box;
1362  Initialize(pad,div);
1363  this->cellShift = 0;
1364  }
1365 
1376  inline void setDimensions(const Box<dim,T> & box, const size_t (&div)[dim], const size_t (&div2)[dim], const Matrix<dim,T> & mat, const size_t pad, Point<dim,long int> cellShift)
1377  {
1378  pointTransform.setTransform(mat,box.getP1());
1379  this->cellListSpaceBox = box;
1380 
1381  Initialize(pad,div);
1382 
1383  // The nested cell is big div2 + 2*off
1384 
1385  size_t div_with_off[dim];
1386 
1387  for(size_t i = 0 ; i < dim ; i++)
1388  div_with_off[i] = div2[i] + 2*off[i];
1389 
1390  gr_cell2.setDimensions(div_with_off);
1391 
1392  for (size_t i = 0 ; i < dim ; i++)
1393  this->cellShift.get(i) = cellShift.get(i) - off[i];
1394  }
1395 
1405  inline void setDimensions(const Box<dim,T> & box, const size_t (&div)[dim], const Matrix<dim,T> & mat, const size_t pad)
1406  {
1407  pointTransform.setTransform(mat,box.getP1());
1408  this->cellListSpaceBox = box;
1409  Initialize(pad,div);
1410  this->cellShift = 0;
1411  }
1412 
1413 
1425  inline void setDimensions(const CellDecomposer_sm<dim,T,transform_type> & cd, const Box<dim,size_t> & cell_extension)
1426  {
1427  this->cellShift = 0;
1428 
1429  // Get the space transformation
1430 
1431  pointTransform.setTransform(cd.getMat(),cd.getOrig());
1432 
1433  // The domain is equivalent to the old one
1434  this->cellListSpaceBox = cd.cellListSpaceBox;
1435 
1436  // The padding must be calculated
1437 
1438  size_t pad = 0;
1439 
1440  for (size_t i = 0 ; i < dim ; i++)
1441  {
1442  if (pad < cell_extension.getLow(i))
1443  pad = cell_extension.getLow(i);
1444  else if (pad > cell_extension.getHigh(i))
1445  pad = cell_extension.getHigh(i);
1446  }
1447 
1448  // We have to give the old division
1449 
1450  size_t sz_div[dim];
1451 
1452  for (size_t i = 0 ; i < dim ; i++)
1453  sz_div[i] = cd.cellListGrid.size(i) - 2*cd.off[i];
1454 
1455  Initialize(pad,sz_div);
1456  }
1457 
1487  CellDecomposer_sm(const Box<dim,T> & box, const size_t (&div)[dim], Matrix<dim,T> & mat, const size_t pad)
1488  :pointTransform(Matrix<dim,T>::identity(),box.getP1()),cellListSpaceBox(box),cellListGrid()
1489  {
1490  Initialize(pad,div);
1491  }
1492 
1522  CellDecomposer_sm(const Box<dim,T> & box, const size_t (&div)[dim], const size_t pad)
1523  :pointTransform(Matrix<dim,T>::identity(),box.getP1()),cellListSpaceBox(box),cellListGrid(div)
1524  {
1525  Initialize(pad,div);
1526  }
1527 
1535  CellDecomposer_sm(const CellDecomposer_sm<dim,T,transform_type> & cd, Box<dim,size_t> & ext)
1536  :pointTransform(Matrix<dim,T>::identity(),cd.getOrig())
1537  {
1538  setDimensions(cd,ext);
1539  }
1540 
1541 
1543  CellDecomposer_sm()
1544  :pointTransform(Matrix<dim,T>::identity(),Point<dim,T>::zero_p()),cellTotalCount(0)
1545  {
1546 
1547  }
1548 
1556  inline const Box<dim,T> & getCellBox() const
1557  {
1558  return unitCellSpaceBox;
1559  }
1560 
1566  inline const Matrix<dim,T> & getMat() const
1567  {
1568  return pointTransform.getMat();
1569  }
1570 
1576  inline const Point<dim,T> & getOrig() const
1577  {
1578  return pointTransform.getOrig();
1579  }
1580 
1623  inline Box<dim,long int> convertDomainSpaceIntoCellUnits(const Box<dim,T> & b_d, const size_t (& bc)[dim]) const
1624  {
1625  Box<dim,long int> g_box;
1626  Box<dim,T> b = b_d;
1627  b -= getOrig();
1628 
1629  // Convert b into grid units
1630  b /= getCellBox().getP2();
1631 
1632  // Considering that we are interested in a box decomposition of the space
1633  // where each box does not intersect any other boxes in the decomposition we include the negative
1634  // countour and exclude the positive one. So ceilP1 do the job for P1 while ceilP2 - 1
1635  // do the job for P2
1636 
1637  b.floorP1();
1638  b.ceilP2();
1639 
1640  g_box = b;
1641 
1642  // Translate the box by the offset
1643 
1644  for (size_t i = 0 ; i < dim ; i++)
1645  {
1646  g_box.setLow(i,g_box.getLow(i) + off[i]);
1647  g_box.setHigh(i,g_box.getHigh(i) + off[i]);
1648  }
1649 
1650  // on the other hand with non periodic boundary condition, the positive border of the
1651  // sub-domain at the edge of the domain must be included
1652 
1653  Point<dim,size_t> p_move;
1654 
1655  for (size_t i = 0 ; i < dim ; i++)
1656  {
1657  // we are at the positive border (We are assuming that there are not rounding error in the decomposition)
1658  if (b_d.getHigh(i) == cellListSpaceBox.getHigh(i))
1659  {
1660  if (bc[i] == NON_PERIODIC)
1661  {
1662  // Here the positive boundary is included
1663  g_box.setHigh(i,cellListGrid.size(i) - off[i]);
1664  }
1665  else
1666  {
1667  // Carefull in periodic cellListGrid is one bigger than the non-periodic
1668  // and the positive boundary is excluded
1669  g_box.setHigh(i,cellListGrid.size(i)-1 - off[i]);
1670  }
1671  }
1672 
1673 
1674  if (b_d.getLow(i) == cellListSpaceBox.getHigh(i))
1675  {
1676  if (bc[i] == NON_PERIODIC)
1677  {
1678  // The instruction is the same but the meaning is different
1679  // for this reason there is anyway a branch
1680  // Here the border is not included
1681  g_box.setLow(i,cellListGrid.size(i) - off[i]);
1682  }
1683  else
1684  {
1685  // Carefull in periodic cellListGrid is one bigger than the non-periodic
1686  // Here the border is included
1687  g_box.setLow(i,cellListGrid.size(i) - off[i]);
1688  }
1689  }
1690 
1692 
1693  // we are at the positive border (We are assuming that there are not rounding error in the decomposition)
1694  /* coverity[copy_paste_error] */
1695  if (b_d.getHigh(i) == cellListSpaceBox.getLow(i))
1696  g_box.setHigh(i,off[i]);
1697 
1698 
1699  if (b_d.getLow(i) == cellListSpaceBox.getLow(i))
1700  g_box.setLow(i,off[i]);
1701  }
1702 
1703  return g_box;
1704  }
1705 
1706 
1749  inline Box<dim,long int> convertDomainSpaceIntoGridUnits(const Box<dim,T> & b_d, const size_t (& bc)[dim]) const
1750  {
1751  Box<dim,long int> g_box;
1752  Box<dim,T> b = b_d;
1753  b -= getOrig();
1754 
1755  // Convert b into grid units
1756  b /= getCellBox().getP2();
1757 
1758  // Considering that we are interested in a box decomposition of the space
1759  // where each box does not intersect any other boxes in the decomposition we include the negative
1760  // countour and exclude the positive one. So ceilP1 do the job for P1 while ceilP2 - 1
1761  // do the job for P2
1762 
1763  b.ceilP1();
1764 
1765  // (we do -1 later)
1766  b.ceilP2();
1767  for (size_t i = 0 ; i < dim ; i++) {b.setHigh(i,b.getHigh(i)-1);}
1768 
1769  g_box = b;
1770 
1771  // on the other hand with non periodic boundary condition, the positive border of the
1772  // sub-domain at the edge of the domain must be included
1773 
1774  Point<dim,size_t> p_move;
1775 
1776  for (size_t i = 0 ; i < dim ; i++)
1777  {
1778  // we are at the positive border (We are assuming that there are not rounding error in the decomposition)
1779  if (b_d.getHigh(i) == cellListSpaceBox.getHigh(i))
1780  {
1781  if (bc[i] == NON_PERIODIC)
1782  {
1783  // Here the positive boundary is included
1784  g_box.setHigh(i,cellListGrid.size(i) - off[i]);
1785  }
1786  else
1787  {
1788  // Carefull in periodic cellListGrid is one bigger than the non-periodic
1789  // and the positive boundary is excluded
1790  g_box.setHigh(i,cellListGrid.size(i)-1 - off[i]);
1791  }
1792  }
1793 
1794 
1795  if (b_d.getLow(i) == cellListSpaceBox.getHigh(i))
1796  {
1797  if (bc[i] == NON_PERIODIC)
1798  {
1799  // The instruction is the same but the meaning is different
1800  // for this reason there is anyway a branch
1801  // Here the border is not included
1802  g_box.setLow(i,cellListGrid.size(i) - off[i]);
1803  }
1804  else
1805  {
1806  // Carefull in periodic cellListGrid is one bigger than the non-periodic
1807  // Here the border is included
1808  g_box.setLow(i,cellListGrid.size(i) - off[i]);
1809  }
1810  }
1811 
1813 
1814  // we are at the positive border (We are assuming that there are not rounding error in the decomposition)
1815  /* coverity[copy_paste_error] */
1816  if (b_d.getHigh(i) == cellListSpaceBox.getLow(i))
1817  g_box.setHigh(i,off[i]);
1818 
1819 
1820  if (b_d.getLow(i) == cellListSpaceBox.getLow(i))
1821  g_box.setLow(i,off[i]);
1822  }
1823 
1824  return g_box;
1825  }
1826 
1827 
1870  inline Box<dim,T> convertCellUnitsIntoDomainSpace(const Box<dim,long int> & b_d) const
1871  {
1872  Box<dim,T> be;
1873 
1874  for (size_t i = 0 ; i < dim ; i++)
1875  {
1876  if ((long int)cellListGrid.size(i) - (long int)off[i] == b_d.getLow(i))
1877  be.setLow(i,cellListSpaceBox.getHigh(i));
1878  else if ((long int)off[i] == b_d.getLow(i))
1879  be.setLow(i,cellListSpaceBox.getLow(i));
1880  else
1881  be.setLow(i,(b_d.getLow(i) - off[i]) * unitCellSpaceBox.getP2()[i] + cellListSpaceBox.getLow(i));
1882 
1883  if ((long int)cellListGrid.size(i) - (long int)off[i] == b_d.getHigh(i))
1884  be.setHigh(i,cellListSpaceBox.getHigh(i));
1885  else if ((long int)off[i] == b_d.getHigh(i))
1886  be.setHigh(i,cellListSpaceBox.getLow(i));
1887  else
1888  be.setHigh(i,(b_d.getHigh(i) - off[i]) * unitCellSpaceBox.getP2()[i] + cellListSpaceBox.getLow(i));
1889  }
1890 
1891  return be;
1892  }
1893 
1894 
1941  inline Box<dim,T> convertCellUnitsIntoDomainSpaceMiddle(const Box<dim,long int> & b_d) const
1942  {
1943  Box<dim,T> be;
1944 
1945  for (size_t i = 0 ; i < dim ; i++)
1946  {
1947  if ((long int)cellListGrid.size(i) - (long int)off[i] == b_d.getLow(i))
1948  {be.setLow(i,cellListSpaceBox.getHigh(i));}
1949  else if ((long int)off[i] == b_d.getLow(i))
1950  {be.setLow(i,cellListSpaceBox.getLow(i));}
1951  else
1952  {be.setLow(i,(b_d.getLow(i) - off[i]) * unitCellSpaceBox.getP2()[i] + cellListSpaceBox.getLow(i) - unitCellSpaceBox.getP2()[i] / 2.0);}
1953 
1954  if ((long int)cellListGrid.size(i) - (long int)off[i] == b_d.getHigh(i))
1955  {be.setHigh(i,cellListSpaceBox.getHigh(i));}
1956  else if ((long int)off[i] == b_d.getHigh(i))
1957  {be.setHigh(i,cellListSpaceBox.getLow(i));}
1958  else
1959  {be.setHigh(i,(b_d.getHigh(i) - off[i]) * unitCellSpaceBox.getP2()[i] + cellListSpaceBox.getLow(i) + unitCellSpaceBox.getP2()[i] / 2.0);}
1960  }
1961 
1962  return be;
1963  }
1964 
1970  const size_t (& getDiv() const)[dim]
1971  {
1972  return cellListGrid.getSize();
1973  }
1974 
1975 
1981  const size_t (& getDivWP() const)[dim]
1982  {
1983  for (size_t i = 0 ; i < dim ; i++)
1984  {div_wp[i] = cellListGrid.getSize()[i] - 2*getPadding(i);}
1985 
1986  return div_wp;
1987  }
1988 
1994  const Box<dim,T> & getDomain() const
1995  {
1996  return cellListSpaceBox;
1997  }
1998 
2004  inline void swap(CellDecomposer_sm<dim,T,transform_type> & cd)
2005  {
2006  // swap all the members
2007  p_middle.swap(cd.p_middle);
2008 
2009  // Point transformation before get the Cell object (useful for example to shift the cell list)
2010  transform_type t_t = pointTransform;
2011  pointTransform = cd.pointTransform;
2012  cd.pointTransform = t_t;
2013 
2014  // Total number of cell
2015  size_t cellTotalCount_t = cellTotalCount;
2016  cellTotalCount = cd.cellTotalCount;
2017  cd.cellTotalCount = cellTotalCount_t;
2018 
2019  cellListSpaceBox.swap(cd.cellListSpaceBox);
2020  unitCellSpaceBox.swap(cd.unitCellSpaceBox);
2021  cellListGrid.swap(cd.cellListGrid);
2022  gr_cell2.swap(cd.gr_cell2);
2023 
2024  for (size_t i = 0 ; i < dim ; i++)
2025  {
2026  size_t off_t = off[i];
2027  off[i] = cd.off[i];
2028  cd.off[i] = off_t;
2029 
2030  size_t cs_t = cellShift.get(i);
2031  cellShift.get(i) = cd.cellShift.get(i);
2032  cd.cellShift.get(i) = cs_t;
2033  }
2034  }
2035 
2043  inline bool operator==(const CellDecomposer_sm<dim,T,transform_type> & cd)
2044  {
2045  if (meta_compare<Point<dim,T>>::meta_compare_f(p_middle,cd.p_middle) == false)
2046  return false;
2047 
2048  if (pointTransform != cd.pointTransform)
2049  return false;
2050 
2051  if (cellTotalCount != cd.cellTotalCount)
2052  return false;
2053 
2054  if (cellListSpaceBox != cd.cellListSpaceBox)
2055  return false;
2056 
2057  if (unitCellSpaceBox != cd.unitCellSpaceBox)
2058  return false;
2059 
2060  if (cellListGrid != cd.cellListGrid)
2061  return false;
2062 
2063  if (gr_cell2 != cd.gr_cell2)
2064  return false;
2065 
2066  for (size_t i = 0 ; i < dim ; i++)
2067  {
2068  if (off[i] != cd.off[i])
2069  return false;
2070 
2071  if (cellShift.get(i) != cd.cellShift.get(i))
2072  return false;
2073  }
2074 
2075  return true;
2076  }
2077 
2085  inline bool operator!=(const CellDecomposer_sm<dim,T,transform_type> & cd)
2086  {
2087  return ! this->operator==(cd);
2088  }
2089 
2097  size_t getPadding(size_t i) const
2098  {
2099  return off[i];
2100  }
2101 
2108  size_t (& getPadding())[dim]
2109  {
2110  return off;
2111  }
2112 
2121  grid_key_dx<dim> getStartDomainCell() const
2122  {
2123  grid_key_dx<dim> key;
2124 
2125  for (size_t i = 0 ; i < dim ; i++)
2126  {
2127  key.set_d(i, cellShift.get(i));
2128  }
2129 
2130  return key;
2131  }
2132 
2141  grid_key_dx<dim> getStopDomainCell() const
2142  {
2143  grid_key_dx<dim> key;
2144 
2145  for (size_t i = 0 ; i < dim ; i++)
2146  {
2147  key.set_d(i,cellShift.get(i) + gr_cell2.size(i) - 2*getPadding(i) - 1);
2148  }
2149 
2150  return key;
2151  }
2152 
2158  grid_key_dx<dim> getShift() const
2159  {
2160  grid_key_dx<dim> k;
2161 
2162  for (size_t i = 0 ; i < dim ; i++)
2163  k.set_d(i,cellShift.get(i));
2164 
2165  return k;
2166  }
2167 
2173  const grid_sm<dim,void> & getInternalGrid() const
2174  {
2175  return gr_cell2;
2176  }
2177 };
2178 
2179 
2180 #endif /* CELLDECOMPOSER_HPP_ */
This class represent an N-dimensional box.
Definition: Box.hpp:60
Point< dim, T > getP1() const
Get the point p1.
Definition: Box.hpp:707
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:555
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:566
void setP2(const grid_key_dx< dim > &p2)
Set the point P2 of the box.
Definition: Box.hpp:587
Point< dim, T > getP2() const
Get the point p2.
Definition: Box.hpp:721
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:543
void setP1(const grid_key_dx< dim > &p1)
Set the point P1 of the box.
Definition: Box.hpp:576
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:532
void swap(Box< dim, T > &b)
exchange the data of two boxes
Definition: Box.hpp:1277
This class implement an NxN (dense) matrix.
Definition: Matrix.hpp:33
static Matrix< dim, T > identity()
Identity matrix.
Definition: Matrix.hpp:161
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:28
std::string toPointString() const
Convert the point into a string.
Definition: Point.hpp:341
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
std::string toString() const
Return the string with the point coordinate.
Definition: Point.hpp:413
__device__ __host__ void set_d(index_type i, index_type id)
Set the i index.
Definition: grid_key.hpp:516
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition: grid_sm.hpp:326
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:760
__device__ __host__ size_t size_s(unsigned int i) const
Definition: grid_sm.hpp:736
void swap(grid_sm< N, T > &g)
swap the grid_sm informations
Definition: grid_sm.hpp:830
__device__ __host__ size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:657
No transformation.
bool operator!=(const no_transform< dim, T > &nt)
It return always false.
__device__ __host__ T transform(const T(&s)[dim], const int i) const
Shift the point transformation.
bool operator==(const no_transform< dim, T > &nt)
It return always true true.
__device__ __host__ T transform(const encapc< 1, Point< dim, T >, Mem > &s, const int i) const
No transformation.
__device__ __host__ T transform(const Point< dim, T > &s, const int i) const
No transformation.
__device__ __host__ T transform(const T *s, const int i) const
Shift the point transformation.
no_transform_only(const Matrix< dim, T > &t, const Point< dim, T > &s)
Constructor.
void setTransform(const Matrix< dim, T > &mat, const Point< dim, T > &orig)
Set the transformation Matrix and shift.
No transformation.
__device__ __host__ T transform(const encapc< 1, Point< dim, T >, Mem > &s, const size_t i) const
No transformation.
__device__ __host__ T transform(const T(&s)[dim], const size_t i) const
Shift the point transformation.
bool operator!=(const no_transform< dim, T > &nt)
It return always false.
void setTransform(const Matrix< dim, T > &mat, const Point< dim, T > &orig)
Set the transformation Matrix and shift.
Point< dim, T > orig
shift transform
const Point< dim, T > & getOrig() const
Get the origin.
__device__ __host__ T transform(const Point< dim, T > &s, const size_t i) const
No transformation.
__device__ __host__ no_transform(const Matrix< dim, T > &t, const Point< dim, T > &s)
Constructor.
bool operator==(const no_transform< dim, T > &nt)
It return always true true.
Matrix< dim, T > mat
Matrix transform.
const Matrix< dim, T > & getMat() const
Get the transformation Matrix.
shift_only()
Default constructor.
Point< dim, T > sh
Shift point.
bool operator!=(const shift< dim, T > &s)
It return true if the shift is different.
__device__ __host__ const Point< dim, T > & getOrig() const
Get the shift vector.
void setTransform(const Matrix< dim, T > &mat, const Point< dim, T > &orig)
Set the transformation Matrix and shift.
shift_only(const Matrix< dim, T > &t, const Point< dim, T > &s)
Constructor.
__device__ __host__ T transform(const T *s, const int i) const
Shift the point transformation.
__device__ __host__ T transform(const encapc< 1, Point< dim, T >, Mem > &s, const int i) const
Shift the point transformation.
bool operator==(const shift< dim, T > &s)
It return true if the shift match.
__device__ __host__ T transform(const Point< dim, T > &s, const int i) const
Shift the point transformation.
__device__ __host__ T transform(const T(&s)[dim], const int i) const
Shift the point transformation.
__device__ __host__ T transform(const Point< dim, T > &s, const size_t i) const
Shift the point transformation.
Matrix< dim, T > mat
Matrix transformation.
const Point< dim, T > & getOrig() const
Get the shift vector.
__device__ __host__ T transform(const encapc< 1, Point< dim, T >, Mem > &s, const size_t i) const
Shift the point transformation.
bool operator==(const shift< dim, T > &s)
It return true if the shift match.
__device__ __host__ T transform(const T(&s)[dim], const size_t i) const
Shift the point transformation.
__device__ __host__ shift(const Matrix< dim, T > &t, const Point< dim, T > &s)
Constructor.
bool operator!=(const shift< dim, T > &s)
It return true if the shift is different.
__device__ __host__ void setTransform(const Matrix< dim, T > &mat, const Point< dim, T > &orig)
Set the transformation Matrix and shift.
const Matrix< dim, T > & getMat() const
Get the transformation Matrix.
Point< dim, T > sh
Shift point.
This class compare general objects.