grid_dist_id_iterator.hpp 8.55 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
Working  
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 25 26
 * \tparam dim dimensionality of the grid
 * \tparam device_grid type of basic grid
 * \tparam impl implementation
 *
incardon's avatar
incardon committed
27
 */
incardon's avatar
incardon committed
28
template<unsigned int dim, typename device_grid, int impl,typename stencil = no_stencil >
incardon's avatar
incardon committed
29 30 31 32 33
class grid_dist_iterator
{

};

incardon's avatar
incardon committed
34

incardon's avatar
incardon committed
35 36 37 38 39 40 41 42 43
/*! \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
44 45
template<unsigned int dim, typename device_grid, typename stencil>
class grid_dist_iterator<dim,device_grid,FREE,stencil>
incardon's avatar
incardon committed
46 47 48 49 50
{
	//! grid list counter
	size_t g_c;

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

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

incardon's avatar
incardon committed
56
	//! Actual iterator
incardon's avatar
incardon committed
57
	grid_key_dx_iterator_sub<dim,stencil> a_it;
incardon's avatar
incardon committed
58

Pietro Incardona's avatar
Pietro Incardona committed
59 60
	//! stop point (is the grid size)
	grid_key_dx<dim> stop;
incardon's avatar
incardon committed
61

incardon's avatar
incardon committed
62 63 64 65 66 67
	/*! \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
68
		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
69 70 71 72

		// get the next grid iterator
		if (g_c < gList.size())
		{
73
			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
74 75 76
		}
	}

incardon's avatar
incardon committed
77 78
	public:

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

incardon's avatar
incardon committed
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
	/*! \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
114 115
	// Destructor
	~grid_dist_iterator()
incardon's avatar
incardon committed
116 117
	{
	}
incardon's avatar
incardon committed
118

incardon's avatar
incardon committed
119
	/*! \brief Get the next element
incardon's avatar
incardon committed
120
	 *
incardon's avatar
incardon committed
121
	 * \return the next grid_key
incardon's avatar
incardon committed
122 123
	 *
	 */
incardon's avatar
incardon committed
124

incardon's avatar
incardon committed
125
	inline grid_dist_iterator<dim,device_grid,FREE,stencil> & operator++()
incardon's avatar
incardon committed
126
	{
incardon's avatar
incardon committed
127 128 129 130 131 132 133 134 135 136 137
		++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
138
			selectValidGrid();
incardon's avatar
incardon committed
139
		}
incardon's avatar
incardon committed
140 141

		return *this;
incardon's avatar
incardon committed
142 143 144 145 146 147 148
	}

	/*! \brief Check if there is the next element
	 *
	 * \return true if there is the next, false otherwise
	 *
	 */
incardon's avatar
incardon committed
149
	inline bool isNext()
incardon's avatar
incardon committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163
	{
		// 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
164
	inline grid_dist_key_dx<dim> get()
incardon's avatar
incardon committed
165 166 167
	{
		return grid_dist_key_dx<dim>(g_c,a_it.get());
	}
Pietro Incardona's avatar
Pietro Incardona committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195

	/*! \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
196 197 198 199 200 201 202 203 204 205 206 207

	/*! \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;
	}
208 209 210 211 212 213

	/*! \brief Convert a g_dist_key_dx into a global key
	 *
	 * \see grid_dist_key_dx
	 * \see grid_dist_iterator
	 *
incardon's avatar
incardon committed
214 215
	 * \param k key position in local coordinates
	 *
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
	 * \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();

		grid_key_dx<dim> k_glob = k.getKey();

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

		return k_glob;
	}
incardon's avatar
incardon committed
231 232 233 234 235 236 237 238 239 240 241 242

	/*! \brief Return the stencil point offset
	 *
	 * \tparam id
	 *
	 * \return linearized distributed key
	 *
	 */
	template<unsigned int id> inline grid_dist_lin_dx getStencil()
	{
		return grid_dist_lin_dx(g_c,a_it.getStencil<id>());
	}
incardon's avatar
incardon committed
243 244 245 246 247 248 249 250 251 252 253 254
};


