23 #ifndef FASTNEIGHBORLIST_HPP
24 #define FASTNEIGHBORLIST_HPP
60 inline double distance(
const double x1,
64 return std::sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
87 const unsigned int NX,
88 const unsigned int NY);
107 void reset(std::map<unsigned int,T> elementmap);
119 const double radius)
const;
133 const unsigned int avoidDomainID)
const;
147 const unsigned int avoidDomainID)
const;
161 unsigned int removeElementAtIndex(T element, listindex index);
168 unsigned int removeElementBruteForce(T element);
176 void appendContentOfCell(std::vector<T> &vec,
178 unsigned int i)
const;
187 void appendContentOfNeighboringCells(std::vector<T>& queryresult,
190 const double radius)
const;
198 inline listindex getIndex(
double posx,
204 void clearList(
void);
209 const double BinSizeX_;
214 const double BinSizeY_;
219 std::vector< std::vector< std::vector< T > > > list_;
229 const unsigned int NX,
230 const unsigned int NY) : BinSizeX_(double(LX)/double(NX)),
231 BinSizeY_(double(LY)/double(NY))
238 this->list_.resize(NY);
239 for (
auto &it : this->list_) {
247 listindex ind = this->getIndex(element->getXPos(), element->getYPos());
248 assert(ind.y < this->list_.size());
249 assert(ind.x < this->list_[0].size());
250 this->list_[ind.y][ind.x].push_back(element);
257 unsigned int count(0);
258 listindex ind = this->getIndex(element->getXPos(),element->getYPos());
262 count = this->removeElementAtIndex(element,ind);
263 assert( (count==0) || (count==1) );
264 if (count==1) {
return true;}
268 tempind.x = ind.x - 1;
270 count = this->removeElementAtIndex(element,tempind);
272 assert( (count==0) || (count==1) );
273 if (count==1) {
return true;}
276 if (ind.x < this->list_[0].size()-1) {
277 tempind.x = ind.x + 1;
279 count = this->removeElementAtIndex(element,tempind);
281 assert( (count==0) || (count==1) );
282 if (count==1) {
return true;}
287 tempind.y = ind.y - 1;
288 count = this->removeElementAtIndex(element,tempind);
290 assert( (count==0) || (count==1) );
291 if (count==1) {
return true;}
294 if (ind.y < this->list_.size() - 1) {
296 tempind.y = ind.y + 1;
297 count = this->removeElementAtIndex(element,tempind);
299 assert( (count==0) || (count==1) );
300 if (count==1) {
return true;}
304 tempind.x = ind.x - 1;
306 tempind.y = ind.y - 1;
307 count = this->removeElementAtIndex(element,tempind);
310 assert( (count==0) || (count==1) );
311 if (count==1) {
return true;}
314 if (ind.x < this->list_[0].size() - 1) {
315 tempind.x = ind.x + 1;
317 tempind.y = ind.y - 1;
318 count = this->removeElementAtIndex(element,tempind);
321 assert( (count==0) || (count==1) );
322 if (count==1) {
return true;}
326 tempind.x = ind.x - 1;
327 if (ind.y < this->list_.size() - 1) {
328 tempind.y = ind.y + 1;
329 count = this->removeElementAtIndex(element,tempind);
332 assert( (count==0) || (count==1) );
333 if (count==1) {
return true;}
336 if (ind.x < this->list_[0].size() - 1) {
337 tempind.x = ind.x + 1;
338 if (ind.y < this->list_.size() - 1) {
339 tempind.y = ind.y + 1;
340 count = this->removeElementAtIndex(element,tempind);
343 assert( (count==0) || (count==1) );
344 if (count==1) {
return true;}
347 unsigned int num = this->removeElementBruteForce(element);
348 assert( (num==0) || (num==1) );
354 unsigned int count(0);
357 this->list_[index.y][index.x].erase( std::remove_if( this->list_[index.y][index.x].begin(),
358 this->list_[index.y][index.x].end(),
359 [element,&count](T node){
360 if (node == element) {
366 this->list_[index.y][index.x].end()
372 unsigned int fastneighborlist<T>::removeElementBruteForce(T element)
374 unsigned int count(0);
376 const size_t sizeX = this->list_[0].size();
379 iy < this->list_.size();
386 count = this->removeElementAtIndex(element,ind);
389 assert( (count==0) || (count==1) );
398 for (
auto& it : elementmap) {
399 this->addElement(it.second);
407 const double radius)
const
410 this->appendContentOfNeighboringCells(queryresult, posx, posy, radius);
413 queryresult.erase( std::remove_if( queryresult.begin(),
415 [posx,posy,radius](T node){
416 if (distance(posx,posy,node->getXPos(),node->getYPos()) > radius) {
430 const unsigned int avoidDomainID)
const
432 this->getGeometryNodesWithinRadius(queryresult, posx, posy, radius);
435 queryresult.erase( std::remove_if( queryresult.begin(),
437 [avoidDomainID](T node) {
438 if (node->getDomainIdOfAdjacentConnections() == avoidDomainID) {
451 const unsigned int avoidDomainID)
const
453 this->getGeometryNodesWithinRadiusWithAvoidance(queryresult, posx, posy, radius, avoidDomainID);
456 if (queryresult.size() > 1) {
457 auto min_it = std::min_element( queryresult.begin(),
459 [posx,posy] (T node1, T node2) {
460 return distance(posx,posy,node1->getXPos(),node1->getYPos()) < distance(posx,posy,node2->getXPos(),node2->getYPos());
465 queryresult.push_back(*min_it);
472 for (
auto ity=0; ity<this->list_.size(); ++ity) {
473 for (
auto itx=0; itx<this->list_[0].size(); ++itx) {
474 std::cout <<
"[x=" << itx <<
", y=" << ity <<
"]" <<
"\t";
476 for (
auto it : this->list_[ity][itx]) {
477 std::cout <<
"(" << it->getXPos() <<
"," << it->getYPos() <<
")" <<
"\t";
488 unsigned int i)
const {
489 vec.insert(vec.end(), this->list_[j][i].begin(), this->list_[j][i].end());
493 void fastneighborlist<T>::appendContentOfNeighboringCells(std::vector<T>& queryresult,
496 const double radius)
const {
498 listindex minind = this->getIndex(posx-radius,posy-radius);
499 listindex maxind = this->getIndex(posx+radius,posy+radius);
501 for (
unsigned int j=minind.y; j<maxind.y+1; ++j) {
502 for (
unsigned int i=minind.x; i<maxind.x+1; ++i) {
503 this->appendContentOfCell(queryresult,j,i);
509 listindex fastneighborlist<T>::getIndex(
double posx,
513 if (posx < 0.0) posx = 0.0;
514 if (posy < 0.0) posy = 0.0;
515 ind.x = std::floor(posx/this->BinSizeX_);
516 ind.y = std::floor(posy/this->BinSizeY_);
517 if (ind.x >= this->list_[0].size()) ind.x = this->list_[0].size()-1;
518 if (ind.y >= this->list_.size()) ind.y = this->list_.size()-1;
523 void fastneighborlist<T>::clearList()
525 for (
auto& ity : this->list_) {
526 for (
auto& itx : ity) {
538 #endif // FASTNEIGHBORLIST_HPP
void addElement(T element)
addElement Adds an element into the fastneighborlist data structure.
fastneighborlist(const double LX, const double LY, const unsigned int NX, const unsigned int NY)
fastneighborlist Constructor
The fastneighborlist class is a class template putting objects of type T into a celllist data structu...
void getGeometryNodesWithinRadius(std::vector< T > &queryresult, const double posx, const double posy, const double radius) const
range query, returns all elements wich are within the radius.
void getGeometryNodesWithinRadiusWithAvoidanceClosest(std::vector< T > &queryresult, const double posx, const double posy, const double radius, const unsigned int avoidDomainID) const
return closest GeometryNode, but only nodes with domainID different from avoidDomainID ...
bool removeElement(T element)
removeElement Removes an element from the fastneighborlist data structure.
void reset(std::map< unsigned int, T > elementmap)
Completely rebuilds the fastneighborlist. T must expose getXPos(), getYPos()
void getGeometryNodesWithinRadiusWithAvoidance(std::vector< T > &queryresult, const double posx, const double posy, const double radius, const unsigned int avoidDomainID) const
range query, but only nodes with domainID different from avoidDomainID
void displayContent() const
displayContent Displays all the content in form [xindex,yindex]: (posx,posy) ...