1/*
2 * PointIterator.hpp
3 *
4 * Created on: Jan 3, 2017
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_NUMERICS_SRC_DRAW_POINTITERATOR_HPP_
9#define OPENFPM_NUMERICS_SRC_DRAW_POINTITERATOR_HPP_
10
11
12/*! \brief this class draw particles on subset of grid-like position
13 *
14 \verbatim
15 Point B
16 | (0.6,0.6)
17 + + + + + | + + + +
18 +---------------+
19 + | + + + + | + + + +
20 | |
21 + | + + + + | + + + +
22 | |
23 + | + + + + | + + + +
24 | |
25 + | + + + + | + + + +
26 | |
27 + | + + + + | + + + +
28 | |
29 + | + + + + | + + + +
30 | |
31 + | + + + + | + + + +
32 +---------------+
33 + + + + + ^ + + + +
34(-1.0,-1.0) |
35 |
36 (Point A)
37
38
39 \endverbatim
40 *
41 *
42 * Suppose we have a grid 9x9 from (-1.0,-1.0 to 0.6,0.6)
43 *
44 * Defined a Box (-0.9,-0.9 to -0.1,0.5)
45 *
46 * This class will return the points
47 *
48 * (-0.8 -0.8)
49 * (-0.6 -0.8)
50 * (-0.4 -0.8)
51 * ...
52 * (-0.1,-0.8) Point A
53 * ...
54 * (-0.1,0.5) Point B
55 *
56 */
57template<unsigned int dim, typename T, typename Decomposition>
58class PointIterator: protected grid_dist_id_iterator_dec<Decomposition>
59{
60 //! Actual point
61 Point<dim,T> ap;
62
63 //! sub_domain
64 Box<dim,T> sub_domain;
65
66 //! domain
67 Box<dim,T> domain;
68
69 //! Spacing
70 T sp[dim];
71
72 static grid_key_dx<dim> getStart(size_t (& gs)[dim], const Box<dim,T> & dom, Box<dim,T> & sub_dom, T (& sp)[dim])
73 {
74 for (size_t i = 0 ; i < dim ; i++)
75 sp[i] = (dom.getHigh(i) - dom.getLow(i)) / (gs[i] -1);
76
77 grid_key_dx<dim> pkey;
78
79 for (size_t i = 0 ; i < dim ; i++)
80 pkey.set_d(i,std::ceil( (sub_dom.getLow(i) - dom.getLow(i)) / sp[i]));
81
82 return pkey;
83 }
84
85 static grid_key_dx<dim> getStop(size_t (& gs)[dim], const Box<dim,T> & dom, Box<dim,T> & sub_dom, T (& sp)[dim])
86 {
87 for (size_t i = 0 ; i < dim ; i++)
88 sp[i] = (dom.getHigh(i) - dom.getLow(i)) / (gs[i] - 1);
89
90 grid_key_dx<dim> pkey;
91
92 for (size_t i = 0 ; i < dim ; i++)
93 pkey.set_d(i,std::floor( (sub_dom.getHigh(i) - dom.getLow(i)) / sp[i]));
94
95 return pkey;
96 }
97
98 void calculateAp()
99 {
100 if (grid_dist_id_iterator_dec<Decomposition>::isNext() == false)
101 return;
102
103 grid_key_dx<dim> key = grid_dist_id_iterator_dec<Decomposition>::get();
104
105 for (size_t i = 0 ; i < dim ; i++)
106 ap.get(i) = key.get(i) * sp[i] + domain.getLow(i);
107 }
108
109public:
110
111 /*! \brief Draw Particles
112 *
113 * \param sp grid spacing
114 *
115 */
116 PointIterator( Decomposition & dec, size_t (& sz)[dim], const Box<dim,T> & domain, Box<dim,T> & sub_domain)
117 :grid_dist_id_iterator_dec<Decomposition>(dec, sz, getStart(sz,domain,sub_domain,sp), getStop(sz,domain,sub_domain,sp)),sub_domain(sub_domain),domain(domain)
118 {
119 calculateAp();
120 }
121
122 /*! \Return the actual point
123 *
124 *
125 */
126 Point<dim,T> & get()
127 {
128 return ap;
129 }
130
131 /*! \brief Next point
132 *
133 * \return itself
134 *
135 */
136 PointIterator & operator++()
137 {
138 grid_dist_id_iterator_dec<Decomposition>::operator++();
139
140 calculateAp();
141
142 return *this;
143 }
144
145 bool isNext()
146 {
147 return grid_dist_id_iterator_dec<Decomposition>::isNext();
148 }
149
150 /*! \brief Return the real Margin of the box
151 *
152 * For example consider to have a domain (0.0,0.0) to (1.0,1.0)
153 * 11 points in each direction (spacing 0.1). if we have a sub-domain
154 * (0.15,0.15) to (0.55,0.55) getBoxMargins return the box (0.2,0.2) to
155 * (0.5,0.5). the smallest box that enclose the points that the point
156 * iterator is going to give
157 *
158 */
159 Box<dim,T> getBoxMargins()
160 {
161 Box<dim,T> box;
162
163 grid_key_dx<dim> start = grid_dist_id_iterator_dec<Decomposition>::getStart();
164 grid_key_dx<dim> stop = grid_dist_id_iterator_dec<Decomposition>::getStop();
165
166 for (size_t i = 0 ; i < dim ; i++)
167 {
168 box.setLow(i, start.get(i)*sp[i] + domain.getLow(i));
169 box.setHigh(i, stop.get(i)*sp[i] + domain.getLow(i));
170 }
171
172 return box;
173 }
174};
175
176
177#endif /* OPENFPM_NUMERICS_SRC_DRAW_POINTITERATOR_HPP_ */
178