diff --git a/disc/groundwater/p1groundwater.hh b/disc/groundwater/p1groundwater.hh
index db738265f97328490bfb9213426136d98b3cdacf..6c214d8567afddab2b794ab04f8af5f179e561b2 100644
--- a/disc/groundwater/p1groundwater.hh
+++ b/disc/groundwater/p1groundwater.hh
@@ -296,30 +296,29 @@ namespace Dune
     }
 
 
-    /** \brief coefficents for evaluation of residual error estimator
+    /** \brief Evaluate element part of error estimator
 
        This functions is only implemented for P1 elements !
             This function assumes a conforming mesh !
 
         @param[in]  e    a codim 0 entity reference
+        @param[out]  elementpart    element part of error estimator
 
      */
-    void estimate (const Entity& e)
+    void estimate (const Entity& e, DT& elementpart)
     {
       // extract some important parameters
       Dune::GeometryType gt = e.geometry().type();
       const typename Dune::LagrangeShapeFunctionSetContainer<DT,RT,n>::value_type& sfs=Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1);
       DT Zero = 0;
       double refvolume = Dune::ReferenceElements<DT,n>::general(gt).volume();
-      vertices = sfs.size();
-      faces = Dune::ReferenceElements<DT,n>::general(gt).size(1);
       Dune::FieldVector<DT,n> center = e.geometry().global(Dune::ReferenceElements<DT,n>::general(gt).position(0,0));
 
       // integral over right hand side, div(K grad u_h) = 0 for P1 elements
       int p=3;
       DT volume = e.geometry().integrationElement(Dune::ReferenceElements<DT,n>::general(gt).position(0,0));
       DT h_K = pow(volume,1.0/((double)n));
-      integralq = 0;
+      DT integralq = 0;
       for (int g=0; g<Dune::QuadratureRules<DT,n>::rule(gt,p).size(); ++g)     // run through all quadrature points
       {
         const Dune::FieldVector<DT,n>& local = Dune::QuadratureRules<DT,n>::rule(gt,p)[g].position();           // pos of integration point
@@ -330,116 +329,117 @@ namespace Dune
         integralq += q*q*weight*refvolume*detjac;
       }
       integralq *= h_K*h_K;     // scaling by h_K^2
+      elementpart = integralq;
+    }
 
