| 1 | /* |
| 2 | * VerletListM.hpp |
| 3 | * |
| 4 | * Created on: Oct 15, 2016 |
| 5 | * Author: i-bird |
| 6 | */ |
| 7 | |
| 8 | #ifndef OPENFPM_DATA_SRC_NN_VERLETLIST_VERLETLISTM_HPP_ |
| 9 | #define OPENFPM_DATA_SRC_NN_VERLETLIST_VERLETLISTM_HPP_ |
| 10 | |
| 11 | #include "NN/VerletList/VerletNNIteratorM.hpp" |
| 12 | #include "VerletList.hpp" |
| 13 | |
| 14 | |
| 15 | /*! \brief Get the neighborhood iterator based on type |
| 16 | * |
| 17 | * \tparam dim dimensionality |
| 18 | * \tparam T type of space |
| 19 | * \tparam CellListImpl Cell-list implementation |
| 20 | * \tparam type of neighborhood |
| 21 | * \tparam PartIt Particle iterator |
| 22 | * |
| 23 | */ |
| 24 | template<unsigned int dim, typename T, typename CellListImpl, typename PartIt, int type> |
| 25 | struct NNTypeM |
| 26 | { |
| 27 | /*! \brief Get the neighborhood |
| 28 | * |
| 29 | * \param v particle positions |
| 30 | * \param xp Position of the particle p |
| 31 | * \param p id of the particle p |
| 32 | * \param cl Cell-list type implementation |
| 33 | * \param r_cut Cutoff radius |
| 34 | * |
| 35 | * \return the NN iterator |
| 36 | * |
| 37 | */ |
| 38 | static inline auto get(const PartIt & it, |
| 39 | const typename CellListImpl::internal_vector_pos_type & pos, |
| 40 | const openfpm::vector<pos_v<typename CellListImpl::internal_vector_pos_type>> & v, |
| 41 | Point<dim,T> & xp, |
| 42 | size_t pp, |
| 43 | size_t p, |
| 44 | CellListImpl & cl, |
| 45 | T r_cut) -> decltype(cl.template getNNIterator<NO_CHECK>(0)) |
| 46 | { |
| 47 | return cl.template getNNIterator<NO_CHECK>(cl.getCell(xp)); |
| 48 | } |
| 49 | }; |
| 50 | |
| 51 | /*! \brief Get the neighborhood iterator based on type |
| 52 | * |
| 53 | * specialization for the case with NN CRS symmetric |
| 54 | * |
| 55 | * \tparam dim dimensionality |
| 56 | * \tparam T type of space |
| 57 | * \tparam CellListImpl Cell-list implementation |
| 58 | * \tparam PartIt Particle iterator |
| 59 | * |
| 60 | */ |
| 61 | template<unsigned int dim, typename T, typename CellListImpl, typename PartIt> |
| 62 | struct NNTypeM<dim,T,CellListImpl,PartIt,VL_CRS_SYMMETRIC> |
| 63 | { |
| 64 | /*! \brief Get the neighborhood |
| 65 | * |
| 66 | * \param it particle iterator |
| 67 | * \param v vector of the particles positions |
| 68 | * \param xp Position of the particle p |
| 69 | * \param p id of the particle p |
| 70 | * \param cl Cell-list type implementation |
| 71 | * \param r_cut Cutoff radius |
| 72 | * |
| 73 | * \return the NN iterator |
| 74 | * |
| 75 | */ |
| 76 | static inline auto get(const PartIt & it, |
| 77 | const typename CellListImpl::internal_vector_pos_type & pos, |
| 78 | const openfpm::vector<pos_v<typename CellListImpl::internal_vector_pos_type>> & v, |
| 79 | Point<dim,T> & xp, |
| 80 | size_t pp, |
| 81 | size_t p, |
| 82 | CellListImpl & cl, |
| 83 | T r_cut) -> decltype(it.getNNIteratorCSRM(pos,v)) |
| 84 | { |
| 85 | return it.getNNIteratorCSRM(pos,v); |
| 86 | } |
| 87 | }; |
| 88 | |
| 89 | /*! \brief Get the neighborhood iterator based on type |
| 90 | * |
| 91 | * specialization for the case with NN symmetric |
| 92 | * |
| 93 | * \tparam dim dimensionality |
| 94 | * \tparam T type of space |
| 95 | * \tparam CellListImpl Cell-list implementation |
| 96 | * \tparam PartIt particle iterator |
| 97 | * |
| 98 | */ |
| 99 | template<unsigned int dim, typename T, typename CellListImpl, typename PartIt> |
| 100 | struct NNTypeM<dim,T,CellListImpl,PartIt,VL_SYMMETRIC> |
| 101 | { |
| 102 | /*! \brief Get the neighborhood |
| 103 | * |
| 104 | * \param v vector of the particles positions |
| 105 | * \param xp Position of the particle p |
| 106 | * \param p id of the particle p |
| 107 | * \param cl Cell-list type implementation |
| 108 | * \param r_cut Cutoff radius |
| 109 | * |
| 110 | * \return the NN iterator |
| 111 | * |
| 112 | */ |
| 113 | static inline auto get(const PartIt & it, |
| 114 | const typename CellListImpl::internal_vector_pos_type & pos, |
| 115 | const openfpm::vector<pos_v<typename CellListImpl::internal_vector_pos_type>> & v, |
| 116 | Point<dim,T> & xp, |
| 117 | size_t pp, |
| 118 | size_t p, |
| 119 | CellListImpl & cl, |
| 120 | T r_cut) -> decltype(cl.template getNNIteratorSym<NO_CHECK>(0,0,0,typename CellListImpl::internal_vector_pos_type(),openfpm::vector<pos_v<typename CellListImpl::internal_vector_pos_type>>())) |
| 121 | { |
| 122 | return cl.template getNNIteratorSym<NO_CHECK>(cl.getCell(xp),pp,p,pos,v); |
| 123 | } |
| 124 | }; |
| 125 | |
| 126 | |
| 127 | |
| 128 | /*! \brief Class for Verlet list implementation with Multiphase |
| 129 | * |
| 130 | * \tparam dim Dimensionality of the space |
| 131 | * \tparam T type of the space float, double ... |
| 132 | * \tparam CellListImpl Base structure that store the information |
| 133 | * |
| 134 | */ |
| 135 | template<unsigned int dim, |
| 136 | typename T, |
| 137 | unsigned int sh_byte , |
| 138 | typename CellListImpl=CellListM<dim,T,sh_byte>, |
| 139 | typename transform = shift<dim,T>, |
| 140 | typename vector_pos_type = openfpm::vector<Point<dim,T>>, |
| 141 | typename VerletBase=VerletList<dim,T,Mem_fast<>,transform, vector_pos_type> > |
| 142 | class VerletListM : public VerletBase |
| 143 | { |
| 144 | |
| 145 | //! Mask to get the high bits of a number |
| 146 | typedef boost::high_bit_mask_t<sh_byte> mask_high; |
| 147 | |
| 148 | //! Mask to get the low bits of a number |
| 149 | typedef boost::low_bits_mask_t<sizeof(size_t)*8-sh_byte> mask_low; |
| 150 | |
| 151 | /*! \brief Create the Verlet list from a given cell-list |
| 152 | * |
| 153 | * \param pos vector of positions |
| 154 | * \param pos2 vector of neighborhood particles position |
| 155 | * \param r_cut cut-off radius to get the neighborhood particles |
| 156 | * \param g_m Indicate form which particles to construct the verlet list. For example |
| 157 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
| 158 | * 100 particles |
| 159 | * \param cl Cell-list elements to use to construct the verlet list |
| 160 | * \param opt options to create the verlet list like VL_SYMMETRIC or VL_NON_SYMMETRIC |
| 161 | * |
| 162 | */ |
| 163 | inline void create(const vector_pos_type & pos, |
| 164 | const openfpm::vector<pos_v<vector_pos_type>> & pos2 , |
| 165 | const openfpm::vector<size_t> & dom, |
| 166 | const openfpm::vector<subsub_lin<dim>> & anom, |
| 167 | size_t pp, |
| 168 | T r_cut, |
| 169 | size_t g_m, |
| 170 | CellListImpl & cl, |
| 171 | size_t opt) |
| 172 | { |
| 173 | if (opt == VL_CRS_SYMMETRIC) |
| 174 | { |
| 175 | create_<CellNNIteratorSymM<dim,CellListImpl,sh_byte,RUNTIME,NO_CHECK>,VL_CRS_SYMMETRIC>(pos,pos2,dom,anom,pp,r_cut,g_m,cl,opt); |
| 176 | } |
| 177 | else if (opt == VL_SYMMETRIC) |
| 178 | { |
| 179 | create_<decltype(cl.template getNNIteratorSym<NO_CHECK>(0,0,0,pos,pos2)),VL_SYMMETRIC>(pos,pos2,dom,anom,pp,r_cut,g_m,cl,opt); |
| 180 | } |
| 181 | else |
| 182 | { |
| 183 | create_<decltype(cl.template getNNIterator<NO_CHECK>(0)),VL_NON_SYMMETRIC>(pos,pos2,dom,anom,pp,r_cut,g_m,cl,opt); |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | /*! \brief Create the Verlet list from a given cell-list |
| 188 | * |
| 189 | * \param pos vector of positions |
| 190 | * \param pos2 vector of position for the neighborhood |
| 191 | * \param r_cut cut-off radius to get the neighborhood particles |
| 192 | * \param g_m Indicate form which particles to construct the verlet list. For example |
| 193 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
| 194 | * 100 particles |
| 195 | * \param cli Cell-list elements to use to construct the verlet list |
| 196 | * \param dom list of domain cells with normal neighborhood |
| 197 | * \param anom list of domain cells with non-normal neighborhood |
| 198 | * \param opt options |
| 199 | * |
| 200 | */ |
| 201 | template<typename NN_type, int type> inline void create_(const vector_pos_type & pos, |
| 202 | const openfpm::vector<pos_v<vector_pos_type>> & pos2 , |
| 203 | const openfpm::vector<size_t> & dom, |
| 204 | const openfpm::vector<subsub_lin<dim>> & anom, |
| 205 | size_t pp, |
| 206 | T r_cut, |
| 207 | size_t g_m, |
| 208 | CellListImpl & cli, |
| 209 | size_t opt) |
| 210 | { |
| 211 | size_t end; |
| 212 | |
| 213 | auto it = PartItNN<type,dim,vector_pos_type,CellListImpl>::get(pos,dom,anom,cli,g_m,end); |
| 214 | |
| 215 | /* this->cl_n.resize(end); |
| 216 | this->cl_base.resize(end*this->slot); |
| 217 | this->cl_n.fill(0);*/ |
| 218 | |
| 219 | this->init_to_zero(this->slot,end); |
| 220 | |
| 221 | // square of the cutting radius |
| 222 | T r_cut2 = r_cut * r_cut; |
| 223 | |
| 224 | // iterate the particles |
| 225 | while (it.isNext()) |
| 226 | { |
| 227 | size_t i = it.get(); |
| 228 | Point<dim,T> xp = pos.template get<0>(i); |
| 229 | |
| 230 | // Get the neighborhood of the particle |
| 231 | NN_type NN = NNTypeM<dim,T,CellListImpl,decltype(it),type>::get(it,pos,pos2,xp,pp,i,cli,r_cut); |
| 232 | |
| 233 | while (NN.isNext()) |
| 234 | { |
| 235 | size_t nnp = NN.getP(); |
| 236 | size_t v = NN.getV(); |
| 237 | size_t nnp_a = NN.get(); |
| 238 | |
| 239 | Point<dim,T> xq = pos2.get(v).pos.template get<0>(nnp); |
| 240 | |
| 241 | if (xp.distance2(xq) < r_cut2) |
| 242 | this->addPart(i,nnp_a); |
| 243 | |
| 244 | // Next particle |
| 245 | ++NN; |
| 246 | } |
| 247 | |
| 248 | ++it; |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | public: |
| 253 | |
| 254 | /*! Initialize the verlet list from an already filled cell-list |
| 255 | * |
| 256 | * \param cli external Cell-list |
| 257 | * \param pp phase of pos |
| 258 | * \param r_cut cutoff-radius |
| 259 | * \param pos vector of particle positions |
| 260 | * \param pos2 vector of particle position for the neighborhood |
| 261 | * \param g_m Indicate form which particles to construct the verlet list. For example |
| 262 | * if we have 120 particles and g_m = 100, the Verlet list will be constructed only for the first |
| 263 | * 100 particles |
| 264 | * \param opt options for the Verlet-list creation |
| 265 | * |
| 266 | */ |
| 267 | void Initialize(CellListImpl & cli, size_t pp, |
| 268 | T r_cut, const vector_pos_type & pos, |
| 269 | const openfpm::vector<struct pos_v<vector_pos_type>> & pos2, size_t g_m, |
| 270 | size_t opt = VL_NON_SYMMETRIC) |
| 271 | { |
| 272 | // this->cl_n.resize(g_m); |
| 273 | // this->cl_base.resize(g_m*this->slot); |
| 274 | |
| 275 | Point<dim,T> spacing = cli.getCellBox().getP2(); |
| 276 | |
| 277 | // Create with radius or not |
| 278 | bool wr = true; |
| 279 | |
| 280 | for (size_t i = 0 ; i < dim ; i++) |
| 281 | {wr &= r_cut <= spacing.get(i);} |
| 282 | |
| 283 | if (wr == true || opt == VL_SYMMETRIC) |
| 284 | { |
| 285 | openfpm::vector<subsub_lin<dim>> anom_c; |
| 286 | openfpm::vector<size_t> dom_c; |
| 287 | |
| 288 | create(pos,pos2,dom_c,anom_c,pp,r_cut,g_m,cli,opt); |
| 289 | } |
| 290 | else |
| 291 | { |
| 292 | std::cerr << __FILE__ << ":" << __LINE__ << " error iterator with radius is not implemented yet " << std::endl; |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | /*! \brief Get the element-id in the cell |
| 297 | * |
| 298 | * \tparam i property to get |
| 299 | * |
| 300 | * \param part part id |
| 301 | * \param ele element id |
| 302 | * |
| 303 | * \return The element value |
| 304 | * |
| 305 | */ |
| 306 | inline size_t getP(size_t part, size_t ele) const |
| 307 | { |
| 308 | return VerletBase::get(part,ele) & mask_low::sig_bits_fast; |
| 309 | } |
| 310 | |
| 311 | /*! \brief Get the element vector in the cell |
| 312 | * |
| 313 | * \tparam i property to get |
| 314 | * |
| 315 | * \param part particle id |
| 316 | * \param ele element id |
| 317 | * |
| 318 | * \return The element value |
| 319 | * |
| 320 | */ |
| 321 | inline size_t getV(size_t part, size_t ele) const |
| 322 | { |
| 323 | return (VerletBase::get(part,ele)) >> (sizeof(size_t)*8-sh_byte); |
| 324 | } |
| 325 | |
| 326 | /*! \brief Get the Neighborhood iterator |
| 327 | * |
| 328 | * It iterate across all the neighborhood particles of a selected particle |
| 329 | * |
| 330 | * \param part_id particle id |
| 331 | * |
| 332 | * \return an interator across the neighborhood particles |
| 333 | * |
| 334 | */ |
| 335 | template<unsigned int impl=NO_CHECK> inline VerletNNIteratorM<dim,VerletListM<dim,T,sh_byte,CellListImpl,transform,vector_pos_type,VerletBase>,sh_byte> getNNIterator(size_t part_id) |
| 336 | { |
| 337 | VerletNNIteratorM<dim,VerletListM<dim,T,sh_byte,CellListImpl,transform,vector_pos_type,VerletBase>,sh_byte> vln(part_id,*this); |
| 338 | |
| 339 | return vln; |
| 340 | } |
| 341 | }; |
| 342 | |
| 343 | |
| 344 | #endif /* OPENFPM_DATA_SRC_NN_VERLETLIST_VERLETLISTM_HPP_ */ |
| 345 | |