24 #include "libmesh/radial_basis_interpolation.h" 
   25 #include "libmesh/radial_basis_functions.h" 
   26 #include "libmesh/mesh_tools.h"  
   27 #include "libmesh/libmesh_logging.h" 
   28 #include "libmesh/eigen_core_support.h" 
   30 #ifdef LIBMESH_HAVE_EIGEN 
   31 # include "libmesh/ignore_warnings.h" 
   32 # include <Eigen/Dense> 
   33 # include "libmesh/restore_warnings.h" 
   41 template <
unsigned int KDDim, 
class RBF>
 
   50 template <
unsigned int KDDim, 
class RBF>
 
   57 #ifndef LIBMESH_HAVE_EIGEN 
   59   libmesh_error_msg(
"ERROR: this functionality presently requires Eigen!");
 
   62   LOG_SCOPE (
"prepare_for_use()", 
"RadialBasisInterpolation<>");
 
   65   _src_bbox.invalidate();
 
   67   const std::size_t  n_src_pts = this->_src_pts.size();
 
   68   const unsigned int n_vars    = this->n_field_variables();
 
   69   libmesh_assert_equal_to (this->_src_vals.size(), n_src_pts*this->n_field_variables());
 
   73       &p_min(_src_bbox.min()),
 
   74       &p_max(_src_bbox.max());
 
   76     for (std::size_t p=0; p<n_src_pts; p++)
 
   78         const Point & p_src(_src_pts[p]);
 
   80         for (
unsigned int d=0; d<LIBMESH_DIM; d++)
 
   82             p_min(d) = std::min(p_min(d), p_src(d));
 
   83             p_max(d) = std::max(p_max(d), p_src(d));
 
   89                << _src_bbox.min() << 
'\n' 
   90                << _src_bbox.max() << std::endl;
 
   95     _r_bbox = (_src_bbox.max() - _src_bbox.min()).
norm();
 
   97     _r_bbox = _r_override;
 
  102                << _src_bbox.min() << 
'\n' 
  103                << _src_bbox.max() << 
'\n' 
  104                << 
"r_bbox = " << _r_bbox << 
'\n' 
  105                << 
"rbf(r_bbox/2) = " << rbf(_r_bbox/2) << std::endl;
 
  109   typedef Eigen::Matrix<Number, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor> DynamicMatrix;
 
  112   DynamicMatrix 
A(n_src_pts, n_src_pts), x(n_src_pts,
n_vars), b(n_src_pts,
n_vars);
 
  114   for (std::size_t i=0; i<n_src_pts; i++)
 
  116       const Point & x_i (_src_pts[i]);
 
  121       for (std::size_t j=i+1; j<n_src_pts; j++)
 
  123           const Point & x_j (_src_pts[j]);
 
  125           const Real r_ij = (x_j - x_i).
norm();
 
  127           A(i,j) = 
A(j,i) = rbf(r_ij);
 
  131       for (
unsigned int var=0; var<
n_vars; var++)
 
  132         b(i,var) = _src_vals[i*
n_vars + var];
 
  137   x = 
A.ldlt().solve(b);
 
  141   _weights.resize (this->_src_vals.size());
 
  143   for (std::size_t i=0; i<n_src_pts; i++)
 
  144     for (
unsigned int var=0; var<
n_vars; var++)
 
  145       _weights[i*
n_vars + var] = x(i,var);
 
  153 template <
unsigned int KDDim, 
class RBF>
 
  155                                                                   const std::vector<Point> & tgt_pts,
 
  156                                                                   std::vector<Number> & tgt_vals)
 const 
  158   LOG_SCOPE (
"interpolate_field_data()", 
"RadialBasisInterpolation<>");
 
  160   libmesh_experimental();
 
  163     n_vars    = this->n_field_variables();
 
  166     n_src_pts = this->_src_pts.size(),
 
  167     n_tgt_pts = tgt_pts.size();
 
  169   libmesh_assert_equal_to (_weights.size(),    this->_src_vals.size());
 
  170   libmesh_assert_equal_to (field_names.size(), this->n_field_variables());
 
  174   if (this->_names.size() != field_names.size())
 
  175     libmesh_error_msg(
"ERROR:  when adding field data to an existing list the \nvariable list must be the same!");
 
  177   for (std::size_t v=0; v<this->_names.size(); v++)
 
  178     if (_names[v] != field_names[v])
 
  179       libmesh_error_msg(
"ERROR:  when adding field data to an existing list the \nvariable list must be the same!");
 
  184   tgt_vals.resize (n_tgt_pts*
n_vars);  std::fill (tgt_vals.begin(), tgt_vals.end(), 
Number(0.));
 
  186   for (std::size_t tgt=0; tgt<n_tgt_pts; tgt++)
 
  188       const Point & p (tgt_pts[tgt]);
 
  190       for (std::size_t i=0; i<n_src_pts; i++)
 
  192           const Point & x_i(_src_pts[i]);
 
  194             r_i   = (p - x_i).
norm(),
 
  197           for (
unsigned int var=0; var<
n_vars; var++)
 
  198             tgt_vals[tgt*
n_vars + var] += _weights[i*
n_vars + var]*phi_i;