-      // the edge terms
-      IntersectionIterator endit = e.iend();
-      for (IntersectionIterator it = e.ibegin(); it!=endit; ++it)
+    /** \brief Evaluate face part of error estimator for a given face
+
+       This functions is only implemented for P1 elements !
+            This function assumes a conforming mesh !
+
+        @param[in]  e    a codim 0 entity reference
+        @param[in]  it    an intersection iterator started from e
+        @param[out]  facefluxK  the faceflux is evaluated as Sum facefluxK[i]*coeff[i] with coefficients of finite element function
+        @param[out]  facefluxN  same for neighbor of the given face
+            @param[out]  facefactor factor by which difference of fluxes has to be multiplied
+            @param[out]  facebctype if bctype is neumann then facefluxN[0] contains neumann value
+     */
+    void estimate (const Entity& e, const IntersectionIterator& it,
+                   RT facefluxK[], RT facefluxN[], DT& facefactor, typename GroundwaterEquationParameters<G,RT>::BC& facebctype)
+    {
+      // extract some important parameters
+      Dune::GeometryType gt = e.geometry().type();
+      const typename Dune::LagrangeShapeFunctionSetContainer<DT,RT,n>::value_type& sfs=Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1);
+      DT Zero = 0;
+      double refvolume = Dune::ReferenceElements<DT,n>::general(gt).volume();
+      Dune::FieldVector<DT,n> center = e.geometry().global(Dune::ReferenceElements<DT,n>::general(gt).position(0,0));
+
+      // the edge term
+      Dune::GeometryType gtface = it.intersectionSelfLocal().type();
+      double refvolumeface = Dune::ReferenceElements<DT,n-1>::general(gtface).volume();
+      int numberInSelf = it.numberInSelf();
+      const Dune::FieldVector<DT,n-1>& facelocal = Dune::ReferenceElements<DT,n-1>::general(gtface).position(0,0);
+      FieldVector<DT,n> local = it.intersectionSelfLocal().global(facelocal);
+      FieldVector<DT,n> global = it.intersectionGlobal().global(facelocal);
+
+      // compute face factor
+      DT detjacface = it.intersectionGlobal().integrationElement(facelocal);
+      DT h_e = pow(detjacface,1.0/((double)n-1));
+      facefactor = detjacface*h_e;
+
+      // handle interior edge
+      if (it.neighbor())
       {
-        // extract geometry of face
-        Dune::GeometryType gtface = it.intersectionSelfLocal().type();
-        double refvolumeface = Dune::ReferenceElements<DT,n-1>::general(gtface).volume();
-        int numberInSelf = it.numberInSelf();
-        const Dune::FieldVector<DT,n-1>& facelocal = Dune::ReferenceElements<DT,n-1>::general(gtface).position(0,0);
-        FieldVector<DT,n> local = it.intersectionSelfLocal().global(facelocal);
-        FieldVector<DT,n> global = it.intersectionGlobal().global(facelocal);
-
-        // compute face factor
-        DT detjacface = it.intersectionGlobal().integrationElement(facelocal);
-        DT h_e = pow(volume,1.0/((double)n-1));
-        facefactor[numberInSelf] = detjacface*h_e;
-
-        // handle interior edge
-        if (it.neighbor())
-        {
-          // compute coefficients of flux evaluation in self
-          const Dune::FieldMatrix<DT,n,n>& jac = e.geometry().jacobianInverse(local);                 // eval jacobian inverse at face center
-          const Dune::FieldMatrix<DT,n,n>& K = problem.K(center,e,local);                             // eval diffusion tensor at face center
-          for (int i=0; i<sfs.size(); i++)
-          {
-            Dune::FieldVector<DT,n> temp;
-            for (int l=0; l<n; l++)
-              temp[l] = sfs[i].evaluateDerivative(0,l,local);
-            Dune::FieldVector<DT,n> gradphi; gradphi=0;
-            jac.umv(temp,gradphi);                       // transform gradient to global ooordinates
-            Dune::FieldVector<DT,n> Kgradphi; Kgradphi=0;
-            K.umv(gradphi,Kgradphi);                       // multiply with diffusion tensor
-            facefluxK[numberInSelf][i] = -(Kgradphi*it.unitOuterNormal(facelocal));
-          }
+        // no neumann condition
+        facebctype = GroundwaterEquationParameters<G,RT>::process;
 
-          // compute coefficients of flux evaluation in neighbor
-          Dune::GeometryType nbgt = it.outside()->geometry().type();
-          Dune::FieldVector<DT,n> nbcenter = it.outside()->geometry().global(Dune::ReferenceElements<DT,n>::general(nbgt).position(0,0));
-          const typename Dune::LagrangeShapeFunctionSetContainer<DT,RT,n>::value_type& nbsfs=Dune::LagrangeShapeFunctions<DT,RT,n>::general(nbgt,1);
-          Dune::GeometryType nbgtface = it.intersectionNeighborLocal().type();
-          double nbrefvolumeface = Dune::ReferenceElements<DT,n-1>::general(nbgtface).volume();
-          int numberInNeighbor = it.numberInNeighbor();
-          const Dune::FieldVector<DT,n-1>& nbfacelocal = Dune::ReferenceElements<DT,n-1>::general(nbgtface).position(0,0);
-          FieldVector<DT,n> nblocal = it.intersectionNeighborLocal().global(nbfacelocal);
-          const Dune::FieldMatrix<DT,n,n>& nbjac = it.outside()->geometry().jacobianInverse(nblocal);
-          const Dune::FieldMatrix<DT,n,n>& nbK = problem.K(nbcenter,*(it.outside()),nblocal);
-          for (int i=0; i<nbsfs.size(); i++)
-          {
-            Dune::FieldVector<DT,n> temp;
-            for (int l=0; l<n; l++)
-              temp[l] = nbsfs[i].evaluateDerivative(0,l,nblocal);
-            Dune::FieldVector<DT,n> gradphi; gradphi=0;
-            nbjac.umv(temp,gradphi);                       // transform gradient to global ooordinates
-            Dune::FieldVector<DT,n> Kgradphi; Kgradphi=0;
-            nbK.umv(gradphi,Kgradphi);                       // multiply with diffusion tensor
-            facefluxN[numberInSelf][i] = -(Kgradphi*it.unitOuterNormal(facelocal));
-          }
+        // compute coefficients of flux evaluation in self
+        const Dune::FieldMatrix<DT,n,n>& jac = e.geometry().jacobianInverse(local);           // eval jacobian inverse at face center
+        const Dune::FieldMatrix<DT,n,n>& K = problem.K(center,e,local);                       // eval diffusion tensor at face center
+        for (int i=0; i<sfs.size(); i++)
+        {
+          Dune::FieldVector<DT,n> temp;
+          for (int l=0; l<n; l++)
+            temp[l] = sfs[i].evaluateDerivative(0,l,local);
+          Dune::FieldVector<DT,n> gradphi; gradphi=0;
+          jac.umv(temp,gradphi);                 // transform gradient to global ooordinates
+          Dune::FieldVector<DT,n> Kgradphi; Kgradphi=0;
+          K.umv(gradphi,Kgradphi);                 // multiply with diffusion tensor
+          facefluxK[i] = -(Kgradphi*it.unitOuterNormal(facelocal));
         }
 
-        // handle face on exterior boundary Neumann boundary
-        if (it.boundary())
+        // compute coefficients of flux evaluation in neighbor
+        Dune::GeometryType nbgt = it.outside()->geometry().type();
+        Dune::FieldVector<DT,n> nbcenter = it.outside()->geometry().global(Dune::ReferenceElements<DT,n>::general(nbgt).position(0,0));
+        const typename Dune::LagrangeShapeFunctionSetContainer<DT,RT,n>::value_type& nbsfs=Dune::LagrangeShapeFunctions<DT,RT,n>::general(nbgt,1);
+        Dune::GeometryType nbgtface = it.intersectionNeighborLocal().type();
+        double nbrefvolumeface = Dune::ReferenceElements<DT,n-1>::general(nbgtface).volume();
+        int numberInNeighbor = it.numberInNeighbor();
+        const Dune::FieldVector<DT,n-1>& nbfacelocal = Dune::ReferenceElements<DT,n-1>::general(nbgtface).position(0,0);
+        FieldVector<DT,n> nblocal = it.intersectionNeighborLocal().global(nbfacelocal);
+        const Dune::FieldMatrix<DT,n,n>& nbjac = it.outside()->geometry().jacobianInverse(nblocal);
+        const Dune::FieldMatrix<DT,n,n>& nbK = problem.K(nbcenter,*(it.outside()),nblocal);
+        for (int i=0; i<nbsfs.size(); i++)
         {
-          // evaluate boundary condition type
-          facebctype[numberInSelf] = problem.bctype(global,e,local);
-          if (facebctype[numberInSelf]!=GroundwaterEquationParameters<G,RT>::neumann)
-            continue;                     // only Neumann conditions require further work
-
-          // evaluate Neumann boundary
-          facefluxN[numberInSelf][0] = problem.J(global,e,local);
-
-          // compute coefficients of flux evaluation in self
-          const Dune::FieldMatrix<DT,n,n>& jac = e.geometry().jacobianInverse(local);                 // eval jacobian inverse at face center
-          const Dune::FieldMatrix<DT,n,n>& K = problem.K(center,e,local);                             // eval diffusion tensor at face center
-          for (int i=0; i<sfs.size(); i++)
-          {
-            Dune::FieldVector<DT,n> temp;
-            for (int l=0; l<n; l++)
-              temp[l] = sfs[i].evaluateDerivative(0,l,local);
-            Dune::FieldVector<DT,n> gradphi; gradphi=0;
-            jac.umv(temp,gradphi);                       // transform gradient to global ooordinates
-            Dune::FieldVector<DT,n> Kgradphi; Kgradphi=0;
-            K.umv(gradphi,Kgradphi);                       // multiply with diffusion tensor
-            facefluxK[numberInSelf][i] = -(Kgradphi*it.unitOuterNormal(facelocal));
-          }
+          Dune::FieldVector<DT,n> temp;
+          for (int l=0; l<n; l++)
+            temp[l] = nbsfs[i].evaluateDerivative(0,l,nblocal);
+          Dune::FieldVector<DT,n> gradphi; gradphi=0;
+          nbjac.umv(temp,gradphi);                 // transform gradient to global ooordinates
+          Dune::FieldVector<DT,n> Kgradphi; Kgradphi=0;
+          nbK.umv(gradphi,Kgradphi);                 // multiply with diffusion tensor
+          facefluxN[i] = -(Kgradphi*it.unitOuterNormal(facelocal));
         }
       }
-    }
-
-    RT faceFactor (int face) const
-    {
-      return facefactor[face];
-    }
 
