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 | */ |
20 | template<unsigned int dim> |
21 | struct 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 | */ |
35 | template<unsigned int dim> |
36 | struct 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 | */ |
52 | template<unsigned int dim,typename CellListType, typename vector_pos_type> class ParticleItCRS_Cells |
53 | { |
54 | private: |
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 | |
140 | public: |
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 | |