diff --git a/dune/gfe/assemblers/geodesicfeassembler.hh b/dune/gfe/assemblers/geodesicfeassembler.hh
index 070c4164084556b8a20721669a0a2573798d870e..b24be8671eb6ae1195985a669a0d9fe7eb1d96ea 100644
--- a/dune/gfe/assemblers/geodesicfeassembler.hh
+++ b/dune/gfe/assemblers/geodesicfeassembler.hh
@@ -168,7 +168,7 @@ assembleGradientAndHessian(const std::vector<TargetSpace>& sol,
       localSolution[i] = sol[localView.index(i)];
 
     std::vector<double> localGradient(numOfBaseFct*blocksize);
-    Dune::Matrix<Dune::FieldMatrix<double,blocksize,blocksize> > localHessian(numOfBaseFct,numOfBaseFct);
+    Dune::Matrix<double> localHessian(numOfBaseFct*blocksize, numOfBaseFct*blocksize);
 
     // setup local matrix and gradient
     localStiffness_->assembleGradientAndHessian(localView, localSolution, localGradient, localHessian);
@@ -181,7 +181,10 @@ assembleGradientAndHessian(const std::vector<TargetSpace>& sol,
       for (int j=0; j<numOfBaseFct; j++ ) {
 
         auto col = localView.index(j);
-        hessian[row][col] += localHessian[i][j];
+
+        for (std::size_t ii=0; ii<blocksize; ii++)
+          for (std::size_t jj=0; jj<blocksize; jj++)
+            hessian[row][col][ii][jj] += localHessian[i*blocksize+ii][j*blocksize+jj];
 
       }
     }
diff --git a/dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh b/dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh
index 9220b8d1618fa3da46fbc3f099848061cae0ec55..594c0c50931b703be1c07b68361caaa3b9abd75b 100644
--- a/dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh
+++ b/dune/gfe/assemblers/localgeodesicfeadolcstiffness.hh
@@ -390,7 +390,7 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
   typedef typename TargetSpace::EmbeddedTangentVector EmbeddedTangentVector;
   typedef typename TargetSpace::TangentVector TangentVector;
 
-  localHessian.setSize(nDofs,nDofs);
+  localHessian.setSize(nDofs*blocksize,nDofs*blocksize);
 
   for (size_t col=0; col<nDofs; col++) {
 
@@ -404,7 +404,7 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
         embeddedHessian[row][col].mv(z,semiEmbeddedProduct);
 
         for (int subRow=0; subRow<blocksize; subRow++)
-          localHessian[row][col][subRow][subCol] = semiEmbeddedProduct[subRow];
+          localHessian[row*blocksize+subRow][col*blocksize+subCol] = semiEmbeddedProduct[subRow];
       }
 
     }
@@ -431,7 +431,8 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
       TangentVector tmp2;
       orthonormalFrame[row].mv(tmp1,tmp2);
 
-      localHessian[row][row][subRow] += tmp2;
+      for (size_t subCol=0; subCol<blocksize; subCol++)
+        localHessian[row*blocksize+subRow][row*blocksize+subCol] += tmp2[subCol];
     }
 
   }
@@ -698,7 +699,7 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
 
     using namespace Dune::Indices;
 
-    localHessian[_0][_0].setSize(nDofs0,nDofs0);
+    localHessian[_0][_0].setSize(nDofs0*blocksize0, nDofs0*blocksize0);
 
     for (size_t col=0; col<nDofs0; col++)
     {
@@ -713,12 +714,12 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
           embeddedHessian00[row][col].mv(z,semiEmbeddedProduct);
 
           for (int subRow=0; subRow<blocksize0; subRow++)
-            localHessian[_0][_0][row][col][subRow][subCol] = semiEmbeddedProduct[subRow];
+            localHessian[_0][_0][row*blocksize0+subRow][col*blocksize0 + subCol] = semiEmbeddedProduct[subRow];
         }
       }
     }
 
-    localHessian[_0][_1].setSize(nDofs0,nDofs1);
+    localHessian[_0][_1].setSize(nDofs0*blocksize0, nDofs1*blocksize1);
 
     for (size_t col=0; col<nDofs1; col++)
     {
@@ -733,12 +734,12 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
           embeddedHessian01[row][col].mv(z,semiEmbeddedProduct);
 
           for (int subRow=0; subRow<blocksize0; subRow++)
-            localHessian[_0][_1][row][col][subRow][subCol] = semiEmbeddedProduct[subRow];
+            localHessian[_0][_1][row*blocksize0+subRow][col*blocksize1+subCol] = semiEmbeddedProduct[subRow];
         }
       }
     }
 