-    RT faceFluxSelf (int face, int vertex) const
-    {
-      return facefluxK[face][vertex];
-    }
+      // handle face on exterior boundary Neumann boundary
+      if (it.boundary())
+      {
+        // evaluate boundary condition type
+        facebctype = problem.bctype(global,e,local);
+        if (facebctype!=GroundwaterEquationParameters<G,RT>::neumann)
+          return;               // only Neumann conditions require further work
 
-    RT faceFluxNeighbor (int face, int vertex) const
-    {
-      return facefluxN[face][vertex];
-    }
+        // evaluate Neumann boundary
+        facefluxN[0] = problem.J(global,e,local);
 
-    typename GroundwaterEquationParameters<G,RT>::BC facebc (int face) const
-    {
-      return facebctype[face];
+        // compute coefficients of flux evaluation in self
+        const Dune::FieldMatrix<DT,n,n>& jac = e.geometry().jacobianInverse(local);           // eval jacobian inverse at face center
+        const Dune::FieldMatrix<DT,n,n>& K = problem.K(center,e,local);                       // eval diffusion tensor at face center
+        for (int i=0; i<sfs.size(); i++)
+        {
+          Dune::FieldVector<DT,n> temp;
+          for (int l=0; l<n; l++)
+            temp[l] = sfs[i].evaluateDerivative(0,l,local);
+          Dune::FieldVector<DT,n> gradphi; gradphi=0;
+          jac.umv(temp,gradphi);                 // transform gradient to global ooordinates
+          Dune::FieldVector<DT,n> Kgradphi; Kgradphi=0;
+          K.umv(gradphi,Kgradphi);                 // multiply with diffusion tensor
+          facefluxK[i] = -(Kgradphi*it.unitOuterNormal(facelocal));
+        }
+      }
     }
 
