diff --git a/dumux/decoupled/2p/diffusion/fv/fvpressure2p.hh b/dumux/decoupled/2p/diffusion/fv/fvpressure2p.hh
index c5d04d53eeaaf1c3d5035995dcc0636194572903..77c046ede075d4aa627c92f0008c84b19138be63 100644
--- a/dumux/decoupled/2p/diffusion/fv/fvpressure2p.hh
+++ b/dumux/decoupled/2p/diffusion/fv/fvpressure2p.hh
@@ -99,11 +99,6 @@ template<class TypeTag> class FVPressure2P: public FVPressure<TypeTag>
         wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx, numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
     };
 
-    enum
-    {
-        rhs = ParentType::rhs, matrix = ParentType::matrix,
-    };
-
     typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     typedef typename GridView::Traits::template Codim<0>::Entity Element;
     typedef typename GridView::template Codim<0>::EntityPointer ElementPointer;
@@ -113,6 +108,12 @@ template<class TypeTag> class FVPressure2P: public FVPressure<TypeTag>
     typedef Dune::FieldMatrix<Scalar, dim, dim> FieldMatrix;
 
 public:
+
+    enum
+    {
+        rhs = ParentType::rhs, matrix = ParentType::matrix,
+    };
+
     void getSource(Dune::FieldVector<Scalar, 2>&, const Element&, const CellData&, const bool);
 
     void getStorage(Dune::FieldVector<Scalar, 2>&, const Element&, const CellData&, const bool);
@@ -201,8 +202,6 @@ public:
             }
         }
 
-        updateMaterialLaws();
-
         ParentType::update();
 
         storePressureSolution();
@@ -217,6 +216,7 @@ public:
         {
             CellData& cellData = problem_.variables().cellData(i);
             storePressureSolution(i, cellData);
+            cellData.fluxData().resetVelocity();
         }
     }
 
diff --git a/dumux/decoupled/2p/diffusion/fv/fvpressure2padaptive.hh b/dumux/decoupled/2p/diffusion/fv/fvpressure2padaptive.hh
index 177cd765206c6ce6ea6a0bf24cd83202d7168eeb..36921788bac1075dfb5b435eb691e9b608128cd6 100644
--- a/dumux/decoupled/2p/diffusion/fv/fvpressure2padaptive.hh
+++ b/dumux/decoupled/2p/diffusion/fv/fvpressure2padaptive.hh
@@ -26,7 +26,7 @@
 
 // dumux environment
 #include <dumux/decoupled/2p/2pproperties.hh>
-
+#include <dumux/decoupled/2p/diffusion/fv/fvpressure2p.hh>
 
 /**
  * @file
@@ -55,12 +55,13 @@ namespace Dumux
  *
  * \tparam TypeTag The Type Tag
  */
-template<class TypeTag> class FVPressure2Padaptive
+template<class TypeTag> class FVPressure2Padaptive: public FVPressure2P<TypeTag>
 {
+    typedef FVPressure2P<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;
-    typedef typename GET_PROP_TYPE(TypeTag, Variables) Variables;
 
     typedef typename GET_PROP_TYPE(TypeTag, SpatialParameters) SpatialParameters;
     typedef typename SpatialParameters::MaterialLaw MaterialLaw;
@@ -73,6 +74,7 @@ template<class TypeTag> class FVPressure2Padaptive
     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;
 
     enum
     {
@@ -92,164 +94,37 @@ template<class TypeTag> class FVPressure2Padaptive
     };
     enum
     {
-        wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx
+        wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx, numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
+    };
+
+    enum
+    {
+        rhs = ParentType::rhs, matrix = ParentType::matrix,
     };
 
     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::Intersection Intersection;
     typedef typename GridView::IntersectionIterator IntersectionIterator;
 
     typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
     typedef Dune::FieldMatrix<Scalar, dim, dim> FieldMatrix;
 
-    typedef typename GET_PROP_TYPE(TypeTag, PressureCoefficientMatrix) Matrix;
-    typedef typename GET_PROP_TYPE(TypeTag, PressureRHSVector) Vector;
-
-    //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);
-
-    //solves the system of equations to get the spatial distribution of the pressure
-    void solve();
-
-protected:
-    Problem& problem()
-    {
-        return problem_;
-    }
-
-    const Problem& problem() const
-    {
-        return problem_;
-    }
-
 public:
-    //! updates and stores constitutive relations
-    void updateMaterialLaws();
-    //! \copydoc Dumux::FVPressure1P::initialize()
-    void initialize(bool solveTwice = true)
-    {
-        updateMaterialLaws();
+    void getFlux(Dune::FieldVector<Scalar, 2>&, const Intersection&, const CellData&, const bool);
 
-        assemble(true);
-        solve();
-        if (solveTwice)
-        {
-            Dune::BlockVector<Dune::FieldVector<Scalar, 1> > pressureOld(this->problem().variables().pressure());
-
-            assemble(false);
-            solve();
-
-            Dune::BlockVector<Dune::FieldVector<Scalar, 1> > pressureDiff(pressureOld);
-            pressureDiff -= this->problem().variables().pressure();
-            pressureOld = this->problem().variables().pressure();
-            Scalar pressureNorm = pressureDiff.infinity_norm();
-            pressureNorm /= pressureOld.infinity_norm();
-            int numIter = 0;
-            while (pressureNorm > 1e-5 && numIter < 10)
-            {
-                updateMaterialLaws();
-                assemble(false);
-                solve();
-
-                pressureDiff = pressureOld;
-                pressureDiff -= this->problem().variables().pressure();
-                pressureNorm = pressureDiff.infinity_norm();
-                pressureOld = this->problem().variables().pressure();
-                pressureNorm /= pressureOld.infinity_norm();
-
-                numIter++;
-            }
-            //            std::cout<<"Pressure defect = "<<pressureNorm<<"; "<<numIter<<" Iterations needed for initial pressure field"<<std::endl;
-        }
-        return;
-    }
-    //! \copydoc Dumux::FVPressure1P::pressure()
-    void pressure(bool solveTwice = true)
-    {
-        assemble(false);
-        solve();
-
-        return;
-    }
-    //! updates the pressure field (analog to update function in Dumux::IMPET)
+    //pressure solution routine: update estimate for secants, assemble, solve.
     void update()
     {
-        updateMaterialLaws();
-
-        pressure(false);
-
-        return;
-    }
-
-    // serialization methods
-    //! \copydoc Dumux::FVPressure1P::serialize(Restarter &res)
-    template<class Restarter>
-    void serialize(Restarter &res)
-    {
-        return;
-    }
-
-    //! \copydoc Dumux::FVPressure1P::deserialize(Restarter &res)
-    template<class Restarter>
-    void deserialize(Restarter &res)
-    {
-        return;
-    }
-
-    //! \copydoc Dumux::FVPressure1P::addOutputVtkFields(MultiWriter &writer)
-    template<class MultiWriter>
-    void addOutputVtkFields(MultiWriter &writer)
-    {
-        typename Variables::ScalarSolutionType *pressure = writer.allocateManagedBuffer (problem_.gridView().size(0));
-
-        *pressure = problem_.variables().pressure();
-
-        if (pressureType == pw)
-        {
-        writer.attachCellData(*pressure, "wetting pressure");
-        }
-
-        if (pressureType == pn)
-        {
-        writer.attachCellData(*pressure, "nonwetting pressure");
-        }
-
-        if (pressureType == pglobal)
-        {
-        writer.attachCellData(*pressure, "global pressure");
-        }
+        int gridSize = problem_.gridView().size(0);
+        // update RHS vector, matrix
+        this->A_.setSize(gridSize, gridSize); //
+        this->f_.resize(gridSize);
+        this->pressure().resize(gridSize);
 
-        // output  phase-dependent stuff
-        typename Variables::ScalarSolutionType *pC = writer.allocateManagedBuffer (problem_.gridView().size(0));
-        *pC = problem_.variables().capillaryPressure();
-        writer.attachCellData(*pC, "capillary pressure");
+        ParentType::initializeMatrix();
 
-        typename Variables::ScalarSolutionType *densityWetting = writer.allocateManagedBuffer (problem_.gridView().size(0));
-        *densityWetting = problem_.variables().densityWetting();
-        writer.attachCellData(*densityWetting, "wetting density");
-
-        typename Variables::ScalarSolutionType *densityNonwetting = writer.allocateManagedBuffer (problem_.gridView().size(0));
-        *densityNonwetting = problem_.variables().densityNonwetting();
-        writer.attachCellData(*densityNonwetting, "nonwetting density");
-
-        typename Variables::ScalarSolutionType *viscosityWetting = writer.allocateManagedBuffer (problem_.gridView().size(0));
-        *viscosityWetting = problem_.variables().viscosityWetting();
-        writer.attachCellData(*viscosityWetting, "wetting viscosity");
-
-        typename Variables::ScalarSolutionType *viscosityNonwetting = writer.allocateManagedBuffer (problem_.gridView().size(0));
-        *viscosityNonwetting = problem_.variables().viscosityNonwetting();
-        writer.attachCellData(*viscosityNonwetting, "nonwetting viscosity");
-
-//        typename Variables::ScalarSolutionType *saturation = writer.allocateManagedBuffer (problem_.gridView().size(0));
-//
-//        *saturation = problem_.variables().saturation();
-//
-//        writer.attachCellData(*saturation, "wetting saturation");
+        ParentType::update();
 
         return;
     }
@@ -259,966 +134,318 @@ public:
      * \param problem a problem class object
      */
     FVPressure2Padaptive(Problem& problem) :
-        problem_(problem), A_(problem.variables().gridSize(), problem.variables().gridSize(), (4 * dim + 1)
-                * problem.variables().gridSize(), Matrix::random), f_(problem.variables().gridSize()),
-                gravity(problem.gravity())
-//        problem_(problem), A_(problem.variables().gridSize(), problem.variables().gridSize(), (4 * dim + 1)
-//                * problem.variables().gridSize(), Matrix::random), f_(problem.variables().gridSize()),
-//                gravity(problem.gravity())
-    {// Comment: the term (4 * dim + 1) only works in the 2D case (or less). For 3D applications, it has to be (8*dim+1)
-        if (pressureType != pw && pressureType != pn && pressureType != pglobal)
+            ParentType(problem), problem_(problem), gravity_(problem.gravity())
+    {
+        if (pressureType_ != pw && pressureType_ != pn && pressureType_ != pglobal)
         {
             DUNE_THROW(Dune::NotImplemented, "Pressure type not supported!");
         }
-        if (saturationType != Sw && saturationType != Sn)
+        if (pressureType_ == pglobal && compressibility_)
+        {
+            DUNE_THROW(Dune::NotImplemented, "Compressibility not supported for global pressure!");
+        }
+        if (saturationType_ != Sw && saturationType_ != Sn)
         {
             DUNE_THROW(Dune::NotImplemented, "Saturation type not supported!");
         }
 
-        initializeMatrix();
+        if (!compressibility_)
+        {
+            const Element& 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);
+        }
     }
 
 private:
     Problem& problem_;
-    Matrix A_;
-    Dune::BlockVector<Dune::FieldVector<Scalar, 1> > f_;
-protected:
-    const GlobalPosition& gravity; //!< vector including the gravity constant
-    static const bool compressibility = GET_PROP_VALUE(TypeTag, EnableCompressibility);
-    static const int pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$p_w\f$, \f$p_n\f$, \f$p_{global}\f$)
-    static const int saturationType = GET_PROP_VALUE(TypeTag, SaturationFormulation); //!< gives kind of saturation used (\f$S_w\f$, \f$S_n\f$)
+    const GlobalPosition& gravity_; //!< vector including the gravity constant
+
+    Scalar density_[numPhases];
+    Scalar viscosity_[numPhases];
+
+    static const bool compressibility_ = GET_PROP_VALUE(TypeTag, EnableCompressibility);
+    static const int pressureType_ = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$p_w\f$, \f$p_n\f$, \f$p_{global}\f$)
+    static const int saturationType_ = GET_PROP_VALUE(TypeTag, SaturationFormulation); //!< gives kind of saturation used (\f$S_w\f$, \f$S_n\f$)
 };
 
-//initializes the matrix to store the system of equations
+//!function which assembles the system of equations to be solved. Only works for 2D.
 template<class TypeTag>
-void FVPressure2Padaptive<TypeTag>::initializeMatrix()
+void FVPressure2Padaptive<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries, const Intersection& intersection
+        , const CellData& cellDataI, const bool first)
 {
-    // determine matrix row sizes
-    ElementIterator eItEnd = problem_.gridView().template end<0> ();
-    for (ElementIterator eIt = problem_.gridView().template begin<0> (); eIt != eItEnd; ++eIt)
+    ElementPointer elementI = intersection.inside();
+    ElementPointer elementJ = intersection.outside();
+
+    if (elementI->level() == elementJ->level())
     {
-        // cell index
-        int globalIdxI = problem_.variables().index(*eIt);
-
-        // initialize row size
-        int rowSize = 1;
-
-        // run through all intersections with neighbors
-        IntersectionIterator isItEnd = problem_.gridView().iend(*eIt);
-        for (IntersectionIterator isIt = problem_.gridView().ibegin(*eIt); isIt != isItEnd; ++isIt)
-            if (isIt->neighbor())
-                rowSize++;
-        A_.setrowsize(globalIdxI, rowSize);
+        ParentType::getFlux(entries, intersection, cellDataI, first);
     }
-    A_.endrowsizes();
-
-    // determine position of matrix entries
-    for (ElementIterator eIt = problem_.gridView().template begin<0> (); eIt != eItEnd; ++eIt)
+    // hanging node situation: neighbor has higher level
+    else if (elementJ->level() == elementI->level() + 1)
     {
-        // cell index
-        int globalIdxI = problem_.variables().index(*eIt);
+        const CellData& cellDataJ = problem_.variables().cellData(problem_.variables().index(*elementJ));
+
+        // get global coordinates of cell centers
+        const GlobalPosition& globalPosI = elementI->geometry().center();
+        const GlobalPosition& globalPosJ = elementJ->geometry().center();
 
-        // add diagonal index
-        A_.addindex(globalIdxI, globalIdxI);
+        int globalIdxI = problem_.variables().index(*elementI);
+        int globalIdxJ = problem_.variables().index(*elementJ);
 
-        // run through all intersections with neighbors
-        IntersectionIterator isItEnd = problem_.gridView().iend(*eIt);
-        for (IntersectionIterator isIt = problem_.gridView().ibegin(*eIt); isIt != isItEnd; ++isIt)
-            if (isIt->neighbor())
+        // get mobilities and fractional flow factors
+        Scalar lambdaWI = cellDataI.mobility(wPhaseIdx);
+        Scalar lambdaNWI = cellDataI.mobility(nPhaseIdx);
+        Scalar fractionalWI = cellDataI.fracFlowFunc(wPhaseIdx);
+        Scalar fractionalNWI = cellDataI.fracFlowFunc(nPhaseIdx);
+        Scalar lambdaWJ = cellDataJ.mobility(wPhaseIdx);
+        Scalar lambdaNWJ = cellDataJ.mobility(nPhaseIdx);
+        Scalar fractionalWJ = cellDataJ.fracFlowFunc(wPhaseIdx);
+        Scalar fractionalNWJ = cellDataJ.fracFlowFunc(nPhaseIdx);
+
+        // get capillary pressure
+        Scalar pcI = cellDataI.capillaryPressure();
+        Scalar pcJ = cellDataJ.capillaryPressure();
+
+        //get face index
+        int isIndexI = intersection.indexInInside();
+
+        //get face normal
+        const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
+
+        // get face area
+        Scalar faceArea = intersection.geometry().volume();
+
+        // distance vector between barycenters
+        GlobalPosition distVecIJ = globalPosJ - globalPosI;
+
+        // compute distance between cell centers
+        Scalar distIJ = distVecIJ.two_norm();
+
+        // Count number of hanging nodes
+        // not really necessary
+        int isIndexJ = intersection.indexInOutside();
+        int globalIdxK = 0;
+        ElementPointer elementK = intersection.outside();
+        // We are looking for two things:
+        // IsIndexJ, the index of the interface from the neighbor-cell point of view
+        // GlobalIdxK, the index of the third cell
+        // Intersectioniterator around cell I
+        IntersectionIterator isItEndI = problem_.gridView().iend(*elementI);
+        for (IntersectionIterator isItI = problem_.gridView().ibegin(*elementI); isItI != isItEndI; ++isItI)
+        {
+            if (isItI->neighbor())
             {
-                // access neighbor
-                ElementPointer outside = isIt->outside();
-                int globalIdxJ = problem_.variables().index(*outside);
+                ElementPointer neighborPointer2 = isItI->outside();
 
-                // add off diagonal index
-                A_.addindex(globalIdxI, globalIdxJ);
+                // make sure we do not chose elemntI as third element
+                // -> faces with hanging node have more than one intersection but only one face index!
+                if (neighborPointer2 != elementJ && isItI->indexInInside() == isIndexI)
+                {
+                    globalIdxK = problem_.variables().index(*neighborPointer2);
+                    elementK = neighborPointer2;
+                    break;
+                }
             }
-    }
-    A_.endindices();
+        }
 
-    return;
-}
+        const CellData& cellDataK = problem_.variables().cellData(globalIdxK);
 
