From ced66b0c8040bb7c6ae27e03b33b400a07531152 Mon Sep 17 00:00:00 2001
From: Markus Wolff <markus.wolff@twt-gmbh.de>
Date: Fri, 6 Sep 2013 15:00:24 +0000
Subject: [PATCH] replaced mimetic finite difference implementation of the 2p
 pressure equation by the newer implementations from dumux-devel

   - includes gravity terms but no capillary pressure terms!
   - additional implementation for adaptive grids



git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/trunk@11406 2fb0f335-1f38-0410-981e-8018bf24f1b0
---
 .../{croperator.hh => croperator2p.hh}        |  66 +-
 .../diffusion/mimetic/croperator2padaptive.hh | 564 +++++++++++++
 .../2p/diffusion/mimetic/mimetic2p.hh         | 747 +++++++++++++++++
 .../2p/diffusion/mimetic/mimetic2padaptive.hh | 775 ++++++++++++++++++
 .../diffusion/mimetic/mimeticgroundwater.hh   | 436 ----------
 .../2p/diffusion/mimetic/mimeticoperator.hh   | 126 ---
 .../2p/diffusion/mimetic/mimeticoperator2p.hh | 300 +++++++
 .../mimetic/mimeticoperator2padaptive.hh      | 308 +++++++
 .../2p/diffusion/mimetic/mimeticpressure2p.hh | 481 ++++++-----
 .../mimetic/mimeticpressure2padaptive.hh      | 481 +++++++++++
 .../mimetic/mimeticpressureproperties2p.hh    |  23 +-
 .../mimeticpressureproperties2padaptive.hh    |  79 ++
 12 files changed, 3589 insertions(+), 797 deletions(-)
 rename dumux/decoupled/2p/diffusion/mimetic/{croperator.hh => croperator2p.hh} (85%)
 create mode 100644 dumux/decoupled/2p/diffusion/mimetic/croperator2padaptive.hh
 create mode 100644 dumux/decoupled/2p/diffusion/mimetic/mimetic2p.hh
 create mode 100644 dumux/decoupled/2p/diffusion/mimetic/mimetic2padaptive.hh
 delete mode 100644 dumux/decoupled/2p/diffusion/mimetic/mimeticgroundwater.hh
 delete mode 100644 dumux/decoupled/2p/diffusion/mimetic/mimeticoperator.hh
 create mode 100644 dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2p.hh
 create mode 100644 dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2padaptive.hh
 create mode 100644 dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2padaptive.hh
 create mode 100644 dumux/decoupled/2p/diffusion/mimetic/mimeticpressureproperties2padaptive.hh

diff --git a/dumux/decoupled/2p/diffusion/mimetic/croperator.hh b/dumux/decoupled/2p/diffusion/mimetic/croperator2p.hh
similarity index 85%
rename from dumux/decoupled/2p/diffusion/mimetic/croperator.hh
rename to dumux/decoupled/2p/diffusion/mimetic/croperator2p.hh
index 8325fd1567..6b07041189 100644
--- a/dumux/decoupled/2p/diffusion/mimetic/croperator.hh
+++ b/dumux/decoupled/2p/diffusion/mimetic/croperator2p.hh
@@ -16,8 +16,8 @@
  *   You should have received a copy of the GNU General Public License       *
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
  *****************************************************************************/
-#ifndef DUMUX_CROPERATOR_HH
-#define DUMUX_CROPERATOR_HH
+#ifndef DUMUX_CROPERATOR2P_HH
+#define DUMUX_CROPERATOR2P_HH
 
 #include<iostream>
 #include<vector>
@@ -25,6 +25,7 @@
 #include<map>
 #include<cassert>
 
+#include<dune/common/timer.hh>
 #include<dune/common/fvector.hh>
 #include<dune/common/fmatrix.hh>
 #include<dune/common/exceptions.hh>
@@ -46,7 +47,7 @@
 namespace Dumux
 {
 /*!
- * \ingroup MimeticPressure2p
+ * \ingroup Mimetic2p
  */
 /**
  * @brief defines a class for Crozieux-Raviart piecewise linear finite element functions
@@ -68,8 +69,8 @@ namespace Dumux
  * \tparam Scalar The field type used in the elements of the global stiffness matrix
  * \tparam GridView The grid view of the simulation grid
  */
-template<class Scalar, class GridView>
-class CROperatorAssembler
+template<class TypeTag>
+class CROperatorAssemblerTwoP
 {
     template<int dim>
     struct FaceLayout
@@ -79,13 +80,11 @@ class CROperatorAssembler
             return gt.dim() == dim-1;
         }
     };
-
-    typedef typename GridView::Grid Grid;
-    enum {dim=Grid::dimension};
-    typedef typename Grid::template Codim<0>::Entity Entity;
-    typedef typename GridView::template Codim<0>::Iterator Iterator;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    enum {dim=GridView::dimension};
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     typedef typename GridView::IndexSet IS;
-    typedef typename Grid::template Codim<0>::EntityPointer EEntityPointer;
     typedef Dune::FieldMatrix<Scalar,1,1> BlockType;
     typedef Dune::BCRSMatrix<BlockType> MatrixType;
     typedef typename MatrixType::block_type MBlockType;
@@ -95,9 +94,10 @@ class CROperatorAssembler
     typedef Dune::BlockVector< Dune::FieldVector<double,1> > SatType;
     typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView,FaceLayout> FaceMapper;
 
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
     enum
     {
-        pressEqIdx = 0
+        pressEqIdx = Indices::pressEqIdx,
     };
 
     //! a function to approximately compute the number of nonzeros
@@ -109,13 +109,12 @@ class CROperatorAssembler
 public:
     typedef MatrixType RepresentationType;
 
-    CROperatorAssembler (const GridView& gridview)
+    CROperatorAssemblerTwoP (const GridView& gridview)
     : gridView_(gridview), faceMapper_(gridView_), size_(faceMapper_.size()),
       A_(size_, size_, nnz(), RepresentationType::random)
     {}
 
