PointIteratorSkin.hpp 4.49 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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 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 97 98 99 100 101 102 103
/*
 * PointIteratorSkin.hpp
 *
 *  Created on: Jan 4, 2017
 *      Author: i-bird
 */

#ifndef OPENFPM_NUMERICS_SRC_DRAW_POINTITERATORSKIN_HPP_
#define OPENFPM_NUMERICS_SRC_DRAW_POINTITERATORSKIN_HPP_

#include "Grid/Iterators/grid_dist_id_iterator_dec_skin.hpp"

#define RETURN_A 1
#define RETURN_B 2

/*! \brief this class draw particles on subset of grid-like position
 *
 \verbatim
             (Box B)
                |                    (0.6,0.6)
  +   +   +   + | +   +   +   +   +
    +---+-------+---+
  + | * | +   + | * | +   +   +   +
    |   |       |
  + | * | +   + | * | +   +   +   +
    |   |       |   |
  + | * | +   + | * | +   +   +   +
    |   |       |   |
  + | * | +   + | * | +   +   +   +
    |   |       |   |
  + | * | +   + | * | +   +   +   +
    |   |       |   |
  + | * | +   + | * | +   +   +   +
    |   +-------+   |
  + | *   *   *   * | +   +   +   +
    +---------------+
  +   +   +   +   + | +   +   +   +
(-1.0,-1.0)         |
                    |
                 (Box A)


 \endverbatim
 *
 *
 *  Suppose we have a grid 9x9 from (-1.0,-1.0 to 0.6,0.6)
 *
 *  Defined a Box A (-0.9,-0.9 to -0.1,0.5) and a box B (-0.7, -0.7 to -0.3,0.5)
 *
 *  This class will return the points indicated with *
 *
 */
template<unsigned int dim, typename T, typename Decomposition>
class PointIteratorSkin: protected grid_dist_id_iterator_dec_skin<Decomposition>
{
	//! Actual point
	Point<dim,T> ap;

	//! sub_domain (required to filter out points)
	openfpm::vector<Box<dim,T>> sub_domainA;

	//! domain
	Box<dim,T> domain;

	//! Spacing
	T sp[dim];

	static Box<dim,long int> getAB(size_t (& gs)[dim], const Box<dim,T> & dom, const Box<dim,T> & sub_domA , const Box<dim,T> & sub_domB, T (& sp)[dim], size_t AB)
	{
		for (size_t i = 0 ; i < dim ; i++)
			sp[i] = (dom.getHigh(i) - dom.getLow(i)) / (gs[i] -1);

		Box<dim,long int> box;

		for (size_t i = 0 ; i < dim ; i++)
		{
			size_t Ast = std::ceil( (sub_domA.getLow(i) - dom.getLow(i)) / sp[i] ) - 1;
			size_t Asp = std::floor( (sub_domA.getHigh(i) - dom.getLow(i)) / sp[i] ) + 1;

			size_t Bst = std::ceil( (sub_domB.getLow(i) - dom.getLow(i)) / sp[i] );
			size_t Bsp = std::floor( (sub_domB.getHigh(i) - dom.getLow(i)) / sp[i] );

			// grid_dist_id_iterator_dec_skin only work if A is contained into B
			Ast = (Ast < Bst)?Bst:Ast;
			Asp = (Asp > Bsp)?Bsp:Asp;

			if (AB == RETURN_A)
			{
				box.setLow(i,Ast);
				box.setHigh(i,Asp);
			}
			else
			{
				box.setLow(i,Bst);
				box.setHigh(i,Bsp);
			}
		}

		return box;
	}

	void calculateAp()
	{
104 105 106
		if (grid_dist_id_iterator_dec_skin<Decomposition>::isNext() == false)
			return;

incardon's avatar
incardon committed
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
		grid_key_dx<dim> key = grid_dist_id_iterator_dec_skin<Decomposition>::get();

		for (size_t i = 0 ; i < dim ; i++)
			ap.get(i) = key.get(i) * sp[i] + domain.getLow(i);
	}


	/*! it check that the actual point is not inside B
	 *
	 * \return true if the point is not inside B
	 *
	 */
	bool isValidPoint()
	{
		bool valid = true;

		for (size_t i = 0 ; i < sub_domainA.size() ; i++)
		{
			if (Box<dim,T>(sub_domainA.get(i)).isInside(ap) == true)
				valid = false;
		}

		return valid;
	}

public:

	/*! \brief Draw Particles
	 *
	 * \param sp grid spacing
	 *
	 */
139
	PointIteratorSkin( Decomposition & dec, size_t (& sz)[dim], const Box<dim,T> & domain, const Box<dim,T> & sub_A, const Box<dim,T> & sub_B, size_t (& bc)[dim])
incardon's avatar
incardon committed
140 141 142 143 144 145 146 147
	:grid_dist_id_iterator_dec_skin<Decomposition>(dec, sz, getAB(sz,domain,sub_A,sub_B,sp,RETURN_A), getAB(sz,domain,sub_A,sub_B,sp,RETURN_B), bc),domain(domain)
	{
		sub_domainA.add(sub_A);
		calculateAp();
	}

	/*! \Return the actual point
	 *
148
	 * \return the actual point
incardon's avatar
incardon committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
	 *
	 */
	Point<dim,T> & get()
	{
		return ap;
	}

	/*! \brief Next point
	 *
	 * \return itself
	 *
	 */
	PointIteratorSkin & operator++()
	{
		grid_dist_id_iterator_dec_skin<Decomposition>::operator++();
164

incardon's avatar
incardon committed
165 166 167 168 169
		calculateAp();

		while (grid_dist_id_iterator_dec_skin<Decomposition>::isNext() && isValidPoint() == false)
		{
			grid_dist_id_iterator_dec_skin<Decomposition>::operator++();
170

incardon's avatar
incardon committed
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
			calculateAp();
		}

		return *this;
	}

	bool isNext()
	{
		return grid_dist_id_iterator_dec_skin<Decomposition>::isNext();
	}

	PointIteratorSkin<dim,T,Decomposition> & operator=(PointIteratorSkin<dim,T,Decomposition> & p)
	{
		grid_dist_id_iterator_dec_skin<Decomposition>::operator=(p);

		ap = p.ap;
		sub_domainA = p.sub_domainA;
		domain = p.domain;

		for (size_t i = 0 ; i < dim; i++)
			sp[i] = p.sp[i];

		return *this;
	}

	void addBoxA(const Box<dim,double> & BoxA)
	{
		sub_domainA.add(BoxA);
	}
};



#endif /* OPENFPM_NUMERICS_SRC_DRAW_POINTITERATORSKIN_HPP_ */