diff --git a/dumux/boxmodels/2p2c/2p2cmodel.hh b/dumux/boxmodels/2p2c/2p2cmodel.hh
index d8f0862cbd4aade516c50375d84df085f9ed785c..7c3dfca9d387de472ad8ad2da26b8eedf019f6ce 100644
--- a/dumux/boxmodels/2p2c/2p2cmodel.hh
+++ b/dumux/boxmodels/2p2c/2p2cmodel.hh
@@ -145,7 +145,10 @@ public:
     {
         ParentType::init(problem);
 
-        staticVertexDat_.resize(this->gridView_().size(dim));
+        unsigned numDofs = this->numDofs();
+        unsigned numVertices = this->problem_().gridView().size(dim);
+
+        staticVertexDat_.resize(numDofs);
 
         setSwitched_(false);
 
@@ -158,25 +161,46 @@ public:
             if(eIt->geometry().type().isCube() == false){
                 velocityOutput_ = false;
             }
+
+            if (numDofs != numVertices) // i.e. cell-centered discretization
+            {
+                velocityOutput_ = false;
+
+                int globalIdx = this->dofMapper().map(*eIt);
+                const GlobalPosition &globalPos = eIt->geometry().center();
+
+                // initialize phase presence
+                staticVertexDat_[globalIdx].phasePresence
+                    = this->problem_().initialPhasePresence(*(this->gridView_().template begin<dim>()),
+                                                            globalIdx, globalPos);
+                staticVertexDat_[globalIdx].wasSwitched = false;
+
+                staticVertexDat_[globalIdx].oldPhasePresence
+                    = staticVertexDat_[globalIdx].phasePresence;
+            }
         }
+
         if (velocityOutput_ != GET_PARAM_FROM_GROUP(TypeTag, bool, Vtk, AddVelocity))
             std::cout << "ATTENTION: Velocity output only works for cubes and is set to false for simplices\n";
 
-        VertexIterator vIt = this->gridView_().template begin<dim> ();
-        const VertexIterator &vEndIt = this->gridView_().template end<dim> ();
-        for (; vIt != vEndIt; ++vIt)
+        if (numDofs == numVertices) // i.e. vertex-centered discretization
         {
-            int globalIdx = this->dofMapper().map(*vIt);
-            const GlobalPosition &globalPos = vIt->geometry().corner(0);
+            VertexIterator vIt = this->gridView_().template begin<dim> ();
+            const VertexIterator &vEndIt = this->gridView_().template end<dim> ();
+            for (; vIt != vEndIt; ++vIt)
+            {
+                int globalIdx = this->dofMapper().map(*vIt);
+                const GlobalPosition &globalPos = vIt->geometry().corner(0);
 
-            // initialize phase presence
-            staticVertexDat_[globalIdx].phasePresence
-                = this->problem_().initialPhasePresence(*vIt, globalIdx,
+                // initialize phase presence
+                staticVertexDat_[globalIdx].phasePresence
+                    = this->problem_().initialPhasePresence(*vIt, globalIdx,
                                                         globalPos);
-            staticVertexDat_[globalIdx].wasSwitched = false;
+                staticVertexDat_[globalIdx].wasSwitched = false;
 
-            staticVertexDat_[globalIdx].oldPhasePresence
-                = staticVertexDat_[globalIdx].phasePresence;
+                staticVertexDat_[globalIdx].oldPhasePresence
+                    = staticVertexDat_[globalIdx].phasePresence;
+            }
         }
     }
 
@@ -196,7 +220,7 @@ public:
         for (; eIt != eEndIt; ++eIt) {
             this->localResidual().evalPhaseStorage(*eIt, phaseIdx);
 
-            for (int i = 0; i < eIt->template count<dim>(); ++i)
+            for (int i = 0; i < this->localResidual().storageTerm().size(); ++i)
                 storage += this->localResidual().storageTerm()[i];
         }
 
@@ -283,32 +307,37 @@ public:
         typedef Dune::BlockVector<Dune::FieldVector<double, dim> > VectorField;
 
         // create the required scalar fields
+        unsigned numDofs = this->numDofs();
         unsigned numVertices = this->problem_().gridView().size(dim);
 