-    //!Initialize the global matrix of the system of equations to solve
-    void initializeMatrix()
+    void initialize()
     {
         faceMapper_.update();
 
@@ -132,8 +131,8 @@ public:
         std::vector<bool> visited(size_, false);
 
         // LOOP 1 : Compute row sizes
-        Iterator eEndIt = gridView_.template end<0>();
-        for (Iterator eIt = gridView_.template begin<0>(); eIt != eEndIt; ++eIt)
+        ElementIterator eEndIt = gridView_.template end<0>();
+        for (ElementIterator eIt = gridView_.template begin<0>(); eIt != eEndIt; ++eIt)
         {
             int numFaces = eIt->template count<1>();
 
@@ -160,7 +159,7 @@ public:
         visited.assign(size_, false);
 
         // LOOP 2 : insert the nonzeros
-        for (Iterator eIt = gridView_.template begin<0>(); eIt!=eEndIt; ++eIt)
+        for (ElementIterator eIt = gridView_.template begin<0>(); eIt!=eEndIt; ++eIt)
         {
             int numFaces = eIt->template count<1>();
 
@@ -197,6 +196,16 @@ public:
         return A_;
     }
 
+    const FaceMapper& faceMapper()
+    {
+        return faceMapper_;
+    }
+
+    const FaceMapper& faceMapper() const
+    {
+        return faceMapper_;
+    }
+
     /*! @brief Assemble global stiffness matrix
 
       This method takes an object that can compute local stiffness matrices and
@@ -223,7 +232,7 @@ public:
 
         // check size
         if (u.N()!=A_.M() || f.N()!=A_.N())
-            DUNE_THROW(Dune::MathError,"CROperatorAssembler::assemble(): size mismatch");
+            DUNE_THROW(Dune::MathError,"CROperatorAssemblerTwoP::assemble(): size mismatch");
         // clear global stiffness matrix and right hand side
         A_ = 0;
         f = 0;
@@ -234,11 +243,11 @@ public:
                 essential[i][0] = BoundaryConditions::neumann;
 
         // local to global id mapping (do not ask vertex mapper repeatedly
-        int local2Global[2*GridView::dimension];
+        Dune::FieldVector<int, 2*dim> local2Global(0);
 
         // run over all leaf elements
-        Iterator eEndIt = gridView_.template end<0>();
-        for (Iterator eIt = gridView_.template begin<0>(); eIt!=eEndIt; ++eIt)
+        ElementIterator eEndIt = gridView_.template end<0>();
+        for (ElementIterator eIt = gridView_.template begin<0>(); eIt!=eEndIt; ++eIt)
         {
             unsigned int numFaces = eIt->template count<1>();
 
@@ -274,6 +283,19 @@ public:
                     f[local2Global[i]][0] += loc.rhs(i)[0];
             }
         }
+        // run over all leaf elements
+        for (ElementIterator eIt = gridView_.template begin<0>(); eIt!=eEndIt; ++eIt)
+        {
+            unsigned int numFaces = eIt->template count<1>();
+
+            // get local to global id map
+            for (int k = 0; k < numFaces; k++)
+            {
+                int alpha = faceMapper_.map(*eIt, k, 1);
+                local2Global[k] = alpha;
+            }
+            loc.completeRHS(*eIt, local2Global, f);
+        }
 
         // put in essential boundary conditions
         rowiterator endi=A_.end();
diff --git a/dumux/decoupled/2p/diffusion/mimetic/croperator2padaptive.hh b/dumux/decoupled/2p/diffusion/mimetic/croperator2padaptive.hh
new file mode 100644
index 0000000000..f8cb84ee07
--- /dev/null
+++ b/dumux/decoupled/2p/diffusion/mimetic/croperator2padaptive.hh
@@ -0,0 +1,564 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+#ifndef DUMUX_CROPERATOR2PADAPTIVE_HH
+#define DUMUX_CROPERATOR2PADAPTIVE_HH
+
+#include<iostream>
+#include<vector>
+#include<set>
+#include<map>
+#include<cassert>
+#include<stdio.h>
+#include<stdlib.h>
+
+#include<dune/common/timer.hh>
+#include<dune/common/fvector.hh>
+#include<dune/common/fmatrix.hh>
+#include<dune/common/exceptions.hh>
+#include<dune/geometry/type.hh>
+#include<dune/grid/common/grid.hh>
+#include<dune/grid/common/mcmgmapper.hh>
+
+#include<dune/istl/bvector.hh>
+#include<dune/istl/operators.hh>
+#include<dune/istl/bcrsmatrix.hh>
+#include<dumux/common/boundaryconditions.hh>
+#include<dumux/decoupled/2p/diffusion/mimetic/localstiffness.hh>
+
+/**
+ * @file
+ * @brief  defines a class for piecewise linear finite element functions
+ */
+
+namespace Dumux
+{
+
+//forward declaration
+template<class GridView>
+class IntersectionMapper;
+
+/*!
+ * \ingroup Mimetic2p
+ */
+/**
+ * @brief defines a class for Crozieux-Raviart piecewise linear finite element functions
+ *
+ */
+
+/*! @brief A class for mapping a CR function to a CR function
+
+  This class sets up a compressed row storage matrix with connectivity for CR elements.
+
+  This class does not fill any entries into the matrix.
+
+  The template parameter TypeTag describes what kind of Assembler we are. There two choices:
+  <dt>LevelTag</dt> We assemble on a grid level.
+  <dt>LeafTag</dt> We assemble on the leaf entities of the grid
+*/
+/*! @brief Extends CROperatorBase by a generic methods to assemble global stiffness matrix from local stiffness matrices
+ *
+ *
+ * The template parameter TypeTag describes what kind of Assembler we are. There two choices:
+ * <dt>LevelTag</dt> We assemble on a grid level.
+ * <dt>LeafTag</dt> We assemble on the leaf entities of the grid
+ */
+template<class TypeTag>
+class CROperatorAssemblerTwoPAdaptive
+{
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    enum {dim=GridView::dimension};
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+    typedef typename GridView::IndexSet IS;
+    typedef typename GridView::template Codim<0>::EntityPointer ElementPointer;
+    typedef Dune::FieldMatrix<Scalar,1,1> BlockType;
+    typedef Dune::BCRSMatrix<BlockType> MatrixType;
+    typedef typename MatrixType::block_type MBlockType;
+    typedef typename MatrixType::RowIterator rowiterator;
+    typedef typename MatrixType::ColIterator coliterator;
+    typedef Dune::array<BoundaryConditions::Flags,1> BCBlockType;     // componentwise boundary conditions
+    typedef Dune::BlockVector< Dune::FieldVector<double,1> > SatType;
+    typedef Dumux::IntersectionMapper<GridView> IntersectionMapper;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum
+    {
+        pressEqIdx = Indices::pressEqIdx,
+    };
+
+    // return number of rows/columns
+    int size () const
+    {
+        return intersectionMapper_.size();
+    }
+
+public:
+    typedef MatrixType RepresentationType;
+
+    CROperatorAssemblerTwoPAdaptive (const GridView& gridview)
+    : gridView_(gridview), is_(gridView_.indexSet()), intersectionMapper_(gridView_)
+    {
+        A_.setBuildMode(MatrixType::random);
+    }
+
+    void initialize()
+    {
+        adapt();
+    }
+
+    void adapt()
+    {
+        intersectionMapper_.update();
+        A_.setSize(size(), size());
+        updateMatrix();
+    }
+
+    //! return const reference to operator matrix
+    const RepresentationType& operator* () const
+    {
+        return A_;
+    }
+
+    //! return reference to operator matrix
+    RepresentationType& operator* ()
+    {
+        return A_;
+    }
+
+    const IntersectionMapper& intersectionMapper()
+    {
+        return intersectionMapper_;
+    }
+
+    const IntersectionMapper& intersectionMapper() const
+    {
+        return intersectionMapper_;
+    }
+
+    /*! @brief Assemble global stiffness matrix
+
+      This method takes an object that can compute local stiffness matrices and
+      assembles the global linear system Au=f.
+
+      @param[in] loc the local assembler providing element stiffness and boundary conditions for all elements
+      @param[in,out] u solution, contains initial values on input, Dirichlet values are set. The
+      type of boundary condition for a node is inferred from the values returned
+      by the local assembler. A node is of Neumann type if all elements referring
+      to that node report a Neumann boundary condition, it is set to Dirichlet
+      if a least one element reports a process or Dirichlet boundary condition. The difference
+      between process and Dirichlet is that process always denotes a homogeneous Dirichlet
+      value.
+      @param[in] f right hand side is filled by this method
+
+      Note that the rows corresponding to nodes at the Dirichlet boundary are filled
+      with trivial equations of the form \f[1\cdot u_i = f_i \f] where \f$u_i\f$ and \f$f_i\f$ are both set to the
+      Dirichlet value at the \f$i\f$th node.
+
+    */
+    template <class LocalStiffness, class Vector>
+    void assemble (LocalStiffness& loc, Vector& u, Vector& f);
+
+    void updateMatrix();
+
+protected:
+    const GridView& gridView_;
+    const IS& is_;
+    IntersectionMapper intersectionMapper_;
+    RepresentationType A_;
+};
+
+template<class TypeTag>
+void CROperatorAssemblerTwoPAdaptive<TypeTag>::updateMatrix()
+{
+    // set size of all rows to zero
+    for (unsigned int i = 0; i < size(); i++)
+        A_.setrowsize(i, 0);
+
+    // build needs a flag for all entities of all codims
+    std::vector<bool> visited(size(), false);
+
+    int numElem = gridView_.size(0);
+
+    for (int elemIdx = 0; elemIdx < numElem; elemIdx++)
+    {
+        int numFaces = intersectionMapper_.size(elemIdx);
+        for (int faceIdx = 0; faceIdx < numFaces; faceIdx++)
+        {
+            int faceIdxGlobal = intersectionMapper_.map(elemIdx, faceIdx);
+            if (!visited[faceIdxGlobal])
+            {
+                A_.incrementrowsize(faceIdxGlobal);
+                visited[faceIdxGlobal] = true;
+            }
+            for (int k = 0; k < numFaces-1; k++) {
+                A_.incrementrowsize(faceIdxGlobal);
+            }
+
+        }
+
+    }
+
+    A_.endrowsizes();
+
+    // clear the flags for the next round, actually that is not necessary because addindex takes care of this
+    for (int i = 0; i < size(); i++)
+        visited[i] = false;
+
+    for (int elemIdx = 0; elemIdx < numElem; elemIdx++)
+    {
+        int numFaces = intersectionMapper_.size(elemIdx);
+        for (int faceIdx = 0; faceIdx < numFaces; faceIdx++)
+        {
+            int faceIdxGlobalI = intersectionMapper_.map(elemIdx, faceIdx);
+            if (!visited[faceIdxGlobalI])
+            {
+                A_.addindex(faceIdxGlobalI,faceIdxGlobalI);
+                visited[faceIdxGlobalI] = true;
+            }
+            for (int k = 0; k < numFaces; k++)
+                if (k != faceIdx) {
+                    int faceIdxGlobalJ = intersectionMapper_.map(elemIdx, k);
+                    A_.addindex(faceIdxGlobalI, faceIdxGlobalJ);
+                }
+
+        }
+
+    }
+
+    A_.endindices();
+}
+
+template<class TypeTag>
+template <class LocalStiffness, class Vector>
+void CROperatorAssemblerTwoPAdaptive<TypeTag>::assemble(LocalStiffness& loc, Vector& u, Vector& f)
+{
+
+    // check size
+    if (u.N()!=A_.M() || f.N()!=A_.N())
+        DUNE_THROW(Dune::MathError,"CROperatorAssemblerTwoPAdaptive::assemble(): size mismatch");
+    // clear global stiffness matrix and right hand side
+    A_ = 0;
+    f = 0;
+
+    // allocate flag vector to hold flags for essential boundary conditions
+    std::vector<BCBlockType> essential(intersectionMapper_.size());
+    for (typename std::vector<BCBlockType>::size_type i=0; i<essential.size(); i++)
+            essential[i][0] = BoundaryConditions::neumann;
+
+    // local to global id mapping (do not ask vertex mapper repeatedly
+    std::vector<int> local2Global(2*dim);
+
+    // run over all leaf elements
+    ElementIterator eendit = gridView_.template end<0>();
+    for (ElementIterator eIt = gridView_.template begin<0>(); eIt!=eendit; ++eIt)
+    {
+        // build local stiffness matrix for CR elements
+        // inludes rhs and boundary condition information
+        loc.assemble(*eIt, 1); // assemble local stiffness matrix
+
+        int globalIdx = intersectionMapper_.map(*eIt);
+
+        unsigned int numFaces = intersectionMapper_.size(globalIdx);
+        local2Global.resize(numFaces);
+
+        for (int i = 0; i < numFaces; i++)
+        {
+                int idx = intersectionMapper_.map(*eIt, i);
+                local2Global[i] = idx;
+        }
+
+        // accumulate local matrix into global matrix for non-hanging nodes
+        for (int i=0; i<numFaces; i++) // loop over rows, i.e. test functions
+        {
+            // accumulate matrix
+            for (int j=0; j<numFaces; j++)
+            {
+                // the standard entry
+                A_[local2Global[i]][local2Global[j]] += loc.mat(i,j);
+            }
+
+            // essential boundary condition and rhs
+            if (loc.bc(i).isDirichlet(pressEqIdx))
+            {
+                essential[local2Global[i]][0] = BoundaryConditions::dirichlet;
+                f[local2Global[i]][0] = loc.rhs(i)[0];
+            }
+            else
+                f[local2Global[i]][0] += loc.rhs(i)[0];
+        }
+
+    }
+    // run over all leaf elements
+    for (ElementIterator eIt = gridView_.template begin<0>(); eIt!=eendit; ++eIt)
+    {
+        int globalIdx = intersectionMapper_.map(*eIt);
+
+        unsigned int numFaces = intersectionMapper_.size(globalIdx);
+        local2Global.resize(numFaces);
+
+        for (int i = 0; i < numFaces; i++)
+        {
+                int idx = intersectionMapper_.map(*eIt, i);
+                local2Global[i] = idx;
+        }
+
+        loc.completeRHS(*eIt, local2Global, f);
+    }
+
+    // put in essential boundary conditions
+    rowiterator endi=A_.end();
+    for (rowiterator i=A_.begin(); i!=endi; ++i)
+    {
+        // muck up extra rows
+        if ((int) i.index() >= (int) size())
+        {
+            coliterator endj=(*i).end();
+            for (coliterator j=(*i).begin(); j!=endj; ++j)
+            {
+                (*j) = 0;
+                if (j.index()==i.index())
+                    (*j)[0][0] = 1;
+            }
+            f[i.index()] = 0;
+            continue;
+        }
+
+        // insert dirichlet ans processor boundary conditions
+        if (essential[i.index()][0]!=BoundaryConditions::neumann)
+        {
+            coliterator endj=(*i).end();
+            for (coliterator j=(*i).begin(); j!=endj; ++j)
+                if (j.index()==i.index())
+                {
+                    (*j)[0][0] = 1;
+                }
+                else
+                {
+                    (*j)[0][0] = 0;
+                }
+            u[i.index()][0] = f[i.index()][0];
+        }
+    }
+}
+
+template<class GridView>
+class IntersectionMapper
+{
+    // mapper: one data element in every entity
+    template<int dim>
+    struct ElementLayout
+    {
+        bool contains (Dune::GeometryType gt)
+        {
+            return gt.dim() == dim;
+        }
+    };
+
+    typedef typename GridView::Grid Grid;
+    enum {dim=Grid::dimension};
+    typedef typename Grid::template Codim<0>::Entity Element;
+    typedef typename Grid::template Codim<0>::EntityPointer ElementPointer;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+    typedef typename GridView::Intersection Intersection;
+    typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView,ElementLayout> ElementMapper;
+
+
+
+public:
+    IntersectionMapper(const GridView& gridview)
+    : gridView_(gridview), elementMapper_(gridView_), size_(gridView_.size(1)), intersectionMapGlobal_(gridView_.size(0)), intersectionMapLocal_(gridView_.size(0))
+    {
+        ElementIterator eIt = gridView_.template begin<0>();
+
+        int faceIdx = 0;
+
+        IntersectionIterator isItEnd = gridView_.iend(*eIt);
+        for (IntersectionIterator isIt = gridView_.ibegin(*eIt); isIt != isItEnd; ++isIt)
+        {
+            int idxInInside = isIt->indexInInside();
+
+            standardLocalIdxMap_[idxInInside] = faceIdx;
+
+            faceIdx++;
+        }
+    }
+
+    const ElementMapper& elementMapper() const
+    {
+        return elementMapper_;
+    }
+
+    int map(const Element& element) const
+    {
+        return elementMapper_.map(element);
+    }
+
+    int map(int elemIdx, int faceIdx)
+    {
+        return intersectionMapGlobal_[elemIdx][faceIdx];
+    }
+
+    int map(int elemIdx, int faceIdx) const
+    {
+        return (intersectionMapGlobal_[elemIdx].find(faceIdx))->second;//use find() for const function!
+    }
+
+    int map(const Element& element, int faceIdx)
+    {
+        return intersectionMapGlobal_[map(element)][faceIdx];
+    }
+
+    int map(const Element& element, int faceIdx) const
+    {
+        return intersectionMapGlobal_[map(element)].find(faceIdx)->second;//use find() for const function!
+    }
+
+    int maplocal(int elemIdx, int faceIdx)
+    {
+        return intersectionMapLocal_[elemIdx][faceIdx];
+    }
+
+    int maplocal(int elemIdx, int faceIdx) const
+    {
+        return (intersectionMapLocal_[elemIdx].find(faceIdx))->second;//use find() for const function!
+    }
+
+
+    int maplocal(const Element& element, int faceIdx)
+    {
+        return intersectionMapLocal_[map(element)][faceIdx];
+    }
+
+    int maplocal(const Element& element, int faceIdx) const
+    {
+        return (intersectionMapLocal_[map(element)].find(faceIdx))->second;//use find() for const function!
+    }
+
+    // return number intersections
+    unsigned int size () const
+    {
+        return size_;
+    }
+
+    unsigned int size (int elemIdx) const
+    {
+        return intersectionMapLocal_[elemIdx].size();
+    }
+
+    unsigned int size (const Element& element) const
+    {
+        return intersectionMapLocal_[map(element)].size();
+    }
+
+    void update()
+    {
+        elementMapper_.update();
+
+        intersectionMapGlobal_.clear();
+        intersectionMapGlobal_.resize(elementMapper_.size());
+        intersectionMapLocal_.clear();
+        intersectionMapLocal_.resize(elementMapper_.size());
+
+        ElementIterator eItEnd = gridView_.template end<0>();
+        for (ElementIterator eIt = gridView_.template begin<0>(); eIt != eItEnd; ++eIt)
+        {
+            int globalIdx = map(*eIt);
+
+            int faceIdx = 0;
+            // run through all intersections with neighbors
+            IntersectionIterator isItEnd = gridView_.iend(*eIt);
+            for (IntersectionIterator isIt = gridView_.ibegin(*eIt); isIt != isItEnd; ++isIt)
+            {
+                int indexInInside = isIt->indexInInside();
+                intersectionMapLocal_[globalIdx][faceIdx] = indexInInside;
+
+                faceIdx++;
+            }
+        }
+
+        int globalIntersectionIdx = 0;
+        for (ElementIterator eIt = gridView_.template begin<0>(); eIt != eItEnd; ++eIt)
+        {
+            int globalIdx = map(*eIt);
+
+            int faceIdx = 0;
+            // run through all intersections with neighbors
+            IntersectionIterator isItEnd = gridView_.iend(*eIt);
+            for (IntersectionIterator isIt = gridView_.ibegin(*eIt); isIt != isItEnd; ++isIt)
+            {
+                if (isIt->neighbor())
+                {
+                    ElementPointer neighbor = isIt->outside();
+                    int globalIdxNeighbor = map(*neighbor);
+
+                    if (eIt->level() > neighbor->level() || (eIt->level() == neighbor->level() && globalIdx < globalIdxNeighbor))
+                    {
+
+                        int faceIdxNeighbor = 0;
+                        if (size(globalIdxNeighbor) == 2 * dim)
+                        {
+                            faceIdxNeighbor = standardLocalIdxMap_[isIt->indexInOutside()];
+                        }
+                        else
+                        {
+                            IntersectionIterator isItNEnd = gridView_.iend(*neighbor);
+                            for (IntersectionIterator isItN = gridView_.ibegin(*neighbor); isItN != isItNEnd; ++isItN)
+                            {
+                                if (isItN->neighbor())
+                                {
+                                    if (isItN->outside() == eIt)
+                                    {
+                                        break;
+                                    }
+                                }
+                                faceIdxNeighbor++;
+                            }
+                        }
+
+                        intersectionMapGlobal_[globalIdx][faceIdx] = globalIntersectionIdx;
+                        intersectionMapGlobal_[globalIdxNeighbor][faceIdxNeighbor] = globalIntersectionIdx;
+                        globalIntersectionIdx ++;
+                    }
+                }
+                else
+                {
+                    intersectionMapGlobal_[globalIdx][faceIdx] = globalIntersectionIdx;
+                    globalIntersectionIdx ++;
+                }
+                faceIdx++;
+            }
+        }
+        size_ = globalIntersectionIdx;
+    }
+
+protected:
+    const GridView& gridView_;
+    ElementMapper elementMapper_;
+    unsigned int size_;
+    std::vector<std::map<int, int> > intersectionMapGlobal_;
+    std::vector<std::map<int, int> > intersectionMapLocal_;
+    std::map<int, int> standardLocalIdxMap_;
+};
+
+}
+
+#endif
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimetic2p.hh b/dumux/decoupled/2p/diffusion/mimetic/mimetic2p.hh
new file mode 100644
index 0000000000..c0e936867e
--- /dev/null
+++ b/dumux/decoupled/2p/diffusion/mimetic/mimetic2p.hh
@@ -0,0 +1,747 @@
+/*****************************************************************************
+ *   Copyright (C) 2011 by Markus Wolff                                      *
+ *   Copyright (C) 2008-2009 by Bernd Flemisch                               *
+ *   Institute for Modelling Hydraulic and Environmental Systems             *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Local stiffness matrix for the diffusion equation discretized by mimetic FD
+ */
+#ifndef DUMUX_MIMETIC2P_HH
+#define DUMUX_MIMETIC2P_HH
+
+#include<map>
+#include<iostream>
+#include<iomanip>
+#include<fstream>
+#include<vector>
+#include<sstream>
+
+#include<dune/common/exceptions.hh>
+#include<dune/grid/common/grid.hh>
+#include<dune/geometry/type.hh>
+#include<dune/geometry/quadraturerules.hh>
+
+#include<dumux/common/boundaryconditions.hh>
+
+#include <dune/common/dynvector.hh>
+
+namespace Dumux
+{
+/*!
+ *  \ingroup Mimetic2p
+ */
+/**
+ * @brief compute local stiffness matrix for conforming finite elements for the full 2-phase pressure equation
+ *
+ */
+
+//! A class for computing local stiffness matrices
+/*! A class for computing local stiffness matrix for the full 2-phase pressure equation
+ */
+template<class TypeTag>
+class MimeticTwoPLocalStiffness: public LocalStiffness<TypeTag, 1>
+{
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    // grid types
+    enum
+    {
+        dim = GridView::dimension
+    };
+    enum
+    {
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        pressureIdx = Indices::pressureIdx,
+        saturationIdx = Indices::saturationIdx,
+        pressEqIdx = Indices::pressEqIdx,
+        satEqIdx = Indices::satEqIdx,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
+    };
+    enum
+    {
+        pw = Indices::pressureW,
+        pn = Indices::pressureNW,
+        pglobal = Indices::pressureGlobal,
+        Sw = Indices::saturationW,
+        Sn = Indices::saturationNW,
+        vw = Indices::velocityW,
+        vn = Indices::velocityNW,
+        pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation), //!< gives kind of pressure used (\f$ 0 = p_w\f$, \f$ 1 = p_n\f$, \f$ 2 = p_{global}\f$)
+        saturationType = GET_PROP_VALUE(TypeTag, SaturationFormulation) //!< gives kind of saturation used (\f$ 0 = S_w\f$, \f$ 1 = S_n\f$)
+    };
+
+    typedef typename GridView::Grid Grid;
+    typedef typename GridView::Traits::template Codim<0>::Entity Element;
+    typedef typename GridView::Traits::template Codim<0>::EntityPointer ElementPointer;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+
+    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
+    typedef typename GET_PROP(TypeTag, SolutionTypes) SolutionTypes;
+    typedef typename SolutionTypes::PrimaryVariables PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+
+public:
+    // define the number of components of your system, this is used outside
+    // to allocate the correct size of (dense) blocks with a FieldMatrix
+    enum
+    {
+        m = 1
+    };
+    enum
+    {
+        size = 2 * dim
+    };
+
+    //! Constructor
+    MimeticTwoPLocalStiffness(Problem& problem,  bool levelBoundaryAsDirichlet,
+            const GridView& gridView, bool procBoundaryAsDirichlet = true) :
+            problem_(problem), gridView_(gridView), maxError_(0), timeStep_(1)
+    {
+        ErrorTermFactor_ = GET_PARAM(TypeTag, Scalar, ImpetErrorTermFactor);
+        ErrorTermLowerBound_ = GET_PARAM(TypeTag, Scalar, ImpetErrorTermLowerBound);
+        ErrorTermUpperBound_ = GET_PARAM(TypeTag, Scalar, ImpetErrorTermUpperBound);
+
+        density_[wPhaseIdx] = 0.0;
+        density_[nPhaseIdx] = 0.0;
+        viscosity_[wPhaseIdx] =0.0;
+        viscosity_[nPhaseIdx] = 0.0;
+    }
+
+    void initialize()
+    {
+        ElementIterator element = problem_.gridView().template begin<0>();
+        FluidState fluidState;
+        fluidState.setPressure(wPhaseIdx, problem_.referencePressure(*element));
+        fluidState.setPressure(nPhaseIdx, problem_.referencePressure(*element));
+        fluidState.setTemperature(problem_.temperature(*element));
+        fluidState.setSaturation(wPhaseIdx, 1.);
+        fluidState.setSaturation(nPhaseIdx, 0.);
+        density_[wPhaseIdx] = FluidSystem::density(fluidState, wPhaseIdx);
+        density_[nPhaseIdx] = FluidSystem::density(fluidState, nPhaseIdx);
+        viscosity_[wPhaseIdx] = FluidSystem::viscosity(fluidState, wPhaseIdx);
+        viscosity_[nPhaseIdx] = FluidSystem::viscosity(fluidState, nPhaseIdx);
+
+        int size = gridView_.size(0);
+        rhs_.resize(size , 0.);
+        W_.resize(size);
+    }
+
+    void reset()
+    {
+        rhs_ = 0;
+        maxError_ = 0;
+        timeStep_ = 1;
+    }
+
+    void setErrorInfo(Scalar maxErr, Scalar dt)
+    {
+        maxError_ = maxErr;
+        timeStep_ = dt;
+    }
+
+    //! assemble local stiffness matrix for given element and order
+    /*! On exit the following things have been done:
+     - The stiffness matrix for the given entity and polynomial degree has been assembled and is
+     accessible with the mat() method.
+     - The boundary conditions have been evaluated and are accessible with the bc() method
+     - The right hand side has been assembled. It contains either the value of the essential boundary
+     condition or the assembled source term and neumann boundary condition. It is accessible via the rhs() method.
+     @param[in]  element a codim 0 entity reference
+     @param[in]  k order of CR basis (only k = 1 is implemented)
+     */
+    void assemble(const Element& element, int k = 1)
+    {
+        unsigned int numFaces = element.template count<1>();
+        this->setcurrentsize(numFaces);
+
+        // clear assemble data
+        for (int i = 0; i < numFaces; i++)
+        {
+            this->b[i] = 0;
+            this->bctype[i].reset();
+            for (int j = 0; j < numFaces; j++)
+                this->A[i][j] = 0;
+        }
+
+        assembleV(element, k);
+        assembleBC(element, k);
+    }
+
+    // TODO/FIXME: this is only valid for linear problems where
+    // the local stiffness matrix is independend of the current
+    // solution. We need to implement this properly, but this
+    // should at least make the thing compile...
+    typedef Dune::FieldVector<Scalar, m> VBlockType;
+    void assemble(const Element &cell, const Dune::BlockVector<VBlockType>& localSolution, int orderOfShapeFns = 1)
+    {
+        assemble(cell, orderOfShapeFns);
+    }
+
+    //! assemble only boundary conditions for given element
+    /*! On exit the following things have been done:
+     - The boundary conditions have been evaluated and are accessible with the bc() method
+     - The right hand side contains either the value of the essential boundary
+     condition or the assembled neumann boundary condition. It is accessible via the rhs() method.
+     @param[in]  element a codim 0 entity reference
+     @param[in]  k order of CR basis
+     */
+    void assembleBoundaryCondition(const Element& element, int k = 1)
+    {
+        unsigned int numFaces = element.template count<1>();
+        this->setcurrentsize(numFaces);
+
+        // clear assemble data
+        for (int i = 0; i < numFaces; i++)
+        {
+            this->b[i] = 0;
+            this->bctype[i].reset();
+        }
+
+        assembleBC(element, k);
+    }
+
+    template<class Vector>
+    void completeRHS(const Element& element, Dune::FieldVector<int, 2*dim>& local2Global, Vector& f)
+    {
+        int globalIdx = problem_.variables().index(element);
+        unsigned int numFaces = element.template count<1>();
+
+        Dune::FieldVector<Scalar, 2 * dim> F(0.);
+        Scalar dInv = 0.;
+        computeReconstructionMatrices(element, W_[globalIdx], F, dInv);
+
+        for (int i = 0; i < numFaces; i++)
+        {
+            if (!this->bc(i).isDirichlet(pressEqIdx))
+                f[local2Global[i]][0] += (dInv * F[i] * rhs_[globalIdx]);
+        }
+    }
+
+    Scalar constructPressure(const Element& element, Dune::FieldVector<Scalar,2*dim>& pressTrace)
+    {
+        int globalIdx = problem_.variables().index(element);
+        unsigned int numFaces = element.template count<1>();
+        Scalar volume = element.geometry().volume();
+
+        PrimaryVariables sourceVec(0.0);
+        problem_.source(sourceVec, element);
+        Scalar qmean = volume * (sourceVec[wPhaseIdx]/density_[wPhaseIdx] + sourceVec[nPhaseIdx]/density_[nPhaseIdx]);
+        qmean += rhs_[globalIdx];
+
+        Dune::FieldVector<Scalar, 2 * dim> F(0.);
+        Scalar dInv = 0.;
+        computeReconstructionMatrices(element, W_[globalIdx], F, dInv);
+
+        return (dInv*(qmean + (F*pressTrace)));
+    }
+
+    void constructVelocity(const Element& element, Dune::FieldVector<Scalar,2*dim>& vel, Dune::FieldVector<Scalar,2*dim>& pressTrace, Scalar press)
+    {
+        int globalIdx = problem_.variables().index(element);
+
+        Dune::FieldVector<Scalar, 2 * dim> faceVol(0);
+        IntersectionIterator isItEnd = gridView_.iend(element);
+        for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+        {
+            faceVol[isIt->indexInInside()] = isIt->geometry().volume();
+        }
+
+        vel = 0;
+        for (int i = 0; i < 2*dim; i++)
+            for (int j = 0; j < 2*dim; j++)
+                vel[i] += W_[globalIdx][i][j]*faceVol[j]*(press - pressTrace[j]);
+    }
+
+    void constructVelocity(const Element& element, int faceIdx, Scalar& vel, Dune::FieldVector<Scalar,2*dim>& pressTrace, Scalar press)
+    {
+        int globalIdx = problem_.variables().index(element);
+
+        Dune::FieldVector<Scalar, 2 * dim> faceVol(0);
+        IntersectionIterator isItEnd = gridView_.iend(element);
+        for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+        {
+            faceVol[isIt->indexInInside()] = isIt->geometry().volume();
+        }
+
+        vel = 0;
+            for (int j = 0; j < 2*dim; j++)
+                vel += W_[globalIdx][faceIdx][j]*faceVol[j]*(press - pressTrace[j]);
+    }
+
+    void computeReconstructionMatrices(const Element& element, const Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim>& W, Dune::FieldVector<Scalar, 2 * dim>& F, Scalar& dInv)
+    {
+        Dune::FieldVector<Scalar, 2 * dim> c(0);
+        Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim> Pi(0);
+
+        IntersectionIterator isItEnd = gridView_.iend(element);
+        for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+        {
+            // local number of facet
+            int idx = isIt->indexInInside();
+
+            Scalar faceVol = isIt->geometry().volume();
+
+            // Corresponding to the element under consideration,
+            // calculate the part of the matrix C coupling velocities and element pressures.
+            // This is just a row vector of size numFaces.
+            // scale with volume
+            c[idx] = faceVol;
+            // Set up the element part of the matrix \Pi coupling velocities
+            // and pressure-traces. This is a diagonal matrix with entries given by faceVol.
+            Pi[idx][idx] = faceVol;
+        }
+
+        // Calculate the element part of the matrix D^{-1} = (c W c^T)^{-1} which is just a scalar value.
+        Dune::FieldVector<Scalar, 2 * dim> Wc(0);
+        W.umv(c, Wc);
+        dInv = 1.0 / (c * Wc);
+
+        // Calculate the element part of the matrix F = Pi W c^T which is a column vector.
+        F = 0;
+        Pi.umv(Wc, F);
+    }
+
+    void assembleElementMatrices(const Element& element, Dune::FieldVector<Scalar, 2 * dim>& faceVol,
+    Dune::FieldVector<Scalar, 2 * dim>& F,
+    Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim>& Pi,
+    Scalar& dInv,
+    Scalar& qmean);
+
+
+    const Problem& problem() const
+    {
+        return problem_;
+    }
+
+private:
+    void assembleV(const Element& element, int k);
+
+    void assembleBC(const Element& element, int k);
+
+    Scalar evaluateErrorTerm(CellData& cellData)
+    {
+        //error term for incompressible models to correct unphysical saturation over/undershoots due to saturation transport
+        // error reduction routine: volumetric error is damped and inserted to right hand side
+        Scalar sat = 0;
+        switch (saturationType)
+        {
+        case Sw:
+            sat = cellData.saturation(wPhaseIdx);
+            break;
+        case Sn:
+            sat = cellData.saturation(nPhaseIdx);
+            break;
+        }
+
+        Scalar error = (sat > 1.0) ? sat - 1.0 : 0.0;
+        if (sat < 0.0)
+        {
+            error = sat;
+        }
+        error /= timeStep_;
+
+        Scalar errorAbs = std::abs(error);
+
+        if ((errorAbs * timeStep_ > 1e-6) && (errorAbs > ErrorTermLowerBound_ * maxError_)
+                && (!problem_.timeManager().willBeFinished()))
+        {
+            return ErrorTermFactor_ * error;
+        }
+        return 0.0;
+    }
+
+private:
+    Problem& problem_;
+    GridView gridView_;
+    Dune::DynamicVector<Scalar> rhs_;
+    std::vector<Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim> > W_;
+    Scalar maxError_;
+    Scalar timeStep_;
+    Scalar ErrorTermFactor_; //!< Handling of error term: relaxation factor
+    Scalar ErrorTermLowerBound_; //!< Handling of error term: lower bound for error dampening
+    Scalar ErrorTermUpperBound_; //!< Handling of error term: upper bound for error dampening
+
+    Scalar density_[numPhases];
+    Scalar viscosity_[numPhases];
+};
+
+template<class TypeTag>
+void MimeticTwoPLocalStiffness<TypeTag>::assembleV(const Element& element, int k = 1)
+{
+    unsigned int numFaces = element.template count<1>();
+    this->setcurrentsize(numFaces);
+
+    int globalIdx = problem_.variables().index(element);
+
+    // The notation is borrowed from Aarnes/Krogstadt/Lie 2006, Section 3.4.
+    // The matrix W developed here corresponds to one element-associated
+    // block of the matrix B^{-1} there.
+    Dune::FieldVector<Scalar, 2 * dim> faceVol(0);
+    Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim> Pi(0.);
+    Dune::FieldVector<Scalar, 2 * dim> F(0.);
+    Scalar dInv = 0.;
+    Scalar qmean = 0.;
+    this->assembleElementMatrices(element, faceVol, F, Pi, dInv, qmean);
+
+    // Calculate the element part of the matrix Pi W Pi^T.
+    Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim> PiWPiT(W_[globalIdx]);
+    PiWPiT.rightmultiply(Pi);
+    PiWPiT.leftmultiply(Pi);
+
+    // Calculate the element part of the matrix F D^{-1} F^T.
+    Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim> FDinvFT(0);
+    for (int i = 0; i < numFaces; i++)
+        for (int j = 0; j < numFaces; j++)
+            FDinvFT[i][j] = dInv * F[i] * F[j];
+
+    // Calculate the element part of the matrix S = Pi W Pi^T - F D^{-1} F^T.
+    for (int i = 0; i < numFaces; i++)
+        for (int j = 0; j < numFaces; j++)
+            this->A[i][j] = PiWPiT[i][j] - FDinvFT[i][j];
+
+    // Calculate the source term F D^{-1} f
+    // NOT WORKING AT THE MOMENT
+    Scalar factor = dInv * qmean;
+    for (int i = 0; i < numFaces; i++)
+        this->b[i] = F[i] * factor;
+
+    //        std::cout << "faceVol = " << faceVol << std::endl << "W = " << std::endl << W << std::endl
+    //              << "c = " << c << std::endl << "Pi = " << std::endl << Pi << std::endl
+    //              << "dinv = " << dinv << std::endl << "F = " << F << std::endl;
+    //        std::cout << "dinvF = " << dinvF << ", q = " << qmean
+    //             << ", b = " << this->b[0] << ", " << this->b[1] << ", " << this->b[2] << ", " << this->b[3] << std::endl;
+}
+
+template<class TypeTag>
+void MimeticTwoPLocalStiffness<TypeTag>::assembleElementMatrices(const Element& element,
+        Dune::FieldVector<Scalar, 2 * dim>& faceVol,
+        Dune::FieldVector<Scalar, 2 * dim>& F,
+        Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim>& Pi,
+        Scalar& dInv,
+        Scalar& qmean)
+{
+    unsigned int numFaces = element.template count<1>();
+    this->setcurrentsize(numFaces);
+
+    // get global coordinate of cell center
+    Dune::FieldVector<Scalar, dim> centerGlobal = element.geometry().center();
+
+    int globalIdx = problem_.variables().index(element);
+
+    CellData& cellData = problem_.variables().cellData(globalIdx);
+
+    // cell volume
+    Scalar volume = element.geometry().volume();
+
+    // build the matrices R and ~N
+    Dune::FieldMatrix<Scalar, 2 * dim, dim> R(0), N(0);
+
+    //       std::cout << "element " << elemId << ": center " << centerGlobal << std::endl;;
+
+    //collect information needed for calculation of fluxes due to capillary-potential (pc + gravity!)
+    Scalar gravPotFace[2*dim];
+
+    Scalar gravPot = (problem_.bBoxMax() - centerGlobal) * problem_.gravity() * (density_[nPhaseIdx] - density_[wPhaseIdx]);
+
+    int i = -1;
+    IntersectionIterator isItEnd = gridView_.iend(element);
+    for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+    {
+        // local number of facet
+        i = isIt->indexInInside();
+
+        Dune::FieldVector<Scalar, dim> faceGlobal = isIt->geometry().center();
+        faceVol[i] = isIt->geometry().volume();
+
+        // get normal vector
+        const Dune::FieldVector<Scalar, dim>& unitOuterNormal = isIt->centerUnitOuterNormal();
+
+        N[i] = unitOuterNormal;
+
+        for (int k = 0; k < dim; k++)
+            // move origin to the center of gravity
+            R[i][k] = faceVol[i] * (faceGlobal[k] - centerGlobal[k]);
+
+        gravPotFace[i] = (problem_.bBoxMax() - faceGlobal) * problem_.gravity() * (density_[nPhaseIdx] - density_[wPhaseIdx]);
+    }
+
+    // proceed along the lines of Algorithm 1 from
+    // Brezzi/Lipnikov/Simonicini M3AS 2005
+    // (1) orthonormalize columns of the matrix R
+    Scalar norm = R[0][0] * R[0][0];
+    for (int i = 1; i < numFaces; i++)
+        norm += R[i][0] * R[i][0];
+    norm = sqrt(norm);
+    for (int i = 0; i < numFaces; i++)
+        R[i][0] /= norm;
+    Scalar weight = R[0][1] * R[0][0];
+    for (int i = 1; i < numFaces; i++)
+        weight += R[i][1] * R[i][0];
+    for (int i = 0; i < numFaces; i++)
+        R[i][1] -= weight * R[i][0];
+    norm = R[0][1] * R[0][1];
+    for (int i = 1; i < numFaces; i++)
+        norm += R[i][1] * R[i][1];
+    norm = sqrt(norm);
+    for (int i = 0; i < numFaces; i++)
+        R[i][1] /= norm;
+    if (dim == 3)
+    {
+        Scalar weight1 = R[0][2] * R[0][0];
+        Scalar weight2 = R[0][2] * R[0][1];
+        for (int i = 1; i < numFaces; i++)
+        {
+            weight1 += R[i][2] * R[i][0];
+            weight2 += R[i][2] * R[i][1];
+        }
+        for (int i = 0; i < numFaces; i++)
+            R[i][2] -= weight1 * R[i][0] + weight2 * R[i][1];
+        norm = R[0][2] * R[0][2];
+        for (int i = 1; i < numFaces; i++)
+            norm += R[i][2] * R[i][2];
+        norm = sqrt(norm);
+        for (int i = 0; i < numFaces; i++)
+            R[i][2] /= norm;
+    }
+    //      std::cout << "~R =\dim" << R;
+
+    // (2) Build the matrix ~D
+    Dune::FieldMatrix<Scalar, 2 * dim, 2 * dim> D(0);
+    for (int s = 0; s < numFaces; s++)
+    {
+        Dune::FieldVector<Scalar, 2 * dim> es(0);
+        es[s] = 1;
+        for (int k = 0; k < numFaces; k++)
+        {
+            D[k][s] = es[k];
+            for (int i = 0; i < dim; i++)
+            {
+                D[k][s] -= R[s][i] * R[k][i];
+            }
+        }
+    }
+
+//    std::cout<<"D = "<<D<<"\n";
+
+    // eval diffusion tensor, ASSUMING to be constant over each cell
+    Dune::FieldMatrix<Scalar, dim, dim> mobility(problem_.spatialParams().intrinsicPermeability(element));
+    mobility *= (cellData.mobility(wPhaseIdx) + cellData.mobility(nPhaseIdx));
+
+    Scalar traceMob = mobility[0][0];
+    for (int i = 1; i < dim; i++)
+        traceMob += mobility[i][i];
+    D *= 2.0 * traceMob / volume;
+    //      std::cout << "u~D =\dim" << D;
+
+    // (3) Build the matrix W = Minv
+    Dune::FieldMatrix<Scalar, 2 * dim, dim> NK(N);
+    NK.rightmultiply(mobility);
+
+    for (int i = 0; i < numFaces; i++)
+    {
+        for (int j = 0; j < numFaces; j++)
+        {
+            W_[globalIdx][i][j] = NK[i][0] * N[j][0];
+            for (int k = 1; k < dim; k++)
+                W_[globalIdx][i][j] += NK[i][k] * N[j][k];
+        }
+    }
+
+    W_[globalIdx] /= volume;
+    W_[globalIdx] += D;
+
+    //       std::cout << "W = \dim" << W;
+
+    // Now the notation is borrowed from Aarnes/Krogstadt/Lie 2006, Section 3.4.
+    // The matrix W developed so far corresponds to one element-associated
+    // block of the matrix B^{-1} there.
+
+    // Corresponding to the element under consideration,
+    // calculate the part of the matrix C coupling velocities and element pressures.
+    // This is just a row vector of size numFaces.
+    // scale with volume
+    Dune::FieldVector<Scalar, 2 * dim> c(0);
+    for (int i = 0; i < numFaces; i++)
+        c[i] = faceVol[i];
+
+    // Set up the element part of the matrix \Pi coupling velocities
+    // and pressure-traces. This is a diagonal matrix with entries given by faceVol.
+    for (int i = 0; i < numFaces; i++)
+        Pi[i][i] = faceVol[i];
+
+    // Calculate the element part of the matrix D^{-1} = (c W c^T)^{-1} which is just a scalar value.
+    Dune::FieldVector<Scalar, 2 * dim> Wc(0);
+    W_[globalIdx].umv(c, Wc);
+    dInv = 1.0 / (c * Wc);
+
+    // Calculate the element part of the matrix F = Pi W c^T which is a column vector.
+    F = 0;
+    Pi.umv(Wc, F);
+    //      std::cout << "Pi = \dim" << Pi << "c = " << c << ", F = " << F << std::endl;
+
+    //accumulate fluxes due to capillary potential (pc + gravity!)
+    for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+    {
+        int idx = isIt->indexInInside();
+
+        Scalar fracFlow = 0;
+
+        Scalar flux = 0;
+        for (int j = 0; j < 2 * dim; j++)
+            flux += W_[globalIdx][idx][j] * faceVol[j] * (gravPot - gravPotFace[j]);
+
+        //it is enough to evaluate the capillary/gravity flux for neighbors -> not needed anyway at the boundaries!
+        if (isIt->neighbor())
+        {
+            ElementPointer neighbor = isIt->outside();
+            int globalIdxNeighbor = problem_.variables().index(*neighbor);
+            if (flux >= 0.)
+            {
+                switch (pressureType)
+                {
+                case pw:
+                {
+                    fracFlow = cellData.fracFlowFunc(nPhaseIdx);
+                    break;
+                }
+                case pn:
+                {
+                    fracFlow = -cellData.fracFlowFunc(wPhaseIdx);
+                    break;
+                }
+                }
+
+
+                rhs_[globalIdx] -= (faceVol[idx] * fracFlow * flux);
+                rhs_[globalIdxNeighbor] += (faceVol[idx] * fracFlow * flux);
+            }
+        }
+        else if (isIt->boundary())
+        {
+            BoundaryTypes bctype;
+            problem_.boundaryTypes(bctype, *isIt);
+
+            if (bctype.isDirichlet(pressEqIdx))
+            {
+                if (flux > 0. || !bctype.isDirichlet(satEqIdx))
+                {
+                    switch (pressureType)
+                    {
+                    case pw:
+                    {
+                        fracFlow = cellData.fracFlowFunc(nPhaseIdx);
+                        break;
+                    }
+                    case pn:
+                    {
+                        fracFlow = -cellData.fracFlowFunc(wPhaseIdx);
+                        break;
+                    }
+                    }
+                }
+                else if (flux < 0. && bctype.isDirichlet(satEqIdx))
+                {
+                    PrimaryVariables boundValues(0.0);
+                    problem_.dirichlet(boundValues, *isIt);
+
+                    Scalar krw = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element),
+                            boundValues[saturationIdx]);
+                    Scalar krn = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element),
+                            boundValues[saturationIdx]);
+
+                    switch (pressureType)
+                    {
+                    case pw:
+                    {
+                        fracFlow = krn / viscosity_[nPhaseIdx]
+                                / (krw / viscosity_[wPhaseIdx] + krn / viscosity_[nPhaseIdx]);
+                        break;
+                    }
+                    case pn:
+                    {
+                        fracFlow = -krw / viscosity_[wPhaseIdx]
+                                / (krw / viscosity_[wPhaseIdx] + krn / viscosity_[nPhaseIdx]);
+                        break;
+                    }
+                    }
+                }
+
+                rhs_[globalIdx] -= (faceVol[idx] * fracFlow * flux);
+            }
+        }
+    }
+
+    PrimaryVariables sourceVec(0.0);
+    problem_.source(sourceVec, element);
+    qmean = volume * (sourceVec[wPhaseIdx]/density_[wPhaseIdx] + sourceVec[nPhaseIdx]/density_[nPhaseIdx]);
+
+        qmean += evaluateErrorTerm(cellData) * volume;
+}
+
+template<class TypeTag>
+void MimeticTwoPLocalStiffness<TypeTag>::assembleBC(const Element& element, int k = 1)
+{
+    // evaluate boundary conditions via intersection iterator
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+
+    IntersectionIterator endIsIt = gridView_.iend(element);
+    for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != endIsIt; ++isIt)
+    {
+        int faceIndex = isIt->indexInInside();
+        if (isIt->boundary())
+        {
+            problem_.boundaryTypes(this->bctype[faceIndex], *isIt);
+            PrimaryVariables boundValues(0.0);
+
+            if (this->bctype[faceIndex].isNeumann(pressEqIdx))
+            {
+                int globalIdx = problem_.variables().index(element);
+
+                problem_.neumann(boundValues, *isIt);
+                Scalar J = (boundValues[wPhaseIdx]/density_[wPhaseIdx] + boundValues[nPhaseIdx]/density_[nPhaseIdx]);
+                this->b[faceIndex] -= J * isIt->geometry().volume();
+            }
+            else if (this->bctype[faceIndex].isDirichlet(pressEqIdx))
+            {
+                problem_.dirichlet(boundValues, *isIt);
+                if (pressureType == pw)
+                    this->b[faceIndex] = boundValues[pressureIdx] + (problem_.bBoxMax() - isIt->geometry().center()) * problem_.gravity() * density_[wPhaseIdx];
+                else if (pressureType == pn)
+                    this->b[faceIndex] = boundValues[pressureIdx] + (problem_.bBoxMax() - isIt->geometry().center()) * problem_.gravity() * density_[nPhaseIdx];
+                else
+                    this->b[faceIndex] = boundValues[pressureIdx];
+            }
+        }
+    }
+
+}
+
+/** @} */
+}
+#endif
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimetic2padaptive.hh b/dumux/decoupled/2p/diffusion/mimetic/mimetic2padaptive.hh
new file mode 100644
index 0000000000..90cb1be901
--- /dev/null
+++ b/dumux/decoupled/2p/diffusion/mimetic/mimetic2padaptive.hh
@@ -0,0 +1,775 @@
+/*****************************************************************************
+ *   Copyright (C) 2011 by Markus Wolff                                      *
+ *   Copyright (C) 2008-2009 by Bernd Flemisch                               *
+ *   Institute for Modelling Hydraulic and Environmental Systems             *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Local stiffness matrix for the diffusion equation discretized by mimetic FD
+ */
+#ifndef DUMUX_MIMETIC2PADAPTIVE_HH
+#define DUMUX_MIMETIC2PADAPTIVE_HH
+
+#include<map>
+#include<iostream>
+#include<iomanip>
+#include<fstream>
+#include<vector>
+#include<sstream>
+
+#include<dune/common/exceptions.hh>
+#include<dune/grid/common/grid.hh>
+#include<dune/geometry/type.hh>
+#include<dune/geometry/quadraturerules.hh>
+
+#include<dumux/common/boundaryconditions.hh>
+
+#include <dune/common/dynvector.hh>
+#include <dune/common/dynmatrix.hh>
+
+namespace Dumux
+{
+/*!
+ *  \ingroup Mimetic2p
+ */
+/**
+ * @brief compute local stiffness matrix for conforming finite elements for the full 2-phase pressure equation
+ *
+ */
+
+//! A class for computing local stiffness matrices
+/*! A class for computing local stiffness matrix for the full 2-phase pressure equation
+ */
+template<class TypeTag>
+class MimeticTwoPLocalStiffnessAdaptive: public LocalStiffness<TypeTag, 1>
+{
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    // grid types
+    enum
+    {
+        dim = GridView::dimension
+    };
+    enum
+    {
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        pressureIdx = Indices::pressureIdx,
+        saturationIdx = Indices::saturationIdx,
+        pressEqIdx = Indices::pressEqIdx,
+        satEqIdx = Indices::satEqIdx,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
+    };
+    enum
+    {
+        pw = Indices::pressureW,
+        pn = Indices::pressureNW,
+        pglobal = Indices::pressureGlobal,
+        Sw = Indices::saturationW,
+        Sn = Indices::saturationNW,
+        vw = Indices::velocityW,
+        vn = Indices::velocityNW,
+        pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation), //!< gives kind of pressure used (\f$ 0 = p_w\f$, \f$ 1 = p_n\f$, \f$ 2 = p_{global}\f$)
+        saturationType = GET_PROP_VALUE(TypeTag, SaturationFormulation) //!< gives kind of saturation used (\f$ 0 = S_w\f$, \f$ 1 = S_n\f$)
+    };
+
+    typedef typename GridView::Grid Grid;
+    typedef typename GridView::Traits::template Codim<0>::Entity Element;
+    typedef typename GridView::Traits::template Codim<0>::EntityPointer ElementPointer;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+
+    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
+    typedef typename GET_PROP(TypeTag, SolutionTypes) SolutionTypes;
+    typedef typename SolutionTypes::PrimaryVariables PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+
+    typedef Dumux::IntersectionMapper<GridView> IntersectionMapper;
+
+public:
+    // define the number of components of your system, this is used outside
+    // to allocate the correct size of (dense) blocks with a FieldMatrix
+    enum
+    {
+        m = 1
+    };
+    enum
+    {
+        size = 2 * dim
+    };
+
+    //! Constructor
+    MimeticTwoPLocalStiffnessAdaptive(Problem& problem,  bool levelBoundaryAsDirichlet,
+            const GridView& gridView, const IntersectionMapper& intersectionMapper,bool procBoundaryAsDirichlet = true) :
+            problem_(problem), gridView_(gridView), intersectionMapper_(intersectionMapper), maxError_(0), timeStep_(1)
+    {
+        int size = gridView_.size(0);
+        rhs_.resize(size , 0.);
+        W_.resize(size);
+        ErrorTermFactor_ = GET_PARAM(TypeTag, Scalar, ImpetErrorTermFactor);
+        ErrorTermLowerBound_ = GET_PARAM(TypeTag, Scalar, ImpetErrorTermLowerBound);
+        ErrorTermUpperBound_ = GET_PARAM(TypeTag, Scalar, ImpetErrorTermUpperBound);
+
+        density_[wPhaseIdx] = 0.0;
+        density_[nPhaseIdx] = 0.0;
+        viscosity_[wPhaseIdx] =0.0;
+        viscosity_[nPhaseIdx] = 0.0;
+    }
+
+    void initialize()
+    {
+        ElementIterator element = problem_.gridView().template begin<0>();
+        FluidState fluidState;
+        fluidState.setPressure(wPhaseIdx, problem_.referencePressure(*element));
+        fluidState.setPressure(nPhaseIdx, problem_.referencePressure(*element));
+        fluidState.setTemperature(problem_.temperature(*element));
+        fluidState.setSaturation(wPhaseIdx, 1.);
+        fluidState.setSaturation(nPhaseIdx, 0.);
+        density_[wPhaseIdx] = FluidSystem::density(fluidState, wPhaseIdx);
+        density_[nPhaseIdx] = FluidSystem::density(fluidState, nPhaseIdx);
+        viscosity_[wPhaseIdx] = FluidSystem::viscosity(fluidState, wPhaseIdx);
+        viscosity_[nPhaseIdx] = FluidSystem::viscosity(fluidState, nPhaseIdx);
+
+        adapt();
+    }
+
+    void adapt()
+    {
+        int size = gridView_.size(0);
+        rhs_.resize(size , 0.);
+        W_.resize(size);
+    }
+
+    void reset()
+    {
+        rhs_ = 0;
+        maxError_ = 0;
+        timeStep_ = 1;
+    }
+
+    void setErrorInfo(Scalar maxErr, Scalar dt)
+    {
+        maxError_ = maxErr;
+        timeStep_ = dt;
+    }
+
+    int numberOfFaces(int globalIdx)
+    {
+        return W_[globalIdx].N();
+    }
+
+    //! assemble local stiffness matrix for given element and order
+    /*! On exit the following things have been done:
+     - The stiffness matrix for the given entity and polynomial degree has been assembled and is
+     accessible with the mat() method.
+     - The boundary conditions have been evaluated and are accessible with the bc() method
+     - The right hand side has been assembled. It contains either the value of the essential boundary
+     condition or the assembled source term and neumann boundary condition. It is accessible via the rhs() method.
+     @param[in]  element a codim 0 entity reference
+     @param[in]  k order of CR basis (only k = 1 is implemented)
+     */
+    void assemble(const Element& element, int k = 1)
+    {
+        int numFaces = intersectionMapper_.size(element);
+
+        this->setcurrentsize(numFaces);
+
+        // clear assemble data
+        for (int i = 0; i < numFaces; i++)
+        {
+            this->b[i] = 0;
+            this->bctype[i].reset();
+            for (int j = 0; j < numFaces; j++)
+                this->A[i][j] = 0;
+        }
+
+        assembleV(element, numFaces, k);
+        assembleBC(element, k);
+    }
+
+    // TODO/FIXME: this is only valid for linear problems where
+    // the local stiffness matrix is independend of the current
+    // solution. We need to implement this properly, but this
+    // should at least make the thing compile...
+    typedef Dune::FieldVector<Scalar, m> VBlockType;
+    void assemble(const Element &cell, const Dune::BlockVector<VBlockType>& localSolution, int orderOfShapeFns = 1)
+    {
+        assemble(cell, orderOfShapeFns);
+    }
+
+    //! assemble only boundary conditions for given element
+    /*! On exit the following things have been done:
+     - The boundary conditions have been evaluated and are accessible with the bc() method
+     - The right hand side contains either the value of the essential boundary
+     condition or the assembled neumann boundary condition. It is accessible via the rhs() method.
+     @param[in]  element a codim 0 entity reference
+     @param[in]  k order of CR basis
+     */
+    void assembleBoundaryCondition(const Element& element, int k = 1)
+    {
+        int numFaces = intersectionMapper_.size(element);
+
+        // clear assemble data
+        for (int i = 0; i < numFaces; i++)
+        {
+            this->b[i] = 0;
+            this->bctype[i].reset();
+        }
+
+        assembleBC(element, k);
+    }
+
+    template<class Vector>
+    void completeRHS(const Element& element, std::vector<int>& local2Global, Vector& f)
+    {
+        int globalIdx = problem_.variables().index(element);
+
+        int numFaces = numberOfFaces(globalIdx);
+
+        Dune::DynamicVector<Scalar> F(numFaces);
+        Scalar dInv = 0.;
+        computeReconstructionMatrices(element, W_[globalIdx], F, dInv);
+
+        for (int i = 0; i < numFaces; i++)
+        {
+//            if (!this->bctype[i].isSet())
+                f[local2Global[i]][0] += (dInv * F[i] * rhs_[globalIdx]);
+        }
+    }
+
+    Scalar constructPressure(const Element& element, Dune::DynamicVector<Scalar>& pressTrace)
+    {
+        int globalIdx = problem_.variables().index(element);
+
+        int numFaces = numberOfFaces(globalIdx);
+
+        Scalar volume = element.geometry().volume();
+
+        PrimaryVariables sourceVec(0.0);
+        problem_.source(sourceVec, element);
+        Scalar qmean = volume * (sourceVec[wPhaseIdx]/density_[wPhaseIdx] + sourceVec[nPhaseIdx]/density_[nPhaseIdx]);
+        qmean += rhs_[globalIdx];
+
+        Dune::DynamicVector<Scalar> F(numFaces, 0.);
+        Scalar dInv = 0.;
+        computeReconstructionMatrices(element, W_[globalIdx], F, dInv);
+
+        return (dInv*(qmean + (F*pressTrace)));
+    }
+
+    void constructVelocity(const Element& element, Dune::DynamicVector<Scalar>& vel, Dune::DynamicVector<Scalar>& pressTrace, Scalar press)
+    {
+        int globalIdx = problem_.variables().index(element);
+
+        int numFaces = numberOfFaces(globalIdx);
+
+        Dune::DynamicVector<Scalar> faceVol(numFaces);
+
+        Dune::FieldVector<Scalar, 2*dim> faceVolumeReal(0.0);
+
+        int idx = 0;
+        IntersectionIterator isItEnd = gridView_.iend(element);
+        for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+        {
+            faceVol[idx] = isIt->geometry().volume();
+            int indexInInside = isIt->indexInInside();
+            faceVolumeReal[indexInInside] += faceVol[idx];
+
+            idx++;
+        }
+
+        vel = 0;
+        for (int i = 0; i < numFaces; i++)
+            for (int j = 0; j < numFaces; j++)
+                vel[i] += W_[globalIdx][i][j]*faceVol[j]*(press - pressTrace[j]);
+
+        for (int i = 0; i < numFaces; i++)
+        {
+                vel[i] *= faceVol[i]/faceVolumeReal[intersectionMapper_.maplocal(globalIdx, i)];
+        }
+
+    }
+
+    void computeReconstructionMatrices(const Element& element, const Dune::DynamicMatrix<Scalar>& W, Dune::DynamicVector<Scalar>& F, Scalar& dInv)
+    {
+        int globalIdx = problem_.variables().index(element);
+
+        int numFaces = numberOfFaces(globalIdx);
+
+        Dune::DynamicVector<Scalar> c(numFaces);
+        Dune::DynamicMatrix<Scalar> Pi(numFaces, numFaces);
+
+        int idx = 0;
+        IntersectionIterator isItEnd = gridView_.iend(element);
+        for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+        {
+            Scalar faceVol = isIt->geometry().volume();
+
+            // Corresponding to the element under consideration,
+            // calculate the part of the matrix C coupling velocities and element pressures.
+            // This is just a row vector of size numFaces.
+            // scale with volume
+            c[idx] = faceVol;
+            // Set up the element part of the matrix \Pi coupling velocities
+            // and pressure-traces. This is a diagonal matrix with entries given by faceVol.
+            Pi[idx][idx] = faceVol;
+            idx++;
+        }
+
+        // Calculate the element part of the matrix D^{-1} = (c W c^T)^{-1} which is just a scalar value.
+        Dune::DynamicVector<Scalar> Wc(numFaces);
+        W.umv(c, Wc);
+        dInv = 1.0 / (c * Wc);
+
+        // Calculate the element part of the matrix F = Pi W c^T which is a column vector.
+        F = 0;
+        Pi.umv(Wc, F);
+    }
+
+    void assembleElementMatrices(const Element& element,
+            Dune::DynamicVector<Scalar>& faceVol,
+            Dune::DynamicVector<Scalar>& F,
+            Dune::DynamicMatrix<Scalar>& Pi,
+    Scalar& dInv,
+    Scalar& qmean);
+
+
+    const Problem& problem() const
+    {
+        return problem_;
+    }
+
+private:
+    void assembleV(const Element& element, int numFaces, int k);
+
+    void assembleBC(const Element& element, int k);
+
+    Scalar evaluateErrorTerm(CellData& cellData)
+    {
+        //error term for incompressible models to correct unphysical saturation over/undershoots due to saturation transport
+        // error reduction routine: volumetric error is damped and inserted to right hand side
+        Scalar sat = 0;
+        switch (saturationType)
+        {
+        case Sw:
+            sat = cellData.saturation(wPhaseIdx);
+            break;
+        case Sn:
+            sat = cellData.saturation(nPhaseIdx);
+            break;
+        }
+
+        Scalar error = (sat > 1.0) ? sat - 1.0 : 0.0;
+        if (sat < 0.0)
+        {
+            error = sat;
+        }
+        error /= timeStep_;
+
+        Scalar errorAbs = std::abs(error);
+
+        if ((errorAbs * timeStep_ > 1e-6) && (errorAbs > ErrorTermLowerBound_ * maxError_)
+                && (!problem_.timeManager().willBeFinished()))
+        {
+            return ErrorTermFactor_ * error;
+        }
+        return 0.0;
+    }
+
+private:
+    Problem& problem_;
+    const GridView& gridView_;
+    const IntersectionMapper& intersectionMapper_;
+    Dune::DynamicVector<Scalar> rhs_;
+    std::vector<Dune::DynamicMatrix<Scalar> > W_;
+    Scalar maxError_;
+    Scalar timeStep_;
+    Scalar ErrorTermFactor_; //!< Handling of error term: relaxation factor
+    Scalar ErrorTermLowerBound_; //!< Handling of error term: lower bound for error dampening
+    Scalar ErrorTermUpperBound_; //!< Handling of error term: upper bound for error dampening
+
+    Scalar density_[numPhases];
+    Scalar viscosity_[numPhases];
+};
+
+template<class TypeTag>
+void MimeticTwoPLocalStiffnessAdaptive<TypeTag>::assembleV(const Element& element, int numFaces, int k = 1)
+{
+    int globalIdx = problem_.variables().index(element);
+
+    // The notation is borrowed from Aarnes/Krogstadt/Lie 2006, Section 3.4.
+    // The matrix W developed here corresponds to one element-associated
+    // block of the matrix B^{-1} there.
+    W_[globalIdx].resize(numFaces, numFaces);
+    Dune::DynamicVector<Scalar> faceVol(numFaces);
+    Dune::DynamicMatrix<Scalar> Pi(numFaces, numFaces);
+    Dune::DynamicVector<Scalar> F(numFaces);
+    Scalar dInv = 0.;
+    Scalar qmean = 0.;
+    this->assembleElementMatrices(element, faceVol, F, Pi, dInv, qmean);
+
+    // Calculate the element part of the matrix Pi W Pi^T.
+    Dune::DynamicMatrix<Scalar> PiWPiT(W_[globalIdx]);
+    PiWPiT.rightmultiply(Pi);
+    PiWPiT.leftmultiply(Pi);
+
+    // Calculate the element part of the matrix F D^{-1} F^T.
+    Dune::DynamicMatrix<Scalar> FDinvFT(numFaces, numFaces);
+    for (int i = 0; i < numFaces; i++)
+        for (int j = 0; j < numFaces; j++)
+            FDinvFT[i][j] = dInv * F[i] * F[j];
+
+    // Calculate the element part of the matrix S = Pi W Pi^T - F D^{-1} F^T.
+    for (int i = 0; i < numFaces; i++)
+        for (int j = 0; j < numFaces; j++)
+            this->A[i][j] = PiWPiT[i][j] - FDinvFT[i][j];
+
+    // Calculate the source term F D^{-1} f
+    // NOT WORKING AT THE MOMENT
+    Scalar factor = dInv * qmean;
+    for (int i = 0; i < numFaces; i++)
+        this->b[i] = F[i] * factor;
+
+    //        std::cout << "faceVol = " << faceVol << std::endl << "W = " << std::endl << W << std::endl
+    //              << "c = " << c << std::endl << "Pi = " << std::endl << Pi << std::endl
+    //              << "dinv = " << dinv << std::endl << "F = " << F << std::endl;
+    //        std::cout << "dinvF = " << dinvF << ", q = " << qmean
+    //             << ", b = " << this->b[0] << ", " << this->b[1] << ", " << this->b[2] << ", " << this->b[3] << std::endl;
+}
+
+template<class TypeTag>
+void MimeticTwoPLocalStiffnessAdaptive<TypeTag>::assembleElementMatrices(const Element& element,
+        Dune::DynamicVector<Scalar>& faceVol,
+        Dune::DynamicVector<Scalar>& F,
+        Dune::DynamicMatrix<Scalar>& Pi,
+        Scalar& dInv,
+        Scalar& qmean)
+{
+    // get global coordinate of cell center
+    const Dune::FieldVector<Scalar, dim>& centerGlobal = element.geometry().center();
+
+    int globalIdx = problem_.variables().index(element);
+
+    CellData& cellData = problem_.variables().cellData(globalIdx);
+
+    int numFaces = intersectionMapper_.size(globalIdx);
+
+    // cell volume
+    Scalar volume = element.geometry().volume();
+
+    // build the matrices R and ~N
+    Dune::DynamicMatrix<Scalar> R(numFaces, dim, 0.);
+    Dune::DynamicMatrix<Scalar> N(numFaces, dim, 0.);
+
+    //       std::cout << "element " << elemId << ": center " << centerGlobal << std::endl;;
+
+    //collect information needed for calculation of fluxes due to capillary-potential (pc + gravity!)
+    std::vector<Scalar> pcPotFace(numFaces);
+    Scalar pcPot = (problem_.bBoxMax() - element.geometry().center()) * problem_.gravity() * (density_[nPhaseIdx] - density_[wPhaseIdx]);
+
+    int idx = 0;
+    IntersectionIterator isItEnd = gridView_.iend(element);
+    for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+    {
+        // local number of facet
+
+        Dune::FieldVector<Scalar, dim> faceGlobal(isIt->geometry().center());
+        faceVol[idx] = isIt->geometry().volume();
+
+        // get normal vector
+        const Dune::FieldVector<Scalar, dim>& unitOuterNormal = isIt->centerUnitOuterNormal();
+
+
+        for (int k = 0; k < dim; k++)
+        {
+            // move origin to the center of gravity
+            R[idx][k] = faceVol[idx] * (faceGlobal[k] - centerGlobal[k]);
+            N[idx][k] = unitOuterNormal[k];
+        }
+
+        pcPotFace[idx] = (problem_.bBoxMax() - faceGlobal) * problem_.gravity() * (density_[nPhaseIdx] - density_[wPhaseIdx]);
+
+        idx++;
+    }
+
+    // proceed along the lines of Algorithm 1 from
+    // Brezzi/Lipnikov/Simonicini M3AS 2005
+    // (1) orthonormalize columns of the matrix R (Gram-Schmidt orthonormalization)
+    Scalar norm = R[0][0] * R[0][0];
+    for (int i = 1; i < numFaces; i++)
+        norm += R[i][0] * R[i][0];
+    norm = sqrt(norm);
+    for (int i = 0; i < numFaces; i++)
+        R[i][0] /= norm;
+    Scalar weight = R[0][1] * R[0][0];
+    for (int i = 1; i < numFaces; i++)
+        weight += R[i][1] * R[i][0];
+    for (int i = 0; i < numFaces; i++)
+        R[i][1] -= weight * R[i][0];
+    norm = R[0][1] * R[0][1];
+    for (int i = 1; i < numFaces; i++)
+        norm += R[i][1] * R[i][1];
+    norm = sqrt(norm);
+    for (int i = 0; i < numFaces; i++)
+        R[i][1] /= norm;
+    if (dim == 3)
+    {
+        Scalar weight1 = R[0][2] * R[0][0];
+        Scalar weight2 = R[0][2] * R[0][1];
+        for (int i = 1; i < numFaces; i++)
+        {
+            weight1 += R[i][2] * R[i][0];
+            weight2 += R[i][2] * R[i][1];
+        }
+        for (int i = 0; i < numFaces; i++)
+            R[i][2] -= weight1 * R[i][0] + weight2 * R[i][1];
+        norm = R[0][2] * R[0][2];
+        for (int i = 1; i < numFaces; i++)
+            norm += R[i][2] * R[i][2];
+        norm = sqrt(norm);
+        for (int i = 0; i < numFaces; i++)
+            R[i][2] /= norm;
+    }
+    //      std::cout << "~R =\dim" << R;
+
+    // (2) Build the matrix ~D
+    Dune::DynamicMatrix<Scalar> D(numFaces, numFaces, 0.);
+    for (int s = 0; s < numFaces; s++)
+    {
+        Dune::DynamicVector<Scalar> es(numFaces, 0.);
+        es[s] = 1;
+        for (int k = 0; k < numFaces; k++)
+        {
+            D[k][s] = es[k];
+            for (int i = 0; i < dim; i++)
+            {
+                D[k][s] -= R[s][i] * R[k][i];
+            }
+        }
+    }
+//    std::cout<<"D = "<<D<<"\n";
+
+    // eval diffusion tensor, ASSUMING to be constant over each cell
+    Dune::FieldMatrix<Scalar, dim, dim> mobility(problem_.spatialParams().intrinsicPermeability(element));
+    mobility *= (cellData.mobility(wPhaseIdx) + cellData.mobility(nPhaseIdx));
+
+    Scalar traceMob = mobility[0][0];
+    for (int i = 1; i < dim; i++)
+        traceMob += mobility[i][i];
+    D *= 2.0 * traceMob / volume;
+    //      std::cout << "u~D =\dim" << D;
+
+    // (3) Build the matrix W = Minv
+    Dune::DynamicMatrix<Scalar> NK(N);
+    NK.rightmultiply(mobility);
+
+//    std::cout<<"NK = "<<NK<<"\n";
+
+    for (int i = 0; i < numFaces; i++)
+    {
+        for (int j = 0; j < numFaces; j++)
+        {
+            W_[globalIdx][i][j] = NK[i][0] * N[j][0];
+            for (int k = 1; k < dim; k++)
+                W_[globalIdx][i][j] += NK[i][k] * N[j][k];
+        }
+    }
+
+    W_[globalIdx] /= volume;
+    W_[globalIdx] += D;
+
+    //       std::cout << "W = \dim" << W;
+
+    // Now the notation is borrowed from Aarnes/Krogstadt/Lie 2006, Section 3.4.
+    // The matrix W developed so far corresponds to one element-associated
+    // block of the matrix B^{-1} there.
+
+    // Corresponding to the element under consideration,
+    // calculate the part of the matrix C coupling velocities and element pressures.
+    // This is just a row vector of size numFaces.
+    // scale with volume
+    Dune::DynamicVector<Scalar> c(numFaces);
+    for (int i = 0; i < numFaces; i++)
+        c[i] = faceVol[i];
+
+    // Set up the element part of the matrix \Pi coupling velocities
+    // and pressure-traces. This is a diagonal matrix with entries given by faceVol.
+    for (int i = 0; i < numFaces; i++)
+        Pi[i][i] = faceVol[i];
+
+    // Calculate the element part of the matrix D^{-1} = (c W c^T)^{-1} which is just a scalar value.
+    Dune::DynamicVector<Scalar> Wc(numFaces);
+    W_[globalIdx].umv(c, Wc);
+    dInv = 1.0 / (c * Wc);
+
+    // Calculate the element part of the matrix F = Pi W c^T which is a column vector.
+    F = 0;
+    Pi.umv(Wc, F);
+    //      std::cout << "Pi = \dim" << Pi << "c = " << c << ", F = " << F << std::endl;
+
+    //accumulate fluxes due to capillary potential (pc + gravity!)
+    idx = 0;
+    for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != isItEnd; ++isIt)
+    {
+            Scalar fracFlow = 0;
+
+            Scalar flux = 0;
+            for (int j = 0; j < numFaces; j++)
+                flux += W_[globalIdx][idx][j] * faceVol[j] * (pcPot - pcPotFace[j]);
+
+            if (isIt->neighbor())
+            {
+
+            ElementPointer neighbor = isIt->outside();
+            int globalIdxNeighbor = problem_.variables().index(*neighbor);
+            if (flux > 0.)
+            {
+                switch (pressureType)
+                {
+                case pw:
+                {
+                    fracFlow = cellData.fracFlowFunc(nPhaseIdx);
+                    break;
+                }
+                case pn:
+                {
+                    fracFlow = -cellData.fracFlowFunc(wPhaseIdx);
+                    break;
+                }
+                }
+
+                rhs_[globalIdx] -= (faceVol[idx] * fracFlow * flux);
+                rhs_[globalIdxNeighbor] += (faceVol[idx] * fracFlow * flux);
+            }
+        }
+        else if (isIt->boundary())
+        {
+        BoundaryTypes bctype;
+        problem_.boundaryTypes(bctype, *isIt);
+
+        if (bctype.isDirichlet(pressEqIdx))
+        {
+            if (flux > 0. || !bctype.isDirichlet(satEqIdx))
+            {
+                switch (pressureType)
+                {
+                case pw:
+                {
+                    fracFlow = cellData.fracFlowFunc(nPhaseIdx);
+                    break;
+                }
+                case pn:
+                {
+                    fracFlow = -cellData.fracFlowFunc(wPhaseIdx);
+                    break;
+                }
+                }
+            }
+            else if (flux < 0. && bctype.isDirichlet(satEqIdx))
+            {
+                PrimaryVariables boundValues(0.0);
+                problem_.dirichlet(boundValues, *isIt);
+
+                Scalar krw = MaterialLaw::krw(problem_.spatialParams().materialLawParams(element),
+                        boundValues[saturationIdx]);
+                Scalar krn = MaterialLaw::krn(problem_.spatialParams().materialLawParams(element),
+                        boundValues[saturationIdx]);
+
+                switch (pressureType)
+                {
+                case pw:
+                {
+                    fracFlow = krn / viscosity_[nPhaseIdx]
+                            / (krw / viscosity_[wPhaseIdx] + krn / viscosity_[nPhaseIdx]);
+                    break;
+                }
+                case pn:
+                {
+                    fracFlow = -krw / viscosity_[wPhaseIdx]
+                            / (krw / viscosity_[wPhaseIdx] + krn / viscosity_[nPhaseIdx]);
+                    break;
+                }
+                }
+            }
+
+            rhs_[globalIdx] -= (faceVol[idx] * fracFlow * flux);
+        }
+    }
+        idx++;
+    }
+
+    PrimaryVariables sourceVec(0.0);
+    problem_.source(sourceVec, element);
+    qmean = volume * (sourceVec[wPhaseIdx]/density_[wPhaseIdx] + sourceVec[nPhaseIdx]/density_[nPhaseIdx]);
+
+    qmean += evaluateErrorTerm(cellData) * volume;
+}
+
+template<class TypeTag>
+void MimeticTwoPLocalStiffnessAdaptive<TypeTag>::assembleBC(const Element& element, int k = 1)
+{
+    // evaluate boundary conditions via intersection iterator
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+
+    unsigned int faceIndex = 0;
+    IntersectionIterator endIsIt = gridView_.iend(element);
+    for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != endIsIt; ++isIt)
+    {
+        if (isIt->neighbor())
+        {
+
+        }
+        else if (isIt->boundary())
+        {
+            problem_.boundaryTypes(this->bctype[faceIndex], *isIt);
+            PrimaryVariables boundValues(0.0);
+
+            if (this->bctype[faceIndex].isNeumann(pressEqIdx))
+            {
+                int globalIdx = problem_.variables().index(element);
+
+                problem_.neumann(boundValues, *isIt);
+                Scalar J = (boundValues[wPhaseIdx]/density_[wPhaseIdx] + boundValues[nPhaseIdx]/density_[nPhaseIdx]);
+                this->b[faceIndex] -= J * isIt->geometry().volume();
+            }
+            else if (this->bctype[faceIndex].isDirichlet(pressEqIdx))
+            {
+                problem_.dirichlet(boundValues, *isIt);
+                if (pressureType == pw)
+                    this->b[faceIndex] = boundValues[pressureIdx] + (problem_.bBoxMax() - isIt->geometry().center()) * problem_.gravity() * density_[wPhaseIdx];
+                else if (pressureType == pn)
+                    this->b[faceIndex] = boundValues[pressureIdx] + (problem_.bBoxMax() - isIt->geometry().center()) * problem_.gravity() * density_[nPhaseIdx];
+                else
+                    this->b[faceIndex] = boundValues[pressureIdx];
+            }
+        }
+        faceIndex++;
+    }
+}
+
+/** @} */
+}
+#endif
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimeticgroundwater.hh b/dumux/decoupled/2p/diffusion/mimetic/mimeticgroundwater.hh
deleted file mode 100644
index 286f1f83a9..0000000000
--- a/dumux/decoupled/2p/diffusion/mimetic/mimeticgroundwater.hh
+++ /dev/null
@@ -1,436 +0,0 @@
-// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-// vi: set et ts=4 sw=4 sts=4:
-/*****************************************************************************
- *   See the file COPYING for full copying permissions.                      *
- *                                                                           *
- *   This program is free software: you can redistribute it and/or modify    *
- *   it under the terms of the GNU General Public License as published by    *
- *   the Free Software Foundation, either version 2 of the License, or       *
- *   (at your option) any later version.                                     *
- *                                                                           *
- *   This program is distributed in the hope that it will be useful,         *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
- *   GNU General Public License for more details.                            *
- *                                                                           *
- *   You should have received a copy of the GNU General Public License       *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Local stiffness matrix for the diffusion equation discretized by mimetic FD
- */
-#ifndef DUMUX_MIMETICGROUNDWATER_HH
-#define DUMUX_MIMETICGROUNDWATER_HH
-
-#include<map>
-#include<iostream>
-#include<iomanip>
-#include<fstream>
-#include<vector>
-#include<sstream>
-
-#include<dune/geometry/type.hh>
-#include<dune/geometry/quadraturerules.hh>
-#include<dune/grid/common/grid.hh>
-
-#include<dumux/common/boundaryconditions.hh>
-#include "localstiffness.hh"
-#include <dumux/decoupled/2p/diffusion/diffusionproperties2p.hh>
-namespace Dumux
-{
-/*!
- *  \ingroup MimeticPressure2p
- */
-/**
- * @brief compute local stiffness matrix for conforming finite elements for diffusion equation
- *
- */
-
-//! A class for computing local stiffness matrices
-/*! A class for computing local stiffness matrix for the diffusion equation
- * \f{eqnarray*}{
- * \text{div} \boldsymbol v_{total} &=& q \\
- * \boldsymbol v_{total} &=& - \lambda \boldsymbol K \textbf{grad} p
- * \f}
- * where \f$ p = p_D \f$ on \f$ \Gamma_{Dirichlet} \f$, and \f$ \boldsymbol v_{total} \cdot  \boldsymbol n  = q_N \f$ on \f$ \Gamma_{Neumann} \f$.
- *
- * \tparam TypeTag The problem TypeTag
- */
-template<class TypeTag>
-class MimeticGroundwaterEquationLocalStiffness: public LocalStiffness<TypeTag, 1>
-{
-    typedef typename GET_PROP_TYPE(TypeTag, GridView)GridView;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-
-    // grid types
-    enum
-    {
-        dim = GridView::dimension
-    };
-    enum
-    {
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        pressureIdx = Indices::pressureIdx,
-        pressEqIdx = Indices::pressureEqIdx,
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
-    };
-    typedef typename GridView::Traits::template Codim<0>::Entity Element;
-    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
-
-    typedef typename GET_PROP(TypeTag, SolutionTypes) SolutionTypes;
-    typedef typename SolutionTypes::PrimaryVariables PrimaryVariables;
-
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
-
-    typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
-
-public:
-    // define the number of components of your system, this is used outside
-    // to allocate the correct size of (dense) blocks with a FieldMatrix
-    enum
-    {   m=1};
-    enum
-    {   size=2*dim};
-
-    //! Constructor
-    MimeticGroundwaterEquationLocalStiffness (Problem& problem,
-            bool levelBoundaryAsDirichlet, const GridView& gridView,
-            bool procBoundaryAsDirichlet=true)
-    : problem_(problem), gridView_(gridView)
-    {}
-
-    //! For initialization
-    void initialize()
-    {
-        ElementIterator element = problem_.gridView().template begin<0> ();
-        FluidState fluidState;
-        fluidState.setPressure(wPhaseIdx, problem_.referencePressure(*element));
-        fluidState.setPressure(nPhaseIdx, problem_.referencePressure(*element));
-        fluidState.setTemperature(problem_.temperature(*element));
-        fluidState.setSaturation(wPhaseIdx, 1.);
-        fluidState.setSaturation(nPhaseIdx, 0.);
-        density_[wPhaseIdx] = FluidSystem::density(fluidState, wPhaseIdx);
-        density_[nPhaseIdx] = FluidSystem::density(fluidState, nPhaseIdx);
-    }
-
-    //! assemble local stiffness matrix for given element and order
-    /*! On exit the following things have been done:
-     - The stiffness matrix for the given entity and polynomial degree has been assembled and is
-     accessible with the mat() method.
-     - The boundary conditions have been evaluated and are accessible with the bc() method
-     - The right hand side has been assembled. It contains either the value of the essential boundary
-     condition or the assembled source term and neumann boundary condition. It is accessible via the rhs() method.
-     @param[in]  element a codim 0 entity reference
-     @param[in]  k order of CR basis (only k = 1 is implemented)
-     */
-    void assemble (const Element& element, int k=1)
-    {
-        unsigned int numFaces = element.template count<1>();
-        this->setcurrentsize(numFaces);
-
-        // clear assemble data
-        for (unsigned int i=0; i<numFaces; i++)
-        {
-            this->b[i] = 0;
-            this->bctype[i].reset();
-            for (unsigned int j=0; j<numFaces; j++)
-            this->A[i][j] = 0;
-        }
-
-        assembleV(element,k);
-        assembleBC(element,k);
-    }
-
-    // TODO/FIXME: this is only valid for linear problems where
-    // the local stiffness matrix is independend of the current
-    // solution. We need to implement this properly, but this
-    // should at least make the thing compile...
-    typedef Dune::FieldVector<Scalar, m> VBlockType;
-    void assemble(const Element &cell, const Dune::BlockVector<VBlockType>& localSolution, int orderOfShapeFns = 1)
-    {
-        assemble(cell, orderOfShapeFns);
-    }
-
-    //! assemble only boundary conditions for given element
-    /*! On exit the following things have been done:
-     - The boundary conditions have been evaluated and are accessible with the bc() method
-     - The right hand side contains either the value of the essential boundary
-     condition or the assembled neumann boundary condition. It is accessible via the rhs() method.
-     @param[in]  element a codim 0 entity reference
-     @param[in]  k order of CR basis
-     */
-    void assembleBoundaryCondition (const Element& element, int k=1)
-    {
-        unsigned int numFaces = element.template count<1>();
-        this->setcurrentsize(numFaces);
-
-        // clear assemble data
-        for (unsigned int i=0; i<numFaces; i++)
-        {
-            this->b[i] = 0;
-            this->bctype[i].reset();
-        }
-
-        assembleBC(element,k);
-    }
-
-    void assembleElementMatrices(const Element& element, Dune::FieldVector<Scalar,2*dim>& faceVol,
-            Dune::FieldMatrix<Scalar,2*dim,2*dim>& W, Dune::FieldVector<Scalar,2*dim>& c,
-            Dune::FieldMatrix<Scalar,2*dim,2*dim>& Pi, Scalar& dinv, Dune::FieldVector<Scalar,2*dim>& F, Scalar& qmean)
-    {
-        unsigned int numFaces = element.template count<1>();
-        this->setcurrentsize(numFaces);
-
-        // get global coordinate of cell center
-        const Dune::FieldVector<Scalar,dim>& centerGlobal = element.geometry().center();
-
-        int globalIdx = problem_.variables().index(element);
-
-        CellData& cellData = problem_.variables().cellData(globalIdx);
-
-        // eval diffusion tensor, ASSUMING to be constant over each cell
-        Dune::FieldMatrix<Scalar,dim,dim> K(0);
-        K = problem_.spatialParams().intrinsicPermeability(element);
-
-        K *= (cellData.mobility(wPhaseIdx) + cellData.mobility(nPhaseIdx));
-
-        // cell volume
-        Scalar volume = element.geometry().volume();
-
-        // build the matrices R and ~N
-        Dune::FieldMatrix<Scalar,2*dim,dim> R(0), N(0);
-
-        //       std::cout << "element " << elemId << ": center " << centerGlobal << std::endl;;
-
-        typedef typename GridView::IntersectionIterator IntersectionIterator;
-
-        int i = -1;
-        IntersectionIterator isEndIt = gridView_.iend(element);
-        for (IntersectionIterator isIt = gridView_.ibegin(element); isIt!=isEndIt; ++isIt)
-        {
-            // local number of facet
-            i = isIt->indexInInside();
-
-            const Dune::FieldVector<Scalar,dim>& faceGlobal = isIt->geometry().center();
-            faceVol[i] = isIt->geometry().volume();
-
-            // get normal vector
-            const Dune::FieldVector<Scalar,dim>& unitOuterNormal = isIt->centerUnitOuterNormal();
-
-            N[i] = unitOuterNormal;
-
-            for (int k = 0; k < dim; k++)
-            // move origin to the center of gravity
-            R[i][k] = faceVol[i]*(faceGlobal[k] - centerGlobal[k]);
-        }
-
-        //      std::cout << "N =\dim" << N;
-        //      std::cout << "R =\dim" << R;
-
-        // proceed along the lines of Algorithm 1 from
-        // Brezzi/Lipnikov/Simonicini M3AS 2005
-        // (1) orthonormalize columns of the matrix R
-        Scalar norm = R[0][0]*R[0][0];
-        for (unsigned int i = 1; i < numFaces; i++)
-        norm += R[i][0]*R[i][0];
-        norm = sqrt(norm);
-        for (unsigned int i = 0; i < numFaces; i++)
-        R[i][0] /= norm;
-        Scalar weight = R[0][1]*R[0][0];
-        for (unsigned int i = 1; i < numFaces; i++)
-        weight += R[i][1]*R[i][0];
-        for (unsigned int i = 0; i < numFaces; i++)
-        R[i][1] -= weight*R[i][0];
-        norm = R[0][1]*R[0][1];
-        for (unsigned int i = 1; i < numFaces; i++)
-        norm += R[i][1]*R[i][1];
-        norm = sqrt(norm);
-        for (unsigned int i = 0; i < numFaces; i++)
-        R[i][1] /= norm;
-        if (dim == 3)
-        {
-            Scalar weight1 = R[0][2]*R[0][0];
-            Scalar weight2 = R[0][2]*R[0][1];
-            for (unsigned int i = 1; i < numFaces; i++)
-            {
-                weight1 += R[i][2]*R[i][0];
-                weight2 += R[i][2]*R[i][1];
-            }
-            for (unsigned int i = 0; i < numFaces; i++)
-            R[i][1] -= weight1*R[i][0] + weight2*R[i][1];
-            norm = R[0][2]*R[0][2];
-            for (unsigned int i = 1; i < numFaces; i++)
-            norm += R[i][2]*R[i][2];
-            norm = sqrt(norm);
-            for (unsigned int i = 0; i < numFaces; i++)
-            R[i][2] /= norm;
-        }
-        //      std::cout << "~R =\dim" << R;
-
-        // (2) Build the matrix ~D
-        Dune::FieldMatrix<Scalar,2*dim,2*dim> D(0);
-        for (unsigned int s = 0; s < numFaces; s++)
-        {
-            Dune::FieldVector<Scalar,2*dim> es(0);
-            es[s] = 1;
-            for (unsigned int k = 0; k < numFaces; k++)
-            {
-                D[k][s] = es[k];
-                for (int i = 0; i < dim; i++)
-                {
-                    D[k][s] -= R[s][i]*R[k][i];
-                }
-            }
-        }
-
-        Scalar traceK = K[0][0];
-        for (int i = 1; i < dim; i++)
-        traceK += K[i][i];
-        D *= 2.0*traceK/volume;
-        //      std::cout << "u~D =\dim" << D;
-
-        // (3) Build the matrix W = Minv
-        Dune::FieldMatrix<Scalar,2*dim,dim> NK(N);
-        NK.rightmultiply (K);
-        for (unsigned int i = 0; i < numFaces; i++)
-        {
-            for (unsigned int j = 0; j < numFaces; j++)
-            {
-                W[i][j] = NK[i][0]*N[j][0];
-                for (int k = 1; k < dim; k++)
-                W[i][j] += NK[i][k]*N[j][k];
-            }
-        }
-
-        W /= volume;
-        W += D;
-        //       std::cout << "W = \dim" << W;
-        //       std::cout << D[2][2] << ", " << D[2][0] << ", " << D[2][3] << ", " << D[2][1] << std::endl;
-        //       std::cout << D[0][2] << ", " << D[0][0] << ", " << D[0][3] << ", " << D[0][1] << std::endl;
-        //       std::cout << D[3][2] << ", " << D[3][0] << ", " << D[3][3] << ", " << D[3][1] << std::endl;
-        //       std::cout << D[1][2] << ", " << D[1][0] << ", " << D[1][3] << ", " << D[1][1] << std::endl;
-
-        // Now the notation is borrowed from Aarnes/Krogstadt/Lie 2006, Section 3.4.
-        // The matrix W developed so far corresponds to one element-associated
-        // block of the matrix B^{-1} there.
-
-        // Corresponding to the element under consideration,
-        // calculate the part of the matrix C coupling velocities and element pressures.
-        // This is just a row vector of size numFaces.
-        // scale with volume
-        for (unsigned int i = 0; i < numFaces; i++)
-        c[i] = faceVol[i];
-
-        // Set up the element part of the matrix \Pi coupling velocities
-        // and pressure-traces. This is a diagonal matrix with entries given by faceVol.
-        for (unsigned int i = 0; i < numFaces; i++)
-        Pi[i][i] = faceVol[i];
-
-        // Calculate the element part of the matrix D^{-1} = (c W c^T)^{-1} which is just a scalar value.
-        Dune::FieldVector<Scalar,2*dim> Wc(0);
-        W.umv(c, Wc);
-        dinv = 1.0/(c*Wc);
-
-        // Calculate the element part of the matrix F = Pi W c^T which is a column vector.
-        F = 0;
-        Pi.umv(Wc, F);
-        //      std::cout << "Pi = \dim" << Pi << "c = " << c << ", F = " << F << std::endl;
-
-        PrimaryVariables sourceVec(0.0);
-        problem_.source(sourceVec, element);
-        qmean = volume*(sourceVec[wPhaseIdx]/density_[wPhaseIdx] + sourceVec[nPhaseIdx]/density_[nPhaseIdx]);
-    }
-
-private:
-    void assembleV (const Element& element, int k=1)
-    {
-        unsigned int numFaces = element.template count<1>();
-        this->setcurrentsize(numFaces);
-
-        // The notation is borrowed from Aarnes/Krogstadt/Lie 2006, Section 3.4.
-        // The matrix W developed here corresponds to one element-associated
-        // block of the matrix B^{-1} there.
-        Dune::FieldVector<Scalar,2*dim> faceVol(0);
-        Dune::FieldMatrix<Scalar,2*dim,2*dim> W(0);
-        Dune::FieldVector<Scalar,2*dim> c(0);
-        Dune::FieldMatrix<Scalar,2*dim,2*dim> Pi(0);
-        Dune::FieldVector<Scalar,2*dim> F(0);
-        Scalar dinv;
-        Scalar qmean;
-        this->assembleElementMatrices(element, faceVol, W, c, Pi, dinv, F, qmean);
-
-        // Calculate the element part of the matrix Pi W Pi^T.
-        Dune::FieldMatrix<Scalar,2*dim,2*dim> PiWPiT(W);
-        PiWPiT.rightmultiply(Pi);
-        PiWPiT.leftmultiply(Pi);
-
-        // Calculate the element part of the matrix F D^{-1} F^T.
-        Dune::FieldMatrix<Scalar,2*dim,2*dim> FDinvFT(0);
-        for (unsigned int i = 0; i < numFaces; i++)
-        for (unsigned int j = 0; j < numFaces; j++)
-        FDinvFT[i][j] = dinv*F[i]*F[j];
-
-        // Calculate the element part of the matrix S = Pi W Pi^T - F D^{-1} F^T.
-        for (unsigned int i = 0; i < numFaces; i++)
-        for (unsigned int j = 0; j < numFaces; j++)
-        this->A[i][j] = PiWPiT[i][j] - FDinvFT[i][j];
-
-        // Calculate the source term F D^{-1} f
-        // NOT WORKING AT THE MOMENT
-        Scalar factor = dinv*qmean;
-        for (unsigned int i = 0; i < numFaces; i++)
-        this->b[i] = F[i]*factor;
-
-        //        std::cout << "faceVol = " << faceVol << std::endl << "W = " << std::endl << W << std::endl
-        //              << "c = " << c << std::endl << "Pi = " << std::endl << Pi << std::endl
-        //              << "dinv = " << dinv << std::endl << "F = " << F << std::endl;
-        //        std::cout << "dinvF = " << dinvF << ", q = " << qmean
-        //             << ", b = " << this->b[0] << ", " << this->b[1] << ", " << this->b[2] << ", " << this->b[3] << std::endl;
-    }
-
-    void assembleBC (const Element& element, int k=1)
-    {
-        // evaluate boundary conditions via intersection iterator
-        typedef typename GridView::IntersectionIterator IntersectionIterator;
-
-        IntersectionIterator endIsIt = gridView_.iend(element);
-        for (IntersectionIterator isIt = gridView_.ibegin(element); isIt != endIsIt; ++isIt)
-        {
-            int faceIndex = isIt->indexInInside();
-            if (isIt->boundary())
-            {
-                problem_.boundaryTypes(this->bctype[faceIndex], *isIt);
-                PrimaryVariables boundValues(0.0);
-
-                if (this->bctype[faceIndex].isNeumann(pressEqIdx))
-                {
-                    problem_.neumann(boundValues, *isIt);
-                    Scalar J = (boundValues[wPhaseIdx]/density_[wPhaseIdx] + boundValues[nPhaseIdx]/density_[nPhaseIdx]);
-                    this->b[faceIndex] -= J * isIt->geometry().volume();
-                }
-                else if (this->bctype[faceIndex].isDirichlet(pressEqIdx))
-                {
-                    problem_.dirichlet(boundValues, *isIt);
-                    this->b[faceIndex] = boundValues[pressureIdx];
-                }
-            }
-        }
-    }
-
-private:
-    Problem& problem_;
-    const GridView gridView_;
-
-    Scalar density_[numPhases];
-};
-
-/** @} */
-}
-#endif
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator.hh b/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator.hh
deleted file mode 100644
index 7646d1a815..0000000000
--- a/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator.hh
+++ /dev/null
@@ -1,126 +0,0 @@
-// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-// vi: set et ts=4 sw=4 sts=4:
-/*****************************************************************************
- *   See the file COPYING for full copying permissions.                      *
- *                                                                           *
- *   This program is free software: you can redistribute it and/or modify    *
- *   it under the terms of the GNU General Public License as published by    *
- *   the Free Software Foundation, either version 2 of the License, or       *
- *   (at your option) any later version.                                     *
- *                                                                           *
- *   This program is distributed in the hope that it will be useful,         *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
- *   GNU General Public License for more details.                            *
- *                                                                           *
- *   You should have received a copy of the GNU General Public License       *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief An assembler for the Jacobian matrix based on mimetic FD.
- */
-#ifndef DUMUX_MIMETICOPERATOR_HH
-#define DUMUX_MIMETICOPERATOR_HH
-
-#include<iostream>
-#include<map>
-
-#include<dune/common/timer.hh>
-#include<dune/common/fvector.hh>
-#include<dune/common/fmatrix.hh>
-#include<dune/geometry/type.hh>
-#include<dune/grid/common/grid.hh>
-#include<dune/grid/common/mcmgmapper.hh>
-#include<dune/istl/bvector.hh>
-#include<dune/istl/operators.hh>
-#include<dune/istl/bcrsmatrix.hh>
-
-#include<dumux/common/boundaryconditions.hh>
-#include"croperator.hh"
-
-namespace Dumux
-{
-/*!
- * \ingroup MimeticPressure2p
- * @brief Levelwise assembler
-
-  This class serves as a base class for local assemblers. It provides
-  space and access to the local stiffness matrix. The actual assembling is done
-  in a derived class via the virtual assemble method.
-
-  \tparam Scalar The field type used in the elements of the stiffness matrix
-  \tparam GridView The grid view of the simulation grid
-*/
-template<class Scalar, class GridView>
-class MimeticOperatorAssembler : public CROperatorAssembler<Scalar, GridView>
-{
-    template<int dim>
-    struct ElementLayout
-    {
-        bool contains (Dune::GeometryType gt)
-        {
-            return gt.dim() == dim;
-        }
-    };
-
-    enum {dim=GridView::dimension};
-    typedef Dune::BlockVector< Dune::FieldVector<Scalar,2*dim> > VType;
-    typedef Dune::BlockVector< Dune::FieldVector<Scalar,1> > PType;
-    typedef typename GridView::template Codim<0>::Iterator Iterator;
-    typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView,ElementLayout> ElementMapper;
-
-public:
-
-    MimeticOperatorAssembler (const GridView& gridView)
-    : CROperatorAssembler<Scalar, GridView>(gridView), elementMapper(gridView)
-    {}
-
-    template<class LocalStiffness, class Vector>
-    void calculatePressure (LocalStiffness& loc, Vector& u,
-                            VType& velocity, PType& pressure)
-    {
-        // run over all level elements
-        Iterator eEndIt = this->gridView_.template end<0>();
-        for (Iterator eIt = this->gridView_.template begin<0>(); eIt!=eEndIt; ++eIt)
-        {
-            unsigned int numFaces = eIt->template count<1>();
-
-            int elemId = elementMapper.map(*eIt);
-
-            // get local to global id map and pressure traces
-            Dune::FieldVector<Scalar,2*dim> pressTrace(0);
-            for (unsigned int k = 0; k < numFaces; k++)
-            {
-                pressTrace[k] = u[this->faceMapper_.map(*eIt, k, 1)];
-            }
-
-            // The notation is borrowed from Aarnes/Krogstadt/Lie 2006, Section 3.4.
-            // The matrix W developed here corresponds to one element-associated
-            // block of the matrix B^{-1} there.
-            Dune::FieldVector<Scalar,2*dim> faceVol(0);
-            Dune::FieldMatrix<Scalar,2*dim,2*dim> W(0);
-            Dune::FieldVector<Scalar,2*dim> c(0);
-            Dune::FieldMatrix<Scalar,2*dim,2*dim> Pi(0);
-            Dune::FieldVector<Scalar,2*dim> F(0);
-            Scalar dinv = 0;
-            Scalar qmean = 0;
-            loc.assembleElementMatrices(*eIt, faceVol, W, c, Pi, dinv, F, qmean);
-
-            pressure[elemId] = dinv*(qmean + (F*pressTrace));
-
-            Dune::FieldVector<Scalar,2*dim> v(0);
-            for (int i = 0; i < 2*dim; i++)
-                for (int j = 0; j < 2*dim; j++)
-                    v[i] += W[i][j]*faceVol[j]*(pressure[elemId] - pressTrace[j]);
-
-            velocity[elemId] = v;
-        }
-    }
-
-private:
-    ElementMapper elementMapper;
-};
-}
-#endif
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2p.hh b/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2p.hh
new file mode 100644
index 0000000000..2a176b74a0
--- /dev/null
+++ b/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2p.hh
@@ -0,0 +1,300 @@
+/*****************************************************************************
+ *   Copyright (C) 2011 by Markus Wolff                                      *
+ *   Copyright (C) 2007-2009 by Bernd Flemisch                               *
+ *   Institute for Modelling Hydraulic and Environmental Systems             *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
+ *                                                                           *
+ *   This program is free software: you can redistribute eIt and/or modify    *
+ *   eIt under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that eIt will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief An assembler for the Jacobian matrix based on mimetic FD.
+ */
+#ifndef DUMUX_MIMETICOPERATOR2P_HH
+#define DUMUX_MIMETICOPERATOR2P_HH
+
+#include"croperator2p.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup Mimetic2P
+ * @brief Levelwise assembler
+
+ This class serves as a base class for local assemblers. It provides
+ space and access to the local stiffness matrix. The actual assembling is done
+ in a derived class via the virtual assemble method.
+
+ The template parameters are:
+
+ - Scalar The field type used in the elements of the stiffness matrix
+ */
+template<class TypeTag>
+class MimeticOperatorAssemblerTwoP: public CROperatorAssemblerTwoP<TypeTag>
+{
+    typedef CROperatorAssemblerTwoP<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    enum
+    {
+        dim = GridView::dimension, dimWorld = GridView::dimensionworld,
+    };
+    typedef typename GET_PROP_TYPE(TypeTag, LocalStiffness) LocalStiffness;
+
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GridView::template Codim<0>::EntityPointer ElementPointer;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+
+    typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
+    typedef typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables PrimaryVariables;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum
+    {
+        pw = Indices::pressureW,
+        pn = Indices::pressureNw,
+        pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation),
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        saturationIdx = Indices::saturationIdx,
+        satEqIdx = Indices::satEqIdx,
+        pressEqIdx = Indices::pressEqIdx
+    };
+
+    typedef Dune::FieldVector<Scalar, dimWorld> FieldVector;
+
+public:
+
+    MimeticOperatorAssemblerTwoP(const GridView& gridView) :
+            ParentType(gridView)
+    {
+    }
+
+    template<class Vector>
+    void calculatePressure(LocalStiffness& loc, Vector& u, Problem& problem)
+    {
+        Dune::FieldVector<Scalar, 2 * dim> velocityW(0);
+        Dune::FieldVector<Scalar, 2 * dim> velocityNw(0);
+        Dune::FieldVector<Scalar, 2 * dim> pressTrace(0);
+        Dune::FieldVector<Scalar, 2 * dim> gravPotTrace(0);
+
+        // run over all level elements
+        ElementIterator eIt = this->gridView_.template begin<0>();
+        ElementIterator eItEnd = this->gridView_.template end<0>();
+
+        FluidState fluidState;
+        fluidState.setPressure(wPhaseIdx, problem.referencePressure(*eIt));
+        fluidState.setPressure(nPhaseIdx, problem.referencePressure(*eIt));
+        fluidState.setTemperature(problem.temperature(*eIt));
+        fluidState.setSaturation(wPhaseIdx, 1.);
+        fluidState.setSaturation(nPhaseIdx, 0.);
+        Scalar densityDiff = FluidSystem::density(fluidState, nPhaseIdx) - FluidSystem::density(fluidState, wPhaseIdx);
+        Scalar viscosityW = FluidSystem::viscosity(fluidState, wPhaseIdx);
+        Scalar viscosityNw = FluidSystem::viscosity(fluidState, nPhaseIdx);
+
+        //reset velocity
+        for (int i = 0; i < problem.gridView().size(0); i++)
+        {
+            problem.variables().cellData(i).fluxData().resetVelocity();
+        }
+
+        for (; eIt != eItEnd; ++eIt)
+        {
+            int globalIdx = problem.variables().index(*eIt);
+
+            CellData& cellData = problem.variables().cellData(globalIdx);
+            FieldVector globalPos = eIt->geometry().center();
+
+            // get local to global id map and pressure traces
+            IntersectionIterator isIt = problem.gridView().template ibegin(*eIt);
+            const IntersectionIterator &isItEnd = problem.gridView().template iend(*eIt);
+            for (; isIt != isItEnd; ++isIt)
+            {
+                int indexInInside = isIt->indexInInside();
+
+                int globalIdxFace = this->faceMapper_.map(*eIt, indexInInside, 1);
+
+                pressTrace[indexInInside] = u[globalIdxFace];
+
+                gravPotTrace[indexInInside] = (problem.bBoxMax() - isIt->geometry().center()) * problem.gravity() * densityDiff;
+            }
+
+            switch (pressureType)
+            {
+            case pw:
+            {
+                Scalar potW = loc.constructPressure(*eIt, pressTrace);
+                Scalar gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * densityDiff;
+                Scalar potNw = potW + gravPot;
+
+                cellData.setPotential(wPhaseIdx, potW);
+                cellData.setPotential(nPhaseIdx, potNw);
+
+                gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, wPhaseIdx);
+
+                cellData.setPressure(wPhaseIdx, potW - gravPot);
+
+                gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, nPhaseIdx);
+
+                cellData.setPressure(nPhaseIdx, potNw - gravPot);
+
+                break;
+            }
+            case pn:
+            {
+                Scalar potNw = loc.constructPressure(*eIt, pressTrace);
+                Scalar  gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * densityDiff;
+                Scalar potW = potNw - gravPot;
+
+                cellData.setPotential(nPhaseIdx, potNw);
+                cellData.setPotential(wPhaseIdx, potW);
+
+                gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, wPhaseIdx);
+
+                cellData.setPressure(wPhaseIdx, potW - gravPot);
+
+                gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, nPhaseIdx);
+
+                cellData.setPressure(nPhaseIdx, potNw - gravPot);
+
+                break;
+            }
+            }
+
+            //velocity reconstruction: !!! The velocity which is not reconstructed from the primary pressure variable can be slightly wrong and not conservative!!!!
+            // -> Should not be used for transport!!
+            switch (pressureType)
+            {
+            case pw:
+            {
+                loc.constructVelocity(*eIt, velocityW, pressTrace, cellData.potential(wPhaseIdx));
+                pressTrace += gravPotTrace;
+                loc.constructVelocity(*eIt, velocityNw, pressTrace, cellData.potential(nPhaseIdx));
+
+                break;
+            }
+            case pn:
+            {
+                loc.constructVelocity(*eIt, velocityW, pressTrace, cellData.potential(nPhaseIdx));
+                pressTrace -= gravPotTrace;
+                loc.constructVelocity(*eIt, velocityNw, pressTrace, cellData.potential(wPhaseIdx));
+
+                break;
+            }
+            }
+
+            isIt = problem.gridView().template ibegin(*eIt);
+            for (; isIt != isItEnd; ++isIt)
+            {
+                int idxInInside = isIt->indexInInside();
+
+                cellData.fluxData().setUpwindPotential(wPhaseIdx, idxInInside, velocityW[idxInInside]);
+                cellData.fluxData().setUpwindPotential(nPhaseIdx, idxInInside, velocityNw[idxInInside]);
+
+                Scalar mobilityW = 0;
+                Scalar mobilityNw = 0;
+
+                if (isIt->neighbor())
+                {
+                    int neighborIdx = problem.variables().index(*(isIt->outside()));
+
+                    CellData& cellDataNeighbor = problem.variables().cellData(neighborIdx);
+
+                    mobilityW =
+                            (velocityW[idxInInside] >= 0.) ? cellData.mobility(wPhaseIdx) :
+                                    cellDataNeighbor.mobility(wPhaseIdx);
+                    mobilityNw =
+                            (velocityNw[idxInInside] >= 0.) ? cellData.mobility(nPhaseIdx) :
+                                    cellDataNeighbor.mobility(nPhaseIdx);
+
+                    int idxInOutside = isIt->indexInOutside();
+
+                    if (velocityW[idxInInside] >= 0.)
+                    {
+                        FieldVector velocity(isIt->centerUnitOuterNormal());
+                        velocity *= mobilityW/(mobilityW+mobilityNw) * velocityW[idxInInside];
+                        cellData.fluxData().addVelocity(wPhaseIdx, idxInInside, velocity);
+                        cellDataNeighbor.fluxData().addVelocity(wPhaseIdx, isIt->indexInOutside(), velocity);
+                    }
+                    if (velocityNw[idxInInside] >= 0.)
+                    {
+                        FieldVector velocity(isIt->centerUnitOuterNormal());
+                        velocity *= mobilityNw/(mobilityW+mobilityNw) * velocityNw[idxInInside];
+                        cellData.fluxData().addVelocity(nPhaseIdx, idxInInside, velocity);
+                        cellDataNeighbor.fluxData().addVelocity(nPhaseIdx, isIt->indexInOutside(), velocity);
+                    }
+
+                    cellData.fluxData().setVelocityMarker(idxInInside);
+                }
+                else
+                {
+                    BoundaryTypes bctype;
+                    problem.boundaryTypes(bctype, *isIt);
+                    if (bctype.isDirichlet(satEqIdx))
+                    {
+                        PrimaryVariables boundValues(0.0);
+                        problem.dirichlet(boundValues, *isIt);
+
+                        if (velocityW[idxInInside] >= 0.)
+                        {
+                            mobilityW = cellData.mobility(wPhaseIdx);
+                        }
+                        else
+                        {
+                            mobilityW = MaterialLaw::krw(problem.spatialParams().materialLawParams(*eIt),
+                                    boundValues[saturationIdx]) / viscosityW;
+                        }
+
+                        if (velocityNw[idxInInside] >= 0.)
+                        {
+                            mobilityNw = cellData.mobility(nPhaseIdx);
+                        }
+                        else
+                        {
+                            mobilityNw = MaterialLaw::krn(problem.spatialParams().materialLawParams(*eIt),
+                                    boundValues[saturationIdx]) / viscosityNw;
+                        }
+                    }
+                    else
+                    {
+                        mobilityW = cellData.mobility(wPhaseIdx);
+                        mobilityNw = cellData.mobility(nPhaseIdx);
+                    }
+
+                    FieldVector velocity(isIt->centerUnitOuterNormal());
+                    velocity *= mobilityW / (mobilityW + mobilityNw) * velocityW[idxInInside];
+                    cellData.fluxData().setVelocity(wPhaseIdx, idxInInside, velocity);
+
+                    velocity = 0;
+                    velocity = isIt->centerUnitOuterNormal();
+                    velocity *= mobilityNw / (mobilityW + mobilityNw) * velocityNw[idxInInside];
+                    cellData.fluxData().setVelocity(nPhaseIdx, idxInInside, velocity);
+                    cellData.fluxData().setVelocityMarker(idxInInside);
+                }
+            }
+        }
+    }
+};
+}
+#endif
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2padaptive.hh b/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2padaptive.hh
new file mode 100644
index 0000000000..8819201010
--- /dev/null
+++ b/dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2padaptive.hh
@@ -0,0 +1,308 @@
+/*****************************************************************************
+ *   Copyright (C) 2011 by Markus Wolff                                      *
+ *   Copyright (C) 2007-2009 by Bernd Flemisch                               *
+ *   Institute for Modelling Hydraulic and Environmental Systems             *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief An assembler for the Jacobian matrix based on mimetic FD.
+ */
+#ifndef DUMUX_MIMETICOPERATOR2PADAPTIVE_HH
+#define DUMUX_MIMETICOPERATOR2PADAPTIVE_HH
+
+#include"croperator2padaptive.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup Mimetic2P
+ * @brief Levelwise assembler
+
+  This class serves as a base class for local assemblers. It provides
+  space and access to the local stiffness matrix. The actual assembling is done
+  in a derived class via the virtual assemble method.
+
+  The template parameters are:
+
+  - Scalar The field type used in the elements of the stiffness matrix
+*/
+template<class TypeTag>
+class MimeticOperatorAssemblerTwoPAdaptive : public CROperatorAssemblerTwoPAdaptive<TypeTag>
+{
+    typedef CROperatorAssemblerTwoPAdaptive<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+
+    enum
+    {
+        dim=GridView::dimension,
+        dimWorld=GridView::dimensionworld
+    };
+    typedef typename GET_PROP_TYPE(TypeTag, LocalStiffness) LocalStiffness;
+
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GridView::template Codim<0>::EntityPointer ElementPointer;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+
+    typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
+    typedef typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables PrimaryVariables;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum
+    {
+        pw = Indices::pressureW,
+        pn = Indices::pressureNw,
+        pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation),
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        saturationIdx = Indices::saturationIdx,
+        satEqIdx = Indices::satEqIdx
+    };
+
+    typedef Dune::FieldVector<Scalar, dimWorld> FieldVector;
+public:
+
+    MimeticOperatorAssemblerTwoPAdaptive (const GridView& gridView)
+    : ParentType(gridView)
+    {}
+
+    template<class Vector>
+    void calculatePressure(LocalStiffness& loc, Vector& u, Problem& problem)
+    {
+        Dune::DynamicVector<Scalar> velocityW(2*dim);
+        Dune::DynamicVector<Scalar> velocityNw(2*dim);
+        Dune::DynamicVector<Scalar> pressTraceW(2*dim);
+        Dune::DynamicVector<Scalar> pressTraceNw(2*dim);
+
+        // run over all level elements
+        ElementIterator eIt = this->gridView_.template begin<0>();
+        ElementIterator eItEnd = this->gridView_.template end<0>();
+
+        FluidState fluidState;
+        fluidState.setPressure(wPhaseIdx, problem.referencePressure(*eIt));
+        fluidState.setPressure(nPhaseIdx, problem.referencePressure(*eIt));
+        fluidState.setTemperature(problem.temperature(*eIt));
+        fluidState.setSaturation(wPhaseIdx, 1.);
+        fluidState.setSaturation(nPhaseIdx, 0.);
+        Scalar densityDiff = FluidSystem::density(fluidState, nPhaseIdx) - FluidSystem::density(fluidState, wPhaseIdx);
+        Scalar viscosityW = FluidSystem::viscosity(fluidState, wPhaseIdx);
+        Scalar viscosityNw = FluidSystem::viscosity(fluidState, nPhaseIdx);
+
+        //reset velocity
+        for (int i = 0; i < problem.gridView().size(0); i++)
+        {
+            problem.variables().cellData(i).fluxData().resetVelocity();
+        }
+
+        for (; eIt != eItEnd; ++eIt)
+        {
+            int globalIdx = problem.variables().index(*eIt);
+
+            unsigned int numFaces = this->intersectionMapper_.size(globalIdx);
+
+            // get local to global id map and pressure traces
+            velocityW.resize(numFaces);
+            velocityNw.resize(numFaces);
+            pressTraceW.resize(numFaces);
+            pressTraceNw.resize(numFaces);
+
+            CellData& cellData = problem.variables().cellData(globalIdx);
+            FieldVector globalPos = eIt->geometry().center();
+
+            int intersectionIdx = -1;
+            // get local to global id map and pressure traces
+            IntersectionIterator isIt = problem.gridView().template ibegin(*eIt);
+            const IntersectionIterator &isItEnd = problem.gridView().template iend(*eIt);
+            for (; isIt != isItEnd; ++isIt)
+            {
+                ++intersectionIdx;
+
+                int globalIdxFace = this->intersectionMapper_.map(*eIt, intersectionIdx);
+
+                Scalar pcPotFace = (problem.bBoxMax() - isIt->geometry().center()) * problem.gravity() * densityDiff;
+
+                switch (pressureType)
+                {
+                case pw:
+                {
+                    pressTraceW[intersectionIdx] = u[globalIdxFace];
+                    pressTraceNw[intersectionIdx] = u[globalIdxFace] + pcPotFace;
+                    break;
+                }
+                case pn:
+                {
+                    pressTraceNw[intersectionIdx] = u[globalIdxFace];
+                    pressTraceW[intersectionIdx] = u[globalIdxFace] - pcPotFace;
+
+                    break;
+                }
+                }
+            }
+
+            switch (pressureType)
+            {
+            case pw:
+            {
+                Scalar potW = loc.constructPressure(*eIt, pressTraceW);
+                Scalar gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * densityDiff;
+                Scalar potNw = potW + gravPot;
+
+                cellData.setPotential(wPhaseIdx, potW);
+                cellData.setPotential(nPhaseIdx, potNw);
+
+                gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, wPhaseIdx);
+
+                cellData.setPressure(wPhaseIdx, potW - gravPot);
+
+                gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, nPhaseIdx);
+
+                cellData.setPressure(nPhaseIdx, potNw - gravPot);
+
+                break;
+            }
+            case pn:
+            {
+                Scalar potNw = loc.constructPressure(*eIt, pressTraceNw);
+                Scalar  gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * densityDiff;
+                Scalar potW = potNw - gravPot;
+
+                cellData.setPotential(nPhaseIdx, potNw);
+                cellData.setPotential(wPhaseIdx, potW);
+
+                gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, wPhaseIdx);
+
+                cellData.setPressure(wPhaseIdx, potW - gravPot);
+
+                gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, nPhaseIdx);
+
+                cellData.setPressure(nPhaseIdx, potNw - gravPot);
+
+                break;
+            }
+            }
+
+            //velocity reconstruction: !!! The velocity which is not reconstructed from the primary pressure variable can be slightly wrong and not conservative!!!!
+            // -> Should not be used for transport!!
+            loc.constructVelocity(*eIt, velocityW, pressTraceW, cellData.potential(wPhaseIdx));
+            loc.constructVelocity(*eIt, velocityNw, pressTraceNw, cellData.potential(nPhaseIdx));
+
+            intersectionIdx = -1;
+            isIt = problem.gridView().template ibegin(*eIt);
+            for (; isIt != isItEnd; ++isIt)
+            {
+                ++intersectionIdx;
+                int idxInInside = isIt->indexInInside();
+
+                cellData.fluxData().addUpwindPotential(wPhaseIdx, idxInInside, velocityW[intersectionIdx]);
+                cellData.fluxData().addUpwindPotential(nPhaseIdx, idxInInside, velocityNw[intersectionIdx]);
+
+                Scalar mobilityW = 0;
+                Scalar mobilityNw = 0;
+
+                if (isIt->neighbor())
+                {
+                    int neighborIdx = problem.variables().index(*(isIt->outside()));
+
+                    CellData& cellDataNeighbor = problem.variables().cellData(neighborIdx);
+
+                    mobilityW =
+                            (velocityW[intersectionIdx] >= 0.) ? cellData.mobility(wPhaseIdx) :
+                                    cellDataNeighbor.mobility(wPhaseIdx);
+                    mobilityNw =
+                            (velocityNw[intersectionIdx] >= 0.) ? cellData.mobility(nPhaseIdx) :
+                                    cellDataNeighbor.mobility(nPhaseIdx);
+
+                    int idxInOutside = isIt->indexInOutside();
+
+                    if (velocityW[intersectionIdx] >= 0.)
+                    {
+                        FieldVector velocity(isIt->centerUnitOuterNormal());
+                        velocity *= mobilityW/(mobilityW+mobilityNw) * velocityW[intersectionIdx];
+                        cellData.fluxData().addVelocity(wPhaseIdx, idxInInside, velocity);
+                        cellDataNeighbor.fluxData().addVelocity(wPhaseIdx, isIt->indexInOutside(), velocity);
+                    }
+                    if (velocityNw[intersectionIdx] >= 0.)
+                    {
+                        FieldVector velocity(isIt->centerUnitOuterNormal());
+                        velocity *= mobilityNw/(mobilityW+mobilityNw) * velocityNw[intersectionIdx];
+                        cellData.fluxData().addVelocity(nPhaseIdx, idxInInside, velocity);
+                        cellDataNeighbor.fluxData().addVelocity(nPhaseIdx, isIt->indexInOutside(), velocity);
+                    }
+
+                    cellData.fluxData().setVelocityMarker(idxInInside);
+                }
+                else
+                {
+                    BoundaryTypes bctype;
+                    problem.boundaryTypes(bctype, *isIt);
+                    if (bctype.isDirichlet(satEqIdx))
+                    {
+                        PrimaryVariables boundValues(0.0);
+                        problem.dirichlet(boundValues, *isIt);
+
+                        if (velocityW[intersectionIdx] >= 0.)
+                        {
+                            mobilityW = cellData.mobility(wPhaseIdx);
+                        }
+                        else
+                        {
+                            mobilityW = MaterialLaw::krw(problem.spatialParams().materialLawParams(*eIt),
+                                boundValues[saturationIdx]) / viscosityW;
+                        }
+
+                        if (velocityNw[intersectionIdx] >= 0.)
+                        {
+                            mobilityNw = cellData.mobility(nPhaseIdx);
+                        }
+                        else
+                        {
+                            mobilityNw = MaterialLaw::krn(problem.spatialParams().materialLawParams(*eIt),
+                                boundValues[saturationIdx]) / viscosityNw;
+                        }
+                    }
+                    else
+                    {
+                        mobilityW = cellData.mobility(wPhaseIdx);
+                        mobilityNw = cellData.mobility(nPhaseIdx);
+                    }
+
+                    FieldVector velocity(isIt->centerUnitOuterNormal());
+                    velocity *= mobilityW/(mobilityW+mobilityNw) * velocityW[intersectionIdx];
+                    cellData.fluxData().addVelocity(wPhaseIdx, idxInInside, velocity);
+
+
+                    velocity = isIt->centerUnitOuterNormal();
+                    velocity *= mobilityNw/(mobilityW+mobilityNw) * velocityNw[intersectionIdx];
+                    cellData.fluxData().addVelocity(nPhaseIdx, idxInInside, velocity);
+                    cellData.fluxData().setVelocityMarker(idxInInside);
+                }
+            }
+        }
+    }
+};
+}
+#endif
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2p.hh b/dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2p.hh
index bcd2c99920..3e519d7520 100644
--- a/dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2p.hh
+++ b/dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2p.hh
@@ -1,7 +1,9 @@
-// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-// vi: set et ts=4 sw=4 sts=4:
 /*****************************************************************************
- *   See the file COPYING for full copying permissions.                      *
+ *   Copyright (C) 2011 by Markus Wolff                                      *
+ *   Copyright (C) 2007-2009 by Bernd Flemisch                               *
+ *   Institute for Modelling Hydraulic and Environmental Systems             *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
  *                                                                           *
  *   This program is free software: you can redistribute it and/or modify    *
  *   it under the terms of the GNU General Public License as published by    *
@@ -10,7 +12,7 @@
  *                                                                           *
  *   This program is distributed in the hope that it will be useful,         *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
  *   GNU General Public License for more details.                            *
  *                                                                           *
  *   You should have received a copy of the GNU General Public License       *
@@ -24,48 +26,40 @@
 #ifndef DUMUX_MIMETICPRESSURE2P_HH
 #define DUMUX_MIMETICPRESSURE2P_HH
 
-// dune environent:
-#include <dune/istl/bvector.hh>
-#include <dune/istl/operators.hh>
-#include <dune/istl/solvers.hh>
-#include <dune/istl/preconditioners.hh>
-
 // dumux environment
-#include <dumux/decoupled/2p/diffusion/diffusionproperties2p.hh>
-#include <dumux/decoupled/common/mimetic/mimeticproperties.hh>
-#include <dumux/decoupled/2p/diffusion/mimetic/mimeticoperator.hh>
+#include "dumux/decoupled/common/mimetic/mimeticproperties.hh"
+#include "dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2p.hh"
+#include "dumux/decoupled/2p/diffusion/mimetic/mimetic2p.hh"
 
 namespace Dumux
 {
 
-//! \ingroup MimeticPressure2p
-/*! \brief Mimetic finite differences discretization of a two-phase pressure equation of the sequential IMPES model.
- *
- * This class provides a mimetic finite differences implementation for solving equations of the form
- * \f[
- * \text{div}\, \boldsymbol{v}_{total} = q.
- * \f]
- * The total velocity \f$\boldsymbol{v}_{total}\f$ is defined using a global pressure approach. This leads to
- * \f[
- * - \text{div}\, \left(\lambda \boldsymbol K \textbf{grad}\, p_{global}\right) = q.
- * \f]
- * Here, \f$ p_{global} \f$ is the global pressure of a classical fractional flow formulation
- * (see e.g. P. Binning and M. A. Celia, “Practical implementation of the fractional flow approach to multi-phase flow simulation,” Advances in water resources, vol. 22, no. 5, pp. 461-478, 1999.),
- * \f$ \boldsymbol K \f$ the absolute permeability, \f$ \lambda = \lambda_w + \lambda_n \f$ the total mobility depending on the
- * saturation (\f$ \lambda_\alpha = k_{r_\alpha} / \mu_\alpha \f$) and \f$ q \f$ the source term. Gravity is neglected in this implementation.
+
+/*! \ingroup Mimetic2p
  *
- * \f$ p = p_D \f$ on \f$ \Gamma_{Dirichlet} \f$, and \f$ \boldsymbol v_{total} \cdot  \boldsymbol n  = q_N \f$ on \f$ \Gamma_{Neumann} \f$.
+ * \brief mimetic method for the pressure equation
  *
- * Remark: gravity is neglected!
+ * Provides a mimetic implementation for the evaluation
+ * of equations of the form
+ * \f[\text{div}\, \boldsymbol{v}_{total} = q.\f]
+ * The definition of the total velocity \f$\boldsymbol{v}_total\f$ depends on the kind of pressure chosen. This could be a wetting (w) phase pressure leading to
+ * \f[ - \text{div}\,  \left[\lambda \boldsymbol{K} \left(\text{grad}\, p_w + f_n \text{grad}\, p_c + \sum f_\alpha \rho_\alpha g  \text{grad}\, z\right)\right] = q, \f]
+ * a non-wetting (n) phase pressure yielding
+ * \f[ - \text{div}\,  \left[\lambda \boldsymbol{K}  \left(\text{grad}\, p_n - f_w \text{grad}\, p_c + \sum f_\alpha \rho_\alpha g  \text{grad}\, z\right)\right] = q, \f]
+ * or a global pressure leading to
+ * \f[ - \text{div}\, \left[\lambda \boldsymbol{K} \left(\text{grad}\, p_{global} + \sum f_\alpha \rho_\alpha g  \text{grad}\, z\right)\right] = q.\f]
+ *  Here, \f$p\f$ denotes a pressure, \f$\boldsymbol{K}\f$ the absolute permeability, \f$\lambda\f$ the total mobility, possibly depending on the
+ * saturation,\f$f\f$ the fractional flow function of a phase, \f$\rho\f$ a phase density, \f$g\f$ the gravity constant and \f$q\f$ the source term.
+ * For all cases, \f$p = p_D\f$ on \f$\Gamma_{Neumann}\f$, and \f$\boldsymbol{v}_{total}  = q_N\f$
+ * on \f$\Gamma_{Dirichlet}\f$.
  *
- * \tparam TypeTag The Type Tag
+ *\tparam TypeTag The Type Tag
  */
 template<class TypeTag> class MimeticPressure2P
 {
     typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
     typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
     typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, Variables) Variables;
 
     typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
     typedef typename SpatialParams::MaterialLaw MaterialLaw;
