$extrastylesheet
meshfree_interpolation.h
Go to the documentation of this file.
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