-    localHessian[_1][_0].setSize(nDofs1,nDofs0);
+    localHessian[_1][_0].setSize(nDofs1*blocksize1, nDofs0*blocksize0);
 
     for (size_t col=0; col<nDofs0; col++)
     {
@@ -752,12 +753,12 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
           embeddedHessian10[row][col].mv(z,semiEmbeddedProduct);
 
           for (int subRow=0; subRow<blocksize1; subRow++)
-            localHessian[_1][_0][row][col][subRow][subCol] = semiEmbeddedProduct[subRow];
+            localHessian[_1][_0][row*blocksize1+subRow][col*blocksize0+subCol] = semiEmbeddedProduct[subRow];
         }
       }
     }
 
-    localHessian[_1][_1].setSize(nDofs1,nDofs1);
+    localHessian[_1][_1].setSize(nDofs1*blocksize1, nDofs1*blocksize1);
 
     for (size_t col=0; col<nDofs1; col++)
     {
@@ -772,7 +773,7 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
           embeddedHessian11[row][col].mv(z,semiEmbeddedProduct);
 
           for (int subRow=0; subRow<blocksize1; subRow++)
-            localHessian[_1][_1][row][col][subRow][subCol] = semiEmbeddedProduct[subRow];
+            localHessian[_1][_1][row*blocksize1+subRow][col*blocksize1+subCol] = semiEmbeddedProduct[subRow];
         }
       }
     }
@@ -802,7 +803,8 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
         typename TargetSpace0::TangentVector tmp2;
         orthonormalFrame0[row].mv(tmp1,tmp2);
 
-        localHessian[_0][_0][row][row][subRow] += tmp2;
+        for (size_t subCol=0; subCol<blocksize0; subCol++)
+          localHessian[_0][_0][row*blocksize0+subRow][row*blocksize0+subCol] += tmp2[subCol];
       }
     }
 
@@ -816,7 +818,8 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
         typename TargetSpace1::TangentVector tmp2;
         orthonormalFrame1[row].mv(tmp1,tmp2);
 
-        localHessian[_1][_1][row][row][subRow] += tmp2;
+        for (size_t subCol=0; subCol<blocksize1; subCol++)
+          localHessian[_1][_1][row*blocksize1+subRow][row*blocksize1+subCol] += tmp2[subCol];
       }
     }
   }
diff --git a/dune/gfe/assemblers/localgeodesicfefdstiffness.hh b/dune/gfe/assemblers/localgeodesicfefdstiffness.hh
index b8c50b4cd444ed8c44cc3f977c6d19b7d19ec454..630e9a1e1cf08899445f68dc985e51ae4ac73fa9 100644
--- a/dune/gfe/assemblers/localgeodesicfefdstiffness.hh
+++ b/dune/gfe/assemblers/localgeodesicfefdstiffness.hh
@@ -156,7 +156,7 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
   size_t nDofs = localSolution.size();
 
   // Clear assemble data
-  localHessian.setSize(nDofs, nDofs);
+  localHessian.setSize(nDofs*blocksize, nDofs*blocksize);
 
   localHessian = 0;
 
@@ -264,9 +264,9 @@ assembleGradientAndHessian(const typename Basis::LocalView& localView,
 
           field_type foo = 0.5 * (forwardValue - 2*centerValue + backwardValue) / (eps*eps);
 #ifdef MULTIPRECISION
-          localHessian[i][j][i2][j2] = localHessian[j][i][j2][i2] = foo.template convert_to<double>();
+          localHessian[i*blocksize+i2][j*blocksize+j2] = localHessian[j*blocksize+j2][i*blocksize+i2] = foo.template convert_to<double>();
 #else
-          localHessian[i][j][i2][j2] = localHessian[j][i][j2][i2] = foo;
+          localHessian[i*blocksize+i2][j*blocksize+j2] = localHessian[j*blocksize+j2][i*blocksize+i2] = foo;
 #endif
         }
       }