@@ -75,16 +69,21 @@ template<class TypeTag> class MimeticPressure2P
     typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
     typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
 
-    typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
-
     enum
     {
         dim = GridView::dimension, dimWorld = GridView::dimensionworld
     };
     enum
     {
+        pw = Indices::pressureW,
+        pn = Indices::pressureNW,
         pGlobal = Indices::pressureGlobal,
-        sw = Indices::saturationW
+        sw = Indices::saturationW,
+        sn = Indices::saturationNW,
+        vw = Indices::velocityW,
+        vn = Indices::velocityNW,
+        pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation), //!< gives kind of pressure used (\f$ 0 = p_w\f$, \f$ 1 = p_n\f$, \f$ 2 = p_{global}\f$)
+        saturationType = GET_PROP_VALUE(TypeTag, SaturationFormulation), //!< gives kind of saturation used (\f$ 0 = S_w\f$, \f$ 1 = S_n\f$)
     };
     enum
     {
@@ -95,20 +94,25 @@ template<class TypeTag> class MimeticPressure2P
     typedef typename GridView::Traits::template Codim<0>::Entity Element;
     typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     typedef typename GridView::Grid Grid;
+    typedef typename GridView::template Codim<0>::EntityPointer ElementPointer;
     typedef typename GridView::IntersectionIterator IntersectionIterator;
 
+    typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix;
+
     typedef typename GET_PROP_TYPE(TypeTag, LocalStiffness) LocalStiffness;
     typedef Dune::BlockVector< Dune::FieldVector<Scalar, 1> > TraceType;
-    typedef Dune::BlockVector< Dune::FieldVector<Scalar, 2*dim> > NormalVelType;
-    typedef MimeticOperatorAssembler<Scalar,GridView> OperatorAssembler;
+    typedef MimeticOperatorAssemblerTwoP<TypeTag> OperatorAssembler;
 
-    ///@cond false
-    typedef typename GET_PROP(TypeTag, SolutionTypes)::ScalarSolution ScalarSolution;
-    ///@endcond
+    typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
+    typedef typename GET_PROP(TypeTag, SolutionTypes)::ScalarSolution ScalarSolutionType;
 
     typedef typename GET_PROP_TYPE(TypeTag, PressureCoefficientMatrix) Matrix;
-    typedef typename GET_PROP_TYPE(TypeTag, PressureRHSVector) RHSVector;
-    typedef typename GET_PROP_TYPE(TypeTag, PressureSolutionVector) PressureSolution;
+    typedef typename GET_PROP_TYPE(TypeTag, PressureRHSVector) Vector;
+
+    typedef Dune::FieldVector<Scalar, dim> DimVector;
+
+    typedef Dune::GenericReferenceElements<Scalar, dim> ReferenceElementContainer;
+    typedef Dune::GenericReferenceElement<Scalar, dim> ReferenceElement;
 
     //initializes the matrix to store the system of equations
     void initializeMatrix();
@@ -116,9 +120,33 @@ template<class TypeTag> class MimeticPressure2P
     //function which assembles the system of equations to be solved
     void assemble(bool first)
     {
-        LocalStiffness lstiff(problem_, false, problem_.gridView());
-        lstiff.initialize();
-        A_.assemble(lstiff, pressTrace_, f_);
+        Scalar timeStep = problem_.timeManager().timeStepSize();
+        Scalar maxError = 0.0;
+        int size = problem_.gridView().size(0);
+        for (int i = 0; i < size; i++)
+        {
+            Scalar sat = 0;
+            switch (saturationType)
+            {
+            case sw:
+                sat = problem_.variables().cellData(i).saturation(wPhaseIdx);
+                break;
+            case sn:
+                sat = problem_.variables().cellData(i).saturation(nPhaseIdx);
+                break;
+            }
+            if (sat > 1.0)
+            {
+                maxError = std::max(maxError, (sat - 1.0) / timeStep);
+            }
+            if (sat < 0.0)
+            {
+                maxError = std::max(maxError, (-sat) / timeStep);
+            }
+        }
+
+        lstiff_.setErrorInfo(maxError, timeStep);
+        A_.assemble(lstiff_, pressTrace_, f_);
         return;
     }
 
@@ -127,36 +155,15 @@ template<class TypeTag> class MimeticPressure2P
 
     void postprocess()
     {
-        LocalStiffness lstiff(problem_, false, problem_.gridView());
-        lstiff.initialize();
-        A_.calculatePressure(lstiff, pressTrace_, normalVelocity_, pressure_);
-        return;
-    }
-
-protected:
-    //! \cond \private
-    Problem& problem()
-    {
-        return problem_;
-    }
+        A_.calculatePressure(lstiff_, pressTrace_, problem_);
 
-    const Problem& problem() const
-    {
-        return problem_;
+        return;
     }
-    //! \endcond
 
 public:
     //constitutive functions are initialized and stored in the variables object
     void updateMaterialLaws();
 
-
-    /*! \brief Initializes the pressure model
-     *
-     * Initializes pressure and velocity field.
-     *
-     * \param solveTwice indicates if more than one iteration is allowed to get an initial pressure solution
-     */
     void initialize(bool solveTwice = true)
     {
         ElementIterator element = problem_.gridView().template begin<0> ();
@@ -172,140 +179,238 @@ public:
         viscosity_[nPhaseIdx] = FluidSystem::viscosity(fluidState, nPhaseIdx);
 
         updateMaterialLaws();
-        A_.initializeMatrix();
-        f_.resize(problem_.gridView().size(1));//resize to make sure the final grid size (after the problem was completely built) is used!
-        pressure_.resize(problem_.gridView().size(0));
+        A_.initialize();
         pressTrace_.resize(problem_.gridView().size(1));
-        normalVelocity_.resize(problem_.gridView().size(0)),
-        pressure_ = 0;
-        pressTrace_ = 0;
+        f_.resize(problem_.gridView().size(1));
+        lstiff_.initialize();
+        lstiff_.reset();
+
+        pressTrace_ = 0.0;
         f_ = 0;
-        normalVelocity_ = 0.0;
+
         assemble(true);
         solve();
         postprocess();
 
-        storePressureSolution();
-        storeVelocity();
-
         return;
     }
 
-    /*! \brief Pressure and velocity update */
+    void updateVelocity()
+    {
+        updateMaterialLaws();
+        postprocess();
+    }
+
     void update()
     {
+        lstiff_.reset();
+
         assemble(false);
         solve();
         postprocess();
 
-        storePressureSolution();
-        storeVelocity();
-
         return;
     }
 
-    /*! \brief Globally stores the pressure solution*/
-    void storePressureSolution()
+    //! \brief Write data files
+     /*  \param name file name */
+    template<class MultiWriter>
+    void addOutputVtkFields(MultiWriter &writer)
     {
         int size = problem_.gridView().size(0);
-        for (int i = 0; i < size; i++)
+        ScalarSolutionType *potential = writer.allocateManagedBuffer(size);
+        ScalarSolutionType *pressure = 0;
+        ScalarSolutionType *pressureSecond = 0;
+        ScalarSolutionType *potentialSecond = 0;
+        Dune::BlockVector < DimVector > *velocityWetting = 0;
+        Dune::BlockVector < DimVector > *velocityNonwetting = 0;
+
+        if (vtkOutputLevel_ > 0)
         {
-            CellData& cellData = problem_.variables().cellData(i);
-            storePressureSolution(i, cellData);
-            cellData.fluxData().resetVelocity();
+            pressure = writer.allocateManagedBuffer(size);
+            pressureSecond = writer.allocateManagedBuffer(size);
+            potentialSecond = writer.allocateManagedBuffer(size);
+            velocityWetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
+            velocityNonwetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
         }
-    }
 
-    /*! \brief Stores the pressure solution of a cell
-     *
-     * \param globalIdx Global cell index
-     * \param cellData A CellData object
-     */
-    void storePressureSolution(int globalIdx, CellData& cellData)
-    {
-        cellData.setGlobalPressure(pressure_[globalIdx]);
-    }
-
-    // Globally stores the velocity solution at cell-cell interfaces
-    void storeVelocity();
 
+            ElementIterator eItBegin = problem_.gridView().template begin<0>();
+            ElementIterator eItEnd = problem_.gridView().template end<0>();
+            for (ElementIterator eIt = eItBegin; eIt != eItEnd; ++eIt)
+            {
+                int globalIdx = problem_.variables().index(*eIt);
+                CellData& cellData = problem_.variables().cellData(globalIdx);
+
+                if (pressureType == pw)
+                {
+                    (*potential)[globalIdx] = cellData.potential(wPhaseIdx);
+                }
+
+                if (pressureType == pn)
+                {
+                    (*potential)[globalIdx] = cellData.potential(nPhaseIdx);
+                }
+
+                if (vtkOutputLevel_ > 0)
+                {
+
+                if (pressureType == pw)
+                {
+                    (*pressure)[globalIdx] = cellData.pressure(wPhaseIdx);
+                    (*potentialSecond)[globalIdx] = cellData.potential(nPhaseIdx);
+                    (*pressureSecond)[globalIdx] = cellData.pressure(nPhaseIdx);
+                }
+
+                if (pressureType == pn)
+                {
+                    (*pressure)[globalIdx] = cellData.pressure(nPhaseIdx);
+                    (*potentialSecond)[globalIdx] = cellData.potential(wPhaseIdx);
+                    (*pressureSecond)[globalIdx] = cellData.pressure(wPhaseIdx);
+                }
+
+                Dune::FieldVector < Scalar, 2 * dim > fluxW(0);
+                Dune::FieldVector < Scalar, 2 * dim > fluxNw(0);
+
+                // run through all intersections with neighbors and boundary
+                IntersectionIterator isItEnd = problem_.gridView().iend(*eIt);
+                for (IntersectionIterator isIt = problem_.gridView().ibegin(*eIt); isIt != isItEnd; ++isIt)
+                {
+                    int isIndex = isIt->indexInInside();
+
+                    fluxW[isIndex] += isIt->geometry().volume()
+                        * (isIt->centerUnitOuterNormal() * cellData.fluxData().velocity(wPhaseIdx, isIndex));
+                    fluxNw[isIndex] += isIt->geometry().volume()
+                        * (isIt->centerUnitOuterNormal() * cellData.fluxData().velocity(nPhaseIdx, isIndex));
+                }
+
+                DimVector refVelocity(0);
+                refVelocity[0] = 0.5 * (fluxW[1] - fluxW[0]);
+                refVelocity[1] = 0.5 * (fluxW[3] - fluxW[2]);
+                refVelocity[2] = 0.5 * (fluxW[5] - fluxW[4]);
+
+                const DimVector& localPos = ReferenceElementContainer::general(eIt->geometry().type()).position(0, 0);
+
+                // get the transposed Jacobian of the element mapping
+                const DimMatrix& jacobianT = eIt->geometry().jacobianTransposed(localPos);
+
+                // calculate the element velocity by the Piola transformation
+                DimVector elementVelocity(0);
+                jacobianT.umtv(refVelocity, elementVelocity);
+                elementVelocity /= eIt->geometry().integrationElement(localPos);
+
+                (*velocityWetting)[globalIdx] = elementVelocity;
+
+                refVelocity = 0;
+                refVelocity[0] = 0.5 * (fluxNw[1] - fluxNw[0]);
+                refVelocity[1] = 0.5 * (fluxNw[3] - fluxNw[2]);
+                refVelocity[2] = 0.5 * (fluxNw[5] - fluxNw[4]);
+
+                // calculate the element velocity by the Piola transformation
+                elementVelocity = 0;
+                jacobianT.umtv(refVelocity, elementVelocity);
+                elementVelocity /= eIt->geometry().integrationElement(localPos);
+
+                (*velocityNonwetting)[globalIdx] = elementVelocity;
+                }
+            }
+
+            if (pressureType == pw)
+            {
+                writer.attachCellData(*potential, "wetting potential");
+            }
+
+            if (pressureType == pn)
+            {
+                writer.attachCellData(*potential, "nonwetting potential");
+            }
+
+            if (vtkOutputLevel_ > 0)
+            {
+            if (pressureType == pw)
+            {
+                writer.attachCellData(*pressure, "wetting pressure");
+                writer.attachCellData(*pressureSecond, "nonwetting pressure");
+                writer.attachCellData(*potentialSecond, "nonwetting potential");
+            }
+
+            if (pressureType == pn)
+            {
+                writer.attachCellData(*pressure, "nonwetting pressure");
+                writer.attachCellData(*pressureSecond, "wetting pressure");
+                writer.attachCellData(*potentialSecond, "wetting potential");
+            }
+
+            writer.attachCellData(*velocityWetting, "wetting-velocity", dim);
+            writer.attachCellData(*velocityNonwetting, "non-wetting-velocity", dim);
+            }
+    }
 
