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_INTERSECTION_HH
#define DUNE_CURVED_SURFACE_GRID_INTERSECTION_HH
{
// Intersection
// ------------
template< class Grid, class HostIntersection >
class Intersection
{
using HostGeometry = typename HostIntersection::Geometry;
using HostLocalGeometry = typename HostIntersection::LocalGeometry;
using Traits = typename std::remove_const_t<Grid>::Traits;
static const int dimension = Traits::dimension;
static const int dimensionworld = Traits::dimensionworld;
using Entity = typename Traits::template Codim<0>::Entity;
using Geometry = typename Traits::template Codim<1>::Geometry;
using LocalGeometry = typename Traits::template Codim<1>::LocalGeometry;
using ElementGeometry = typename Traits::template Codim<0>::Geometry;
using EntityImpl = typename Traits::template Codim<0>::EntityImpl;
using GeometryImpl = typename Traits::template Codim<1>::GeometryImpl;
using ElementGeometryImpl = typename Traits::template Codim<0>::GeometryImpl;
template <class HI>
Intersection (HI&& hostIntersection, const ElementGeometryImpl& insideGeo)
: hostIntersection_(std::forward<HI>(hostIntersection))
, insideGeo_ (insideGeo)
bool equals (const Intersection& other) const
{
return hostIntersection_ == other.hostIntersection_;
}
explicit operator bool () const { return bool(hostIntersection_); }
return EntityImpl(insideGeo_, hostIntersection().inside());
return EntityImpl(grid(), hostIntersection().outside());
}
bool boundary () const { return hostIntersection().boundary(); }
bool conforming () const { return hostIntersection().conforming(); }
bool neighbor () const { return hostIntersection().neighbor(); }
size_t boundarySegmentIndex () const
{
return hostIntersection().boundarySegmentIndex();
}
LocalGeometry geometryInInside () const
{
return hostIntersection().geometryInInside();
}
LocalGeometry geometryInOutside () const
{
return hostIntersection().geometryInOutside();
}
//! Construct a curved geometry for the intersection.
/**
* This does only work properly if the intersection is a full subEntity of inside and
* outside and the trace of the local basis functions along that subEntity is again
* a local basis function of codim=1
**/
auto ff = [f=grid().coordFunction(),geo=hostIntersection().geometry()](const auto& local) {
return f(geo.global(local));
};
}
GeometryType type () const { return hostIntersection().type(); }
int indexInInside () const
{
return hostIntersection().indexInInside();
}
int indexInOutside () const
{
return hostIntersection().indexInOutside();
}
FieldVector<ctype, dimensionworld> outerNormal (const FieldVector<ctype, dimension-1>& local) const
FieldVector<ctype, dimensionworld> integrationOuterNormal (const FieldVector<ctype, dimension-1>& local) const
FieldVector<ctype, dimensionworld> unitOuterNormal (const FieldVector<ctype, dimension-1>& local) const
FieldVector<ctype, dimensionworld> normal = outerNormal(local);
return normal /= normal.two_norm();
FieldVector<ctype, dimensionworld> centerUnitOuterNormal () const
auto refFace = referenceElement<ctype, dimension-1>(type());
return unitOuterNormal(refFace.position(0, 0));
const HostIntersection& hostIntersection () const
const Grid& grid () const { return insideGeo_.grid(); }
private:
FieldVector<ctype, dimensionworld>
outerNormalImpl (const FieldVector<ctype, dimension-1>& local, bool scaleByIntegrationElement) const
{
const LocalGeometry geoInInside = geometryInInside();
const int idxInInside = indexInInside();
auto refElement = referenceElement<ctype, dimension>(insideGeo_.type());
FieldVector<ctype, dimension> x(geoInInside.global(local));
const auto& jit = insideGeo_.jacobianInverseTransposed(x);
FieldVector<ctype, dimension> refNormal = refElement.integrationOuterNormal(idxInInside);
FieldVector<ctype, dimensionworld> normal;
jit.mv(refNormal, normal);
if (scaleByIntegrationElement) {
if (!conforming())
normal *= geoInInside.volume() / refElement.template geometry<1>(idxInInside).volume();
normal *= jit.detInv();
}
return normal;
}
private:
HostIntersection hostIntersection_;
ElementGeometryImpl insideGeo_;
mutable Std::optional<GeometryImpl> geo_;
#endif // DUNE_CURVED_SURFACE_GRID_INTERSECTION_HH