Domain_NN_calculator_cart.hpp 9.13 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
/*
 * Domain_NN_calculator.hpp
 *
 *  Created on: Nov 26, 2016
 *      Author: i-bird
 */

#ifndef SRC_DECOMPOSITION_DOMAIN_NN_CALCULATOR_CART_HPP_
#define SRC_DECOMPOSITION_DOMAIN_NN_CALCULATOR_CART_HPP_

/*! \brief This class calculate processor domains and neighborhood
 *  of each processor domain
 *
 * \param dim Dimensionality
 *
 */
template<unsigned int dim>
class domain_nn_calculator_cart
{
	//! True if domain and anomalous domain cells are computed
	bool are_domain_anom_computed;

incardon's avatar
incardon committed
23 24 25 26
	//! Are linearized the domain cells
    bool are_dom_cells_lin;

	//! Are linearized the CRS domain cell
incardon's avatar
incardon committed
27 28
    bool are_dom_lin;

incardon's avatar
incardon committed
29
    //! are linearized the CRS anomalous cells
incardon's avatar
incardon committed
30 31
    bool are_anom_lin;

incardon's avatar
incardon committed
32
	//! anomalous cell neighborhood for CRS
incardon's avatar
incardon committed
33 34
	openfpm::vector<subsub<dim>> anom;

incardon's avatar
incardon committed
35
	//! Set of normal domain cells for CRS
incardon's avatar
incardon committed
36 37
	openfpm::vector<grid_key_dx<dim>> dom;

incardon's avatar
incardon committed
38 39 40
	//! Set of domain cells
	openfpm::vector<grid_key_dx<dim>> dom_cells;

incardon's avatar
incardon committed
41 42 43 44 45 46 47 48 49 50 51 52 53
	//! Linearization is calculated out of a shift and grid dimension this is the shift
	grid_key_dx<dim> shift_calc_dom;

	//! Linearization is calculated out of a grid dimensions this is the grid dimension
	grid_sm<dim,void> gs_calc_dom;

	//! Linearization is calculated out of a shift and grid dimension this is the shift
	grid_key_dx<dim> shift_calc_anom;

	//! Linearization is calculated out of a grid dimensions this is the grid dimension
	grid_sm<dim,void> gs_calc_anom;


incardon's avatar
incardon committed
54
	//! Set of normal CRS domain cells linearized
incardon's avatar
incardon committed
55 56
	openfpm::vector<size_t> dom_lin;

incardon's avatar
incardon committed
57
	//! Set of anomalous CRS domain cells linearized
incardon's avatar
incardon committed
58 59
	openfpm::vector<subsub_lin<dim>> anom_lin;

incardon's avatar
incardon committed
60 61 62
	//! Set of linearized domain cells
	openfpm::vector<size_t> dom_cells_lin;

incardon's avatar
incardon committed
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 104 105 106 107 108 109 110 111 112
	//! Processor box
	Box<dim,long int> proc_box;