-//!function which assembles the system of equations to be solved. Only works for 2D.
-template<class TypeTag>
-void FVPressure2Padaptive<TypeTag>::assemble(bool first)
-{
-	updateMaterialLaws();
-	// Adapt size of matrix A_ and Vector f_
-	{int size = problem_.variables().gridSize();
-	A_.setSize(size,size);
-	f_.resize(size);}
-	initializeMatrix(); // define non-zero entries in matrix
+        // neighbor cell center in global coordinates
+        const GlobalPosition& globalPosInterface = intersection.geometry().center();
 
-    // initialization: set matrix A_ to zero
-    A_ = 0;
-    f_ = 0;
+        Dune::FieldVector < Scalar, dimWorld > distVec = globalPosInterface - globalPosI;
+        Scalar lI = distVec * unitOuterNormal;
+        distVec = globalPosJ - globalPosInterface;
+        Scalar lJ = distVec * unitOuterNormal;
+        Scalar l = lI + lJ;
 
-    int nodecount = 0;
+        FieldMatrix permeabilityI(0);
+        FieldMatrix permeabilityJ(0);
+        FieldMatrix permeabilityK(0);
 
-    BoundaryTypes bcType;
+        problem_.spatialParameters().meanK(permeabilityI,
+                problem_.spatialParameters().intrinsicPermeability(*elementI));
+        problem_.spatialParameters().meanK(permeabilityJ,
+                problem_.spatialParameters().intrinsicPermeability(*elementJ));
+        problem_.spatialParameters().meanK(permeabilityK,
+                problem_.spatialParameters().intrinsicPermeability(*elementK));
 
-    ElementIterator eItEnd = problem_.gridView().template end<0> ();
-    for (ElementIterator eIt = problem_.gridView().template begin<0> (); eIt != eItEnd; ++eIt)
-    {
-        // cell index
-        int globalIdxI = problem_.variables().index(*eIt);
+        // Calculate permeablity component normal to interface
+        Scalar kI, kJ, kK, kMean, ng;
+        Dune::FieldVector < Scalar, dim > permI(0);
+        Dune::FieldVector < Scalar, dim > permJ(0);
+        Dune::FieldVector < Scalar, dim > permK(0);
 
-        // get global coordinate of cell center
-        const GlobalPosition& globalPos = eIt->geometry().center();
+        permeabilityI.mv(unitOuterNormal, permI);
+        permeabilityJ.mv(unitOuterNormal, permJ);
+        permeabilityK.mv(unitOuterNormal, permK);
 
+        // kI,kJ,kK=(n^T)Kn
+        kI = unitOuterNormal * permI;
+        kJ = unitOuterNormal * permJ;
+        kK = unitOuterNormal * permK;
 
-        // cell volume, assume linear map here
-        Scalar volume = eIt->geometry().volume();
+        // See Diplomarbeit Michael Sinsbeck
+        kMean = kI * kJ * kK * l / (kJ * kK * lI + kI * (kJ + kK) / 2 * lJ);
 
-        Scalar densityWI = problem_.variables().densityWetting(globalIdxI);
-        Scalar densityNWI = problem_.variables().densityNonwetting(globalIdxI);
+        ng = gravity_ * unitOuterNormal;
 
-        // set sources
-        PrimaryVariables source(0.0);
-        problem().source(source, *eIt);
-        if (!compressibility)
-        {
-            source[wPhaseIdx] /= densityWI;
-            source[nPhaseIdx] /= densityNWI;
-        }
-        f_[globalIdxI] += volume * (source[wPhaseIdx] + source[nPhaseIdx]);
+        Scalar lambdaWK = cellDataK.mobility(wPhaseIdx);
+        Scalar lambdaNWK = cellDataK.mobility(nPhaseIdx);
+        Scalar fractionalWK = cellDataK.fracFlowFunc(wPhaseIdx);
+        Scalar fractionalNWK = cellDataK.fracFlowFunc(nPhaseIdx);
 
-        Scalar porosity = problem_.spatialParameters().porosity(*eIt);
+        Scalar pcK = cellDataK.capillaryPressure();
+        Scalar pcJK = (pcJ + pcK) / 2;
 
-        // get mobilities and fractional flow factors
-        Scalar lambdaWI = problem_.variables().mobilityWetting(globalIdxI);
-        Scalar lambdaNWI = problem_.variables().mobilityNonwetting(globalIdxI);
-        Scalar fractionalWI = problem_.variables().fracFlowFuncWetting(globalIdxI);
-        Scalar fractionalNWI = problem_.variables().fracFlowFuncNonwetting(globalIdxI);
-        Scalar pcI = problem_.variables().capillaryPressure(globalIdxI);
-
-        IntersectionIterator isItEnd = problem_.gridView().iend(*eIt);
-        for (IntersectionIterator isIt = problem_.gridView().ibegin(*eIt); isIt != isItEnd; ++isIt)
-        {
-            int isIndex = isIt->indexInInside();
+        // Potentials from previous time step are not available.
+        // Instead, calculate mean density, then find potentials,
+        // then upwind density.
+        // pressure from previous time step might also be incorrect.
 
-            // get normal vector
-            const GlobalPosition& unitOuterNormal = isIt->centerUnitOuterNormal();
+        Scalar rhoMeanWIJ = density_[wPhaseIdx];
+        Scalar rhoMeanNWIJ = density_[nPhaseIdx];
+        Scalar rhoMeanWIK = density_[wPhaseIdx];
+        Scalar rhoMeanNWIK = density_[nPhaseIdx];
 
-            // get face volume
-            Scalar faceArea = isIt->geometry().volume();
+        if (compressibility_)
+        {
+            rhoMeanWIJ = (lJ * cellDataI.density(wPhaseIdx) + lI * cellDataJ.density(wPhaseIdx)) / l;
+            rhoMeanNWIJ = (lJ * cellDataI.density(nPhaseIdx) + lI * cellDataJ.density(nPhaseIdx)) / l;
+            rhoMeanWIK = (lJ * cellDataI.density(wPhaseIdx) + lI * cellDataK.density(wPhaseIdx)) / l;
+            rhoMeanNWIK = (lJ * cellDataI.density(nPhaseIdx) + lI * cellDataK.density(nPhaseIdx)) / l;
+        }
 
-            // handle interior face
-            if (isIt->neighbor())
-            {
-                // access neighbor
-                ElementPointer neighborPointer = isIt->outside();
-                int globalIdxJ = problem_.variables().index(*neighborPointer);
+        Scalar densityWIJ = density_[wPhaseIdx];
+        Scalar densityNWIJ = density_[nPhaseIdx];
+        Scalar densityWIK = density_[wPhaseIdx];
+        Scalar densityNWIK = density_[nPhaseIdx];
 
-                // "normal" case: neighbor has same level
-                if (neighborPointer->level()==eIt.level())
-                {
-					// neighbor cell center in global coordinates
-					const GlobalPosition& globalPosNeighbor = neighborPointer->geometry().center();
-
-					// distance vector between barycenters
-					GlobalPosition distVec = globalPosNeighbor - globalPos;
-
-					// compute distance between cell centers
-//					Scalar dist = distVec.two_norm();
-					Scalar dist = distVec*unitOuterNormal;
-
-					// compute vectorized permeabilities
-					FieldMatrix meanPermeability(0);
-
-					problem_.spatialParameters().meanK(meanPermeability,
-							problem_.spatialParameters().intrinsicPermeability(*eIt),
-							problem_.spatialParameters().intrinsicPermeability(*neighborPointer));
-
-					Dune::FieldVector<Scalar, dim> permeability(0);
-					meanPermeability.mv(unitOuterNormal, permeability);
-
-					// get mobilities and fractional flow factors
-					Scalar lambdaWJ = problem_.variables().mobilityWetting(globalIdxJ);
-					Scalar lambdaNWJ = problem_.variables().mobilityNonwetting(globalIdxJ);
-					Scalar fractionalWJ = problem_.variables().fracFlowFuncWetting(globalIdxJ);
-					Scalar fractionalNWJ = problem_.variables().fracFlowFuncNonwetting(globalIdxJ);
-					Scalar densityWJ = problem_.variables().densityWetting(globalIdxJ);
-					Scalar densityNWJ = problem_.variables().densityNonwetting(globalIdxJ);
-
-					Scalar pcJ = problem_.variables().capillaryPressure(globalIdxJ);
-
-					Scalar rhoMeanW = 0.5 * (densityWI + densityWJ);
-					Scalar rhoMeanNW = 0.5 * (densityNWI + densityNWJ);
-					Scalar fMeanW = 0.5 * (fractionalWI + fractionalWJ);
-					Scalar fMeanNW = 0.5 * (fractionalNWI + fractionalNWJ);
-
-					// update diagonal entry
-					Scalar entry;
-
-					//calculate potential gradients
-					Scalar potentialW = 0;
-					Scalar potentialNW = 0;
-
-					Scalar densityW = 0;
-					Scalar densityNW = 0;
-
-					//if we are at the very first iteration we can't calculate phase potentials
-					if (!first)
-					{
-						// After grid adaption, the potentials from the previous time step
-						// can not be used for upwinding. The mean values is assumed instead.
-						densityW = rhoMeanW;
-						densityNW = rhoMeanNW;
-
-						switch (pressureType)
-						{
-						case pw:
-						{
-							potentialW = (problem_.variables().pressure()[globalIdxI] - problem_.variables().pressure()[globalIdxJ]);
-							potentialNW = (problem_.variables().pressure()[globalIdxI] - problem_.variables().pressure()[globalIdxJ] + pcI
-									- pcJ);
-							break;
-						}
-						case pn:
-						{
-							potentialW
-									= (problem_.variables().pressure()[globalIdxI] - problem_.variables().pressure()[globalIdxJ] - pcI + pcJ);
-							potentialNW = (problem_.variables().pressure()[globalIdxI] - problem_.variables().pressure()[globalIdxJ]);
-							break;
-						}
-						case pglobal:
-						{
-							potentialW = (problem_.variables().pressure()[globalIdxI] - problem_.variables().pressure()[globalIdxJ] - fMeanNW
-									* (pcI - pcJ));
-							potentialNW = (problem_.variables().pressure()[globalIdxI] - problem_.variables().pressure()[globalIdxJ] + fMeanW
-									* (pcI - pcJ));
-							break;
-						}
-						}
-
-						potentialW += densityW * (distVec * gravity);
-						potentialNW += densityNW * (distVec * gravity);
-
-						//store potentials for further calculations (velocity, saturation, ...)
-						problem_.variables().potentialWetting(globalIdxI, isIndex) = potentialW;
-						problem_.variables().potentialNonwetting(globalIdxI, isIndex) = potentialNW;
-					}
-
-					//do the upwinding of the mobility depending on the phase potentials
-					Scalar lambdaW = (potentialW > 0.) ? lambdaWI : lambdaWJ;
-					lambdaW = (potentialW == 0) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaW;
-					Scalar lambdaNW = (potentialNW > 0) ? lambdaNWI : lambdaNWJ;
-					lambdaNW = (potentialNW == 0) ? 0.5 * (lambdaNWI + lambdaNWJ) : lambdaNW;
-
-					densityW = (potentialW > 0.) ? densityWI : densityWJ;
-					densityNW = (potentialNW > 0.) ? densityNWI : densityNWJ;
-
-					densityW = (potentialW == 0) ? rhoMeanW : densityW;
-					densityNW = (potentialNW == 0) ? rhoMeanNW : densityNW;
-
-					//calculate current matrix entry
-					entry = (lambdaW + lambdaNW) * ((permeability * unitOuterNormal) / dist) * faceArea;
-
-					//calculate right hand side
-					Scalar rightEntry = (lambdaW * densityW + lambdaNW * densityNW) * (permeability * gravity) * faceArea;
-
-					switch (pressureType)
-					{
-					case pw:
-					{
-						// calculate capillary pressure gradient
-						Dune::FieldVector<Scalar, dim> pCGradient = unitOuterNormal;
-						pCGradient *= (pcI - pcJ) / dist;
-
-						//add capillary pressure term to right hand side
-						rightEntry += 0.5 * (lambdaNWI + lambdaNWJ) * (permeability * pCGradient) * faceArea;
-						break;
-					}
-					case pn:
-					{
-						// calculate capillary pressure gradient
-						Dune::FieldVector<Scalar, dim> pCGradient = unitOuterNormal;
-						pCGradient *= (pcI - pcJ) / dist;
-
-						//add capillary pressure term to right hand side
-						rightEntry -= 0.5 * (lambdaWI + lambdaWJ) * (permeability * pCGradient) * faceArea;
-						break;
-					}
-					}
-
-					//set right hand side
-					f_[globalIdxI] -= rightEntry;
-
-					// set diagonal entry
-					A_[globalIdxI][globalIdxI] += entry;
-
-					// set off-diagonal entry
-					A_[globalIdxI][globalIdxJ] -= entry;
-
-                } // end of case "neighbor has same level"
-
-                // hanging node situation: neighbor has higher level
-                if (neighborPointer->level()==eIt.level()+1)
-                {
-                	// Count number of hanging nodes
-					// nodecount counts each hanging node twice, we have to divide by 2 in the end
-					// not really necessary
-					nodecount++;
-
-					int globalIdxK = 0;
-					ElementPointer thirdCellPointer = isIt->outside();
-					bool foundK=false;
-					bool foundIJ=false;
-					// We are looking for two things:
-					// IsIndexJ, the index of the interface from the neighbor-cell point of view
-					// GlobalIdxK, the index of the third cell
-					// for efficienty this is done in one IntersectionIterator-Loop
-
-					// Intersectioniterator around cell J
-					IntersectionIterator isItEndJ = this->problem().gridView().iend(*neighborPointer);
-
-					for (IntersectionIterator isItJ = this->problem().gridView().ibegin(*neighborPointer); isItJ != isItEndJ; ++isItJ)
-					{
-						if (isItJ->neighbor())
-						{
-							ElementPointer neighborPointer2 = isItJ->outside();
-
-							// Neighbor of neighbor is Cell I?
-							if (this->problem().variables().index(*neighborPointer2)==globalIdxI)
-							{
-								foundIJ=true;
-							}
-							else
-							{
-								if (neighborPointer2->level()==eIt.level()+1)
-								{
-									// To verify, we found the correct Cell K, we check
-									// - is level(K)=level(J)?
-									// - is distance(IJ)=distance(IK)?
-									// - K is neighbor of J.
-									const GlobalPosition& globalPosNeighbor = neighborPointer->geometry().center();
-									const GlobalPosition& globalPosThirdCell = neighborPointer2->geometry().center();
-									Dune::FieldVector<Scalar, dimWorld> distVecIJ = globalPosNeighbor - globalPos;
-									Dune::FieldVector<Scalar, dimWorld> distVecIK = globalPosThirdCell - globalPos;
-									if (((distVecIK.two_norm()-distVecIJ.two_norm()))/distVecIJ.two_norm() < 0.001)
-									{
-										globalIdxK= this->problem().variables().index(*neighborPointer2);
-										thirdCellPointer = neighborPointer2;
-										foundK=true;
-									}
-
-								}
-							}
-						}
-						if (foundIJ && foundK) break;
-					}
-
-                    int isIndexJ = isIt->indexInOutside();
-
-					// neighbor cell center in global coordinates
-					const GlobalPosition& globalPosNeighbor = neighborPointer->geometry().center();
-//					const GlobalPosition& globalPosThirdCell = thirdCellPointer->geometry().center();
-					const GlobalPosition& globalPosInterface = isIt->geometry().center();
-
-					Dune::FieldVector<Scalar,dimWorld> distVec = globalPosInterface - globalPos;
-					Scalar lI= distVec*unitOuterNormal;
-					distVec = globalPosNeighbor - globalPosInterface;
-					Scalar lJ= distVec*unitOuterNormal;
-					Scalar l=lI+lJ;
-
-					FieldMatrix permeabilityI(0);
-					FieldMatrix permeabilityJ(0);
-					FieldMatrix permeabilityK(0);
-
-					problem_.spatialParameters().meanK(permeabilityI,
-							problem_.spatialParameters().intrinsicPermeability(*eIt));
-					problem_.spatialParameters().meanK(permeabilityJ,
-							problem_.spatialParameters().intrinsicPermeability(*neighborPointer));
-					problem_.spatialParameters().meanK(permeabilityK,
-							problem_.spatialParameters().intrinsicPermeability(*thirdCellPointer));
-
-					// Calculate permeablity component normal to interface
-					Scalar kI, kJ, kK, kMean, ng;
-					Dune::FieldVector<Scalar, dim> permI(0);
-					Dune::FieldVector<Scalar, dim> permJ(0);
-					Dune::FieldVector<Scalar, dim> permK(0);
-
-					permeabilityI.mv(unitOuterNormal, permI);
-					permeabilityJ.mv(unitOuterNormal, permJ);
-					permeabilityK.mv(unitOuterNormal, permK);
-
-					// kI,kJ,kK=(n^T)Kn
-					kI=unitOuterNormal*permI;
-					kJ=unitOuterNormal*permJ;
-					kK=unitOuterNormal*permK;
-
-					// See Diplomarbeit Michael Sinsbeck
-					kMean=kI*kJ*kK*l/(kJ*kK*lI+kI*(kJ+kK)/2*lJ);
-
-					ng=this->gravity*unitOuterNormal;
-
-					// get mobilities
-					// fractional flow function is not evaluated, since we do not use p_global
-					Scalar lambdaWJ = problem_.variables().mobilityWetting(globalIdxJ);
-					Scalar lambdaNWJ = problem_.variables().mobilityNonwetting(globalIdxJ);
-					Scalar densityWJ = problem_.variables().densityWetting(globalIdxJ);
-					Scalar densityNWJ = problem_.variables().densityNonwetting(globalIdxJ);
-					Scalar fractionalWJ = problem_.variables().fracFlowFuncWetting(globalIdxJ);
-					Scalar fractionalNWJ = problem_.variables().fracFlowFuncNonwetting(globalIdxJ);
-
-//					Scalar lambdaWK = problem_.variables().mobilityWetting(globalIdxK);
-//					Scalar lambdaNWK = problem_.variables().mobilityNonwetting(globalIdxK);
-					Scalar densityWK = problem_.variables().densityWetting(globalIdxK);
-					Scalar densityNWK = problem_.variables().densityNonwetting(globalIdxK);
-					Scalar fractionalWK = problem_.variables().fracFlowFuncWetting(globalIdxK);
-					Scalar fractionalNWK = problem_.variables().fracFlowFuncNonwetting(globalIdxK);
-
-					Scalar pcJ = problem_.variables().capillaryPressure(globalIdxJ);
-					Scalar pcK = problem_.variables().capillaryPressure(globalIdxK);
-					Scalar pcJK=(pcJ+pcK)/2;
-
-					// Potentials from previous time step are not available.
-					// Instead, calculate mean density, then find potentials,
-					// then upwind density.
-					// pressure from previous time step might also be incorrect.
-
-					Scalar rhoMeanWIJ = (lJ*densityWI + lI*densityWJ)/l;
-					Scalar rhoMeanNWIJ = (lJ*densityNWI + lI*densityNWJ)/l;
-					Scalar rhoMeanWIK = (lJ*densityWI + lI*densityWK)/l;
-					Scalar rhoMeanNWIK = (lJ*densityNWI + lI*densityNWK)/l;
-
-					Scalar densityWIJ = 0;
-					Scalar densityNWIJ = 0;
-					Scalar densityWIK = 0;
-					Scalar densityNWIK = 0;
-
-					Scalar fMeanWIJ = (lJ*fractionalWI+lI*fractionalWJ)/l;
-					Scalar fMeanNWIJ = (lJ*fractionalNWI+lI*fractionalNWJ)/l;
-					Scalar fMeanWIK = (lJ*fractionalWI+lI*fractionalWK)/l;
-					Scalar fMeanNWIK = (lJ*fractionalNWI+lI*fractionalNWK)/l;
-
-					Scalar potentialWIJ = 0;
-					Scalar potentialNWIJ = 0;
-					Scalar potentialWIK = 0;
-					Scalar potentialNWIK = 0;
-
-					//if we are at the very first iteration we can't calculate phase potentials
-					if (!first)
-					{
-						// potentials from previous time step no available.
-						densityWIJ = rhoMeanWIJ;
-						densityNWIJ = rhoMeanNWIJ;
-						densityWIK = rhoMeanWIK;
-						densityNWIK = rhoMeanNWIK;
-
-						// Old pressure field
-						Scalar pressI=problem_.variables().pressure()[globalIdxI];
-						Scalar pressJ=problem_.variables().pressure()[globalIdxJ];
-						Scalar pressK=problem_.variables().pressure()[globalIdxK];
-						Scalar pressJK=(pressJ+pressK)/2;
-						Scalar pcJK=(pcJ+pcK)/2;
-
-						switch (pressureType)
-						{
-							case pw:
-							{
-								potentialWIJ = (pressI-pressJK)/l+
-										(densityWIJ-lJ/l*(kI+kK)/kI*(densityWIK-densityWIJ)/2)*ng;
-								potentialNWIJ = (pressI+pcI-(pressJK+pcJK))/l+
-										(densityNWIJ-lJ/l*(kI+kK)/kI*(densityNWIK-densityNWIJ)/2)*ng;
-								potentialWIK = (pressI-pressJK)/l+
-										(densityWIK-lJ/l*(kI+kK)/kI*(densityWIJ-densityWIK)/2)*ng;
-								potentialNWIK = (pressI+pcI-(pressJK+pcJK))/l+
-										(densityNWIK-lJ/l*(kI+kK)/kI*(densityNWIJ-densityNWIK)/2)*ng;
-								break;
-							}
-							case pn:
-							{
-								potentialWIJ = (pressI-pcI-(pressJK-pcJK))/l+
-										(densityWIJ-lJ/l*(kI+kK)/kI*(densityWIK-densityWIJ)/2)*ng;
-								potentialNWIJ = (pressI-pressJK)/l+
-										(densityNWIJ-lJ/l*(kI+kK)/kI*(densityNWIK-densityNWIJ)/2)*ng;
-								potentialWIK = (pressI-pcI-(pressJK-pcJK))/l+
-										(densityWIK-lJ/l*(kI+kK)/kI*(densityWIJ-densityWIK)/2)*ng;
-								potentialNWIK = (pressI-pressJK)/l+
-										(densityNWIK-lJ/l*(kI+kK)/kI*(densityNWIJ-densityNWIK)/2)*ng;
-								break;
-							}
-							case pglobal:
-							{
-								potentialWIJ = (pressI-fMeanNWIJ*pcI-(pressJK-fMeanNWIJ*pcJK))/l+
-										(densityWIJ-lJ/l*(kI+kK)/kI*(densityWIK-densityWIJ)/2)*ng;
-								potentialNWIJ = (pressI+fMeanWIJ*pcI-(pressJK+fMeanWIJ*pcJK))/l+
-										(densityNWIJ-lJ/l*(kI+kK)/kI*(densityNWIK-densityNWIJ)/2)*ng;
-								potentialWIK = (pressI-fMeanNWIK*pcI-(pressJK-fMeanNWIK*pcJK))/l+
-										(densityWIK-lJ/l*(kI+kK)/kI*(densityWIJ-densityWIK)/2)*ng;
-								potentialNWIK = (pressI+fMeanWIK*pcI-(pressJK+fMeanWIK*pcJK))/l+
-										(densityNWIK-lJ/l*(kI+kK)/kI*(densityNWIJ-densityNWIK)/2)*ng;
-								break;
-							}
-						}
-
-						//store potentials for further calculations (velocity, saturation, ...)
-
-						problem_.variables().potentialWetting(globalIdxI, isIndex) = potentialWIJ;
-						problem_.variables().potentialNonwetting(globalIdxI, isIndex) = potentialNWIJ;
-						problem_.variables().potentialWetting(globalIdxJ, isIndexJ) = -potentialWIJ;
-						problem_.variables().potentialNonwetting(globalIdxJ, isIndexJ) = -potentialNWIJ;
-					}
-
-					//do the upwinding of the mobility depending on the phase potentials
-					Scalar lambdaWIJ = (potentialWIJ > 0.) ? lambdaWI : lambdaWJ;
-					lambdaWIJ = (potentialWIJ == 0) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaWIJ;
-					Scalar lambdaNWIJ = (potentialNWIJ > 0) ? lambdaNWI : lambdaNWJ;
-					lambdaNWIJ = (potentialNWIJ == 0) ? 0.5 * (lambdaNWI + lambdaNWJ) : lambdaNWIJ;
-					densityWIJ = (potentialWIJ > 0.) ? densityWI : densityWJ;
-					densityNWIJ = (potentialNWIJ > 0.) ? densityNWI : densityNWJ;
-					densityWIJ = (potentialWIJ == 0) ? rhoMeanWIJ : densityWIJ;
-					densityNWIJ = (potentialNWIJ == 0) ? rhoMeanNWIJ : densityNWIJ;
-
-					densityWIK = (potentialWIK > 0.) ? densityWI : densityWK;
-					densityNWIK = (potentialNWIK > 0.) ? densityNWI : densityNWK;
-					densityWIK = (potentialWIK == 0) ? rhoMeanWIK : densityWIK;
-					densityNWIK = (potentialNWIK == 0) ? rhoMeanNWIK : densityNWIK;
-
-
-					// update diagonal entry and right hand side
-
-					Scalar entry;
-					Scalar rightEntry;
-
-					entry = (lambdaWIJ + lambdaNWIJ)*kMean/l*faceArea;
-					rightEntry  = faceArea*lambdaWIJ*kMean*ng*((densityWIJ)-(lJ/l)*(kI+kK)/kI*(densityWIK-densityWIJ)/2);
-					rightEntry += faceArea*lambdaNWIJ*kMean*ng*((densityNWIJ)-(lJ/l)*(kI+kK)/kI*(densityNWIK-densityNWIJ)/2);
-
-					switch (pressureType)
-					{
-						case pw:
-						{
-							rightEntry += faceArea*lambdaNWIJ*kMean*(pcJK-pcI)/l;
-							break;
-						}
-						case pn:
-						{
-							rightEntry -= faceArea*lambdaWIJ*kMean*(pcJK-pcI)/l;
-							break;
-						}
-					}
-
-					f_[globalIdxI] -= rightEntry;
-					f_[globalIdxJ] += rightEntry;
-
-					// set diagonal entry
-					A_[globalIdxI][globalIdxI] += entry;
-					A_[globalIdxI][globalIdxJ] -= 0.5*entry;
-					A_[globalIdxI][globalIdxK] -= 0.5*entry;
-
-					// set off-diagonal entry
-					A_[globalIdxJ][globalIdxI] -= entry;
-					A_[globalIdxJ][globalIdxJ] += 0.5*entry;
-					A_[globalIdxJ][globalIdxK] += 0.5*entry;
+        Scalar fMeanWIJ = (lJ * fractionalWI + lI * fractionalWJ) / l;
+        Scalar fMeanNWIJ = (lJ * fractionalNWI + lI * fractionalNWJ) / l;
+        Scalar fMeanWIK = (lJ * fractionalWI + lI * fractionalWK) / l;
+        Scalar fMeanNWIK = (lJ * fractionalNWI + lI * fractionalNWK) / l;
 
-                }
-            }
+        Scalar potentialWIJ = 0;
+        Scalar potentialNWIJ = 0;
+        Scalar potentialWIK = 0;
+        Scalar potentialNWIK = 0;
 
-            // boundary face
-
-            else
+        //if we are at the very first iteration we can't calculate phase potentials
+        if (!first)
+        {
+            // potentials from previous time step no available.
+            if (compressibility_)
             {
-                // center of face in global coordinates
-                const GlobalPosition& globalPosFace = isIt->geometry().center();
-
-                problem().boundaryTypes(bcType, *isIt);
-                PrimaryVariables boundValues(0.0);
-
-                GlobalPosition distVec(globalPosFace - globalPos);
-//                Scalar dist = distVec.two_norm();
-                Scalar dist = distVec * unitOuterNormal;
-
-                if (bcType.isDirichlet(eqIdxPress))
-                {
-                    problem().dirichlet(boundValues, *isIt);
-
-                    //permeability vector at boundary
-                    // compute vectorized permeabilities
-                    FieldMatrix meanPermeability(0);
-
-                    problem_.spatialParameters().meanK(meanPermeability,
-                            problem_.spatialParameters().intrinsicPermeability(*eIt));
-
-                    Dune::FieldVector<Scalar, dim> permeability(0);
-                    meanPermeability.mv(unitOuterNormal, permeability);
-
-                    //determine saturation at the boundary -> if no saturation is known directly at the boundary use the cell saturation
-                    Scalar satBound;
-                    if (bcType.isDirichlet(eqIdxSat))
-                    {
-                        satBound = boundValues[saturationIdx];
-                    }
-                    else
-                    {
-                        satBound = problem_.variables().saturation()[globalIdxI];
-                    }
-                    Scalar temperature = problem_.temperature(*eIt);
-
-                    //get dirichlet pressure boundary condition
-                    Scalar pressBound = boundValues[pressureIdx];
-
-                    //calculate consitutive relations depending on the kind of saturation used
-                    //determine phase saturations from primary saturation variable
-                    Scalar satW = 0;
-                    //Scalar satNW = 0;
-                    switch (saturationType)
-                    {
-                    case Sw:
-                    {
-                        satW = satBound;
-                        //satNW = 1 - satBound;
-                        break;
-                    }
-                    case Sn:
-                    {
-                        satW = 1 - satBound;
-                        //satNW = satBound;
-                        break;
-                    }
-                    }
-
-                    Scalar pcI = problem_.variables().capillaryPressure(globalIdxI);
-                    Scalar pcBound = MaterialLaw::pC(problem_.spatialParameters().materialLawParams(*eIt), satW);
-
-                    //determine phase pressures from primary pressure variable
-                    Scalar pressW = 0;
-                    Scalar pressNW = 0;
-                    switch (pressureType)
-                    {
-                    case pw:
-                    {
-                        pressW = pressBound;
-                        pressNW = pressBound + pcBound;
-                        break;
-                    }
-                    case pn:
-                    {
-                        pressW = pressBound - pcBound;
-                        pressNW = pressBound;
-                        break;
-                    }
-                    }
-
-                    Scalar densityWBound = 0;
-                    Scalar densityNWBound = 0;
-                    Scalar lambdaWBound = 0;
-                    Scalar lambdaNWBound = 0;
-
-                    if (compressibility)
-                    {
-                        FluidState fluidState;
-                        fluidState.update(satW, pressW, pressNW, temperature);
-                        densityWBound = FluidSystem::phaseDensity(wPhaseIdx, temperature, pressW, fluidState);
-                        densityNWBound = FluidSystem::phaseDensity(nPhaseIdx, temperature, pressNW, fluidState);
-                        Scalar viscosityWBound = FluidSystem::phaseViscosity(wPhaseIdx, temperature, pressW, fluidState);
-                        Scalar viscosityNWBound = FluidSystem::phaseViscosity(nPhaseIdx, temperature, pressNW, fluidState);
-                        lambdaWBound = MaterialLaw::krw(problem_.spatialParameters().materialLawParams(*eIt), satW)
-                                / viscosityWBound * densityWBound;
-                        lambdaNWBound = MaterialLaw::krn(problem_.spatialParameters().materialLawParams(*eIt), satW)
-                                / viscosityNWBound * densityNWBound;
-                    }
-                    else
-                    {
-                        Scalar referencePressure = problem_.referencePressure(*eIt);
-                        FluidState fluidState;
-                        fluidState.update(satW, referencePressure, referencePressure, temperature);
-
-                        densityWBound = FluidSystem::phaseDensity(wPhaseIdx, temperature, referencePressure, fluidState);
-                        densityNWBound = FluidSystem::phaseDensity(nPhaseIdx, temperature, referencePressure, fluidState);
-                        Scalar viscosityWBound = FluidSystem::phaseViscosity(wPhaseIdx, temperature, referencePressure, fluidState);
-                        Scalar viscosityNWBound = FluidSystem::phaseViscosity(nPhaseIdx, temperature, referencePressure, fluidState);
-                        lambdaWBound = MaterialLaw::krw(problem_.spatialParameters().materialLawParams(*eIt), satW)
-                                / viscosityWBound;
-                        lambdaNWBound = MaterialLaw::krn(problem_.spatialParameters().materialLawParams(*eIt), satW)
-                                / viscosityNWBound;
-                    }
-                    Scalar fractionalWBound = lambdaWBound / (lambdaWBound + lambdaNWBound);
-                    Scalar fractionalNWBound = lambdaNWBound / (lambdaWBound + lambdaNWBound);
-
-                    Scalar rhoMeanW = 0.5 * (densityWI + densityWBound);
-                    Scalar rhoMeanNW = 0.5 * (densityNWI + densityNWBound);
-                    Scalar fMeanW = 0.5 * (fractionalWI + fractionalWBound);
-                    Scalar fMeanNW = 0.5 * (fractionalNWI + fractionalNWBound);
-
-                    Scalar potentialW = 0;
-                    Scalar potentialNW = 0;
-
-                    Scalar densityW = 0;
-                    Scalar densityNW = 0;
-
-                    if (!first)
-                    {
-                    	// Comment: In the non-adaptive case, one can upwind the density using the
-                    	// old potential. Here, we use the mean density instead.
-                    	// For the incompressible case, it does not make a difference, anyway.
-						densityW = rhoMeanW;
-						densityNW = rhoMeanNW;
-
-                        //calculate potential gradient
-                        switch (pressureType)
-                        {
-                        case pw:
-                        {
-                            potentialW = (problem_.variables().pressure()[globalIdxI] - pressBound);
-                            potentialNW = (problem_.variables().pressure()[globalIdxI] + pcI - pressBound - pcBound);
-                            break;
-                        }
-                        case pn:
-                        {
-                            potentialW = (problem_.variables().pressure()[globalIdxI] - pcI - pressBound + pcBound);
-                            potentialNW = (problem_.variables().pressure()[globalIdxI] - pressBound);
-                            break;
-                        }
-                        case pglobal:
-                        {
-                            potentialW = (problem_.variables().pressure()[globalIdxI] - pressBound - fMeanNW * (pcI - pcBound));
-                            potentialNW = (problem_.variables().pressure()[globalIdxI] - pressBound + fMeanW * (pcI - pcBound));
-                            break;
-                        }
-                        }
-
-                        potentialW += densityW * (distVec * gravity);
-                        potentialNW += densityNW * (distVec * gravity);
-
-                        //store potential gradients for further calculations
-                        problem_.variables().potentialWetting(globalIdxI, isIndex) = potentialW;
-                        problem_.variables().potentialNonwetting(globalIdxI, isIndex) = potentialNW;
-                    }
-
-                    //do the upwinding of the mobility depending on the phase potentials
-                    Scalar lambdaW = (potentialW > 0.) ? lambdaWI : lambdaWBound;
-                    lambdaW = (potentialW == 0) ? 0.5 * (lambdaWI + lambdaWBound) : lambdaW;
-                    Scalar lambdaNW = (potentialNW > 0.) ? lambdaNWI : lambdaNWBound;
-                    lambdaNW = (potentialNW == 0) ? 0.5 * (lambdaNWI + lambdaNWBound) : lambdaNW;
-
-                    densityW = (potentialW > 0.) ? densityWI : densityWBound;
-                    densityW = (potentialW == 0) ? rhoMeanW : densityW;
-                    densityNW = (potentialNW > 0.) ? densityNWI : densityNWBound;
-                    densityNW = (potentialNW == 0) ? rhoMeanNW : densityNW;
-
-                    //calculate current matrix entry
-                    Scalar entry = (lambdaW + lambdaNW) * ((permeability * unitOuterNormal) / dist) * faceArea;
-
-                    //calculate right hand side
-                    Scalar rightEntry = (lambdaW * densityW + lambdaNW * densityNW) * (permeability * gravity) * faceArea;
-
-                    switch (pressureType)
-                    {
-                    case pw:
-                    {
-                        // calculate capillary pressure gradient
-                        Dune::FieldVector<Scalar, dim> pCGradient = unitOuterNormal;
-                        pCGradient *= (pcI - pcBound) / dist;
-
-                        //add capillary pressure term to right hand side
-                        rightEntry += 0.5 * (lambdaNWI + lambdaNWBound) * (permeability * pCGradient) * faceArea;
-                        break;
-                    }
-                    case pn:
-                    {
-                        // calculate capillary pressure gradient
-                        Dune::FieldVector<Scalar, dim> pCGradient = unitOuterNormal;
-                        pCGradient *= (pcI - pcBound) / dist;
-
-                        //add capillary pressure term to right hand side
-                        rightEntry -= 0.5 * (lambdaWI + lambdaWBound) * (permeability * pCGradient) * faceArea;
-                        break;
-                    }
-                    }
-
-                    // set diagonal entry and right hand side entry
-                    A_[globalIdxI][globalIdxI] += entry;
-                    f_[globalIdxI] += entry * pressBound;
-                    f_[globalIdxI] -= rightEntry;
-                }
-                //set neumann boundary condition
-
-                else if (bcType.isNeumann(eqIdxPress))
-                {
-                    problem().neumann(boundValues, *isIt);
-
-                    if (!compressibility)
-                    {
-                        boundValues[wPhaseIdx] /= densityWI;
-                        boundValues[nPhaseIdx] /= densityNWI;
-                    }
-                    f_[globalIdxI] -= (boundValues[wPhaseIdx] + boundValues[nPhaseIdx]) * faceArea;
-
-                    //Assumes that the phases flow in the same direction at the neumann boundary, which is the direction of the total flux!!!
-                    //needed to determine the upwind direction in the saturation equation
-                    problem_.variables().potentialWetting(globalIdxI, isIndex) = boundValues[wPhaseIdx];
-                    problem_.variables().potentialNonwetting(globalIdxI, isIndex) = boundValues[nPhaseIdx];
-                }
-                else
-                {
-                    DUNE_THROW(Dune::NotImplemented, "No valid boundary condition type defined for pressure equation!");
-                }
+                densityWIJ = rhoMeanWIJ;
+                densityNWIJ = rhoMeanNWIJ;
+                densityWIK = rhoMeanWIK;
+                densityNWIK = rhoMeanNWIK;
             }
-        } // end all intersections
 
-        //volume correction due to density differences
-        if (compressibility)
-        {
-            switch (saturationType)
+            switch (pressureType_)
             {
-            case Sw:
+            case pglobal:
             {
-                f_[globalIdxI] -= problem_.variables().volumecorrection(globalIdxI) * porosity * volume * (densityWI - densityNWI);
+                Scalar pressJK = (cellDataJ.globalPressure() + cellDataK.globalPressure()) / 2;
+
+                potentialWIJ = (cellDataI.globalPressure() - fMeanNWIJ * pcI - (pressJK - fMeanNWIJ * pcJK)) / l
+                        + (densityWIJ - lJ / l * (kI + kK) / kI * (densityWIK - densityWIJ) / 2) * ng;
+                potentialNWIJ = (cellDataI.globalPressure() + fMeanWIJ * pcI - (pressJK + fMeanWIJ * pcJK)) / l
+                        + (densityNWIJ - lJ / l * (kI + kK) / kI * (densityNWIK - densityNWIJ) / 2) * ng;
+                potentialWIK = (cellDataI.globalPressure() - fMeanNWIK * pcI - (pressJK - fMeanNWIK * pcJK)) / l
+                        + (densityWIK - lJ / l * (kI + kK) / kI * (densityWIJ - densityWIK) / 2) * ng;
+                potentialNWIK = (cellDataI.globalPressure() + fMeanWIK * pcI - (pressJK + fMeanWIK * pcJK)) / l
+                        + (densityNWIK - lJ / l * (kI + kK) / kI * (densityNWIJ - densityNWIK) / 2) * ng;
                 break;
             }
-            case Sn:
+            default:
             {
-                f_[globalIdxI] -= problem_.variables().volumecorrection(globalIdxI) * porosity * volume * (densityNWI - densityWI);
+                potentialWIJ = (cellDataI.pressure(wPhaseIdx)
+                        - 0.5 * (cellDataJ.pressure(wPhaseIdx) + cellDataK.pressure(wPhaseIdx))) / l
+                        + (densityWIJ - lJ / l * (kI + kK) / kI * (densityWIK - densityWIJ) / 2) * ng;
+                potentialNWIJ = (cellDataI.pressure(nPhaseIdx)
+                        - (0.5 * (cellDataJ.pressure(nPhaseIdx) + cellDataK.pressure(nPhaseIdx)))) / l
+                        + (densityNWIJ - lJ / l * (kI + kK) / kI * (densityNWIK - densityNWIJ) / 2) * ng;
+                potentialWIK = (cellDataI.pressure(wPhaseIdx)
+                        - 0.5 * (cellDataJ.pressure(wPhaseIdx) + cellDataK.pressure(wPhaseIdx))) / l
+                        + (densityWIK - lJ / l * (kI + kK) / kI * (densityWIJ - densityWIK) / 2) * ng;
+                potentialNWIK = (cellDataI.pressure(nPhaseIdx)
+                        - (0.5 * (cellDataJ.pressure(nPhaseIdx) + cellDataK.pressure(nPhaseIdx)))) / l
+                        + (densityNWIK - lJ / l * (kI + kK) / kI * (densityNWIJ - densityNWIK) / 2) * ng;
                 break;
             }
             }
         }
 
-//        Dune::printmatrix(std::cout,A_,"title","-");
-    } // end grid traversal
-    return;
-}
-
-//!solves the system of equations to get the spatial distribution of the pressure
-template<class TypeTag>
-void FVPressure2Padaptive<TypeTag>::solve()
-{
-    typedef typename GET_PROP_TYPE(TypeTag, LinearSolver) Solver;
-
-    int verboseLevelSolver = GET_PARAM(TypeTag, int, LinearSolver, Verbosity);
-
-    if (verboseLevelSolver)
-    std::cout << "FVPressure2Padaptive: solve for pressure" << std::endl;
-
-//    printmatrix(std::cout, A_, "global stiffness matrix", "row", 11, 3);
-//    printvector(std::cout, f_, "right hand side", "row", 200, 1, 3);
-
-    Solver solver(problem_);
-    solver.solve(A_, problem_.variables().pressure(), f_);
-
-//                    printvector(std::cout, (problem_.variables().pressure()), "pressure", "row", 200, 1, 3);
+        //do the upwinding of the mobility depending on the phase potentials
+        Scalar lambdaWIJ = (potentialWIJ > 0.) ? lambdaWI : lambdaWJ;
+        lambdaWIJ = (potentialWIJ == 0) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaWIJ;
+        Scalar lambdaNWIJ = (potentialNWIJ > 0) ? lambdaNWI : lambdaNWJ;
+        lambdaNWIJ = (potentialNWIJ == 0) ? 0.5 * (lambdaNWI + lambdaNWJ) : lambdaNWIJ;
 
-    //for parallel use
-//    problem_.variables().communicatePressure();
-
-    return;
-}
-//!constitutive functions are updated once if new saturations are calculated and stored in the variables object
-template<class TypeTag>
-void FVPressure2Padaptive<TypeTag>::updateMaterialLaws()
-{
-//    //for parallel use
-////    printvector(std::cout, (problem_.variables().pressure()), "pressure", "row", 200, 1, 3);
-////    problem_.variables().communicatePressure();
-////    printvector(std::cout, (problem_.variables().pressure()), "pressureComm", "row", 200, 1, 3);
-//
-////    printvector(std::cout, (problem_.variables().saturation()), "sat", "row", 200, 1, 3);
-//    problem_.variables().communicateTransportedQuantity();
-////    printvector(std::cout, (problem_.variables().saturation()), "satComm", "row", 200, 1, 3);
-
-    FluidState fluidState;
-
-    // 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 temperature = problem_.temperature(*eIt);
-
-        //determine phase saturations from primary saturation variable
-        Scalar satW = 0;
-        //Scalar satNW = 0;
-        switch (saturationType)
-        {
-        case Sw:
+        if (compressibility_)
         {
-            satW = problem_.variables().saturation()[globalIdx];
-            //satNW = 1 - problem_.variables().saturation()[globalIdx];
-            break;
-        }
-        case Sn:
-        {
-            satW = 1 - problem_.variables().saturation()[globalIdx];
-            //satNW = problem_.variables().saturation()[globalIdx];
-            break;
-        }
+            densityWIJ = (potentialWIJ > 0.) ? cellDataI.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
+            densityNWIJ = (potentialNWIJ > 0.) ? cellDataI.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
+            densityWIJ = (potentialWIJ == 0) ? rhoMeanWIJ : densityWIJ;
+            densityNWIJ = (potentialNWIJ == 0) ? rhoMeanNWIJ : densityNWIJ;
+            densityWIK = (potentialWIK > 0.) ? cellDataI.density(wPhaseIdx) : cellDataK.density(wPhaseIdx);
+            densityNWIK = (potentialNWIK > 0.) ? cellDataI.density(nPhaseIdx) : densityNWIK;
+            densityWIK = (potentialWIK == 0) ? rhoMeanWIK : densityWIK;
+            densityNWIK = (potentialNWIK == 0) ? rhoMeanNWIK : densityNWIK;
         }
 
-        problem_.variables().capillaryPressure(globalIdx) = MaterialLaw::pC(
-            problem_.spatialParameters().materialLawParams(*eIt), satW);
+        // update diagonal entry and right hand side
+        entries[matrix] = (lambdaWIJ + lambdaNWIJ) * kMean / l * faceArea;
+        entries[rhs] = faceArea * lambdaWIJ * kMean * ng
+                * ((densityWIJ) - (lJ / l) * (kI + kK) / kI * (densityWIK - densityWIJ) / 2);
+        entries[rhs] += faceArea * lambdaNWIJ * kMean * ng
+                * ((densityNWIJ) - (lJ / l) * (kI + kK) / kI * (densityNWIK - densityNWIJ) / 2);
 
-        //determine phase pressures from primary pressure variable
-        Scalar pressW = 0;
-        Scalar pressNW = 0;
-        switch (pressureType)
+        switch (pressureType_)
         {
         case pw:
         {
-            pressW = problem_.variables().pressure()[globalIdx];
-            pressNW = problem_.variables().pressure()[globalIdx] + problem_.variables().capillaryPressure(globalIdx);
+            entries[rhs] += faceArea * lambdaNWIJ * kMean * (pcJK - pcI) / l;
             break;
         }
         case pn:
         {
-            pressW = problem_.variables().pressure()[globalIdx] - problem_.variables().capillaryPressure(globalIdx);
-            pressNW = problem_.variables().pressure()[globalIdx];
+            entries[rhs] -= faceArea * lambdaWIJ * kMean * (pcJK - pcI) / l;
             break;
         }
         }
 
-        Scalar densityW = 0;
-        Scalar densityNW = 0;
-        Scalar viscosityW = 0;
-        Scalar viscosityNW = 0;
+        //write hanging-node-specific stuff directly into matrix and rhs!
+        this->f_[globalIdxI] -= entries[rhs];
+        this->f_[globalIdxJ] += entries[rhs];
 
-        if (compressibility)
-        {
-            fluidState.update(satW, pressW, pressNW, temperature);
-        }
-        else
-        {
-            pressW = problem_.referencePressure(*eIt);
-            pressNW = problem_.referencePressure(*eIt);
-            fluidState.update(satW, pressW, pressNW, temperature);
-        }
+        // set diagonal entry
+        this->A_[globalIdxI][globalIdxI] += entries[matrix];
+        this->A_[globalIdxI][globalIdxJ] -= 0.5 * entries[matrix];
+        this->A_[globalIdxI][globalIdxK] -= 0.5 * entries[matrix];
 
-        densityW = FluidSystem::phaseDensity(wPhaseIdx, temperature, pressW, fluidState);
-        densityNW = FluidSystem::phaseDensity(nPhaseIdx, temperature, pressNW, fluidState);
+        // set off-diagonal entry
+        this->A_[globalIdxJ][globalIdxI] -= entries[matrix];
+        this->A_[globalIdxJ][globalIdxJ] += 0.5 * entries[matrix];
+        this->A_[globalIdxJ][globalIdxK] += 0.5 * entries[matrix];
 
-        viscosityW = FluidSystem::phaseViscosity(wPhaseIdx, temperature, pressW, fluidState);
-        viscosityNW = FluidSystem::phaseViscosity(nPhaseIdx, temperature, pressNW, fluidState);
+        //set entries to zero -> matrix already written!
+        entries = 0.;
 
-        // initialize mobilities
-        Scalar mobilityW = MaterialLaw::krw(problem_.spatialParameters().materialLawParams(*eIt), satW) / viscosityW;
-        Scalar mobilityNW = MaterialLaw::krn(problem_.spatialParameters().materialLawParams(*eIt), satW) / viscosityNW;
-
-        if (compressibility)
-        {
-            mobilityW *= densityW;
-            mobilityNW *= densityNW;
-        }
-
-        // initialize mobilities
-        problem_.variables().mobilityWetting(globalIdx) = mobilityW;
-        problem_.variables().mobilityNonwetting(globalIdx) = mobilityNW;
-
-        // initialize densities
-        problem_.variables().densityWetting(globalIdx) = densityW;
-        problem_.variables().densityNonwetting(globalIdx) = densityNW;
-
-        // initialize viscosities
-        problem_.variables().viscosityWetting(globalIdx) = viscosityW;
-        problem_.variables().viscosityNonwetting(globalIdx) = viscosityNW;
-
-        //initialize fractional flow functions
-        problem_.variables().fracFlowFuncWetting(globalIdx) = mobilityW / (mobilityW + mobilityNW);
-        problem_.variables().fracFlowFuncNonwetting(globalIdx) = mobilityNW / (mobilityW + mobilityNW);
+//        std::cout<<"finished hanging node!\n";
     }
+
     return;
 }
 