-
   private:
     // local stiffness matrix
     int currentsize;
@@ -448,15 +448,6 @@ namespace Dune
     RT b[SIZE];
     typename GroundwaterEquationParameters<G,RT>::BC bctype[SIZE];
     bool procBoundaryAsDirichlet;
-
-    // error estimator
-    int faces;
-    int vertices;
-    RT facefactor[SIZEF];
-    RT facefluxK[SIZEF][SIZE];
-    RT facefluxN[SIZEF][SIZE];
-    typename GroundwaterEquationParameters<G,RT>::BC facebctype[SIZEF];
-    RT integralq;
   };
 
 
@@ -468,6 +459,7 @@ namespace Dune
     enum {n=G::dimension};
     typedef typename G::Traits::template Codim<0>::Entity Entity;
     typedef typename IS::template Codim<0>::template Partition<All_Partition>::Iterator Iterator;
+    typedef typename G::Traits::IntersectionIterator IntersectionIterator;
     typedef typename P1FEFunction<G,RT,IS>::RepresentationType VectorType;
     typedef typename AssembledP1FEOperator<G,RT,IS>::RepresentationType MatrixType;
     typedef typename MatrixType::RowIterator rowiterator;
@@ -556,7 +548,34 @@ namespace Dune
      */
     template<class P1FEFunc, class P0FEFunc>
     void estimate (const P1FEFunc& u, P0FEFunc& eta)
-    {}
+    {
+      // clear vector with elementwise error estimates
+      *eta = 0;
+
+      // run over all leaf elements
+      Iterator eendit = this->is.template end<0,All_Partition>();
+      for (Iterator it = this->is.template begin<0,All_Partition>(); it!=eendit; ++it)
+      {
+        // get access to shape functions for P1 elements
+        Dune::GeometryType gt = it->geometry().type();
+        const typename Dune::LagrangeShapeFunctionSetContainer<DT,RT,n>::value_type&
+        sfs=Dune::LagrangeShapeFunctions<DT,RT,n>::general(gt,1);
+
+        // evaluate element part of estimator
+        DT elementpart;
+        loc.estimate(*it,elementpart);
+
+        // loop over all neighbors
+        IntersectionIterator iendit = it->iend();
+        for (IntersectionIterator iit = it->ibegin(); iit!=iendit; ++iit)
+        {
+          // if we have a neighbor then we assume there is no boundary
+          // (it might still be an interior boundary ... )
+          if (it.neighbor()) continue;
+        }
+
+      }
+    }
 
   private:
     LagrangeFEMForGroundwaterEquation<G,RT> loc;