grid_dist_id_iterator.hpp 9.5 KB
Newer Older
incardon's avatar
incardon committed
1
/*
incardon's avatar
incardon committed
2
 * grid_dist_id_iterator_sub.hpp
incardon's avatar
incardon committed
3 4 5 6 7 8 9 10
 *
 *  Created on: Feb 4, 2015
 *      Author: Pietro Incardona
 */

#ifndef GRID_DIST_ID_ITERATOR_HPP_
#define GRID_DIST_ID_ITERATOR_HPP_

incardon's avatar
incardon committed
11 12 13
#define FREE 1
#define FIXED 2

incardon's avatar
incardon committed
14
#include "Grid/grid_dist_key.hpp"
incardon's avatar
incardon committed
15
#include "VCluster/VCluster.hpp"
incardon's avatar
incardon committed
16
#include "util/GBoxes.hpp"
incardon's avatar
incardon committed
17 18


incardon's avatar
incardon committed
19 20
/*! \brief Distributed grid iterator
 *
incardon's avatar
incardon committed
21
 * Iterator across the local elements of the distributed grid
incardon's avatar
incardon committed
22
 *
incardon's avatar
incardon committed
23 24
 * \tparam dim dimensionality of the grid
 * \tparam device_grid type of basic grid
incardon's avatar
incardon committed
25
 * \tparam device_sub_it device grid sib-iterator type
incardon's avatar
incardon committed
26 27
 * \tparam impl implementation
 *
incardon's avatar
incardon committed
28
 */
incardon's avatar
incardon committed
29
template<unsigned int dim, typename device_grid, typename device_sub_it, int impl,typename stencil = no_stencil >
incardon's avatar
incardon committed
30 31 32 33 34
class grid_dist_iterator
{

};

incardon's avatar
incardon committed
35

incardon's avatar
incardon committed
36 37 38 39 40 41
/*! \brief Distributed grid iterator
 *
 * Iterator across the local elements of the distributed grid
 *
 * \tparam dim dimensionality of the grid
 * \tparam device_grid type of basic grid
incardon's avatar
incardon committed
42 43
 * \tparam stencil it inject the code to calculate stencil offset
 * \tparam sub_iterator it indicate the sub-iterator type of the device_grid
incardon's avatar
incardon committed
44 45
 *
 */