diff --git a/dumux/decoupled/2p/diffusion/fv/fvvelocity2padaptive.hh b/dumux/decoupled/2p/diffusion/fv/fvvelocity2padaptive.hh
index 0ebc8dfaabd4c29169853515422e931ca6910099..9063b2871ba0f1c110f959aa8f4156a938f74742 100644
--- a/dumux/decoupled/2p/diffusion/fv/fvvelocity2padaptive.hh
+++ b/dumux/decoupled/2p/diffusion/fv/fvvelocity2padaptive.hh
@@ -28,8 +28,7 @@
  * @author Markus Wolff
  */
 
-#include <dumux/decoupled/2p/diffusion/fv/fvpressure2padaptive.hh>
-#include <dune/grid/common/gridenums.hh>
+#include <dumux/decoupled/2p/diffusion/fv/fvvelocity2p.hh>
 
 namespace Dumux
 {
@@ -51,14 +50,14 @@ namespace Dumux
  */
 
 template<class TypeTag>
-class FVVelocity2Padaptive: public FVPressure2Padaptive<TypeTag>
+class FVVelocity2Padaptive: public FVVelocity2P<TypeTag>
 {
-    typedef FVVelocity2Padaptive<TypeTag> ThisType;
-    typedef FVPressure2Padaptive<TypeTag> ParentType;
+    typedef FVVelocity2P<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;
-     typedef typename GET_PROP_TYPE(TypeTag, Variables) Variables;
+
 
      typedef typename GET_PROP_TYPE(TypeTag, SpatialParameters) SpatialParameters;
      typedef typename SpatialParameters::MaterialLaw MaterialLaw;
@@ -71,13 +70,13 @@ class FVVelocity2Padaptive: public FVPressure2Padaptive<TypeTag>
      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 GridView::Traits::template Codim<0>::Entity Element;
-    typedef typename GridView::Grid Grid;
-    typedef typename GridView::IndexSet IndexSet;
     typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     typedef typename GridView::IntersectionIterator IntersectionIterator;
-    typedef typename Grid::template Codim<0>::EntityPointer ElementPointer;
+    typedef typename GridView::Intersection Intersection;
+    typedef typename GridView::template Codim<0>::EntityPointer ElementPointer;
 
     enum
     {
@@ -85,8 +84,6 @@ typedef typename GridView::Traits::template Codim<0>::Entity Element;
     };
 
     typedef Dune::GenericReferenceElements<Scalar, dim> ReferenceElementContainer;
-    typedef Dune::GenericReferenceElements<Scalar, dim-1> ReferenceElementFaceContainer;
-    typedef Dune::GenericReferenceElement<Scalar, dim> ReferenceElement;
 
     enum
     {
@@ -105,7 +102,7 @@ typedef typename GridView::Traits::template Codim<0>::Entity Element;
     };
     enum
     {
-        wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx
+        wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx, numPhases = GET_PROP_VALUE(TypeTag, NumPhases)
     };
 
     typedef Dune::FieldVector<Scalar,dimWorld> GlobalPosition;
@@ -117,7 +114,7 @@ public:
      * \param problem a problem class object
      */
     FVVelocity2Padaptive(Problem& problem)
-    : FVPressure2Padaptive<TypeTag>(problem)
+    : ParentType(problem), problem_(problem), gravity_(problem.gravity())
     {
     	// todo: kompatibilität prüfen
         if (GET_PROP_VALUE(TypeTag, EnableCompressibility) && velocityType_ == vt)
@@ -128,6 +125,21 @@ public:
         {
             DUNE_THROW(Dune::NotImplemented, "Velocity type not supported!");
         }
+
+        if (!compressibility_)
+        {
+            const Element& 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);
+        }
     }
 
     //! Calculate the velocity.
@@ -138,954 +150,324 @@ public:
      *  The method is needed in the IMPES (Implicit Pressure Explicit Saturation) algorithm which is used for a fractional flow formulation
      *  to provide the velocity field required for the solution of the saturation equation.
      */
-    void calculateVelocity();
+    void calculateVelocity(const Intersection& intersection, CellData& cellDataI);
 
-    void update()
-    {
-        ParentType::update();
+private:
+    Problem& problem_;
+    const GlobalPosition& gravity_; //!< vector including the gravity constant
+    Scalar density_[numPhases];
+    Scalar viscosity_[numPhases];
 
-        calculateVelocity();
+    static const int velocityType_ = GET_PROP_VALUE(TypeTag, VelocityFormulation); //!< gives kind of velocity used (\f$ 0 = v_w\f$, \f$ 1 = v_n\f$, \f$ 2 = v_t\f$)
+    static const bool compressibility_ = GET_PROP_VALUE(TypeTag, EnableCompressibility);
+    static const int pressureType_ = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$p_w\f$, \f$p_n\f$, \f$p_{global}\f$)
+    static const int saturationType_ = GET_PROP_VALUE(TypeTag, SaturationFormulation); //!< gives kind of saturation used (\f$S_w\f$, \f$S_n\f$)
+};
 
