Skip to content
Snippets Groups Projects
Forked from agnumpde / dune-fufem
362 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
boundarypatch.hh 31.25 KiB
// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set ts=8 sw=4 et sts=4:
#ifndef BOUNDARY_PATCH_HH
#define BOUNDARY_PATCH_HH

#include <vector>
#include <set>
#include <memory>

#include <dune/common/bitsetvector.hh>
#include <dune/common/version.hh>

#include <dune/geometry/referenceelements.hh>
#include <dune/grid/common/mcmgmapper.hh>
#include <dune/grid/common/gridview.hh>
#include <dune/grid/common/gridfactory.hh>

#include <dune/fufem/globalintersectioniterator.hh>
#include <dune/fufem/boundaryiterator.hh>



// Forward declaration
template <class GridView> class BoundaryPatchIterator;



/** \brief Insertion property for segment insertion indices
 *
 * You can use a BoundaryPatchInsertionIndexProperty
 * with BoundaryPatch::insertFacesByProperty()
 * to insert all faces contained a set boundary
 * segments described by insertion indices.
 */
template <class GridView>
class BoundaryPatchInsertionIndexProperty
{
    typedef typename Dune::GridFactory<typename GridView::Grid> GridFactory;

public:
    typedef typename GridView::Intersection Intersection;

    /** \brief Create property from GridFactory and container of insertion indices
     */
    template<class T>
    BoundaryPatchInsertionIndexProperty(const GridFactory& factory, const T& t) : factory_(factory)
    {
        indices_.insert(t.begin(), t.end());
    }

    /** \brief Create property from GridFactory and a single insertion index
     */
    BoundaryPatchInsertionIndexProperty(const GridFactory& factory, int i) : factory_(factory)
    {
        indices_.insert(i);
    }

    /** \brief Check if intersection is contained in one of the boundary segments
     */
    bool operator() (const Intersection& i) const
    {
        return (factory_.wasInserted(i) and (indices_.find(factory_.insertionIndex(i))!=indices_.end()));
    }
private:
    const GridFactory& factory_;
    std::set<int> indices_;
};


/** \brief Insertion property for segment indices
 *
 * You can use a BoundaryPatchSegmentIndexProperty
 * with BoundaryPatch::insertFacesByProperty()
 * to insert all faces contained a set boundary
 * segments described by boundary segment indices.
 */
template <class GridView>
class BoundaryPatchSegmentIndexProperty
{
public:
    typedef typename GridView::Intersection Intersection;

    /** \brief Create property from a container of boundary segment indices
     */
    template<class T>
    BoundaryPatchSegmentIndexProperty(const T& t)
    {
        indices_.insert(t.begin(), t.end());
    }

    /** \brief Create property from a single boundary segment index
     */
    BoundaryPatchSegmentIndexProperty(int i)
    {
        indices_.insert(i);
    }

    /** \brief Check if intersection is contained in one of the boundary segments
     */
    bool operator() (const Intersection& i) const
    {
        return (indices_.find(i.boundarySegmentIndex())!=indices_.end());
    }
private:
    std::set<int> indices_;
};



/** \brief Insertion property for vertex vector
 *
 * You can use a BoundaryPatchEnclosingVerticesProperty
 * with BoundaryPatch::insertFacesByProperty()
 * to insert all faces that are enclosed by vertices
 * marked in a vector.
 */
template <class GridView, int ncomp = 1>
class BoundaryPatchEnclosingVerticesProperty
{
    typedef typename GridView::IndexSet IndexSet;
    static const int dim = GridView::dimension;
public:
    typedef typename GridView::Intersection Intersection;

    /** \brief Create property from a marker vector
     */
    BoundaryPatchEnclosingVerticesProperty(const GridView& gridView, const Dune::BitSetVector<ncomp>& vertices) :
        indexSet_(gridView.indexSet()),
        vertices_(vertices)
    {}