diff --git a/dune/gfe/assemblers/localgeodesicfestiffness.hh b/dune/gfe/assemblers/localgeodesicfestiffness.hh
index b784821040d47f7ab20fb99c6077bb51b5928236..e1f936facfe6df2a9a0a46635ae1763aa8ef750f 100644
--- a/dune/gfe/assemblers/localgeodesicfestiffness.hh
+++ b/dune/gfe/assemblers/localgeodesicfestiffness.hh
@@ -28,10 +28,9 @@ namespace Dune::GFE
     public:
 
       // Type of the local Hessian
-      using Hessian = Matrix<FieldMatrix<RT, blocksize, blocksize> >;
+      using Hessian = Matrix<double>;
 
-      using Row = MultiTypeBlockVector<Matrix<FieldMatrix<RT, blocksize, blocksize> > >;
-      using CompositeHessian = MultiTypeBlockMatrix<Row>;
+      using CompositeHessian = FieldMatrix<Matrix<double>,1,1>;
     };
 
     /** \brief A class exporting container types for sets local Hesse matrices
@@ -60,15 +59,10 @@ namespace Dune::GFE
     public:
 
       // Type of the local Hessian
-      using Hessian = Matrix<FieldMatrix<RT, blocksize, blocksize> >;
+      using Hessian = Matrix<double>;
 
       // Type of the local Hessian
-      using Row0 = MultiTypeBlockVector<Matrix<FieldMatrix<RT, blocksize0, blocksize0> >,
-          Matrix<FieldMatrix<RT, blocksize0, blocksize1> > >;
-      using Row1 = MultiTypeBlockVector<Matrix<FieldMatrix<RT, blocksize1, blocksize0> >,
-          Matrix<FieldMatrix<RT, blocksize1, blocksize1> > >;
-
-      using CompositeHessian = MultiTypeBlockMatrix<Row0, Row1>;
+      using CompositeHessian = FieldMatrix<Matrix<double>,2,2>;
     };
   }
 }
diff --git a/dune/gfe/assemblers/mixedgfeassembler.hh b/dune/gfe/assemblers/mixedgfeassembler.hh
index 4df0b50a948252026e11ddaada4ef85c004ba570..a3cef7265c981104e19b33eac656c792d2f05b38 100644
--- a/dune/gfe/assemblers/mixedgfeassembler.hh
+++ b/dune/gfe/assemblers/mixedgfeassembler.hh
@@ -194,12 +194,7 @@ assembleGradientAndHessian(const std::vector<TargetSpace0>& configuration0,
 
     std::vector<double> localGradient(nDofs0*blocksize0 + nDofs1*blocksize1);
 
-    using Row0 = Dune::MultiTypeBlockVector<Dune::Matrix<Dune::FieldMatrix<double, blocksize0, blocksize0> >,
-        Dune::Matrix<Dune::FieldMatrix<double, blocksize0, blocksize1> > >;
-    using Row1 = Dune::MultiTypeBlockVector<Dune::Matrix<Dune::FieldMatrix<double, blocksize1, blocksize0> >,
-        Dune::Matrix<Dune::FieldMatrix<double, blocksize1, blocksize1> > >;
-
-    using HessianType = Dune::MultiTypeBlockMatrix<Row0, Row1>;
+    using HessianType = Dune::FieldMatrix<Dune::Matrix<double>,2,2>;
 
     HessianType localHessian;
 
@@ -237,16 +232,25 @@ assembleGradientAndHessian(const std::vector<TargetSpace0>& configuration0,
         auto col = localView.index(localIndexCol);
 
         if (row[0]==0 and col[0]==0)
-          hessian[_0][_0][row[1]][col[1]] += localHessian[_0][_0][i][j];
+          for (std::size_t ii=0; ii<blocksize0; ii++)
+            for (std::size_t jj=0; jj<blocksize0; jj++)
+              hessian[_0][_0][row[1]][col[1]][ii][jj] += localHessian[_0][_0][i*blocksize0+ii][j*blocksize0+jj];
 
         if (row[0]==0 and col[0]==1)
-          hessian[_0][_1][row[1]][col[1]] += localHessian[_0][_1][i][j-nDofs0];
+          for (std::size_t ii=0; ii<blocksize0; ii++)
+            for (std::size_t jj=0; jj<blocksize1; jj++)
+              hessian[_0][_1][row[1]][col[1]][ii][jj] += localHessian[_0][_1][i*blocksize0+ii][(j-nDofs0)*blocksize1+jj];
 
         if (row[0]==1 and col[0]==0)
-          hessian[_1][_0][row[1]][col[1]] += localHessian[_1][_0][i-nDofs0][j];
+          for (std::size_t ii=0; ii<blocksize1; ii++)
+            for (std::size_t jj=0; jj<blocksize0; jj++)
+              hessian[_1][_0][row[1]][col[1]][ii][jj] += localHessian[_1][_0][(i-nDofs0)*blocksize1+ii][j*blocksize0+jj];
 
         if (row[0]==1 and col[0]==1)
-          hessian[_1][_1][row[1]][col[1]] += localHessian[_1][_1][i-nDofs0][j-nDofs0];
+          for (std::size_t ii=0; ii<blocksize1; ii++)
+            for (std::size_t jj=0; jj<blocksize1; jj++)
+              hessian[_1][_1][row[1]][col[1]][ii][jj] += localHessian[_1][_1][(i-nDofs0)*blocksize1+ii][(j-nDofs0)*
+                                                                                                        blocksize1+jj];
       }
 
       // Add local gradient to global gradient
diff --git a/test/localadolcstiffnesstest.cc b/test/localadolcstiffnesstest.cc
index 5c5faef4bae66f7d1ec12fec9bcc011dd7bba267..10ca626bb187f9c1b62725860d6542a974059b22 100644
--- a/test/localadolcstiffnesstest.cc
+++ b/test/localadolcstiffnesstest.cc
@@ -55,9 +55,8 @@ const int dim = 2;
 using TargetSpace = GFE::ProductManifold<RealTuple<double,3>,Rotation<double,3> >;
 
 // Compare two matrices
-template <int N>
-void compareMatrices(const Matrix<FieldMatrix<double,N,N> >& matrixA, std::string nameA,
-                     const Matrix<FieldMatrix<double,N,N> >& matrixB, std::string nameB)
+void compareMatrices(const Matrix<double>& matrixA, std::string nameA,
+                     const Matrix<double>& matrixB, std::string nameB)
 {
   double maxAbsDifference = -1;
   double maxRelDifference = -1;
@@ -66,22 +65,18 @@ void compareMatrices(const Matrix<FieldMatrix<double,N,N> >& matrixA, std::strin
 
     for (size_t j=0; j<matrixA.M(); j++ ) {
 
-      for (size_t ii=0; ii<matrixA[i][j].N(); ii++)
-        for (size_t jj=0; jj<matrixA[i][j].M(); jj++)
-        {
-          double valueA = matrixA[i][j][ii][jj];
-          double valueB = matrixB[i][j][ii][jj];
-
-          double absDifference = valueA - valueB;
-          double relDifference = std::abs(absDifference) / std::abs(valueA);
-          maxAbsDifference = std::max(maxAbsDifference, std::abs(absDifference));
-          if (not std::isinf(relDifference))
-            maxRelDifference = std::max(maxRelDifference, relDifference);
-
-          if (relDifference > 1)
-            std::cout << i << ", " << j << "   " << ii << ", " << jj
-                      << ",       " << nameA << ": " << valueA << ",           " << nameB << ": " << valueB << std::endl;
-        }
+      const double valueA = matrixA[i][j];
+      const double valueB = matrixB[i][j];
+
+      double absDifference = valueA - valueB;
+      double relDifference = std::abs(absDifference) / std::abs(valueA);
+      maxAbsDifference = std::max(maxAbsDifference, std::abs(absDifference));
+      if (not std::isinf(relDifference))
+        maxRelDifference = std::max(maxRelDifference, relDifference);
+
+      if (relDifference > 1)
+        std::cout << i << ", " << j << "   ,       "
+                  << nameA << ": " << valueA << ",           " << nameB << ": " << valueB << std::endl;
     }
   }
 
@@ -213,8 +208,8 @@ int main (int argc, char *argv[]) try
     std::vector<double> localRiemannianADGradient(numOfBaseFct*blocksize);
     std::vector<double> localRiemannianFDGradient(numOfBaseFct*blocksize);
 
-    Matrix<FieldMatrix<double,blocksize,blocksize> > localRiemannianADHessian;
-    Matrix<FieldMatrix<double,blocksize,blocksize> > localRiemannianFDHessian;
+    Matrix<double> localRiemannianADHessian;
+    Matrix<double> localRiemannianFDHessian;
 
     localGFEADOLCStiffness.assembleGradientAndHessian(localView,
                                                       localSolution,