-    /*! \brief  Function for serialization of the pressure field.
-     *
-     *  Function needed for restart option. Writes the pressure of a grid element to a restart file.
-     *
-     *  \param outstream Stream into the restart file.
-     *  \param element Grid element
-     */
+    /*! \name general methods for serialization, output */
+    //@{
+    // serialization methods
+    //! Function needed for restart option.
     void serializeEntity(std::ostream &outstream, const Element &element)
     {
-        int globalIdx = problem_.variables().index(element);
-        outstream << pressure_[globalIdx][0];
+        int numFaces = element.template count<1>();
+        for (int i=0; i < numFaces; i++)
+        {
+            int globalIdx = A_.faceMapper().map(element, i, 1);
+            outstream << pressTrace_[globalIdx][0];
+        }
     }
 
-    /*! \brief  Function for deserialization of the pressure field.
-     *
-     *  Function needed for restart option. Reads the pressure of a grid element from a restart file.
-     *
-     *  \param instream Stream from the restart file.
-     *  \param element Grid element
-     */
     void deserializeEntity(std::istream &instream, const Element &element)
     {
-        int globalIdx = problem_.variables().index(element);
-        instream >> pressure_[globalIdx][0];
-    }
-
-    /*! \brief Adds pressure output to the output file
-     *
-     * Adds the global pressure to the output.
-     *
-     * \tparam MultiWriter Class defining the output writer
-     * \param writer The output writer (usually a <tt>VTKMultiWriter</tt> object)
-     *
-     */
-    template<class MultiWriter>
-    void addOutputVtkFields(MultiWriter &writer)
-    {
-        ScalarSolution *pressure = writer.allocateManagedBuffer (problem_.gridView().size(0));
-
-        *pressure = pressure_;
-
-        writer.attachCellData(*pressure, "global pressure");
-
-        return;
+        int numFaces = element.template count<1>();
+        for (int i=0; i < numFaces; i++)
+        {
+            int globalIdx = A_.faceMapper().map(element, i, 1);
+            instream >> pressTrace_[globalIdx][0];
+        }
     }