/*! \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
255 256
template<unsigned int dim, typename device_grid,typename stencil>
class grid_dist_iterator<dim,device_grid,FIXED,stencil>
incardon's avatar
incardon committed
257 258 259 260 261
{
	//! grid list counter
	size_t g_c;

	//! List of the grids we are going to iterate
262
	const openfpm::vector<device_grid> & gList;
incardon's avatar
incardon committed
263 264 265 266 267

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

	//! Actual iterator
incardon's avatar
incardon committed
268
	grid_key_dx_iterator<dim,stencil> a_it;
incardon's avatar
incardon committed
269

270 271 272 273 274 275
	/*! \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
276
		while (g_c < gList.size() && (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false ) ) g_c++;
277 278 279 280

		// get the next grid iterator
		if (g_c < gList.size())
		{
281
			a_it.reinitialize(gList.get(g_c).getIterator(gdb_ext.get(g_c).Dbox.getKP1(),gdb_ext.get(g_c).Dbox.getKP2()));
282 283 284
		}
	}

incardon's avatar
incardon committed
285 286
	public:

incardon's avatar
incardon committed
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
	/*! \brief Copy operator=
	*
	* \param tmp iterator to copy
	*
	*/
	grid_dist_iterator<dim,device_grid,FIXED> & operator=(const grid_dist_iterator<dim,device_grid,FIXED> & tmp)
	{
		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
303 304 305 306
	 *
	 * \param gk std::vector of the local grid
	 *
	 */
307
	grid_dist_iterator(const openfpm::vector<device_grid> & gk, const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
incardon's avatar
incardon committed
308 309 310 311
	:g_c(0),gList(gk),gdb_ext(gdb_ext)
	{
		// Initialize the current iterator
		// with the first grid
312
		selectValidGrid();
incardon's avatar
incardon committed
313 314 315 316 317 318
	}

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

incardon's avatar
incardon committed
320 321 322 323 324 325
	/*! \brief Get the next element
	 *
	 * \return the next grid_key
	 *
	 */

incardon's avatar
incardon committed
326
	grid_dist_iterator<dim,device_grid,FIXED> &  operator++()
incardon's avatar
incardon committed
327
	{
incardon's avatar
incardon committed
328
		++a_it;
incardon's avatar
incardon committed
329 330 331

		// check if a_it is at the end

incardon's avatar
incardon committed
332
		if (a_it.isNext() == true)
incardon's avatar
incardon committed
333 334 335 336 337
			return *this;
		else
		{
			// switch to the new grid
			g_c++;
338
			selectValidGrid();
incardon's avatar
incardon committed
339 340 341 342 343 344 345 346 347 348
		}

		return *this;
	}

	/*! \brief Check if there is the next element
	 *
	 * \return true if there is the next, false otherwise
	 *
	 */
incardon's avatar
incardon committed
349
	bool isNext()
incardon's avatar
incardon committed
350 351 352 353
	{
		// If there are no other grid stop

		if (g_c >= gList.size())
incardon's avatar
incardon committed
354 355 356
			return false;

		return true;
incardon's avatar
incardon committed
357 358 359 360 361 362 363 364 365
	}

	/*! \brief Get the actual key
	 *
	 * \return the actual key
	 *
	 */
	grid_dist_key_dx<dim> get()
	{
incardon's avatar
incardon committed
366
		return grid_dist_key_dx<dim>(g_c,a_it.get());
incardon's avatar
incardon committed
367
	}
Pietro Incardona's avatar
Pietro Incardona committed
368 369 370 371 372 373 374 375 376 377 378 379

	/*! \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;
	}
380 381 382 383 384 385

	/*! \brief Convert a g_dist_key_dx into a global key
	 *
	 * \see grid_dist_key_dx
	 * \see grid_dist_iterator
	 *
incardon's avatar
incardon committed
386 387
	 * \param k local coordinates to convert into global
	 *
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
	 * \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();

		grid_key_dx<dim> k_glob = k.getKey();

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

		return k_glob;
	}
incardon's avatar
incardon committed
403 404 405 406 407 408 409 410 411 412 413 414

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

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