OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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 #include "Grid/grid_sm.hpp"
15 
16 #define CELL_DECOMPOSER 8001lu
17 
18 
19 
20 
25 template<unsigned int dim, typename T>
26 class shift
27 {
30 
33 
34 public:
35 
42  shift(const Matrix<dim,T> & t, const Point<dim,T> & s)
43  :sh(s)
44  {
45  mat.identity();
46  }
47 
56  inline T transform(const T(&s)[dim], const size_t i) const
57  {
58  return s[i] - sh.get(i);
59  }
60 
69  inline T transform(const Point<dim,T> & s, const size_t i) const
70  {
71  return s.get(i) - sh.get(i);
72  }
73 
82  template<typename Mem> inline T transform(const encapc<1,Point<dim,T>,Mem> & s, const size_t i) const
83  {
84  return s.template get<0>()[i] - sh.get(i);
85  }
86 
93  inline void setTransform(const Matrix<dim,T> & mat, const Point<dim,T> & orig)
94  {
95  for (size_t i = 0 ; i < dim ; i++)
96  sh.get(i) = orig.get(i);
97  }
98 
104  inline const Point<dim,T> & getOrig() const
105  {
106  return sh;
107  }
108 
114  inline const Matrix<dim,T> & getMat() const
115  {
116  return mat;
117  }
118 
126  inline bool operator==(const shift<dim,T> & s)
127  {
128  return sh == s.sh;
129  }
130 
138  inline bool operator!=(const shift<dim,T> & s)
139  {
140  return !this->operator==(s);
141  }
142 };
143 
144 
145 
147 template<unsigned int dim, typename T>
149 {
152 
155 
156 public:
157 
165  {
166  orig.zero();
167  mat.identity();
168  }
169 
178  inline T transform(const T(&s)[dim], const size_t i) const
179  {
180  return s[i];
181  }
182 
191  inline T transform(const Point<dim,T> & s, const size_t i) const
192  {
193  return s.get(i);
194  }
195 
204  template<typename Mem> inline T transform(const encapc<1,Point<dim,T>,Mem> & s, const size_t i) const
205  {
206  return s.template get<Point<dim,T>::x>()[i];
207  }
208 
215  inline void setTransform(const Matrix<dim,T> & mat, const Point<dim,T> & orig)
216  {
217 
218  }
219 
229  inline bool operator==(const no_transform<dim,T> & nt)
230  {
231  return true;
232  }
233 
243  inline bool operator!=(const no_transform<dim,T> & nt)
244  {
245  return false;
246  }
247 
253  inline const Point<dim,T> & getOrig() const
254  {
255  return orig;
256  }
257 
263  inline const Matrix<dim,T> & getMat() const
264  {
265  return mat;
266  }
267 };
268 
269 
310 template<unsigned int dim,typename T, typename transform = no_transform<dim,T>>
311 class CellDecomposer_sm
312 {
313  // Point in the middle of a cell
314  //
315  // \verbatim
316  //
317  // C (0.1,0.1)
318  // +-----+
319  // | |
320  // | .P |
321  // | |
322  // +-----+
323  //
324  // \endverbatim
325  //
326  // C is the cell and P is the point inside the middle of the cell
327  // for example if the cell is (0.1,0.1) P is (0.05,0.05)
328  //
329  //
330  Point<dim,T> p_middle;
331 
332  // Point transformation before get the Cell object (useful for example to shift the cell list)
333  transform t;
334 
341  inline size_t ConvertToID(const T (&x)[dim] ,size_t s) const
342  {
343  size_t id = openfpm::math::size_t_floor(t.transform(x,s) / box_unit.getHigh(s)) + off[s];
344  id = (id >= gr_cell.size(s))?(gr_cell.size(s)-1-cell_shift.get(s)):id-cell_shift.get(s);
345  return id;
346  }
347 
354  inline size_t ConvertToID(const Point<dim,T> & x ,size_t s, size_t sc = 0) const
355  {
356  size_t id = openfpm::math::size_t_floor(t.transform(x,s) / box_unit.getHigh(s)) + off[s];
357  id = (id >= gr_cell.size(s))?(gr_cell.size(s)-1-cell_shift.get(s)):id-cell_shift.get(s);
358  return id;
359  }
360 
367  inline size_t ConvertToID_ns(const T (&x)[dim] ,size_t s) const
368  {
369  size_t id = openfpm::math::size_t_floor(t.transform(x,s) / box_unit.getHigh(s)) + off[s];
370  id = (id >= gr_cell.size(s))?(gr_cell.size(s)-1):id;
371  return id;
372  }
373 
380  inline size_t ConvertToID_ns(const Point<dim,T> & x ,size_t s, size_t sc = 0) const
381  {
382  size_t id = openfpm::math::size_t_floor(t.transform(x,s) / box_unit.getHigh(s)) + off[s];
383  id = (id >= gr_cell.size(s))?(gr_cell.size(s)-1):id;
384  return id;
385  }
386 
393  template <typename Mem> inline size_t ConvertToID_(const encapc<1,Point<dim,T>,Mem> & x ,size_t s, size_t sc = 0) const
394  {
395  size_t id = (size_t)(t.transform(x,s) / box_unit.getHigh(s)) + off[s];
396  id = (id >= gr_cell.size(s))?(gr_cell.size(s)-1-cell_shift.get(s)):id-cell_shift.get(s);
397  return id;
398  }
399 
406  template<typename Ele> inline void check_and_print_error(const Ele & pos ,size_t s) const
407  {
408 #ifdef SE_CLASS1
409  if (tot_n_cell == 0)
410  {
411  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
412  ACTION_ON_ERROR(CELL_DECOMPOSER);
413  }
414 
415  if (pos[0] < box.getLow(s) - off[s]*box_unit.getP2()[s] || pos[s] > box.getHigh(s) + off[s]*box_unit.getP2()[s])
416  {
417  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << Point<dim,T>(pos).toString() << " is not inside the cell space";
418  ACTION_ON_ERROR(CELL_DECOMPOSER);
419  }
420 #endif
421  }
422 
423 
424  template<typename Ele> inline size_t getCellDom_impl(const Ele & pos) const
425  {
426  check_and_print_error(pos,0);
427 
428  size_t cell_id = ConvertToID_ns(pos,0);
429 
430  cell_id = (cell_id == gr_cell.size(0) - off[0])?gr_cell.size(0) - off[0] - 1:cell_id;
431  cell_id = (cell_id == off[0]-1)?off[0]:cell_id;
432 
433  cell_id -= cell_shift.get(0);
434 
435  for (size_t s = 1 ; s < dim ; s++)
436  {
437  /* coverity[dead_error_begin] */
438  check_and_print_error(pos,s);
439 
440  size_t cell_idt = ConvertToID_ns(pos,s);
441 
442  cell_idt = (cell_idt == gr_cell.size(s) - off[s])?gr_cell.size(s) - off[s] - 1:cell_idt;
443  cell_idt = (cell_idt == off[s]-1)?off[s]:cell_idt;
444 
445  cell_idt -= cell_shift.get(s);
446 
447  cell_id += gr_cell2.size_s(s-1) * cell_idt;
448  }
449 
450  return cell_id;
451  }
452 
453  template<typename Ele> inline size_t getCellPad_impl(const Ele & pos) const
454  {
455  check_and_print_error(pos,0);
456 
457  size_t cell_id = ConvertToID_ns(pos,0);
458  cell_id = (cell_id == off[0])?off[0]-1:cell_id;
459  cell_id = (cell_id == gr_cell.size(0) - off[0] - 1)?gr_cell.size(0) - off[0]:cell_id;
460 
461  cell_id -= cell_shift.get(0);
462 
463  for (size_t s = 1 ; s < dim ; s++)
464  {
465  check_and_print_error(pos,s);
466 
467  size_t cell_idt = ConvertToID_ns(pos,s);
468  cell_idt = (cell_idt == off[s])?off[s]-1:cell_idt;
469  cell_idt = (cell_idt == gr_cell.size(s) - off[s] - 1)?gr_cell.size(s) - off[s]:cell_idt;
470 
471  cell_idt -= cell_shift.get(s);
472 
473  cell_id += gr_cell2.size_s(s-1) * cell_idt;
474  }
475 
476  return cell_id;
477  }
478 
479 
480 protected:
481 
483  size_t tot_n_cell;
484 
486  SpaceBox<dim,T> box;
487 
489  SpaceBox<dim,T> box_unit;
490 
492  grid_sm<dim,void> gr_cell;
493 
495  grid_sm<dim,void> gr_cell2;
496 
498  Box<dim,T> box_gr_cell2;
499 
501  size_t off[dim];
502 
504  Point<dim,long int> cell_shift;
505 
506  // temporal buffer
507  mutable size_t div_wp[dim];
508 
512  void Initialize(const size_t pad, const size_t (& div)[dim])
513  {
514 #ifdef SE_CLASS1
515 
516  for (size_t i = 0 ; i < dim ; i++)
517  {
518  if (div[i] == 0)
519  {
520  std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " the number of cells on each dimension must be different from zero\n";
521  ACTION_ON_ERROR(CELL_DECOMPOSER)
522  }
523  }
524 
525 #endif
526 
527  // created a padded div
528  size_t div_p[dim];
529 
530  for (size_t i = 0 ; i < dim ; i++)
531  div_p[i] = div[i] + 2*pad;
532 
533  gr_cell.setDimensions(div_p);
534  gr_cell2.setDimensions(div_p);
535 
536  tot_n_cell = 1;
537 
538  // Total number of cells and calculate the unit cell size
539 
540  for (size_t i = 0 ; i < dim ; i++)
541  {
542  tot_n_cell *= gr_cell.size(i);
543 
544  // Cell are padded by
545  box_unit.setHigh(i,(box.getHigh(i) - box.getLow(i)) / (gr_cell.size(i)- 2*pad) );
546  }
547 
548  for (size_t i = 0; i < dim ; i++)
549  off[i] = pad;
550 
551  // Initialize p_middle
552 
553  p_middle = box_unit.getP2();
554  p_middle = p_middle / 2;
555  }
556 
557 public:
558 
564  const grid_sm<dim,void> & getGrid() const
565  {
566 #ifdef DEBUG
567  if (tot_n_cell == 0)
568  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
569 #endif
570 
571  return gr_cell;
572  }
573 
583  inline grid_key_dx<dim> getCellGrid(const T (& pos)[dim]) const
584  {
585 #ifdef SE_CLASS1
586  if (tot_n_cell == 0)
587  {
588  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
589  ACTION_ON_ERROR(CELL_DECOMPOSER);
590  }
591 #endif
592 
594  key.set_d(0,ConvertToID(pos,0));
595 
596  for (size_t s = 1 ; s < dim ; s++)
597  {
598 #ifdef SE_CLASS1
599  if ((size_t)(t.transform(pos,s) / box_unit.getHigh(s)) + off[s] < 0)
600  {
601  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point is not inside the cell space\n";
602  ACTION_ON_ERROR(CELL_DECOMPOSER);
603  }
604 #endif
605  key.set_d(s,ConvertToID(pos,s));
606 
607  }
608 
609  return key;
610  }
611 
621  inline size_t getCellLin(grid_key_dx<dim> && k) const
622  {
623 #ifdef SE_CLASS1
624  if (tot_n_cell == 0)
625  {
626  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
627  ACTION_ON_ERROR(CELL_DECOMPOSER);
628  }
629 
630  if (gr_cell2.size(0) < k.get(0) + off[0] - cell_shift.get(0))
631  {
632  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " cell coordinate 0 = " << k.get(0) + off[0] - cell_shift.get(0) << " bigger than cell space " << gr_cell2.size(0) << std::endl;
633  ACTION_ON_ERROR(CELL_DECOMPOSER);
634  }
635 #endif
636 
637  size_t cell_id = k.get(0) + off[0] - cell_shift.get(0);
638 
639  for (size_t s = 1 ; s < dim ; s++)
640  {
641 #ifdef SE_CLASS1
642  if (gr_cell2.size(s) < k.get(s) + off[s] - cell_shift.get(s))
643  {
644  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " cell coordinate 0 = " << k.get(0) + off[0] - cell_shift.get(0) << " bigger than cell space " << gr_cell2.size(s) << std::endl;
645  ACTION_ON_ERROR(CELL_DECOMPOSER);
646  }
647 #endif
648  cell_id += gr_cell2.size_s(s-1) * (k.get(s) + off[s] -cell_shift.get(s));
649  }
650 
651  return cell_id;
652  }
653 
663  inline size_t getCellLin(const grid_key_dx<dim> & k) const
664  {
665 #ifdef SE_CLASS1
666  if (tot_n_cell == 0)
667  {
668  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
669  ACTION_ON_ERROR(CELL_DECOMPOSER);
670  }
671 
672  if (gr_cell2.size(0) < k.get(0) + off[0] - cell_shift.get(0))
673  {
674  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " cell coordinate 0 = " << k.get(0) + off[0] - cell_shift.get(0) << " bigger than cell space " << gr_cell2.size(0) << std::endl;
675  ACTION_ON_ERROR(CELL_DECOMPOSER);
676  }
677 #endif
678 
679  size_t cell_id = k.get(0) + off[0] -cell_shift.get(0);
680 
681  for (size_t s = 1 ; s < dim ; s++)
682  {
683 #ifdef SE_CLASS1
684  if (gr_cell2.size(s) < k.get(s) + off[s] - cell_shift.get(s))
685  {
686  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " cell coordinate 0 = " << k.get(0) + off[0] - cell_shift.get(0) << " bigger than cell space " << gr_cell2.size(s) << std::endl;
687  ACTION_ON_ERROR(CELL_DECOMPOSER);
688  }
689 #endif
690  cell_id += gr_cell2.size_s(s-1) * (k.get(s) + off[s] -cell_shift.get(s));
691  }
692 
693  return cell_id;
694  }
695 
705  inline grid_key_dx<dim> getCellGrid(const Point<dim,T> & pos) const
706  {
707 #ifdef SE_CLASS1
708  if (tot_n_cell == 0)
709  {
710  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer" << std::endl;
711  ACTION_ON_ERROR(CELL_DECOMPOSER);
712  }
713 #endif
714 
715  grid_key_dx<dim> key;
716  key.set_d(0,ConvertToID(pos,0));
717 
718  for (size_t s = 1 ; s < dim ; s++)
719  {
720 #ifdef SE_CLASS1
721  if ((size_t)(t.transform(pos,s) / box_unit.getHigh(s)) + off[s] < 0)
722  {
723  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point is not inside the cell space" << std::endl;
724  ACTION_ON_ERROR(CELL_DECOMPOSER);
725  }
726 #endif
727  /* coverity[dead_error_line] */
728  key.set_d(s,ConvertToID(pos,s));
729  }
730 
731  return key;
732  }
733 
745  inline size_t getCellDom(const Point<dim,T> & pos) const
746  {
747  return getCellDom_impl<Point<dim,T>>(pos);
748  }
749 
750 
762  inline size_t getCellDom(const T (& pos)[dim]) const
763  {
764  return getCellDom_impl<T[dim]>(pos);
765  }
766 
778  inline size_t getCellPad(const Point<dim,T> & pos) const
779  {
780  return getCellPad_impl<Point<dim,T>>(pos);
781  }
782 
794  inline size_t getCellPad(const T (& pos)[dim]) const
795  {
796  return getCellPad_impl<T[dim]>(pos);
797  }
798 
808  inline size_t getCell(const T (& pos)[dim]) const
809  {
810 #ifdef SE_CLASS1
811  if (tot_n_cell == 0)
812  {
813  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
814  ACTION_ON_ERROR(CELL_DECOMPOSER);
815  }
816 
817  if (pos[0] < box.getLow(0) - off[0]*box_unit.getP2()[0] || pos[0] > box.getHigh(0) + off[0]*box_unit.getP2()[0])
818  {
819  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
820  ACTION_ON_ERROR(CELL_DECOMPOSER);
821  }
822 #endif
823 
824  size_t cell_id = ConvertToID(pos,0);
825 
826  for (size_t s = 1 ; s < dim ; s++)
827  {
828 #ifdef SE_CLASS1
829  if (pos[s] < box.getLow(s) - off[s]*box_unit.getP2()[s] || pos[s] > box.getHigh(s) + off[s]*box_unit.getP2()[s])
830  {
831  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
832  ACTION_ON_ERROR(CELL_DECOMPOSER);
833  }
834 #endif
835  cell_id += gr_cell2.size_s(s-1) * ConvertToID(pos,s);
836  }
837 
838  return cell_id;
839  }
840 
850  inline size_t getCell(const Point<dim,T> & pos) const
851  {
852 #ifdef SE_CLASS1
853  if (tot_n_cell == 0)
854  {
855  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
856  ACTION_ON_ERROR(CELL_DECOMPOSER);
857  }
858 
859  if (pos.get(0) < box.getLow(0) - off[0]*box_unit.getP2()[0] || pos.get(0) > box.getHigh(0) + off[0]*box_unit.getP2()[0])
860  {
861  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << pos.toPointString() << " is not inside the cell space";
862  ACTION_ON_ERROR(CELL_DECOMPOSER);
863  }
864 #endif
865 
866  size_t cell_id = ConvertToID(pos,0);
867 
868  for (size_t s = 1 ; s < dim ; s++)
869  {
870 #ifdef SE_CLASS1
871  if (pos.get(s) < box.getLow(s) - off[s]*box_unit.getP2()[s] || pos.get(s) > box.getHigh(s) + off[s]*box_unit.getP2()[s])
872  {
873  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << pos.toPointString() << " is not inside the cell space";
874  ACTION_ON_ERROR(CELL_DECOMPOSER);
875  }
876 #endif
877  /* coverity[dead_error_line] */
878  cell_id += gr_cell2.size_s(s-1) * ConvertToID(pos,s);
879  }
880 
881  return cell_id;
882  }
883 
893  template<typename Mem> inline size_t getCell(const encapc<1,Point<dim,T>,Mem> & pos) const
894  {
895 
896 #ifdef SE_CLASS1
897  if (tot_n_cell == 0)
898  {
899  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " using an uninitialized CellDecomposer";
900  ACTION_ON_ERROR(CELL_DECOMPOSER);
901  }
902 
903  if (pos.template get<0>()[0] < box.getLow(0) - off[0]*box_unit.getP2()[0] || pos.template get<0>()[0] > box.getHigh(0) + off[0]*box_unit.getP2()[0])
904  {
905  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space " << box.toString() << std::endl;
906  ACTION_ON_ERROR(CELL_DECOMPOSER);
907  }
908 #endif
909 
910  size_t cell_id = ConvertToID_(pos,0);
911 
912  for (size_t s = 1 ; s < dim ; s++)
913  {
914 #ifdef SE_CLASS1
915 
916  if (pos.template get<0>()[s] < box.getLow(s) - off[s]*box_unit.getP2()[s] || pos.template get<0>()[s] > box.getHigh(s) + off[s]*box_unit.getP2()[s])
917  {
918  std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " point " << toPointString(pos) << " is not inside the cell space";
919  ACTION_ON_ERROR(CELL_DECOMPOSER);
920  }
921 #endif
922  cell_id += gr_cell2.size_s(s-1) * ConvertToID_(pos,s);
923  }
924 
925  return cell_id;
926  }
927 
960  inline Box<dim,size_t> getGridPoints(const Box<dim,T> & s_box) const
961  {
962  // Box with inside grid
963  Box<dim,size_t> bx;
964 
965  // Point p2
966  Point<dim,T> p2 = s_box.getP2();
967  p2 = p2 - p_middle;
968 
969  // Point p1
970  Point<dim,T> p1 = s_box.getP1();
971  p1 = p1 + p_middle;
972 
973  bx.setP2(getCellGrid(p2));
974  bx.setP1(getCellGrid(p1));
975 
976  return bx;
977  }
978 
986  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> cell_shift)
987  {
988  Matrix<dim,T> mat;
989  mat.identity();
990  t.setTransform(mat,box.getP1());
991  this->box = box;
992 
993  Initialize(pad,div);
994 
995  // calculate the box for gr_cell2
996 /* Box<dim,T> box_gr_cell2;
997 
998  for (size_t i = 0 ; i < dim ; i++)
999  {
1000  box_gr_cell2.setLow(i,cell_shift.get(i) * box_unit.getHigh(i));
1001  box_gr_cell2.setHigh(i,(cell_shift.get(i) + div2[i]) * box_unit.getHigh(i));
1002  }*/
1003 
1004  size_t cells[dim];
1005 
1006  for (size_t i = 0 ; i < dim ; i++)
1007  cells[i] = div2[i] + 2*pad;
1008 
1009  gr_cell2.setDimensions(cells);
1010 
1011  for (size_t i = 0 ; i < dim ; i++)
1012  this->cell_shift.get(i) = cell_shift.get(i) - off[i];
1013  }
1014 
1022  inline void setDimensions(const Box<dim,T> & box, const size_t (&div)[dim], const size_t pad)
1023  {
1024  Matrix<dim,T> mat;
1025  mat.identity();
1026  t.setTransform(mat,box.getP1());
1027  this->box = box;
1028  Initialize(pad,div);
1029  this->cell_shift = 0;
1030  }
1031 
1042  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> cell_shift)
1043  {
1044  t.setTransform(mat,box.getP1());
1045  this->box = box;
1046 
1047  Initialize(pad,div);
1048 
1049  // The nested cell is big div2 + 2*off
1050 
1051  size_t div_with_off[dim];
1052 
1053  for(size_t i = 0 ; i < dim ; i++)
1054  div_with_off[i] = div2[i] + 2*off[i];
1055 
1056  gr_cell2.setDimensions(div_with_off);
1057 
1058  for (size_t i = 0 ; i < dim ; i++)
1059  this->cell_shift.get(i) = cell_shift.get(i) - off[i];
1060  }
1061 
1071  inline void setDimensions(const Box<dim,T> & box, const size_t (&div)[dim], const Matrix<dim,T> & mat, const size_t pad)
1072  {
1073  t.setTransform(mat,box.getP1());
1074  this->box = box;
1075  Initialize(pad,div);
1076  this->cell_shift = 0;
1077  }
1078 
1079 
1091  inline void setDimensions(const CellDecomposer_sm<dim,T,transform> & cd, const Box<dim,size_t> & cell_extension)
1092  {
1093  this->cell_shift = 0;
1094 
1095  // Get the space transformation
1096 
1097  t.setTransform(cd.getMat(),cd.getOrig());
1098 
1099  // The domain is equivalent to the old one
1100  this->box = cd.box;
1101 
1102  // The padding must be calculated
1103 
1104  size_t pad = 0;
1105 
1106  for (size_t i = 0 ; i < dim ; i++)
1107  {
1108  if (pad < cell_extension.getLow(i))
1109  pad = cell_extension.getLow(i);
1110  else if (pad > cell_extension.getHigh(i))
1111  pad = cell_extension.getHigh(i);
1112  }
1113 
1114  // We have to give the old division
1115 
1116  size_t sz_div[dim];
1117 
1118  for (size_t i = 0 ; i < dim ; i++)
1119  sz_div[i] = cd.gr_cell.size(i) - 2*cd.off[i];
1120 
1121  Initialize(pad,sz_div);
1122  }
1123 
1153  CellDecomposer_sm(const SpaceBox<dim,T> & box, const size_t (&div)[dim], Matrix<dim,T> & mat, const size_t pad)
1154  :t(Matrix<dim,T>::identity(),box.getP1()),box(box),gr_cell()
1155  {
1156  Initialize(pad);
1157  }
1158 
1188  CellDecomposer_sm(const SpaceBox<dim,T> & box, const size_t (&div)[dim], const size_t pad)
1189  :t(Matrix<dim,T>::identity(),box.getP1()),box(box),gr_cell(div)
1190  {
1191  Initialize(pad,div);
1192  }
1193 
1201  CellDecomposer_sm(const CellDecomposer_sm<dim,T,transform> & cd, Box<dim,size_t> & ext)
1202  :t(Matrix<dim,T>::identity(),cd.getOrig())
1203  {
1204  setDimensions(cd,ext);
1205  }
1206 
1207 
1209  CellDecomposer_sm()
1210  :t(Matrix<dim,T>::identity(),Point<dim,T>::zero_p()),tot_n_cell(0)
1211  {
1212 
1213  }
1214 
1222  inline const Box<dim,T> & getCellBox() const
1223  {
1224  return box_unit;
1225  }
1226 
1232  inline const Matrix<dim,T> & getMat() const
1233  {
1234  return t.getMat();
1235  }
1236 
1242  inline const Point<dim,T> & getOrig() const
1243  {
1244  return t.getOrig();
1245  }
1246 
1289  inline Box<dim,long int> convertDomainSpaceIntoCellUnits(const Box<dim,T> & b_d, const size_t (& bc)[dim]) const
1290  {
1291  Box<dim,long int> g_box;
1292  Box<dim,T> b = b_d;
1293  b -= getOrig();
1294 
1295  // Convert b into grid units
1296  b /= getCellBox().getP2();
1297 
1298  // Considering that we are interested in a box decomposition of the space
1299  // where each box does not intersect any other boxes in the decomposition we include the negative
1300  // countour and exclude the positive one. So ceilP1 do the job for P1 while ceilP2 - 1
1301  // do the job for P2
1302 
1303  b.floorP1();
1304  b.ceilP2();
1305 
1306  g_box = b;
1307 
1308  // Translate the box by the offset
1309 
1310  for (size_t i = 0 ; i < dim ; i++)
1311  {
1312  g_box.setLow(i,g_box.getLow(i) + off[i]);
1313  g_box.setHigh(i,g_box.getHigh(i) + off[i]);
1314  }
1315 
1316  // on the other hand with non periodic boundary condition, the positive border of the
1317  // sub-domain at the edge of the domain must be included
1318 
1319  Point<dim,size_t> p_move;
1320 
1321  for (size_t i = 0 ; i < dim ; i++)
1322  {
1323  // we are at the positive border (We are assuming that there are not rounding error in the decomposition)
1324  if (b_d.getHigh(i) == box.getHigh(i))
1325  {
1326  if (bc[i] == NON_PERIODIC)
1327  {
1328  // Here the positive boundary is included
1329  g_box.setHigh(i,gr_cell.size(i) - off[i]);
1330  }
1331  else
1332  {
1333  // Carefull in periodic gr_cell is one bigger than the non-periodic
1334  // and the positive boundary is excluded
1335  g_box.setHigh(i,gr_cell.size(i)-1 - off[i]);
1336  }
1337  }
1338 
1339 
1340  if (b_d.getLow(i) == box.getHigh(i))
1341  {
1342  if (bc[i] == NON_PERIODIC)
1343  {
1344  // The instruction is the same but the meaning is different
1345  // for this reason there is anyway a branch
1346  // Here the border is not included
1347  g_box.setLow(i,gr_cell.size(i) - off[i]);
1348  }
1349  else
1350  {
1351  // Carefull in periodic gr_cell is one bigger than the non-periodic
1352  // Here the border is included
1353  g_box.setLow(i,gr_cell.size(i) - off[i]);
1354  }
1355  }
1356 
1358 
1359  // we are at the positive border (We are assuming that there are not rounding error in the decomposition)
1360  /* coverity[copy_paste_error] */
1361  if (b_d.getHigh(i) == box.getLow(i))
1362  g_box.setHigh(i,off[i]);
1363 
1364 
1365  if (b_d.getLow(i) == box.getLow(i))
1366  g_box.setLow(i,off[i]);
1367  }
1368 
1369  return g_box;
1370  }
1371 
1372 
1415  inline Box<dim,long int> convertDomainSpaceIntoGridUnits(const Box<dim,T> & b_d, const size_t (& bc)[dim]) const
1416  {
1417  Box<dim,long int> g_box;
1418  Box<dim,T> b = b_d;
1419  b -= getOrig();
1420 
1421  // Convert b into grid units
1422  b /= getCellBox().getP2();
1423 
1424  // Considering that we are interested in a box decomposition of the space
1425  // where each box does not intersect any other boxes in the decomposition we include the negative
1426  // countour and exclude the positive one. So ceilP1 do the job for P1 while ceilP2 - 1
1427  // do the job for P2
1428 
1429  b.ceilP1();
1430 
1431  // (we do -1 later)
1432  b.ceilP2();
1433  for (size_t i = 0 ; i < dim ; i++) {b.setHigh(i,b.getHigh(i)-1);}
1434 
1435  g_box = b;
1436 
1437  // on the other hand with non periodic boundary condition, the positive border of the
1438  // sub-domain at the edge of the domain must be included
1439 
1440  Point<dim,size_t> p_move;
1441 
1442  for (size_t i = 0 ; i < dim ; i++)
1443  {
1444  // we are at the positive border (We are assuming that there are not rounding error in the decomposition)
1445  if (b_d.getHigh(i) == box.getHigh(i))
1446  {
1447  if (bc[i] == NON_PERIODIC)
1448  {
1449  // Here the positive boundary is included
1450  g_box.setHigh(i,gr_cell.size(i) - off[i]);
1451  }
1452  else
1453  {
1454  // Carefull in periodic gr_cell is one bigger than the non-periodic
1455  // and the positive boundary is excluded
1456  g_box.setHigh(i,gr_cell.size(i)-1 - off[i]);
1457  }
1458  }
1459 
1460 
1461  if (b_d.getLow(i) == box.getHigh(i))
1462  {
1463  if (bc[i] == NON_PERIODIC)
1464  {
1465  // The instruction is the same but the meaning is different
1466  // for this reason there is anyway a branch
1467  // Here the border is not included
1468  g_box.setLow(i,gr_cell.size(i) - off[i]);
1469  }
1470  else
1471  {
1472  // Carefull in periodic gr_cell is one bigger than the non-periodic
1473  // Here the border is included
1474  g_box.setLow(i,gr_cell.size(i) - off[i]);
1475  }
1476  }
1477 
1479 
1480  // we are at the positive border (We are assuming that there are not rounding error in the decomposition)
1481  /* coverity[copy_paste_error] */
1482  if (b_d.getHigh(i) == box.getLow(i))
1483  g_box.setHigh(i,off[i]);
1484 
1485 
1486  if (b_d.getLow(i) == box.getLow(i))
1487  g_box.setLow(i,off[i]);
1488  }
1489 
1490  return g_box;
1491  }
1492 
1493  inline Box<dim,long int> convertDomainSpaceIntoCellUnitsNear(const Box<dim,T> & b_d) const
1494  {
1495  Box<dim,long int> g_box;
1496  Box<dim,T> b = b_d;
1497  b -= getOrig();
1498 
1499  // Convert b into grid units
1500  b /= getCellBox().getP2();
1501 
1502  // Considering that we are interested in a box decomposition of the space
1503  // where each box does not intersect any other boxes in the decomposition we include the negative
1504  // countour and exclude the positive one. So ceilP1 do the job for P1 while ceilP2 - 1
1505  // do the job for P2
1506 
1507  for (size_t i = 0 ; i < dim ; i++)
1508  {
1509  b.setLow(i,b.getLow(i) + 0.125);
1510  b.setHigh(i,b.getHigh(i) + 0.125);
1511  }
1512 
1513  b.floorP1();
1514  b.floorP2();
1515 
1516  g_box = b;
1517 
1518  // Translate the box by the offset
1519 
1520  for (size_t i = 0 ; i < dim ; i++)
1521  {
1522  g_box.setLow(i,g_box.getLow(i) + off[i]);
1523  g_box.setHigh(i,g_box.getHigh(i) + off[i]);
1524  }
1525 
1526 
1527  return g_box;
1528  }
1529 
1571  inline Box<dim,T> convertCellUnitsIntoDomainSpace(const Box<dim,long int> & b_d) const
1572  {
1573  Box<dim,T> be;
1574 
1575  for (size_t i = 0 ; i < dim ; i++)
1576  {
1577  if ((long int)gr_cell.size(i) - (long int)off[i] == b_d.getLow(i))
1578  be.setLow(i,box.getHigh(i));
1579  else if ((long int)off[i] == b_d.getLow(i))
1580  be.setLow(i,box.getLow(i));
1581  else
1582  be.setLow(i,(b_d.getLow(i) - off[i]) * box_unit.getP2()[i] + box.getLow(i));
1583 
1584  if ((long int)gr_cell.size(i) - (long int)off[i] == b_d.getHigh(i))
1585  be.setHigh(i,box.getHigh(i));
1586  else if ((long int)off[i] == b_d.getHigh(i))
1587  be.setHigh(i,box.getLow(i));
1588  else
1589  be.setHigh(i,(b_d.getHigh(i) - off[i]) * box_unit.getP2()[i] + box.getLow(i));
1590  }
1591 
1592  return be;
1593  }
1594 
1600  const size_t (& getDiv() const)[dim]
1601  {
1602  return gr_cell.getSize();
1603  }
1604 
1605 
1611  const size_t (& getDivWP() const)[dim]
1612  {
1613  for (size_t i = 0 ; i < dim ; i++)
1614  {div_wp[i] = gr_cell.getSize()[i] - 2*getPadding(i);}
1615 
1616  return div_wp;
1617  }
1618 
1624  const Box<dim,T> & getDomain() const
1625  {
1626  return box;
1627  }
1628 
1634  inline void swap(CellDecomposer_sm<dim,T,transform> & cd)
1635  {
1636  // swap all the members
1637  p_middle.swap(cd.p_middle);
1638 
1639  // Point transformation before get the Cell object (useful for example to shift the cell list)
1640  transform t_t = t;
1641  t = cd.t;
1642  cd.t = t_t;
1643 
1644  // Total number of cell
1645  size_t tot_n_cell_t = tot_n_cell;
1646  tot_n_cell = cd.tot_n_cell;
1647  cd.tot_n_cell = tot_n_cell_t;
1648 
1649  box.swap(cd.box);
1650  box_unit.swap(cd.box_unit);
1651  gr_cell.swap(cd.gr_cell);
1652  gr_cell2.swap(cd.gr_cell2);
1653 
1654  for (size_t i = 0 ; i < dim ; i++)
1655  {
1656  size_t off_t = off[i];
1657  off[i] = cd.off[i];
1658  cd.off[i] = off_t;
1659 
1660  size_t cs_t = cell_shift.get(i);
1661  cell_shift.get(i) = cd.cell_shift.get(i);
1662  cd.cell_shift.get(i) = cs_t;
1663  }
1664  }
1665 
1673  inline bool operator==(const CellDecomposer_sm<dim,T,transform> & cd)
1674  {
1675  if (meta_compare<Point<dim,T>>::meta_compare_f(p_middle,cd.p_middle) == false)
1676  return false;
1677 
1678  if (t != cd.t)
1679  return false;
1680 
1681  if (tot_n_cell != cd.tot_n_cell)
1682  return false;
1683 
1684  if (box != cd.box)
1685  return false;
1686 
1687  if (box_unit != cd.box_unit)
1688  return false;
1689 
1690  if (gr_cell != cd.gr_cell)
1691  return false;
1692 
1693  if (gr_cell2 != cd.gr_cell2)
1694  return false;
1695 
1696  for (size_t i = 0 ; i < dim ; i++)
1697  {
1698  if (off[i] != cd.off[i])
1699  return false;
1700 
1701  if (cell_shift.get(i) != cd.cell_shift.get(i))
1702  return false;
1703  }
1704 
1705  return true;
1706  }
1707 
1715  inline bool operator!=(const CellDecomposer_sm<dim,T,transform> & cd)
1716  {
1717  return ! this->operator==(cd);
1718  }
1719 
1727  size_t getPadding(size_t i) const
1728  {
1729  return off[i];
1730  }
1731 
1738  size_t (& getPadding())[dim]
1739  {
1740  return off;
1741  }
1742 
1751  grid_key_dx<dim> getStartDomainCell() const
1752  {
1753  grid_key_dx<dim> key;
1754 
1755  for (size_t i = 0 ; i < dim ; i++)
1756  {
1757  key.set_d(i, cell_shift.get(i));
1758  }
1759 
1760  return key;
1761  }
1762 
1771  grid_key_dx<dim> getStopDomainCell() const
1772  {
1773  grid_key_dx<dim> key;
1774 
1775  for (size_t i = 0 ; i < dim ; i++)
1776  {
1777  key.set_d(i,cell_shift.get(i) + gr_cell2.size(i) - 2*getPadding(i) - 1);
1778  }
1779 
1780  return key;
1781  }
1782 
1788  grid_key_dx<dim> getShift() const
1789  {
1790  grid_key_dx<dim> k;
1791 
1792  for (size_t i = 0 ; i < dim ; i++)
1793  k.set_d(i,cell_shift.get(i));
1794 
1795  return k;
1796  }
1797 
1803  const grid_sm<dim,void> & getInternalGrid() const
1804  {
1805  return gr_cell2;
1806  }
1807 };
1808 
1809 
1810 #endif /* CELLDECOMPOSER_HPP_ */
bool operator!=(const shift< dim, T > &s)
It return true if the shift is different.
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:500
T transform(const Point< dim, T > &s, const size_t i) const
No transformation.
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
const Point< dim, T > & getOrig() const
Get the shift vector.
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
No transformation.
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
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:467
void floorP2()
Apply the ceil operation to the point P2.
Definition: Box.hpp:1040
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:22
void setTransform(const Matrix< dim, T > &mat, const Point< dim, T > &orig)
Set the transformation Matrix and shift.
Point< dim, T > getP1() const
Get the point p1.
Definition: Box.hpp:605
void swap(Box< dim, T > &b)
exchange the data of two boxes
Definition: Box.hpp:1090
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.
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
void setP2(const grid_key_dx< dim > &p2)
Set the point P2 of the box.
Definition: Box.hpp:511
void floorP1()
Apply the ceil operation to the point P1.
Definition: Box.hpp:1028
Matrix< dim, T > mat
Matrix transformation.
void ceilP1()
Apply the ceil operation to the point P1.
Definition: Box.hpp:1052
const Matrix< dim, T > & getMat() const
Get the transformation Matrix.
no_transform(const Matrix< dim, T > &t, const Point< dim, T > &s)
Constructor.
bool operator==(const shift< dim, T > &s)
It return true if the shift match.
This class implement an NxN (dense) matrix.
Definition: Matrix.hpp:32
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:456
const Point< dim, T > & getOrig() const
Get the origin.
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:201
This class compare general objects.
T transform(const encapc< 1, Point< dim, T >, Mem > &s, const size_t i) const
Shift the point transformation.
static Matrix< dim, T > identity()
Identity matrix.
Definition: Matrix.hpp:161
T transform(const T(&s)[dim], const size_t i) const
Shift the point transformation.
Point< dim, T > sh
Shift point.
T transform(const Point< dim, T > &s, const size_t i) const
Shift the point transformation.
Matrix< dim, T > mat
Matrix transform.
void ceilP2()
Apply the ceil operation to the point P2.
Definition: Box.hpp:1064
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_key.hpp:407
std::string toPointString() const
Convert the point into a string.
Definition: Point.hpp:297
Point< dim, T > orig
shift transform
const Matrix< dim, T > & getMat() const
Get the transformation Matrix.
bool operator!=(const no_transform< dim, T > &nt)
It return always false.
Point< dim, T > getP2() const
Get the point p2.
Definition: Box.hpp:619