OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
shift_vect_converter.hpp
1 /*
2  * shift_vect_converter.hpp
3  *
4  * Created on: Feb 8, 2018
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_DECOMPOSITION_SHIFT_VECT_CONVERTER_HPP_
9 #define SRC_DECOMPOSITION_SHIFT_VECT_CONVERTER_HPP_
10 
11 #include "Space/Shape/HyperCube.hpp"
12 
19 template<unsigned int dim, typename T, typename Memory, template<typename> class layout_base>
21 {
23  size_t red_shift_v[dim];
24 
25  // indexes
26  size_t tmp[dim];
27 
28  // Dimension
29  int dim_r = 0;
30 
36  void generateShiftVectors_ld(const Box<dim,T> & domain, size_t (& bc)[dim],
37  openfpm::vector<Point<dim,T>,Memory,layout_base> & shifts)
38  {
39  shifts.resize(openfpm::math::pow(3,dim));
40 
41  HyperCube<dim> hyp;
42 
43  for (long int i = dim ; i >= 0 ; i--)
44  {
45  std::vector<comb<dim>> cmbs = hyp.getCombinations_R(i);
46 
47  for (size_t j = 0 ; j < cmbs.size() ; j++)
48  {
49  for (size_t k = 0 ; k < dim ; k++)
50  {
51  switch (cmbs[j][k])
52  {
53  case 1:
54  shifts.get(cmbs[j].lin()).template get<0>()[k] = -(domain.getHigh(k) - domain.getLow(k));
55  break;
56  case 0:
57  shifts.get(cmbs[j].lin()).template get<0>()[k] = 0;
58  break;
59  case (char)-1:
60  shifts.get(cmbs[j].lin()).template get<0>()[k] = (domain.getHigh(k) - domain.getLow(k));
61  break;
62  }
63  }
64  }
65  }
66  }
67 
73  void generateShiftVectors_hd(const Box<dim,T> & domain, size_t (& bc)[dim],
74  openfpm::vector<Point<dim,T>,Memory,layout_base> & shifts)
75  {
76  // get the indexes of the free degree of freedom
77  for (size_t i = 0 ; i < dim ; i++)
78  {
79  if (bc[i] == PERIODIC)
80  {
81  red_shift_v[dim_r] = i;
82  dim_r++;
83  }
84  }
85 
86  HyperCube<dim> hyp;
87 
88  // precalculate the nuber of shift vectors
89  size_t nsv = 0;
90  for (long int i = dim-1 ; i >= 0 ; i--)
91  {nsv += hyp.getCombinations_R_bc(i,bc).size();}
92  shifts.resize(nsv+1);
93 
94  for (long int i = dim-1 ; i >= 0 ; i--)
95  {
96  std::vector<comb<dim>> cmbs = hyp.getCombinations_R_bc(i,bc);
97 
98  for (size_t j = 0 ; j < cmbs.size() ; j++)
99  {
100  size_t lin_cmb = linId_hd(cmbs[j]);
101 
102  for (size_t k = 0 ; k < dim ; k++)
103  {
104  switch (cmbs[j][k])
105  {
106  case 1:
107  shifts.get(lin_cmb).template get<0>()[k] = -(domain.getHigh(k) - domain.getLow(k));
108  break;
109  case 0:
110  shifts.get(lin_cmb).template get<0>()[k] = 0;
111  break;
112  case (char)-1:
113  shifts.get(lin_cmb).template get<0>()[k] = (domain.getHigh(k) - domain.getLow(k));
114  break;
115  }
116  }
117  }
118  }
119  }
120 
121 public:
122 
128  void generateShiftVectors(const Box<dim,T> & domain, size_t (& bc)[dim],
129  openfpm::vector<Point<dim,T>,Memory,layout_base> & shifts)
130  {
131  if (dim < 10)
132  {generateShiftVectors_ld(domain,bc,shifts);}
133  else
134  {generateShiftVectors_hd(domain,bc,shifts);}
135  }
136 
142  void Initialize(size_t (& bc)[dim])
143  {
144  // get the indexes of the free degree of freedom
145  for (size_t i = 0 ; i < dim ; i++)
146  {
147  if (bc[i] == PERIODIC)
148  {
149  red_shift_v[dim] = i;
150  dim_r++;
151  }
152  }
153  }
154 
160  size_t linId_hd(const comb<dim> & cmb)
161  {
162  size_t cul = 1;
163  size_t lin = 0;
164  for (long int i = 0 ; i < dim_r ; i++)
165  {
166  lin += cul*(cmb.c[red_shift_v[i]] + 1);
167  cul *= 3;
168  }
169 
170  return lin;
171  }
172 
178  inline size_t linId_ld(const comb<dim> & cmb)
179  {
180  return cmb.lin();
181  }
182 
188  inline size_t linId(const comb<dim> & cmb)
189  {
190  if (dim < 10)
191  {return linId_ld(cmb);}
192 
193  return linId_hd(cmb);
194  }
195 
196 };
197 
198 
199 #endif /* SRC_DECOMPOSITION_SHIFT_VECT_CONVERTER_HPP_ */
void generateShiftVectors(const Box< dim, T > &domain, size_t(&bc)[dim], openfpm::vector< Point< dim, T >, Memory, layout_base > &shifts)
Here we generare the shift vectors for the low dimension case.
static std::vector< comb< dim > > getCombinations_R(size_t d)
Definition: HyperCube.hpp:100
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:34
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:556
size_t red_shift_v[dim]
Indicate which indexes are non_periodic.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:27
static std::vector< comb< dim > > getCombinations_R_bc(size_t d, const size_t(&bc)[dim])
Definition: HyperCube.hpp:151
size_t linId(const comb< dim > &cmb)
linearize the combination in case of high dimensions
size_t linId_ld(const comb< dim > &cmb)
linearize the combination in case of low dimensions
size_t lin() const
Linearization.
Definition: comb.hpp:376
size_t linId_hd(const comb< dim > &cmb)
linearize the combination in case of high dimension
void generateShiftVectors_ld(const Box< dim, T > &domain, size_t(&bc)[dim], openfpm::vector< Point< dim, T >, Memory, layout_base > &shifts)
Here we generare the shift vectors for the low dimension case.
This class represent an N-dimensional box.
Definition: Box.hpp:60
void Initialize(size_t(&bc)[dim])
Initialize.
in case of high dimensions shift vector converter
This class calculate elements of the hyper-cube.
Definition: HyperCube.hpp:57
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567
char c[dim]
Array that store the combination.
Definition: comb.hpp:37
void generateShiftVectors_hd(const Box< dim, T > &domain, size_t(&bc)[dim], openfpm::vector< Point< dim, T >, Memory, layout_base > &shifts)
Here we generare the shift vectors for the high dimension case.