meshfree_interpolation.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_MESHFREE_INTERPOLATION_H
21 #define LIBMESH_MESHFREE_INTERPOLATION_H
22 
23 // Local includes
24 #include "libmesh/libmesh_config.h"
25 #include "libmesh/libmesh_common.h"
26 #include "libmesh/auto_ptr.h" // deprecated
27 #include "libmesh/point.h"
29 #ifdef LIBMESH_HAVE_NANOFLANN
30 # include "libmesh/ignore_warnings.h"
31 # include "libmesh/nanoflann.hpp"
33 #endif
34 
35 // C++ includes
36 #include <string>
37 #include <vector>
38 #include <memory>
39 
40 
41 namespace libMesh
42 {
43 
58 {
59 public:
60 
79  ParallelObject(comm_in),
81  {}
82 
87  void print_info (std::ostream & os=libMesh::out) const;
88 
92  friend std::ostream & operator << (std::ostream & os,
93  const MeshfreeInterpolation & mfi);
94 
99  virtual void clear();
100 
104  unsigned int n_field_variables () const
105  { return cast_int<unsigned int>(_names.size()); }
106 
111  void set_field_variables (const std::vector<std::string> & names)
112  { _names = names; }
113 
117  const std::vector<std::string> & field_variables() const
118  { return _names; }
119 
123  std::vector<Point> & get_source_points ()
124  { return _src_pts; }
125 
129  std::vector<Number> & get_source_vals ()
130  { return _src_vals; }
131 
135  virtual void add_field_data (const std::vector<std::string> & field_names,
136  const std::vector<Point> & pts,
137  const std::vector<Number> & vals);
138 
145  virtual void prepare_for_use ();
146 
151  virtual void interpolate_field_data (const std::vector<std::string> & field_names,
152  const std::vector<Point> & tgt_pts,
153  std::vector<Number> & tgt_vals) const = 0;
154 
155 protected:
156 
166  virtual void gather_remote_data ();
167 
169  std::vector<std::string> _names;
170  std::vector<Point> _src_pts;
171  std::vector<Number> _src_vals;
172 };
173 
174 
175 
179 template <unsigned int KDDim>
181 {
182 protected:
183 
184 #ifdef LIBMESH_HAVE_NANOFLANN
185 
191  template <unsigned int PLDim>
193  {
194  private:
195  const std::vector<Point> & _pts;
196 
197  public:
198  PointListAdaptor (const std::vector<Point> & pts) :
199  _pts(pts)
200  {}
201 
205  typedef Real coord_t;
206 
210  inline size_t kdtree_get_point_count() const { return _pts.size(); }
211 
216  inline coord_t kdtree_distance(const coord_t * p1, const size_t idx_p2, size_t size) const
217  {
218  libmesh_assert_equal_to (size, PLDim);
219  libmesh_assert_less (idx_p2, _pts.size());
220 
221  const Point & p2(_pts[idx_p2]);
222 
223  switch (size)
224  {
225  case 3:
226  {
227  const coord_t d0=p1[0] - p2(0);
228  const coord_t d1=p1[1] - p2(1);
229  const coord_t d2=p1[2] - p2(2);
230 
231  return d0*d0 + d1*d1 + d2*d2;
232  }
233 
234  case 2:
235  {
236  const coord_t d0=p1[0] - p2(0);
237  const coord_t d1=p1[1] - p2(1);
238 
239  return d0*d0 + d1*d1;
240  }
241 
242  case 1:
243  {
244  const coord_t d0=p1[0] - p2(0);
245 
246  return d0*d0;
247  }
248 
249  default:
250  libmesh_error_msg("ERROR: unknown size " << size);
251  }
252 
253  return -1.;
254  }
255 
261  inline coord_t kdtree_get_pt(const size_t idx, int dim) const
262  {
263  libmesh_assert_less (dim, (int) PLDim);
264  libmesh_assert_less (idx, _pts.size());
265  libmesh_assert_less (dim, 3);
266 
267  const Point & p(_pts[idx]);
268 
269  if (dim==0) return p(0);
270  if (dim==1) return p(1);
271  return p(2);
272  }
273 
284  template <class BBOX>
285  bool kdtree_get_bbox(BBOX & /* bb */) const { return false; }
286  };
287 
289 
290  // template <int KDDIM>
291  // class KDTree : public KDTreeSingleIndexAdaptor<L2_Simple_Adaptor<num_t, PointListAdaptor >,
292  // PointListAdaptor,
293  // KDDIM>
294  // {
295  // };
296 
297  typedef nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<Real, PointListAdaptor<KDDim>>,
299 
300  mutable std::unique_ptr<kd_tree_t> _kd_tree;
301 
302 #endif // LIBMESH_HAVE_NANOFLANN
303 
307  virtual void construct_kd_tree ();
308 
313  virtual void interpolate (const Point & pt,
314  const std::vector<size_t> & src_indices,
315  const std::vector<Real> & src_dist_sqr,
316  std::vector<Number>::iterator & out_it) const;
317 
319  const unsigned int _n_interp_pts;
320 
324  mutable std::vector<Number> _vals;
325 
326 public:
327 
333  const unsigned int n_interp_pts = 8,
334  const Real power = 2) :
335  MeshfreeInterpolation(comm_in),
336 #if LIBMESH_HAVE_NANOFLANN
338 #endif
339  _half_power(power/2.0),
340  _n_interp_pts(n_interp_pts)
341  {}
342 
347  virtual void clear() override;
348 
353  virtual void interpolate_field_data (const std::vector<std::string> & field_names,
354  const std::vector<Point> & tgt_pts,
355  std::vector<Number> & tgt_vals) const override;
356 };
357 
358 } // namespace libMesh
359 
360 
361 #endif // #define LIBMESH_MESHFREE_INTERPOLATION_H
const std::vector< std::string > & field_variables() const
virtual void interpolate(const Point &pt, const std::vector< size_t > &src_indices, const std::vector< Real > &src_dist_sqr, std::vector< Number >::iterator &out_it) const
virtual void add_field_data(const std::vector< std::string > &field_names, const std::vector< Point > &pts, const std::vector< Number > &vals)
if(!eq) SETERRQ2(((PetscObject) dm) -> comm, PETSC_ERR_ARG_WRONG, "DM of type %s, not of type %s",((PetscObject) dm) ->type, DMLIBMESH)
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
std::vector< Point > & get_source_points()
virtual void interpolate_field_data(const std::vector< std::string > &field_names, const std::vector< Point > &tgt_pts, std::vector< Number > &tgt_vals) const =0
virtual void interpolate_field_data(const std::vector< std::string > &field_names, const std::vector< Point > &tgt_pts, std::vector< Number > &tgt_vals) const override
ParallelizationStrategy _parallelization_strategy
void print_info(std::ostream &os=libMesh::out) const
Base class which defines the mesh-free interpolation interface.
friend std::ostream & operator<<(std::ostream &os, const MeshfreeInterpolation &mfi)
std::vector< Number > & get_source_vals()
An object whose state is distributed along a set of processors.
InverseDistanceInterpolation(const libMesh::Parallel::Communicator &comm_in, const unsigned int n_interp_pts=8, const Real power=2)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
nanoflann::KDTreeSingleIndexAdaptor< nanoflann::L2_Simple_Adaptor< Real, PointListAdaptor< KDDim > >, PointListAdaptor< KDDim >, KDDim > kd_tree_t
void set_field_variables(const std::vector< std::string > &names)
std::vector< std::string > _names
MeshfreeInterpolation(const libMesh::Parallel::Communicator &comm_in)
OStreamProxy out(std::cout)
A geometric point in (x,y,z) space.
Definition: point.h:38
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)