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 */
53template<unsigned int dim, typename T, typename Decomposition>
54class 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
132public:
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