+    //@}
 
     //! Constructs a MimeticPressure2P object
     /**
-     * \param problem A problem class object
+     * \param problem The Dumux problem
      */
     MimeticPressure2P(Problem& problem) :
     problem_(problem),
-    A_(problem.gridView())
+    A_(problem.gridView()), lstiff_(problem_, false, problem_.gridView())
     {
-        if (pressureType != pGlobal)
+        if (pressureType != pw && pressureType != pn)
         {
             DUNE_THROW(Dune::NotImplemented, "Pressure type not supported!");
         }
-        if (saturationType != sw)
+        if (saturationType != sw && saturationType != sn)
         {
             DUNE_THROW(Dune::NotImplemented, "Saturation type not supported!");
         }
+        if (GET_PROP_VALUE(TypeTag, EnableCompressibility))
+        {
+            DUNE_THROW(Dune::NotImplemented, "Compressibility not supported!");
+        }
+
+        density_[wPhaseIdx] = 0.0;
+        density_[nPhaseIdx] = 0.0;
+        viscosity_[wPhaseIdx] = 0.0;
+        viscosity_[nPhaseIdx] = 0.0;
+
+        vtkOutputLevel_ = GET_PARAM_FROM_GROUP(TypeTag, int, Vtk, OutputLevel);
     }
 
 private:
     Problem& problem_;
