From 7dad3d4f3dfb48659325fc53407cf38e27074eb0 Mon Sep 17 00:00:00 2001 From: Elias Pipping <elias.pipping@fu-berlin.de> Date: Tue, 14 Apr 2015 21:00:53 +0200 Subject: [PATCH] Add hierarchic search for a/the closest element --- dune/fufem/CMakeLists.txt | 1 + dune/fufem/hierarchic-approximation.hh | 124 +++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 dune/fufem/hierarchic-approximation.hh diff --git a/dune/fufem/CMakeLists.txt b/dune/fufem/CMakeLists.txt index b074c992..1b1f16f1 100644 --- a/dune/fufem/CMakeLists.txt +++ b/dune/fufem/CMakeLists.txt @@ -34,6 +34,7 @@ install(FILES facelocalfiniteelement.hh formatstring.hh globalintersectioniterator.hh + hierarchic-approximation.hh improvegrid.hh interval.hh lumpmatrix.hh diff --git a/dune/fufem/hierarchic-approximation.hh b/dune/fufem/hierarchic-approximation.hh new file mode 100644 index 00000000..daf61a39 --- /dev/null +++ b/dune/fufem/hierarchic-approximation.hh @@ -0,0 +1,124 @@ +#ifndef DUNE_FUFEM_HIERARCHIC_APPROXIMATION_HH +#define DUNE_FUFEM_HIERARCHIC_APPROXIMATION_HH + +// Based on +// dune/grid/utility/hierarchicsearch.hh + +/** + @file + @brief Utility class for hierarchically searching for the Entity + closest to a given point. + */ + +#include <cstddef> +#include <sstream> +#include <string> +#include <utility> + +#include <dune/common/classname.hh> +#include <dune/common/fvector.hh> + +#include <dune/grid/common/grid.hh> +#include <dune/grid/common/gridenums.hh> + +#include <dune/fufem/polyhedrondistance.hh> + +/** + @brief Search an IndexSet for the Entity closest to a given point. + */ +template <class Grid, class IS> class HierarchicApproximation { + //! get dimension from the grid + enum { dim = Grid::dimension }; + + //! get world dimension from the grid + enum { dimw = Grid::dimensionworld }; + + //! get coord type from the grid + typedef typename Grid::ctype ct; + + //! get entity from the grid + typedef typename Grid::template Codim<0>::Entity Entity; + + //! type of EntityPointer + typedef typename Grid::template Codim<0>::EntityPointer EntityPointer; + + //! type of HierarchicIterator + typedef typename Grid::HierarchicIterator HierarchicIterator; + + template <class Iterator> + Entity findBestEntity(Iterator first, Iterator last, + const Dune::FieldVector<ct, dimw> &global) const { + double minDistance = std::numeric_limits<double>::infinity(); + Entity ret; + + for (Iterator it = first; it != last; ++it) { + const Entity child = *it; + const double d = distance(global, child.geometry(), tolerance_); + if (d < minDistance) { + ret = child; + minDistance = d; + } + } + return ret; + } + + /** + internal helper method + + @param[in] entity Entity whos children should be searched + @param[in] global Point you are searching for + + Search the child entity closest to the point global. Recursively + continue until we found an entity that is part of + the IndexSet. + */ + Entity hFindEntity(const Entity &entity, + const Dune::FieldVector<ct, dimw> &global) const { + const int childLevel = entity.level() + 1; + Entity const best = findBestEntity(entity.hbegin(childLevel), + entity.hend(childLevel), global); + if (indexSet_.contains(best)) + return best; + else + return hFindEntity(best, global); + } + +public: + /** + @brief Construct a HierarchicApproximation object from a Grid, an IndexSet, + and an approximation tolerance + */ + HierarchicApproximation(const Grid &g, const IS &is, double tolerance) + : grid_(g), indexSet_(is), tolerance_(tolerance) {} + + /** + @brief Search the IndexSet of this HierarchicSearch for the Entity + closest to the point global. + */ + Entity findEntity(const Dune::FieldVector<ct, dimw> &global) const { + return findEntity<Dune::All_Partition>(global); + } + + /** + @brief Search the IndexSet of this HierarchicSearch for the Entity + closest to the point global. + */ + template <Dune::PartitionIteratorType partition> + Entity findEntity(const Dune::FieldVector<ct, dimw> &global) const { + typedef typename Grid::LevelGridView LevelGV; + const LevelGV &gv = grid_.template levelGridView(0); + + Entity const best = findBestEntity(gv.template begin<0, partition>(), + gv.template end<0, partition>(), global); + if (indexSet_.contains(best)) + return best; + else + return hFindEntity(best, global); + } + +private: + const Grid &grid_; + const IS &indexSet_; + const double tolerance_; +}; +#endif -- GitLab