    /** \brief Check if intersection is enclosed by vertices in the vector
     */
    bool operator() (const Intersection& i) const
    {
        const auto inside = i.inside();
        int localFaceIndex = i.indexInInside();

        const auto& refElement = Dune::ReferenceElements<double, dim>::general(inside.type());

        // Get global node ids
        int n = refElement.size(localFaceIndex, 1, dim);

        // Using ReferenceElement::subEntity is OK here, because we loop
        // over all subEntities (i.e. sub-vertices) and just return false
        // if _any_ of them is not marked.
        for (int i=0; i<n; i++) {
            int localVertexIndex = refElement.subEntity(localFaceIndex, 1, i, dim);
            if (not(vertices_[indexSet_.subIndex(inside, localVertexIndex, dim)].any()))
                return false;
        }
        return true;
    }

private:
    const IndexSet& indexSet_;
    const Dune::BitSetVector<ncomp>& vertices_;
};

/** \brief Insertion property for vertex vector
 *
 * You can use a BoundaryPatchTouchingVerticesProperty
 * with BoundaryPatch::insertFacesByProperty()
 * to insert all faces that are touched by any vertices
 * marked in a vector.
 */
template <class GridView>
class BoundaryPatchTouchingVerticesProperty
{
    typedef typename GridView::IndexSet IndexSet;
    static const int dim = GridView::dimension;
public:
    typedef typename GridView::Intersection Intersection;

    /** \brief Create property from a marker vector
     */
    BoundaryPatchTouchingVerticesProperty(const GridView& gridView, const Dune::BitSetVector<1>& vertices) :
        indexSet_(gridView.indexSet()),
        vertices_(vertices)
    {}

    /** \brief Check if intersection is enclosed by vertices in the vector
     */
    bool operator() (const Intersection& i) const
    {
        const auto inside = i.inside();
        int localFaceIndex = i.indexInInside();

        const auto& refElement = Dune::ReferenceElements<double, dim>::general(inside.type());

        // Get global node ids
        int n = refElement.size(localFaceIndex, 1, dim);

        // Using ReferenceElement::subEntity is OK here, because we loop
        // over all subEntities (i.e. sub-vertices) and return true as soon
        // as _any_ of them is marked.
        for (int i=0; i<n; i++) {
            int localVertexIndex = refElement.subEntity(localFaceIndex, 1, i, dim);
            if (vertices_[indexSet_.subIndex(inside, localVertexIndex, dim)][0])
                return true;
        }
        return false;
    }

private:
    const IndexSet& indexSet_;
    const Dune::BitSetVector<1>& vertices_;
};



/** \brief Encapsulate a part of a grid boundary
    \tparam GridView The grid view on which this boundary patch lives
*/
template <class GV>
class BoundaryPatch
{

public:

    typedef GV GridView;

protected:

    static const int dim = GridView::dimension;

    typedef typename GridView::IndexSet IndexSetType;
    typedef typename GridView::IntersectionIterator IntersectionIterator;
    typedef typename GridView::Intersection Intersection;
    typedef typename GridView::template Codim<0>::Entity EntityType;
    typedef typename GridView::template Codim<0>::Iterator ElementIterator;

    typedef typename Dune::MultipleCodimMultipleGeomTypeMapper<GridView> MapperType;

public:

    /** \brief Export the appropriate iterator type */
    typedef BoundaryPatchIterator<GridView> iterator;

    BoundaryPatch() : verticesAreUpToDate_(false)
    {}

    /** \brief Constructor for a given grid view

    \param initialValue If true: BoundaryPatch contains all boundary faces
    */
    BoundaryPatch(const GridView& gridView, bool initialValue = false)
        : verticesAreUpToDate_(false)
    {
        setup(gridView, initialValue);
    }

    BoundaryPatch(const BoundaryPatch& other) {
        vertices_             = other.vertices_;
        verticesAreUpToDate_  = other.verticesAreUpToDate_;
        faces_                = other.faces_;
        if (other.gridView_.get() != NULL)
            gridView_ = std::unique_ptr<GridView>(new GridView(*other.gridView_));
        if (other.mapper_.get() != NULL)
            mapper_   = std::unique_ptr<MapperType>(new MapperType(*gridView_,Dune::mcmgLayout(Dune::Codim<1>())));
    }

    /** \brief Construct boundary patch from given vertices

        \param gridView The grid view
        \param vertices A vector of which any bit component is set if the corresponding vertex belongs to the patch.
    */
    template <int blocksize>
    BoundaryPatch(const GridView& gridView, const Dune::BitSetVector<blocksize>& vertices)
    {
        setup(gridView, vertices);
    }


