1/*
2 * CellNNIteratorRuntime.hpp
3 *
4 * Created on: Nov 18, 2016
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_DATA_SRC_NN_CELLLIST_CELLNNITERATORRUNTIME_HPP_
9#define OPENFPM_DATA_SRC_NN_CELLLIST_CELLNNITERATORRUNTIME_HPP_
10
11#include "util/mathutil.hpp"
12
13#define FULL openfpm::math::pow(3,dim)
14#define SYM openfpm::math::pow(3,dim)/2 + 1
15#define CRS openfpm::math::pow(2,dim)
16
17#define RUNTIME -1
18
19/*! \brief Iterator for the neighborhood of the cell structures
20 *
21 * In general you never create it directly but you get it from the CellList structures
22 *
23 * It iterate across all the element of the selected cell and the near cells
24 *
25 * \note to calculate quantities that involve a total reduction (like energies) use the CellIteratorSymRed
26 *
27 * \tparam dim dimensionality of the space where the cell live
28 * \tparam Cell cell type on which the iterator is working
29 * \tparam impl implementation specific options NO_CHECK do not do check on access, SAFE do check on access
30 *
31 */
32template<unsigned int dim, typename Cell,unsigned int impl>
33class CellNNIterator<dim,Cell,RUNTIME,impl>
34{
35protected:
36
37 //! actual element id
38 const typename Cell::Mem_type_type::loc_index * start_id;
39
40 //! stop id to read the end of the cell
41 const typename Cell::Mem_type_type::loc_index * stop_id;
42
43 //! Actual NNc_id;
44 size_t NNc_id;
45
46 //! Size of the neighboring cells
47 size_t NNc_size;
48
49 //! Center cell, or cell for witch we are searching the NN-cell
50 const long int cell;
51
52 //! actual cell id = NNc[NNc_id]+cell stored for performance reason
53 size_t cell_id;
54
55 //! Cell list
56 Cell & cl;
57
58 //! NN cell id
59 const long int * NNc;
60
61 /*! \brief Select non-empty cell
62 *
63 */
64 __attribute__((always_inline)) inline void selectValid()
65 {
66 while (start_id == stop_id)
67 {
68 NNc_id++;
69
70 // No more Cell
71 if (NNc_id >= NNc_size) return;
72
73 cell_id = NNc[NNc_id] + cell;
74
75 start_id = &cl.getStartId(cell_id);
76 stop_id = &cl.getStopId(cell_id);
77 }
78 }
79
80private:
81
82
83public:
84
85 /*! \brief
86 *
87 * Cell NN iterator
88 *
89 * \param cell Cell id
90 * \param NNc Cell neighborhood indexes (relative)
91 * \param NNc_size size of the neighborhood
92 * \param cl Cell structure
93 *
94 */
95 __attribute__((always_inline)) inline CellNNIterator(size_t cell, const long int * NNc, size_t NNc_size, Cell & cl)
96 :NNc_id(0),NNc_size(NNc_size),cell(cell),cell_id(NNc[NNc_id] + cell),cl(cl),NNc(NNc)
97 {
98 start_id = &cl.getStartId(cell_id);
99 stop_id = &cl.getStopId(cell_id);
100 selectValid();
101 }
102
103 /*! \brief Check if there is the next element
104 *
105 * \return true if there is the next element
106 *
107 */
108 __attribute__((always_inline)) inline bool isNext()
109 {
110 if (NNc_id >= NNc_size)
111 return false;
112 return true;
113 }
114
115 /*! \brief take the next element
116 *
117 * \return itself
118 *
119 */
120 __attribute__((always_inline)) inline CellNNIterator & operator++()
121 {
122 start_id++;
123
124 selectValid();
125
126 return *this;
127 }
128
129 /*! \brief Get the value of the cell
130 *
131 * \return the next element object
132 *
133 */
134 __attribute__((always_inline)) inline const typename Cell::Mem_type_type::loc_index & get()
135 {
136 return cl.get_lin(start_id);
137 }
138};
139
140
141/*! \brief Symmetric iterator for the neighborhood of the cell structures
142 *
143 * In general you never create it directly but you get it from the CellList structures
144 *
145 * It iterate across all the element of the selected cell and the near cells.
146 *
147 * \note if we query the neighborhood of p and q is the neighborhood of p
148 * when we will query the neighborhood of q p is not present. This is
149 * useful to implement formula like \f$ \sum_{q = neighborhood(p) and p <= q} \f$
150 *
151 * \tparam dim dimensionality of the space where the cell live
152 * \tparam Cell cell type on which the iterator is working
153 * \tparam NNc_size neighborhood size
154 * \tparam impl implementation specific options NO_CHECK do not do check on access, SAFE do check on access
155 *
156 */
157template<unsigned int dim, typename Cell,typename vector_pos_type, unsigned int impl>
158class CellNNIteratorSym<dim,Cell,vector_pos_type,RUNTIME,impl> : public CellNNIterator<dim,Cell,RUNTIME,impl>
159{
160 //! index of the particle p
161 size_t p;
162
163 //! Position of the particle p
164 const vector_pos_type & v;
165
166 /*! Select the next valid element
167 *
168 */
169 __attribute__((always_inline)) inline void selectValid()
170 {
171 if (this->NNc[this->NNc_id] == 0)
172 {
173 while (this->start_id < this->stop_id)
174 {
175 size_t q = this->cl.get_lin(this->start_id);
176 for (long int i = dim-1 ; i >= 0 ; i--)
177 {
178 if (v.template get<0>(p)[i] < v.template get<0>(q)[i])
179 return;
180 else if (v.template get<0>(p)[i] > v.template get<0>(q)[i])
181 goto next;
182 }
183 if (q >= p) return;
184next:
185 this->start_id++;
186 }
187
188 CellNNIterator<dim,Cell,RUNTIME,impl>::selectValid();
189 }
190 else
191 {
192 CellNNIterator<dim,Cell,RUNTIME,impl>::selectValid();
193 }
194 }
195
196public:
197
198 /*! \brief
199 *
200 * Cell NN iterator
201 *
202 * \param cell Cell id
203 * \param p index of the particle from which we are searching the neighborhood particles
204 * \param NNc Cell neighborhood indexes (relative)
205 * \param cl Cell structure
206 *
207 */
208 __attribute__((always_inline)) inline CellNNIteratorSym(size_t cell,
209 size_t p,
210 const long int * NNc,
211 size_t NNc_size,
212 Cell & cl,
213 const vector_pos_type & v)
214 :CellNNIterator<dim,Cell,RUNTIME,impl>(cell,NNc,NNc_size,cl),p(p),v(v)
215 {
216 if (this->NNc_id >= this->NNc_size)
217 return;
218
219 selectValid();
220 }
221
222
223 /*! \brief take the next element
224 *
225 * \return itself
226 *
227 */
228 __attribute__((always_inline)) inline CellNNIteratorSym<dim,Cell,vector_pos_type,RUNTIME,impl> & operator++()
229 {
230 this->start_id++;
231
232 selectValid();
233
234 return *this;
235 }
236};
237
238#endif /* OPENFPM_DATA_SRC_NN_CELLLIST_CELLNNITERATORRUNTIME_HPP_ */
239