19 #include "libmesh/libmesh_config.h" 22 #ifdef LIBMESH_HAVE_NANOFLANN 25 #include "libmesh/point_locator_nanoflann.h" 26 #include "libmesh/elem.h" 27 #include "libmesh/libmesh_logging.h" 28 #include "libmesh/mesh_base.h" 29 #include "libmesh/mesh_tools.h" 30 #include "libmesh/int_range.h" 43 _out_of_mesh_mode(false),
73 LOG_SCOPE(
"init()",
"PointLocatorNanoflann");
79 bool we_are_master = (
_master ==
nullptr);
85 _elems = std::make_shared<std::vector<const Elem *>>();
103 for (
const auto & elem :
_mesh.active_element_ptr_range())
110 _kd_tree = std::make_shared<kd_tree_t>
111 (LIBMESH_DIM, *
this, nanoflann::KDTreeSingleIndexAdaptorParams(10));
119 const auto my_master =
120 cast_ptr<const PointLocatorNanoflann *>(this->
_master);
123 _elems = my_master->_elems;
133 nanoflann::KNNResultSet<Real>
135 std::size_t num_results)
const 143 std::array<Real, LIBMESH_DIM> query_pt;
144 for (
int i=0; i<LIBMESH_DIM; ++i)
153 nanoflann::KNNResultSet<Real> result_set(num_results);
161 _kd_tree->findNeighbors(result_set, query_pt.data(), nanoflann::SearchParameters());
170 const std::set<subdomain_id_type> * allowed_subdomains)
const 174 LOG_SCOPE(
"operator()",
"PointLocatorNanoflann");
180 unsigned int n_elems_checked = 0;
183 const Elem * found_elem =
nullptr;
197 auto comp = [
this](std::size_t lhs, std::size_t rhs) ->
bool 208 auto elem_id_lhs = (*_elems)[nanoflann_index_lhs]->id();
211 auto elem_id_rhs = (*_elems)[nanoflann_index_rhs]->id();
213 if (elem_id_lhs < elem_id_rhs)
222 _b.resize(result_set.size());
224 std::sort(
_b.begin(),
_b.end(), comp);
236 const Elem * candidate_elem = (*_elems)[nanoflann_index];
248 if (allowed_subdomains && !allowed_subdomains->count(candidate_elem->
subdomain_id()))
274 found_elem = candidate_elem;
301 libmesh_error_msg(
"Point " << p <<
" was not contained within the closest " << n_elems_checked <<
302 " elems (by vertex average distance), and _out_of_mesh_mode was not enabled.");
311 std::set<const Elem *> & candidate_elements,
312 const std::set<subdomain_id_type> * allowed_subdomains)
const 316 LOG_SCOPE(
"operator() returning set",
"PointLocatorNanoflann");
319 candidate_elements.clear();
332 const Elem * candidate_elem = (*_elems)[nanoflann_index];
339 if (allowed_subdomains && !allowed_subdomains->count(candidate_elem->
subdomain_id()))
358 candidate_elements.insert(candidate_elem);
396 _num_results = std::max(static_cast<std::size_t>(1), val);
412 const std::size_t idx_p2,
413 std::size_t libmesh_dbg_var(size))
const 417 libmesh_assert_equal_to(size, LIBMESH_DIM);
422 for (
int i=0; i<LIBMESH_DIM; ++i)
435 libmesh_assert_less (
dim, LIBMESH_DIM);
nanoflann::KNNResultSet< Real > kd_tree_find_neighbors(const Point &p, std::size_t num_results) const
Helper function that wraps the call to the KDTree's findNeighbors() routine.
std::vector< std::size_t > _b
Vector of indices used by indirect sort.
coord_t kdtree_distance(const coord_t *p1, const std::size_t idx_p2, std::size_t size) const
Returns the squared distance between the vector (p1[0], p1[1], p1[2]) and the vertex average of Elem ...
bool _out_of_mesh_mode
true if out-of-mesh mode is enabled.
This is the base class from which all geometric element types are derived.
bool _initialized
true when properly initialized, false otherwise.
virtual void init() override final
Initializes the locator, so that the operator() methods can be used.
std::size_t get_num_results() const
Set/get the number of results returned by each Nanoflann findNeighbors() search.
virtual const Elem * operator()(const Point &p, const std::set< subdomain_id_type > *allowed_subdomains=nullptr) const override final
Locates the element in which the point with global coordinates p is located, optionally restricted to...
The libMesh namespace provides an interface to certain functionality in the library.
void iota(ForwardIter first, ForwardIter last, T value)
Utility::iota was created back when std::iota was just an SGI STL extension.
This is the MeshBase class.
std::size_t _num_results
The number of results returned by Nanoflann when operator() is called.
auto norm_sq() const -> decltype(std::norm(T()))
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
const MeshBase & _mesh
constant reference to the mesh in which the point is looked for.
std::vector< Real > _out_dist_sqr
Real coord_t
Floating point type used for storing coordinates.
virtual ~PointLocatorNanoflann()
Destructor.
This is the base class for point locators.
std::size_t kdtree_get_point_count() const
Must return the number of data points.
std::vector< std::size_t > _ret_index
The operator() functions on PointLocator-derived classes are const, so to avoid re-allocating these r...
virtual bool close_to_point(const Point &p, Real tol) const
PointLocatorNanoflann(const MeshBase &mesh, const PointLocatorBase *master=nullptr)
Constructor.
subdomain_id_type subdomain_id() const
std::shared_ptr< kd_tree_t > _kd_tree
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
const PointLocatorBase * _master
Const pointer to our master, initialized to nullptr if none given.
virtual void disable_out_of_mesh_mode() override final
Disables out-of-mesh mode (default).
coord_t kdtree_get_pt(const std::size_t idx, int dim) const
Returns the dim'th component of the idx'th vertex average.
std::shared_ptr< std::vector< const Elem * > > _elems
Lists of Points and ids which make up the "point cloud" that is to be searched via Nanoflann...
void set_num_results(std::size_t val)
std::shared_ptr< std::vector< Point > > _point_cloud
A Point defines a location in LIBMESH_DIM dimensional Real space.
bool _use_contains_point_tol
true if we will use a user-specified tolerance for locating the element.
virtual void enable_out_of_mesh_mode() override final
Enables out-of-mesh mode.
virtual void clear() override final
Restore to PointLocator to a just-constructed state.
Real _contains_point_tol
The tolerance to use when locating an element in the tree.