    /** \brief Setup for a given grid view
     *
     * \param initialValue If true: BoundaryPatch contains all boundary faces
     */
    void setup(const GridView& gridView, bool initialValue = false)
    {
        gridView_ = std::unique_ptr<GridView>(new GridView(gridView));
        mapper_ = std::unique_ptr<MapperType>(new MapperType(*gridView_,Dune::mcmgLayout(Dune::Codim<1>())));
        faces_.resize(gridView_->size(1));
        faces_.unsetAll();
        verticesAreUpToDate_ = false;

        // include all boundary faces, if requested
        if (initialValue)
        {
            BoundaryIterator<GridView> bIt(*gridView_, BoundaryIterator<GridView>::begin);
            BoundaryIterator<GridView> bEnd(*gridView_, BoundaryIterator<GridView>::end);
            for(; bIt!=bEnd; ++bIt)
                addFace(bIt->inside(), bIt->indexInInside());
        }
    }

    /** \brief Setup for a given grid view and a bitfield
     *
     * \param gridView The grid view
     * \param vertices A vector of which any bit component is set if the corresponding vertex belongs to the patch.
     */
    template <int blocksize>
    void setup(const GridView& gridView, const Dune::BitSetVector<blocksize>& vertices)
    {
        // setup empty BoundaryPatch
        setup(gridView);

        // create property for insertion by vertex vector
        BoundaryPatchEnclosingVerticesProperty<GridView, blocksize> prop(*gridView_, vertices);

        // insert by property
        insertFacesByProperty(prop);
    }

    /** \brief Return iterator on first boundary face */
    iterator begin() const
    {
        return iterator(gridView_->template begin<0>(),
                        gridView_->template end<0>(), *this);
    }

    /** \brief Return iterator after last boundary patch face */
    iterator end() const
    {
        return iterator(gridView_->template end<0>(),
                        gridView_->template end<0>(), *this);
    }

    /** \brief Clear the boundary patch, but don't disconnect it from the grid and level */
    void clear() {
        vertices_.unsetAll();
        verticesAreUpToDate_ = false;
        faces_.unsetAll();
    }

    void getFaces(Dune::BitSetVector<1>& faces) const {
        faces = faces_;
    }

    /** \brief Returns the number of faces in the surface */
    int numFaces() const {
        return faces_.count();
    }

    /** \brief Add a boundary face to the patch */
    void addFace(const IntersectionIterator& nIt) {
        this->addFace(*nIt);
    }

    /** \brief Add a boundary face to the patch */
    void addFace(const Intersection& nIt) {
        this->faces_[mapper_->subIndex(nIt.inside(), nIt.indexInInside(),1)] = true;
    }

    /** \brief Add a boundary face to the patch */
    void addFace(const EntityType& en, int fIdx) {
        this->faces_[mapper_->subIndex(en, fIdx,1)] = true;
    }

    /** \brief Insert boundary faces filtered by an insertion property
     *
     * \tparam InsertionProperty a class providing bool operator()(Intersection)
     * \param property All boundary intersections with property(intersection)==true are inserted
     */
    template<class InsertionProperty>
    void insertFacesByProperty(const InsertionProperty& property)
    {
        BoundaryIterator<GridView> bIt(*gridView_, BoundaryIterator<GridView>::begin);
        BoundaryIterator<GridView> bEnd(*gridView_, BoundaryIterator<GridView>::end);
        for(; bIt!=bEnd; ++bIt)
        {
            if (property(*bIt))
                addFace(bIt->inside(), bIt->indexInInside());
        }

        this->verticesAreUpToDate_ = false;
    }


    /** \brief Return true if the BoundaryPatch contains a certain boundary face */
    template<class IntersectionType>
    bool contains(const IntersectionType& intersection) const {
        return this->faces_[mapper_->subIndex(intersection.inside(), intersection.indexInInside(),1)][0];
    }

    /** \brief Return true if the BoundaryPatch contains a certain boundary face */
    bool contains(const IntersectionIterator& nIt) const {
        return this->faces_[mapper_->subIndex(nIt->inside(), nIt->indexInInside(),1)][0];
    }

    /** \brief Return true if the BoundaryPatch contains a certain boundary face */
    bool contains(const EntityType& en, int faceIdx) const {
        return this->faces_[mapper_->subIndex(en, faceIdx,1)][0];
    }