-        ScalarField *sN    = writer.allocateManagedBuffer(numVertices);
-        ScalarField *sW    = writer.allocateManagedBuffer(numVertices);
-        ScalarField *pN    = writer.allocateManagedBuffer(numVertices);
-        ScalarField *pW    = writer.allocateManagedBuffer(numVertices);
-        ScalarField *pC    = writer.allocateManagedBuffer(numVertices);
-        ScalarField *rhoW  = writer.allocateManagedBuffer(numVertices);
-        ScalarField *rhoN  = writer.allocateManagedBuffer(numVertices);
-        ScalarField *mobW  = writer.allocateManagedBuffer(numVertices);
-        ScalarField *mobN = writer.allocateManagedBuffer(numVertices);
-        ScalarField *phasePresence = writer.allocateManagedBuffer(numVertices);
+        // velocity output currently only works for vertex data
+        if (numDofs != numVertices)
+          velocityOutput_ = false;
+
+        ScalarField *sN    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *sW    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pN    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pW    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pC    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *rhoW  = writer.allocateManagedBuffer(numDofs);
+        ScalarField *rhoN  = writer.allocateManagedBuffer(numDofs);
+        ScalarField *mobW  = writer.allocateManagedBuffer(numDofs);
+        ScalarField *mobN = writer.allocateManagedBuffer(numDofs);
+        ScalarField *phasePresence = writer.allocateManagedBuffer(numDofs);
         ScalarField *massFrac[numPhases][numComponents];
         for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
             for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                massFrac[phaseIdx][compIdx] = writer.allocateManagedBuffer(numVertices);
-        ScalarField *temperature = writer.allocateManagedBuffer(numVertices);
-        ScalarField *poro = writer.allocateManagedBuffer(numVertices);
-        ScalarField *cellNum =writer.allocateManagedBuffer (numVertices);
-        VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numVertices);
-        VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numVertices);
+                massFrac[phaseIdx][compIdx] = writer.allocateManagedBuffer(numDofs);
+        ScalarField *temperature = writer.allocateManagedBuffer(numDofs);
+        ScalarField *poro = writer.allocateManagedBuffer(numDofs);
+        ScalarField *cellNum =writer.allocateManagedBuffer (numDofs);
+        VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs);
+        VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs);
 
         if(velocityOutput_) // check if velocity output is demanded
         {
             // initialize velocity fields
-            for (unsigned int i = 0; i < numVertices; ++i)
+            for (unsigned int i = 0; i < numDofs; ++i)
             {
                 (*velocityN)[i] = Scalar(0);
                 (*velocityW)[i] = Scalar(0);
@@ -317,8 +346,7 @@ public:
         }
 
         unsigned numElements = this->gridView_().size(0);
-        ScalarField *rank =
-            writer.allocateManagedBuffer (numElements);
+        ScalarField *rank = writer.allocateManagedBuffer(numElements);
 
         FVElementGeometry fvGeometry;
         VolumeVariables volVars;
@@ -331,10 +359,14 @@ public:
             (*rank)[idx] = this->gridView_().comm().rank();
             fvGeometry.update(this->gridView_(), *eIt);
 
-            int numVerts = eIt->template count<dim> ();
-            for (int scvIdx = 0; scvIdx < numVerts; ++scvIdx)
+            for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx)
             {
-                int globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim);
+                int globalIdx;
+                if (numDofs == numElements) // element data
+                    globalIdx = idx;
+                else
+                    globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim);
+
                 volVars.update(sol[globalIdx],
                                this->problem_(),
                                *eIt,
@@ -356,8 +388,7 @@ public:
                         (*massFrac[phaseIdx][compIdx])[globalIdx]
                             = volVars.fluidState().massFraction(phaseIdx, compIdx);
 
-                        Valgrind::CheckDefined(
-                                               (*massFrac[phaseIdx][compIdx])[globalIdx][0]);
+                        Valgrind::CheckDefined((*massFrac[phaseIdx][compIdx])[globalIdx][0]);
                     }
                 (*poro)[globalIdx]  = volVars.porosity();
                 (*temperature)[globalIdx] = volVars.temperature();
@@ -403,14 +434,6 @@ public:
 
                     for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
                     {
-
-                        // data attached to upstream and the downstream vertices
-                        // of the current phase
-                        const VolumeVariables up =
-                            elemVolVars[fluxVars.upstreamIdx(phaseIdx)];
-                        const VolumeVariables dn =
-                            elemVolVars[fluxVars.downstreamIdx(phaseIdx)];
-
                         // local position of integration point
                         const Dune::FieldVector<Scalar, dim>& localPosIP = fvGeometry.subContVolFace[faceIdx].ipLocal;
 
@@ -453,7 +476,7 @@ public:
                 const Dune::FieldMatrix<CoordScalar, dim, dim> jacobianT2 = eIt->geometry().jacobianTransposed(localPos);
 
                 // transform vertex velocities from local to global coordinates
-                for (int scvIdx = 0; scvIdx < numVerts; ++scvIdx)
+                for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx)
                 {
                     int globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim);
                     // calculate the subcontrolvolume velocity by the Piola transformation
