Newer
Older
// -*- 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
#include <dune/common/std/optional.hh>
#include <dune/geometry/referenceelements.hh>
#include <dune/grid/common/grid.hh>
#include <dune/curvedsurfacegrid/geometry.hh>
{
// Internal Forward Declarations
// -----------------------------
/** \class EntityBase
* \brief actual implementation of the entity
*
* \tparam codim codimension of the entity
* \tparam Grid CurvedSurfaceGrid, this entity belongs to
*/
class EntityBase;
/** \class Entity
* \brief DUNE-conform implementation of the entity
*
* 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;
template< int codim, class G >
using Traits = typename std::remove_const_t<G>::Traits;
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
/** \} */
public:
/** \name Host Types
* \{ */
//! type of corresponding entity seed
using EntitySeed = typename Traits::template Codim<codimension>::EntitySeed;
using Grid = typename Traits::Grid;
using GridFunction = typename Traits::GridFunction;
//! type of the host grid
using HostGrid = typename Traits::HostGrid;
//! 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:
// Construct the entity from an entity seed
EntityBase (const Grid& grid, const EntitySeed& seed)
: hostEntity_(grid.hostGrid().entity(seed.impl().hostEntitySeed()))
, gridFunction_(&grid.gridFunction())
// 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))
, gridFunction_(&gridFunction)
// construct the entity from a host-entity
EntityBase (const GridFunction& gridFunction, const HostEntity& hostEntity)
, gridFunction_(&gridFunction)
// construct the entity from a host-entity
EntityBase (const GridFunction& gridFunction, HostEntity&& hostEntity)
, gridFunction_(&gridFunction)
//! compare two entities
bool equals (const EntityBase& other) const
{
return hostEntity_ == other.hostEntity_;
}
public:
/** \name Methods Shared by Entities of All Codimensions
* \{ */
//! obtain the name of the corresponding reference element
/**
* This type can be used to access the DUNE reference element.
*/
GeometryType type () const
{
return hostEntity().type();
}
int level () const
{
return hostEntity().level();
}
//! obtain the partition type of this entity
PartitionType partitionType () const
{
return hostEntity().partitionType();
}
//! obtain number of sub-entities of the current entity
unsigned int subEntities (unsigned int cc) const
//! return EntitySeed of host grid entity
EntitySeed seed () const
return typename EntitySeed::Implementation(hostEntity().seed());
/** \name Methods Supporting the Grid Implementation
const GridFunction& gridFunction () const
return *gridFunction_;
//! return the wrapped host-entity
const HostEntity& hostEntity () const
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;

Praetorius, Simon
committed
//! type of host elements, i.e., of host entities of codimension 0
using HostElement = typename Traits::HostGrid::template Codim<0>::Entity;
using GridFunction = typename Super::GridFunction;
public:
//! type of corresponding geometry
using Geometry = typename Traits::template Codim<codim>::Geometry;

Praetorius, Simon
committed
using ctype = typename Geometry::ctype;
public:
using Super::Super;

Praetorius, Simon
committed
// construct the entity from a subentity of a host-entity
EntityBaseGeometry (const GridFunction& gridFunction, const HostElement& hostElement, int i)
: Super(gridFunction, hostElement, i)
, hostElement_(hostElement)
, subEntity_(i)
{}
//! obtain the geometry of this entity
Geometry geometry () const
{
if (!geo_) {
auto localFct = localFunction(Super::gridFunction());

Praetorius, Simon
committed
if (hostElement_) {
localFct.bind(*hostElement_);
auto refElem = referenceElement<ctype, Super::dimension>(hostElement_->type());
auto localGeometry = refElem.template geometry<codim>(subEntity_);
geo_ = std::make_shared<GeometryImpl>(Super::type(), localFct, localGeometry);
}
else {
DUNE_THROW(Dune::NotImplemented, "Geometry of entities of codim!=0 not implemented");
}
}
return Geometry(*geo_);
}
private:

Praetorius, Simon
committed
Std::optional<HostElement> hostElement_;
int subEntity_ = -1;
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;
//! type of corresponding local geometry
using LocalGeometry = typename Traits::template Codim<0>::LocalGeometry;
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());
auto fakeDefaultGeometry = Dune::DefaultLocalGeometry<typename Super::ctype, Super::mydimension, Super::mydimension>{};

Praetorius, Simon
committed
geo_ = std::make_shared<GeometryImpl>(Super::type(), localFct, fakeDefaultGeometry);
}
return Geometry(*geo_);
}
private:
using GeometryImpl = typename Traits::template Codim<0>::GeometryImpl;
mutable std::shared_ptr<GeometryImpl> geo_;
template< int codim, int dim, class G >
: public EntityBaseGeometry<codim, G>
using Super = EntityBaseGeometry<codim, G>;
// import constructors from base class
using Super::Super;
};
// Entity for codimension 0
// ------------------------
template< int dim, class G >
class Entity<0, dim, G>
: public EntityBaseGeometry<0, G>
using Super = EntityBaseGeometry<0, G>;
using Traits = typename std::remove_const_t<G>::Traits;
using Grid = typename Traits::Grid;
using GridFunction = typename Grid::GridFunction;
using HostGrid = typename Traits::HostGrid;
public:
/** \name Types Required by DUNE
* \{ */
//! type of corresponding local geometry
using LocalGeometry = typename Traits::template Codim<0>::LocalGeometry;
using EntityFacade = Dune::Entity<0, dim, G, Dune::CGeo::Entity>;
using HierarchicIterator = typename Traits::HierarchicIterator;
using LeafIntersectionIterator = typename Traits::LeafIntersectionIterator;
using LevelIntersectionIterator = typename Traits::LevelIntersectionIterator;
// import constructors from base class
using Super::Super;
typename Grid::template Codim<codim>::Entity subEntity (int i) const
using EntityImpl = typename Traits::template Codim<codim>::EntityImpl;
return EntityImpl(Super::gridFunction(), Super::hostEntity(), i);
}
LevelIntersectionIterator ilevelbegin () const
{
using IteratorImpl = CGeo::IntersectionIterator<Grid, typename HostGrid::LevelIntersectionIterator>;
return IteratorImpl(*this, Super::hostEntity().ilevelbegin());
using IteratorImpl = CGeo::IntersectionIterator<Grid, typename HostGrid::LevelIntersectionIterator>;
return IteratorImpl(*this, Super::hostEntity().ilevelend());
using IteratorImpl = CGeo::IntersectionIterator<Grid, typename HostGrid::LeafIntersectionIterator>;
return IteratorImpl(*this, Super::hostEntity().ileafbegin());
using IteratorImpl = CGeo::IntersectionIterator<Grid, typename HostGrid::LeafIntersectionIterator>;
return IteratorImpl(*this, Super::hostEntity().ileafend());
return Super::hostEntity().hasBoundaryIntersections();
return Entity(Super::gridFunction(), Super::hostEntity().father());
return Super::hostEntity().geometryInFather();
HierarchicIterator hbegin (int maxLevel) const
using IteratorImpl = CGeo::HierarchicIterator<G>;
return IteratorImpl(Super::gridFunction(), Super::hostEntity().hbegin(maxLevel));
HierarchicIterator hend (int maxLevel) const
using IteratorImpl = CGeo::HierarchicIterator<G>;
return IteratorImpl(Super::gridFunction(), Super::hostEntity().hend(maxLevel));
#endif // DUNE_CURVED_SURFACE_GRID_ENTITY_HH