    /** \brief Return true if the BoundaryPatch contains a certain subentity in some face */
    bool contains(const EntityType& en, int subEntity, int codim) const {
        if (codim==0)  // disregard element dofs
            return false;
        if (codim==1)
            return this->faces_[mapper_->subIndex(en, subEntity, 1)][0];
        const auto& refElement = Dune::ReferenceElements<double, GridView::dimension>::general(en.type());

        for (int faceIdx = 0; faceIdx<refElement.size(1); ++faceIdx)
        {
            if (this->faces_[mapper_->subIndex(en, faceIdx, 1)][0])
                if (isSubEntity(refElement, faceIdx, 1, subEntity, codim))
                    return true;
        }
        return false;
    }

    /** \brief Return true if the BoundaryPatch contains a face of given element
     *
     */
    bool containsFaceOf(const EntityType& e) const
    {
        int numFaces = e.subEntities(1);

        for (int faceIdx = 0; faceIdx<numFaces; ++faceIdx)
        {
            if (contains(e, faceIdx))
                return true;
        }
        return false;
    }

    /** \brief Return reference to the carrier grid view */
    const GridView& gridView() const {return *gridView_;}

    /** \brief Check if BoundaryPatch is initialized */
    bool isInitialized() const
    {
        return gridView_.get();
    }

    /** \brief Partial deep copy */
    BoundaryPatch& operator=(const BoundaryPatch& other) {
        vertices_             = other.vertices_;
        verticesAreUpToDate_  = other.verticesAreUpToDate_;
        faces_                = other.faces_;
        gridView_             = std::unique_ptr<GridView>(new GridView(*other.gridView_));
        mapper_               = std::unique_ptr<MapperType>(new MapperType(*gridView_,Dune::mcmgLayout(Dune::Codim<1>())));
        return *this;
    }

    bool operator==(const BoundaryPatch& other) {
        size_t s = faces_.size();
        if (s != other.faces_.size())
            return false;
        // There is no BitSetVector::operator==
        for (size_t i = 0; i < s; ++i)
            if (faces_[i] != other.faces_[i])
                return false;
        return true;
    }

    bool containsVertex(size_t v) const {
        if (!verticesAreUpToDate_)
            makeVertices();

#ifdef DUNE_RANGE_CHECKING
        if (v<0 || v>=vertices_.size())
            DUNE_THROW(Dune::RangeError, "Trying to check for vertex " << v
                       << ", but the vertices are only in the range [0..." << int(vertices_.size())-1
                       << "]!");
#endif

        return vertices_[v][0];
    }

    /** \brief Returns the area of the boundary patch */
    typename GridView::Grid::ctype area() const {

        typename GridView::Grid::ctype patchArea = 0;

        // loop over all elements
        iterator it    = begin();
        iterator endIt = end();

        for (; it!=endIt; ++it)
            patchArea += it->geometry().volume();

        return patchArea;
    }

    void getVertices(Dune::BitSetVector<1>& vertices) const {
        if (!this->verticesAreUpToDate_)
            this->makeVertices();

        vertices = this->vertices_;
    }

    const Dune::BitSetVector<1>* getVertices() const {
        if (!this->verticesAreUpToDate_)
            this->makeVertices();

        return &this->vertices_;
    }

    /**
     * \brief Get the vertices which are on the boundary of the boundary patch
     *
     * ATTENTION: Don't use this method, until you're absolutely sure that the internals
     * work correctly for your grid implementation! It does not work for general
     * grids. See the internal documentation for details.
     */
    void getPatchBoundaryVertices(Dune::BitSetVector<1>& patchBoundary) const {

        const IndexSetType& indexSet = gridView_->indexSet();

        patchBoundary.resize(indexSet.size(dim));
        patchBoundary.unsetAll();

        // loop over all elements
        for (const auto& e : elements(*gridView_)) {

            const auto& refElement = Dune::ReferenceElements<double, dim>::general(e.type());

            // Loop over all neighbors
            for (const auto& is : intersections(*gridView_,e)) {

                // if the element is a boundary element, but _not_ a patch element
                if (is.boundary() && !contains(is)) {

                    // Get global node ids
                    int n = refElement.size(is.indexInInside(),1,dim);

                    // ATTENTION: This implementation is broken!
                    //
                    // It will not work in general, because there's no guarantee that:
                    //
                    //   subIndex(e, refElement.subEntity(face,1,i,dim)) == subIndex(e.subEntity<1>(face), i, dim)
                    //
                    // The latter is what you really want because it uses the correct embedding
                    // of the face into the element (which is not the same as the one in the
                    // reference element)
                    for (int i=0; i<n; i++) {
                        int faceIdxi = refElement.subEntity(is.indexInInside(), 1, i, dim);
                        int globalIdx = indexSet.subIndex(e, faceIdxi,dim);
                        if (this->containsVertex(globalIdx))
                            patchBoundary[globalIdx] = true;
                    }

                }

            }

        }

    }

