OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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>
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], openfpm::vector<Point<dim,T>> & shifts)
37  {
38  shifts.resize(openfpm::math::pow(3,dim));
39 
40  HyperCube<dim> hyp;
41 
42  for (long int i = dim-1 ; i >= 0 ; i--)
43  {
44  std::vector<comb<dim>> cmbs = hyp.getCombinations_R(i);
45 
46  for (size_t j = 0 ; j < cmbs.size() ; j++)
47  {
48  for (size_t k = 0 ; k < dim ; k++)
49  {
50  switch (cmbs[j][k])
51  {
52  case 1:
53  shifts.get(cmbs[j].lin()).template get<0>()[k] = -(domain.getHigh(k) - domain.getLow(k));
54  break;
55  case 0:
56  shifts.get(cmbs[j].lin()).template get<0>()[k] = 0;
57  break;
58  case -1:
59  shifts.get(cmbs[j].lin()).template get<0>()[k] = (domain.getHigh(k) - domain.getLow(k));
60  break;
61  }
62  }
63  }
64  }
65  }
66 
72  void generateShiftVectors_hd(const Box<dim,T> & domain, size_t (& bc)[dim], openfpm::vector<Point<dim,T>> & shifts)
73  {
74  // get the indexes of the free degree of freedom
75  for (size_t i = 0 ; i < dim ; i++)
76  {
77  if (bc[i] == PERIODIC)
78  {
79  red_shift_v[dim_r] = i;
80  dim_r++;
81  }
82  }
83 
84  HyperCube<dim> hyp;
85 
86  // precalculate the nuber of shift vectors
87  size_t nsv = 0;
88  for (long int i = dim-1 ; i >= 0 ; i--)
89  {nsv += hyp.getCombinations_R_bc(i,bc).size();}
90  shifts.resize(nsv+1);
91 
92  for (long int i = dim-1 ; i >= 0 ; i--)
93  {
94  std::vector<comb<dim>> cmbs = hyp.getCombinations_R_bc(i,bc);
95 
96  for (size_t j = 0 ; j < cmbs.size() ; j++)
97  {
98  size_t lin_cmb = linId_hd(cmbs[j]);
99 
100  for (size_t k = 0 ; k < dim ; k++)
101  {
102  switch (cmbs[j][k])
103  {
104  case 1:
105  shifts.get(lin_cmb).template get<0>()[k] = -(domain.getHigh(k) - domain.getLow(k));
106  break;
107  case 0:
108  shifts.get(lin_cmb).template get<0>()[k] = 0;
109  break;
110  case -1:
111  shifts.get(lin_cmb).template get<0>()[k] = (domain.getHigh(k) - domain.getLow(k));
112  break;
113  }
114  }
115  }
116  }
117  }
118 
119 public:
120 
126  void generateShiftVectors(const Box<dim,T> & domain, size_t (& bc)[dim], openfpm::vector<Point<dim,T>> & shifts)
127  {
128  if (dim < 10)
129  {generateShiftVectors_ld(domain,bc,shifts);}
130  else
131  {generateShiftVectors_hd(domain,bc,shifts);}
132  }
133 
139  void Initialize(size_t (& bc)[dim])
140  {
141  // get the indexes of the free degree of freedom
142  for (size_t i = 0 ; i < dim ; i++)
143  {
144  if (bc[i] == PERIODIC)
145  {
146  red_shift_v[dim] = i;
147  dim_r++;
148  }
149  }
150  }
151 
157  size_t linId_hd(const comb<dim> & cmb)
158  {
159  size_t cul = 1;
160  size_t lin = 0;
161  for (long int i = 0 ; i < dim_r ; i++)
162  {
163  lin += cul*(cmb.c[red_shift_v[i]] + 1);
164  cul *= 3;
165  }
166 
167  return lin;
168  }
169 
175  inline size_t linId_ld(const comb<dim> & cmb)
176  {
177  return cmb.lin();
178  }
179 
185  inline size_t linId(const comb<dim> & cmb)
186  {
187  if (dim < 10)
188  {return linId_ld(cmb);}
189 
190  return linId_hd(cmb);
191  }
192 
193 };
194 
195 
196 #endif /* SRC_DECOMPOSITION_SHIFT_VECT_CONVERTER_HPP_ */
size_t linId(const comb< dim > &cmb)
linearize the combination in case of high dimensions
static std::vector< comb< dim > > getCombinations_R(size_t d)
Definition: HyperCube.hpp:100
void generateShiftVectors_ld(const Box< dim, T > &domain, size_t(&bc)[dim], openfpm::vector< Point< dim, T >> &shifts)
Here we generare the shift vectors for the low dimension case.
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
Position of the element of dimension d in the hyper-cube of dimension dim.
Definition: comb.hpp:34
size_t linId_ld(const comb< dim > &cmb)
linearize the combination in case of low dimensions
void generateShiftVectors_hd(const Box< dim, T > &domain, size_t(&bc)[dim], openfpm::vector< Point< dim, T >> &shifts)
Here we generare the shift vectors for the high dimension case.
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
void Initialize(size_t(&bc)[dim])
Initialize.
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
static std::vector< comb< dim > > getCombinations_R_bc(size_t d, const size_t(&bc)[dim])
Definition: HyperCube.hpp:151
size_t lin() const
Linearization.
Definition: comb.hpp:376
void generateShiftVectors(const Box< dim, T > &domain, size_t(&bc)[dim], openfpm::vector< Point< dim, T >> &shifts)
Here we generare the shift vectors for the low dimension case.
size_t red_shift_v[dim]
Indicate which indexes are non_periodic.
This class represent an N-dimensional box.
Definition: Box.hpp:56
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:61
size_t linId_hd(const comb< dim > &cmb)
linearize the combination in case of high dimension
char c[dim]
Array that store the combination.
Definition: comb.hpp:37