1/*
2 * grid_skin_iterator.hpp
3 *
4 * Created on: Jun 24, 2016
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_DATA_SRC_GRID_GRID_SKIN_ITERATOR_HPP_
9#define OPENFPM_DATA_SRC_GRID_GRID_SKIN_ITERATOR_HPP_
10
11#include "grid_key_dx_iterator_sub_bc.hpp"
12
13/**
14 *
15 * Grid key class iterator, iterate through the grid elements on the skin on the grid
16 *
17 * In particular given 2 boxes A and B
18 *
19 *
20 \verbatim
21
22+----------------------------+
23| skin B |
24| +----------------------+ |
25| | | |
26| s | | |
27| k | | |
28| i | | |
29| n | A | |
30| | | |
31| | | |
32| | | |
33| | | |
34| | | |
35| +----------------------+ |
36| skin |
37+----------------------------+
38
39\endverbatim
40
41 *
42 * \warning A MUST BE fully contained into B
43 *
44 * The skin is the part in between the two boxes A and B
45 *
46 * More in general is the Box B removed of A without border. This iterator respect the boundary
47 * conditions
48 *
49 * \param dim dimensionality of the grid
50 *
51 */
52
53template<unsigned int dim>
54class grid_skin_iterator_bc
55{
56protected:
57 //! Internal iterator for each faces
58 grid_key_dx_iterator_sub_bc<dim> sub_it[2*dim];
59
60private:
61
62 //! Actual iterator
63 size_t act;
64
65public:
66
67 /*! \brief Constructor require a grid_sm<dim,T>
68 *
69 * \param g_sm grid information
70 * \param A box A
71 * \param B box B
72 * \param bc boundary conditions
73 *
74 */
75 template <typename T> grid_skin_iterator_bc(const grid_sm<dim,T> & g_sm, const Box<dim,size_t> & A, const Box<dim,size_t> & B, const size_t (& bc)[dim])
76 :act(0)
77 {
78 for (size_t i = 0 ; i < dim ; i++)
79 {
80 grid_key_dx<dim> k1;
81 grid_key_dx<dim> k2;
82
83 for (size_t j = 0 ; j < dim ; j++)
84 {
85 if (j == i)
86 {
87 k1.set_d(j,A.getHigh(j));
88 k2.set_d(j,B.getHigh(j));
89 }
90 else
91 {
92 if ( j < i )
93 {
94 k1.set_d(j,A.getLow(j)+1);
95 k2.set_d(j,A.getHigh(j)-1);
96 }
97 else
98 {
99 k1.set_d(j,B.getLow(j));
100 k2.set_d(j,B.getHigh(j));
101 }
102 }
103 }
104
105 // Initialize a box from the keys and check if it is a valid box
106 Box<dim,long int> br(k1,k2);
107 if (br.isValid() == true)
108 sub_it[2*i].Initialize(g_sm,k1,k2,bc);
109
110 for (size_t j = 0 ; j < dim ; j++)
111 {
112 if (j == i)
113 {
114 k1.set_d(j,B.getLow(j));
115 k2.set_d(j,A.getLow(j));
116 }
117 else
118 {
119 /* coverity[dead_error_line] */
120 if ( j < i )
121 {
122 k1.set_d(j,A.getLow(j)+1);
123 k2.set_d(j,A.getHigh(j)-1);
124 }
125 else
126 {
127 k1.set_d(j,B.getLow(j));
128 k2.set_d(j,B.getHigh(j));
129 }
130 }
131 }
132
133 // Initialize a box from the keys and check if it is a valid box
134 Box<dim,long int> bl(k1,k2);
135 if (bl.isValid() == true && bl != br)
136 sub_it[2*i+1].Initialize(g_sm,k1,k2,bc);
137 }
138
139 while (sub_it[act].isNext() == false)
140 act++;
141 }
142
143 /*! \brief Get the next element
144 *
145 * \return the next grid_key
146 *
147 */
148
149 grid_skin_iterator_bc<dim> & operator++()
150 {
151 ++sub_it[act];
152
153 while (act < 2*dim && sub_it[act].isNext() == false)
154 act++;
155
156 return *this;
157 }
158
159 /*! \brief Check if there is the next element
160 *
161 * Check if there is the next element
162 *
163 * \return true if there is the next, false otherwise
164 *
165 */
166 bool isNext()
167 {
168 if (act < 2*dim)
169 {
170 //! we did not reach the end of the iterator
171
172 return true;
173 }
174
175 //! we reach the end of the iterator
176 return false;
177 }
178
179 /*! \brief Get the actual key
180 *
181 * Get the actual key
182 *
183 * \return the actual key
184 *
185 */
186 inline grid_key_dx<dim> get() const
187 {
188 return sub_it[act].get();
189 }
190
191 /*! \brief Reset the iterator (it restart from the beginning)
192 *
193 */
194 void reset()
195 {
196 act = 0;
197 //! Initialize to 0 the index
198
199 for (size_t i = 0 ; i < 2*dim ; i++)
200 {sub_it[i].reset();}
201 }
202};
203
204
205#endif /* OPENFPM_DATA_SRC_GRID_GRID_SKIN_ITERATOR_HPP_ */
206