incardon's avatar
incardon committed
46 47
template<unsigned int dim, typename device_grid, typename device_sub_it, typename stencil>
class grid_dist_iterator<dim,device_grid,device_sub_it,FREE,stencil>
incardon's avatar
incardon committed
48 49 50 51 52
{
	//! grid list counter
	size_t g_c;

	//! List of the grids we are going to iterate
53
	const openfpm::vector<device_grid> & gList;
incardon's avatar
incardon committed
54

incardon's avatar
incardon committed
55
	//! Extension of each grid: domain and ghost + domain
56
	const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext;
incardon's avatar
incardon committed
57

incardon's avatar
incardon committed
58
	//! Actual iterator
incardon's avatar
incardon committed
59
	device_sub_it a_it;
incardon's avatar
incardon committed
60

61 62
	//! stop point (is the grid size)
	grid_key_dx<dim> stop;
incardon's avatar
incardon committed
63

incardon's avatar
incardon committed
64 65 66 67 68 69
	/*! \brief from g_c increment g_c until you find a valid grid
	 *
	 */
	void selectValidGrid()
	{
		// When the grid has size 0 potentially all the other informations are garbage
70
		while (g_c < gList.size() && (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++;
incardon's avatar
incardon committed
71 72 73 74

		// get the next grid iterator
		if (g_c < gList.size())
		{
75
			a_it.reinitialize(gList.get(g_c).getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2()));
incardon's avatar
incardon committed
76 77 78
		}
	}

incardon's avatar
incardon committed
79 80
	public:

81
	/*! \brief Constructor of the distributed grid iterator
incardon's avatar
incardon committed
82 83
	 *
	 * \param gk std::vector of the local grid
Pietro Incardona's avatar
Pietro Incardona committed
84 85
	 * \param gdb_ext set of local subdomains
	 * \param stop end point
incardon's avatar
incardon committed
86 87
	 *
	 */
incardon's avatar
incardon committed
88 89 90
	grid_dist_iterator(const openfpm::vector<device_grid> & gk,
					   const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext,
					   const grid_key_dx<dim> & stop)
91
	:g_c(0),gList(gk),gdb_ext(gdb_ext),stop(stop)
incardon's avatar
incardon committed
92
	{
incardon's avatar
incardon committed
93
		// Initialize the current iterator
incardon's avatar
incardon committed
94
		// with the first grid
incardon's avatar
incardon committed
95
		selectValidGrid();
incardon's avatar
incardon committed
96 97
	}

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	/*! \brief Constructor of the distributed grid iterator with
	 *         stencil support
	 *
	 * \param gk std::vector of the local grid
	 * \param gdb_ext set of local subdomains
	 * \param stop end point
	 * \param stencil_pnt stencil points
	 *
	 */
	grid_dist_iterator(const openfpm::vector<device_grid> & gk,
			           const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext,
					   const grid_key_dx<dim> & stop,
					   const grid_key_dx<dim> (& stencil_pnt)[stencil::nsp])
	:g_c(0),gList(gk),gdb_ext(gdb_ext),a_it(stencil_pnt),stop(stop)
	{
		// Initialize the current iterator
		// with the first grid
		selectValidGrid();
	}

incardon's avatar
incardon committed
118
	//! Copy constructor
incardon's avatar
incardon committed
119
	grid_dist_iterator(const grid_dist_iterator<dim,device_grid,device_sub_it,FREE,stencil> & g)
incardon's avatar
incardon committed
120 121 122 123
	:g_c(g.g_c),gList(g.gList),gdb_ext(g.gdb_ext),a_it(g.a_it),stop(g.stop)
	{}

	//! Copy constructor
incardon's avatar
incardon committed
124
	grid_dist_iterator(grid_dist_iterator<dim,device_grid,device_sub_it,FREE,stencil> && g)
incardon's avatar
incardon committed
125 126 127 128
	:g_c(g.g_c),gList(g.gList),gdb_ext(g.gdb_ext),a_it(g.a_it),stop(g.stop)
	{}

	//! Destructor
incardon's avatar
incardon committed
129
	~grid_dist_iterator()
incardon's avatar
incardon committed
130 131
	{
	}
incardon's avatar
incardon committed
132

incardon's avatar
incardon committed
133
	/*! \brief Get the next element
incardon's avatar
incardon committed
134
	 *
incardon's avatar
incardon committed
135
	 * \return the next grid_key
incardon's avatar
incardon committed
136 137
	 *
	 */
incardon's avatar
incardon committed
138
	inline grid_dist_iterator<dim,device_grid,device_sub_it,FREE,stencil> & operator++()
incardon's avatar
incardon committed
139
	{
incardon's avatar
incardon committed
140 141 142 143 144 145 146 147 148 149 150
		++a_it;

		// check if a_it is at the end

		if (a_it.isNext() == true)
			return *this;
		else
		{
			// switch to the new grid
			g_c++;

incardon's avatar
incardon committed
151
			selectValidGrid();
incardon's avatar
incardon committed
152
		}
incardon's avatar
incardon committed
153 154

		return *this;
incardon's avatar
incardon committed
155 156 157 158 159 160 161
	}

	/*! \brief Check if there is the next element
	 *
	 * \return true if there is the next, false otherwise
	 *
	 */
incardon's avatar
incardon committed
162
	inline bool isNext() const
incardon's avatar
incardon committed
163 164 165 166 167 168 169 170 171 172 173 174 175 176
	{
		// If there are no other grid stop

		if (g_c >= gList.size())
			return false;

		return true;
	}

	/*! \brief Get the actual key
	 *
	 * \return the actual key
	 *
	 */
incardon's avatar
incardon committed
177
	inline grid_dist_key_dx<dim, typename device_grid::base_key> get() const
incardon's avatar
incardon committed
178
	{
incardon's avatar
incardon committed
179
		return grid_dist_key_dx<dim,typename device_grid::base_key>(g_c,a_it.get());
incardon's avatar
incardon committed
180
	}
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208

	/*! \brief it return the stop point of the iterator
	 *
	 * The stop point of the iterator is just the grid size
	 *
	 * \return the stop point
	 *
	 */
	inline grid_key_dx<dim> getStop() const
	{
		return stop;
	}

	/*! \brief it return the start point of the iterator
	 *
	 * The start point of the iterator is the point with all coordinates zeros
	 *
	 * \return the start point
	 *
	 */
	inline grid_key_dx<dim> getStart() const
	{
		grid_key_dx<dim> start;

		start.zero();

		return start;
	}
Pietro Incardona's avatar
Pietro Incardona committed
209 210 211 212 213 214 215 216 217 218 219 220

	/*! \brief Get the boxes
	 *
	 *  Get the boxes that define the local grids
	 *
	 * \return Vector of local boxes
	 *
	 */
	inline const openfpm::vector<GBoxes<device_grid::dims>> & getGBoxes()
	{
		return gdb_ext;
	}
221 222 223 224 225 226

	/*! \brief Convert a g_dist_key_dx into a global key
	 *
	 * \see grid_dist_key_dx
	 * \see grid_dist_iterator
	 *
227 228
	 * \param k key position in local coordinates
	 *
229 230 231
	 * \return the global position in the grid
	 *
	 */
incardon's avatar
incardon committed
232
	inline grid_key_dx<dim> getGKey(const grid_dist_key_dx<dim,typename device_grid::base_key> & k)
233 234 235 236 237
	{
		// Get the sub-domain id
		size_t sub_id = k.getSub();

		grid_key_dx<dim> k_glob = k.getKey();
incardon's avatar
incardon committed
238
//		gList.get(sub_id).convert_key(k_glob,k.getKey());
239 240 241 242 243 244

		// shift
		k_glob = k_glob + gdb_ext.get(sub_id).origin;

		return k_glob;
	}
245 246 247 248 249 250 251 252 253 254

	/*! \brief Return the stencil point offset
	 *
	 * \tparam id
	 *
	 * \return linearized distributed key
	 *
	 */
	template<unsigned int id> inline grid_dist_lin_dx getStencil()
	{
incardon's avatar
incardon committed
255
		return grid_dist_lin_dx(g_c,a_it.template getStencil<id>());
256
	}
incardon's avatar
incardon committed
257 258 259 260 261 262 263 264 265 266 267 268
};


/*! \brief Distributed grid iterator
 *
 * Iterator across the local elements of the distributed grid
 *
 * \tparam dim dimensionality of the grid
 * \tparam device_grid type of basic grid
 * \tparam impl implementation
 *
 */
incardon's avatar
incardon committed
269 270
template<unsigned int dim, typename device_grid, typename device_sub_it,typename stencil>
class grid_dist_iterator<dim,device_grid,device_sub_it,FIXED,stencil>
incardon's avatar
incardon committed
271 272 273 274 275
{
	//! grid list counter
	size_t g_c;

	//! List of the grids we are going to iterate
276
	const openfpm::vector<device_grid> & gList;
incardon's avatar
incardon committed
277 278 279 280 281

	//! Extension of each grid: domain and ghost + domain
	const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext;

	//! Actual iterator
incardon's avatar
incardon committed
282
	device_sub_it a_it;
incardon's avatar
incardon committed
283

284 285 286 287 288 289
	/*! \brief from g_c increment g_c until you find a valid grid
	 *
	 */
	void selectValidGrid()
	{
		// When the grid has size 0 potentially all the other informations are garbage
290
		while (g_c < gList.size() && (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++;
291 292 293 294

		// get the next grid iterator
		if (g_c < gList.size())
		{
295
			a_it.reinitialize(gList.get(g_c).getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2()));
296 297 298
		}
	}

incardon's avatar
incardon committed
299 300
	public:

301 302 303 304
	/*! \brief Copy operator=
	*
	* \param tmp iterator to copy
	*
incardon's avatar
incardon committed
305 306
	* \return itself
	*
307
	*/
incardon's avatar
incardon committed
308
	grid_dist_iterator<dim,device_grid,device_sub_it,FIXED> & operator=(const grid_dist_iterator<dim,device_grid,device_sub_it,FIXED> & tmp)
309 310 311 312 313 314 315 316 317 318
	{
		g_c = tmp.g_c;
		gList = tmp.gList;
		gdb_ext = tmp.gdb_ext;
		a_it.reinitialize(tmp.a_it);

		return *this;
	}

	/*! \brief Constructor of the distributed grid iterator
incardon's avatar
incardon committed
319 320
	 *
	 * \param gk std::vector of the local grid
incardon's avatar
incardon committed
321
	 * \param gdb_ext information about the local grids
incardon's avatar
incardon committed
322 323
	 *
	 */
324
	grid_dist_iterator(const openfpm::vector<device_grid> & gk, const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
incardon's avatar
incardon committed
325 326 327 328
	:g_c(0),gList(gk),gdb_ext(gdb_ext)
	{
		// Initialize the current iterator
		// with the first grid
329
		selectValidGrid();
incardon's avatar
incardon committed
330 331 332 333 334 335
	}

	// Destructor
	~grid_dist_iterator()
	{
	}
incardon's avatar
incardon committed
336

incardon's avatar
incardon committed
337 338 339 340 341 342
	/*! \brief Get the next element
	 *
	 * \return the next grid_key
	 *
	 */

incardon's avatar
incardon committed
343
	grid_dist_iterator<dim,device_grid,device_sub_it,FIXED> &  operator++()
incardon's avatar
incardon committed
344
	{
incardon's avatar
incardon committed
345
		++a_it;
incardon's avatar
incardon committed
346 347 348

		// check if a_it is at the end

incardon's avatar
incardon committed
349
		if (a_it.isNext() == true)
incardon's avatar
incardon committed
350 351 352 353 354
			return *this;
		else
		{
			// switch to the new grid
			g_c++;
355
			selectValidGrid();
incardon's avatar
incardon committed
356 357 358 359 360 361 362 363 364 365
		}

		return *this;
	}

	/*! \brief Check if there is the next element
	 *
	 * \return true if there is the next, false otherwise
	 *
	 */
incardon's avatar
incardon committed
366
	bool isNext()
incardon's avatar
incardon committed
367 368 369 370
	{
		// If there are no other grid stop

		if (g_c >= gList.size())
incardon's avatar
incardon committed
371 372 373
			return false;

		return true;
incardon's avatar
incardon committed
374 375 376 377 378 379 380 381 382
	}

	/*! \brief Get the actual key
	 *
	 * \return the actual key
	 *
	 */
	grid_dist_key_dx<dim> get()
	{
incardon's avatar
incardon committed
383
		return grid_dist_key_dx<dim>(g_c,a_it.get());
incardon's avatar
incardon committed
384
	}
Pietro Incardona's avatar
Pietro Incardona committed
385 386 387 388 389 390 391 392 393 394 395 396

	/*! \brief Get the boxes
	 *
	 *  Get the boxes that define the local grids
	 *
	 * \return Vector of local boxes
	 *
	 */
	inline const openfpm::vector<GBoxes<device_grid::dims>> & getGBoxes()
	{
		return gdb_ext;
	}
397 398 399 400 401 402

	/*! \brief Convert a g_dist_key_dx into a global key
	 *
	 * \see grid_dist_key_dx
	 * \see grid_dist_iterator
	 *
403 404
	 * \param k local coordinates to convert into global
	 *
405 406 407 408 409 410 411 412
	 * \return the global position in the grid
	 *
	 */
	inline grid_key_dx<dim> getGKey(const grid_dist_key_dx<dim> & k)
	{
		// Get the sub-domain id
		size_t sub_id = k.getSub();

incardon's avatar
incardon committed
413 414
		grid_key_dx<dim> k_glob;
		gList.get(sub_id).convert_key(k_glob,k.getKey());
415 416 417 418 419 420

		// shift
		k_glob = k_glob + gdb_ext.get(sub_id).origin;

		return k_glob;
	}
421 422 423 424 425 426 427 428 429 430

	/*! \brief Return the stencil point offset
	 *
	 * \tparam id
	 *
	 * \return linearized distributed key
	 *
	 */
	template<unsigned int id> inline grid_dist_lin_dx getStencil()
	{
incardon's avatar
incardon committed
431
		return grid_dist_lin_dx(g_c,a_it.template getStencil<id>());
432
	}
incardon's avatar
incardon committed
433 434
};

incardon's avatar
incardon committed
435
#endif /* GRID_DIST_ID_ITERATOR_SUB_HPP_ */