OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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 warn=print_warning_on_adjustment<dim>>
19 class grid_key_dx_iterator_sub_bc : public grid_key_dx_iterator_sub<dim,stencil,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  template<typename T> grid_key_dx_iterator_sub_bc(const grid_sm<dim,T> & g, const grid_key_dx<dim> & start , const grid_key_dx<dim> & stop, const size_t (& bc)[dim])
105  :act(0)
106  {
107  Initialize(g,start,stop,bc);
108  }
109 
118  template<typename T> void Initialize(const grid_sm<dim,T> & g, const grid_key_dx<dim> & start , const grid_key_dx<dim> & stop, const size_t (& bc)[dim])
119  {
120  // copy the boundary conditions
121 
122  for (size_t i = 0 ; i < dim ; i++)
123  {this->bc[i] = bc[i];}
124 
125  // compile-time array {0,0,0,....} {2,2,2,...} {1,1,1,...}
126 
127  typedef typename generate_array<size_t,dim, Fill_zero>::result NNzero;
128  typedef typename generate_array<size_t,dim, Fill_two>::result NNtwo;
129  typedef typename generate_array<size_t,dim, Fill_three>::result NNthree;
130 
131  // In case of high dimension grid_key_dx_iterator_sub can become exponentially
132  // expensive, on the other hand we are expecting that some of the dimensions
133  // are cropped by non periodicity, so we adjust the iteration
134 
135  size_t end_p[dim];
136  size_t start_p[dim];
137 
138  for (size_t i = 0 ; i < dim ; i++)
139  {
140  if (this->bc[i] == NON_PERIODIC && g.size(i) == 1)
141  {start_p[i] = 1; end_p[i] = 1;}
142  else
143  {start_p[i] = 0; end_p[i] = 2;}
144  }
145 
146  // Generate the sub-grid iterator
147 
148  grid_sm<dim,void> nn(NNthree::data);
149  grid_key_dx_iterator_sub<dim,stencil> it(nn,start_p,end_p);
150 
151  // Box base
152  Box<dim,long int> base_b(start,stop);
153 
154  // intersect with all the boxes
155  while (it.isNext())
156  {
157  auto key = it.get();
158 
159  if (check_invalid(key,bc) == true)
160  {
161  ++it;
162  continue;
163  }
164 
165  bool intersect;
166 
167  // intersection box
168  Box<dim,long int> b_int;
169  Box<dim,long int> b_out;
170 
171  for (size_t i = 0 ; i < dim ; i++)
172  {
173  b_int.setLow(i,(key.get(i)-1)*g.getSize()[i]);
174  b_int.setHigh(i,key.get(i)*g.getSize()[i]-1);
175  }
176 
177  intersect = base_b.Intersect(b_int,b_out);
178 
179  // Bring to 0 and size[i]
180  for (size_t i = 0 ; i < dim ; i++)
181  {
182  if (bc[i] == PERIODIC)
183  {
184  b_out.setLow(i,openfpm::math::positive_modulo(b_out.getLow(i),g.size(i)));
185  b_out.setHigh(i,openfpm::math::positive_modulo(b_out.getHigh(i),g.size(i)));
186  }
187  }
188 
189  // if intersect add in the box list
190  if (intersect == true)
191  boxes.push_back(b_out);
192 
193  ++it;
194  }
195 
196  // initialize the first iterator
197  if (boxes.size() > 0)
199  }
200 
210  {
213  {
214  return *this;
215  }
216  else
217  {
218  act++;
219  if (act < boxes.size())
221  }
222 
223  return *this;
224  }
225 
234  inline bool isNext()
235  {
236  return act < boxes.size();
237  }
238 
244  inline const grid_key_dx<dim> get() const
245  {
247  }
248 
252  inline void reset()
253  {
254  act = 0;
255  // initialize the first iterator
256  reinitialize(boxes.get(0).getKP1,boxes.get(0).getKP2);
257  }
258 };
259 
260 
261 #endif /* OPENFPM_DATA_SRC_GRID_ITERATORS_GRID_KEY_DX_ITERATOR_SUB_BC_HPP_ */
void Initialize(const grid_sm< dim, T > &g, const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop, const size_t(&bc)[dim])
Initialize the iterator.
grid_key_dx_iterator_sub< dim, stencil, warn > & operator++()
Get the next element.
std::vector< Box< dim, size_t > > boxes
Here we have all the boxes that this iterator produce.
grid_key_dx_iterator_sub_bc(const grid_sm< dim, T > &g, const grid_key_dx< dim > &start, const grid_key_dx< dim > &stop, const size_t(&bc)[dim])
Constructor.
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
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 size() const
Return the size of the grid.
Definition: grid_sm.hpp:572
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:467
bool isNext()
Check if there is the next element.
const grid_sm< dim, void > & getGridInfo() const
Return the grid information related to this grid.
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:394
bool Intersect(const Box< dim, T > &b, Box< dim, T > &b_out) const
Intersect.
Definition: Box.hpp:88
The same as grid_key_dx_iterator_sub_p but with periodic boundary.
void reset()
Reset the iterator (it restart from the beginning)
const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:677
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:456
grid_key_dx< dim > get() const
Return the actual grid key iterator.
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
Declaration grid_key_dx_iterator_sub.
Definition: grid_sm.hpp:77
size_t bc[dim]
Boundary conditions.
bool isNext()
Check if there is the next element.
void reinitialize(const grid_key_dx_iterator_sub< dim > &g_s_it)
Reinitialize the iterator.
grid_key_dx_iterator_sub_bc< dim, stencil, warn > & operator++()
Get the next element.