-        return;
-    }
+template<class TypeTag>
+void FVVelocity2Padaptive<TypeTag>::calculateVelocity(const Intersection& intersection, CellData& cellDataI)
+{
+    ElementPointer elementI = intersection.inside();
+    ElementPointer elementJ = intersection.outside();
 
-    //! \brief Write data files
-    /*  \param name file name */
-    template<class MultiWriter>
-    void addOutputVtkFields(MultiWriter &writer)
+    if (elementI->level() == elementJ->level())
     {
-        ParentType::addOutputVtkFields(writer);
-
-        Dune::BlockVector<Dune::FieldVector<Scalar, dim> > &velocity = *(writer.template allocateManagedBuffer<Scalar, dim> (
-                this->problem().gridView().size(0)));
-        Dune::BlockVector<Dune::FieldVector<Scalar, dim> > &velocitySecondPhase = *(writer.template allocateManagedBuffer<Scalar, dim> (
-                this->problem().gridView().size(0)));
-
-        // compute update vector
-        ElementIterator eItEnd = this->problem().gridView().template end<0>();
-        for (ElementIterator eIt = this->problem().gridView().template begin<0>(); eIt != eItEnd; ++eIt)
+        ParentType::calculateVelocity(intersection, cellDataI);
+    }
+    else if (elementJ->level() == elementI->level() + 1)
+    {
+        CellData& cellDataJ = problem_.variables().cellData(problem_.variables().index(*elementJ));
+
+        // get global coordinates of cell centers
+        const GlobalPosition& globalPosI = elementI->geometry().center();
+        const GlobalPosition& globalPosJ = elementJ->geometry().center();
+
+        // get mobilities and fractional flow factors
+        Scalar lambdaWI = cellDataI.mobility(wPhaseIdx);
+        Scalar lambdaNWI = cellDataI.mobility(nPhaseIdx);
+        Scalar fractionalWI = cellDataI.fracFlowFunc(wPhaseIdx);
+        Scalar fractionalNWI = cellDataI.fracFlowFunc(nPhaseIdx);
+        Scalar lambdaWJ = cellDataJ.mobility(wPhaseIdx);
+        Scalar lambdaNWJ = cellDataJ.mobility(nPhaseIdx);
+        Scalar fractionalWJ = cellDataJ.fracFlowFunc(wPhaseIdx);
+        Scalar fractionalNWJ = cellDataJ.fracFlowFunc(nPhaseIdx);
+
+        // get capillary pressure
+        Scalar pcI = cellDataI.capillaryPressure();
+        Scalar pcJ = cellDataJ.capillaryPressure();
+
+        //get face index
+        int isIndexI = intersection.indexInInside();
+
+        //get face normal
+        const Dune::FieldVector<Scalar, dim>& unitOuterNormal = intersection.centerUnitOuterNormal();
+
+        // get face area
+        Scalar faceArea = intersection.geometry().volume();
+
+        // distance vector between barycenters
+        GlobalPosition distVecIJ = globalPosJ - globalPosI;
+
+        // compute distance between cell centers
+        Scalar distIJ = distVecIJ.two_norm();
+
+        // Count number of hanging nodes
+        // not really necessary
+        int isIndexJ = intersection.indexInOutside();
+
+        int globalIdxK = 0;
+        ElementPointer elementK = intersection.outside();
+        // We are looking for two things:
+        // IsIndexJ, the index of the interface from the neighbor-cell point of view
+        // GlobalIdxK, the index of the third cell
+        // for efficienty this is done in one IntersectionIterator-Loop
+
+        // Intersectioniterator around cell I
+        IntersectionIterator isItEndI = problem_.gridView().iend(*elementI);
+        for (IntersectionIterator isItI = problem_.gridView().ibegin(*elementI); isItI != isItEndI; ++isItI)
         {
-            // cell index
-            int globalIdx = this->problem().variables().index(*eIt);
-
-            Dune::FieldVector<Scalar, 2*dim> fluxW(0);
-            Dune::FieldVector<Scalar, 2*dim> fluxNW(0);
-            // run through all intersections with neighbors and boundary
-            IntersectionIterator
-            isItEnd = this->problem().gridView().iend(*eIt);
-            for (IntersectionIterator
-                    isIt = this->problem().gridView().ibegin(*eIt); isIt
-                    !=isItEnd; ++isIt)
+            if (isItI->neighbor())
             {
-                int isIndex = isIt->indexInInside();
+                ElementPointer neighborPointer2 = isItI->outside();
 
-                fluxW[isIndex] = isIt->geometry().volume() * (isIt->centerUnitOuterNormal() * this->problem().variables().velocityElementFace(*eIt, isIndex));
-                fluxNW[isIndex] = isIt->geometry().volume() * (isIt->centerUnitOuterNormal() * this->problem().variables().velocitySecondPhase()[this->problem().variables().index(*eIt)][isIndex]);
+                // make sure we do not chose elemntI as third element
+                // -> faces with hanging node have more than one intersection but only one face index!
+                if (neighborPointer2 != elementJ && isItI->indexInInside() == isIndexI)
+                {
+                    globalIdxK = problem_.variables().index(*neighborPointer2);
+                    elementK = neighborPointer2;
+                    break;
+                }
             }
+        }
 
-            Dune::FieldVector<Scalar, dim> refVelocity(0);
-            refVelocity[0] = 0.5 * (fluxW[1] - fluxW[0]);
-            refVelocity[1] = 0.5 * (fluxW[3] - fluxW[2]);
-
-            const Dune::FieldVector<Scalar, dim>& localPos = ReferenceElementContainer::general(eIt->geometry().type()).position(0,
-                    0);
-
-            // get the transposed Jacobian of the element mapping
-            const FieldMatrix& jacobianInv = eIt->geometry().jacobianInverseTransposed(localPos);
-            FieldMatrix jacobianT(jacobianInv);
-            jacobianT.invert();
+        CellData& cellDataK = problem_.variables().cellData(globalIdxK);
+
+        // face global coordinates
+        const GlobalPosition& globalPosInterface = intersection.geometry().center();
+
+        Dune::FieldVector < Scalar, dimWorld > distVec = globalPosInterface - globalPosI;
+        Scalar lI = distVec * unitOuterNormal;
+        distVec = globalPosJ - globalPosInterface;
+        Scalar lJ = distVec * unitOuterNormal;
+        Scalar l = lI + lJ;
+
+        FieldMatrix permeabilityI(0);
+        FieldMatrix permeabilityJ(0);
+        FieldMatrix permeabilityK(0);
+
+        problem_.spatialParameters().meanK(permeabilityI,
+                problem_.spatialParameters().intrinsicPermeability(*elementI));
+        problem_.spatialParameters().meanK(permeabilityJ,
+                problem_.spatialParameters().intrinsicPermeability(*elementJ));
+        problem_.spatialParameters().meanK(permeabilityK,
+                problem_.spatialParameters().intrinsicPermeability(*elementK));
+
+        // Calculate permeablity component normal to interface
+        Scalar kI, kJ, kK, ng, kMean; //, gI, gJ, gK;
+        Dune::FieldVector < Scalar, dim > permI(0);
+        Dune::FieldVector < Scalar, dim > permJ(0);
+        Dune::FieldVector < Scalar, dim > permK(0);
+
+        permeabilityI.mv(unitOuterNormal, permI);
+        permeabilityJ.mv(unitOuterNormal, permJ);
+        permeabilityK.mv(unitOuterNormal, permK);
+
+        // kI,kJ,kK = (n^T)Kn
+        kI = unitOuterNormal * permI;
+        kJ = unitOuterNormal * permJ;
+        kK = unitOuterNormal * permK;
+        kMean = kI * kJ * kK * l / (kJ * kK * lI + kI * (kJ + kK) / 2 * lJ);
+
+        ng = gravity_ * unitOuterNormal;
+
+        Scalar lambdaWK = cellDataK.mobility(wPhaseIdx);
+        Scalar lambdaNWK = cellDataK.mobility(nPhaseIdx);
+        Scalar fractionalWK = cellDataK.fracFlowFunc(wPhaseIdx);
+        Scalar fractionalNWK = cellDataK.fracFlowFunc(nPhaseIdx);
+
+        Scalar pcK = cellDataK.capillaryPressure();
+        Scalar pcJK = (pcJ + pcK) / 2;
+
+        // calculate potential gradients
+        // reuse potentials from fvpressure2padaptive
+        Scalar potentialWIJ = cellDataI.fluxData().potential(wPhaseIdx, isIndexI);
+        Scalar potentialNWIJ = cellDataI.fluxData().potential(nPhaseIdx, isIndexI);
+        Scalar potentialWIK = potentialWIJ;
+        Scalar potentialNWIK = potentialNWIJ;
+        // preliminary potential. The "real" ones are found below
+
+        // Comment: reversed weighting is plausible, too (swap lJ and lI)
+        Scalar rhoMeanWIJ = density_[wPhaseIdx];
+        Scalar rhoMeanNWIJ = density_[nPhaseIdx];
+        Scalar rhoMeanWIK = density_[wPhaseIdx];
+        Scalar rhoMeanNWIK = density_[nPhaseIdx];
+
+        if (compressibility_)
+        {
+            rhoMeanWIJ = (lJ * cellDataI.density(wPhaseIdx) + lI * cellDataJ.density(wPhaseIdx)) / l;
+            rhoMeanNWIJ = (lJ * cellDataI.density(nPhaseIdx) + lI * cellDataJ.density(nPhaseIdx)) / l;
+            rhoMeanWIK = (lJ * cellDataI.density(wPhaseIdx) + lI * cellDataK.density(wPhaseIdx)) / l;
+            rhoMeanNWIK = (lJ * cellDataI.density(nPhaseIdx) + lI * cellDataK.density(nPhaseIdx)) / l;
+        }
 
-            // calculate the element velocity by the Piola transformation
-            Dune::FieldVector<Scalar, dim> elementVelocity(0);
-            jacobianT.umtv(refVelocity, elementVelocity);
-            elementVelocity /= eIt->geometry().integrationElement(localPos);
+        Scalar fMeanWIJ = (lJ * fractionalWI + lI * fractionalWJ) / l;
+        Scalar fMeanNWIJ = (lJ * fractionalNWI + lI * fractionalNWJ) / l;
+        Scalar fMeanWIK = (lJ * fractionalWI + lI * fractionalWK) / l;
+        Scalar fMeanNWIK = (lJ * fractionalNWI + lI * fractionalNWK) / l;
 
-            velocity[globalIdx] = elementVelocity;
+        Scalar densityWIJ = density_[wPhaseIdx];
+        Scalar densityNWIJ = density_[nPhaseIdx];
+        Scalar densityWIK = density_[wPhaseIdx];
+        Scalar densityNWIK = density_[nPhaseIdx];
 
-            refVelocity = 0;
-            refVelocity[0] = 0.5 * (fluxNW[1] - fluxNW[0]);
-            refVelocity[1] = 0.5 * (fluxNW[3] - fluxNW[2]);
+        if (compressibility_)
+        {
+        // Upwinding for finding the upwinding direction
+            densityWIJ = (potentialWIJ > 0.) ? cellDataI.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
+            densityNWIJ = (potentialNWIJ > 0.) ? cellDataI.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
+            densityWIK = (potentialWIK > 0.) ? cellDataI.density(wPhaseIdx) : cellDataK.density(wPhaseIdx);
+            densityNWIK = (potentialNWIK > 0.) ? cellDataI.density(nPhaseIdx) : cellDataK.density(nPhaseIdx);
+
+            densityWIJ = (potentialWIJ == 0.) ? rhoMeanWIJ : densityWIJ;
+            densityNWIJ = (potentialNWIJ == 0.) ? rhoMeanNWIJ : densityNWIJ;
+            densityWIK = (potentialWIK == 0.) ? rhoMeanWIK : densityWIK;
+            densityNWIK = (potentialNWIK == 0.) ? rhoMeanNWIK : densityNWIK;
+        }
 
-            // calculate the element velocity by the Piola transformation
-            elementVelocity = 0;
-            jacobianT.umtv(refVelocity, elementVelocity);
-            elementVelocity /= eIt->geometry().integrationElement(localPos);
+        Scalar fractionalWIJ = (potentialWIJ > 0.) ? fractionalWI : fractionalWJ;
+        Scalar fractionalNWIJ = (potentialNWIJ > 0.) ? fractionalNWI : fractionalNWJ;
+        Scalar fractionalWIK = (potentialWIK > 0.) ? fractionalWI : fractionalWK;
+        Scalar fractionalNWIK = (potentialNWIK > 0.) ? fractionalNWI : fractionalNWK;
 
-            velocitySecondPhase[globalIdx] = elementVelocity;
-        }
+        fractionalWIJ = (potentialWIJ == 0.) ? fMeanWIJ : fractionalWIJ;
+        fractionalNWIJ = (potentialNWIJ == 0.) ? fMeanNWIJ : fractionalNWIJ;
+        fractionalWIK = (potentialWIK == 0.) ? fMeanWIK : fractionalWIK;
+        fractionalNWIK = (potentialNWIK == 0.) ? fMeanNWIK : fractionalNWIK;
 
-        //switch velocities
-        switch (velocityType_)
+        switch (pressureType_)
         {
-        case vw:
+        case pglobal:
         {
-            writer.attachCellData(velocity, "wetting-velocity", dim);
-            writer.attachCellData(velocitySecondPhase, "non-wetting-velocity", dim);
+            Scalar pressJK = (cellDataJ.globalPressure() + cellDataK.globalPressure()) / 2;
+
+            potentialWIJ = (cellDataI.globalPressure() - fMeanNWIJ * pcI - (pressJK - fMeanNWIJ * pcJK)) / l
+                    + (densityWIJ - lJ / l * (kI + kK) / kI * (densityWIK - densityWIJ) / 2) * ng;
+            potentialNWIJ = (cellDataI.globalPressure() + fMeanWIJ * pcI - (pressJK + fMeanWIJ * pcJK)) / l
+                    + (densityNWIJ - lJ / l * (kI + kK) / kI * (densityNWIK - densityNWIJ) / 2) * ng;
+            potentialWIK = (cellDataI.globalPressure() - fMeanNWIK * pcI - (pressJK - fMeanNWIK * pcJK)) / l
+                    + (densityWIK - lJ / l * (kI + kK) / kI * (densityWIJ - densityWIK) / 2) * ng;
+            potentialNWIK = (cellDataI.globalPressure() + fMeanWIK * pcI - (pressJK + fMeanWIK * pcJK)) / l
+                    + (densityNWIK - lJ / l * (kI + kK) / kI * (densityNWIJ - densityNWIK) / 2) * ng;
             break;
         }
-        case vn:
+        default:
         {
-            writer.attachCellData(velocity, "non-wetting-velocity", dim);
-            writer.attachCellData(velocitySecondPhase, "wetting-velocity", dim);
+            potentialWIJ = (cellDataI.pressure(wPhaseIdx)
+                    - 0.5 * (cellDataJ.pressure(wPhaseIdx) + cellDataK.pressure(wPhaseIdx))) / l
+                    + (densityWIJ - lJ / l * (kI + kK) / kI * (densityWIK - densityWIJ) / 2) * ng;
+            potentialNWIJ = (cellDataI.pressure(nPhaseIdx)
+                    - (0.5 * (cellDataJ.pressure(nPhaseIdx) + cellDataK.pressure(nPhaseIdx)))) / l
+                    + (densityNWIJ - lJ / l * (kI + kK) / kI * (densityNWIK - densityNWIJ) / 2) * ng;
+            potentialWIK = (cellDataI.pressure(wPhaseIdx)
+                    - 0.5 * (cellDataJ.pressure(wPhaseIdx) + cellDataK.pressure(wPhaseIdx))) / l
+                    + (densityWIK - lJ / l * (kI + kK) / kI * (densityWIJ - densityWIK) / 2) * ng;
+            potentialNWIK = (cellDataI.pressure(nPhaseIdx)
+                    - (0.5 * (cellDataJ.pressure(nPhaseIdx) + cellDataK.pressure(nPhaseIdx)))) / l
+                    + (densityNWIK - lJ / l * (kI + kK) / kI * (densityNWIJ - densityNWIK) / 2) * ng;
             break;
         }
-        case vt:
-        {
-            writer.attachCellData(velocity, "total velocity", dim);
-            break;
         }
+
+        //store potentials for further calculations (velocity, saturation, ...)
+        // these quantities only have correct sign (needed for upwinding)
+        // potentials are defined slightly different for adaptive scheme
+        cellDataI.fluxData().setPotential(wPhaseIdx, isIndexI, potentialWIJ);
+        cellDataI.fluxData().setPotential(nPhaseIdx, isIndexI, potentialNWIJ);
+        cellDataJ.fluxData().setPotential(wPhaseIdx, isIndexJ, -potentialWIJ);
+        cellDataJ.fluxData().setPotential(nPhaseIdx, isIndexJ, -potentialNWIJ);
+
+        //do the upwinding of the mobility depending on the phase potentials
+        Scalar lambdaWIJ = (potentialWIJ > 0.) ? lambdaWI : lambdaWJ;
+        lambdaWIJ = (potentialWIJ == 0) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaWIJ;
+        Scalar lambdaNWIJ = (potentialNWIJ > 0.) ? lambdaNWI : lambdaNWJ;
+        lambdaNWIJ = (potentialNWIJ == 0) ? 0.5 * (lambdaNWI + lambdaNWJ) : lambdaNWIJ;
+
+        if (compressibility_)
+        {
+            densityWIJ = (potentialWIJ > 0.) ? cellDataI.density(wPhaseIdx) : cellDataJ.density(wPhaseIdx);
+            densityNWIJ = (potentialNWIJ > 0.) ? cellDataI.density(nPhaseIdx) : cellDataJ.density(nPhaseIdx);
+            densityWIJ = (potentialWIJ == 0) ? rhoMeanWIJ : densityWIJ;
+            densityNWIJ = (potentialNWIJ == 0) ? rhoMeanNWIJ : densityNWIJ;
+            densityWIK = (potentialWIK > 0.) ? cellDataI.density(wPhaseIdx) : cellDataK.density(wPhaseIdx);
+            densityNWIK = (potentialNWIK > 0.) ? cellDataI.density(nPhaseIdx) : cellDataK.density(nPhaseIdx);
+            densityWIK = (potentialWIK == 0) ? rhoMeanWIK : densityWIK;
+            densityNWIK = (potentialNWIK == 0) ? rhoMeanNWIK : densityNWIK;
         }
 
-        return;
-    }
+        fractionalWIJ = (potentialWIJ > 0.) ? fractionalWI : fractionalWJ;
+        fractionalNWIJ = (potentialNWIJ > 0.) ? fractionalNWI : fractionalNWJ;
+        fractionalWIK = (potentialWIK > 0.) ? fractionalWI : fractionalWK;
+        fractionalNWIK = (potentialNWIK > 0.) ? fractionalNWI : fractionalNWK;
 
-private:
-    static const int velocityType_ = GET_PROP_VALUE(TypeTag, VelocityFormulation); //!< gives kind of velocity used (\f$ 0 = v_w\f$, \f$ 1 = v_n\f$, \f$ 2 = v_t\f$)
-};
+        fractionalWIJ = (potentialWIJ == 0.) ? fMeanWIJ : fractionalWIJ;
+        fractionalNWIJ = (potentialNWIJ == 0.) ? fMeanNWIJ : fractionalNWIJ;
+        fractionalWIK = (potentialWIK == 0.) ? fMeanWIK : fractionalWIK;
+        fractionalNWIK = (potentialNWIK == 0.) ? fMeanNWIK : fractionalNWIK;
 
