diff --git a/dumux/boxmodels/common/boxelementboundarytypes.hh b/dumux/boxmodels/common/boxelementboundarytypes.hh
index 44998ebbf5042548f657495b91aa0182ccf8e8e6..c3e229974bff92ab3b2b5cd8f681e3f02fa95f67 100644
--- a/dumux/boxmodels/common/boxelementboundarytypes.hh
+++ b/dumux/boxmodels/common/boxelementboundarytypes.hh
@@ -29,8 +29,6 @@
 
 #include "boxproperties.hh"
 
-#include <dune/grid/common/geometry.hh>
-
 #include <dumux/common/valgrind.hh>
 
 namespace Dumux
@@ -55,11 +53,6 @@ class BoxElementBoundaryTypes : public std::vector<typename GET_PROP_TYPE(TypeTa
     enum { dim = GridView::dimension };
     typedef typename GridView::template Codim<0>::Entity Element;
     typedef typename GridView::template Codim<dim>::EntityPointer VertexPointer;
-    typedef typename GridView::IntersectionIterator IntersectionIterator;
-    typedef typename GridView::ctype CoordScalar;
-
-    typedef typename Dune::GenericReferenceElements<CoordScalar, dim> ReferenceElements;
-    typedef typename Dune::GenericReferenceElement<CoordScalar, dim> ReferenceElement;
 
 public:
     /*!
@@ -97,50 +90,14 @@ public:
         int numVerts = element.template count<dim>();
         this->resize(numVerts);
 
-        int nBoundary = 0;
-        std::vector<bool> onBoundary(numVerts, false);
-
-        // loop over all intersections of the element and mark all
-        // vertices in these intersections
-        Dune::GeometryType geoType = element.geometry().type();
-        const ReferenceElement &refElem = ReferenceElements::general(geoType);
-        IntersectionIterator isIt = problem.gridView().ibegin(element);
-        IntersectionIterator isEndIt = problem.gridView().iend(element);
-        for (; isIt != isEndIt; ++isIt) {
-            if (!isIt->boundary())
-                continue; // intersection is not on grid boundary
-
-            // mark all vertices on the intersection
-            int faceIdx = isIt->indexInInside();
-            int numFaceVerts = refElem.size(faceIdx, 1, dim);
-            for (int faceVertIdx = 0;
-                 faceVertIdx < numFaceVerts;
-                 ++faceVertIdx)
-            {
-                int elemVertIdx = refElem.subEntity(faceIdx,
-                                                    1,
-                                                    faceVertIdx,
-                                                    dim);
-                if (!onBoundary[elemVertIdx]) {
-                    ++ nBoundary;
-                    onBoundary[elemVertIdx] = true;
-                }
-            }
-        }
-
         hasDirichlet_ = false;
         hasNeumann_ = false;
         hasOutflow_ = false;
 
-        if (nBoundary == 0) {
-            for (int i = 0; i < numVerts; ++i)
-                (*this)[i].reset();
-            return;
-        }
         for (int i = 0; i < numVerts; ++i) {
             (*this)[i].reset();
 
-            if (!onBoundary[i])
+            if (!problem.model().onBoundary(element, i))
                 continue;
 
             const VertexPointer vptr = element.template subEntity<dim>(i);
@@ -150,7 +107,7 @@ public:
             hasNeumann_ = hasNeumann_ || (*this)[i].hasNeumann();
             hasOutflow_ = hasOutflow_ || (*this)[i].hasOutflow();
         }
-    };
+    }
 
     /*!
      * \brief Returns whether the element has a vertex which contains
diff --git a/dumux/boxmodels/common/boxmodel.hh b/dumux/boxmodels/common/boxmodel.hh
index 2463f7e1d202f8ea236d5696c153fa4cbcf1035f..73621ebf8569464701d27340b7cc491127ce5df2 100644
--- a/dumux/boxmodels/common/boxmodel.hh
+++ b/dumux/boxmodels/common/boxmodel.hh
@@ -37,6 +37,7 @@
 
 #include <dumux/parallel/vertexhandles.hh>
 
+#include <dune/grid/common/geometry.hh>
 
 namespace Dumux
 {
@@ -74,10 +75,15 @@ class BoxModel
     typedef typename GET_PROP_TYPE(TypeTag, NewtonMethod) NewtonMethod;
     typedef typename GET_PROP_TYPE(TypeTag, NewtonController) NewtonController;
 
+    typedef typename GridView::ctype CoordScalar;
     typedef typename GridView::template Codim<0>::Entity Element;
     typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     typedef typename GridView::template Codim<dim>::Entity Vertex;
     typedef typename GridView::template Codim<dim>::Iterator VertexIterator;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+
+    typedef typename Dune::GenericReferenceElements<CoordScalar, dim> ReferenceElements;
+    typedef typename Dune::GenericReferenceElement<CoordScalar, dim> ReferenceElement;
 
     // copying a model is not a good idea
     BoxModel(const BoxModel &);
@@ -104,6 +110,8 @@ public:
     {
         problemPtr_ = &prob;
 
+        updateBoundaryIndices_();
+
         int nDofs = asImp_().numDofs();
         uCur_.resize(nDofs);
         uPrev_.resize(nDofs);
@@ -705,6 +713,27 @@ public:
     const GridView &gridView() const
     { return problem_().gridView(); }
 
+    /*!
+     * \brief Returns true if the vertex with 'globalVertIdx' is
+     *        located on the grid's boundary.
+     *
+     * \param globalVertIdx The global index of the control volume's
+     *                      associated vertex
+     */
+    bool onBoundary(int globalVertIdx) const
+    { return boundaryIndices_[globalVertIdx]; }
+
+    /*!
+     * \brief Returns true if a vertex is located on the grid's
+     *        boundary.
+     *
+     * \param elem A DUNE Codim<0> entity which contains the control
+     *             volume's associated vertex.
+     * \param vIdx The local vertex index inside elem
+     */
+    bool onBoundary(const Element &elem, int vIdx) const
+    { return onBoundary(vertexMapper().map(elem, vIdx, dim)); }
+
     template <class FluidState>
     static void completeFluidState(const PrimaryVariables& primaryVariables,
                                    const Problem& problem,
@@ -815,23 +844,55 @@ protected:
         }
     }
 