    /**
     * \brief Get the edges which are on the boundary of the boundary patch
     *
     * \todo This only works when dim==3
     *
     * ATTENTION: Don't use this method, until you're absolutely sure that the internals
     * work correctly for your grid implementation! It does not work for general
     * grids. See the internal documentation for details.
     */
    void getPatchBoundaryEdges(Dune::BitSetVector<1>& patchBoundaryEdges) const {

        assert(dim==3);
        const IndexSetType& indexSet = gridView_->indexSet();

        patchBoundaryEdges.resize(indexSet.size(dim-1));
        patchBoundaryEdges.unsetAll();

        // loop over all elements
        for (const auto& e : elements(*gridView_)) {

            const auto& refElement = Dune::ReferenceElements<double, dim>::general(e.type());

            // Loop over all neighbors
            for (const auto& is : intersections(*gridView_,e)) {

                // if the element is a boundary element, but _not_ a patch element
                if (is.boundary() && !contains(is)) {

                    // Loop over the face edges
                    int n = refElement.size(is.indexInInside(),1,dim-1);

                    for (int i=0; i<n; i++) {

                        // ATTENTION: This implementation is broken!
                        //
                        // It will not work in general, because there's no guarantee that:
                        //
                        //   subIndex(e, refElement.subEntity(face,1,i,dim-1)) == subIndex(e.subEntity<1>(face), i, dim-1)
                        //
                        // The latter is what you really want because it uses the correct embedding
                        // of the face into the element (which is not the same as the one in the
                        // reference element).
                        int edge = refElement.subEntity(is.indexInInside(), 1, i, dim-1);

                        // If 'edge' would be correct, the following use of ReferenceElement::subEntity
                        // would be OK, because we just do a check for all vertices we pass, i.e. 0 and 1.
                        int v0 = refElement.subEntity(edge, dim-1, 0, dim);
                        int v1 = refElement.subEntity(edge, dim-1, 1, dim);

                        if (containsVertex(indexSet.subIndex(e, v0,dim))
                            && containsVertex(indexSet.subIndex(e, v1,dim)))
                            patchBoundaryEdges[indexSet.subIndex(e, edge,dim-1)] = true;
                    }

                }

            }

        }

    }

    /** \brief Returns the number of vertices in the surface */
    int numVertices() const {
        if (!this->verticesAreUpToDate_)
            this->makeVertices();

        return this->vertices_.count();
    }

    /**
     * \brief Return vertex unit normals
     *
     * ATTENTION: This will only work correctly if unitOuterNormal
     * is constant along intersections. See the internal documentation for details.
     * */
    void getNormals(std::vector<Dune::FieldVector<double, dim> >& normals) const {
        normals = getNormals();
    }

    /** \brief Return vertex unit normals */
    std::vector<Dune::FieldVector<double,dim> > getNormals() const {
        if (!this->verticesAreUpToDate_)
            this->makeVertices();

        typedef Dune::FieldVector<double, dim> Vector;
        std::vector<Vector> normals(this->vertices_.size(), Vector(0.0));

        // Loop over all boundary segments
        iterator it    = begin();
        iterator endIt = end();

        for (; it!=endIt; ++it) {
            const auto inside = it->inside();

            const auto& refElement = Dune::ReferenceElements<double, dim>::general(inside.type());

            // Compute actual surface normals
            int n = refElement.size(it->indexInInside(),1,dim);

            for (int i=0; i<n; i++) {
                // ATTENTION: This implementation does only work if unitOuterNormal is constant on the intersection.
                // It will not work in general, because there's no guarantee that:
                //
                //   subIndex(e, refElement.subEntity(inside,1,i,dim)) == subIndex(e.subEntity<1>(inside), i, dim)
                //
                // The latter is what you really want because it uses the correct embedding
                // of the face into the element (which is not the same as the one in the
                // reference element).
                //
                // If unitOuterNormal is constant we add the same faceNormal to all vertices
                // of this face, hence the proper order does not matter. Otherwise this
                // implementation may compute the faceNormal at the wrong posInBoundary
                // because posInElement and vertexIdx don't correspond to each other.
                int faceIdxi = refElement.subEntity(it->indexInInside(), 1, i, dim);

                // local position of vertex in element
                const Dune::FieldVector<double, dim>& posInElement = refElement.position(faceIdxi, dim);

                // local position in boundary segment
                Dune::FieldVector<double, dim-1> posInBoundary = it->geometryInInside().local(posInElement);

                // Get normal there
                const Dune::FieldVector<double, dim>& faceNormal = it->unitOuterNormal(posInBoundary);

                int vertexIdx = gridView_->indexSet().subIndex(inside, faceIdxi,dim);
                normals[vertexIdx] += faceNormal;
            }

        }

        // Normalize vertex normals
        for (size_t i=0; i<normals.size(); i++)
            if (this->vertices_[i][0])
                normals[i] /= normals[i].two_norm();

        return normals;
    }

