1
2/*
3 * MemBalanced.hpp
4 *
5 * Created on: Mar 22, 2015
6 * Last modified: June 25, 2015
7 * Authors: Pietro Incardona, Yaroslav Zaluzhnyi
8 */
9
10#ifndef CELLLISTBAL_HPP_
11#define CELLLISTBAL_HPP_
12
13#include "NN/CellList/CellList.hpp"
14#include "Space/SpaceBox.hpp"
15#include "util/mathutil.hpp"
16#include "NN/CellList/CellNNIterator.hpp"
17#include "Space/Shape/HyperCube.hpp"
18
19/*! \brief Class for BALANCED cell list implementation
20 *
21 * \tparam local_index type of local index
22 *
23 * This class implement the BALANCED cell list is fast (not best)
24 * The memory allocation is small (not best).
25 * The memory allocation is (in byte) Size = M*16 + N*sizeof(ele)
26 *
27 * Where
28 *
29 * N = total number of elements
30 * M = number of cells
31 * sizeof(ele) = the size of the element the cell list is storing, example if
32 * the cell list store the particle id (64bit) is 8 byte
33 *
34 * \warning Do not use for extremely fine cell list (M big)
35 *
36 * \tparam dim Dimensionality of the space
37 * \tparam T type of the space float, double, complex
38 *
39 */
40template<typename local_index = size_t>
41class Mem_bal
42{
43 //! vector that store the information
44 typedef openfpm::vector<local_index> base;
45
46 //! each cell has a pointer to a dynamic structure
47 // that store the elements in the cell
48 openfpm::vector<base> cl_base;
49
50 //! Invalid element
51 local_index invalid;
52
53public:
54
55 typedef void toKernel_type;
56
57 //! expose the type of the local index
58 typedef local_index local_index_type;
59
60 /*! \brief Initialize all to zero
61 *
62 * \param slot number of slot (unused)
63 * \param tot_n_cell total number of cells
64 *
65 */
66 inline void init_to_zero(size_t slot, size_t tot_n_cell)
67 {
68 //resize the vector to needed number of cells
69
70 cl_base.resize(tot_n_cell);
71 clear();
72 }
73
74 /*! \brief Copy mem balanced
75 *
76 * \param cell memory to copy
77 *
78 * \return itself
79 *
80 */
81 inline Mem_bal & operator=(const Mem_bal & cell)
82 {
83 cl_base = cell.cl_base;
84
85 return *this;
86 }
87
88 /*! \brief Add an element to the cell
89 *
90 * \param cell_id id of the cell
91 * \param ele element to add
92 *
93 */
94 inline void addCell(size_t cell_id, typename base::value_type ele)
95 {
96 //add another neighbor element
97
98 cl_base.get(cell_id).add(ele);
99 }
100
101 /*! \brief Add an element to the cell
102 *
103 * \param cell_id id of the cell
104 * \param ele element to add
105 *
106 */
107 inline void add(size_t cell_id, typename base::value_type ele)
108 {
109 this->addCell(cell_id,ele);
110 }
111
112 /*! \brief Remove an element from the cell
113 *
114 * \param cell id of the cell
115 * \param ele element to remove
116 *
117 */
118 inline void remove(local_index cell, local_index ele)
119 {
120 cl_base.get(cell).remove(ele);
121 }
122
123 /*! \brief Get the number of elements in the cell
124 *
125 * \param cell_id id of the cell
126 *
127 * \return the number of elements in the cell
128 *
129 */
130 inline local_index getNelements(const local_index cell_id) const
131 {
132 return cl_base.get(cell_id).size();
133 }
134
135 /*! \brief Return an element from the cell
136 *
137 * \param cell id of the cell
138 * \param ele element id
139 *
140 * \return reference to the element
141 *
142 */
143 inline auto get(local_index cell, local_index ele) -> decltype(cl_base.get(0).get(0)) &
144 {
145 return cl_base.get(cell).get(ele);
146 }
147
148 /*! \brief Return an element from the cell
149 *
150 * \param cell id of the cell
151 * \param ele element id
152 *
153 * \return reference to the element
154 *
155 */
156 inline auto get(local_index cell, local_index ele) const -> decltype(cl_base.get(0).get(0)) &
157 {
158 return cl_base.get(cell).get(ele);
159 }
160
161 /*! \brief Swap two Mem_bal
162 *
163 * \param cl element to swap with
164 *
165 */
166 inline void swap(Mem_bal & cl)
167 {
168 cl_base.swap(cl.cl_base);
169 }
170
171 /*! \brief Swap two Mem_bal
172 *
173 * \param cell element to swap with
174 *
175 */
176 inline void swap(Mem_bal && cell)
177 {
178 cl_base.swap(cell.cl_base);
179 }
180
181 /*! \brief Reset the object
182 *
183 *
184 */
185 inline void clear()
186 {
187 for (size_t i = 0 ; i < cl_base.size() ; i++)
188 cl_base.get(i).clear();
189 }
190
191 /*! \brief Get the start index of the selected element
192 *
193 * \param part_id element
194 *
195 */
196 inline const local_index & getStartId(local_index part_id) const
197 {
198 if (cl_base.get(part_id).size() == 0)
199 return invalid;
200
201 return cl_base.get(part_id).get(0);
202 }
203
204 /*! \brief Get the stop index of the selected element
205 *
206 * \param part_id element
207 *
208 */
209 inline const local_index & getStopId(local_index part_id) const
210 {
211 if (cl_base.get(part_id).size() == 0)
212 return invalid;
213
214 return *(&cl_base.get(part_id).last() + 1);
215 }
216
217 /*! \brief get_lin
218 *
219 * It just return the element pointed by part_id
220 *
221 * \param part_id element
222 *
223 * \return the element pointed
224 *
225 */
226 inline const local_index & get_lin(const local_index * part_id) const
227 {
228 return *part_id;
229 }
230
231public:
232
233 inline Mem_bal(size_t slot)
234 :invalid(0)
235 {}
236
237 inline void set_slot(size_t slot)
238 {}
239
240};
241
242
243#endif /* CELLLISTBAL_HPP_ */
244