diff --git a/dune/elasticity/assemblers/feassembler.hh b/dune/elasticity/assemblers/feassembler.hh
index 8e7c7fcb2c8506cab9f4d824724e0d6f56a17d76..eae94ae0c359f499a5c2d01a80222e32e1a06c43 100644
--- a/dune/elasticity/assemblers/feassembler.hh
+++ b/dune/elasticity/assemblers/feassembler.hh
@@ -13,6 +13,8 @@
 #include <dune/functions/functionspacebases/concepts.hh>
 #include <dune/functions/backends/istlvectorbackend.hh>
 
+#include <dune/grid/common/partitionset.hh>
+
 #include "localfestiffness.hh"
 
 
diff --git a/dune/elasticity/materials/mooneyrivlindensity.hh b/dune/elasticity/materials/mooneyrivlindensity.hh
index 6871bc92b168156a50038d23d92057ba7d7f9339..3cf4d5d591a863bcacc5c300688066d516c60cd1 100644
--- a/dune/elasticity/materials/mooneyrivlindensity.hh
+++ b/dune/elasticity/materials/mooneyrivlindensity.hh
@@ -58,53 +58,62 @@ public:
         for (int k=0; k<dim; k++)
           C[i][j] += gradient[k][i] * gradient[k][j];
 
-    //////////////////////////////////////////////////////////
-    //  Eigenvalues of C = F^TF
-    //////////////////////////////////////////////////////////
-
-
-    // eigenvalues of C, i.e., squared singular values \sigma_i of F
-    Dune::FieldVector<field_type, dim> sigmaSquared;
-    FMatrixHelp::eigenValues(C, sigmaSquared);
-
-    field_type normFSquared = gradient.frobenius_norm2();
+    /* The Mooney-Rivlin-Density is given as a function of the eigenvalues of the right Cauchy-Green-Deformation tensor C = F^TF
+       or the right Cauchy-Green-Deformation tensor B = FF^T.
+       C = F^TF and B = FF^T have the same eigenvalues - we can use either one of them.
+       
+       There are three Mooney-Rivlin-Variants:
+       ciarlet: W(F) = mooneyrivlin_a*(normF)^2 + mooneyrivlin_b*(normFinv)^2*detF + mooneyrivlin_c*(detF)^2 -
+                       ((dim-1)*mooneyrivlin_a + mooneyrivlin_b + 2*mooneyrivlin_c)*ln(detF)
+       log:     W(F) = \sum_{i,j=0}^{i+j<=n} mooneyrivlin_ij * (I1 - 3)^i * (I2 - 3)^j + mooneyrivlin_k * ln(det(F))
+       square:  W(F) = \sum_{i,j=0}^{i+j<=n} mooneyrivlin_ij * (I1 - 3)^i * (I2 - 3)^j + mooneyrivlin_k * 0.5 * (det(F) - 1)
+       
+       For log and square: I1 and I2 are the first two invariants of C (or B), multiplied with a factor depending on det(F):
+       I1 = (det(F)^(-2/dim)) * [ first invariant of C ]
+          = (det(F)^(-2/dim)) * (sum of all eigenvalues of C)
+          = (det(F)^(-2/dim)) * trace(C)
+          = (det(F)^(-2/dim)) * trace(F^TF)
+          = (det(F)^(-2/dim)) * (frobenius_norm(F))^2
+       I2 = (det(F)^(-4/dim)) * [ second invariant of C ]
+          = (det(F)^(-4/dim)) * 0.5 * [ trace(C)^2 - tr(C^2) ]
+          = (det(F)^(-4/dim)) * [C_11C_22 + C_11C_33 + C_22C_33 - C_12C_21 - C_13C_31 - C_23C_32]
+          = (det(F)^(-4/dim)) * [C_11C_22 + C_11C_33 + C_22C_33 - C_12^2 - C_13^2 - C_23^2]
+    */
+
+    field_type frobeniusNormFsquared = gradient.frobenius_norm2();
     field_type detF = gradient.determinant();
 
     if (detF < 0)
       DUNE_THROW( Dune::Exception, "det(F) < 0, so it is not possible to calculate the MooneyRivlinEnergy.");
 
