| 1 | /* | 
| 2 |  * CellListIterator_CRS.hpp | 
| 3 |  * | 
| 4 |  *  Created on: Nov 14, 2016 | 
| 5 |  *      Author: i-bird | 
| 6 |  */ | 
| 7 |  | 
| 8 | #ifndef OPENFPM_DATA_SRC_NN_CELLLIST_PARTICLEITCRS_CELLS_HPP_ | 
| 9 | #define OPENFPM_DATA_SRC_NN_CELLLIST_PARTICLEITCRS_CELLS_HPP_ | 
| 10 |  | 
| 11 | #include "CellNNIterator.hpp" | 
| 12 | #include "CellList_util.hpp" | 
| 13 | #include "NN/CellList/NNc_array.hpp" | 
| 14 |  | 
| 15 | /*! \brief sub-sub-domain | 
| 16 |  * | 
| 17 |  * \tparam dim dimensionality | 
| 18 |  * | 
| 19 |  */ | 
| 20 | template<unsigned int dim> | 
| 21 | struct subsub | 
| 22 | { | 
| 23 | 	//! sub-sub-domain | 
| 24 | 	grid_key_dx<dim> subsub; | 
| 25 |  | 
| 26 | 	//! Neighborhood of each sub-sub-domains | 
| 27 | 	openfpm::vector<grid_key_dx<dim>> NN_subsub; | 
| 28 | }; | 
| 29 |  | 
| 30 | /*! \brief Linearized version of subsub | 
| 31 |  * | 
| 32 |  * \tparam dim dimensionality | 
| 33 |  * | 
| 34 |  */ | 
| 35 | template<unsigned int dim> | 
| 36 | struct subsub_lin | 
| 37 | { | 
| 38 | 	//! sub-sub-domain | 
| 39 | 	size_t subsub; | 
| 40 |  | 
| 41 | 	//! Neighborhood of each sub-sub-domains (indicate the relative position compared to subsub) | 
| 42 | 	openfpm::vector<long int> NN_subsub; | 
| 43 | }; | 
| 44 |  | 
| 45 | /*! \brief This iterator iterate across the particles of a Cell-list following the Cell structure | 
| 46 |  * | 
| 47 |  * | 
| 48 |  * \tparam dim Dimensionality | 
| 49 |  * \tparam CellListType type of the cell-list | 
| 50 |  * | 
| 51 |  */ | 
| 52 | template<unsigned int dim,typename CellListType, typename vector_pos_type> class ParticleItCRS_Cells | 
| 53 | { | 
| 54 | private: | 
| 55 |  | 
| 56 | 	//! starting position | 
| 57 | 	const typename CellListType::Mem_type_type::loc_index * start; | 
| 58 |  | 
| 59 | 	//! stop position | 
| 60 | 	const typename CellListType::Mem_type_type::loc_index * stop; | 
| 61 |  | 
| 62 | 	//! Actual cell | 
| 63 | 	size_t cid; | 
| 64 |  | 
| 65 | 	//! Neighborhood | 
| 66 | 	const long int * NNc; | 
| 67 |  | 
| 68 | 	//! Neighborhood size | 
| 69 | 	long int NNc_size; | 
| 70 |  | 
| 71 | 	//! If 0 we are iterating over the domain, if 1 we are iterating over the | 
| 72 | 	//! anomalous neighborhood cells, if 2 we terminate | 
| 73 | 	size_t dom_or_anom; | 
| 74 |  | 
| 75 | 	//! List of all the domain cells | 
| 76 | 	const openfpm::vector<size_t> &dom_cell; | 
| 77 |  | 
| 78 | 	//! List of all anomalous domain cells with neighborhood | 
| 79 | 	const openfpm::vector<subsub_lin<dim>> &anom_dom_cell; | 
| 80 |  | 
| 81 | 	//! The array contain the neighborhood of the cell-id in case of symmetric interaction | 
| 82 | 	// | 
| 83 | 	//   * * * | 
| 84 | 	//     x * | 
| 85 | 	// | 
| 86 | 	const NNc_array<dim,openfpm::math::pow(3,dim)/2+1> & NNc_sym; | 
| 87 |  | 
| 88 | 	//! Celllist type | 
| 89 | 	CellListType & cli; | 
| 90 |  | 
| 91 | 	/*! \brief Adjust the counters to reach a valid particle element | 
| 92 | 	 * | 
| 93 | 	 * | 
| 94 | 	 */ | 
| 95 | 	void selectValid() | 
| 96 | 	{ | 
| 97 | 		while (start == stop) | 
| 98 | 		{ | 
| 99 | 			cid++; | 
| 100 |  | 
| 101 | 			size_t s_cell; | 
| 102 | 			if (dom_or_anom == 0) | 
| 103 | 			{ | 
| 104 | 				if (cid >= dom_cell.size()) | 
| 105 | 				{ | 
| 106 | 					dom_or_anom = 1; | 
| 107 | 					cid = 0; | 
| 108 |  | 
| 109 | 					// Terminate if we do not have anom cell | 
| 110 | 					if (anom_dom_cell.size() == 0) | 
| 111 | 					{ | 
| 112 | 						dom_or_anom = 2; | 
| 113 | 						return; | 
| 114 | 					} | 
| 115 |  | 
| 116 | 					s_cell = anom_dom_cell.get(cid).subsub; | 
| 117 | 				} | 
| 118 | 				else | 
| 119 | 					s_cell = dom_cell.get(cid); | 
| 120 | 			} | 
| 121 | 			else | 
| 122 | 			{ | 
| 123 | 				if (cid >= anom_dom_cell.size()) | 
| 124 | 				{ | 
| 125 | 					dom_or_anom = 2; | 
| 126 | 					return; | 
| 127 | 				} | 
| 128 |  | 
| 129 | 				s_cell = anom_dom_cell.get(cid).subsub; | 
| 130 | 			} | 
| 131 |  | 
| 132 | 			// Get the starting particle | 
| 133 | 			start = &cli.getStartId(s_cell); | 
| 134 |  | 
| 135 | 			// Get the stop particle | 
| 136 | 			stop = &cli.getStopId(s_cell); | 
| 137 | 		} | 
| 138 | 	} | 
| 139 |  | 
| 140 | public: | 
| 141 |  | 
| 142 | 	/*! \brief Initialize the iterator | 
| 143 | 	 * | 
| 144 | 	 * \param cli Cell-list | 
| 145 | 	 * \param dom_cell domain cell | 
| 146 | 	 * \param anom_dom_cell anomalous domain cell | 
| 147 | 	 * \param NNc_sym symmetric neighborhood | 
| 148 | 	 * | 
| 149 | 	 * | 
| 150 | 	 */ | 
| 151 | 	ParticleItCRS_Cells(CellListType & cli, | 
| 152 | 					 const openfpm::vector<size_t> & dom_cell, | 
| 153 | 					 const openfpm::vector<subsub_lin<dim>> & anom_dom_cell, | 
| 154 | 			         const NNc_array<dim,openfpm::math::pow(3,dim)/2+1> & NNc_sym) | 
| 155 | 	:cid(0),NNc(NULL),NNc_size(0),dom_or_anom(0),dom_cell(dom_cell),anom_dom_cell(anom_dom_cell),NNc_sym(NNc_sym),cli(cli) | 
| 156 | 	{ | 
| 157 | 		size_t s_cell; | 
| 158 | 		if (dom_cell.size() != 0) | 
| 159 | 			s_cell = dom_cell.get(0); | 
| 160 | 		else if (anom_dom_cell.size() != 0) | 
| 161 | 		{ | 
| 162 | 			s_cell = anom_dom_cell.get(0).subsub; | 
| 163 | 			dom_or_anom = 1; | 
| 164 | 		} | 
| 165 | 		else | 
| 166 | 		{ | 
| 167 | 			dom_or_anom = 2; | 
| 168 |  | 
| 169 | 			start = NULL; | 
| 170 | 			stop = NULL; | 
| 171 |  | 
| 172 | 			return; | 
| 173 | 		} | 
| 174 |  | 
| 175 | 		// Get the starting particle | 
| 176 | 		start = &cli.getStartId(s_cell); | 
| 177 |  | 
| 178 | 		// Get the stop particle | 
| 179 | 		stop = &cli.getStopId(s_cell); | 
| 180 |  | 
| 181 | 		selectValid(); | 
| 182 | 	} | 
| 183 |  | 
| 184 | 	/*! \brief Increment to the next particle | 
| 185 | 	 * | 
| 186 | 	 * \return The actual particle iterator | 
| 187 | 	 * | 
| 188 | 	 */ | 
| 189 | 	ParticleItCRS_Cells & operator++() | 
| 190 | 	{ | 
| 191 | 		++start; | 
| 192 |  | 
| 193 | 		selectValid(); | 
| 194 |  | 
| 195 | 		return *this; | 
| 196 | 	} | 
| 197 |  | 
| 198 | 	/*! \brief Return true if there is the next particle | 
| 199 | 	 * | 
| 200 | 	 * \return true if there is a new point | 
| 201 | 	 * | 
| 202 | 	 */ | 
| 203 | 	bool isNext() | 
| 204 | 	{ | 
| 205 | 		return dom_or_anom != 2; | 
| 206 | 	} | 
| 207 |  | 
| 208 | 	/*! \brief Get the actual particle id | 
| 209 | 	 * | 
| 210 | 	 * \return the actual particle id | 
| 211 | 	 * | 
| 212 | 	 */ | 
| 213 | 	size_t get() | 
| 214 | 	{ | 
| 215 | 		return *start; | 
| 216 | 	} | 
| 217 |  | 
| 218 |  | 
| 219 | 	/*! \brief Get the neighborhood iterator according to the CRS scheme | 
| 220 | 	 * | 
| 221 | 	 * The CRS scheme use different neighborhood based on where the cell | 
| 222 | 	 * is positioned in the processor domain | 
| 223 | 	 * | 
| 224 | 	 * | 
| 225 | 	 * * * * | 
| 226 | 	 *   x *  for a cell x in the center of the domain | 
| 227 | 	 * | 
| 228 | 	 *  * | 
| 229 | 	 *    x   for a cell in the outside right | 
| 230 | 	 * | 
| 231 | 	 * \return Return an iterator over the neighborhood particles | 
| 232 | 	 * | 
| 233 | 	 */ | 
| 234 | 	typename CellListType::SymNNIterator getNNIteratorCSR(const vector_pos_type & v) const | 
| 235 | 	{ | 
| 236 | 		if (dom_or_anom == 0) | 
| 237 | 		{return typename CellListType::SymNNIterator(dom_cell.get(cid),*start,NNc_sym.getPointer(),openfpm::math::pow(3,dim)/2+1,cli,v);} | 
| 238 | 		else | 
| 239 | 		{return typename CellListType::SymNNIterator(anom_dom_cell.get(cid).subsub, | 
| 240 | 					                                    *start, | 
| 241 | 														&anom_dom_cell.get(cid).NN_subsub.get(0), | 
| 242 | 														anom_dom_cell.get(cid).NN_subsub.size(), | 
| 243 | 														cli, | 
| 244 | 														v);} | 
| 245 | 	} | 
| 246 |  | 
| 247 | 	/*! \brief Get the neighborhood iterator according to the CRS scheme Multi-phase case | 
| 248 | 	 * | 
| 249 | 	 * The CRS scheme use different neighborhood based on where the cell | 
| 250 | 	 * is positioned in the processor domain | 
| 251 | 	 * | 
| 252 | 	 * | 
| 253 | 	 * * * * | 
| 254 | 	 *   x *  for a cell x in the center of the domain | 
| 255 | 	 * | 
| 256 | 	 *  * | 
| 257 | 	 *    x   for a cell in the outside right | 
| 258 | 	 * | 
| 259 | 	 * \return Return an iterator over the neighborhood particles | 
| 260 | 	 * | 
| 261 | 	 */ | 
| 262 | 	typename CellListType::SymNNIterator getNNIteratorCSRM(const vector_pos_type & pos , | 
| 263 | 														   const openfpm::vector<pos_v<vector_pos_type>> & v) const | 
| 264 | 	{ | 
| 265 | 		if (dom_or_anom == 0) | 
| 266 | 			return typename CellListType::SymNNIterator(dom_cell.get(cid),CellListType::getV(*start),CellListType::getP(*start),NNc_sym.getPointer(),openfpm::math::pow(3,dim)/2+1,cli,pos,v); | 
| 267 | 		else | 
| 268 | 			return typename CellListType::SymNNIterator(anom_dom_cell.get(cid).subsub,CellListType::getV(*start),CellListType::getP(*start),&anom_dom_cell.get(cid).NN_subsub.get(0),anom_dom_cell.get(cid).NN_subsub.size(),cli,pos,v); | 
| 269 | 	} | 
| 270 | }; | 
| 271 |  | 
| 272 |  | 
| 273 | #endif /* OPENFPM_DATA_SRC_NN_CELLLIST_PARTICLEITCRS_CELLS_HPP_ */ | 
| 274 |  |