    /** \brief Return vertex unit normals corr. to local indices */
    std::vector<Dune::FieldVector<double,dim> > getLocalNormals() const {
        if (!this->verticesAreUpToDate_)
            this->makeVertices();

        auto globalToLocal = makeGlobalToLocal();
        using Vector = Dune::FieldVector<double, dim>;
        std::vector<Vector> normals(this->vertices_.count(), Vector(0.0));

        // Loop over all boundary segments
        for (const auto& it : *this) {

            const auto inside = it.inside();

            const auto& refElement = Dune::ReferenceElements<double, dim>::general(inside.type());

            // Compute actual surface normals
            int n = refElement.size(it.indexInInside(),1,dim);

            const auto& geomInInside = it.geometryInInside();
            for (int i=0; i<n; i++) {

                // See the Warning in the method above!
                int faceIdxi = refElement.subEntity(it.indexInInside(), 1, i, dim);

                // local position of vertex in element
                auto& posInElement = refElement.position(faceIdxi, dim);

                // local position in boundary segment
                auto posInBoundary = geomInInside.local(posInElement);

                // Get normal there
                const auto& faceNormal = it.unitOuterNormal(posInBoundary);

                int vertexIdx = gridView_->indexSet().subIndex(inside, faceIdxi,dim);
                normals[globalToLocal[vertexIdx]] += faceNormal;
            }

        }

        // Normalize vertex normals
        for (size_t i=0; i<normals.size(); i++)
            normals[i] /= normals[i].two_norm();

        return normals;
    }

    void makeGlobalToLocal(std::vector<int>& globalToLocal) const {
        globalToLocal = makeGlobalToLocal();
    }

    std::vector<int> makeGlobalToLocal() const {
        if (!this->verticesAreUpToDate_)
            this->makeVertices();

        std::vector<int> globalToLocal(this->vertices_.size());
        int idx = 0;
        for (size_t i=0; i< globalToLocal.size(); i++)
            globalToLocal[i] = (this->vertices_[i][0]) ? idx++ : -1;

        return globalToLocal;
    }


    /** \brief Adds another patch in the sense that afterwards this patch
     * contains all the vertices included in any one of the two patches
     *
     * \param patch Patch to be added*/

    BoundaryPatch<GridView> addPatch(const BoundaryPatch<GridView>& patch) {

        /* test whether both patches live on the same grid
         * for LevelBoundaryPatches it is not tested whether both patches refer to the same level*/
        if (&this->gridView().grid() != &patch.gridView().grid())
            DUNE_THROW(Dune::NotImplemented, "addPatch only works for patches defined on the same grid");
        Dune::BitSetVector<1> vertices, additionalVertices;
        this->getVertices(vertices);
        patch.getVertices(additionalVertices);

        // create combined BitSetVector
        for (size_t i=0; i<vertices.size(); i++)
            if (additionalVertices[i][0])
                vertices[i] = true;

        GridView gridView = this->gridView();
        this->setup(gridView, vertices);

        return *this;
    }


    /** \brief Determines the overlap of this boundary patch and another
     * by reducing this patch to the common vertices.
     *
     * \param patch Patch to be intersected with*/

