dune-grid  2.1.1
hierarchicsearch.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GRID_HIERARCHICSEARCH_HH
00002 #define DUNE_GRID_HIERARCHICSEARCH_HH
00003 
00010 #include <dune/common/fvector.hh>
00011 #include <dune/grid/common/grid.hh>
00012 
00013 namespace Dune
00014 {
00015 
00019   template<class Grid, class IS>
00020   class HierarchicSearch
00021   {
00023         enum {dim=Grid::dimension};
00024 
00026         enum {dimw=Grid::dimensionworld};
00027 
00029         typedef typename Grid::ctype ct;
00030 
00032         typedef typename Grid::template Codim<0>::Entity Entity;
00033 
00035         typedef typename Grid::template Codim<0>::EntityPointer EntityPointer;
00036 
00038         typedef typename Grid::template Codim<0>::LevelIterator LevelIterator;
00039 
00041         typedef typename Grid::HierarchicIterator HierarchicIterator;
00042 
00053     EntityPointer hFindEntity ( const Entity &e,
00054                                 const FieldVector<ct,dimw>& global) const
00055       {
00056         // loop over all child Entities
00057         const HierarchicIterator end = e.hend(e.level()+1);
00058         for( HierarchicIterator it = e.hbegin( e.level()+1 ); it != end; ++it )
00059         {
00060           FieldVector<ct,dim> local = it->geometry().local(global);
00061           if (GenericReferenceElements<double, dim>::general(it->type()).checkInside(local))
00062           {
00063             // return if we found the leaf, else search through the child entites
00064             if( is.contains( *it ) )
00065               return EntityPointer( it );
00066             else
00067               return hFindEntity( *it, global );
00068           }
00069         }
00070         DUNE_THROW(Exception, "Unexpected internal Error");
00071       }
00072 
00073   public:
00077     HierarchicSearch(const Grid & _g, const IS & _is) : g(_g), is(_is) {};
00078 
00086     EntityPointer findEntity(const FieldVector<ct,dimw>& global) const
00087       {
00088         // loop over macro level
00089         LevelIterator it = g.template lbegin<0>(0);
00090         LevelIterator end = g.template lend<0>(0);
00091         for (; it != end; ++it)
00092         {
00093           const Entity &e = *it;
00094           const typename Entity::Geometry &geo = e.geometry();
00095 
00096           FieldVector< ct, dim > local = geo.local( global );
00097           if( !GenericReferenceElements< double, dim >::general( geo.type() ).checkInside( local ) )
00098             continue;
00099 
00100           if( (int(dim) != int(dimw)) && ((geo.global( local ) - global).two_norm() > 1e-8) )
00101             continue;
00102 
00103           // return if we found the leaf, else search through the child entites
00104           if( is.contains( *it ) )
00105             return EntityPointer( it );
00106           else
00107             return hFindEntity( *it, global );
00108         }
00109         DUNE_THROW( GridError, "Coordinate " << global << " is outside the grid." );
00110       }
00111     
00112   private:
00113     const Grid& g;
00114     const IS& is;
00115   };
00116   
00117 } // end namespace Dune
00118 
00119 #endif // DUNE_GRID_HIERARCHICSEARCH_HH
00120