-    ScalarSolution pressure_;
-    PressureSolution pressTrace_; //!< vector of pressure traces
-    NormalVelType normalVelocity_;
-    RHSVector f_;
+    TraceType pressTrace_; //!< vector of pressure traces
+    TraceType f_;
     OperatorAssembler A_;
+    LocalStiffness lstiff_;
 
     Scalar density_[numPhases];
     Scalar viscosity_[numPhases];
-    static const int pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$ 0 = p_w \f$, \f$ 1 = p_n \f$, \f$ 2 = p_{global} \f$)
-    static const int saturationType = GET_PROP_VALUE(TypeTag, SaturationFormulation); //!< gives kind of saturation used (\f$ 0 = S_w \f$, \f$ 1 = S_n \f$)
+
+    int vtkOutputLevel_;
 };
 
 //solves the system of equations to get the spatial distribution of the pressure
@@ -319,74 +424,44 @@ void MimeticPressure2P<TypeTag>::solve()
     if (verboseLevelSolver)
     std::cout << "MimeticPressure2P: solve for pressure" << std::endl;
 
+//        printmatrix(std::cout, *A_, "global stiffness matrix", "row", 11, 3);
+//        printvector(std::cout, f_, "right hand side", "row", 10, 1, 3);
+
     Solver solver(problem_);
     solver.solve(*A_, pressTrace_, f_);
