From 94d3e79a8617f88dc0219cfdeedfa3147833719d Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 24 Jun 2019 14:43:36 +0200 Subject: Initialize at openlb-1-3 --- .../contactDetection/nanoflann_adaptor.hpp | 127 +++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/particles/contactDetection/nanoflann_adaptor.hpp (limited to 'src/particles/contactDetection/nanoflann_adaptor.hpp') diff --git a/src/particles/contactDetection/nanoflann_adaptor.hpp b/src/particles/contactDetection/nanoflann_adaptor.hpp new file mode 100644 index 0000000..bded346 --- /dev/null +++ b/src/particles/contactDetection/nanoflann_adaptor.hpp @@ -0,0 +1,127 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2013 Thomas Henn, Mathias J. Krause + * E-mail contact: info@openlb.net + * The most recent release of OpenLB can be downloaded at + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef NanoflannParticleAdaptor_H_ +#define NanoflannParticleAdaptor_H_ + +#include "nanoflann.hpp" + +using namespace std; +using namespace nanoflann; + +namespace olb { + +template class PARTICLETYPE> +class ContactDetection; + +template class PARTICLETYPE> +class ParticleSystem3D; + +template +class NanoflannParticleAdaptor { + public: +// typedef typename T coord_t; + const Derived &obj; //!< A const ref to the data set origin + + /// The constructor that sets the data set source + NanoflannParticleAdaptor(const Derived &obj_) + : obj(obj_) { + } + + /// CRTP helper method + inline const Derived& derived() const { + return obj; + } + + // Must return the number of data points + inline size_t kdtree_get_point_count() const { + return derived().sizeInclShadow(); + } + + // Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class: + inline coord_t kdtree_distance(const coord_t *p1, const size_t idx_p2, + size_t size) const { + return std::pow(p1[0] - derived()[idx_p2].getPos()[0], 2) + + std::pow(p1[1] - derived()[idx_p2].getPos()[1], 2) + + std::pow(p1[2] - derived()[idx_p2].getPos()[2], 2); +// return (p1[0] - derived()[idx_p2].getPos()[0]) * (p1[0] - derived()[idx_p2].getPos()[0]) + +// (p1[1] - derived()[idx_p2].getPos()[1]) * (p1[1] - derived()[idx_p2].getPos()[1]) + +// (p1[2] - derived()[idx_p2].getPos()[2]) * (p1[2] - derived()[idx_p2].getPos()[2]); + } + + // Returns the dim'th component of the idx'th point in the class: + // Since this is inlined and the "dim" argument is typically an immediate value, the + // "if/else's" are actually solved at compile time. + inline coord_t kdtree_get_pt(const size_t idx, int dim) const { + return derived()[idx].getPos()[dim]; + } + + // Optional bounding-box computation: return false to default to a standard bbox computation loop. + // Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again. + // Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds) + template + bool kdtree_get_bbox(BBOX &bb) const { + return false; + } +}; + +template class PARTICLETYPE> +class NanoflannContact : public ContactDetection { + public: + + NanoflannContact(ParticleSystem3D& pSys, T sRad) : ContactDetection (pSys, "Nanoflann"), + _pc2kd(pSys), + _index(3,_pc2kd, KDTreeSingleIndexAdaptorParams(10) ), + _sRad2(sRad*sRad), + _sRad(sRad) + { + _index.init(); + _params.sorted = false; + } + virtual ContactDetection* generate(ParticleSystem3D& pSys) { + //std::cout << "calling NanoflannContact.generate()" << std::endl; + return new NanoflannContact(pSys,_sRad); + } + + void sort() { + _index.buildIndex(); + } + + int getMatches(int pInt, std::vector >& matches) { + _index.radiusSearch(&this->_pSys[pInt].getPos()[0], _sRad2, matches, _params); + return matches.size(); + } + + private: + typedef NanoflannParticleAdaptor > PC2KD; + const PC2KD _pc2kd; + typedef KDTreeSingleIndexAdaptor ,PC2KD, 3> kd_tree; + kd_tree _index; + nanoflann::SearchParams _params; + T _sRad2; + T _sRad; +}; + +} // namespace olb + +#endif -- cgit v1.2.3