-template<class TypeTag>
-void FVVelocity2Padaptive<TypeTag>::calculateVelocity()
-{
-    //reset velocity
-    this->problem().variables().velocity() = Dune::FieldVector<Scalar, dimWorld>(0.0);
-    this->problem().variables().velocitySecondPhase() = Dune::FieldVector<Scalar, dimWorld>(0.0);
+        //calculate velocities and the gravity term
+        Dune::FieldVector < Scalar, dimWorld > velocityW(unitOuterNormal);
+        Dune::FieldVector < Scalar, dimWorld > velocityNW(unitOuterNormal);
+        Dune::FieldVector < Scalar, dimWorld > gravityTermW(unitOuterNormal);
+        Dune::FieldVector < Scalar, dimWorld > gravityTermNW(unitOuterNormal);
 
-    BoundaryTypes bcType;
+        gravityTermW *= lambdaWIJ * kMean * ng;
+        gravityTermW *= densityWIJ - (lJ / l) * (kI + kK) / kI * (densityWIK - densityWIJ) / 2;
+        gravityTermNW *= lambdaNWIJ * kMean * ng;
+        gravityTermNW *= densityNWIJ - (lJ / l) * (kI + kK) / kI * (densityNWIK - densityNWIJ) / 2;
 
-    // compute update vector
-    ElementIterator eItEnd = this->problem().gridView().template end<0>();
-    for (ElementIterator eIt = this->problem().gridView().template begin<0>(); eIt != eItEnd; ++eIt)
-    {
-#if HAVE_MPI
-        if (eIt->partitionType() == Dune::GhostEntity || eIt->partitionType() == Dune::OverlapEntity)
+        switch (pressureType_)
         {
-            continue;
-        }
-#endif
-
-        // cell index
-        int globalIdxI = this->problem().variables().index(*eIt);
-
-        GlobalPosition globalPos = eIt->geometry().center();
-
-        Scalar pressI = this->problem().variables().pressure()[globalIdxI];
-        Scalar pcI = this->problem().variables().capillaryPressure(globalIdxI);
-        Scalar lambdaWI = this->problem().variables().mobilityWetting(globalIdxI);
-        Scalar lambdaNWI = this->problem().variables().mobilityNonwetting(globalIdxI);
-        Scalar fractionalWI = this->problem().variables().fracFlowFuncWetting(globalIdxI);
-        Scalar fractionalNWI = this->problem().variables().fracFlowFuncNonwetting(globalIdxI);
-        Scalar densityWI = this->problem().variables().densityWetting(globalIdxI);
-        Scalar densityNWI = this->problem().variables().densityNonwetting(globalIdxI);
-
-        // run through all intersections with neighbors and boundary
-        IntersectionIterator isItEnd = this->problem().gridView().iend(*eIt);
-        for (IntersectionIterator
-                isIt = this->problem().gridView().ibegin(*eIt); isIt
-                !=isItEnd; ++isIt)
+        case pw:
         {
-            // local number of facet
-            int isIndex = isIt->indexInInside();
+            velocityW *= lambdaWIJ * kMean * (cellDataI.pressure(wPhaseIdx) - (cellDataJ.pressure(wPhaseIdx) + cellDataK.pressure(wPhaseIdx)) / 2.0) / l;
+            velocityNW *= lambdaNWIJ * kMean * (cellDataI.pressure(nPhaseIdx) - (cellDataJ.pressure(nPhaseIdx) + cellDataK.pressure(nPhaseIdx)) / 2.0) / l;
 
-            Dune::FieldVector<Scalar,dimWorld> unitOuterNormal = isIt->centerUnitOuterNormal();
+            velocityW += gravityTermW;
+            velocityNW += gravityTermNW;
+            break;
+        }
+        case pn:
+        {
+            velocityNW *= lambdaNWIJ * kMean * (cellDataI.pressure(nPhaseIdx) - (cellDataJ.pressure(nPhaseIdx) + cellDataK.pressure(nPhaseIdx)) / 2.0) / l;
+            velocityW *= lambdaWIJ * kMean * (cellDataI.pressure(wPhaseIdx) - (cellDataJ.pressure(wPhaseIdx) + cellDataK.pressure(wPhaseIdx)) / 2.0) / l;
 
-            // handle interior face
-            if (isIt->neighbor())
-            {
-                // access neighbor
-                ElementPointer neighborPointer = isIt->outside();
-                int globalIdxJ = this->problem().variables().index(*neighborPointer);
+            velocityW += gravityTermW;
+            velocityNW += gravityTermNW;
+            break;
+        }
+        case pglobal:
+        {
+            Scalar pressJK = (cellDataJ.globalPressure() + cellDataK.globalPressure()) / 2;
 
-                if (neighborPointer->level()==eIt.level())
-                {
-					// neighbor cell center in global coordinates
-					const GlobalPosition& globalPosNeighbor = neighborPointer->geometry().center();
-
-					// distance vector between barycenters
-					Dune::FieldVector<Scalar,dimWorld> distVec = globalPosNeighbor - globalPos;
-
-					// compute distance between cell centers
-					Scalar dist = distVec * unitOuterNormal;
-//					Scalar dist = distVec.two_norm();
-
-					// compute vectorized permeabilities
-					FieldMatrix meanPermeability(0);
-
-					this->problem().spatialParameters().meanK(meanPermeability,
-							this->problem().spatialParameters().intrinsicPermeability(*eIt),
-							this->problem().spatialParameters().intrinsicPermeability(*neighborPointer));
-
-					Dune::FieldVector<Scalar, dim> permeability(0);
-					meanPermeability.mv(unitOuterNormal, permeability);
-
-					Scalar pressJ = this->problem().variables().pressure()[globalIdxJ];
-					Scalar pcJ = this->problem().variables().capillaryPressure(globalIdxJ);
-					Scalar lambdaWJ = this->problem().variables().mobilityWetting(globalIdxJ);
-					Scalar lambdaNWJ = this->problem().variables().mobilityNonwetting(globalIdxJ);
-					Scalar fractionalWJ = this->problem().variables().fracFlowFuncWetting(globalIdxJ);
-					Scalar fractionalNWJ = this->problem().variables().fracFlowFuncNonwetting(globalIdxJ);
-					Scalar densityWJ = this->problem().variables().densityWetting(globalIdxJ);
-					Scalar densityNWJ = this->problem().variables().densityNonwetting(globalIdxJ);
-
-					//calculate potential gradients
-					Scalar potentialW = 0;
-					Scalar potentialNW = 0;
-
-					potentialW = this->problem().variables().potentialWetting(globalIdxI, isIndex);
-					potentialNW = this->problem().variables().potentialNonwetting(globalIdxI, isIndex);
-
-					Scalar densityW = (potentialW> 0.) ? densityWI : densityWJ;
-					Scalar densityNW = (potentialNW> 0.) ? densityNWI : densityNWJ;
-
-					densityW = (potentialW == 0.) ? 0.5 * (densityWI + densityWJ) : densityW;
-					densityNW = (potentialNW == 0.) ? 0.5 * (densityNWI + densityNWJ) : densityNW;
-
-					switch (this->pressureType)
-					{
-						case pw:
-						{
-							potentialW = (pressI - pressJ);
-							potentialNW = (pressI - pressJ+ pcI - pcJ);
-							break;
-						}
-						case pn:
-						{
-							potentialW = (pressI - pressJ - pcI + pcJ);
-							potentialNW = (pressI - pressJ);
-							break;
-						}
-						case pglobal:
-						{
-							potentialW = (pressI - pressJ - 0.5 * (fractionalNWI+fractionalNWJ)*(pcI - pcJ));
-							potentialNW = (pressI - pressJ + 0.5 * (fractionalWI+fractionalWJ)*(pcI - pcJ));
-							break;
-						}
-					}
-
-					potentialW += densityW * (distVec * this->gravity);//delta z/delta x in unitOuterNormal[z]
-					potentialNW += densityNW * (distVec * this->gravity);
-
-					//store potentials for further calculations (velocity, saturation, ...)
-					this->problem().variables().potentialWetting(globalIdxI, isIndex) = potentialW;
-					this->problem().variables().potentialNonwetting(globalIdxI, isIndex) = potentialNW;
-
-					//do the upwinding of the mobility depending on the phase potentials
-					Scalar lambdaW = (potentialW > 0.) ? lambdaWI : lambdaWJ;
-					lambdaW = (potentialW == 0) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaW;
-					Scalar lambdaNW = (potentialNW > 0.) ? lambdaNWI : lambdaNWJ;
-					lambdaNW = (potentialNW == 0) ? 0.5 * (lambdaNWI + lambdaNWJ) : lambdaNW;
-					densityW = (potentialW> 0.) ? densityWI : densityWJ;
-					densityW = (potentialW == 0.) ? 0.5 * (densityWI + densityWJ) : densityW;
-					densityNW = (potentialNW> 0.) ? densityNWI : densityNWJ;
-					densityNW = (potentialNW == 0.) ? 0.5 * (densityNWI + densityNWJ) : densityNW;
-
-					//calculate the gravity term
-					Dune::FieldVector<Scalar,dimWorld> velocityW(permeability);
-					Dune::FieldVector<Scalar,dimWorld> velocityNW(permeability);
-					Dune::FieldVector<Scalar,dimWorld> gravityTermW(unitOuterNormal);
-					Dune::FieldVector<Scalar,dimWorld> gravityTermNW(unitOuterNormal);
-
-					gravityTermW *= (this->gravity*permeability)*(lambdaW * densityW);
-					gravityTermNW *= (this->gravity*permeability)*(lambdaNW * densityNW);
-
-					//calculate velocity depending on the pressure used -> use pc = pn - pw
-					switch (this->pressureType)
-					{
-						case pw:
-						{
-							velocityW *= lambdaW * (pressI - pressJ)/dist;
-							velocityNW *= lambdaNW * (pressI - pressJ)/dist + 0.5 * (lambdaNWI + lambdaNWJ) * (pcI - pcJ) / dist;
-							velocityW += gravityTermW;
-							velocityNW += gravityTermNW;
-							break;
-						}
-						case pn:
-						{
-							velocityW *= lambdaW * (pressI - pressJ)/dist - 0.5 * (lambdaWI + lambdaWJ) * (pcI - pcJ) / dist;
-							velocityNW *= lambdaNW * (pressI - pressJ) / dist;
-							velocityW += gravityTermW;
-							velocityNW += gravityTermNW;
-							break;
-						}
-						case pglobal:
-						{
-							this->problem().variables().velocity()[globalIdxI][isIndex] = permeability;
-							this->problem().variables().velocity()[globalIdxI][isIndex]*= (lambdaW + lambdaNW)* (pressI - pressJ )/ dist;
-							this->problem().variables().velocity()[globalIdxI][isIndex] += gravityTermW;
-							this->problem().variables().velocity()[globalIdxI][isIndex] += gravityTermNW;
-							break;
-						}
-					}
-
-					//store velocities
-					switch (velocityType_)
-					{
-						case vw:
-						{
-							this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW;
-							this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityNW;
-							break;
-						}
-						case vn:
-						{
-							this->problem().variables().velocity()[globalIdxI][isIndex] = velocityNW;
-							this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityW;
-							break;
-						}
-						case vt:
-						{
-							switch (this->pressureType)
-							{
-								case pw:
-								{
-									this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW + velocityNW;
-									this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityNW;
-									break;
-								}
-								case pn:
-								{
-									this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW + velocityNW;
-									this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityW;
-									break;
-								}
-							}
-							break;
-						}
-					} //end of switch (velocityType_)
-                } //End of case "same level"
-
-                if (neighborPointer->level()==eIt.level()+1)
-                {
-                	int globalIdxK = 0;
-					ElementPointer thirdCellPointer = isIt->outside();
-					bool foundK=false;
-					bool foundIJ=false;
-					// We are looking for two things:
-					// IsIndexJ, the index of the interface from the neighbor-cell point of view
-					// GlobalIdxK, the index of the third cell
-					// for efficienty this is done in one IntersectionIterator-Loop
-
-					// Intersectioniterator around cell J
-					IntersectionIterator isItEndJ = this->problem().gridView().iend(*neighborPointer);
-					for (IntersectionIterator isItJ = this->problem().gridView().ibegin(*neighborPointer); isItJ != isItEndJ; ++isItJ)
-					{
-						if (isItJ->neighbor())
-						{
-							ElementPointer neighborPointer2 = isItJ->outside();
-
-							// Neighbor of neighbor is Cell I?
-							if (this->problem().variables().index(*neighborPointer2)==globalIdxI)
-							{
-								foundIJ=true;
-							}
-							else
-							{
-								if (neighborPointer2->level()==eIt.level()+1)
-								{
-									// To verify, we found the correct Cell K, we check
-									// - is level(K)=level(J)?
-									// - is distance(IJ)=distance(IK)?
-									// - K is neighbor of J.
-									const GlobalPosition& globalPosNeighbor = neighborPointer->geometry().center();
-									const GlobalPosition& globalPosThirdCell = neighborPointer2->geometry().center();
-									Dune::FieldVector<Scalar, dimWorld> distVecIJ = globalPosNeighbor - globalPos;
-									Dune::FieldVector<Scalar, dimWorld> distVecIK = globalPosThirdCell - globalPos;
-									if (((distVecIK.two_norm()-distVecIJ.two_norm()))/distVecIJ.two_norm() < 0.001)
-									{
-										globalIdxK= this->problem().variables().index(*neighborPointer2);
-										thirdCellPointer = neighborPointer2;
-										foundK=true;
-									}
-
-								}
-							}
-						}
-						if (foundIJ && foundK) break;
-					}
-
-					int isIndexJ = isIt->indexInOutside();
-
-					// neighbor cell center in global coordinates
-					const GlobalPosition& globalPosNeighbor = neighborPointer->geometry().center();
-					const GlobalPosition& globalPosInterface = isIt->geometry().center();
-
-					Dune::FieldVector<Scalar,dimWorld> distVec = globalPosInterface - globalPos;
-					Scalar lI= distVec*unitOuterNormal;
-					distVec = globalPosNeighbor - globalPosInterface;
-					Scalar lJ= distVec*unitOuterNormal;
-					Scalar l=lI+lJ;
-
-					FieldMatrix permeabilityI(0);
-					FieldMatrix permeabilityJ(0);
-					FieldMatrix permeabilityK(0);
-
-					this->problem().spatialParameters().meanK(permeabilityI,
-							this->problem().spatialParameters().intrinsicPermeability(*eIt));
-					this->problem().spatialParameters().meanK(permeabilityJ,
-							this->problem().spatialParameters().intrinsicPermeability(*neighborPointer));
-					this->problem().spatialParameters().meanK(permeabilityK,
-							this->problem().spatialParameters().intrinsicPermeability(*thirdCellPointer));
-
-					// Calculate permeablity component normal to interface
-					Scalar kI, kJ, kK, ng, kMean;//, gI, gJ, gK;
-					Dune::FieldVector<Scalar, dim> permI(0);
-					Dune::FieldVector<Scalar, dim> permJ(0);
-					Dune::FieldVector<Scalar, dim> permK(0);
-
-					permeabilityI.mv(unitOuterNormal, permI);
-					permeabilityJ.mv(unitOuterNormal, permJ);
-					permeabilityK.mv(unitOuterNormal, permK);
-
-					// kI,kJ,kK = (n^T)Kn
-					kI=unitOuterNormal*permI;
-					kJ=unitOuterNormal*permJ;
-					kK=unitOuterNormal*permK;
-					kMean=kI*kJ*kK*l/(kJ*kK*lI+kI*(kJ+kK)/2*lJ);
-
-					ng=this->gravity*unitOuterNormal;
-
-					// find secondary variables in cell J and K
-					Scalar pressJ = this->problem().variables().pressure()[globalIdxJ];
-					Scalar pcJ = this->problem().variables().capillaryPressure(globalIdxJ);
-					Scalar lambdaWJ = this->problem().variables().mobilityWetting(globalIdxJ);
-					Scalar lambdaNWJ = this->problem().variables().mobilityNonwetting(globalIdxJ);
-					Scalar densityWJ = this->problem().variables().densityWetting(globalIdxJ);
-					Scalar densityNWJ = this->problem().variables().densityNonwetting(globalIdxJ);
-					Scalar fractionalWJ = this->problem().variables().fracFlowFuncWetting(globalIdxJ);
-					Scalar fractionalNWJ = this->problem().variables().fracFlowFuncNonwetting(globalIdxJ);
-
-					Scalar pressK = this->problem().variables().pressure()[globalIdxK];
-					Scalar pcK = this->problem().variables().capillaryPressure(globalIdxK);
-					Scalar densityWK = this->problem().variables().densityWetting(globalIdxK);
-					Scalar densityNWK = this->problem().variables().densityNonwetting(globalIdxK);
-					Scalar fractionalWK = this->problem().variables().fracFlowFuncWetting(globalIdxK);
-					Scalar fractionalNWK = this->problem().variables().fracFlowFuncNonwetting(globalIdxK);
-
-					Scalar pressJK=(pressJ+pressK)/2;
-					Scalar pcJK=(pcJ+pcK)/2;
-
-
-					// calculate potential gradients
-					// reuse potentials from fvpressure2padaptive
-
-					Scalar potentialWIJ = this->problem().variables().potentialWetting(globalIdxI, isIndex);
-					Scalar potentialNWIJ = this->problem().variables().potentialNonwetting(globalIdxI, isIndex);
-					// We dont know the insideIndex of interface IK
-					Scalar potentialWIK = potentialWIJ;
-					Scalar potentialNWIK = potentialNWIJ;
-					// preliminary potential. The "real" ones are found below
-
-					// Comment: reversed weighting is plausible, too (swap lJ and lI)
-					Scalar rhoMeanWIJ = (lJ*densityWI + lI*densityWJ)/l;
-					Scalar rhoMeanNWIJ = (lJ*densityNWI + lI*densityNWJ)/l;
-					Scalar rhoMeanWIK = (lJ*densityWI + lI*densityWK)/l;
-					Scalar rhoMeanNWIK = (lJ*densityNWI + lI*densityNWK)/l;
-
-					Scalar fMeanWIJ = (lJ*fractionalWI+lI*fractionalWJ)/l;
-					Scalar fMeanNWIJ = (lJ*fractionalNWI+lI*fractionalNWJ)/l;
-					Scalar fMeanWIK = (lJ*fractionalWI+lI*fractionalWK)/l;
-					Scalar fMeanNWIK = (lJ*fractionalNWI+lI*fractionalNWK)/l;
-
-					// Upwinding for finding the upwinding direction
-					Scalar densityWIJ = (potentialWIJ> 0.) ? densityWI : densityWJ;
-					Scalar densityNWIJ = (potentialNWIJ> 0.) ? densityNWI : densityNWJ;
-					Scalar densityWIK = (potentialWIK> 0.) ? densityWI : densityWK;
-					Scalar densityNWIK = (potentialNWIK> 0.) ? densityNWI : densityNWK;
-
-					densityWIJ = (potentialWIJ == 0.) ? rhoMeanWIJ : densityWIJ;
-					densityNWIJ = (potentialNWIJ == 0.) ? rhoMeanNWIJ : densityNWIJ;
-					densityWIK = (potentialWIK == 0.) ? rhoMeanWIK : densityWIK;
-					densityNWIK = (potentialNWIK == 0.) ? rhoMeanNWIK : densityNWIK;
-
-					Scalar fractionalWIJ = (potentialWIJ> 0.) ? fractionalWI : fractionalWJ;
-					Scalar fractionalNWIJ = (potentialNWIJ> 0.) ? fractionalNWI : fractionalNWJ;
-					Scalar fractionalWIK = (potentialWIK> 0.) ? fractionalWI : fractionalWK;
-					Scalar fractionalNWIK = (potentialNWIK> 0.) ? fractionalNWI : fractionalNWK;
-
-					fractionalWIJ = (potentialWIJ == 0.) ? fMeanWIJ : fractionalWIJ;
-					fractionalNWIJ = (potentialNWIJ == 0.) ? fMeanNWIJ : fractionalNWIJ;
-					fractionalWIK = (potentialWIK == 0.) ? fMeanWIK : fractionalWIK;
-					fractionalNWIK = (potentialNWIK == 0.) ? fMeanNWIK : fractionalNWIK;
-
-					switch (this->pressureType)
-					{
-						case pw:
-						{
-							potentialWIJ = (pressI-pressJK)/l+
-									(densityWIJ-lJ/l*(kI+kK)/kI*(densityWIK-densityWIJ)/2)*ng;
-							potentialNWIJ = (pressI+pcI-(pressJK+pcJK))/l+
-									(densityNWIJ-lJ/l*(kI+kK)/kI*(densityNWIK-densityNWIJ)/2)*ng;
-							potentialWIK = (pressI-pressJK)/l+
-									(densityWIK-lJ/l*(kI+kK)/kI*(densityWIJ-densityWIK)/2)*ng;
-							potentialNWIK = (pressI+pcI-(pressJK+pcJK))/l+
-									(densityNWIK-lJ/l*(kI+kK)/kI*(densityNWIJ-densityNWIK)/2)*ng;
-							break;
-						}
-						case pn:
-						{
-							potentialWIJ = (pressI-pcI-(pressJK-pcJK))/l+
-									(densityWIJ-lJ/l*(kI+kK)/kI*(densityWIK-densityWIJ)/2)*ng;
-							potentialNWIJ = (pressI-pressJK)/l+
-									(densityNWIJ-lJ/l*(kI+kK)/kI*(densityNWIK-densityNWIJ)/2)*ng;
-							potentialWIK = (pressI-pcI-(pressJK-pcJK))/l+
-									(densityWIK-lJ/l*(kI+kK)/kI*(densityWIJ-densityWIK)/2)*ng;
-							potentialNWIK = (pressI-pressJK)/l+
-									(densityNWIK-lJ/l*(kI+kK)/kI*(densityNWIJ-densityNWIK)/2)*ng;
-							break;
-						}
-						case pglobal:
-						{
-							potentialWIJ = (pressI-fractionalNWIJ*pcI-(pressJK-fractionalNWIJ*pcJK))/l+
-									(densityWIJ-lJ/l*(kI+kK)/kI*(densityWIK-densityWIJ)/2)*ng;
-							potentialNWIJ = (pressI+fractionalWIJ*pcI-(pressJK+fractionalWIJ*pcJK))/l+
-									(densityNWIJ-lJ/l*(kI+kK)/kI*(densityNWIK-densityNWIJ)/2)*ng;
-							potentialWIK = (pressI-fractionalNWIK*pcI-(pressJK-fractionalNWIK*pcJK))/l+
-									(densityWIK-lJ/l*(kI+kK)/kI*(densityWIJ-densityWIK)/2)*ng;
-							potentialNWIK = (pressI+fractionalWIK*pcI-(pressJK+fractionalWIK*pcJK))/l+
-									(densityNWIK-lJ/l*(kI+kK)/kI*(densityNWIJ-densityNWIK)/2)*ng;
-							break;
-						}
-					}
-
-					//store potentials for further calculations (velocity, saturation, ...)
-					// these quantities only have correct sign (needed for upwinding)
-					// potentials are defined slightly different for adaptive scheme
-					this->problem().variables().potentialWetting(globalIdxI, isIndex) = potentialWIJ;
-					this->problem().variables().potentialNonwetting(globalIdxI, isIndex) = potentialNWIJ;
-					this->problem().variables().potentialWetting(globalIdxJ, isIndexJ) = -potentialWIJ;
-					this->problem().variables().potentialNonwetting(globalIdxJ, isIndexJ) = -potentialNWIJ;
-
-
-					//do the upwinding of the mobility depending on the phase potentials
-					Scalar lambdaWIJ = (potentialWIJ > 0.) ? lambdaWI : lambdaWJ;
-					lambdaWIJ = (potentialWIJ == 0) ? 0.5 * (lambdaWI + lambdaWJ) : lambdaWIJ;
-					Scalar lambdaNWIJ = (potentialNWIJ > 0.) ? lambdaNWI : lambdaNWJ;
-					lambdaNWIJ = (potentialNWIJ == 0) ? 0.5 * (lambdaNWI + lambdaNWJ) : lambdaNWIJ;
-
-					densityWIJ = (potentialWIJ> 0.) ? densityWI : densityWJ;
-					densityNWIJ = (potentialNWIJ> 0.) ? densityNWI : densityNWJ;
-					densityWIK = (potentialWIK> 0.) ? densityWI : densityWK;
-					densityNWIK = (potentialNWIK> 0.) ? densityNWI : densityNWK;
-
-					densityWIJ = (potentialWIJ == 0.) ? rhoMeanWIJ : densityWIJ;
-					densityNWIJ = (potentialNWIJ == 0.) ? rhoMeanNWIJ : densityNWIJ;
-					densityWIK = (potentialWIK == 0.) ? rhoMeanWIK : densityWIK;
-					densityNWIK = (potentialNWIK == 0.) ? rhoMeanNWIK : densityNWIK;
-
-					fractionalWIJ = (potentialWIJ> 0.) ? fractionalWI : fractionalWJ;
-					fractionalNWIJ = (potentialNWIJ> 0.) ? fractionalNWI : fractionalNWJ;
-					fractionalWIK = (potentialWIK> 0.) ? fractionalWI : fractionalWK;
-					fractionalNWIK = (potentialNWIK> 0.) ? fractionalNWI : fractionalNWK;
-
-					fractionalWIJ = (potentialWIJ == 0.) ? fMeanWIJ : fractionalWIJ;
-					fractionalNWIJ = (potentialNWIJ == 0.) ? fMeanNWIJ : fractionalNWIJ;
-					fractionalWIK = (potentialWIK == 0.) ? fMeanWIK : fractionalWIK;
-					fractionalNWIK = (potentialNWIK == 0.) ? fMeanNWIK : fractionalNWIK;
-
-					//calculate velocities and the gravity term
-					Dune::FieldVector<Scalar,dimWorld> velocityW(unitOuterNormal);
-					Dune::FieldVector<Scalar,dimWorld> velocityNW(unitOuterNormal);
-					Dune::FieldVector<Scalar,dimWorld> gravityTermW(unitOuterNormal);
-					Dune::FieldVector<Scalar,dimWorld> gravityTermNW(unitOuterNormal);
-
-					gravityTermW *= lambdaWIJ*kMean*ng;
-					gravityTermW *= densityWIJ-(lJ/l)*(kI+kK)/kI*(densityWIK-densityWIJ)/2;
-					gravityTermNW *= lambdaNWIJ*kMean*ng;
-					gravityTermNW *= densityNWIJ-(lJ/l)*(kI+kK)/kI*(densityNWIK-densityNWIJ)/2;
-
-					switch (this->pressureType)
-					{
-						case pw:
-						{
-							velocityW *= lambdaWIJ*kMean*(pressI-pressJK)/l;
-							velocityNW *= lambdaNWIJ*kMean*(pressI+pcI-(pressJK+pcJK))/l;
-
-							velocityW += gravityTermW;
-							velocityNW += gravityTermNW;
-							break;
-						}
-						case pn:
-						{
-							velocityNW *= lambdaNWIJ*kMean*(pressI-pressJK)/l;
-							velocityW *= lambdaWIJ*kMean*(pressI-pcI-(pressJK-pcJK))/l;
-
-							velocityW += gravityTermW;
-							velocityNW += gravityTermNW;
-							break;
-						}
-						case pglobal:
-						{
-							velocityW *= lambdaWIJ*kMean*(pressI-fractionalNWIJ*pcI-(pressJK-fractionalNWIJ*pcJK))/l;
-							velocityNW *= lambdaNWIJ*kMean*(pressI+fractionalWIJ*pcI-(pressJK+fractionalWIJ*pcJK))/l;
-
-							velocityW += gravityTermW;
-							velocityNW += gravityTermNW;
-							break;
-						}
-					}
-
-					switch (velocityType_)
-					{
-						case vw:
-						{
-						    Dune::FieldVector<Scalar,dimWorld> vel(velocityW);
-						    vel*=0.5;//0.5 -> only one hanging node per face!
-							this->problem().variables().velocity()[globalIdxI][isIndex] += vel;
-						    vel = velocityNW;
-						    vel*=0.5;
-							this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] += vel;
-							this->problem().variables().velocity()[globalIdxJ][isIndexJ] = velocityW;
-							this->problem().variables().velocitySecondPhase()[globalIdxJ][isIndexJ] = velocityNW;
-							break;
-						}
-						case vn:
-						{
-                            Dune::FieldVector<Scalar,dimWorld> vel(velocityNW);
-                            vel*=0.5;
-							this->problem().variables().velocity()[globalIdxI][isIndex] += (vel);
-                            vel = velocityW;
-                            vel*=0.5;
-							this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] += (vel);
-							this->problem().variables().velocity()[globalIdxJ][isIndexJ] = velocityNW;
-							this->problem().variables().velocitySecondPhase()[globalIdxJ][isIndexJ] = velocityW;
-							break;
-						}
-						case vt:
-						{
-							switch (this->pressureType)
-							{
-								case pw:
-								{
-								    Dune::FieldVector<Scalar,dimWorld> vel(velocityW);
-								    vel+=velocityNW;
-									this->problem().variables().velocity()[globalIdxI][isIndex] += (vel *=0.5);
-									vel = velocityNW;
-									this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] += (vel*=0.5);
-									this->problem().variables().velocity()[globalIdxJ][isIndexJ] = velocityW + velocityNW;
-									this->problem().variables().velocitySecondPhase()[globalIdxJ][isIndexJ] = velocityNW;
-
-									break;
-								}
-								case pn:
-								{
-                                    Dune::FieldVector<Scalar,dimWorld> vel(velocityW);
-                                    vel+=velocityNW;
-									this->problem().variables().velocity()[globalIdxI][isIndex] += (vel *=0.5);
-									vel = velocityW;
-									this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] += (vel*=0.5);
-									this->problem().variables().velocity()[globalIdxJ][isIndexJ] = velocityW + velocityNW;
-									this->problem().variables().velocitySecondPhase()[globalIdxJ][isIndexJ] = velocityW;
-									break;
-								}
-							}
-							break;
-						}
-					}
-                }
-            }//end intersection with neighbor
+            velocityW *= lambdaWIJ * kMean * (cellDataI.globalPressure() - pressJK) / l;
+            velocityW += gravityTermW;
+            velocityW += gravityTermNW;
+            velocityNW = 0;
+            break;
+        }
+        }
 