@@ -469,45 +492,73 @@ public:
                     // add up the nonwetting phase subcontrolvolume velocities for each vertex
                     (*velocityN)[globalIdx] += scvVelocity;
                 }
-            }
-        }
+            } // velocity output
+        } // loop over elements
+
         if(velocityOutput_)
         {
             // divide the vertex velocities by the number of adjacent scvs i.e. cells
-            for(unsigned int globalIdx = 0; globalIdx<numVertices; ++globalIdx){
+            for(unsigned int globalIdx = 0; globalIdx < numDofs; ++globalIdx){
                 (*velocityW)[globalIdx] /= (*cellNum)[globalIdx];
                 (*velocityN)[globalIdx] /= (*cellNum)[globalIdx];
             }
         }
 
-
-        writer.attachVertexData(*sN,     "Sn");
-        writer.attachVertexData(*sW,     "Sw");
-        writer.attachVertexData(*pN,     "pN");
-        writer.attachVertexData(*pW,     "pW");
-        writer.attachVertexData(*pC,     "pC");
-        writer.attachVertexData(*rhoW,   "rhoW");
-        writer.attachVertexData(*rhoN,   "rhoN");
-        writer.attachVertexData(*mobW,   "mobW");
-        writer.attachVertexData(*mobN,   "mobN");
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        if (numDofs == numElements) // element data
         {
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            writer.attachCellData(*sN,     "Sn");
+            writer.attachCellData(*sW,     "Sw");
+            writer.attachCellData(*pN,     "pN");
+            writer.attachCellData(*pW,     "pW");
+            writer.attachCellData(*pC,     "pC");
+            writer.attachCellData(*rhoW,   "rhoW");
+            writer.attachCellData(*rhoN,   "rhoN");
+            writer.attachCellData(*mobW,   "mobW");
+            writer.attachCellData(*mobN,   "mobN");
+            for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
             {
-                std::ostringstream oss;
-                oss << "X_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx);
-                writer.attachVertexData(*massFrac[phaseIdx][compIdx], oss.str());
+                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                {
+                    std::ostringstream oss;
+                    oss << "X_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx);
+                    writer.attachCellData(*massFrac[phaseIdx][compIdx], oss.str());
+                }
             }
+            writer.attachCellData(*poro, "porosity");
+            writer.attachCellData(*temperature,    "temperature");
+            writer.attachCellData(*phasePresence,  "phase presence");
         }
-        writer.attachVertexData(*poro, "porosity");
-        writer.attachVertexData(*temperature,    "temperature");
-        writer.attachVertexData(*phasePresence,  "phase presence");
-
-        if(velocityOutput_) // check if velocity output is demanded
+        else
         {
-            writer.attachVertexData(*velocityW,  "velocityW", dim);
-            writer.attachVertexData(*velocityN,  "velocityN", dim);
+            writer.attachVertexData(*sN,     "Sn");
+            writer.attachVertexData(*sW,     "Sw");
+            writer.attachVertexData(*pN,     "pN");
+            writer.attachVertexData(*pW,     "pW");
+            writer.attachVertexData(*pC,     "pC");
+            writer.attachVertexData(*rhoW,   "rhoW");
+            writer.attachVertexData(*rhoN,   "rhoN");
+            writer.attachVertexData(*mobW,   "mobW");
+            writer.attachVertexData(*mobN,   "mobN");
+            for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            {
+                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                {
+                    std::ostringstream oss;
+                    oss << "X_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx);
+                    writer.attachVertexData(*massFrac[phaseIdx][compIdx], oss.str());
+                }
+            }
+            writer.attachVertexData(*poro, "porosity");
+            writer.attachVertexData(*temperature,    "temperature");
+            writer.attachVertexData(*phasePresence,  "phase presence");
+
+            if(velocityOutput_) // check if velocity output is demanded
+            {
+                writer.attachVertexData(*velocityW,  "velocityW", dim);
+                writer.attachVertexData(*velocityN,  "velocityN", dim);
+            }
         }
+
         writer.attachCellData(*rank, "process rank");
     }
 
@@ -515,37 +566,38 @@ public:
      * \brief Write the current solution to a restart file.
      *
      * \param outStream The output stream of one vertex for the restart file
-     * \param vertex The vertex
+     * \param entity The entity, either a vertex or an element
      */