    BoundaryPatch<GridView> intersect(const BoundaryPatch<GridView>& patch) {

        /* test whether both patches live on the same grid
         * for LevelBoundaryPatches it is not tested whether both patches refer to the same level*/
        if (&this->gridView().grid() != &patch.gridView().grid())
            DUNE_THROW(Dune::NotImplemented, "addPatch only works for patches defined on the same grid");

        Dune::BitSetVector<1> vertices, intersectionVertices;
        this->getVertices(vertices);
        patch.getVertices(intersectionVertices);

        // create intersection BitSetVector
        for (size_t i=0; i<vertices.size(); i++)
            if (vertices[i][0] && intersectionVertices[i][0])
                vertices[i][0] = true;
            else
                vertices[i][0] = false;

        GridView gridView = this->gridView();
        this->setup(gridView, vertices);

        return *this;
    }



protected:

    // Given a reference element for an entity E this
    // checks if subentity (j, jCodim) of E is a subentity of subentity (i,iCodim) of E
    // e.g. if the j-th vertex of E is also a vertex of the i-th edge of E
    template<class RefElement>
    static bool isSubEntity(const RefElement& referenceElement, int i, int iCodim, int j, int jCodim)
    {
        for (int jj = 0; jj<referenceElement.size(i, iCodim, jCodim); jj++)
        {
            // This use of ReferenceElement::subEntity is OK, because
            // we just check if any of the returned indices matches j.
            if (referenceElement.subEntity(i, iCodim, jj, jCodim) == j)
                return true;
        }
        return false;
    }

    void makeVertices() const {

        const typename GridView::IndexSet& indexSet = gridView_->indexSet();

        this->vertices_.resize(gridView_->size(dim));
        this->vertices_.unsetAll();

        // loop over all elements
        iterator it    = begin();
        iterator endIt = end();

        for (; it!=endIt; ++it) {
            const auto inside = it->inside();

            const auto& refElement = Dune::ReferenceElements<double, dim>::general(inside.type());

            // Get global node ids
            int n = refElement.size(it->indexInInside(),1,dim);

            // This use of ReferenceElement::subEntity is OK, because
            // we mark the vertices corresponding to all returned indices.
            for (int i=0; i<n; i++) {
                int faceIdxi = refElement.subEntity(it->indexInInside(), 1, i, dim);
                vertices_[indexSet.template subIndex(inside,faceIdxi,dim)] = true;
            }

        }

        verticesAreUpToDate_ = true;

    }



    mutable Dune::BitSetVector<1> vertices_;

    mutable bool verticesAreUpToDate_;

    Dune::BitSetVector<1> faces_;

    std::unique_ptr<GridView> gridView_;

    std::unique_ptr<MapperType> mapper_;
};




/** \brief Iterator of boundary intersections of grid view
 *
 * \tparam GridView The grid view on which this boundary patch lives
*/
template <class GridView>
class BoundaryPatchIterator
    : public GlobalIntersectionIterator<GridView, BoundaryPatchIterator<GridView> >
{
    // Only BoundaryPatch can call this class' constructors
    friend class BoundaryPatch<GridView>;

    typedef GlobalIntersectionIterator<GridView, BoundaryPatchIterator<GridView> > Base;
    enum {dim=GridView::dimension};

    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
    typedef typename GridView::template Codim<0>::Entity Element;

public:

    /** \brief The type of objects we are iterating over */
    typedef typename Base::Intersection Intersection;

    /** \brief Return true if the given element contains no boundary patch faces (and hence can be skipped) */
    bool skipElement(const Element& e)
    {
        return not(boundaryPatchPtr_->containsFaceOf(e));
    }

    bool skipIntersection(const Intersection& i)
    {
        return not(boundaryPatchPtr_->contains(i.inside(), i.indexInInside()));
    }

protected:

    /** \brief Create iterator for given grid view
     *
     * \param eIt Element iterator to the first element to consider
     * \param endEIt Element iterator after the last element to consider
     */
    BoundaryPatchIterator(const ElementIterator& eIt, const ElementIterator& endEIt,
                          const BoundaryPatch<GridView>& boundaryPatch) :
        Base(boundaryPatch.gridView(), eIt, endEIt),
        boundaryPatchPtr_(&boundaryPatch)
    {
        Base::initialIncrement();
    }

    const BoundaryPatch<GridView>* boundaryPatchPtr_;
};

#endif