grid_dist_id_iterator_sub.hpp 7.24 KB
Newer Older
incardon's avatar
incardon committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 * grid_dist_id_iterator_sub.hpp
 *
 *  Created on: Oct 14, 2015
 *      Author: i-bird
 */

#ifndef SRC_GRID_GRID_DIST_ID_ITERATOR_SUB_HPP_
#define SRC_GRID_GRID_DIST_ID_ITERATOR_SUB_HPP_


/*! \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
 *
 */
template<unsigned int dim, typename device_grid>
class grid_dist_iterator_sub
{
	// sub_set of the grid where to iterate
	struct sub_set
	{
		//! start point where iterate
		grid_key_dx<dim> start;
incardon's avatar
incardon committed
29
		//! stop point where iterate
incardon's avatar
incardon committed
30 31 32 33 34 35 36
		grid_key_dx<dim> stop;
	};

	//! grid list counter
	size_t g_c;

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

	//! Extension of each grid: domain and ghost + domain
Pietro Incardona's avatar
Pietro Incardona committed
40
	const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext;
incardon's avatar
incardon committed
41 42 43 44 45 46 47 48 49 50 51 52

	//! Actual iterator
	grid_key_dx_iterator_sub<dim> a_it;

	//! start key
	grid_key_dx<dim> start;

	//! stop key
	grid_key_dx<dim> stop;

	/*! \brief compute the subset where it has to iterate
	 *
incardon's avatar
incardon committed
53
	 * \param gc Actual grid
incardon's avatar
incardon committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
	 * \param start_c adjusted start point for the grid g_c
	 * \param stop_c adjusted stop point for the grid g_c
	 *
	 * \return false if the sub-set does not contain points
	 *
	 */
	bool compute_subset(size_t gc, grid_key_dx<dim> & start_c, grid_key_dx<dim> & stop_c)
	{
		// Intersect the grid keys

		for (size_t i = 0 ; i < dim ; i++)
		{
			long int start_p = gdb_ext.get(g_c).Dbox.getP1().get(i) + gdb_ext.get(g_c).origin.get(i);
			long int stop_p = gdb_ext.get(g_c).Dbox.getP2().get(i) + gdb_ext.get(g_c).origin.get(i);
			if (start.get(i) <= start_p)
				start_c.set_d(i,gdb_ext.get(g_c).Dbox.getP1().get(i));
			else if (start.get(i) <= stop_p)
				start_c.set_d(i,start.get(i) - gdb_ext.get(g_c).origin.get(i));
			else
				return false;

			if (stop.get(i) >= stop_p)
				stop_c.set_d(i,gdb_ext.get(g_c).Dbox.getP2().get(i));
			else if (stop.get(i) >= start_p)
				stop_c.set_d(i,stop.get(i) - gdb_ext.get(g_c).origin.get(i));
			else
				return false;
		}

		return true;
	}

	/*! \brief from g_c increment g_c until you find a valid grid
	 *
	 */
	void selectValidGrid()
	{
		// start and stop for the subset grid
		grid_key_dx<dim> start_c;
		grid_key_dx<dim> stop_c;

		// When the grid has size 0 potentially all the other informations are garbage
		while (g_c < gList.size() &&
97
			   (gList.get(g_c).size() == 0 || gdb_ext.get(g_c).Dbox.isValid() == false || compute_subset(g_c,start_c,stop_c) == false ))
incardon's avatar
incardon committed
98 99 100 101 102
		{g_c++;}

		// get the next grid iterator
		if (g_c < gList.size())
		{
103
			a_it.reinitialize(gList.get(g_c).getIterator(start_c,stop_c));
incardon's avatar
incardon committed
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
		}
	}

	public:

	/*! \brief Copy operator=
	*
	* \param tmp iterator to copy
	*
	*/
	grid_dist_iterator_sub<dim,device_grid> & operator=(const grid_dist_iterator_sub<dim,device_grid> & tmp)
	{
		g_c = tmp.g_c;
		gList = tmp.gList;
		gdb_ext = tmp.gdb_ext;
Pietro Incardona's avatar
Pietro Incardona committed
119 120
		start = tmp.start;
		stop = tmp.stop;
incardon's avatar
incardon committed
121 122 123 124 125 126 127 128 129 130 131
		a_it.reinitialize(tmp.a_it);

		return *this;
	}

	/*! \brief Copy constructor
	*
	* \param tmp iterator to copy
	*
	*/
	grid_dist_iterator_sub(const grid_dist_iterator_sub<dim,device_grid> & tmp)
132
	:g_c(tmp.g_c),gList(tmp.gList),gdb_ext(tmp.gdb_ext),start(tmp.start),stop(tmp.stop)
incardon's avatar
incardon committed
133
	{
Pietro Incardona's avatar
Pietro Incardona committed
134 135 136 137 138
		// get the next grid iterator
		if (g_c < gList.size())
		{
			a_it.reinitialize(tmp.a_it);
		}
incardon's avatar
incardon committed
139 140 141 142 143 144 145 146 147 148
	}

	/*! \brief Constructor of the distributed grid iterator
	 *
	 * \param start position
	 * \param stop position
	 * \param gk std::vector of the local grid
	 * \param gdb_ext information about the local grids
	 *
	 */
149
	grid_dist_iterator_sub(const grid_key_dx<dim> & start, const grid_key_dx<dim> & stop ,const openfpm::vector<device_grid> & gk, const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext)
Pietro Incardona's avatar
Pietro Incardona committed
150
	:g_c(0),gList(gk),gdb_ext(gdb_ext),start(start),stop(stop)
incardon's avatar
incardon committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
	{
		// Initialize the current iterator
		// with the first grid
		selectValidGrid();
	}