-    field_type normFinvSquared = 0;
-
-    field_type c2Tilde = 0;
-    for (int i = 0; i < dim; i++) {
-      normFinvSquared += 1/sigmaSquared[i];
-      // compute D, which is the sum of the squared eigenvalues
-      for (int j = i+1; j < dim; j++)
-        c2Tilde += sigmaSquared[j]*sigmaSquared[i];
-      }
-
-    field_type trCTildeMinus3 = normFSquared/pow(detF, 2.0/dim) - 3;
-    // \tilde{D} = \frac{1}{\det{F}^{4/3}}D -> divide by det(F)^(4/3)= det(C)^(2/3)
-    c2Tilde /= pow(detF, 4.0/dim);
-    field_type c2TildeMinus3 = c2Tilde - 3;
-
     // Add the local energy density
     field_type strainEnergy = 0;
 
     if (mooneyrivlin_energy == "ciarlet")
     {
+      //To calculate the squared frobeniusnorm of F^(-1), we actually invert F^(-1)
+      auto gradientInverse = gradient;
+      gradientInverse.invert();
+      field_type frobeinusNormFInverseSquared = gradientInverse.frobenius_norm2();
       using std::log;
-      return mooneyrivlin_a*normFSquared + mooneyrivlin_b*normFinvSquared*detF + mooneyrivlin_c*detF*detF - ((dim-1)*mooneyrivlin_a + mooneyrivlin_b + 2*mooneyrivlin_c)*log(detF);
-    } else {
-      strainEnergy = mooneyrivlin_10 * trCTildeMinus3 +
-                        mooneyrivlin_01 * c2TildeMinus3  +
-                        mooneyrivlin_20 * trCTildeMinus3 * trCTildeMinus3 +
-                        mooneyrivlin_02 * c2TildeMinus3  * c2TildeMinus3  +
-                        mooneyrivlin_11 * trCTildeMinus3 * c2TildeMinus3  +
-                        mooneyrivlin_30 * trCTildeMinus3 * trCTildeMinus3 * trCTildeMinus3 +
-                        mooneyrivlin_21 * trCTildeMinus3 * trCTildeMinus3 * c2TildeMinus3  +
-                        mooneyrivlin_12 * trCTildeMinus3 * c2TildeMinus3  * c2TildeMinus3  +
-                        mooneyrivlin_03 * c2TildeMinus3  * c2TildeMinus3  * c2TildeMinus3;
+      return mooneyrivlin_a*frobeniusNormFsquared + mooneyrivlin_b*frobeinusNormFInverseSquared*detF + mooneyrivlin_c*detF*detF - ((dim-1)*mooneyrivlin_a + mooneyrivlin_b + 2*mooneyrivlin_c)*log(detF);
+    } else { // mooneyrivlin_energy is "log" or "square"
+      field_type a = pow(detF, 2.0/dim);
+      field_type invariant1Minus3 = frobeniusNormFsquared/a - 3;
+      field_type secondInvariantOfC = 0;
+      for (int i=0; i<dim-1; i++)
+        for (int j=i+1; j<dim; j++)
+          secondInvariantOfC += C[i][i]*C[j][j] - C[i][j]*C[i][j];
+      field_type invariant2Minus3 = secondInvariantOfC/(a*a) - 3;
+      strainEnergy = mooneyrivlin_10 * invariant1Minus3 +
+                        mooneyrivlin_01 * invariant2Minus3  +
+                        mooneyrivlin_20 * invariant1Minus3 * invariant1Minus3 +
+                        mooneyrivlin_02 * invariant2Minus3  * invariant2Minus3  +
+                        mooneyrivlin_11 * invariant1Minus3 * invariant2Minus3  +
+                        mooneyrivlin_30 * invariant1Minus3 * invariant1Minus3 * invariant1Minus3 +
+                        mooneyrivlin_21 * invariant1Minus3 * invariant1Minus3 * invariant2Minus3  +
+                        mooneyrivlin_12 * invariant1Minus3 * invariant2Minus3  * invariant2Minus3  +
+                        mooneyrivlin_03 * invariant2Minus3  * invariant2Minus3  * invariant2Minus3;
       if (mooneyrivlin_energy == "log") {
         using std::log;
         field_type logDetF = log(detF);
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 65035164e33cd40989d38618a114079d84a4bb14..262d1474df7f0cc6dde019e24b4fee36f93fb729 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,5 +8,8 @@ dune_add_test(SOURCES materialtest
 add_dune_ug_flags(materialtest)
 add_dune_adolc_flags(materialtest)
 
+dune_add_test(SOURCES mooneyrivlintest
+              CMAKE_GUARD ADOLC_FOUND)
+
 dune_add_test(SOURCES localhyperdualstiffnesstest
               CMAKE_GUARD ADOLC_FOUND)
diff --git a/test/mooneyrivlintest.cc b/test/mooneyrivlintest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b69f5eb4151ad60a4236740d79004266a0ef1718
--- /dev/null
+++ b/test/mooneyrivlintest.cc
@@ -0,0 +1,176 @@
+#include <config.h>
+
+// Includes for the ADOL-C automatic differentiation library
+// Need to come before (almost) all others.
+#include <adolc/adouble.h>
+#include <dune/fufem/utilities/adolcnamespaceinjections.hh>
+
+#include <dune/common/parametertree.hh>
+#include <dune/common/parallel/mpihelper.hh>
+
+#include <dune/elasticity/assemblers/localadolcstiffness.hh>
+#include <dune/elasticity/assemblers/feassembler.hh>
+#include <dune/elasticity/materials/localintegralenergy.hh>
+#include <dune/elasticity/materials/mooneyrivlindensity.hh>
+
+#include <dune/functions/functionspacebases/interpolate.hh>
+#include <dune/functions/functionspacebases/lagrangebasis.hh>
+#include <dune/functions/functionspacebases/powerbasis.hh>
+
+#include <dune/grid/utility/structuredgridfactory.hh>
+#include <dune/grid/uggrid.hh>
+
+// grid dimension
+const int dim = 3;
+
+//order of integration
+const int order = 1;
+
+using namespace Dune;
+
+//differentiation method: ADOL-C
+typedef adouble ValueType;
+
+using namespace Dune;
+
+typedef BlockVector<FieldVector<double,dim> > VectorType;
+typedef BCRSMatrix<FieldMatrix<double, dim, dim> > MatrixType;
+
+template <class Basis>
+int assembleAndCompare (const Basis basis, const ParameterTree parameters, const VectorType x,
+                        double expectedEnergy, double expectedGradientTwoNorm, double expectedGradientInfinityNorm, double expectedMatrixFrobeniusNorm) {
+  using LocalView = typename Basis::LocalView;
+
+  std::string mooneyrivlin_energy = parameters.get<std::string>("mooneyrivlin_energy");
+
+  auto elasticDensity = std::make_shared<Elasticity::MooneyRivlinDensity<dim,ValueType>>(parameters);
+  auto elasticEnergy = std::make_shared<Elasticity::LocalIntegralEnergy<LocalView, adouble>>(elasticDensity);
+  auto localADOLCStiffness = std::make_shared<Elasticity::LocalADOLCStiffness<LocalView>>(elasticEnergy);
+  Elasticity::FEAssembler<Basis,VectorType> assembler(basis, localADOLCStiffness);
+
+  //////////////////////////////////////////////////////////////
+  //  Compute the energy, assemble and compare!
+  //////////////////////////////////////////////////////////////
+  
+  VectorType gradient;
+  MatrixType hessianMatrix;
+  double energy = assembler.computeEnergy(x);
+
+  if ( std::abs(energy - expectedEnergy)/expectedEnergy > 1e-3)
+  {
+      std::cerr << std::setprecision(9);
+      std::cerr << "In " << mooneyrivlin_energy << ": Calculated energy is " << energy << " but '" << expectedEnergy << "' was expected!" << std::endl;
+      return 1;
+  }
+
+  assembler.assembleGradientAndHessian(x, gradient, hessianMatrix, true);
+
+  double gradientTwoNorm = gradient.two_norm();
+  double gradientInfinityNorm = gradient.infinity_norm();
+  double matrixFrobeniusNorm = hessianMatrix.frobenius_norm();
+  if ( std::abs(gradientTwoNorm - expectedGradientTwoNorm)/expectedGradientTwoNorm > 1e-4 || std::abs(gradientInfinityNorm - expectedGradientInfinityNorm)/expectedGradientInfinityNorm > 1e-8)
+  {
+      std::cerr << std::setprecision(9);
+      std::cerr << "In " << mooneyrivlin_energy << ": Calculated gradient max norm is " << gradientInfinityNorm << " but '" << expectedGradientInfinityNorm << "' was expected!" << std::endl;
+      std::cerr << "In " << mooneyrivlin_energy << ": Calculated gradient norm is " << gradientTwoNorm << " but '" << expectedGradientTwoNorm << "' was expected!" << std::endl;
+      return 1;
+  }
+
+  if ( std::abs(matrixFrobeniusNorm - expectedMatrixFrobeniusNorm)/expectedMatrixFrobeniusNorm > 1e-4)
+  {
+      std::cerr << std::setprecision(9);
+      std::cerr << "In " << mooneyrivlin_energy << ": Calculated matrix norm is " << matrixFrobeniusNorm << " but '" << expectedMatrixFrobeniusNorm << "' was expected!" << std::endl;
+      return 1;
+  }
+
+  return 0;
+}
+
+int main (int argc, char *argv[])
+{
+
+  Dune::MPIHelper& mpiHelper = MPIHelper::instance(argc, argv);
+
+  // ///////////////////////////////////////
+  //    Create the grid
+  // ///////////////////////////////////////
+  using GridType = UGGrid<dim>;
+  auto grid = StructuredGridFactory<GridType>::createCubeGrid({0,0,0}, {1,1,1}, {3,3,3});
+  int refine = 3;
+  while(refine > 0) {
+    for (auto&& e : elements(grid->leafGridView())){
+      bool refine = false;
+      for (int i = 0; i < e.geometry().corners(); i++) {
+          refine = refine || (e.geometry().corner(i)[0] > 0.99);
+      }
+      grid->mark(refine ? 1 : 0, e);
+    }
+    grid->adapt();
+    refine--;
+  }
+  grid->loadBalance();
+
+  using GridView = GridType::LeafGridView;
+  GridView gridView = grid->leafGridView();
+
+  /////////////////////////////////////////////////////////////////////////
+  //  Create a power basis
+  /////////////////////////////////////////////////////////////////////////
+
+  using namespace Functions::BasisFactory;
+  auto basis = makeBasis(
+    gridView,
+    power<dim>(
+      lagrange<order>(),
+      blockedInterleaved()
+  ));
+
+  using PowerBasis = decltype(basis);
+
+  //////////////////////////////////////////////////////////////
+  //  Prepare the iterate x where we want to assemble
+  //////////////////////////////////////////////////////////////
+  VectorType x(basis.size());
+  Functions::interpolate(basis, x, [](FieldVector<double,dim> x){
+    FieldVector<double,dim> y = {0.5*x[0]*x[0], 0.5*x[1] + 0.2*x[0], 4*std::abs(std::sin(x[2]))};
+    return y;
+  });
+
+  ParameterTree parameters;
+  parameters["mooneyrivlin_10"] = "1.67e+6";
+  parameters["mooneyrivlin_01"] = "1.94e+6";
+  parameters["mooneyrivlin_20"] = "2.42e+6";
+  parameters["mooneyrivlin_02"] = "6.52e+6";
+  parameters["mooneyrivlin_11"] = "-7.34e+6";
+  parameters["mooneyrivlin_30"] = "0";
+  parameters["mooneyrivlin_03"] = "0";
+  parameters["mooneyrivlin_21"] = "0";
+  parameters["mooneyrivlin_12"] = "0";
+  parameters["mooneyrivlin_k"] = "75e+6";
+
+  parameters["mooneyrivlin_energy"] = "square";
+  double expectedEnergy = 177758377;
+  double expectedGradientTwoNorm = 2.13791422e+09;
+  double expectedGradientInfinityNorm = 599188506;
+  double expectedMatrixFrobeniusNorm = 1.62529884e+11;
+  int testSquare = assembleAndCompare(basis, parameters, x, expectedEnergy, expectedGradientTwoNorm, expectedGradientInfinityNorm, expectedMatrixFrobeniusNorm);
+
+  parameters["mooneyrivlin_energy"] = "log";
+  expectedEnergy = 181180273;
+  expectedGradientTwoNorm = 2.29399362e+09;
+  expectedGradientInfinityNorm = 648551554;
+  expectedMatrixFrobeniusNorm = 1.67152642e+11;
+  int testLog = assembleAndCompare(basis, parameters, x, expectedEnergy, expectedGradientTwoNorm, expectedGradientInfinityNorm, expectedMatrixFrobeniusNorm);
+
+  parameters["mooneyrivlin_energy"] = "ciarlet";
+  parameters["mooneyrivlin_a"] = "2.42e+6";
+  parameters["mooneyrivlin_b"] = "6.52e+6";
+  parameters["mooneyrivlin_c"] = "-7.34e+6";
+  expectedEnergy = 83069427.2;
+  expectedGradientTwoNorm = 163210957;
+  expectedGradientInfinityNorm = 49284369.2;
+  expectedMatrixFrobeniusNorm = 5.92126562e+09;
+  int testCiarlet = assembleAndCompare(basis, parameters, x, expectedEnergy, expectedGradientTwoNorm, expectedGradientInfinityNorm, expectedMatrixFrobeniusNorm);
+
+  return testCiarlet + testLog + testSquare;
+}