1/*
2 * CellListIterator_CRS.hpp
3 *
4 * Created on: Nov 14, 2016
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_DATA_SRC_NN_CELLLIST_PARTICLEITCRS_CELLS_HPP_
9#define OPENFPM_DATA_SRC_NN_CELLLIST_PARTICLEITCRS_CELLS_HPP_
10
11#include "CellNNIterator.hpp"
12#include "CellList_util.hpp"
13#include "NN/CellList/NNc_array.hpp"
14
15/*! \brief sub-sub-domain
16 *
17 * \tparam dim dimensionality
18 *
19 */
20template<unsigned int dim>
21struct subsub
22{
23 //! sub-sub-domain
24 grid_key_dx<dim> subsub;
25
26 //! Neighborhood of each sub-sub-domains
27 openfpm::vector<grid_key_dx<dim>> NN_subsub;
28};
29
30/*! \brief Linearized version of subsub
31 *
32 * \tparam dim dimensionality
33 *
34 */
35template<unsigned int dim>
36struct subsub_lin
37{
38 //! sub-sub-domain
39 size_t subsub;
40
41 //! Neighborhood of each sub-sub-domains (indicate the relative position compared to subsub)
42 openfpm::vector<long int> NN_subsub;
43};
44
45/*! \brief This iterator iterate across the particles of a Cell-list following the Cell structure
46 *
47 *
48 * \tparam dim Dimensionality
49 * \tparam CellListType type of the cell-list
50 *
51 */
52template<unsigned int dim,typename CellListType, typename vector_pos_type> class ParticleItCRS_Cells
53{
54private:
55
56 //! starting position
57 const typename CellListType::Mem_type_type::loc_index * start;
58
59 //! stop position
60 const typename CellListType::Mem_type_type::loc_index * stop;
61
62 //! Actual cell
63 size_t cid;
64
65 //! Neighborhood
66 const long int * NNc;
67
68 //! Neighborhood size
69 long int NNc_size;
70
71 //! If 0 we are iterating over the domain, if 1 we are iterating over the
72 //! anomalous neighborhood cells, if 2 we terminate
73 size_t dom_or_anom;
74
75 //! List of all the domain cells
76 const openfpm::vector<size_t> &dom_cell;
77
78 //! List of all anomalous domain cells with neighborhood
79 const openfpm::vector<subsub_lin<dim>> &anom_dom_cell;
80
81 //! The array contain the neighborhood of the cell-id in case of symmetric interaction
82 //
83 // * * *
84 // x *
85 //
86 const NNc_array<dim,openfpm::math::pow(3,dim)/2+1> & NNc_sym;
87
88 //! Celllist type
89 CellListType & cli;
90
91 /*! \brief Adjust the counters to reach a valid particle element
92 *
93 *
94 */
95 void selectValid()
96 {
97 while (start == stop)
98 {
99 cid++;
100
101 size_t s_cell;
102 if (dom_or_anom == 0)
103 {
104 if (cid >= dom_cell.size())
105 {
106 dom_or_anom = 1;
107 cid = 0;
108
109 // Terminate if we do not have anom cell
110 if (anom_dom_cell.size() == 0)
111 {
112 dom_or_anom = 2;
113 return;
114 }
115
116 s_cell = anom_dom_cell.get(cid).subsub;
117 }
118 else
119 s_cell = dom_cell.get(cid);
120 }
121 else
122 {
123 if (cid >= anom_dom_cell.size())
124 {
125 dom_or_anom = 2;
126 return;
127 }
128
129 s_cell = anom_dom_cell.get(cid).subsub;
130 }
131
132 // Get the starting particle
133 start = &cli.getStartId(s_cell);
134
135 // Get the stop particle
136 stop = &cli.getStopId(s_cell);
137 }
138 }
139
140public:
141
142 /*! \brief Initialize the iterator
143 *
144 * \param cli Cell-list
145 * \param dom_cell domain cell
146 * \param anom_dom_cell anomalous domain cell
147 * \param NNc_sym symmetric neighborhood
148 *
149 *
150 */
151 ParticleItCRS_Cells(CellListType & cli,
152 const openfpm::vector<size_t> & dom_cell,
153 const openfpm::vector<subsub_lin<dim>> & anom_dom_cell,
154 const NNc_array<dim,openfpm::math::pow(3,dim)/2+1> & NNc_sym)
155 :cid(0),NNc(NULL),NNc_size(0),dom_or_anom(0),dom_cell(dom_cell),anom_dom_cell(anom_dom_cell),NNc_sym(NNc_sym),cli(cli)
156 {
157 size_t s_cell;
158 if (dom_cell.size() != 0)
159 s_cell = dom_cell.get(0);
160 else if (anom_dom_cell.size() != 0)
161 {
162 s_cell = anom_dom_cell.get(0).subsub;
163 dom_or_anom = 1;
164 }
165 else
166 {
167 dom_or_anom = 2;
168
169 start = NULL;
170 stop = NULL;
171
172 return;
173 }
174
175 // Get the starting particle
176 start = &cli.getStartId(s_cell);
177
178 // Get the stop particle
179 stop = &cli.getStopId(s_cell);
180
181 selectValid();
182 }
183
184 /*! \brief Increment to the next particle
185 *
186 * \return The actual particle iterator
187 *
188 */
189 ParticleItCRS_Cells & operator++()
190 {
191 ++start;
192
193 selectValid();
194
195 return *this;
196 }
197
198 /*! \brief Return true if there is the next particle
199 *
200 * \return true if there is a new point
201 *
202 */
203 bool isNext()
204 {
205 return dom_or_anom != 2;
206 }
207
208 /*! \brief Get the actual particle id
209 *
210 * \return the actual particle id
211 *
212 */
213 size_t get()
214 {
215 return *start;
216 }
217
218
219 /*! \brief Get the neighborhood iterator according to the CRS scheme
220 *
221 * The CRS scheme use different neighborhood based on where the cell
222 * is positioned in the processor domain
223 *
224 *
225 * * * *
226 * x * for a cell x in the center of the domain
227 *
228 * *
229 * x for a cell in the outside right
230 *
231 * \return Return an iterator over the neighborhood particles
232 *
233 */
234 typename CellListType::SymNNIterator getNNIteratorCSR(const vector_pos_type & v) const
235 {
236 if (dom_or_anom == 0)
237 {return typename CellListType::SymNNIterator(dom_cell.get(cid),*start,NNc_sym.getPointer(),openfpm::math::pow(3,dim)/2+1,cli,v);}
238 else
239 {return typename CellListType::SymNNIterator(anom_dom_cell.get(cid).subsub,
240 *start,
241 &anom_dom_cell.get(cid).NN_subsub.get(0),
242 anom_dom_cell.get(cid).NN_subsub.size(),
243 cli,
244 v);}
245 }
246
247 /*! \brief Get the neighborhood iterator according to the CRS scheme Multi-phase case
248 *
249 * The CRS scheme use different neighborhood based on where the cell
250 * is positioned in the processor domain
251 *
252 *
253 * * * *
254 * x * for a cell x in the center of the domain
255 *
256 * *
257 * x for a cell in the outside right
258 *
259 * \return Return an iterator over the neighborhood particles
260 *
261 */
262 typename CellListType::SymNNIterator getNNIteratorCSRM(const vector_pos_type & pos ,
263 const openfpm::vector<pos_v<vector_pos_type>> & v) const
264 {
265 if (dom_or_anom == 0)
266 return typename CellListType::SymNNIterator(dom_cell.get(cid),CellListType::getV(*start),CellListType::getP(*start),NNc_sym.getPointer(),openfpm::math::pow(3,dim)/2+1,cli,pos,v);
267 else
268 return typename CellListType::SymNNIterator(anom_dom_cell.get(cid).subsub,CellListType::getV(*start),CellListType::getP(*start),&anom_dom_cell.get(cid).NN_subsub.get(0),anom_dom_cell.get(cid).NN_subsub.size(),cli,pos,v);
269 }
270};
271
272
273#endif /* OPENFPM_DATA_SRC_NN_CELLLIST_PARTICLEITCRS_CELLS_HPP_ */
274