diff --git a/dune/gfe/assemblers/CMakeLists.txt b/dune/gfe/assemblers/CMakeLists.txt
index 2a6d415715361df50741cecb6e5a2df1fd250545..cdfd6ade5b61b5d9181f8c0bc9de747b8fed0dcf 100644
--- a/dune/gfe/assemblers/CMakeLists.txt
+++ b/dune/gfe/assemblers/CMakeLists.txt
@@ -5,7 +5,6 @@ install(FILES
         cosseratrodenergy.hh
         geodesicfeassembler.hh
         geodesicfeassemblerwrapper.hh
-        harmonicenergy.hh
         l2distancesquaredenergy.hh
         localenergy.hh
         localfirstordermodel.hh
diff --git a/dune/gfe/assemblers/harmonicenergy.hh b/dune/gfe/assemblers/harmonicenergy.hh
deleted file mode 100644
index 90c47a93ca7627f286ace775b9639bae253ef40e..0000000000000000000000000000000000000000
--- a/dune/gfe/assemblers/harmonicenergy.hh
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef DUNE_GFE_HARMONICENERGY_HH
-#define DUNE_GFE_HARMONICENERGY_HH
-
-#include <dune/common/fmatrix.hh>
-#include <dune/common/fvector.hh>
-#include <dune/geometry/quadraturerules.hh>
-
-#include <dune/gfe/assemblers/localenergy.hh>
-#include <dune/gfe/densities/harmonicdensity.hh>
-
-template<class Basis, class LocalInterpolationRule, class TargetSpace>
-class HarmonicEnergy
-  : public Dune::GFE::LocalEnergy<Basis,TargetSpace>
-{
-  // grid types
-  typedef typename Basis::GridView GridView;
-  typedef typename GridView::ctype DT;
-  typedef typename TargetSpace::ctype RT;
-
-  // some other sizes
-  constexpr static int gridDim = GridView::dimension;
-
-public:
-
-  /** \brief Assemble the energy for a single element */
-  RT energy (const typename Basis::LocalView& localView,
-             const std::vector<TargetSpace>& localSolution) const override;
-
-  virtual RT energy (const typename Basis::LocalView& localView,
-                     const typename Dune::GFE::Impl::LocalEnergyTypes<TargetSpace>::CompositeCoefficients& coefficients) const override
-  {
-    DUNE_THROW(Dune::NotImplemented, "!");
-  }
-
-};
-
-template <class Basis, class LocalInterpolationRule, class TargetSpace>
-typename HarmonicEnergy<Basis, LocalInterpolationRule, TargetSpace>::RT
-HarmonicEnergy<Basis, LocalInterpolationRule, TargetSpace>::
-energy(const typename Basis::LocalView& localView,
-       const std::vector<TargetSpace>& localSolution) const
-{
-  Dune::GFE::HarmonicDensity<Dune::FieldVector<DT,gridDim>,TargetSpace> density;
-
-  RT energy = 0;
-
-  const auto& localFiniteElement = localView.tree().finiteElement();
-  LocalInterpolationRule localInterpolationRule(localFiniteElement,localSolution);
-
-  int quadOrder = (localFiniteElement.type().isSimplex()) ? (localFiniteElement.localBasis().order()-1) * 2
-                                                 : (localFiniteElement.localBasis().order() * gridDim - 1) * 2;
-
-  const auto element = localView.element();
-
-  const auto& quad = Dune::QuadratureRules<double, gridDim>::rule(localFiniteElement.type(), quadOrder);
-
-  for (size_t pt=0; pt<quad.size(); pt++) {
-
-    // Local position of the quadrature point
-    const Dune::FieldVector<double,gridDim>& quadPos = quad[pt].position();
-
-    const auto integrationElement = element.geometry().integrationElement(quadPos);
-
-    const auto jacobianInverse = element.geometry().jacobianInverse(quadPos);
-
-    auto weight = quad[pt].weight() * integrationElement;
-
-    // The derivative of the local function defined on the reference element
-
-    // Function value at the point where we are evaluating the derivative
-    // (not needed by the energy, but needed to compute the derivative)
-    TargetSpace q = localInterpolationRule.evaluate(quadPos);
-
-    // Compute the derivative
-    auto referenceDerivative = localInterpolationRule.evaluateDerivative(quadPos, q);
-    auto derivative = referenceDerivative * jacobianInverse;
-
-    energy += weight * density(quadPos,q,derivative);
-  }
-
-  return energy;
-}
-
-#endif
diff --git a/dune/gfe/assemblers/localintegralenergy.hh b/dune/gfe/assemblers/localintegralenergy.hh
index b1bee967ac5ccf0256b835a2d03d26526d52bb0a..4317850f67f38eaf5282af2e3bec7ab010a7b9ca 100644
--- a/dune/gfe/assemblers/localintegralenergy.hh
+++ b/dune/gfe/assemblers/localintegralenergy.hh
@@ -51,86 +51,125 @@ namespace Dune::GFE {
 
     /** \brief Assemble the energy for a single element */
     RT energy(const typename Basis::LocalView& localView,
-              const std::vector<TargetSpace>& localSolutions) const
+              const std::vector<TargetSpace>& localConfiguration) const
     {
-      DUNE_THROW(NotImplemented, "!");
+      RT energy = 0;
+
+      if constexpr (not Impl::LocalEnergyTypes<TargetSpace>::isProductManifold)
+      {
+        const auto& localFiniteElement = localView.tree().finiteElement();
+        LocalInterpolationRule localInterpolationRule(localFiniteElement,localConfiguration);
+
+        int quadOrder = (localFiniteElement.type().isSimplex())
+           ? (localFiniteElement.localBasis().order()-1) * 2
+           : (localFiniteElement.localBasis().order() * gridDim - 1) * 2;
+
+        const auto element = localView.element();
+
+        const auto& quad = QuadratureRules<double, gridDim>::rule(localFiniteElement.type(), quadOrder);
+
+        for (auto&& qp : quad)
+        {
+          // Local position of the quadrature point
+          const auto& quadPos = qp.position();
+
+          const auto integrationElement = element.geometry().integrationElement(quadPos);
+
+          const auto jacobianInverse = element.geometry().jacobianInverse(quadPos);
+
+          // Function value at the quadrature point
+          TargetSpace q = localInterpolationRule.evaluate(quadPos);
+
+          // The derivative of the finite element function at the quadrature point
+          auto referenceDerivative = localInterpolationRule.evaluateDerivative(quadPos, q);
+          auto derivative = referenceDerivative * jacobianInverse;
+
+          energy += qp.weight() * integrationElement * (*localDensityGFE_)(quadPos,q,derivative);
+        }
+      }
+
+      return energy;
     }
 
     RT energy (const typename Basis::LocalView& localView,
                const typename Impl::LocalEnergyTypes<TargetSpace>::CompositeCoefficients& coefficients) const override
     {
-      // TODO: Cosserat materials are hard-wired here for historical reasons.
-      static_assert(TargetSpace::size() == 2, "LocalGeodesicIntegralEnergy needs two TargetSpaces!");
-      using TargetSpaceDeformation = typename std::tuple_element<0, TargetSpace>::type;
-      using TargetSpaceRotation = typename std::tuple_element<1, TargetSpace>::type;
+      RT energy = 0;
 
-      const auto& element = localView.element();
+      if constexpr (Impl::LocalEnergyTypes<TargetSpace>::isProductManifold)
+      {
+        // TODO: Cosserat materials are hard-wired here for historical reasons.
+        static_assert(TargetSpace::size() == 2, "LocalGeodesicIntegralEnergy needs two TargetSpaces!");
+        using TargetSpaceDeformation = typename std::tuple_element<0, TargetSpace>::type;
+        using TargetSpaceRotation = typename std::tuple_element<1, TargetSpace>::type;
 
-      using namespace Indices;
-      const std::vector<TargetSpaceDeformation>& localDeformationConfiguration = coefficients[_0];
-      const std::vector<TargetSpaceRotation>& localOrientationConfiguration = coefficients[_1];
+        const auto& element = localView.element();
 
-      // composite Basis: grab the finite element of the first child
-      const auto& deformationLocalFiniteElement = localView.tree().child(_0,0).finiteElement();
-      const auto& orientationLocalFiniteElement = localView.tree().child(_1,0).finiteElement();
+        using namespace Indices;
+        const std::vector<TargetSpaceDeformation>& localDeformationConfiguration = coefficients[_0];
+        const std::vector<TargetSpaceRotation>& localOrientationConfiguration = coefficients[_1];
 
-      using LocalDeformationGFEFunctionType = typename std::tuple_element<0, LocalInterpolationRule>::type;
-      using LocalOrientationGFEFunctionType = typename std::tuple_element<1, LocalInterpolationRule>::type;
+        // composite Basis: grab the finite element of the first child
+        const auto& deformationLocalFiniteElement = localView.tree().child(_0,0).finiteElement();
+        const auto& orientationLocalFiniteElement = localView.tree().child(_1,0).finiteElement();
 
-      LocalDeformationGFEFunctionType localDeformationGFEFunction(deformationLocalFiniteElement,localDeformationConfiguration);
-      LocalOrientationGFEFunctionType localOrientationGFEFunction(orientationLocalFiniteElement,localOrientationConfiguration);
+        using LocalDeformationGFEFunctionType = typename std::tuple_element<0, LocalInterpolationRule>::type;
+        using LocalOrientationGFEFunctionType = typename std::tuple_element<1, LocalInterpolationRule>::type;
 
-      RT energy = 0;
+        LocalDeformationGFEFunctionType localDeformationGFEFunction(deformationLocalFiniteElement,localDeformationConfiguration);
+        LocalOrientationGFEFunctionType localOrientationGFEFunction(orientationLocalFiniteElement,localOrientationConfiguration);
 
-      int quadOrder = (element.type().isSimplex()) ? deformationLocalFiniteElement.localBasis().order()
+
+        int quadOrder = (element.type().isSimplex()) ? deformationLocalFiniteElement.localBasis().order()
                                                  : deformationLocalFiniteElement.localBasis().order() * gridDim;
 
-      const auto& quad = QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
+        const auto& quad = QuadratureRules<DT, gridDim>::rule(element.type(), quadOrder);
 
-      for (size_t pt=0; pt<quad.size(); pt++)
-      {
-        // Local position of the quadrature point
-        const FieldVector<DT,gridDim>& quadPos = quad[pt].position();
+        for (size_t pt=0; pt<quad.size(); pt++)
+        {
+          // Local position of the quadrature point
+          const FieldVector<DT,gridDim>& quadPos = quad[pt].position();
 
-        auto x = element.geometry().global(quadPos);
+          auto x = element.geometry().global(quadPos);
 
-        const DT integrationElement = element.geometry().integrationElement(quadPos);
+          const DT integrationElement = element.geometry().integrationElement(quadPos);
 
-        const auto jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(quadPos);
+          const auto jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(quadPos);
 
-        DT weightWithintegrationElement = quad[pt].weight() * integrationElement;
+          DT weightWithintegrationElement = quad[pt].weight() * integrationElement;
 
-        // The value of the local deformation
-        RealTuple<RT,gridDim> deformationValue = localDeformationGFEFunction.evaluate(quadPos);
+          // The value of the local deformation
+          RealTuple<RT,gridDim> deformationValue = localDeformationGFEFunction.evaluate(quadPos);
 
-        // The derivative of the deformation defined on the reference element
-        typename LocalDeformationGFEFunctionType::DerivativeType deformationReferenceDerivative = localDeformationGFEFunction.evaluateDerivative(quadPos,deformationValue);
+          // The derivative of the deformation defined on the reference element
+          typename LocalDeformationGFEFunctionType::DerivativeType deformationReferenceDerivative = localDeformationGFEFunction.evaluateDerivative(quadPos,deformationValue);
 
-        // The derivative of the deformation defined on the actual element
-        typename LocalDeformationGFEFunctionType::DerivativeType deformationDerivative;
-        for (size_t comp=0; comp<deformationReferenceDerivative.N(); comp++)
-          jacobianInverseTransposed.mv(deformationReferenceDerivative[comp], deformationDerivative[comp]);
+          // The derivative of the deformation defined on the actual element
+          typename LocalDeformationGFEFunctionType::DerivativeType deformationDerivative;
+          for (size_t comp=0; comp<deformationReferenceDerivative.N(); comp++)
+            jacobianInverseTransposed.mv(deformationReferenceDerivative[comp], deformationDerivative[comp]);
 
-        // Integrate the energy density
-        if (localDensityElasticity_)
-          energy += weightWithintegrationElement * (*localDensityElasticity_)(x, deformationDerivative);
-        else if (localDensityGFE_) {
-          // The value of the local rotation
-          Rotation<RT,gridDim>  orientationValue = localOrientationGFEFunction.evaluate(quadPos);
+          // Integrate the energy density
+          if (localDensityElasticity_)
+            energy += weightWithintegrationElement * (*localDensityElasticity_)(x, deformationDerivative);
+          else if (localDensityGFE_) {
+            // The value of the local rotation
+            Rotation<RT,gridDim>  orientationValue = localOrientationGFEFunction.evaluate(quadPos);
 
-          // The derivative of the rotation defined on the reference element
-          typename LocalOrientationGFEFunctionType::DerivativeType orientationReferenceDerivative = localOrientationGFEFunction.evaluateDerivative(quadPos,orientationValue);
+            // The derivative of the rotation defined on the reference element
+            typename LocalOrientationGFEFunctionType::DerivativeType orientationReferenceDerivative = localOrientationGFEFunction.evaluateDerivative(quadPos,orientationValue);
 
-          // The derivative of the rotation defined on the actual element
-          typename LocalOrientationGFEFunctionType::DerivativeType orientationDerivative;
-          for (size_t comp=0; comp<orientationReferenceDerivative.N(); comp++)
-            jacobianInverseTransposed.mv(orientationReferenceDerivative[comp], orientationDerivative[comp]);
+            // The derivative of the rotation defined on the actual element
+            typename LocalOrientationGFEFunctionType::DerivativeType orientationDerivative;
+            for (size_t comp=0; comp<orientationReferenceDerivative.N(); comp++)
+              jacobianInverseTransposed.mv(orientationReferenceDerivative[comp], orientationDerivative[comp]);
 
-          energy += weightWithintegrationElement * (*localDensityGFE_)(x,
-                                                                       deformationValue,
-                                                                       deformationDerivative,
-                                                                       orientationValue,
-                                                                       orientationDerivative);
+            energy += weightWithintegrationElement * (*localDensityGFE_)(x,
+                                                                         deformationValue,
+                                                                         deformationDerivative,
+                                                                         orientationValue,
+                                                                         orientationDerivative);
+          }
         }
       }
 
diff --git a/src/gradient-flow.cc b/src/gradient-flow.cc
index 005bfed4a8a2246e8ac54f018a2d57a2df3d2828..c55aed10ff833454277f082a93aa3d27f7a417f3 100644
--- a/src/gradient-flow.cc
+++ b/src/gradient-flow.cc
@@ -39,9 +39,10 @@
 #include <dune/gfe/riemanniantrsolver.hh>
 #include <dune/gfe/globalgfefunction.hh>
 #include <dune/gfe/embeddedglobalgfefunction.hh>
-#include <dune/gfe/assemblers/harmonicenergy.hh>
+#include <dune/gfe/assemblers/localintegralenergy.hh>
 #include <dune/gfe/assemblers/l2distancesquaredenergy.hh>
 #include <dune/gfe/assemblers/weightedsumenergy.hh>
+#include <dune/gfe/densities/harmonicdensity.hh>
 #include <dune/gfe/spaces/unitvector.hh>
 
 // grid dimension
@@ -208,7 +209,9 @@ int main (int argc, char *argv[]) try
 
   std::vector<std::shared_ptr<GFE::LocalEnergy<FEBasis,ATargetSpace> > > addends(2);
   using GeodesicInterpolationRule  = LocalGeodesicFEFunction<dim, double, FEBasis::LocalView::Tree::FiniteElement, ATargetSpace>;
-  addends[0] = std::make_shared<HarmonicEnergy<FEBasis, GeodesicInterpolationRule, ATargetSpace> >();
+
+  auto harmonicDensity = std::make_shared<GFE::HarmonicDensity<GridType::Codim<0>::Entity::Geometry::LocalCoordinate, ATargetSpace> >();
+  addends[0] = std::make_shared<GFE::LocalIntegralEnergy<FEBasis, GeodesicInterpolationRule, ATargetSpace> >(harmonicDensity);
   addends[1] = l2DistanceSquaredEnergy;
 
   std::vector<double> weights = {1.0, 1.0/(2*timeStepSize)};
diff --git a/src/harmonicmaps.cc b/src/harmonicmaps.cc
index f6e7fff752109ffcd57675da06fbe4770e5c6870..095cc200404c6568a10aa762b6ceb6df667810da 100644
--- a/src/harmonicmaps.cc
+++ b/src/harmonicmaps.cc
@@ -42,9 +42,10 @@
 #include <dune/gfe/localgeodesicfefunction.hh>
 #include <dune/gfe/localprojectedfefunction.hh>
 #include <dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh>
-#include <dune/gfe/assemblers/harmonicenergy.hh>
+#include <dune/gfe/assemblers/localintegralenergy.hh>
 #include <dune/gfe/assemblers/chiralskyrmionenergy.hh>
 #include <dune/gfe/assemblers/geodesicfeassembler.hh>
+#include <dune/gfe/densities/harmonicdensity.hh>
 #include <dune/gfe/riemanniantrsolver.hh>
 #include <dune/gfe/embeddedglobalgfefunction.hh>
 #include <dune/gfe/spaces/realtuple.hh>
@@ -277,10 +278,12 @@ int main (int argc, char *argv[])
   std::string energy = parameterSet.get<std::string>("energy");
   if (energy == "harmonic")
   {
+    auto harmonicDensity = std::make_shared<GFE::HarmonicDensity<GridType::Codim<0>::Entity::Geometry::LocalCoordinate, ATargetSpace> >();
+
     if (parameterSet["interpolationMethod"] == "geodesic")
-      localEnergy.reset(new HarmonicEnergy<FEBasis, GeodesicInterpolationRule, ATargetSpace>);
+      localEnergy.reset(new GFE::LocalIntegralEnergy<FEBasis, GeodesicInterpolationRule, ATargetSpace>(harmonicDensity));
     else if (parameterSet["interpolationMethod"] == "projected")
-      localEnergy.reset(new HarmonicEnergy<FEBasis, ProjectedInterpolationRule, ATargetSpace>);
+      localEnergy.reset(new GFE::LocalIntegralEnergy<FEBasis, ProjectedInterpolationRule, ATargetSpace>(harmonicDensity));
     else
       DUNE_THROW(Exception, "Unknown interpolation method " << parameterSet["interpolationMethod"] << " requested!");
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 0789635fe108f492e94993c243034f5f49eea67c..9141ecd85da90b0e57eaa023a7b69f5d9144b179 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -5,7 +5,6 @@ set(TESTS
   cosseratrodenergytest
   cosseratrodtest
   embeddedglobalgfefunctiontest
-  harmonicenergytest
   localgeodesicfefunctiontest
   localgfetestfunctiontest
   localprojectedfefunctiontest
diff --git a/test/harmonicenergytest.cc b/test/harmonicenergytest.cc
deleted file mode 100644
index bdfa68dfa1ff24b7fe1b73313999ed135d823644..0000000000000000000000000000000000000000
--- a/test/harmonicenergytest.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-#include "config.h"
-
-#include <dune/grid/uggrid.hh>
-
-#include <dune/functions/functionspacebases/lagrangebasis.hh>
-
-#include <dune/gfe/assemblers/harmonicenergy.hh>
-#include <dune/gfe/localgeodesicfefunction.hh>
-#include <dune/gfe/spaces/unitvector.hh>
-
-#include "multiindex.hh"
-#include "valuefactory.hh"
-
-
-
-using namespace Dune;
-
-/** \brief Computes the diameter of a set */
-template <class TargetSpace>
-double diameter(const std::vector<TargetSpace>& v)
-{
-  double d = 0;
-  for (size_t i=0; i<v.size(); i++)
-    for (size_t j=0; j<v.size(); j++)
-      d = std::max(d, TargetSpace::distance(v[i],v[j]));
-  return d;
-}
-
-template <class Basis, class TargetSpace>
-void testEnergy(const Basis& basis, const std::vector<TargetSpace>& coefficients)
-{
-  using GridView = typename Basis::GridView;
-  GridView gridView = basis.gridView();
-
-  using GeodesicInterpolationRule  = LocalGeodesicFEFunction<Basis::GridView::dimension, double, typename Basis::LocalView::Tree::FiniteElement, TargetSpace>;
-
-  HarmonicEnergy<Basis,GeodesicInterpolationRule,TargetSpace> assembler;
-  std::vector<TargetSpace> rotatedCoefficients(coefficients.size());
-
-  auto localView = basis.localView();
-  localView.bind(*gridView.template begin<0>());
-
-  for (int i=0; i<10; i++) {
-
-    Rotation<double,3> rotation(FieldVector<double,3>(1), double(i));
-
-    FieldMatrix<double,3,3> matrix;
-    rotation.matrix(matrix);
-    for (size_t j=0; j<coefficients.size(); j++) {
-      FieldVector<double,3> tmp;
-      matrix.mv(coefficients[j].globalCoordinates(), tmp);
-      rotatedCoefficients[j] = tmp;
-    }
-
-    std::cout << "energy: " << assembler.energy(localView,
-                                                rotatedCoefficients) << std::endl;
-
-  }
-
-}
-
-
-template <int domainDim, class TargetSpace>
-void test()
-{
-  // ////////////////////////////////////////////////////////
-  //   Make a test grid consisting of a single simplex
-  // ////////////////////////////////////////////////////////
-
-  typedef UGGrid<domainDim> GridType;
-
-  GridFactory<GridType> factory;
-
-  FieldVector<double,domainDim> pos(0);
-  factory.insertVertex(pos);
-
-  for (int i=0; i<domainDim; i++) {
-    pos = 0;
-    pos[i] = 1;
-    factory.insertVertex(pos);
-  }
-
-  std::vector<unsigned int> v(domainDim+1);
-  for (int i=0; i<domainDim+1; i++)
-    v[i] = i;
-  factory.insertElement(GeometryTypes::simplex(domainDim), v);
-
-  auto grid = std::unique_ptr<const GridType>(factory.createGrid());
-  using GridView = typename GridType::LeafGridView;
-  auto gridView = grid->leafGridView();
-
-  // A function space basis
-  using Basis = Functions::LagrangeBasis<GridView,1>;
-  Basis basis(gridView);
-
-  // //////////////////////////////////////////////////////////
-  //  Test whether the energy is invariant under isometries
-  // //////////////////////////////////////////////////////////
-
-  std::vector<TargetSpace> testPoints;
-  ValueFactory<TargetSpace>::get(testPoints);
-
-  // Set up elements of S^2
-  std::vector<TargetSpace> coefficients(domainDim+1);
-
-  ::MultiIndex index(domainDim+1, testPoints.size());
-  int numIndices = index.cycle();
-
-  for (int i=0; i<numIndices; i++, ++index) {
-
-    for (int j=0; j<domainDim+1; j++)
-      coefficients[j] = testPoints[index[j]];
-
-    // This may be overly restrictive, but see the TODO in targetspacetrsolver.cc
-    if (diameter(coefficients) > TargetSpace::convexityRadius)
-      continue;
-
-    testEnergy<Basis>(basis, coefficients);
-
-  }
-
-}
-
-
-int main(int argc, char** argv)
-{
-  MPIHelper::instance(argc, argv);
-
-  test<2,UnitVector<double,3> >();
-}
diff --git a/test/harmonicmaptest.cc b/test/harmonicmaptest.cc
index 6dd18b70ff65a383171eccc6688b25b73089a188..3550b42664173380e98bb79f58daeb2143569cf3 100644
--- a/test/harmonicmaptest.cc
+++ b/test/harmonicmaptest.cc
@@ -25,8 +25,9 @@
 #include <dune/gfe/localgeodesicfefunction.hh>
 #include <dune/gfe/localprojectedfefunction.hh>
 #include <dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh>
-#include <dune/gfe/assemblers/harmonicenergy.hh>
 #include <dune/gfe/assemblers/geodesicfeassembler.hh>
+#include <dune/gfe/assemblers/localintegralenergy.hh>
+#include <dune/gfe/densities/harmonicdensity.hh>
 #include <dune/gfe/riemanniantrsolver.hh>
 #include <dune/gfe/spaces/unitvector.hh>
 
@@ -151,8 +152,9 @@ int main (int argc, char *argv[])
   //using GeodesicInterpolationRule  = LocalGeodesicFEFunction<dim, double, FEBasis::LocalView::Tree::FiniteElement, ATargetSpace>;
   using ProjectedInterpolationRule = GFE::LocalProjectedFEFunction<dim, double, FEBasis::LocalView::Tree::FiniteElement, ATargetSpace>;
 
+  auto harmonicDensity = std::make_shared<GFE::HarmonicDensity<GridType::Codim<0>::Entity::Geometry::LocalCoordinate, ATargetSpace> >();
   //std::shared_ptr<GFE::LocalEnergy<FEBasis,ATargetSpace> > localEnergy = std::make_shared<HarmonicEnergy<FEBasis, GeodesicInterpolationRule, ATargetSpace> >();
-  std::shared_ptr<GFE::LocalEnergy<FEBasis,ATargetSpace> > localEnergy = std::make_shared<HarmonicEnergy<FEBasis, ProjectedInterpolationRule, ATargetSpace> >();
+  std::shared_ptr<GFE::LocalEnergy<FEBasis,ATargetSpace> > localEnergy = std::make_shared<GFE::LocalIntegralEnergy<FEBasis, ProjectedInterpolationRule, ATargetSpace> >(harmonicDensity);
 
   LocalGeodesicFEADOLCStiffness<FEBasis,TargetSpace> localGFEADOLCStiffness(localEnergy.get());