21 #include "libmesh/meshfree_interpolation.h" 23 #include "libmesh/int_range.h" 24 #include "libmesh/libmesh_logging.h" 25 #include "libmesh/parallel.h" 26 #include "libmesh/parallel_algebra.h" 27 #include "libmesh/point.h" 40 os <<
"MeshfreeInterpolation" 41 <<
"\n n_source_points()=" <<
_src_pts.size()
47 os <<
" variables = ";
75 const std::vector<Point> & pts,
76 const std::vector<Number> & vals)
78 libmesh_experimental();
79 libmesh_assert_equal_to (field_names.size()*pts.size(), vals.size());
85 libmesh_error_msg_if(
_names.size() != field_names.size(),
86 "ERROR: when adding field data to an existing list the \nvariable list must be the same!");
89 libmesh_error_msg_if(
_names[v] != field_names[v],
90 "ERROR: when adding field data to an existing list the \nvariable list must be the same!");
106 libmesh_assert_equal_to (
_src_vals.size(),
133 #ifndef LIBMESH_HAVE_MPI 141 parallel_object_only();
143 LOG_SCOPE (
"gather_remote_data()",
"MeshfreeInterpolation");
148 #endif // LIBMESH_HAVE_MPI 155 template <
unsigned int KDDim>
158 #ifdef LIBMESH_HAVE_NANOFLANN 160 LOG_SCOPE (
"construct_kd_tree()",
"InverseDistanceInterpolation<>");
163 if (_kd_tree.get() ==
nullptr)
164 _kd_tree = std::make_unique<kd_tree_t>
167 nanoflann::KDTreeSingleIndexAdaptorParams(10 ));
171 _kd_tree->buildIndex();
177 template <
unsigned int KDDim>
180 #ifdef LIBMESH_HAVE_NANOFLANN 183 _kd_tree.reset (
nullptr);
192 template <
unsigned int KDDim>
194 const std::vector<Point> & tgt_pts,
195 std::vector<Number> & tgt_vals)
const 197 libmesh_experimental();
200 #ifdef LIBMESH_HAVE_NANOFLANN 201 if (_kd_tree.get() ==
nullptr)
205 LOG_SCOPE (
"interpolate_field_data()",
"InverseDistanceInterpolation<>");
207 libmesh_assert_equal_to (field_names.size(), this->n_field_variables());
211 libmesh_error_msg_if(_names.size() != field_names.size(),
212 "ERROR: when adding field data to an existing list the \nvariable list must be the same!");
215 libmesh_error_msg_if(_names[v] != field_names[v],
216 "ERROR: when adding field data to an existing list the \nvariable list must be the same!");
218 tgt_vals.resize (tgt_pts.size()*this->n_field_variables());
220 #ifdef LIBMESH_HAVE_NANOFLANN 222 std::vector<Number>::iterator out_it = tgt_vals.begin();
224 const size_t num_results = std::min((
size_t) _n_interp_pts, _src_pts.size());
226 std::vector<size_t> ret_index(num_results);
227 std::vector<Real> ret_dist_sqr(num_results);
229 for (
const auto & tgt : tgt_pts)
231 const Real query_pt[] = { tgt(0), tgt(1), tgt(2) };
233 _kd_tree->knnSearch(query_pt, num_results, ret_index.data(), ret_dist_sqr.data());
235 this->interpolate (tgt, ret_index, ret_dist_sqr, out_it);
251 libmesh_error_msg(
"ERROR: This functionality requires the library to be configured with nanoflann support!");
256 template <
unsigned int KDDim>
258 const std::vector<size_t> & src_indices,
259 const std::vector<Real> & src_dist_sqr,
260 std::vector<Number>::iterator & out_it)
const 265 if (!src_dist_sqr.empty())
267 Real min_dist = src_dist_sqr.front();
269 for (
auto i : src_dist_sqr)
271 libmesh_error_msg_if(i < min_dist, i <<
" was less than min_dist = " << min_dist);
279 libmesh_assert_equal_to (src_dist_sqr.size(), src_indices.size());
283 const unsigned int n_fv = this->n_field_variables();
286 std::fill (_vals.begin(), _vals.end(),
Number(0.));
291 if (_background_eff_dist > 0.0)
293 const Real background_wt = _background_eff_dist * _background_eff_dist > std::numeric_limits<Real>::epsilon()
294 ? 1.0 /
std::pow(_background_eff_dist * _background_eff_dist, _half_power)
296 tot_weight += background_wt;
297 std::fill (_vals.begin(), _vals.end(),
Number(_background_value * background_wt));
300 std::vector<Real>::const_iterator src_dist_sqr_it=src_dist_sqr.begin();
301 std::vector<size_t>::const_iterator src_idx_it=src_indices.begin();
304 while ((src_dist_sqr_it != src_dist_sqr.end()) &&
305 (src_idx_it != src_indices.end()))
307 libmesh_assert_greater_equal (*src_dist_sqr_it, 0.);
310 dist_sq = std::max(*src_dist_sqr_it, std::numeric_limits<Real>::epsilon()),
315 const std::size_t src_idx = *src_idx_it;
318 for (
unsigned int v=0; v<n_fv; v++)
320 libmesh_assert_less (src_idx*n_fv+v, _src_vals.size());
321 _vals[v] += _src_vals[src_idx*n_fv+v]*
weight;
329 for (
unsigned int v=0; v<n_fv; v++, ++out_it)
331 _vals[v] /= tot_weight;
unsigned int n_field_variables() const
The number of field variables.
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
Inverse distance interpolation.
std::ostream & operator<<(std::ostream &os, const OrderWrapper &order)
Overload stream operators.
const Parallel::Communicator & comm() const
The libMesh namespace provides an interface to certain functionality in the library.
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
Performs inverse distance interpolation at the input point from the specified points.
virtual void clear()
Clears all internal data structures and restores to a pristine state.
ParallelizationStrategy _parallelization_strategy
std::vector< Number > _src_vals
virtual void add_field_data(const std::vector< std::string > &field_names, const std::vector< Point > &pts, const std::vector< Number > &vals)
Sets source data at specified points.
std::vector< Point > _src_pts
void print_info(std::ostream &os=libMesh::out) const
Prints information about this object, by default to libMesh::out.
Base class to support various mesh-free interpolation methods.
virtual void construct_kd_tree()
Build & initialize the KD tree, if needed.
virtual void clear() override
Clears all internal data structures and restores to a pristine state.
virtual void gather_remote_data()
Gathers source points and values that have been added on other processors.
virtual void prepare_for_use()
Prepares data structures for use.
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
Interpolate source data at target points.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< std::string > _names
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
A Point defines a location in LIBMESH_DIM dimensional Real space.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...