	/*! \brief Calculate the subdomain that are in the skin part of the domain
	 *
       \verbatim

		+---+---+---+---+---+---+
		| 1 | 2 | 3 | 4 | 5 | 6 |
		+---+---+---+---+---+---+
		|27 |               | 7 |
		+---+               +---+
		|26 |               | 8 |
		+---+               +---+
		|25 |               | 9 |
		+---+   DOM1        +---+
		|24 |               |10 |
		+---+               +---+
		|23 |               |11 |
		+---+               +---+
		|22 |               |12 |
		+---+-----------+---+---+
		|21 |           |13 |
		+---+           +---+
		|20 |   DOM2    |14 |
		+---+---+---+---+---+
		|19 |18 |17 | 16|15 |
		+---+---+---+---+---+    <----- Domain end here
                                      |
                        ^             |
                        |_____________|


       \endverbatim
	 *
	 * In some cases like symmetric with CRS Scheme The cells indicated with numbers has a non straigh-forward
	 * neighborhood. This function calculate the list of the domain cells with normal symmetric neighborhood type
	 * and compute a list of cells with more complex neighboring cells.
	 *
	 * \param sub_keys array that contain the position of the sub-sub-domains indicated with numbers
	 *        in grid coordinates + for each its neighboring cells
	 *
	 * \param list of all the domain cells
	 *
	 * \param loc_box array of local sub-sub-domain in grid coordinates
	 *
	 * \param proc_box Processor bounding box in local coordinates
	 *
	 *
	 */
incardon's avatar
incardon committed
113 114
	void CalculateDomAndAnomCells(openfpm::vector<subsub<dim>> & sub_keys,
			                      openfpm::vector<grid_key_dx<dim>> & dom_subsub,
incardon's avatar
incardon committed
115
								  openfpm::vector<grid_key_dx<dim>> & dom_cells,
incardon's avatar
incardon committed
116 117 118
								  const ::Box<dim,long int> & proc_box,
								  grid_key_dx<dim> & shift,
								  const openfpm::vector<::Box<dim, size_t>> & loc_box)
incardon's avatar
incardon committed
119
	{
incardon's avatar
incardon committed
120 121 122 123
		// Reset dom and dom_subsub
		sub_keys.clear();
		dom_subsub.clear();

incardon's avatar
incardon committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
		size_t sz[dim];

		for (size_t j = 0 ; j < dim ; j++)
			sz[j] = proc_box.getHigh(j) - proc_box.getLow(j) + 2;

		// Set the grid
		grid_cpu<dim, aggregate<openfpm::vector<grid_key_dx<dim>>> > g(sz);
		g.setMemory();

		// Calculate the csr neighborhood
		openfpm::vector<std::pair<grid_key_dx<dim>,grid_key_dx<dim>>> csr;
		NNcalc_csr(csr);

		// Draw the domain on this grid
		for (size_t i = 0 ; i < loc_box.size() ; i++)
		{
			grid_key_dx<dim> start;
			grid_key_dx<dim> stop;

			for (size_t j = 0 ; j < dim ; j++)
			{
				start.set_d(j,loc_box.template get<0>(i)[j] - proc_box.getLow(j));
				stop.set_d(j,loc_box.template get<1>(i)[j] - proc_box.getLow(j));
			}

			grid_key_dx_iterator_sub<dim> sub(g.getGrid(),start,stop);

			while (sub.isNext())
			{
				auto key = sub.get();

				for (size_t j = 0 ; j < csr.size() ; j++)
				{
					grid_key_dx<dim> src = key + csr.get(j).first;
					grid_key_dx<dim> dst = key + csr.get(j).second;
					g.template get<0>(src).add(dst + shift);
				}

incardon's avatar
incardon committed
162 163
				dom_cells.add(key + shift);

incardon's avatar
incardon committed
164 165 166 167 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 196 197
				++sub;
			}
		}

		// Span all the grid point and take all the sub-sub-domains that has a
		// neighborhood non-consistent to the normal symmetric NN, and the one that
		// are consistent to NN symmetric
		grid_key_dx_iterator<dim> it(g.getGrid());

		while (it.isNext())
		{
			auto key = it.get();

			// Adding in the list of the non-normal neighborhood cells
			if (g.template get<0>(key).size() == openfpm::math::pow(3,dim)/2+1)
			{
				// Add in the list of the normal neighborhood list
				dom_subsub.add(key + shift);
			}
			else if (g.template get<0>(key).size() != 0)
			{
				sub_keys.add();
				sub_keys.last().subsub = key + shift;
				// Adding the neighborhood of the cell
				sub_keys.last().NN_subsub = g.template get<0>(key);
			}

			++it;
		}
	}

public:

	domain_nn_calculator_cart()
incardon's avatar
incardon committed
198
	:are_domain_anom_computed(false),are_dom_cells_lin(false),are_dom_lin(false),are_anom_lin(false)
incardon's avatar
incardon committed
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
	{}

