OpenLB 1.7
Loading...
Searching...
No Matches
nanoflann_adaptor.hpp
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2013 Thomas Henn, Mathias J. Krause
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#ifndef NanoflannParticleAdaptor_H_
25#define NanoflannParticleAdaptor_H_
26
27#include "nanoflann.hpp"
28
29using namespace nanoflann;
30
31namespace olb {
32
33template<typename T, template<typename U> class PARTICLETYPE>
34class ContactDetection;
35
36template<typename T, template<typename U> class PARTICLETYPE>
37class ParticleSystem3D;
38
39template<typename coord_t, typename Derived>
41 public:
42// typedef typename T coord_t;
43 const Derived &obj;
44
46 NanoflannParticleAdaptor(const Derived &obj_)
47 : obj(obj_) {
48 }
49
51 inline const Derived& derived() const {
52 return obj;
53 }
54
55 // Must return the number of data points
56 inline size_t kdtree_get_point_count() const {
57 return derived().sizeInclShadow();
58 }
59
60 // Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
61 inline coord_t kdtree_distance(const coord_t *p1, const size_t idx_p2,
62 size_t size) const {
63 return std::pow(p1[0] - derived()[idx_p2].getPos()[0], 2) +
64 std::pow(p1[1] - derived()[idx_p2].getPos()[1], 2) +
65 std::pow(p1[2] - derived()[idx_p2].getPos()[2], 2);
66// return (p1[0] - derived()[idx_p2].getPos()[0]) * (p1[0] - derived()[idx_p2].getPos()[0]) +
67// (p1[1] - derived()[idx_p2].getPos()[1]) * (p1[1] - derived()[idx_p2].getPos()[1]) +
68// (p1[2] - derived()[idx_p2].getPos()[2]) * (p1[2] - derived()[idx_p2].getPos()[2]);
69 }
70
71 // Returns the dim'th component of the idx'th point in the class:
72 // Since this is inlined and the "dim" argument is typically an immediate value, the
73 // "if/else's" are actually solved at compile time.
74 inline coord_t kdtree_get_pt(const size_t idx, int dim) const {
75 return derived()[idx].getPos()[dim];
76 }
77
78 // Optional bounding-box computation: return false to default to a standard bbox computation loop.
79 // Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
80 // Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
81 template<class BBOX>
82 bool kdtree_get_bbox(BBOX &bb) const {
83 return false;
84 }
85};
86
87template<typename T, template<typename U> class PARTICLETYPE>
88class NanoflannContact : public ContactDetection<T, PARTICLETYPE> {
89 public:
90
91 NanoflannContact(ParticleSystem3D<T, PARTICLETYPE>& pSys, T sRad) : ContactDetection<T, PARTICLETYPE> (pSys, "Nanoflann"),
92 _pc2kd(pSys),
93 _index(3,_pc2kd, KDTreeSingleIndexAdaptorParams(10) ),
94 _sRad2(sRad*sRad),
95 _sRad(sRad)
96 {
97 _index.init();
98 _params.sorted = false;
99 }
101 //std::cout << "calling NanoflannContact.generate()" << std::endl;
102 return new NanoflannContact(pSys,_sRad);
103 }
104
105 void sort() override {
106 _index.buildIndex();
107 }
108
109 int getMatches(int pInt, std::vector<std::pair<size_t, T> >& matches) override {
110 _index.radiusSearch(&this->_pSys[pInt].getPos()[0], _sRad2, matches, _params);
111 return matches.size();
112 }
113
114 private:
116 const PC2KD _pc2kd;
118 kd_tree _index;
120 T _sRad2;
121 T _sRad;
122};
123
124} // namespace olb
125
126#endif
size_t radiusSearch(const ElementType *query_point, const DistanceType radius, std::vector< std::pair< IndexType, DistanceType > > &IndicesDists, const SearchParams &searchParams) const
Find all the neighbors to query_point[0:dim-1] within a maximum radius.
void buildIndex()
Builds the index.
ParticleSystem3D< T, PARTICLETYPE > & _pSys
int getMatches(int pInt, std::vector< std::pair< size_t, T > > &matches) override
ContactDetection< T, PARTICLETYPE > * generate(ParticleSystem3D< T, PARTICLETYPE > &pSys) override
NanoflannContact(ParticleSystem3D< T, PARTICLETYPE > &pSys, T sRad)
NanoflannParticleAdaptor(const Derived &obj_)
The constructor that sets the data set source.
const Derived & obj
A const ref to the data set origin.
const Derived & derived() const
CRTP helper method.
bool kdtree_get_bbox(BBOX &bb) const
coord_t kdtree_distance(const coord_t *p1, const size_t idx_p2, size_t size) const
coord_t kdtree_get_pt(const size_t idx, int dim) const
Top level namespace for all of OpenLB.
Parameters (see http://code.google.com/p/nanoflann/ for help choosing the parameters)
Search options for KDTreeSingleIndexAdaptor::findNeighbors()
bool sorted
only for radius search, require neighbours sorted by distance (default: true)