+    /*!
+     * \brief Find all indices of boundary vertices.
+     *
+     * For this we need to loop over all intersections (which is slow
+     * in general). If the DUNE grid interface would provide a
+     * onBoundary() method for entities this could be done in a much
+     * nicer way (actually this would not be necessary)
+     */
+    void updateBoundaryIndices_()
+    {
+        boundaryIndices_.resize(numDofs());
+        std::fill(boundaryIndices_.begin(), boundaryIndices_.end(), false);
+
+        ElementIterator eIt = gridView_().template begin<0>();
+        ElementIterator eEndIt = gridView_().template end<0>();
+        for (; eIt != eEndIt; ++eIt) {
+            Dune::GeometryType geoType = eIt->geometry().type();
+            const ReferenceElement &refElem = ReferenceElements::general(geoType);
+
+            IntersectionIterator isIt = gridView_().ibegin(*eIt);
+            IntersectionIterator isEndIt = gridView_().iend(*eIt);
+            for (; isIt != isEndIt; ++isIt) {
+                if (!isIt->boundary())
+                    continue;
+                // add all vertices on the intersection to the set of
+                // boundary vertices
+                int faceIdx = isIt->indexInInside();
+                int numFaceVerts = refElem.size(faceIdx, 1, dim);
+                for (int faceVertIdx = 0;
+                     faceVertIdx < numFaceVerts;
+                     ++faceVertIdx)
+                {
+                    int elemVertIdx = refElem.subEntity(faceIdx,
+                                                        1,
+                                                        faceVertIdx,
+                                                        dim);
+                    int globalVertIdx = vertexMapper().map(*eIt, elemVertIdx, dim);
+                    boundaryIndices_[globalVertIdx] = true;
+                }
+            }
+        }
+    }
+
     // the hint cache for the previous and the current volume
     // variables
     mutable std::vector<bool> hintsUsable_;
     mutable std::vector<VolumeVariables> curHints_;
     mutable std::vector<VolumeVariables> prevHints_;
 
-    /*!
-     * \brief Returns whether messages should be printed
-     */
-    bool verbose_() const
-    { return gridView_().comm().rank() == 0; };
-
-    Implementation &asImp_()
-    { return *static_cast<Implementation*>(this); }
-    const Implementation &asImp_() const
-    { return *static_cast<const Implementation*>(this); }
-
     // the problem we want to solve. defines the constitutive
     // relations, matxerial laws, etc.
     Problem *problemPtr_;
@@ -842,6 +903,9 @@ protected:
     // local jacobian
     JacobianAssembler *jacAsm_;
 
+    // the set of all indices of vertices on the boundary
+    std::vector<bool> boundaryIndices_;
+
     // cur is the current iterative solution, prev the converged
     // solution of the previous time step
     SolutionVector uCur_;
@@ -850,6 +914,17 @@ protected:
     Dune::BlockVector<Dune::FieldVector<Scalar, 1> > boxVolume_;
 
 private:
+    /*!
+     * \brief Returns whether messages should be printed
+     */
+    bool verbose_() const
+    { return gridView_().comm().rank() == 0; };
+
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+
     bool enableHints_;
 };
 }