$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 #ifndef LIBMESH_MESHFREE_INTERPOLATION_H 00021 #define LIBMESH_MESHFREE_INTERPOLATION_H 00022 00023 // Local includes 00024 #include "libmesh/libmesh_config.h" 00025 #include "libmesh/libmesh_common.h" 00026 #include "libmesh/auto_ptr.h" 00027 #include "libmesh/point.h" 00028 #include "libmesh/parallel_object.h" 00029 #ifdef LIBMESH_HAVE_NANOFLANN 00030 # include "libmesh/nanoflann.hpp" 00031 #endif 00032 00033 // C++ includes 00034 #include <string> 00035 #include <vector> 00036 00037 00038 00039 namespace libMesh 00040 { 00041 00051 class MeshfreeInterpolation : public ParallelObject 00052 { 00053 public: 00054 00067 enum ParallelizationStrategy { SYNC_SOURCES = 0, 00068 INVALID_STRATEGY}; 00072 MeshfreeInterpolation (const libMesh::Parallel::Communicator &comm_in 00073 LIBMESH_CAN_DEFAULT_TO_COMMWORLD) : 00074 ParallelObject(comm_in), 00075 _parallelization_strategy (SYNC_SOURCES) 00076 {} 00077 00082 void print_info (std::ostream& os=libMesh::out) const; 00083 00087 friend std::ostream& operator << (std::ostream& os, 00088 const MeshfreeInterpolation& mfi); 00089 00094 virtual void clear(); 00095 00099 unsigned int n_field_variables () const 00100 { return cast_int<unsigned int>(_names.size()); } 00101 00106 void set_field_variables (const std::vector<std::string> &names) 00107 { _names = names; } 00108 00112 const std::vector<std::string> & field_variables() const 00113 { return _names; } 00114 00118 std::vector<Point> & get_source_points () 00119 { return _src_pts; } 00120 00124 std::vector<Number> & get_source_vals () 00125 { return _src_vals; } 00126 00130 virtual void add_field_data (const std::vector<std::string> &field_names, 00131 const std::vector<Point> &pts, 00132 const std::vector<Number> &vals); 00133 00140 virtual void prepare_for_use (); 00141 00146 virtual void interpolate_field_data (const std::vector<std::string> &field_names, 00147 const std::vector<Point> &tgt_pts, 00148 std::vector<Number> &tgt_vals) const = 0; 00149 00150 protected: 00151 00160 virtual void gather_remote_data (); 00161 00162 ParallelizationStrategy _parallelization_strategy; 00163 std::vector<std::string> _names; 00164 std::vector<Point> _src_pts; 00165 std::vector<Number> _src_vals; 00166 }; 00167 00168 00169 00173 template <unsigned int KDDim> 00174 class InverseDistanceInterpolation : public MeshfreeInterpolation 00175 { 00176 protected: 00177 00178 #ifdef LIBMESH_HAVE_NANOFLANN 00179 00185 template <unsigned int PLDim> 00186 class PointListAdaptor 00187 { 00188 private: 00189 const std::vector<Point> &_pts; 00190 00191 public: 00192 PointListAdaptor (const std::vector<Point> &pts) : 00193 _pts(pts) 00194 {} 00195 00199 typedef Real coord_t; 00200 00204 inline size_t kdtree_get_point_count() const { return _pts.size(); } 00205 00210 inline coord_t kdtree_distance(const coord_t *p1, const size_t idx_p2, size_t size) const 00211 { 00212 libmesh_assert_equal_to (size, PLDim); 00213 libmesh_assert_less (idx_p2, _pts.size()); 00214 00215 const Point &p2(_pts[idx_p2]); 00216 00217 switch (size) 00218 { 00219 case 3: 00220 { 00221 const coord_t d0=p1[0] - p2(0); 00222 const coord_t d1=p1[1] - p2(1); 00223 const coord_t d2=p1[2] - p2(2); 00224 00225 return d0*d0 + d1*d1 + d2*d2; 00226 } 00227 00228 case 2: 00229 { 00230 const coord_t d0=p1[0] - p2(0); 00231 const coord_t d1=p1[1] - p2(1); 00232 00233 return d0*d0 + d1*d1; 00234 } 00235 00236 case 1: 00237 { 00238 const coord_t d0=p1[0] - p2(0); 00239 00240 return d0*d0; 00241 } 00242 00243 default: 00244 libmesh_error_msg("ERROR: unknown size " << size); 00245 } 00246 00247 return -1.; 00248 } 00249 00255 inline coord_t kdtree_get_pt(const size_t idx, int dim) const 00256 { 00257 libmesh_assert_less (dim, (int) PLDim); 00258 libmesh_assert_less (idx, _pts.size()); 00259 libmesh_assert_less (dim, 3); 00260 00261 const Point &p(_pts[idx]); 00262 00263 if (dim==0) return p(0); 00264 if (dim==1) return p(1); 00265 return p(2); 00266 } 00267 00274 template <class BBOX> 00275 bool kdtree_get_bbox(BBOX & /* bb */) const { return false; } 00276 }; 00277 00278 PointListAdaptor<KDDim> _point_list_adaptor; 00279 00280 // template <int KDDIM> 00281 // class KDTree : public KDTreeSingleIndexAdaptor<L2_Simple_Adaptor<num_t, PointListAdaptor >, 00282 // PointListAdaptor, 00283 // KDDIM> 00284 // { 00285 // }; 00286 00287 typedef nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<Real, PointListAdaptor<KDDim> >, 00288 PointListAdaptor<KDDim>, KDDim> kd_tree_t; 00289 00290 mutable UniquePtr<kd_tree_t> _kd_tree; 00291 00292 #endif // LIBMESH_HAVE_NANOFLANN 00293 00297 virtual void construct_kd_tree (); 00298 00303 virtual void interpolate (const Point &pt, 00304 const std::vector<size_t> &src_indices, 00305 const std::vector<Real> &src_dist_sqr, 00306 std::vector<Number>::iterator &out_it) const; 00307 00308 const Real _half_power; 00309 const unsigned int _n_interp_pts; 00310 00314 mutable std::vector<Number> _vals; 00315 00316 public: 00317 00322 InverseDistanceInterpolation (const libMesh::Parallel::Communicator &comm_in, 00323 const unsigned int n_interp_pts = 8, 00324 const Real power = 2) : 00325 MeshfreeInterpolation(comm_in), 00326 #if LIBMESH_HAVE_NANOFLANN 00327 _point_list_adaptor(_src_pts), 00328 #endif 00329 _half_power(power/2.0), 00330 _n_interp_pts(n_interp_pts) 00331 {} 00332 00337 virtual void clear(); 00338 00343 virtual void interpolate_field_data (const std::vector<std::string> &field_names, 00344 const std::vector<Point> &tgt_pts, 00345 std::vector<Number> &tgt_vals) const; 00346 00347 }; 00348 00349 } // namespace libMesh 00350 00351 00352 #endif // #define LIBMESH_MESHFREE_INTERPOLATION_H