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;
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
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());

Praetorius, Simon
committed
auto fakeDefaultGeometry = Dune::CGeo::Impl::DefaultLocalGeometry{};
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