-            // handle boundary face
-            if (isIt->boundary())
-            {
-                //get boundary type
-                this->problem().boundaryTypes(bcType, *isIt);
-                PrimaryVariables boundValues(0.0);
+        cellDataJ.fluxData().setVelocity(wPhaseIdx, isIndexJ, velocityW);
+        cellDataJ.fluxData().setVelocity(nPhaseIdx, isIndexJ, velocityNW);
+        cellDataJ.fluxData().setVelocityMarker(isIndexJ);
 
-                if (bcType.isDirichlet(eqIdxPress))
-                {
-                    this->problem().dirichlet(boundValues, *isIt);
-
-                    // center of face in global coordinates
-                    GlobalPosition globalPosFace = isIt->geometry().center();
-
-                    // distance vector between barycenters
-                    Dune::FieldVector<Scalar,dimWorld> distVec = globalPosFace - globalPos;
-
-                    // compute distance between cell centers
-                    Scalar dist = distVec * unitOuterNormal;
-//                    Scalar dist = distVec.two_norm();
-
-                    //permeability vector at boundary
-                    // compute vectorized permeabilities
-                    FieldMatrix meanPermeability(0);
-
-                    this->problem().spatialParameters().meanK(meanPermeability,
-                            this->problem().spatialParameters().intrinsicPermeability(*eIt));
-
-                    Dune::FieldVector<Scalar, dim> permeability(0);
-                    meanPermeability.mv(unitOuterNormal, permeability);
-
-                    Scalar satBound = 0;
-                    if (bcType.isDirichlet(eqIdxSat))
-                    {
-                        satBound = boundValues[saturationIdx];
-                    }
-                    else
-                    {
-                        satBound = this->problem().variables().saturation()[globalIdxI];
-                    }
-
-                    //determine phase saturations from primary saturation variable
-                    Scalar satW;
-                    //Scalar satNW;
-                    switch (this->saturationType)
-                    {
-                    case Sw:
-                    {
-                        satW = satBound;
-                        //satNW = 1-satBound;
-                        break;
-                    }
-                    case Sn:
-                    {
-                        satW = 1-satBound;
-                        //satNW = satBound;
-                        break;
-                    }
-                    default:
-                    {
-                        DUNE_THROW(Dune::RangeError, "saturation type not implemented");
-                        break;
-                    }
-                    }
-                    Scalar pressBound = boundValues[pressureIdx];
-                    Scalar pcBound = MaterialLaw::pC(this->problem().spatialParameters().materialLawParams(*eIt), satW);
-
-                    //determine phase pressures from primary pressure variable
-                    Scalar pressW=0;
-                    Scalar pressNW=0;
-                    switch (this->pressureType)
-                    {
-                    case pw:
-                    {
-                        pressW = pressBound;
-                        pressNW = pressBound + pcBound;
-                        break;
-                    }
-                    case pn:
-                    {
-                        pressW = pressBound - pcBound;
-                        pressNW = pressBound;
-                        break;
-                    }
-                    }
-
-                    //get temperature at current position
-                    Scalar temperature = this->problem().temperature(*eIt);
-
-                    Scalar densityWBound = 0;
-                    Scalar densityNWBound = 0;
-                    Scalar lambdaWBound = 0;
-                    Scalar lambdaNWBound = 0;
-                    if (this->compressibility)
-                    {
-                        FluidState fluidState;
-                        fluidState.update(satW, pressW, pressNW, temperature);
-                        densityWBound = FluidSystem::phaseDensity(wPhaseIdx, temperature, pressW, fluidState);
-                        densityNWBound = FluidSystem::phaseDensity(nPhaseIdx, temperature, pressNW, fluidState);
-                        Scalar viscosityWBound = FluidSystem::phaseViscosity(wPhaseIdx, temperature, pressW, fluidState);
-                        Scalar viscosityNWBound = FluidSystem::phaseViscosity(nPhaseIdx, temperature, pressNW, fluidState);
-                        lambdaWBound = MaterialLaw::krw(this->problem().spatialParameters().materialLawParams(*eIt), satW) / viscosityWBound * densityWBound;
-                        lambdaNWBound = MaterialLaw::krn(this->problem().spatialParameters().materialLawParams(*eIt), satW) / viscosityNWBound * densityNWBound;
-                    }
-                    else
-                    {
-                        Scalar referencePressure =  this->problem().referencePressure(*eIt);
-                        FluidState fluidState;
-                        fluidState.update(satW, referencePressure, referencePressure, temperature);
-                        densityWBound = FluidSystem::phaseDensity(wPhaseIdx, temperature, referencePressure, fluidState);
-                        densityNWBound = FluidSystem::phaseDensity(nPhaseIdx, temperature, referencePressure, fluidState);
-                        Scalar viscosityWBound = FluidSystem::phaseViscosity(wPhaseIdx, temperature, referencePressure, fluidState);
-                        Scalar viscosityNWBound = FluidSystem::phaseViscosity(nPhaseIdx, temperature, referencePressure, fluidState);
-                        lambdaWBound = MaterialLaw::krw(this->problem().spatialParameters().materialLawParams(*eIt), satW) / viscosityWBound;
-                        lambdaNWBound = MaterialLaw::krn(this->problem().spatialParameters().materialLawParams(*eIt), satW) / viscosityNWBound;
-                    }
-
-                    Scalar potentialW = 0;
-                    Scalar potentialNW = 0;
-
-                    potentialW = this->problem().variables().potentialWetting(globalIdxI, isIndex);
-                    potentialNW = this->problem().variables().potentialNonwetting(globalIdxI, isIndex);
-
-                    Scalar densityW = (potentialW> 0.) ? densityWI : densityWBound;
-                    Scalar densityNW = (potentialNW> 0.) ? densityNWI : densityNWBound;
-
-                    densityW = (potentialW == 0.) ? 0.5 * (densityWI + densityWBound) : densityW;
-                    densityNW = (potentialNW == 0.) ? 0.5 * (densityNWI + densityNWBound) : densityNW;
-
-                    //calculate potential gradient
-                    switch (this->pressureType)
-                    {
-                    case pw:
-                    {
-                        potentialW = (pressI - pressBound);
-                        potentialNW = (pressI + pcI - pressBound - pcBound);
-                        break;
-                    }
-                    case pn:
-                    {
-                        potentialW = (pressI - pcI - pressBound + pcBound);
-                        potentialNW = (pressI - pressBound);
-                        break;
-                    }
-                    case pglobal:
-                    {
-                        potentialW = (pressI - pressBound - fractionalNWI * (pcI - pcBound));
-                        potentialNW = (pressI - pressBound + fractionalWI * (pcI - pcBound));
-                        break;
-                    }
-                    }
-
-                    potentialW += densityW * (distVec * this->gravity);
-                    potentialNW += densityNW * (distVec * this->gravity);
-
-                    //store potential gradients for further calculations
-                    this->problem().variables().potentialWetting(globalIdxI, isIndex) = potentialW;
-                    this->problem().variables().potentialNonwetting(globalIdxI, isIndex) = potentialNW;
-
-                    //do the upwinding of the mobility depending on the phase potentials
-                    Scalar lambdaW = (potentialW > 0.) ? lambdaWI : lambdaWBound;
-                    lambdaW = (potentialW == 0) ? 0.5 * (lambdaWI + lambdaWBound) : lambdaW;
-                    Scalar lambdaNW = (potentialNW > 0.) ? lambdaNWI : lambdaNWBound;
-                    lambdaNW = (potentialNW == 0) ? 0.5 * (lambdaNWI + lambdaNWBound) : lambdaNW;
-                    densityW = (potentialW> 0.) ? densityWI : densityWBound;
-                    densityW = (potentialW == 0.) ? 0.5 * (densityWI + densityWBound) : densityW;
-                    densityNW = (potentialNW> 0.) ? densityNWI : densityNWBound;
-                    densityNW = (potentialNW == 0.) ? 0.5 * (densityNWI + densityNWBound) : densityNW;
-
-                    //calculate the gravity term
-                    Dune::FieldVector<Scalar,dimWorld> velocityW(permeability);
-                    Dune::FieldVector<Scalar,dimWorld> velocityNW(permeability);
-                    Dune::FieldVector<Scalar,dimWorld> gravityTermW(unitOuterNormal);
-                    Dune::FieldVector<Scalar,dimWorld> gravityTermNW(unitOuterNormal);
-
-                    gravityTermW *= (this->gravity*permeability)*(lambdaW * densityW);
-                    gravityTermNW *= (this->gravity*permeability)*(lambdaNW * densityNW);
-
-                    //calculate velocity depending on the pressure used -> use pc = pn - pw
-                    switch (this->pressureType)
-                    {
-                    case pw:
-                    {
-                        velocityW *= lambdaW * (pressI - pressBound)/dist;
-                        velocityNW *= lambdaNW * (pressI - pressBound)/dist + 0.5 * (lambdaNWI + lambdaNWBound) * (pcI - pcBound) / dist;
-                        velocityW += gravityTermW;
-                        velocityNW += gravityTermNW;
-                        break;
-                    }
-                    case pn:
-                    {
-                        velocityW *= lambdaW * (pressI - pressBound)/dist - 0.5 * (lambdaWI + lambdaWBound) * (pcI - pcBound) / dist;
-                        velocityNW *= lambdaNW * (pressI - pressBound) / dist;
-                        velocityW += gravityTermW;
-                        velocityNW += gravityTermNW;
-                        break;
-                    }
-                    case pglobal:
-                    {
-                        this->problem().variables().velocity()[globalIdxI][isIndex] = permeability;
-                        this->problem().variables().velocity()[globalIdxI][isIndex] *= (lambdaW + lambdaNW)* (pressI - pressBound )/ dist;
-                        this->problem().variables().velocity()[globalIdxI][isIndex] += gravityTermW;
-                        this->problem().variables().velocity()[globalIdxI][isIndex] += gravityTermNW;
-                        break;
-                    }
-                    }
-
-                    //store velocities
-                    switch (velocityType_)
-                    {
-                    case vw:
-                    {
-                        this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW;
-                        this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityNW;
-                        break;
-                    }
-                    case vn:
-                    {
-                        this->problem().variables().velocity()[globalIdxI][isIndex] = velocityNW;
-                        this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityW;
-                        break;
-                    }
-                    case vt:
-                    {
-                        switch (this->pressureType)
-                        {
-                        case pw:
-                        {
-                            this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW + velocityNW;
-                            this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityNW;
-                            break;
-                        }
-                        case pn:
-                        {
-                            this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW + velocityNW;
-                            this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityW;
-                            break;
-                        }
-                        }
-                        break;
-                    }
-                    }
-                }//end dirichlet boundary
-
-                else if (bcType.isNeumann(eqIdxPress))
-                {
-                    this->problem().neumann(boundValues, *isIt);
-
-                    Dune::FieldVector<Scalar,dimWorld> velocityW(unitOuterNormal);
-                    Dune::FieldVector<Scalar,dimWorld> velocityNW(unitOuterNormal);
-
-                    velocityW *= boundValues[wPhaseIdx];
-                    velocityNW *= boundValues[nPhaseIdx];
-
-                    if (!this->compressibility)
-                    {
-                        velocityW /= densityWI;
-                        velocityNW /= densityNWI;
-                    }
-
-                    switch (velocityType_)
-                    {
-                    case vw:
-                    {
-                        this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW;
-                        this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityNW;
-                        break;
-                    }
-                    case vn:
-                    {
-                        this->problem().variables().velocity()[globalIdxI][isIndex] = velocityNW;
-                        this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityW;
-                        break;
-                    }
-                    case vt:
-                    {
-                        switch (this->pressureType)
-                        {
-                        case pw:
-                        {
-                            this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW + velocityNW;
-                            this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityNW;
-                            break;
-                        }
-                        case pn:
-                        {
-                            this->problem().variables().velocity()[globalIdxI][isIndex] = velocityW + velocityNW;
-                            this->problem().variables().velocitySecondPhase()[globalIdxI][isIndex] = velocityW;
-                            break;
-                        }
-                        }
-                        break;
-                    }
-                    }
-                }//end neumann boundary
-                else
-                {
-                    DUNE_THROW(Dune::NotImplemented, "No valid boundary condition type defined for pressure equation!");
-                }
-            }//end boundary
-        }// end all intersections
-    }// end grid traversal
-//                        printvector(std::cout, this->problem().variables().velocity(), "velocity", "row", 4, 1, 3);
+        velocityW *= 0.5;
+        velocityNW *= 0.5;
+        cellDataI.fluxData().setVelocity(wPhaseIdx, isIndexI, velocityW);
+        cellDataI.fluxData().setVelocity(nPhaseIdx, isIndexI, velocityNW);
+        cellDataI.fluxData().setVelocityMarker(isIndexI);
+    }
     return;
 }
 }