diff --git a/src/averageinterface.hh b/src/averageinterface.hh
new file mode 100644
index 0000000000000000000000000000000000000000..2e59640e5fc7c51537863100383f275aed51bff6
--- /dev/null
+++ b/src/averageinterface.hh
@@ -0,0 +1,156 @@
+#ifndef AVERAGE_INTERFACE_HH
+#define AVERAGE_INTERFACE_HH
+
+#include <dune/common/fmatrix.hh>
+#include "svd.hh"
+
+template <class GridType>
+void computeAverageInterface(const BoundaryPatch<GridType>& interface,
+                             const Dune::BlockVector<Dune::FieldVector<double,GridType::dimension> > deformation,
+                             Configuration& average)
+{
+    using namespace Dune;
+
+    typedef typename GridType::template Codim<0>::LevelIterator ElementIterator;
+    typedef typename GridType::template Codim<0>::Entity EntityType;
+    typedef typename EntityType::LevelIntersectionIterator NeighborIterator;
+
+    const GridType& grid = interface.getGrid();
+    const int level      = interface.level();
+    const typename GridType::Traits::LevelIndexSet& indexSet = grid.levelIndexSet(level);
+    const int dim        = GridType::dimension;
+
+    // ///////////////////////////////////////////
+    //   Initialize output configuration
+    // ///////////////////////////////////////////
+    average.r = 0;
+    
+    double interfaceArea = 0;
+    FieldMatrix<double,dim,dim> deformationGradient(0);
+
+    // ///////////////////////////////////////////
+    //   Loop and integrate over the interface
+    // ///////////////////////////////////////////
+    ElementIterator eIt    = grid.template lbegin<0>(level);
+    ElementIterator eEndIt = grid.template lend<0>(level);
+    for (; eIt!=eEndIt; ++eIt) {
+
+        NeighborIterator nIt    = eIt->ilevelbegin();
+        NeighborIterator nEndIt = eIt->ilevelend();
+
+        for (; nIt!=nEndIt; ++nIt) {
+
+            if (!interface.contains(*eIt, nIt))
+                continue;
+
+            const typename NeighborIterator::Geometry& segmentGeometry = nIt.intersectionGlobal();
+
+            const ReferenceElement<double,dim>& refElement = ReferenceElements<double, dim>::general(eIt->geometry().type());
+            int nDofs = refElement.size(nIt.numberInSelf(),1,dim);
+
+            // Get quadrature rule
+            const QuadratureRule<double, dim-1>& quad = QuadratureRules<double, dim-1>::rule(segmentGeometry.type(), dim-1);
+
+            // Get set of shape functions on this segment
+            const typename LagrangeShapeFunctionSetContainer<double,double,dim>::value_type& sfs
+                = LagrangeShapeFunctions<double,double,dim>::general(eIt->geometry().type(),1);
+
+            /* Loop over all integration points */
+            for (int ip=0; ip<quad.size(); ip++) {
+                
+                // Local position of the quadrature point
+                //const FieldVector<double,dim-1>& quadPos = quad[ip].position();
+                const FieldVector<double,dim> quadPos = nIt.intersectionSelfLocal().global(quad[ip].position());
+                
+                const double integrationElement = segmentGeometry.integrationElement(quad[ip].position());
+
+                // Evaluate base functions
+                FieldVector<double,dim> posAtQuadPoint(0);
+
+                for(int i=0; i<eIt->geometry().corners(); i++) {
+
+                    int idx = indexSet.template subIndex<dim>(*eIt, i);
+
+                    // Deformation at the quadrature point 
+                    posAtQuadPoint.axpy(sfs[i].evaluateFunction(0,quadPos), deformation[idx]);
+                }
+
+                const FieldMatrix<double,dim,dim>& inv = eIt->geometry().jacobianInverseTransposed(quadPos);
+                
+                /* Compute the weight of the current integration point */
+                double weight = quad[ip].weight() * integrationElement;
+                
+                /**********************************************/
+                /* compute gradients of the shape functions   */
+                /**********************************************/
+                Array<FieldVector<double, dim> > shapeGrads(eIt->geometry().corners());
+                
+                for (int dof=0; dof<eIt->geometry().corners(); dof++) {
+                    
+                    for (int i=0; i<dim; i++)
+                        shapeGrads[dof][i] = sfs[dof].evaluateDerivative(0, i, quadPos);
+                    
+                    // multiply with jacobian inverse 
+                    FieldVector<double,dim> tmp(0);
+                    inv.umv(shapeGrads[dof], tmp);
+                    shapeGrads[dof] = tmp;
+                    //std::cout << "Gradient " << dof << ": " << shape_grads[dof] << std::endl;
+                }
+
+                /****************************************************/
+                // The deformation gradient of the deformation
+                // in formulas: F(i,j) = $\partial \phi_i / \partial x_j$
+                // or F(i,j) = Id + $\partial u_i / \partial x_j$
+                /****************************************************/
+                FieldMatrix<double, dim, dim> F;
+                for (int i=0; i<dim; i++) {
+                    
+                    for (int j=0; j<dim; j++) {
+                        
+                        F[i][j] = (i==j) ? 1 : 0;
+                        
+                        for (int k=0; k<eIt->geometry().corners(); k++)
+                            F[i][j] += deformation[indexSet.template subIndex<dim>(*eIt, k)][i]*shapeGrads[k][j];
+                        
+                    }
+                    
+                }
+
+                interfaceArea += quad[ip].weight() * integrationElement;
+
+                average.r.axpy(quad[ip].weight() * integrationElement, posAtQuadPoint);
+
+                F *= quad[ip].weight();
+                deformationGradient += F;
+
+            }
+
+        }
+
+    }
+
+
+    // average deformation of the interface is the integral over its
+    // deformation divided by its area
+    average.r /= interfaceArea;
+
+    // average deformation is the integral over the deformation gradient
+    // divided by its area
+    deformationGradient /= interfaceArea;
+    std::cout << "deformationGradient: " << deformationGradient << std::endl;
+
+    // Get the rotational part of the deformation gradient by performing a 
+    // polar composition.
+    FieldVector<double,dim> W;
+    FieldMatrix<double,dim,dim> VT;
+    svdcmp<double,dim,dim>(deformationGradient, W, VT);
+
+    deformationGradient.rightmultiply(VT);
+    std::cout << "determinant: " << deformationGradient.determinant() << "  (should be 1)\n";
+    
+
+    // average orientation not implemented yet
+    average.q = Quaternion<double>::identity();
+}
+
+#endif