OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
grid_key_dx_iterator_sub_bc.hpp
1 /*
2  * grid_key_dx_iterator_sub_p.hpp
3  *
4  * Created on: Dec 15, 2015
5  * Author: i-bird
6  */
7 
8 #ifndef OPENFPM_DATA_SRC_GRID_ITERATORS_GRID_KEY_DX_ITERATOR_SUB_BC_HPP_
9 #define OPENFPM_DATA_SRC_GRID_ITERATORS_GRID_KEY_DX_ITERATOR_SUB_BC_HPP_
10 
11 #include "grid_key_dx_iterator_sub.hpp"
12 
18 template<unsigned int dim, typename stencil=no_stencil, typename linearizer = grid_sm<dim,void>, typename warn=print_warning_on_adjustment<dim,linearizer>>
19 class grid_key_dx_iterator_sub_bc : public grid_key_dx_iterator_sub<dim,stencil,linearizer,warn>
20 {
22  size_t bc[dim];
23 
25  size_t act;
26 
28  std::vector<Box<dim,size_t>> boxes;
29 
35  bool inline check_invalid(const grid_key_dx<dim> & key, const size_t (& bc)[dim])
36  {
37  for (size_t i = 0 ; i < dim ; i++)
38  {
39  if (bc[i] == NON_PERIODIC && key.get(i) != 1)
40  {
41  return true;
42  }
43  }
44 
45  return false;
46  }
47 
48 public:
49 
50 
52  {
53  this->operator=(tmp);
54 
55  }
56 
58  {
59  this->operator=(tmp);
60 
61  }
62 
64  {
65  for (size_t i = 0 ; i < dim ; i++)
66  bc[i] = tmp.bc[i];
67 
68  act = tmp.act;
69  boxes = tmp.boxes;
70 
71  return *this;
72  }
73 
75  {
76  for (size_t i = 0 ; i < dim ; i++)
77  bc[i] = tmp.bc[i];
78 
79  act = tmp.act;
80  boxes.swap(tmp.boxes);
81 
82  return *this;
83  }
84 
90  :act(0)
91  {
92 
93  }
94 
95 
104  grid_key_dx_iterator_sub_bc(const linearizer & g,
105  const grid_key_dx<dim> & start,
106  const grid_key_dx<dim> & stop,
107  const size_t (& bc)[dim])
108  :act(0)
109  {
110  Initialize(g,start,stop,bc);
111  }
112 
121  void Initialize(const linearizer & g,
122  const grid_key_dx<dim> & start ,
123  const grid_key_dx<dim> & stop,
124  const size_t (& bc)[dim])
125  {
126  // copy the boundary conditions
127 
128  for (size_t i = 0 ; i < dim ; i++)
129  {this->bc[i] = bc[i];}
130 
131  // compile-time array {3,3,3,....}
132 
133  typedef typename generate_array<size_t,dim, Fill_three>::result NNthree;
134 
135  // In case of high dimension grid_key_dx_iterator_sub can become exponentially
136  // expensive, on the other hand we are expecting that some of the dimensions
137  // are cropped by non periodicity, so we adjust the iteration
138 
139  size_t end_p[dim];
140  size_t start_p[dim];
141 
142  for (size_t i = 0 ; i < dim ; i++)
143  {
144  if (this->bc[i] == NON_PERIODIC && g.size(i) == 1)
145  {start_p[i] = 1; end_p[i] = 1;}
146  else
147  {start_p[i] = 0; end_p[i] = 2;}
148  }
149 
150  // Generate the sub-grid iterator
151 
152  grid_sm<dim,void> nn(NNthree::data);
153  grid_key_dx_iterator_sub<dim,stencil> it(nn,start_p,end_p);
154 
155  // Box base
156  Box<dim,long int> base_b(start,stop);
157 
158  // intersect with all the boxes
159  while (it.isNext())
160  {
161  auto key = it.get();
162 
163  if (check_invalid(key,bc) == true)
164  {
165  ++it;
166  continue;
167  }
168 
169  bool intersect;
170 
171  // intersection box
172  Box<dim,long int> b_int;
173  Box<dim,long int> b_out;
174 
175  for (size_t i = 0 ; i < dim ; i++)
176  {
177  b_int.setLow(i,(key.get(i)-1)*g.getSize()[i]);
178  b_int.setHigh(i,key.get(i)*g.getSize()[i]-1);
179  }
180 
181  intersect = base_b.Intersect(b_int,b_out);
182 
183  // Bring to 0 and size[i]
184  for (size_t i = 0 ; i < dim ; i++)
185  {
186  if (bc[i] == PERIODIC)
187  {
188  b_out.setLow(i,openfpm::math::positive_modulo(b_out.getLow(i),g.size(i)));
189  b_out.setHigh(i,openfpm::math::positive_modulo(b_out.getHigh(i),g.size(i)));
190  }
191  }
192 
193  // if intersect add in the box list
194  if (intersect == true)
195  {boxes.push_back(b_out);}
196 
197  ++it;
198  }
199 
200  // initialize the first iterator
201  if (boxes.size() > 0)
203  }
204 
214  {
217  {
218  return *this;
219  }
220  else
221  {
222  act++;
223  if (act < boxes.size())
225  }
226 
227  return *this;
228  }
229 
238  inline bool isNext()
239  {
240  return act < boxes.size();
241  }
242 
248  inline const grid_key_dx<dim> get() const
249  {
251  }
252 
256  inline void reset()
257  {
258  act = 0;
259  // initialize the first iterator
260  reinitialize(boxes.get(0).getKP1,boxes.get(0).getKP2);
261  }
262 };
263 
264 
265 #endif /* OPENFPM_DATA_SRC_GRID_ITERATORS_GRID_KEY_DX_ITERATOR_SUB_BC_HPP_ */
bool isNext()
Check if there is the next element.
std::vector< Box< dim, size_t > > boxes
Here we have all the boxes that this iterator produce.
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:556
bool check_invalid(const grid_key_dx< dim > &key, const size_t(&bc)[dim])
Check if the position is valid with the actual boundary conditions.
size_t bc[dim]
Boundary conditions.
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition: grid_key.hpp:503
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:544
The same as grid_key_dx_iterator_sub_p but with periodic boundary.
grid_key_dx< dim > get() const
Return the actual grid key iterator.
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:533
const linearizer & getGridInfo() const
Return the grid information related to this grid.
grid_key_dx_iterator_sub< dim, stencil, linearizer, warn > & operator++()
Get the next element.
const grid_key_dx< dim > get() const
Return the actual grid key iterator.
void reset()
Reset the iterator (it restart from the beginning)
__device__ __host__ bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:95
Declaration grid_key_dx_iterator_sub.
Definition: grid_sm.hpp:156
void reinitialize(const grid_key_dx_iterator_sub< dim > &g_s_it)
Reinitialize the iterator.
void Initialize(const linearizer &g, const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop, const size_t(&bc)[dim])
Initialize the iterator.
bool isNext()
Check if there is the next element.
grid_key_dx_iterator_sub_bc(const linearizer &g, const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop, const size_t(&bc)[dim])
Constructor.
grid_key_dx_iterator_sub_bc< dim, stencil, linearizer, warn > & operator++()
Get the next element.
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:567