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;