+
     return;
 }
 
-/*! \brief Updates constitutive relations and stores them in the variable class
- *
- * Stores mobility, fractional flow function and capillary pressure for all grid cells.
- */
+//constitutive functions are updated once if new saturations are calculated and stored in the variables object
 template<class TypeTag>
 void MimeticPressure2P<TypeTag>::updateMaterialLaws()
 {
-    // iterate through leaf grid an evaluate c0 at cell center
-    ElementIterator eItEnd = problem_.gridView().template end<0>();
-    for (ElementIterator eIt = problem_.gridView().template begin<0>(); eIt != eItEnd; ++eIt)
-    {
-        int globalIdx = problem_.variables().index(*eIt);
-
-        CellData& cellData = problem_.variables().cellData(globalIdx);
-
-        //determine phase saturations from primary saturation variable
+        // iterate through leaf grid an evaluate c0 at cell center
+        ElementIterator eItEnd = problem_.gridView().template end<0>();
+        for (ElementIterator eIt = problem_.gridView().template begin<0>(); eIt != eItEnd; ++eIt)
+        {
+            int globalIdx = problem_.variables().index(*eIt);
 
-        Scalar satW = cellData.saturation(wPhaseIdx);
-        Scalar pc = MaterialLaw::pc(problem_.spatialParams().materialLawParams(*eIt), satW);
+            CellData& cellData = problem_.variables().cellData(globalIdx);
 
-        cellData.setCapillaryPressure(pc);
+            Scalar satW = cellData.saturation(wPhaseIdx);
 
-        // initialize mobilities
-        Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(*eIt), satW) / viscosity_[wPhaseIdx];
-        Scalar mobilityNW = MaterialLaw::krn(problem_.spatialParams().materialLawParams(*eIt), satW) / viscosity_[nPhaseIdx];
+            // initialize mobilities
+            Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(*eIt), satW)
+                    / viscosity_[wPhaseIdx];
+            Scalar mobilityNW = MaterialLaw::krn(problem_.spatialParams().materialLawParams(*eIt), satW)
+                    / viscosity_[nPhaseIdx];
 
-        // initialize mobilities
-        cellData.setMobility(wPhaseIdx, mobilityW);
-        cellData.setMobility(nPhaseIdx, mobilityNW);
+            // initialize mobilities
+            cellData.setMobility(wPhaseIdx, mobilityW);
+            cellData.setMobility(nPhaseIdx, mobilityNW);
 
-        //initialize fractional flow functions
-        cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNW));
-        cellData.setFracFlowFunc(nPhaseIdx, mobilityNW / (mobilityW + mobilityNW));
-    }
-    return;
-}
-
-/*! \brief Globally stores the velocity solution at cell-cell interfaces*/
-template<class TypeTag>
-void MimeticPressure2P<TypeTag>::storeVelocity()
-{
-    // iterate through leaf grid an evaluate c0 at cell center
-    const ElementIterator &eItEnd = this->problem_.gridView().template end<0>();
-    for (ElementIterator eIt = this->problem_.gridView().template begin<0>(); eIt != eItEnd; ++eIt)
-    {
-        int globalIdx = problem_.variables().index(*eIt);
-
-        CellData& cellData = problem_.variables().cellData(globalIdx);
-
-        IntersectionIterator isIt = problem_.gridView().ibegin(*eIt);
-        const IntersectionIterator &isItEnd = problem_.gridView().iend(*eIt);
-        for (; isIt != isItEnd; ++isIt)
-        {
-            int idxInInside = isIt->indexInInside();
-            Dune::FieldVector<Scalar, dimWorld> velocity(isIt->centerUnitOuterNormal());
-            velocity*= normalVelocity_[globalIdx][idxInInside];
-            cellData.fluxData().setVelocity(wPhaseIdx, idxInInside, velocity);
-            cellData.fluxData().setUpwindPotential(wPhaseIdx, idxInInside, normalVelocity_[globalIdx][idxInInside]);
-            cellData.fluxData().setUpwindPotential(nPhaseIdx, idxInInside, normalVelocity_[globalIdx][idxInInside]);
+            //initialize fractional flow functions
+            cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNW));
+            cellData.setFracFlowFunc(nPhaseIdx, mobilityNW / (mobilityW + mobilityNW));
         }