	// Destructor
	~grid_dist_iterator_sub()
	{
	}

	/*! \brief Get the next element
	 *
	 * \return the next grid_key
	 *
	 */

incardon's avatar
incardon committed
168
	inline grid_dist_iterator_sub<dim,device_grid> & operator++()
incardon's avatar
incardon committed
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 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
	{
		++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++;

			selectValidGrid();
		}

		return *this;
	}

	/*! \brief Check if there is the next element
	 *
	 * \return true if there is the next, false otherwise
	 *
	 */
	inline bool isNext()
	{
		// 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
	 *
	 */
	inline grid_dist_key_dx<dim> get()
	{
		return grid_dist_key_dx<dim>(g_c,a_it.get());
	}

	/*! \brief Convert a g_dist_key_dx into a global key
	 *
	 * \see grid_dist_key_dx
	 * \see grid_dist_iterator
	 *
	 * \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;
	}
232 233 234 235 236 237

	/* \brief Get the starting point of the grid iterator
	 *
	 * \return the starting point
	 *
	 */
Pietro Incardona's avatar
Pietro Incardona committed
238
	inline grid_key_dx<dim> getStart() const
239 240 241 242 243 244 245 246 247
	{
		return start;
	}

	/* \brief Get the stop point of the grid iterator
	 *
	 * \return the stop point
	 *
	 */
Pietro Incardona's avatar
Pietro Incardona committed
248
	inline grid_key_dx<dim> getStop() const
249 250 251
	{
		return stop;
	}
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286

	/*! \brief Return the number of local grids
	 *
	 *
	 */
	inline size_t N_loc_grid()
	{
		return gList.size();
	}

	/*! \brief Return the component j of the starting point (P1) of the domain part
	 *         for the local grid i
	 *
	 * \param i local grid
	 * \param j dimension
	 *
	 *
	 */
	inline size_t loc_grid_info_start(size_t i,size_t j)
	{
		return gdb_ext.get(i).DBox.getLow(i);
	}

	/*! \brief Return the component j of the stop point (P2) of the domain part
	 *         for the local grid i
	 *
	 * \param i local grid
	 * \param j dimension
	 *
	 *
	 */
	inline size_t loc_grid_info_size(size_t i,size_t j)
	{
		return gdb_ext.get(i).GDBox.getHigh(i);
	}
incardon's avatar
incardon committed
287 288
};

incardon's avatar
incardon committed
289 290 291 292

//////// MACRO in 3D

#define WHILE_M(grid,stencil) auto & ginfo = grid.getLocalGridsInfo();\
incardon's avatar
incardon committed
293
								 for (size_t s = 0 ; s < grid.getN_loc_grid() ; s++)\
incardon's avatar
incardon committed
294
								 {\
incardon's avatar
incardon committed
295
									 auto it = grid.get_loc_grid_iterator_stencil(s,stencil);\
incardon's avatar
incardon committed
296
\
incardon's avatar
incardon committed
297 298
										int lo[3] = {(int)ginfo.get(s).Dbox.getLow(0),(int)ginfo.get(s).Dbox.getLow(1),(int)ginfo.get(s).Dbox.getLow(2)};\
										int hi[3] = {(int)ginfo.get(s).Dbox.getHigh(0),(int)ginfo.get(s).Dbox.getHigh(1),(int)ginfo.get(s).Dbox.getHigh(2)};\
incardon's avatar
incardon committed
299
\
incardon's avatar
incardon committed
300
										int uhi[3] = {(int)ginfo.get(s).GDbox.getHigh(0),(int)ginfo.get(s).GDbox.getHigh(1),(int)ginfo.get(s).GDbox.getHigh(2)};\
incardon's avatar
incardon committed
301 302 303 304
\
										int sx = uhi[0]+1;\
										int sxsy = (uhi[0]+1)*(uhi[1]+1);

incardon's avatar
incardon committed
305 306
#define ITERATE_3D_M			int i = lo[2];\
								for ( ; i <= hi[2] ; i+=1)\
incardon's avatar
incardon committed
307
								{\
incardon's avatar
incardon committed
308 309
									int j = lo[1];\
									for ( ; j <= hi[1] ; j+=1)\
incardon's avatar
incardon committed
310
									{\
incardon's avatar
incardon committed
311 312
										int k = lo[0];\
										for ( ; k <= hi[0] ; k+=Vc::double_v::Size)\
incardon's avatar
incardon committed
313 314
										{

incardon's avatar
incardon committed
315
#define GET_GRID_M(grid)	grid.get_loc_grid(s);
incardon's avatar
incardon committed
316 317 318 319


#define END_LOOP_M 					it.private_sum<Vc::double_v::Size>();\
								}\
incardon's avatar
incardon committed
320
								it.private_adjust( - k + sx + lo[0]);\
incardon's avatar
incardon committed
321
							}\
incardon's avatar
incardon committed
322
							it.private_adjust(- j*sx + sxsy + lo[1]*sx);\
incardon's avatar
incardon committed
323 324 325
						}\
					}

incardon's avatar
incardon committed
326
#endif /* SRC_GRID_GRID_DIST_ID_ITERATOR_SUB_HPP_ */