24 #include "libmesh/point.h" 
   25 #include "libmesh/meshfree_interpolation.h" 
   26 #include "libmesh/libmesh_logging.h" 
   27 #include "libmesh/parallel.h" 
   28 #include "libmesh/parallel_algebra.h" 
   29 #include "libmesh/auto_ptr.h"  
   38   os << 
"MeshfreeInterpolation" 
   39      << 
"\n n_source_points()=" << 
_src_pts.size()
 
   45       os << 
"  variables = ";
 
   73                                             const std::vector<Point> & pts,
 
   74                                             const std::vector<Number> & vals)
 
   76   libmesh_experimental();
 
   77   libmesh_assert_equal_to (field_names.size()*pts.size(), vals.size());
 
   83       if (
_names.size() != field_names.size())
 
   84         libmesh_error_msg(
"ERROR:  when adding field data to an existing list the \nvariable list must be the same!");
 
   86       for (std::size_t v=0; v<
_names.size(); v++)
 
   87         if (
_names[v] != field_names[v])
 
   88           libmesh_error_msg(
"ERROR:  when adding field data to an existing list the \nvariable list must be the same!");
 
  104   libmesh_assert_equal_to (
_src_vals.size(),
 
  131 #ifndef LIBMESH_HAVE_MPI 
  139   parallel_object_only();
 
  141   LOG_SCOPE (
"gather_remote_data()", 
"MeshfreeInterpolation");
 
  146 #endif // LIBMESH_HAVE_MPI 
  153 template <
unsigned int KDDim>
 
  156 #ifdef LIBMESH_HAVE_NANOFLANN 
  158   LOG_SCOPE (
"construct_kd_tree()", 
"InverseDistanceInterpolation<>");
 
  161   if (_kd_tree.get() == 
nullptr)
 
  162     _kd_tree = libmesh_make_unique<kd_tree_t>
 
  165        nanoflann::KDTreeSingleIndexAdaptorParams(10 ));
 
  169   _kd_tree->buildIndex();
 
  175 template <
unsigned int KDDim>
 
  178 #ifdef LIBMESH_HAVE_NANOFLANN 
  181     _kd_tree.reset (
nullptr);
 
  190 template <
unsigned int KDDim>
 
  192                                                                   const std::vector<Point> & tgt_pts,
 
  193                                                                   std::vector<Number> & tgt_vals)
 const 
  195   libmesh_experimental();
 
  198 #ifdef LIBMESH_HAVE_NANOFLANN 
  199   if (_kd_tree.get() == 
nullptr)
 
  203   LOG_SCOPE (
"interpolate_field_data()", 
"InverseDistanceInterpolation<>");
 
  205   libmesh_assert_equal_to (field_names.size(), this->n_field_variables());
 
  209   if (_names.size() != field_names.size())
 
  210     libmesh_error_msg(
"ERROR:  when adding field data to an existing list the \nvariable list must be the same!");
 
  212   for (std::size_t v=0; v<_names.size(); v++)
 
  213     if (_names[v] != field_names[v])
 
  214       libmesh_error_msg(
"ERROR:  when adding field data to an existing list the \nvariable list must be the same!");
 
  216   tgt_vals.resize (tgt_pts.size()*this->n_field_variables());
 
  218 #ifdef LIBMESH_HAVE_NANOFLANN 
  220     std::vector<Number>::iterator out_it = tgt_vals.begin();
 
  222     const size_t num_results = std::min((
size_t) _n_interp_pts, _src_pts.size());
 
  224     std::vector<size_t> ret_index(num_results);
 
  225     std::vector<Real>   ret_dist_sqr(num_results);
 
  227     for (
const auto & tgt : tgt_pts)
 
  229         const Real query_pt[] = { tgt(0), tgt(1), tgt(2) };
 
  231         _kd_tree->knnSearch(query_pt, num_results, ret_index.data(), ret_dist_sqr.data());
 
  233         this->interpolate (tgt, ret_index, ret_dist_sqr, out_it);
 
  249   libmesh_error_msg(
"ERROR: This functionality requires the library to be configured with nanoflann support!");
 
  254 template <
unsigned int KDDim>
 
  256                                                        const std::vector<size_t> & src_indices,
 
  257                                                        const std::vector<Real>   & src_dist_sqr,
 
  258                                                        std::vector<Number>::iterator & out_it)
 const 
  263   if (!src_dist_sqr.empty())
 
  265       Real min_dist = src_dist_sqr.front();
 
  267       for (
auto i : src_dist_sqr)
 
  270             libmesh_error_msg(i << 
" was less than min_dist = " << min_dist);
 
  278   libmesh_assert_equal_to (src_dist_sqr.size(), src_indices.size());
 
  282   const unsigned int n_fv = this->n_field_variables();
 
  283   _vals.resize(n_fv);  std::fill (_vals.begin(), _vals.end(), 
Number(0.));
 
  285   Real tot_weight = 0.;
 
  287   std::vector<Real>::const_iterator src_dist_sqr_it=src_dist_sqr.begin();
 
  288   std::vector<size_t>::const_iterator src_idx_it=src_indices.begin();
 
  291   while ((src_dist_sqr_it != src_dist_sqr.end()) &&
 
  292          (src_idx_it      != src_indices.end()))
 
  294       libmesh_assert_greater_equal (*src_dist_sqr_it, 0.);
 
  297         dist_sq = std::max(*src_dist_sqr_it, std::numeric_limits<Real>::epsilon()),
 
  302       const std::size_t src_idx = *src_idx_it;
 
  305       for (
unsigned int v=0; v<n_fv; v++)
 
  307           libmesh_assert_less (src_idx*n_fv+v, _src_vals.size());
 
  308           _vals[v] += _src_vals[src_idx*n_fv+v]*
weight;
 
  316   for (
unsigned int v=0; v<n_fv; v++, ++out_it)
 
  318       _vals[v] /= tot_weight;