1/*
2 * CellNNIteratorM.hpp
3 *
4 * Created on: Jun 23, 2016
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_DATA_SRC_NN_CELLLIST_CELLNNITERATORM_HPP_
9#define OPENFPM_DATA_SRC_NN_CELLLIST_CELLNNITERATORM_HPP_
10
11
12#include "util/mathutil.hpp"
13#include <boost/integer/integer_mask.hpp>
14#include "CellList_util.hpp"
15#include "CellNNIterator.hpp"
16
17/*! \brief Iterator for the neighborhood of the cell structures
18 *
19 * In general you never create it directly but you get it from the CellList structures
20 *
21 * It iterate across all the element of the selected cell and the near cells accordingly yo the
22 * symmetric scheme
23 *
24 * \tparam dim dimensionality of the space where the cell live
25 * \tparam Cell cell type on which the iterator is working
26 * \tparam NNc_size neighborhood size
27 * \tparam impl implementation specific options NO_CHECK do not do check on access, SAFE do check on access
28 *
29 */
30template<unsigned int dim, typename Cell, unsigned int sh_byte, int NNc_size, unsigned int impl>
31class CellNNIteratorSymM : public CellNNIterator<dim,Cell,NNc_size,impl>
32{
33 typedef boost::low_bits_mask_t<sizeof(size_t)*8-sh_byte> mask_low;
34
35 //! phase of particle p
36 size_t pp;
37
38 //! index of the particle p
39 size_t p;
40
41 //! Position of the particles p
42 const typename Cell::internal_vector_pos_type & pos;
43
44 //! Position of the particle p
45 const typename openfpm::vector<pos_v<typename Cell::internal_vector_pos_type>> & ps;
46
47 /*! Select the next valid element
48 *
49 */
50 inline void selectValid()
51 {
52 if (this->NNc[this->NNc_id] == 0)
53 {
54 while (this->start_id < this->stop_id)
55 {
56 size_t q = this->cl.get_lin(this->start_id);
57 for (long int i = dim-1 ; i >= 0 ; i--)
58 {
59 if (pos.template get<0>(p)[i] < ps.get(q >> (sizeof(size_t)*8-sh_byte)).pos.template get<0>(q & mask_low::sig_bits_fast)[i])
60 return;
61 else if (pos.template get<0>(p)[i] > ps.get(q >> (sizeof(size_t)*8-sh_byte)).pos.template get<0>(q & mask_low::sig_bits_fast)[i])
62 goto next;
63 }
64 if (q >> (sizeof(size_t)*8-sh_byte) != pp) return;
65 if ((q & mask_low::sig_bits_fast) >= p) return;
66next:
67 this->start_id++;
68 }
69
70 CellNNIterator<dim,Cell,NNc_size,impl>::selectValid();
71 }
72 else
73 {
74 CellNNIterator<dim,Cell,NNc_size,impl>::selectValid();
75 }
76 }
77
78public:
79
80 /*! \brief
81 *
82 * Cell NN iterator
83 *
84 * \param cell Cell id
85 * \param NNc Cell neighborhood indexes (relative)
86 * \param cl Cell structure
87 *
88 */
89 CellNNIteratorSymM(size_t cell,
90 size_t pp,
91 size_t p,
92 const NNc_array<dim,NNc_size> & NNc,
93 Cell & cl,
94 const typename Cell::internal_vector_pos_type & pos,
95 const typename openfpm::vector<pos_v<typename Cell::internal_vector_pos_type>> & ps)
96 :CellNNIterator<dim,Cell,NNc_size,impl>(cell,NNc,cl),pp(pp),p(p),pos(pos),ps(ps)
97 {
98 selectValid();
99 }
100
101
102 /*! \brief Get the value of the cell
103 *
104 * \return the next element object
105 *
106 */
107 inline size_t getP()
108 {
109 return CellNNIterator<dim,Cell,NNc_size,impl>::get() & mask_low::sig_bits_fast;
110 }
111
112 /*! \brief Get the value of the cell
113 *
114 * \return the next element object
115 *
116 */
117 inline size_t getV()
118 {
119 return (CellNNIterator<dim,Cell,NNc_size,impl>::get()) >> (sizeof(size_t)*8-sh_byte);
120 }
121
122 /*! \brief take the next element
123 *
124 * \return itself
125 *
126 */
127 inline CellNNIteratorSymM<dim,Cell,sh_byte,NNc_size,impl> & operator++()
128 {
129 this->start_id++;
130
131 selectValid();
132
133 return *this;
134 }
135};
136
137/*! \brief Iterator for the neighborhood of the cell structures
138 *
139 * In general you never create it directly but you get it from the CellList structures
140 *
141 * It iterate across all the element of the selected cell and the near cells
142 *
143 * \tparam dim dimensionality of the space where the cell live
144 * \tparam Cell cell type on which the iterator is working
145 * \tparam NNc_size neighborhood size
146 * \tparam impl implementation specific options NO_CHECK do not do check on access, SAFE do check on access
147 *
148 */
149template<unsigned int dim, typename Cell, unsigned int sh_byte, int NNc_size, unsigned int impl> class CellNNIteratorM : public CellNNIterator<dim,Cell,NNc_size,impl>
150{
151 typedef boost::low_bits_mask_t<sizeof(size_t)*8-sh_byte> mask_low;
152
153public:
154
155 /*! \brief
156 *
157 * Cell NN iterator
158 *
159 * \param cell Cell id
160 * \param NNc Cell neighborhood indexes (relative)
161 * \param cl Cell structure
162 *
163 */
164 CellNNIteratorM(size_t cell, const NNc_array<dim,NNc_size> &NNc, Cell & cl)
165 :CellNNIterator<dim,Cell,NNc_size,impl>(cell,NNc,cl)
166 {}
167
168
169 /*! \brief Get the value of the cell
170 *
171 * \return the next element object
172 *
173 */
174 inline size_t getP()
175 {
176 return CellNNIterator<dim,Cell,NNc_size,impl>::get() & mask_low::sig_bits_fast;
177 }
178
179 /*! \brief Get the value of the cell
180 *
181 * \return the next element object
182 *
183 */
184 inline size_t getV()
185 {
186 return (CellNNIterator<dim,Cell,NNc_size,impl>::get()) >> (sizeof(size_t)*8-sh_byte);
187 }
188};
189
190/*! \brief it iterate through the elements of a cell
191 *
192 * In general you do not create this object you get it from the CellList structures
193 *
194 * \tparam Cell cell type
195 *
196 */
197template<typename Cell, unsigned int sh_byte> class CellIteratorM : public CellIterator<Cell>
198{
199
200 typedef boost::low_bits_mask_t<sizeof(size_t)*8-sh_byte> mask_low;
201
202public:
203
204 /*! \brief Cell iterator
205 *
206 * \param cell Cell id
207 * \param cl Cell on which iterate
208 *
209 */
210 CellIteratorM(const size_t cell, Cell & cl)
211 :CellIterator<Cell>(cell,cl)
212 {}
213
214 /*! \brief Get the value of the cell
215 *
216 * \return the next element object
217 *
218 */
219 inline size_t getP()
220 {
221 return CellIterator<Cell>::get() & mask_low::sig_bits_fast;
222 }
223
224 /*! \brief Get the value of the cell
225 *
226 * \return the next element object
227 *
228 */
229 inline size_t getV()
230 {
231 return (CellIterator<Cell>::get()) >> (sizeof(size_t)*8-sh_byte);
232 }
233};
234
235#include "CellNNIteratorRuntimeM.hpp"
236
237#endif /* OPENFPM_DATA_SRC_NN_CELLLIST_CELLNNITERATORM_HPP_ */
238