1#ifndef DUNE_MULTIDOMAINGRID_SUBDOMAINGRID_INTERSECTION_HH 
    2#define DUNE_MULTIDOMAINGRID_SUBDOMAINGRID_INTERSECTION_HH 
    4#include <dune/grid/common/intersection.hh> 
   12template<
int codim, 
int dim, 
typename Gr
idImp>
 
   15template<
typename GridImp,
 
   17         typename MultiDomainIntersection_
 
   19class IntersectionWrapper {
 
   21  template<
class, 
class, 
class>
 
   22  friend class Dune::IntersectionIterator;
 
   24  template<
class,
class,
class>
 
   25  friend class IntersectionIteratorWrapper;
 
   27  template<
class, 
class>
 
   28  friend class Dune::Intersection;
 
   30  template<
typename MDGr
id>
 
   31  friend class SubDomainGrid;
 
   33  using MultiDomainIntersection = MultiDomainIntersection_;
 
   34  using Entity                  = 
typename GridImp::Traits::template Codim<0>::Entity;
 
   35  using Geometry                = 
typename GridImp::Traits::template Codim<1>::Geometry;
 
   36  using LocalGeometry           = 
typename GridImp::Traits::template Codim<1>::LocalGeometry;
 
   37  using EntityWrapper           = Dune::mdgrid::subdomain::EntityWrapper<0,GridImp::dimension,GridImp>;
 
   39  static const int dimension = GridImp::dimension;
 
   40  static const int dimensionworld = GridImp::dimensionworld;
 
   42  using ctype            = 
typename GridImp::ctype;
 
   43  using GlobalCoords     = FieldVector<ctype,dimensionworld>;
 
   44  using LocalCoords      = FieldVector<ctype,dimension - 1>;
 
   48    , _intersectionTypeTested(false)
 
   51  IntersectionWrapper(
const IndexSet* indexSet, 
const MultiDomainIntersection& multiDomainIntersection)
 
   53    , _multiDomainIntersection(multiDomainIntersection)
 
   54    , _intersectionTypeTested(false)
 
   60  hostIntersection()
 const {
 
   61    return _multiDomainIntersection.impl().hostIntersection();
 
   65  bool equals(
const IntersectionWrapper& rhs)
 const {
 
   66    return _indexSet == rhs._indexSet && _multiDomainIntersection == rhs._multiDomainIntersection;
 
   69  void checkIntersectionType()
 const {
 
   70    if (!_intersectionTypeTested) {
 
   71      if (_multiDomainIntersection.boundary()) {
 
   72        _intersectionType = GridImp::boundary;
 
   73        _intersectionTypeTested = 
true;
 
   76      if (!_multiDomainIntersection.neighbor()) {
 
   77        _intersectionType = GridImp::processor;
 
   78        _intersectionTypeTested = 
true;
 
   81      if (_indexSet->containsMultiDomainEntity(_multiDomainIntersection.outside())) {
 
   82        _intersectionType = GridImp::neighbor;
 
   83        _intersectionTypeTested = 
true;
 
   86        _intersectionType = GridImp::foreign;
 
   87        _intersectionTypeTested = 
true;
 
   90      assert(
false && 
"Should never get here - invalid intersection type!");
 
   94  bool boundary()
 const {
 
   95    checkIntersectionType();
 
   97      _intersectionType == GridImp::boundary ||
 
   98      _intersectionType == GridImp::foreign;
 
  101  int boundaryId()
 const {
 
  102    return _multiDomainIntersection.boundaryId();
 
  105  std::size_t boundarySegmentIndex()
 const {
 
  106    checkIntersectionType();
 
  109    return _intersectionType == GridImp::boundary ? _multiDomainIntersection.boundarySegmentIndex() : 0;
 
  112  bool neighbor()
 const {
 
  113    checkIntersectionType();
 
  114    return _intersectionType == GridImp::neighbor;
 
  117  Entity inside()
 const {
 
  118    return {EntityWrapper(&_indexSet->_grid,_multiDomainIntersection.inside())};
 
  121  Entity outside()
 const {
 
  122    checkIntersectionType();
 
  123    assert(_intersectionType == GridImp::neighbor);
 
  124    return {EntityWrapper(&_indexSet->_grid,_multiDomainIntersection.outside())};
 
  127  bool conforming()
 const {
 
  128    return _multiDomainIntersection.conforming();
 
  131  LocalGeometry geometryInInside()
 const {
 
  132    return LocalGeometry(hostIntersection().geometryInInside());
 
  135  LocalGeometry geometryInOutside()
 const {
 
  136    checkIntersectionType();
 
  137    assert(_intersectionType == GridImp::neighbor);
 
  138    return LocalGeometry(hostIntersection().geometryInOutside());
 
  141  Geometry geometry()
 const {
 
  142    return Geometry(hostIntersection().geometry());
 
  145  GeometryType type()
 const {
 
  146    return _multiDomainIntersection.type();
 
  149  int indexInInside()
 const {
 
  150    return _multiDomainIntersection.indexInInside();
 
  153  int indexInOutside()
 const {
 
  154    checkIntersectionType();
 
  155    assert(_intersectionType == GridImp::neighbor);
 
  156    return _multiDomainIntersection.indexInOutside();
 
  159  GlobalCoords outerNormal(
const LocalCoords& local)
 const {
 
  160    return _multiDomainIntersection.outerNormal(local);
 
  163  GlobalCoords integrationOuterNormal(
const LocalCoords& local)
 const {
 
  164    return _multiDomainIntersection.integrationOuterNormal(local);
 
  167  GlobalCoords unitOuterNormal(
const LocalCoords& local)
 const {
 
  168    return _multiDomainIntersection.unitOuterNormal(local);
 
  171  GlobalCoords centerUnitOuterNormal()
 const {
 
  172    return _multiDomainIntersection.centerUnitOuterNormal();
 
  175  typename GridImp::IntersectionType intersectionType()
 const {
 
  176    checkIntersectionType();
 
  177    return _intersectionType;
 
  180  const MultiDomainIntersection& multiDomainIntersection()
 const 
  182    return _multiDomainIntersection;
 
  187  const IndexSet* _indexSet;
 
  188  MultiDomainIntersection _multiDomainIntersection;
 
  189  mutable bool _intersectionTypeTested;
 
  190  mutable typename GridImp::IntersectionType _intersectionType;