-    void serializeEntity(std::ostream &outStream, const Vertex &vertex)
+    template<class Entity>
+    void serializeEntity(std::ostream &outStream, const Entity &entity)
     {
         // write primary variables
-        ParentType::serializeEntity(outStream, vertex);
+        ParentType::serializeEntity(outStream, entity);
 
-        int globalIdx = this->dofMapper().map(vertex);
+        int globalIdx = this->dofMapper().map(entity);
         if (!outStream.good())
-            DUNE_THROW(Dune::IOError, "Could not serialize vertex " << globalIdx);
+            DUNE_THROW(Dune::IOError, "Could not serialize entity " << globalIdx);
 
         outStream << staticVertexDat_[globalIdx].phasePresence << " ";
     }
 
     /*!
-     * \brief Reads the current solution for a vertex from a restart
-     *        file.
+     * \brief Reads the current solution from a restart file.
      *
      * \param inStream The input stream of one vertex from the restart file
-     * \param vertex The vertex
+     * \param entity The entity, either a vertex or an element
      */
-    void deserializeEntity(std::istream &inStream, const Vertex &vertex)
+    template<class Entity>
+    void deserializeEntity(std::istream &inStream, const Entity &entity)
     {
         // read primary variables
-        ParentType::deserializeEntity(inStream, vertex);
+        ParentType::deserializeEntity(inStream, entity);
 
         // read phase presence
-        int globalIdx = this->dofMapper().map(vertex);
+        int globalIdx = this->dofMapper().map(entity);
         if (!inStream.good())
             DUNE_THROW(Dune::IOError,
-                       "Could not deserialize vertex " << globalIdx);
+                       "Could not deserialize entity " << globalIdx);
 
         inStream >> staticVertexDat_[globalIdx].phasePresence;
         staticVertexDat_[globalIdx].oldPhasePresence
@@ -567,6 +619,9 @@ public:
         for (unsigned i = 0; i < staticVertexDat_.size(); ++i)
             staticVertexDat_[i].visited = false;
 
+        unsigned numDofs = this->numDofs();
+        unsigned numVertices = this->problem_().gridView().size(dim);
+
         FVElementGeometry fvGeometry;
         static VolumeVariables volVars;
         ElementIterator eIt = this->gridView_().template begin<0> ();
@@ -576,7 +631,12 @@ public:
             fvGeometry.update(this->gridView_(), *eIt);
             for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx)
             {
-                int globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim);
+                int globalIdx;
+
+                if (numDofs != numVertices)
+                    globalIdx = this->elementMapper().map(*eIt);
+                else
+                    globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim);
 
                 if (staticVertexDat_[globalIdx].visited)
                     continue;
@@ -630,8 +690,7 @@ protected:
      */
     void resetPhasePresence_()
     {
-        int numVertices = this->gridView_().size(dim);
-        for (int idx = 0; idx < numVertices; ++idx)
+        for (int idx = 0; idx < staticVertexDat_.size(); ++idx)
         {
             staticVertexDat_[idx].phasePresence
                 = staticVertexDat_[idx].oldPhasePresence;
@@ -644,8 +703,7 @@ protected:
      */
     void updateOldPhasePresence_()
     {
-        int numVertices = this->gridView_().size(dim);
-        for (int idx = 0; idx < numVertices; ++idx)
+        for (int idx = 0; idx < staticVertexDat_.size(); ++idx)
         {
             staticVertexDat_[idx].oldPhasePresence
                 = staticVertexDat_[idx].phasePresence;
diff --git a/dumux/boxmodels/2p2c/2p2cvolumevariables.hh b/dumux/boxmodels/2p2c/2p2cvolumevariables.hh
index 522b1f794fbce5840f4a36b9b0ec385fff0d1f69..4756a2572ed77c5bb8800b5f03326b4f9df7200e 100644
--- a/dumux/boxmodels/2p2c/2p2cvolumevariables.hh
+++ b/dumux/boxmodels/2p2c/2p2cvolumevariables.hh
@@ -182,8 +182,16 @@ public:
                                                 fvGeometry, scvIdx);
         fluidState.setTemperature(t);
 
-        int globalVertIdx = problem.model().dofMapper().map(element, scvIdx, dim);
-        int phasePresence = problem.model().phasePresence(globalVertIdx, isOldSol);
+        unsigned numDofs = problem.model().numDofs();
+        unsigned numVertices = problem.gridView().size(dim);
+
+        int globalIdx;
+        if (numDofs != numVertices) // element data
+            globalIdx = problem.model().dofMapper().map(element);
+        else
+            globalIdx = problem.model().dofMapper().map(element, scvIdx, dim);
+
+        int phasePresence = problem.model().phasePresence(globalIdx, isOldSol);
 
         /////////////
         // set the saturations