Skip to content
Snippets Groups Projects
entity.hh 11.7 KiB
Newer Older
Stenger, Florian's avatar
Stenger, Florian committed
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CURVED_SURFACE_GRID_ENTITY_HH
#define DUNE_CURVED_SURFACE_GRID_ENTITY_HH
Stenger, Florian's avatar
Stenger, Florian committed

#include <dune/common/std/optional.hh>
Stenger, Florian's avatar
Stenger, Florian committed
#include <dune/geometry/referenceelements.hh>

#include <dune/grid/common/grid.hh>
#include <dune/curvedsurfacegrid/geometry.hh>
Stenger, Florian's avatar
Stenger, Florian committed

namespace Dune
{
  namespace CGeo
Stenger, Florian's avatar
Stenger, Florian committed
  {

    // Internal Forward Declarations
    // -----------------------------

    /** \class EntityBase
     *  \brief actual implementation of the entity
     *  \ingroup CurvedGeo
Stenger, Florian's avatar
Stenger, Florian committed
     *
     *  \tparam  codim  codimension of the entity
     *  \tparam  Grid   CurvedSurfaceGrid, this entity belongs to
     */
    template< int codim, class Grid >
Stenger, Florian's avatar
Stenger, Florian committed
    class EntityBase;

    /** \class Entity
     *  \brief DUNE-conform implementation of the entity
     *  \ingroup CurvedGeo
Stenger, Florian's avatar
Stenger, Florian committed
     *
     *  This class merely changes the template parameters of the entity to make
     *  DUNE happy. The actual implementation of the entity can be found in
     *  EntityBase.
     *
     *  \tparam  codim  codimension of the entity
     *  \tparam  dim    dimension of the Grid (redundant information)
     *  \tparam  Grid   CurvedSurfaceGrid, this entity belongs to
     */
    template< int codim, int dim, class Grid >
    class Entity;



    // External Forward Declarations
    // -----------------------------

    template< class Grid >
    class HierarchicIterator;

    template< class Grid, class HostIntersectionIterator >
    class IntersectionIterator;


    class EntityBase
Stenger, Florian's avatar
Stenger, Florian committed
    {
      using Traits = typename std::remove_const_t<G>::Traits;
Stenger, Florian's avatar
Stenger, Florian committed

    public:
      /** \name Attributes
       *  \{ */

      //! codimensioon of the entity
      static const int codimension = codim;
      //! dimension of the grid
      static const int dimension = Traits::dimension;
      //! dimension of the entity
      static const int mydimension = dimension - codimension;
      //! dimension of the world
      static const int dimensionworld = Traits::dimensionworld;

      /** \} */

      /** \name Types Required by DUNE
       *  \{ */

      //! coordinate type of the grid
      using ctype = typename Traits::ctype;
Stenger, Florian's avatar
Stenger, Florian committed

      /** \} */

    public:
      /** \name Host Types
       *  \{ */

      //! type of corresponding entity seed
      using EntitySeed = typename Traits::template Codim<codimension>::EntitySeed;
Stenger, Florian's avatar
Stenger, Florian committed

      /** \} */
Stenger, Florian's avatar
Stenger, Florian committed

    public:
      using Grid = typename Traits::Grid;
      using GridFunction = typename Traits::GridFunction;

      //! type of the host grid
      using HostGrid = typename Traits::HostGrid;
Stenger, Florian's avatar
Stenger, Florian committed

      //! type of corresponding host entity
      using HostEntity = typename HostGrid::template Codim<codim>::Entity;

      //! type of host elements, i.e., of host entities of codimension 0
      using HostElement = typename HostGrid::template Codim<0>::Entity;

    public:
      EntityBase () = default;
Stenger, Florian's avatar
Stenger, Florian committed

      // Construct the entity from an entity seed
      EntityBase (const Grid& grid, const EntitySeed& seed)
        : hostEntity_(grid.hostGrid().entity(seed.impl().hostEntitySeed()))
        , gridFunction_(&grid.gridFunction())
Stenger, Florian's avatar
Stenger, Florian committed
      {}

      // construct the entity from a subentity of a host-entity
      EntityBase (const GridFunction& gridFunction, const HostElement& hostElement, int i)
        : hostEntity_(hostElement.template subEntity<codim>(i))
Stenger, Florian's avatar
Stenger, Florian committed
      {}

      // construct the entity from a host-entity
      EntityBase (const GridFunction& gridFunction, const HostEntity& hostEntity)
        : hostEntity_(hostEntity)
Stenger, Florian's avatar
Stenger, Florian committed
      {}

      // construct the entity from a host-entity
      EntityBase (const GridFunction& gridFunction, HostEntity&& hostEntity)
        : hostEntity_(std::move(hostEntity))
Stenger, Florian's avatar
Stenger, Florian committed
      {}

      //! compare two entities
      bool equals (const EntityBase& other) const
Stenger, Florian's avatar
Stenger, Florian committed
      {
        return hostEntity_ == other.hostEntity_;
      }

    public:
      /** \name Methods Shared by Entities of All Codimensions
       *  \{ */

      //! obtain the name of the corresponding reference element
      /**
Stenger, Florian's avatar
Stenger, Florian committed
       *  This type can be used to access the DUNE reference element.
       */
      GeometryType type () const
      {
        return hostEntity().type();
      }

      //! obtain the level of this entity
Stenger, Florian's avatar
Stenger, Florian committed
      int level () const
      {
        return hostEntity().level();
      }

      //! obtain the partition type of this entity
Stenger, Florian's avatar
Stenger, Florian committed
      PartitionType partitionType () const
      {
        return hostEntity().partitionType();
      }

      //! obtain number of sub-entities of the current entity
      unsigned int subEntities (unsigned int cc) const
Stenger, Florian's avatar
Stenger, Florian committed
      {
        return hostEntity().subEntities(cc);
Stenger, Florian's avatar
Stenger, Florian committed
      }

      //! return EntitySeed of host grid entity
      EntitySeed seed () const
Stenger, Florian's avatar
Stenger, Florian committed
      {
        return typename EntitySeed::Implementation(hostEntity().seed());
      /** \name Methods Supporting the Grid Implementation
Stenger, Florian's avatar
Stenger, Florian committed
       *  \{ */

      const GridFunction& gridFunction () const
Stenger, Florian's avatar
Stenger, Florian committed
      {
Stenger, Florian's avatar
Stenger, Florian committed
      }

      //! return the wrapped host-entity
      const HostEntity& hostEntity () const
Stenger, Florian's avatar
Stenger, Florian committed
      {
        return hostEntity_;
Stenger, Florian's avatar
Stenger, Florian committed
      }

      /** \} */
Stenger, Florian's avatar
Stenger, Florian committed

    private:
      HostEntity hostEntity_;
      const GridFunction* gridFunction_ = nullptr;
    };



    template< int codim, class G >
    class EntityBaseGeometry
        : public EntityBase<codim, G>
    {
      using Super = EntityBase<codim, G>;
      using Traits = typename std::remove_const_t<G>::Traits;

    public:
      //! type of corresponding geometry
      using Geometry = typename Traits::template Codim<codim>::Geometry;

    public:
      using Super::Super;

      //! obtain the geometry of this entity
      Geometry geometry () const
      {
        if (!geo_) {
          auto localFct = localFunction(Super::gridFunction());
          // localFct.bind(Super::hostEntity());

          // construct a fake local geometry for transformations.
          // auto refElem = referenceElement<typename Geometry::ctype, Super::dimension>(GeometryTypes::simplex(Super::dimension));
          geo_ = std::make_shared<GeometryImpl>(Super::type(), localFct);
        }

        return Geometry(*geo_);

        //return Super::hostEntity().geometry();
      }

    private:
      using GeometryImpl = typename Traits::template Codim<codim>::GeometryImpl;
      mutable std::shared_ptr<GeometryImpl> geo_;
    };


    template< class G >
    class EntityBaseGeometry<0, G>
        : public EntityBase<0, G>
    {
      using Super = EntityBase<0, G>;
      using Traits = typename std::remove_const_t<G>::Traits;

    public:
      //! type of corresponding geometry
      using Geometry = typename Traits::template Codim<0>::Geometry;

    public:
      using Super::Super;

      //! obtain the geometry of this entity
      /**
       *  Each DUNE entity encapsulates a geometry object, representing the map
       *  from the reference element to world coordinates. Wrapping the geometry
       *  is the main objective of the CurvedSurfaceGrid.
       *
       *  The CurvedSurfaceGrid provides geometries by parametrization with local basis
       *  functions, using the CurvedGeometry.
       *
       *  \returns a new curvedgeometry object
       */
      Geometry geometry () const
      {
        if (!geo_) {
          auto localFct = localFunction(Super::gridFunction());
          localFct.bind(Super::hostEntity());
          geo_ = std::make_shared<GeometryImpl>(Super::type(), localFct, Dune::CGeo::Impl::DefaultLocalGeometry{});
        }

        return Geometry(*geo_);
      }

    private:
      using GeometryImpl = typename Traits::template Codim<0>::GeometryImpl;
      mutable std::shared_ptr<GeometryImpl> geo_;
Stenger, Florian's avatar
Stenger, Florian committed
    };


    // Entity
    // ------

    template< int codim, int dim, class G >
Stenger, Florian's avatar
Stenger, Florian committed
    class Entity
        : public EntityBaseGeometry<codim, G>
Stenger, Florian's avatar
Stenger, Florian committed
    {
      using Super = EntityBaseGeometry<codim, G>;
Stenger, Florian's avatar
Stenger, Florian committed

    public:
      // import constructors from base class
      using Super::Super;
Stenger, Florian's avatar
Stenger, Florian committed
    };


    // Entity for codimension 0
    // ------------------------

    template< int dim, class G >
    class Entity<0, dim, G>
        : public EntityBaseGeometry<0, G>
Stenger, Florian's avatar
Stenger, Florian committed
    {
      using Super = EntityBaseGeometry<0, G>;
Stenger, Florian's avatar
Stenger, Florian committed

      using Traits = typename std::remove_const_t<G>::Traits;
      using Grid = typename Traits::Grid;
      using GridFunction = typename Grid::GridFunction;
      using HostGrid = typename Traits::HostGrid;
Stenger, Florian's avatar
Stenger, Florian committed

    public:

      /** \name Types Required by DUNE
       *  \{ */

      //! type of corresponding local geometry
      using LocalGeometry = typename Traits::template Codim<0>::LocalGeometry;
Stenger, Florian's avatar
Stenger, Florian committed

      //! facade type for entities
      using EntityFacade = Dune::Entity<0, dim, G, Dune::CGeo::Entity>;
Stenger, Florian's avatar
Stenger, Florian committed

      //! type of hierarchic iterator
      using HierarchicIterator = typename Traits::HierarchicIterator;

Stenger, Florian's avatar
Stenger, Florian committed
      //! type of leaf intersection iterator
      using LeafIntersectionIterator = typename Traits::LeafIntersectionIterator;

Stenger, Florian's avatar
Stenger, Florian committed
      //! type of level intersection iterator
      using LevelIntersectionIterator = typename Traits::LevelIntersectionIterator;
Stenger, Florian's avatar
Stenger, Florian committed

      /** \} */

      // import constructors from base class
      using Super::Super;
Stenger, Florian's avatar
Stenger, Florian committed

      template< int codim >
      typename Grid::template Codim<codim>::Entity subEntity (int i) const
Stenger, Florian's avatar
Stenger, Florian committed
      {
        using EntityImpl = typename Traits::template Codim<codim>::EntityImpl;
        return EntityImpl(Super::gridFunction(), Super::hostEntity(), i);
Stenger, Florian's avatar
Stenger, Florian committed
      }

      LevelIntersectionIterator ilevelbegin () const
      {
        using IteratorImpl = CGeo::IntersectionIterator<Grid, typename HostGrid::LevelIntersectionIterator>;
        return IteratorImpl(*this, Super::hostEntity().ilevelbegin());
Stenger, Florian's avatar
Stenger, Florian committed
      }

      LevelIntersectionIterator ilevelend () const
      {
        using IteratorImpl = CGeo::IntersectionIterator<Grid, typename HostGrid::LevelIntersectionIterator>;
        return IteratorImpl(*this, Super::hostEntity().ilevelend());
Stenger, Florian's avatar
Stenger, Florian committed
      }

      LeafIntersectionIterator ileafbegin () const
      {
        using IteratorImpl = CGeo::IntersectionIterator<Grid, typename HostGrid::LeafIntersectionIterator>;
        return IteratorImpl(*this, Super::hostEntity().ileafbegin());
Stenger, Florian's avatar
Stenger, Florian committed
      }

      LeafIntersectionIterator ileafend () const
      {
        using IteratorImpl = CGeo::IntersectionIterator<Grid, typename HostGrid::LeafIntersectionIterator>;
        return IteratorImpl(*this, Super::hostEntity().ileafend());
Stenger, Florian's avatar
Stenger, Florian committed
      }

      bool hasBoundaryIntersections () const
      {
        return Super::hostEntity().hasBoundaryIntersections();
Stenger, Florian's avatar
Stenger, Florian committed
      }

      bool isLeaf () const
      {
        return Super::hostEntity().isLeaf();
Stenger, Florian's avatar
Stenger, Florian committed
      }

      EntityFacade father () const
      {
        return Entity(Super::gridFunction(), Super::hostEntity().father());
Stenger, Florian's avatar
Stenger, Florian committed
      }

      bool hasFather () const
      {
        return Super::hostEntity().hasFather();
Stenger, Florian's avatar
Stenger, Florian committed
      }

      LocalGeometry geometryInFather () const
      {
        return Super::hostEntity().geometryInFather();
Stenger, Florian's avatar
Stenger, Florian committed
      }

      HierarchicIterator hbegin (int maxLevel) const
Stenger, Florian's avatar
Stenger, Florian committed
      {
        using IteratorImpl = CGeo::HierarchicIterator<G>;
        return IteratorImpl(Super::gridFunction(), Super::hostEntity().hbegin(maxLevel));
Stenger, Florian's avatar
Stenger, Florian committed
      }

      HierarchicIterator hend (int maxLevel) const
Stenger, Florian's avatar
Stenger, Florian committed
      {
        using IteratorImpl = CGeo::HierarchicIterator<G>;
        return IteratorImpl(Super::gridFunction(), Super::hostEntity().hend(maxLevel));
Stenger, Florian's avatar
Stenger, Florian committed
      }

      bool isRegular () const
      {
        return Super::hostEntity().isRegular();
Stenger, Florian's avatar
Stenger, Florian committed
      }

      bool isNew () const
      {
        return Super::hostEntity().isNew();
Stenger, Florian's avatar
Stenger, Florian committed
      }

      bool mightVanish () const
      {
        return Super::hostEntity().mightVanish();
Stenger, Florian's avatar
Stenger, Florian committed
      }
    };

  } // namespace CGeo
Stenger, Florian's avatar
Stenger, Florian committed
} // namespace Dune

#endif // DUNE_CURVED_SURFACE_GRID_ENTITY_HH