	/*! \brief Get the domain Cells
	 *
	 * \param shift Shifting point
	 * \param gs grid extension
	 * \param proc_box processor bounding box
	 * \param loc_box set of local sub-domains
	 *
	 * \return The set of domain cells
	 *
	 */
	openfpm::vector<size_t> & getDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs, Box<dim,size_t> & proc_box, openfpm::vector<::Box<dim, size_t>> & loc_box)
	{
		if (are_domain_anom_computed == false)
		{
incardon's avatar
incardon committed
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
			CalculateDomAndAnomCells(anom,dom,dom_cells,proc_box,shift,loc_box);
			are_domain_anom_computed = true;
		}

		if (are_dom_cells_lin == false)
		{
			dom_cells_lin.clear();
			shift_calc_dom = shift;
			gs_calc_dom = gs;
			for (size_t i = 0 ; i < dom_cells.size() ; i++)
				dom_cells_lin.add(gs.LinId(dom_cells.get(i) - cell_shift));

			are_dom_cells_lin = true;
		}

		return dom_cells_lin;
	}

	/*! \brief Get the domain Cells
	 *
	 * \param shift Shifting point
	 * \param gs grid extension
	 * \param proc_box processor bounding box
	 * \param loc_box set of local sub-domains
	 *
	 * \return The set of domain cells
	 *
	 */
	openfpm::vector<size_t> & getCRSDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs, Box<dim,size_t> & proc_box, openfpm::vector<::Box<dim, size_t>> & loc_box)
	{
		if (are_domain_anom_computed == false)
		{
			CalculateDomAndAnomCells(anom,dom,dom_cells,proc_box,shift,loc_box);
incardon's avatar
incardon committed
248 249 250
			are_domain_anom_computed = true;
		}

incardon's avatar
incardon committed
251
		if (are_dom_lin == false)
incardon's avatar
incardon committed
252 253 254 255 256 257
		{
			dom_lin.clear();
			shift_calc_dom = shift;
			gs_calc_dom = gs;
			for (size_t i = 0 ; i < dom.size() ; i++)
				dom_lin.add(gs.LinId(dom.get(i) - cell_shift));
incardon's avatar
incardon committed
258 259

			are_dom_lin = true;
incardon's avatar
incardon committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
		}

		return dom_lin;
	}

	/*! \brief Get the domain anomalous cells
	 *
	 * \param shift Shifting point
	 * \param gs grid extension
	 * \param proc_box processor bounding box
	 * \param loc_box set of local sub-domains
	 *
	 * \return The set of anomalous cells
	 *
	 */
incardon's avatar
incardon committed
275
	openfpm::vector<subsub_lin<dim>> & getCRSAnomDomainCells(grid_key_dx<dim> & shift, grid_key_dx<dim> & cell_shift, grid_sm<dim,void> & gs, Box<dim,size_t> & proc_box, openfpm::vector<::Box<dim, size_t>> & loc_box)
incardon's avatar
incardon committed
276 277 278 279
	{
		// if the neighborhood of each sub-sub-domains has not been calculated, calculate it
		if (are_domain_anom_computed == false)
		{
incardon's avatar
incardon committed
280
			CalculateDomAndAnomCells(anom,dom,dom_cells,proc_box,shift,loc_box);
incardon's avatar
incardon committed
281 282 283
			are_domain_anom_computed = true;
		}

incardon's avatar
incardon committed
284
		if (are_anom_lin == false)
incardon's avatar
incardon committed
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
		{
			anom_lin.clear();
			shift_calc_anom = shift;
			gs_calc_anom = gs;
			for (size_t i = 0 ; i < anom.size() ; i++)
			{
				anom_lin.add();
				anom_lin.last().subsub = gs.LinId(anom.get(i).subsub - cell_shift);

				long int self_cell = -1;

				for (size_t j = 0 ; j < anom.get(i).NN_subsub.size() ; j++)
				{
					anom_lin.get(i).NN_subsub.add((long int)gs.LinId(anom.get(i).NN_subsub.get(j) - cell_shift) - anom_lin.get(i).subsub);

					// This indicate that for example in the neighborhood of one cell it-self is included in the list
					// For example the cell 100 is in the neighborhood of the cell 100
					if (anom_lin.get(i).NN_subsub.last() == 0)
						self_cell = anom_lin.get(i).NN_subsub.size() - 1;
				}

				// if exist the self interacting cell (Example cell 100 neighborhood of cell 100), this cell MUST BE ALWAYS at the beginning
				if (self_cell != -1)
				{
					// bring the self-cell into the beginning
					size_t tmp = anom_lin.get(i).NN_subsub.get(0);
					anom_lin.get(i).NN_subsub.get(0) = 0;
					anom_lin.get(i).NN_subsub.get(self_cell) = tmp;
				}
			}
incardon's avatar
incardon committed
315 316

			are_anom_lin = true;
incardon's avatar
incardon committed
317 318 319 320
		}

		return anom_lin;
	}
incardon's avatar
incardon committed
321 322 323 324 325 326 327

	void reset()
	{
		are_domain_anom_computed = false;
		are_dom_lin = false;
		are_anom_lin = false;
	}
incardon's avatar
incardon committed
328 329 330
};

#endif /* SRC_DECOMPOSITION_DOMAIN_NN_CALCULATOR_CART_HPP_ */