https://mooseframework.inl.gov
NanoflannMeshAdaptor.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 // For MooseIndex
13 #include "MooseTypes.h"
14 
15 #include "libmesh/libmesh_config.h"
16 #include "libmesh/libmesh_common.h"
17 #include "libmesh/mesh_base.h"
18 #include "libmesh/point.h"
19 #include "libmesh/elem.h"
20 #ifdef LIBMESH_HAVE_NANOFLANN
21 #include "libmesh/nanoflann.hpp"
22 #else
23 SORRY THIS APPLICATION REQUIRES NANOFLANN
24 #endif
25 
26 // Using statements. These are used so that the code below does not
27 // need to be littered with libMesh:: disambiguations.
28 using libMesh::Point;
29 using libMesh::MeshBase;
30 using libMesh::Real;
33 using libMesh::Elem;
34 
40 template <unsigned int Dim>
42 {
43 private:
44  // Constant reference to the Mesh we are adapting for use in Nanoflann
45  const MeshBase & _mesh;
46 
47 public:
49 
53  typedef Real coord_t;
54 
58  inline size_t kdtree_get_point_count() const { return _mesh.n_nodes(); }
59 
64  inline coord_t kdtree_distance(const coord_t * p1, const size_t idx_p2, size_t size) const
65  {
66  libmesh_assert_equal_to(size, Dim);
67 
68  // Construct a libmesh Point object from the input coord_t. This
69  // assumes LIBMESH_DIM==3.
70  Point point1(p1[0], size > 1 ? p1[1] : 0., size > 2 ? p1[2] : 0.);
71 
72  // Get the referred-to point from the Mesh
73  const Point & point2 = _mesh.point(idx_p2);
74 
75  // Compute Euclidean distance, squared
76  return (point1 - point2).norm_sq();
77  }
78 
82  inline coord_t kdtree_get_pt(const size_t idx, int dim) const
83  {
84  libmesh_assert_less(dim, (int)Dim);
85  libmesh_assert_less(idx, _mesh.n_nodes());
86  libmesh_assert_less(dim, 3);
87 
88  return _mesh.point(idx)(dim);
89  }
90 
95  template <class BBOX>
96  bool kdtree_get_bbox(BBOX & /* bb */) const
97  {
98  return false;
99  }
100 };
101 
102 // Useful typedefs for working with NanoflannMeshAdaptors.
103 
104 // Declare a type templated on NanoflannMeshAdaptor
105 typedef nanoflann::L2_Simple_Adaptor<Real, NanoflannMeshAdaptor<3>> adatper_t;
106 
107 // Declare a KDTree type based on NanoflannMeshAdaptor
108 typedef nanoflann::KDTreeSingleIndexAdaptor<adatper_t, NanoflannMeshAdaptor<3>, 3> kd_tree_t;
109 
117 template <unsigned int Dim>
119 {
120 private:
121  // Constant reference to the Mesh we are adapting for use in Nanoflann
122  const MeshBase & _mesh;
123 
124  // This could be generalized to a std::set of subodmain ids.
126 
127  // Indices of points that are attached to elements in the requested subdomain.
128  std::set<dof_id_type> _legal_point_indices;
129 
130 public:
132  {
133  // Loop over the elements of the Mesh, for those in the requested
134  // subdomain, add its node ids to the _legal_point_indices set.
135  for (const auto & elem : _mesh.active_element_ptr_range())
136  if (elem->subdomain_id() == _sid)
137  for (MooseIndex(elem->n_vertices()) n = 0; n < elem->n_vertices(); ++n)
138  _legal_point_indices.insert(elem->node_id(n));
139  }
140 
144  typedef Real coord_t;
145 
149  inline size_t kdtree_get_point_count() const { return _mesh.n_nodes(); }
150 
155  inline coord_t kdtree_distance(const coord_t * p1, const size_t idx_p2, size_t size) const
156  {
157  libmesh_assert_equal_to(size, Dim);
158 
159  // If this is not a valid point, then return a "large" distance.
160  if (!_legal_point_indices.count(static_cast<dof_id_type>(idx_p2)))
162 
163  // Construct a libmesh Point object from the input coord_t. This
164  // assumes LIBMESH_DIM==3.
165  Point point1(p1[0], size > 1 ? p1[1] : 0., size > 2 ? p1[2] : 0.);
166 
167  // Get the referred-to point from the Mesh
168  const Point & point2 = _mesh.point(idx_p2);
169 
170  // Compute Euclidean distance, squared
171  return (point1 - point2).norm_sq();
172  }
173 
177  inline coord_t kdtree_get_pt(const size_t idx, int dim) const
178  {
179  libmesh_assert_less(dim, (int)Dim);
180  libmesh_assert_less(idx, _mesh.n_nodes());
181  libmesh_assert_less(dim, 3);
182 
183  // If this is not a valid point, then return a "large" distance.
184  if (!_legal_point_indices.count(static_cast<dof_id_type>(idx)))
186 
187  return _mesh.point(idx)(dim);
188  }
189 
194  template <class BBOX>
195  bool kdtree_get_bbox(BBOX & /* bb */) const
196  {
197  return false;
198  }
199 };
200 
201 // Useful typedefs for working with NanoflannMeshAdaptors.
202 
203 // Declare a type templated on NanoflannMeshAdaptor
204 typedef nanoflann::L2_Simple_Adaptor<Real, NanoflannMeshSubdomainAdaptor<3>> subdomain_adatper_t;
205 
206 // Declare a KDTree type based on NanoflannMeshAdaptor
207 typedef nanoflann::
208  KDTreeSingleIndexAdaptor<subdomain_adatper_t, NanoflannMeshSubdomainAdaptor<3>, 3>
nanoflann::L2_Simple_Adaptor< Real, NanoflannMeshAdaptor< 3 > > adatper_t
coord_t kdtree_get_pt(const size_t idx, int dim) const
Returns the dim&#39;th component of the idx&#39;th point in the class.
size_t kdtree_get_point_count() const
Must return the number of data points.
TestClass subdomain_id_type
MeshBase & mesh
NANOFLANN
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:153
Special adaptor that works with subdomains of the Mesh.
auto max(const L &left, const R &right)
nanoflann::KDTreeSingleIndexAdaptor< adatper_t, NanoflannMeshAdaptor< 3 >, 3 > kd_tree_t
auto norm_sq() const -> decltype(std::norm(Real()))
bool kdtree_get_bbox(BBOX &) const
Optional bounding-box computation: return false to default to a standard bbox computation loop...
NanoflannMeshSubdomainAdaptor(const MeshBase &mesh, subdomain_id_type s)
coord_t kdtree_distance(const coord_t *p1, const size_t idx_p2, size_t size) const
Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored ...
NanoflannMeshAdaptor(const MeshBase &mesh)
nanoflann::KDTreeSingleIndexAdaptor< subdomain_adatper_t, NanoflannMeshSubdomainAdaptor< 3 >, 3 > subdomain_kd_tree_t
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real coord_t
libMesh Point coordinate type
bool kdtree_get_bbox(BBOX &) const
Optional bounding-box computation: return false to default to a standard bbox computation loop...
This allows us to adapt the MeshBase class for use with nanoflann.
virtual const Point & point(const dof_id_type i) const=0
Real coord_t
libMesh Point coordinate type
nanoflann::L2_Simple_Adaptor< Real, NanoflannMeshSubdomainAdaptor< 3 > > subdomain_adatper_t
virtual dof_id_type n_nodes() const=0
coord_t kdtree_distance(const coord_t *p1, const size_t idx_p2, size_t size) const
Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored ...
size_t kdtree_get_point_count() const
Must return the number of data points.
coord_t kdtree_get_pt(const size_t idx, int dim) const
Returns the dim&#39;th component of the idx&#39;th point in the class.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
uint8_t dof_id_type
std::set< dof_id_type > _legal_point_indices