diff --git a/dune/gfe/henckyenergy.hh b/dune/gfe/henckyenergy.hh
new file mode 100644
index 0000000000000000000000000000000000000000..93f59aabd320d943b18b554596db44068a560923
--- /dev/null
+++ b/dune/gfe/henckyenergy.hh
@@ -0,0 +1,421 @@
+#ifndef DUNE_GFE_HENCKYENERGY_HH
+#define DUNE_GFE_HENCKYENERGY_HH
+
+#include <dune/common/fmatrix.hh>
+#include <dune/geometry/quadraturerules.hh>
+
+#include <dune/fufem/functions/virtualgridfunction.hh>
+#include <dune/fufem/boundarypatch.hh>
+
+#include <dune/gfe/localgeodesicfestiffness.hh>
+#include <dune/gfe/localfestiffness.hh>
+#include <dune/gfe/localgeodesicfefunction.hh>
+#include <dune/gfe/realtuple.hh>
+#include <dune/gfe/eigenvalues.hh>
+
+namespace Dune {
+
+  namespace Fufem {
+
+template<class GridView, class LocalFiniteElement, class field_type=double>
+class HenckyEnergy
+    : public LocalFEStiffness<GridView,LocalFiniteElement,std::vector<Dune::FieldVector<field_type,3> > >
+{
+    // grid types
+    typedef typename GridView::Grid::ctype DT;
+    typedef typename GridView::template Codim<0>::Entity Entity;
+
+    // some other sizes
+    enum {gridDim=GridView::dimension};
+    enum {dim=GridView::dimension};
+
+public:  // for testing
+
+    /** \brief Constructor with a set of material parameters
+     * \param parameters The material parameters
+     */
+    HenckyEnergy(const Dune::ParameterTree& parameters,
+                 const BoundaryPatch<GridView>* neumannBoundary,
+                 const Dune::VirtualFunction<Dune::FieldVector<double,gridDim>, Dune::FieldVector<double,3> >* neumannFunction)
+    : neumannBoundary_(neumannBoundary),
+      neumannFunction_(neumannFunction)
+    {
+      // Lame constants
+      mu_ = parameters.template get<double>("mu");
+      lambda_ = parameters.template get<double>("lambda");
+    }
+
+    /** \brief Assemble the energy for a single element */
+    field_type energy (const Entity& e,
+               const LocalFiniteElement& localFiniteElement,
+               const std::vector<Dune::FieldVector<field_type,gridDim> >& localConfiguration,
+               const std::vector<Dune::FieldVector<double,gridDim> >& localPointLoads) const;
+
+    /** \brief Lame constants */
+    double mu_, lambda_;
+
+    /** \brief The Neumann boundary */
+    const BoundaryPatch<GridView>* neumannBoundary_;
+
+    /** \brief The function implementing the Neumann data */
+    const Dune::VirtualFunction<Dune::FieldVector<double,gridDim>, Dune::FieldVector<double,3> >* neumannFunction_;
+};
+
+template <class GridView, class LocalFiniteElement, class field_type>
+field_type
+HenckyEnergy<GridView,LocalFiniteElement,field_type>::
+energy(const Entity& element,
+       const LocalFiniteElement& localFiniteElement,
+       const std::vector<Dune::FieldVector<field_type,gridDim> >& localConfiguration,
+       const std::vector<Dune::FieldVector<double,gridDim> >& localPointLoads) const
+{
+    assert(element.type() == localFiniteElement.type());
+    typedef typename GridView::template Codim<0>::Entity::Geometry Geometry;
+
+    field_type energy = 0;
+
+//     typedef LocalGeodesicFEFunction<gridDim, DT, LocalFiniteElement, TargetSpace> LocalGFEFunctionType;
+//     LocalGFEFunctionType localGeodesicFEFunction(localFiniteElement,localConfiguration);
+
+    // store gradients of shape functions and base functions
+    std::vector<Dune::FieldMatrix<DT,1,gridDim> > referenceGradients(localFiniteElement.localBasis().size());
+    std::vector<Dune::FieldVector<DT,gridDim> > gradients(localFiniteElement.localBasis().size());
+
+    int quadOrder = (element.type().isSimplex()) ? localFiniteElement.localBasis().order()
+                                                 : localFiniteElement.localBasis().order() * gridDim;
+
+    const Dune::QuadratureRule<DT, gridDim>& quad
+        = Dune::QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
+
+    for (size_t pt=0; pt<quad.size(); pt++) {
+
+        // Local position of the quadrature point
+        const Dune::FieldVector<DT,gridDim>& quadPos = quad[pt].position();
+
+        const DT integrationElement = element.geometry().integrationElement(quadPos);
+
+        const typename Geometry::JacobianInverseTransposed& jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(quadPos);
+
+        DT weight = quad[pt].weight() * integrationElement;
+
+#if 1
+        // get gradients of shape functions
+        localFiniteElement.localBasis().evaluateJacobian(quadPos, referenceGradients);
+
+        // compute gradients of base functions
+        for (size_t i=0; i<gradients.size(); ++i) {
+
+          // transform gradients
+          jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]);
+
+        }
+#endif
+#if 0
+        // The derivative of the local function defined on the reference element
+        typename LocalGFEFunctionType::DerivativeType referenceDerivative = localGeodesicFEFunction.evaluateDerivative(quadPos);
+
+        // The derivative of the function defined on the actual element
+        typename LocalGFEFunctionType::DerivativeType derivative(0);
+
+        for (size_t comp=0; comp<referenceDerivative.N(); comp++)
+            jacobianInverseTransposed.umv(referenceDerivative[comp], derivative[comp]);
+#endif
+        Dune::FieldMatrix<field_type,gridDim,gridDim> derivative(0);
+        for (size_t i=0; i<gradients.size(); i++)
+          for (int j=0; j<gridDim; j++)
+            derivative[j].axpy(localConfiguration[i][j], gradients[i]);
+
+        /////////////////////////////////////////////////////////
+        // compute F^T F
+        /////////////////////////////////////////////////////////
+
+        Dune::FieldMatrix<field_type,gridDim,gridDim> FTF(0);
+        for (int i=0; i<gridDim; i++)
+          for (int j=0; j<gridDim; j++)
+            for (int k=0; k<gridDim; k++)
+              FTF[i][j] += derivative[k][i] * derivative[k][j];
+
+        //////////////////////////////////////////////////////////
+        //  Eigenvalues of FTF
+        //////////////////////////////////////////////////////////
+#if 0   // hencky
+        std::array<field_type,dim> lambda = eigenValues(FTF);
+
+        //////////////////////////////////////////////////////////
+        //  Compute the derivative of the rotation
+        //  Note: we need it in matrix coordinates
+        //////////////////////////////////////////////////////////
+
+        // logarithms of the eigenvalues
+        std::array<field_type,dim> ln;
+        for (int i=0; i<dim; i++)
+          ln[i] = std::log(lambda[i]);
+
+        // Add the local energy density
+        for (int i=0; i<dim; i++)
+          energy += weight * mu_ * ln[i]*ln[i];
+
+        field_type trace = 0;
+        for (int i=0; i<dim; i++)
+          trace += ln[i];
+
+        energy += weight * 0.5 * lambda_ * trace * trace;
+#else   // St.Venant-Kirchhoff
+        Dune::FieldMatrix<field_type,dim,dim> E = FTF;
+        for (int i=0; i<dim; i++)
+          E[i][i] -= 1.0;
+        E *= 0.5;
+
+        field_type trE = E[0][0] + E[1][1] + E[2][2];
+
+        Dune::FieldMatrix<field_type,dim,dim> ESquared = E*E;
+
+        field_type trESquared = ESquared[0][0] + ESquared[1][1] + ESquared[2][2];
+
+        energy += weight * mu_ * trESquared + weight * 0.5 * lambda_ * trE * trE;
+#endif
+    }
+
+    //////////////////////////////////////////////////////////////////////////////
+    //   Assemble boundary contributions
+    //////////////////////////////////////////////////////////////////////////////
+
+    for (size_t i=0; i<localPointLoads.size(); i++)
+      for (size_t j=0; j<dim; j++)
+        energy -= localConfiguration[i][j] * localPointLoads[i][j];
+
+    if (not neumannFunction_)
+        return energy;
+
+    for (typename Entity::LeafIntersectionIterator it = element.ileafbegin(); it != element.ileafend(); ++it) {
+
+        if (not neumannBoundary_ or not neumannBoundary_->contains(*it))
+            continue;
+
+        const Dune::QuadratureRule<DT, gridDim-1>& quad
+            = Dune::QuadratureRules<DT, gridDim-1>::rule(it->type(), quadOrder);
+
+        for (size_t pt=0; pt<quad.size(); pt++) {
+
+            // Local position of the quadrature point
+            const Dune::FieldVector<DT,gridDim>& quadPos = it->geometryInInside().global(quad[pt].position());
+
+            const DT integrationElement = it->geometry().integrationElement(quad[pt].position());
+
+            // The value of the local function
+            //RealTuple<field_type,dim> value = localGeodesicFEFunction.evaluate(quadPos);
+            // get gradients of shape functions
+            std::vector<Dune::FieldVector<DT,1> > shapeFunctionValues;
+            localFiniteElement.localBasis().evaluateFunction(quadPos, shapeFunctionValues);
+            Dune::FieldVector<field_type,dim> value(0);
+            for (int i=0; i<localFiniteElement.size(); i++)
+              for (int j=0; j<dim; j++)
+                value[j] += shapeFunctionValues[i] * localConfiguration[i][j];
+
+            // Value of the Neumann data at the current position
+            Dune::FieldVector<double,3> neumannValue;
+
+            if (dynamic_cast<const VirtualGridViewFunction<GridView,Dune::FieldVector<double,3> >*>(neumannFunction_))
+                dynamic_cast<const VirtualGridViewFunction<GridView,Dune::FieldVector<double,3> >*>(neumannFunction_)->evaluateLocal(element, quadPos, neumannValue);
+            else
+                neumannFunction_->evaluate(it->geometry().global(quad[pt].position()), neumannValue);
+
+            // Only translational dofs are affected by the Neumann force
+            for (size_t i=0; i<neumannValue.size(); i++)
+                energy += (neumannValue[i] * value[i]) * quad[pt].weight() * integrationElement;
+
+        }
+
+    }
+
+    return energy;
+}
+
+  }  // namespace Fufem
+
+}  // namespace Dune
+
+template<class GridView, class LocalFiniteElement, int dim, class field_type=double>
+class HenckyEnergy
+    : public LocalGeodesicFEStiffness<GridView,LocalFiniteElement,RealTuple<field_type,dim> >
+{
+    // grid types
+    typedef typename GridView::Grid::ctype DT;
+    typedef RealTuple<field_type,dim> TargetSpace;
+    typedef typename TargetSpace::ctype RT;
+    typedef typename GridView::template Codim<0>::Entity Entity;
+
+    // some other sizes
+    enum {gridDim=GridView::dimension};
+
+
+public:  // for testing
+
+    /** \brief Constructor with a set of material parameters
+     * \param parameters The material parameters
+     */
+    HenckyEnergy(const Dune::ParameterTree& parameters,
+                 const BoundaryPatch<GridView>* neumannBoundary,
+                 const Dune::VirtualFunction<Dune::FieldVector<double,gridDim>, Dune::FieldVector<double,3> >* neumannFunction)
+    : neumannBoundary_(neumannBoundary),
+      neumannFunction_(neumannFunction)
+    {
+      // Lame constants
+      mu_ = parameters.template get<double>("mu");
+      lambda_ = parameters.template get<double>("lambda");
+    }
+
+    /** \brief Assemble the energy for a single element */
+    RT energy (const Entity& e,
+               const LocalFiniteElement& localFiniteElement,
+               const std::vector<TargetSpace>& localSolution) const;
+
+    /** \brief Lame constants */
+    double mu_, lambda_;
+
+    /** \brief The Neumann boundary */
+    const BoundaryPatch<GridView>* neumannBoundary_;
+
+    /** \brief The function implementing the Neumann data */
+    const Dune::VirtualFunction<Dune::FieldVector<double,gridDim>, Dune::FieldVector<double,3> >* neumannFunction_;
+};
+
+template <class GridView, class LocalFiniteElement, int dim, class field_type>
+typename HenckyEnergy<GridView,LocalFiniteElement,dim,field_type>::RT
+HenckyEnergy<GridView,LocalFiniteElement,dim,field_type>::
+energy(const Entity& element,
+       const LocalFiniteElement& localFiniteElement,
+       const std::vector<RealTuple<field_type,dim> >& localConfiguration) const
+{
+    assert(element.type() == localFiniteElement.type());
+    typedef typename GridView::template Codim<0>::Entity::Geometry Geometry;
+
+    RT energy = 0;
+
+    typedef LocalGeodesicFEFunction<gridDim, DT, LocalFiniteElement, TargetSpace> LocalGFEFunctionType;
+    LocalGFEFunctionType localGeodesicFEFunction(localFiniteElement,localConfiguration);
+
+    int quadOrder = (element.type().isSimplex()) ? localFiniteElement.localBasis().order()
+                                                 : localFiniteElement.localBasis().order() * gridDim;
+
+    const Dune::QuadratureRule<DT, gridDim>& quad
+        = Dune::QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
+
+    for (size_t pt=0; pt<quad.size(); pt++) {
+
+        // Local position of the quadrature point
+        const Dune::FieldVector<DT,gridDim>& quadPos = quad[pt].position();
+
+        const DT integrationElement = element.geometry().integrationElement(quadPos);
+
+        const typename Geometry::JacobianInverseTransposed& jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(quadPos);
+
+        DT weight = quad[pt].weight() * integrationElement;
+
+        // The derivative of the local function defined on the reference element
+        typename LocalGFEFunctionType::DerivativeType referenceDerivative = localGeodesicFEFunction.evaluateDerivative(quadPos);
+
+        // The derivative of the function defined on the actual element
+        typename LocalGFEFunctionType::DerivativeType derivative(0);
+
+        for (size_t comp=0; comp<referenceDerivative.N(); comp++)
+            jacobianInverseTransposed.umv(referenceDerivative[comp], derivative[comp]);
+
+        /////////////////////////////////////////////////////////
+        // compute F^T F
+        /////////////////////////////////////////////////////////
+
+        Dune::FieldMatrix<field_type,dim,dim> FTF(0);
+        for (int i=0; i<dim; i++)
+          for (int j=0; j<dim; j++)
+            for (int k=0; k<dim; k++)
+              FTF[i][j] += derivative[k][i] * derivative[k][j];
+
+        //////////////////////////////////////////////////////////
+        //  Eigenvalues of FTF
+        //////////////////////////////////////////////////////////
+#if 0   // hencky
+        std::array<field_type,dim> lambda = eigenValues(FTF);
+
+        //////////////////////////////////////////////////////////
+        //  Compute the derivative of the rotation
+        //  Note: we need it in matrix coordinates
+        //////////////////////////////////////////////////////////
+
+        // logarithms of the eigenvalues
+        std::array<field_type,dim> ln;
+        for (int i=0; i<dim; i++)
+          ln[i] = std::log(lambda[i]);
+
+        // Add the local energy density
+        for (int i=0; i<dim; i++)
+          energy += weight * mu_ * ln[i]*ln[i];
+
+        field_type trace = 0;
+        for (int i=0; i<dim; i++)
+          trace += ln[i];
+
+        energy += weight * 0.5 * lambda_ * trace * trace;
+#else   // St.Venant-Kirchhoff
+        Dune::FieldMatrix<field_type,dim,dim> E = FTF;
+        for (int i=0; i<dim; i++)
+          E[i][i] -= 1.0;
+        E *= 0.5;
+
+        field_type trE = E[0][0] + E[1][1] + E[2][2];
+
+        Dune::FieldMatrix<field_type,dim,dim> ESquared = E*E;
+
+        field_type trESquared = ESquared[0][0] + ESquared[1][1] + ESquared[2][2];
+
+        energy += weight * mu_ * trESquared + weight * 0.5 * lambda_ * trE * trE;
+#endif
+    }
+
+    //////////////////////////////////////////////////////////////////////////////
+    //   Assemble boundary contributions
+    //////////////////////////////////////////////////////////////////////////////
+
+    if (not neumannFunction_)
+        return energy;
+
+    for (typename Entity::LeafIntersectionIterator it = element.ileafbegin(); it != element.ileafend(); ++it) {
+
+        if (not neumannBoundary_ or not neumannBoundary_->contains(*it))
+            continue;
+
+        const Dune::QuadratureRule<DT, gridDim-1>& quad
+            = Dune::QuadratureRules<DT, gridDim-1>::rule(it->type(), quadOrder);
+
+        for (size_t pt=0; pt<quad.size(); pt++) {
+
+            // Local position of the quadrature point
+            const Dune::FieldVector<DT,gridDim>& quadPos = it->geometryInInside().global(quad[pt].position());
+
+            const DT integrationElement = it->geometry().integrationElement(quad[pt].position());
+
+            // The value of the local function
+            RealTuple<field_type,dim> value = localGeodesicFEFunction.evaluate(quadPos);
+
+            // Value of the Neumann data at the current position
+            Dune::FieldVector<double,3> neumannValue;
+
+            if (dynamic_cast<const VirtualGridViewFunction<GridView,Dune::FieldVector<double,3> >*>(neumannFunction_))
+                dynamic_cast<const VirtualGridViewFunction<GridView,Dune::FieldVector<double,3> >*>(neumannFunction_)->evaluateLocal(element, quadPos, neumannValue);
+            else
+                neumannFunction_->evaluate(it->geometry().global(quad[pt].position()), neumannValue);
+
+            // Only translational dofs are affected by the Neumann force
+            for (size_t i=0; i<neumannValue.size(); i++)
+                energy += (neumannValue[i] * value.globalCoordinates()[i]) * quad[pt].weight() * integrationElement;
+
+        }
+
+    }
+
+    return energy;
+}
+
+#endif   //#ifndef COSSERAT_ENERGY_LOCAL_STIFFNESS_HH
+
+