-    }
-//    printvector(std::cout, problem_.variables().velocity(), "velocity", "row", 4, 1, 3);
-    return;
+        return;
 }
 
 }
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2padaptive.hh b/dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2padaptive.hh
new file mode 100644
index 0000000000..0f1f462629
--- /dev/null
+++ b/dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2padaptive.hh
@@ -0,0 +1,481 @@
+/*****************************************************************************
+ *   Copyright (C) 2011 by Markus Wolff                                      *
+ *   Copyright (C) 2007-2009 by Bernd Flemisch                               *
+ *   Institute for Modelling Hydraulic and Environmental Systems             *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Model for the pressure equation discretized by mimetic FD.
+ */
+#ifndef DUMUX_MIMETICPRESSURE2PADAPTIVE_HH
+#define DUMUX_MIMETICPRESSURE2PADAPTIVE_HH
+
+// dumux environment
+#include "dumux/decoupled/common/mimetic/mimeticproperties.hh"
+#include "dumux/decoupled/2p/diffusion/mimetic/mimeticoperator2padaptive.hh"
+#include "dumux/decoupled/2p/diffusion/mimetic/mimetic2padaptive.hh"
+
+namespace Dumux
+{
+
+/*! \ingroup Mimetic2p
+ *
+ * \brief mimetic method for the pressure equation
+ *
+ * Provides a mimetic implementation for the evaluation
+ * of equations of the form
+ * \f[\text{div}\, \boldsymbol{v}_{total} = q.\f]
+ * The definition of the total velocity \f$\boldsymbol{v}_total\f$ depends on the kind of pressure chosen. This could be a wetting (w) phase pressure leading to
+ * \f[ - \text{div}\,  \left[\lambda \boldsymbol{K} \left(\text{grad}\, p_w + f_n \text{grad}\, p_c + \sum f_\alpha \rho_\alpha g  \text{grad}\, z\right)\right] = q, \f]
+ * a non-wetting (n) phase pressure yielding
+ * \f[ - \text{div}\,  \left[\lambda \boldsymbol{K}  \left(\text{grad}\, p_n - f_w \text{grad}\, p_c + \sum f_\alpha \rho_\alpha g  \text{grad}\, z\right)\right] = q, \f]
+ * or a global pressure leading to
+ * \f[ - \text{div}\, \left[\lambda \boldsymbol{K} \left(\text{grad}\, p_{global} + \sum f_\alpha \rho_\alpha g  \text{grad}\, z\right)\right] = q.\f]
+ *  Here, \f$p\f$ denotes a pressure, \f$\boldsymbol{K}\f$ the absolute permeability, \f$\lambda\f$ the total mobility, possibly depending on the
+ * saturation,\f$f\f$ the fractional flow function of a phase, \f$\rho\f$ a phase density, \f$g\f$ the gravity constant and \f$q\f$ the source term.
+ * For all cases, \f$p = p_D\f$ on \f$\Gamma_{Neumann}\f$, and \f$\boldsymbol{v}_{total}  = q_N\f$
+ * on \f$\Gamma_{Dirichlet}\f$.
+ *
+ *\tparam TypeTag The Type Tag
+ */
+template<class TypeTag> class MimeticPressure2PAdaptive
+{
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename SpatialParams::MaterialLaw MaterialLaw;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+
+    enum
+    {
+        dim = GridView::dimension, dimWorld = GridView::dimensionworld
+    };
+    enum
+    {
+        pw = Indices::pressureW,
+        pn = Indices::pressureNW,
+        pglobal = Indices::pressureGlobal,
+        Sw = Indices::saturationW,
+        Sn = Indices::saturationNW,
+        vw = Indices::velocityW,
+        vn = Indices::velocityNW,
+        pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation), //!< gives kind of pressure used (\f$ 0 = p_w\f$, \f$ 1 = p_n\f$, \f$ 2 = p_{global}\f$)
+        saturationType = GET_PROP_VALUE(TypeTag, SaturationFormulation), //!< gives kind of saturation used (\f$ 0 = S_w\f$, \f$ 1 = S_n\f$)
+    };
+    enum
+    {
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
+    };
+
+    typedef typename GridView::Traits::template Codim<0>::Entity Element;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
+    typedef typename GridView::Grid Grid;
+    typedef typename GridView::template Codim<0>::EntityPointer ElementPointer;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+
+    typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix;
+    typedef Dune::FieldVector<Scalar, dim> DimVector;
+
+    typedef typename GET_PROP_TYPE(TypeTag, LocalStiffness) LocalStiffness;
+    typedef Dune::BlockVector< Dune::FieldVector<Scalar, 1> > TraceType;
+    typedef MimeticOperatorAssemblerTwoPAdaptive<TypeTag> OperatorAssembler;
+
+    typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData;
+    typedef typename GET_PROP(TypeTag, SolutionTypes)::ScalarSolution ScalarSolutionType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, PressureCoefficientMatrix) Matrix;
+    typedef typename GET_PROP_TYPE(TypeTag, PressureRHSVector) Vector;
+
+    typedef Dune::GenericReferenceElements<Scalar, dim> ReferenceElementContainer;
+    typedef Dune::GenericReferenceElement<Scalar, dim> ReferenceElement;
+
+    //initializes the matrix to store the system of equations
+    void initializeMatrix();
+
+    //function which assembles the system of equations to be solved
+    void assemble(bool first)
+    {
+        Scalar timeStep = problem_.timeManager().timeStepSize();
+        Scalar maxError = 0.0;
+        int size = problem_.gridView().size(0);
+        for (int i = 0; i < size; i++)
+        {
+            Scalar sat = 0;
+            switch (saturationType)
+            {
+            case Sw:
+                sat = problem_.variables().cellData(i).saturation(wPhaseIdx);
+                break;
+            case Sn:
+                sat = problem_.variables().cellData(i).saturation(nPhaseIdx);
+                break;
+            }
+            if (sat > 1.0)
+            {
+                maxError = std::max(maxError, (sat - 1.0) / timeStep);
+            }
+            if (sat < 0.0)
+            {
+                maxError = std::max(maxError, (-sat) / timeStep);
+            }
+        }
+
+        lstiff_.setErrorInfo(maxError, timeStep);
+        A_.assemble(lstiff_, pressTrace_, f_);
+        return;
+    }
+
+    //solves the system of equations to get the spatial distribution of the pressure
+    void solve();
+
+    void postprocess()
+    {
+            A_.calculatePressure(lstiff_, pressTrace_, problem_);
+
+        return;
+    }
+
+public:
+    //constitutive functions are initialized and stored in the variables object
+    void updateMaterialLaws();
+
+    void initialize(bool solveTwice = true)
+    {
+        ElementIterator element = problem_.gridView().template begin<0> ();
+        FluidState fluidState;
+        fluidState.setPressure(wPhaseIdx, problem_.referencePressure(*element));
+        fluidState.setPressure(nPhaseIdx, problem_.referencePressure(*element));
+        fluidState.setTemperature(problem_.temperature(*element));
+        fluidState.setSaturation(wPhaseIdx, 1.);
+        fluidState.setSaturation(nPhaseIdx, 0.);
+        density_[wPhaseIdx] = FluidSystem::density(fluidState, wPhaseIdx);
+        density_[nPhaseIdx] = FluidSystem::density(fluidState, nPhaseIdx);
+        viscosity_[wPhaseIdx] = FluidSystem::viscosity(fluidState, wPhaseIdx);
+        viscosity_[nPhaseIdx] = FluidSystem::viscosity(fluidState, nPhaseIdx);
+
+        updateMaterialLaws();
+        adapt();
+        lstiff_.initialize();
+        lstiff_.reset();
+
+        assemble(true);
+        solve();
+        postprocess();
+
+        return;
+    }
+
+    void adapt()
+    {
+        A_.adapt();
+        pressTrace_.resize(A_.intersectionMapper().size());
+        f_.resize(A_.intersectionMapper().size());
+        pressTrace_ = 0.0;
+        f_ = 0;
+        lstiff_.adapt();
+    }
+
+    void updateVelocity()
+    {
+        updateMaterialLaws();
+        postprocess();
+    }
+
+    void update()
+    {
+        if (problem_.gridAdapt().wasAdapted())
+        {
+            adapt();
+        }
+
+        lstiff_.reset();
+        assemble(false);
+
+        solve();
+
+        postprocess();
+
+        return;
+    }
+
+
+    //! \brief Write data files
+     /*  \param name file name */
+    template<class MultiWriter>
+    void addOutputVtkFields(MultiWriter &writer)
+    {
+        int size = problem_.gridView().size(0);
+        ScalarSolutionType *potential = writer.allocateManagedBuffer(size);
+        ScalarSolutionType *pressure = 0;
+        ScalarSolutionType *pressureSecond = 0;
+        ScalarSolutionType *potentialSecond = 0;
+        Dune::BlockVector < DimVector > *velocityWetting = 0;
+        Dune::BlockVector < DimVector > *velocityNonwetting = 0;
+
+        if (vtkOutputLevel_ > 0)
+        {
+            pressure = writer.allocateManagedBuffer(size);
+            pressureSecond = writer.allocateManagedBuffer(size);
+            potentialSecond = writer.allocateManagedBuffer(size);
+            velocityWetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
+            velocityNonwetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
+        }
+
+
+            ElementIterator eItBegin = problem_.gridView().template begin<0>();
+            ElementIterator eItEnd = problem_.gridView().template end<0>();
+            for (ElementIterator eIt = eItBegin; eIt != eItEnd; ++eIt)
+            {
+                int globalIdx = problem_.variables().index(*eIt);
+                CellData& cellData = problem_.variables().cellData(globalIdx);
+
+                if (pressureType == pw)
+                {
+                    (*potential)[globalIdx] = cellData.potential(wPhaseIdx);
+                }
+
+                if (pressureType == pn)
+                {
+                    (*potential)[globalIdx] = cellData.potential(nPhaseIdx);
+                }
+
+                if (vtkOutputLevel_ > 0)
+                {
+
+                if (pressureType == pw)
+                {
+                    (*pressure)[globalIdx] = cellData.pressure(wPhaseIdx);
+                    (*potentialSecond)[globalIdx] = cellData.potential(nPhaseIdx);
+                    (*pressureSecond)[globalIdx] = cellData.pressure(nPhaseIdx);
+                }
+
+                if (pressureType == pn)
+                {
+                    (*pressure)[globalIdx] = cellData.pressure(nPhaseIdx);
+                    (*potentialSecond)[globalIdx] = cellData.potential(wPhaseIdx);
+                    (*pressureSecond)[globalIdx] = cellData.pressure(wPhaseIdx);
+                }
+
+                Dune::FieldVector < Scalar, 2 * dim > fluxW(0);
+                Dune::FieldVector < Scalar, 2 * dim > fluxNw(0);
+
+                // run through all intersections with neighbors and boundary
+                IntersectionIterator isItEnd = problem_.gridView().iend(*eIt);
+                for (IntersectionIterator isIt = problem_.gridView().ibegin(*eIt); isIt != isItEnd; ++isIt)
+                {
+                    int isIndex = isIt->indexInInside();
+
+                    fluxW[isIndex] += isIt->geometry().volume()
+                        * (isIt->centerUnitOuterNormal() * cellData.fluxData().velocity(wPhaseIdx, isIndex));
+                    fluxNw[isIndex] += isIt->geometry().volume()
+                        * (isIt->centerUnitOuterNormal() * cellData.fluxData().velocity(nPhaseIdx, isIndex));
+                }
+
+                DimVector refVelocity(0);
+                refVelocity[0] = 0.5 * (fluxW[1] - fluxW[0]);
+                refVelocity[1] = 0.5 * (fluxW[3] - fluxW[2]);
+                refVelocity[2] = 0.5 * (fluxW[5] - fluxW[4]);
+
+                const DimVector& localPos = ReferenceElementContainer::general(eIt->geometry().type()).position(0, 0);
+
+                // get the transposed Jacobian of the element mapping
+                const DimMatrix& jacobianT = eIt->geometry().jacobianTransposed(localPos);
+
+                // calculate the element velocity by the Piola transformation
+                DimVector elementVelocity(0);
+                jacobianT.umtv(refVelocity, elementVelocity);
+                elementVelocity /= eIt->geometry().integrationElement(localPos);
+
+                (*velocityWetting)[globalIdx] = elementVelocity;
+
+                refVelocity = 0;
+                refVelocity[0] = 0.5 * (fluxNw[1] - fluxNw[0]);
+                refVelocity[1] = 0.5 * (fluxNw[3] - fluxNw[2]);
+                refVelocity[2] = 0.5 * (fluxNw[5] - fluxNw[4]);
+
+                // calculate the element velocity by the Piola transformation
+                elementVelocity = 0;
+                jacobianT.umtv(refVelocity, elementVelocity);
+                elementVelocity /= eIt->geometry().integrationElement(localPos);
+
+                (*velocityNonwetting)[globalIdx] = elementVelocity;
+                }
+            }
+
+            if (pressureType == pw)
+            {
+                writer.attachCellData(*potential, "wetting potential");
+            }
+
+            if (pressureType == pn)
+            {
+                writer.attachCellData(*potential, "nonwetting potential");
+            }
+
+            if (vtkOutputLevel_ > 0)
+            {
+            if (pressureType == pw)
+            {
+                writer.attachCellData(*pressure, "wetting pressure");
+                writer.attachCellData(*pressureSecond, "nonwetting pressure");
+                writer.attachCellData(*potentialSecond, "nonwetting potential");
+            }
+
+            if (pressureType == pn)
+            {
+                writer.attachCellData(*pressure, "nonwetting pressure");
+                writer.attachCellData(*pressureSecond, "wetting pressure");
+                writer.attachCellData(*potentialSecond, "wetting potential");
+            }
+
+            writer.attachCellData(*velocityWetting, "wetting-velocity", dim);
+            writer.attachCellData(*velocityNonwetting, "non-wetting-velocity", dim);
+            }
+    }
+
+    /*! \name general methods for serialization, output */
+    //@{
+    // serialization methods
+    //! Function needed for restart option.
+    void serializeEntity(std::ostream &outstream, const Element &element)
+    {
+        int numFaces = element.template count<1>();
+        for (int i=0; i < numFaces; i++)
+        {
+            int globalIdx = A_.intersectionMapper().map(element, i);
+            outstream << pressTrace_[globalIdx][0];
+        }
+    }
+
+    void deserializeEntity(std::istream &instream, const Element &element)
+    {
+        int numFaces = element.template count<1>();
+        for (int i=0; i < numFaces; i++)
+        {
+            int globalIdx = A_.intersectionMapper().map(element, i);
+            instream >> pressTrace_[globalIdx][0];
+        }
+    }
+    //@}
+
+    //! Constructs a MimeticPressure2PAdaptive object
+    /**
+     * \param problem The Dumux problem
+     */
+    MimeticPressure2PAdaptive(Problem& problem) :
+    problem_(problem),
+    A_(problem.gridView()), lstiff_(problem_, false, problem_.gridView(), A_.intersectionMapper())
+    {
+        if (pressureType != pw && pressureType != pn)
+        {
+            DUNE_THROW(Dune::NotImplemented, "Pressure type not supported!");
+        }
+        if (saturationType != Sw && saturationType != Sn)
+        {
+            DUNE_THROW(Dune::NotImplemented, "Saturation type not supported!");
+        }
+        if (GET_PROP_VALUE(TypeTag, EnableCompressibility))
+        {
+            DUNE_THROW(Dune::NotImplemented, "Compressibility not supported!");
+        }
+
+        density_[wPhaseIdx] = 0.0;
+        density_[nPhaseIdx] = 0.0;
+        viscosity_[wPhaseIdx] = 0.0;
+        viscosity_[nPhaseIdx] = 0.0;
+
+        vtkOutputLevel_ = GET_PARAM_FROM_GROUP(TypeTag, int, Vtk, OutputLevel);
+    }
+
+private:
+    Problem& problem_;
+    TraceType pressTrace_; //!< vector of pressure traces
+    TraceType f_;
+    OperatorAssembler A_;
+    LocalStiffness lstiff_;
+
+    Scalar density_[numPhases];
+    Scalar viscosity_[numPhases];
+
+    int vtkOutputLevel_;
+};
+
+//solves the system of equations to get the spatial distribution of the pressure
+template<class TypeTag>
+void MimeticPressure2PAdaptive<TypeTag>::solve()
+{
+    typedef typename GET_PROP_TYPE(TypeTag, LinearSolver) Solver;
+
+    int verboseLevelSolver = GET_PARAM_FROM_GROUP(TypeTag, int, LinearSolver, Verbosity);
+
+    if (verboseLevelSolver)
+    std::cout << "MimeticPressure2PAdaptive: solve for pressure" << std::endl;
+
+    Solver solver(problem_);
+    solver.solve(*A_, pressTrace_, f_);
+
+//                                    printmatrix(std::cout, *A_, "global stiffness matrix", "row", 11, 3);
+//                                    printvector(std::cout, f_, "right hand side", "row", 200, 1, 3);
+//                printvector(std::cout, pressTrace_, "pressure", "row", 200, 1, 3);
+    return;
+}
+
+//constitutive functions are updated once if new saturations are calculated and stored in the variables object
+template<class TypeTag>
+void MimeticPressure2PAdaptive<TypeTag>::updateMaterialLaws()
+{
+    // iterate through leaf grid an evaluate c0 at cell center
+    ElementIterator eItEnd = problem_.gridView().template end<0>();
+    for (ElementIterator eIt = problem_.gridView().template begin<0>(); eIt != eItEnd; ++eIt)
+    {
+        int globalIdx = problem_.variables().index(*eIt);
+
+        CellData& cellData = problem_.variables().cellData(globalIdx);
+
+        Scalar satW = cellData.saturation(wPhaseIdx);
+
+        // initialize mobilities
+        Scalar mobilityW = MaterialLaw::krw(problem_.spatialParams().materialLawParams(*eIt), satW)
+                / viscosity_[wPhaseIdx];
+        Scalar mobilityNW = MaterialLaw::krn(problem_.spatialParams().materialLawParams(*eIt), satW)
+                / viscosity_[nPhaseIdx];
+
+        // initialize mobilities
+        cellData.setMobility(wPhaseIdx, mobilityW);
+        cellData.setMobility(nPhaseIdx, mobilityNW);
+
+        //initialize fractional flow functions
+        cellData.setFracFlowFunc(wPhaseIdx, mobilityW / (mobilityW + mobilityNW));
+        cellData.setFracFlowFunc(nPhaseIdx, mobilityNW / (mobilityW + mobilityNW));
+    }
+    return;
+}
+
+
+
+}
+#endif
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimeticpressureproperties2p.hh b/dumux/decoupled/2p/diffusion/mimetic/mimeticpressureproperties2p.hh
index 0be450181a..39b197ff63 100644
--- a/dumux/decoupled/2p/diffusion/mimetic/mimeticpressureproperties2p.hh
+++ b/dumux/decoupled/2p/diffusion/mimetic/mimeticpressureproperties2p.hh
@@ -1,7 +1,12 @@
 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 // vi: set et ts=4 sw=4 sts=4:
 /*****************************************************************************
- *   See the file COPYING for full copying permissions.                      *
+ *   Copyright (C) 2008-2009 by Markus Wolff                                 *
+ *   Copyright (C) 2008-2009 by Andreas Lauser                               *
+ *   Copyright (C) 2008 by Bernd Flemisch                                    *
+ *   Institute of Hydraulic Engineering                                      *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
  *                                                                           *
  *   This program is free software: you can redistribute it and/or modify    *
  *   it under the terms of the GNU General Public License as published by    *
@@ -10,20 +15,20 @@
  *                                                                           *
  *   This program is distributed in the hope that it will be useful,         *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
  *   GNU General Public License for more details.                            *
  *                                                                           *
  *   You should have received a copy of the GNU General Public License       *
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
  *****************************************************************************/
 /*!
- * \ingroup MimeticPressure2p
- * \ingroup IMPETProperties
+ * \ingroup IMPES
+ * \ingroup Properties
  */
 /*!
  * \file
  *
- * \brief Defines the properties required for a two-phase mimetic finite differences model.
+ * \brief Defines the properties required for (immiscible) twophase sequential models.
  */
 
 #ifndef DUMUX_MIMETICPROPERTIES2P_DECOUPLED_HH
@@ -49,7 +54,7 @@ namespace Properties
 // Type tags
 //////////////////////////////////////////////////////////////////
 
-//! The type tag for two-phase problems using a mimetic finite differences method.
+//! The type tag for the two-phase problems
 NEW_TYPE_TAG(MimeticPressureTwoP, INHERITS_FROM(PressureTwoP, Mimetic))
 ;
 
@@ -60,16 +65,14 @@ NEW_TYPE_TAG(MimeticPressureTwoP, INHERITS_FROM(PressureTwoP, Mimetic))
 }
 
 #include <dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2p.hh>
-#include <dumux/decoupled/2p/diffusion/mimetic/mimeticgroundwater.hh>
+#include <dumux/decoupled/2p/diffusion/mimetic/mimetic2p.hh>
 
 namespace Dumux
 {
 namespace Properties
 {
-//! Set mimetic finite differences implementation of the two-phase pressure equation as default pressure model
 SET_TYPE_PROP(MimeticPressureTwoP, PressureModel, MimeticPressure2P<TypeTag>);
-//! Set the local stiffness implementation for the two-phase model
-SET_TYPE_PROP(MimeticPressureTwoP, LocalStiffness, MimeticGroundwaterEquationLocalStiffness<TypeTag>);
+SET_TYPE_PROP(MimeticPressureTwoP, LocalStiffness, MimeticTwoPLocalStiffness<TypeTag>);
 }
 }
 
diff --git a/dumux/decoupled/2p/diffusion/mimetic/mimeticpressureproperties2padaptive.hh b/dumux/decoupled/2p/diffusion/mimetic/mimeticpressureproperties2padaptive.hh
new file mode 100644
index 0000000000..6962b76c0d
--- /dev/null
+++ b/dumux/decoupled/2p/diffusion/mimetic/mimeticpressureproperties2padaptive.hh
@@ -0,0 +1,79 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   Copyright (C) 2008-2009 by Markus Wolff                                 *
+ *   Copyright (C) 2008-2009 by Andreas Lauser                               *
+ *   Copyright (C) 2008 by Bernd Flemisch                                    *
+ *   Institute of Hydraulic Engineering                                      *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup IMPES
+ * \ingroup Properties
+ */
+/*!
+ * \file
+ *
+ * \brief Defines the properties required for (immiscible) twophase sequential models.
+ */
+
+#ifndef DUMUX_MIMETICPROPERTIES2PADAPTIVE_DECOUPLED_HH
+#define DUMUX_MIMETICPROPERTIES2PADAPTIVE_DECOUPLED_HH
+
+//Dumux-includes
+#include <dumux/decoupled/2p/diffusion/diffusionproperties2p.hh>
+#include <dumux/decoupled/common/mimetic/mimeticproperties.hh>
+namespace Dumux
+{
+
+////////////////////////////////
+// forward declarations
+////////////////////////////////
+
+
+////////////////////////////////
+// properties
+////////////////////////////////
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tag for the two-phase problems
+NEW_TYPE_TAG(MimeticPressureTwoPAdaptive, INHERITS_FROM(PressureTwoP, Mimetic))
+;
+
+//////////////////////////////////////////////////////////////////
+// Property tags
+//////////////////////////////////////////////////////////////////
+}
+}
+
+#include <dumux/decoupled/2p/diffusion/mimetic/mimeticpressure2padaptive.hh>
+#include <dumux/decoupled/2p/diffusion/mimetic/mimetic2padaptive.hh>
+
+namespace Dumux
+{
+namespace Properties
+{
+SET_TYPE_PROP(MimeticPressureTwoPAdaptive, PressureModel, MimeticPressure2PAdaptive<TypeTag>);
+SET_TYPE_PROP(MimeticPressureTwoPAdaptive, LocalStiffness, MimeticTwoPLocalStiffnessAdaptive<TypeTag>);
+}
+}
+
+#endif
-- 
GitLab