1 | /* |
2 | * PointIteratorSkin.hpp |
3 | * |
4 | * Created on: Jan 4, 2017 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef OPENFPM_NUMERICS_SRC_DRAW_POINTITERATORSKIN_HPP_ |
9 | #define OPENFPM_NUMERICS_SRC_DRAW_POINTITERATORSKIN_HPP_ |
10 | |
11 | #include "Grid/Iterators/grid_dist_id_iterator_dec_skin.hpp" |
12 | |
13 | #define RETURN_A 1 |
14 | #define RETURN_B 2 |
15 | |
16 | /*! \brief this class draw particles on subset of grid-like position |
17 | * |
18 | \verbatim |
19 | (Box B) |
20 | | (0.6,0.6) |
21 | + + + + | + + + + + |
22 | +---+-------+---+ |
23 | + | * | + + | * | + + + + |
24 | | | | |
25 | + | * | + + | * | + + + + |
26 | | | | | |
27 | + | * | + + | * | + + + + |
28 | | | | | |
29 | + | * | + + | * | + + + + |
30 | | | | | |
31 | + | * | + + | * | + + + + |
32 | | | | | |
33 | + | * | + + | * | + + + + |
34 | | +-------+ | |
35 | + | * * * * | + + + + |
36 | +---------------+ |
37 | + + + + + | + + + + |
38 | (-1.0,-1.0) | |
39 | | |
40 | (Box A) |
41 | |
42 | |
43 | \endverbatim |
44 | * |
45 | * |
46 | * Suppose we have a grid 9x9 from (-1.0,-1.0 to 0.6,0.6) |
47 | * |
48 | * Defined a Box A (-0.9,-0.9 to -0.1,0.5) and a box B (-0.7, -0.7 to -0.3,0.5) |
49 | * |
50 | * This class will return the points indicated with * |
51 | * |
52 | */ |
53 | template<unsigned int dim, typename T, typename Decomposition> |
54 | class PointIteratorSkin: protected grid_dist_id_iterator_dec_skin<Decomposition> |
55 | { |
56 | //! Actual point |
57 | Point<dim,T> ap; |
58 | |
59 | //! sub_domain (required to filter out points) |
60 | openfpm::vector<Box<dim,T>> sub_domainA; |
61 | |
62 | //! domain |
63 | Box<dim,T> domain; |
64 | |
65 | //! Spacing |
66 | T sp[dim]; |
67 | |
68 | static Box<dim,long int> getAB(size_t (& gs)[dim], const Box<dim,T> & dom, const Box<dim,T> & sub_domA , const Box<dim,T> & sub_domB, T (& sp)[dim], size_t AB) |
69 | { |
70 | for (size_t i = 0 ; i < dim ; i++) |
71 | sp[i] = (dom.getHigh(i) - dom.getLow(i)) / (gs[i] -1); |
72 | |
73 | Box<dim,long int> box; |
74 | |
75 | for (size_t i = 0 ; i < dim ; i++) |
76 | { |
77 | size_t Ast = std::ceil( (sub_domA.getLow(i) - dom.getLow(i)) / sp[i] ) - 1; |
78 | size_t Asp = std::floor( (sub_domA.getHigh(i) - dom.getLow(i)) / sp[i] ) + 1; |
79 | |
80 | size_t Bst = std::ceil( (sub_domB.getLow(i) - dom.getLow(i)) / sp[i] ); |
81 | size_t Bsp = std::floor( (sub_domB.getHigh(i) - dom.getLow(i)) / sp[i] ); |
82 | |
83 | // grid_dist_id_iterator_dec_skin only work if A is contained into B |
84 | Ast = (Ast < Bst)?Bst:Ast; |
85 | Asp = (Asp > Bsp)?Bsp:Asp; |
86 | |
87 | if (AB == RETURN_A) |
88 | { |
89 | box.setLow(i,Ast); |
90 | box.setHigh(i,Asp); |
91 | } |
92 | else |
93 | { |
94 | box.setLow(i,Bst); |
95 | box.setHigh(i,Bsp); |
96 | } |
97 | } |
98 | |
99 | return box; |
100 | } |
101 | |
102 | void calculateAp() |
103 | { |
104 | if (grid_dist_id_iterator_dec_skin<Decomposition>::isNext() == false) |
105 | return; |
106 | |
107 | grid_key_dx<dim> key = grid_dist_id_iterator_dec_skin<Decomposition>::get(); |
108 | |
109 | for (size_t i = 0 ; i < dim ; i++) |
110 | ap.get(i) = key.get(i) * sp[i] + domain.getLow(i); |
111 | } |
112 | |
113 | |
114 | /*! it check that the actual point is not inside B |
115 | * |
116 | * \return true if the point is not inside B |
117 | * |
118 | */ |
119 | bool isValidPoint() |
120 | { |
121 | bool valid = true; |
122 | |
123 | for (size_t i = 0 ; i < sub_domainA.size() ; i++) |
124 | { |
125 | if (Box<dim,T>(sub_domainA.get(i)).isInside(ap) == true) |
126 | valid = false; |
127 | } |
128 | |
129 | return valid; |
130 | } |
131 | |
132 | public: |
133 | |
134 | /*! \brief Draw Particles |
135 | * |
136 | * \param sp grid spacing |
137 | * |
138 | */ |
139 | PointIteratorSkin( Decomposition & dec, |
140 | size_t (& sz)[dim], |
141 | const Box<dim,T> & domain, |
142 | const Box<dim,T> & sub_A, |
143 | const Box<dim,T> & sub_B, |
144 | size_t (& bc)[dim]) |
145 | :grid_dist_id_iterator_dec_skin<Decomposition>(dec, sz, getAB(sz,domain,sub_A,sub_B,sp,RETURN_A), |
146 | getAB(sz,domain,sub_A,sub_B,sp,RETURN_B), bc), |
147 | domain(domain) |
148 | { |
149 | sub_domainA.add(sub_A); |
150 | calculateAp(); |
151 | } |
152 | |
153 | /*! \Return the actual point |
154 | * |
155 | * \return the actual point |
156 | * |
157 | */ |
158 | Point<dim,T> & get() |
159 | { |
160 | return ap; |
161 | } |
162 | |
163 | /*! \brief Next point |
164 | * |
165 | * \return itself |
166 | * |
167 | */ |
168 | PointIteratorSkin & operator++() |
169 | { |
170 | grid_dist_id_iterator_dec_skin<Decomposition>::operator++(); |
171 | |
172 | calculateAp(); |
173 | |
174 | while (grid_dist_id_iterator_dec_skin<Decomposition>::isNext() && isValidPoint() == false) |
175 | { |
176 | grid_dist_id_iterator_dec_skin<Decomposition>::operator++(); |
177 | |
178 | calculateAp(); |
179 | } |
180 | |
181 | return *this; |
182 | } |
183 | |
184 | bool isNext() |
185 | { |
186 | return grid_dist_id_iterator_dec_skin<Decomposition>::isNext(); |
187 | } |
188 | |
189 | PointIteratorSkin<dim,T,Decomposition> & operator=(PointIteratorSkin<dim,T,Decomposition> & p) |
190 | { |
191 | grid_dist_id_iterator_dec_skin<Decomposition>::operator=(p); |
192 | |
193 | ap = p.ap; |
194 | sub_domainA = p.sub_domainA; |
195 | domain = p.domain; |
196 | |
197 | for (size_t i = 0 ; i < dim; i++) |
198 | sp[i] = p.sp[i]; |
199 | |
200 | return *this; |
201 | } |
202 | |
203 | void addBoxA(const Box<dim,double> & BoxA) |
204 | { |
205 | sub_domainA.add(BoxA); |
206 | } |
207 | }; |
208 | |
209 | |
210 | |
211 | #endif /* OPENFPM_NUMERICS_SRC_DRAW_POINTITERATORSKIN_HPP_ */ |
212 | |