diff --git a/src/rodassembler.cc b/src/rodassembler.cc
index 237ba99185e7c2420295a978f15a7a6f0e976b5c..fad5b84d8738fa38e4e852494c1fed1c0dceddad 100644
--- a/src/rodassembler.cc
+++ b/src/rodassembler.cc
@@ -93,57 +93,51 @@ assembleMatrix(const std::vector<Configuration>& sol,
 
 }
 
-
-
 template <class GridType>
 void Dune::RodAssembler<GridType>::
 getFirstDerivativesOfDirectors(const Quaternion<double>& q, 
-                               Dune::FixedArray<Dune::FixedArray<Dune::FixedArray<Dune::FieldVector<double,3>, 3>, 2>, 3>& dd_dvij,
-                               const Dune::FixedArray<Dune::FixedArray<Quaternion<double>, 3>, 2>& dq_dvij)
+                               Dune::FixedArray<Dune::FixedArray<Dune::FieldVector<double,3>, 3>, 3>& dd_dvj,
+                               const Dune::FixedArray<Quaternion<double>, 3>& dq_dvj)
 {
  
-    // Contains \parder d \parder v^i_j
-    
-    for (int i=0; i<2; i++) {
+    // Contains \parder d \parder v_j
         
-        for (int j=0; j<3; j++) {
-            
-            // d1
-            dd_dvij[0][i][j][0] = q[0]*(dq_dvij[i][j].mult(q))[0] - q[1]*(dq_dvij[i][j].mult(q))[1] 
-                - q[2]*(dq_dvij[i][j].mult(q))[2] + q[3]*(dq_dvij[i][j].mult(q))[3];
-            
-            dd_dvij[0][i][j][1] = (dq_dvij[i][j].mult(q))[0]*q[1] + q[0]*(dq_dvij[i][j].mult(q))[1]
-                + (dq_dvij[i][j].mult(q))[2]*q[3] + q[2]*(dq_dvij[i][j].mult(q))[3];
-            
-            dd_dvij[0][i][j][2] = (dq_dvij[i][j].mult(q))[0]*q[2] + q[0]*(dq_dvij[i][j].mult(q))[2]
-                - (dq_dvij[i][j].mult(q))[1]*q[3] - q[1]*(dq_dvij[i][j].mult(q))[3];
-            
-            // d2
-            dd_dvij[1][i][j][0] = (dq_dvij[i][j].mult(q))[0]*q[1] + q[0]*(dq_dvij[i][j].mult(q))[1]
-                - (dq_dvij[i][j].mult(q))[2]*q[3] - q[2]*(dq_dvij[i][j].mult(q))[3];
-            
-            dd_dvij[1][i][j][1] = - q[0]*(dq_dvij[i][j].mult(q))[0] + q[1]*(dq_dvij[i][j].mult(q))[1] 
-                - q[2]*(dq_dvij[i][j].mult(q))[2] + q[3]*(dq_dvij[i][j].mult(q))[3];
-            
-            dd_dvij[1][i][j][2] = (dq_dvij[i][j].mult(q))[1]*q[2] + q[1]*(dq_dvij[i][j].mult(q))[2]
-                + (dq_dvij[i][j].mult(q))[0]*q[3] + q[0]*(dq_dvij[i][j].mult(q))[3];
-            
-            // d3
-            dd_dvij[2][i][j][0] = (dq_dvij[i][j].mult(q))[0]*q[2] + q[0]*(dq_dvij[i][j].mult(q))[2]
-                + (dq_dvij[i][j].mult(q))[1]*q[3] + q[1]*(dq_dvij[i][j].mult(q))[3];
-            
-            dd_dvij[2][i][j][1] = (dq_dvij[i][j].mult(q))[1]*q[2] + q[1]*(dq_dvij[i][j].mult(q))[2]
-                - (dq_dvij[i][j].mult(q))[0]*q[3] - q[0]*(dq_dvij[i][j].mult(q))[3];
-            
-            dd_dvij[2][i][j][2] = - q[0]*(dq_dvij[i][j].mult(q))[0] - q[1]*(dq_dvij[i][j].mult(q))[1] 
-                + q[2]*(dq_dvij[i][j].mult(q))[2] + q[3]*(dq_dvij[i][j].mult(q))[3];
-            
-            
-            dd_dvij[0][i][j] *= 2;
-            dd_dvij[1][i][j] *= 2;
-            dd_dvij[2][i][j] *= 2;
-            
-        }
+    for (int j=0; j<3; j++) {
+        
+        // d1
+        dd_dvj[0][j][0] = q[0]*(dq_dvj[j].mult(q))[0] - q[1]*(dq_dvj[j].mult(q))[1] 
+            - q[2]*(dq_dvj[j].mult(q))[2] + q[3]*(dq_dvj[j].mult(q))[3];
+        
+        dd_dvj[0][j][1] = (dq_dvj[j].mult(q))[0]*q[1] + q[0]*(dq_dvj[j].mult(q))[1]
+            + (dq_dvj[j].mult(q))[2]*q[3] + q[2]*(dq_dvj[j].mult(q))[3];
+        
+        dd_dvj[0][j][2] = (dq_dvj[j].mult(q))[0]*q[2] + q[0]*(dq_dvj[j].mult(q))[2]
+            - (dq_dvj[j].mult(q))[1]*q[3] - q[1]*(dq_dvj[j].mult(q))[3];
+        
+        // d2
+        dd_dvj[1][j][0] = (dq_dvj[j].mult(q))[0]*q[1] + q[0]*(dq_dvj[j].mult(q))[1]
+            - (dq_dvj[j].mult(q))[2]*q[3] - q[2]*(dq_dvj[j].mult(q))[3];
+        
+        dd_dvj[1][j][1] = - q[0]*(dq_dvj[j].mult(q))[0] + q[1]*(dq_dvj[j].mult(q))[1] 
+            - q[2]*(dq_dvj[j].mult(q))[2] + q[3]*(dq_dvj[j].mult(q))[3];
+        
+        dd_dvj[1][j][2] = (dq_dvj[j].mult(q))[1]*q[2] + q[1]*(dq_dvj[j].mult(q))[2]
+            + (dq_dvj[j].mult(q))[0]*q[3] + q[0]*(dq_dvj[j].mult(q))[3];
+        
+        // d3
+        dd_dvj[2][j][0] = (dq_dvj[j].mult(q))[0]*q[2] + q[0]*(dq_dvj[j].mult(q))[2]
+            + (dq_dvj[j].mult(q))[1]*q[3] + q[1]*(dq_dvj[j].mult(q))[3];
+        
+        dd_dvj[2][j][1] = (dq_dvj[j].mult(q))[1]*q[2] + q[1]*(dq_dvj[j].mult(q))[2]
+            - (dq_dvj[j].mult(q))[0]*q[3] - q[0]*(dq_dvj[j].mult(q))[3];
+        
+        dd_dvj[2][j][2] = - q[0]*(dq_dvj[j].mult(q))[0] - q[1]*(dq_dvj[j].mult(q))[1] 
+            + q[2]*(dq_dvj[j].mult(q))[2] + q[3]*(dq_dvj[j].mult(q))[3];
+        
+        
+        dd_dvj[0][j] *= 2;
+        dd_dvj[1][j] *= 2;
+        dd_dvj[2][j] *= 2;
         
     }
 
@@ -222,17 +216,17 @@ getLocalMatrix( EntityPointer &entity,
         Quaternion<double> hatq = Quaternion<double>::interpolate(localSolution[0].q, localSolution[1].q,quadPos[0]);
 
         // Contains \partial q / \partial v^i_j  at v = 0
-        FixedArray<FixedArray<Quaternion<double>,3>,2> dq_dvij;
+        FixedArray<Quaternion<double>,3> dq_dvj;
         Quaternion<double> dq_dvij_ds[2][3];
         for (int i=0; i<2; i++)
             for (int j=0; j<3; j++) {
                 
                 for (int m=0; m<3; m++) {
-                    dq_dvij[i][j][m]    = (j==m) * 0.5 * shapeFunction[i];
+                    dq_dvj[j][m]    = (j==m) * 0.5;
                     dq_dvij_ds[i][j][m] = (j==m) * 0.5 * shapeGrad[i];
                 }
                 
-                dq_dvij[i][j][3]    = 0;
+                dq_dvj[j][3]    = 0;
                 dq_dvij_ds[i][j][3] = 0;
             }
 
@@ -263,8 +257,8 @@ getLocalMatrix( EntityPointer &entity,
         }        
         
         // Contains \parder d \parder v^i_j
-        FixedArray<FixedArray<FixedArray<FieldVector<double,3>, 3>, 2>, 3> dd_dvij;
-        getFirstDerivativesOfDirectors(hatq, dd_dvij, dq_dvij);
+        FixedArray<FixedArray<FieldVector<double,3>, 3>, 3> dd_dvj;
+        getFirstDerivativesOfDirectors(hatq, dd_dvj, dq_dvj);
 
         // Contains \parder {dm}{v^i_j}{v^k_l}
         FieldVector<double,3> dd_dvij_dvkl[3][2][3][2][3];
@@ -280,7 +274,8 @@ getLocalMatrix( EntityPointer &entity,
                         FieldMatrix<double,4,4> A;
                         for (int a=0; a<4; a++)
                             for (int b=0; b<4; b++) 
-                                A[a][b] = (dq_dvij[k][l].mult(hatq))[a] * (dq_dvij[i][j].mult(hatq))[b]
+                                A[a][b] = (dq_dvj[l].mult(hatq))[a] * (dq_dvj[j].mult(hatq))[b]
+                                    * shapeFunction[i] * shapeFunction[k]
                                     + hatq[a] * dq_dvij_dvkl[i][j][k][l].mult(hatq)[b];
                 
                         // d1
@@ -338,24 +333,30 @@ getLocalMatrix( EntityPointer &entity,
             for (int j=0; j<3; j++) {
                 
                 for (int m=0; m<3; m++) {
-//                     duCan_dvij[i][j][m]  = 2*(B(m, dq_dvij[i][j].mult(hatq))*hatq_s);
-//                     duCan_dvij[i][j][m] += 2*(B(m,hatq)*(dq_dvij_ds[i][j].mult(hatq) + dq_dvij[i][j].mult(hatq_s)));
-                    duCan_dvij[i][j][m]  = 2 * ( (dq_dvij[i][j].mult(hatq)).B(m)*hatq_s );
-                    duCan_dvij[i][j][m] += 2 * ( hatq.B(m)*(dq_dvij_ds[i][j].mult(hatq) + dq_dvij[i][j].mult(hatq_s)));
+                    duCan_dvij[i][j][m]  = 2 * ( (dq_dvj[j].mult(hatq)).B(m)*hatq_s ) * shapeFunction[i];
+                    Quaternion<double> tmp = dq_dvj[j];
+                    tmp *= shapeFunction[i];
+                    duCan_dvij[i][j][m] += 2 * ( hatq.B(m)*(dq_dvij_ds[i][j].mult(hatq) + tmp.mult(hatq_s)));
                 }
 
                 // Don't fuse the two loops, we need the complete duCan_dvij[i][j]
                 for (int m=0; m<3; m++)
-                    duLocal_dvij[i][j][m] = duCan_dvij[i][j] * hatq.director(m) + darbouxCan*dd_dvij[m][i][j];
+                    duLocal_dvij[i][j][m] = duCan_dvij[i][j] * hatq.director(m) + darbouxCan*dd_dvj[m][j]*shapeFunction[i];
 
                 for (int k=0; k<2; k++) {
 
                     for (int l=0; l<3; l++) {
 
+                        Quaternion<double> tmp_ij = dq_dvj[j];
+                        Quaternion<double> tmp_kl = dq_dvj[l];
+
+                        tmp_ij *= shapeFunction[i];
+                        tmp_kl *= shapeFunction[k];
+
                         for (int m=0; m<3; m++)
                             duCan_dvij_dvkl[i][j][k][l] = 2 * ( (dq_dvij_dvkl[i][j][k][l].mult(hatq)).B(m) * hatq_s)
-                                + 2 * ( (dq_dvij[i][j].mult(hatq)).B(m) * (dq_dvij_ds[k][l].mult(hatq) + dq_dvij[k][l].mult(hatq_s)))
-                                + 2 * ( (dq_dvij[k][l].mult(hatq)).B(m) * (dq_dvij_ds[i][j].mult(hatq) + dq_dvij[i][j].mult(hatq_s)))
+                                + 2 * ( (tmp_ij.mult(hatq)).B(m) * (dq_dvij_ds[k][l].mult(hatq) + tmp_kl.mult(hatq_s)))
+                                + 2 * ( (tmp_kl.mult(hatq)).B(m) * (dq_dvij_ds[i][j].mult(hatq) + tmp_ij.mult(hatq_s)))
                                 + 2 * ( hatq.B(m) * (dq_dvij_dvkl_ds[i][j][k][l].mult(hatq) + dq_dvij_dvkl[i][j][k][l].mult(hatq_s)));
 
                     }
@@ -389,8 +390,8 @@ getLocalMatrix( EntityPointer &entity,
 
                             // \partial W^2 \partial v^i_j \partial r^k_l
                             localMat[i][k][j][l+3] += weight
-                                * ( A_[m] * shapeGrad[k]*hatq.director(m)[l]*(r_s*dd_dvij[m][i][j])
-                                    + A_[m] * (strain[m] - referenceStrain[m]) * shapeGrad[k] * dd_dvij[m][i][j][l]);
+                                * ( A_[m] * shapeGrad[k]*hatq.director(m)[l]*(r_s*dd_dvj[m][j] * shapeFunction[i])
+                                    + A_[m] * (strain[m] - referenceStrain[m]) * shapeGrad[k] * dd_dvj[m][j][l]*shapeFunction[i]);
 
                             // This is programmed stupidly.  To ensure the symmetry it is enough to make
                             // the following assignment once and not for each quadrature point
@@ -398,7 +399,7 @@ getLocalMatrix( EntityPointer &entity,
 
                             // \partial W^2 \partial v^i_j \partial v^k_l
                             localMat[i][k][j+3][l+3] += weight
-                                * (  A_[m] * (r_s * dd_dvij[m][k][l]) * (r_s * dd_dvij[m][i][j])
+                                * (  A_[m] * (r_s * dd_dvj[m][l]*shapeFunction[k]) * (r_s * dd_dvj[m][j]*shapeFunction[i])
                                      + A_[m] * (strain[m] - referenceStrain[m]) * (r_s * dd_dvij_dvkl[m][i][j][k][l]) );
 
                             // ////////////////////////////////////////////
@@ -408,11 +409,11 @@ getLocalMatrix( EntityPointer &entity,
                             // \partial W^2 \partial v^i_j \partial v^k_l
                             // All other derivatives are zero
 
-                            double sum = duLocal_dvij[k][l][m] * (duCan_dvij[i][j] * hatq.director(m) + darbouxCan*dd_dvij[m][i][j]);
+                            double sum = duLocal_dvij[k][l][m] * (duCan_dvij[i][j] * hatq.director(m) + darbouxCan*dd_dvj[m][j]*shapeFunction[i]);
                             
                             sum += (strain[m+3] - referenceStrain[m+3]) * (duCan_dvij_dvkl[i][j][k][l] * hatq.director(m)
-                                                                           + duCan_dvij[i][j] * dd_dvij[m][k][l]
-                                                                           + duCan_dvij[k][l] * dd_dvij[m][i][j]
+                                                                           + duCan_dvij[i][j] * dd_dvj[m][l] * shapeFunction[k]
+                                                                           + duCan_dvij[k][l] * dd_dvj[m][j] * shapeFunction[i]
                                                                            + darbouxCan * dd_dvij_dvkl[m][i][j][k][l]);
                        
                             localMat[i][k][j+3][l+3] += weight *K_[m] * sum;
@@ -522,24 +523,24 @@ assembleGradient(const std::vector<Configuration>& sol,
             FieldVector<double,blocksize> referenceStrain = getStrain(referenceConfiguration_, it, quadPos);
 
             // Contains \partial q / \partial v^i_j  at v = 0
-            FixedArray<FixedArray<Quaternion<double>,3>,2> dq_dvij;
+            FixedArray<Quaternion<double>,3> dq_dvj;
 
             Quaternion<double> dq_dvij_ds[2][3];
             for (int i=0; i<2; i++)
                 for (int j=0; j<3; j++) {
 
                     for (int m=0; m<3; m++) {
-                        dq_dvij[i][j][m]    = (j==m) * 0.5 * shapeFunction[i];
+                        dq_dvj[j][m]    = (j==m) * 0.5;
                         dq_dvij_ds[i][j][m] = (j==m) * 0.5 * shapeGrad[i];
                     }
 
-                    dq_dvij[i][j][3]    = 0;
+                    dq_dvj[j][3]    = 0;
                     dq_dvij_ds[i][j][3] = 0;
                 }
 
             // dd_dvij[k][i][j] = \parder {d_k} {v^i_j}
-            FixedArray<FixedArray<FixedArray<FieldVector<double,3>, 3>, 2>, 3> dd_dvij;
-            getFirstDerivativesOfDirectors(hatq, dd_dvij, dq_dvij);
+            FixedArray<FixedArray<FieldVector<double,3>, 3>, 3> dd_dvj;
+            getFirstDerivativesOfDirectors(hatq, dd_dvj, dq_dvj);
 
             
             // /////////////////////////////////////////////
@@ -568,9 +569,9 @@ assembleGradient(const std::vector<Configuration>& sol,
                 for (int j=0; j<3; j++) {
 
                     grad[globalDof][3+j] += weight 
-                        * (  (A_[0] * (strain[0] - referenceStrain[0]) * (r_s*dd_dvij[0][i][j]))
-                           + (A_[1] * (strain[1] - referenceStrain[1]) * (r_s*dd_dvij[1][i][j]))
-                           + (A_[2] * (strain[2] - referenceStrain[2]) * (r_s*dd_dvij[2][i][j])));
+                        * (  (A_[0] * (strain[0] - referenceStrain[0]) * (r_s*dd_dvj[0][j]*shapeFunction[i]))
+                           + (A_[1] * (strain[1] - referenceStrain[1]) * (r_s*dd_dvj[1][j]*shapeFunction[i]))
+                           + (A_[2] * (strain[2] - referenceStrain[2]) * (r_s*dd_dvj[2][j]*shapeFunction[i])));
 
                 }
 
@@ -583,10 +584,11 @@ assembleGradient(const std::vector<Configuration>& sol,
 
                     FieldVector<double,3> du_dvij;
                     for (int m=0; m<3; m++) {
-//                         du_dvij[m] = B(m, dq_dvij[i][j].mult(hatq)) * hatq_s;
-//                         du_dvij[m] += B(m, hatq) * (dq_dvij_ds[i][j].mult(hatq) + dq_dvij[i][j].mult(hatq_s));
-                        du_dvij[m] = (dq_dvij[i][j].mult(hatq)).B(m) * hatq_s;
-                        du_dvij[m] += hatq.B(m) * (dq_dvij_ds[i][j].mult(hatq) + dq_dvij[i][j].mult(hatq_s));
+                        du_dvij[m] = (dq_dvj[j].mult(hatq)).B(m) * hatq_s;
+                        du_dvij[m] *= shapeFunction[i];
+                        Quaternion<double> tmp = dq_dvj[j];
+                        tmp *= shapeFunction[i];
+                        du_dvij[m] += hatq.B(m) * (dq_dvij_ds[i][j].mult(hatq) + tmp.mult(hatq_s));
                     }
                     du_dvij *= 2;
 
@@ -594,7 +596,7 @@ assembleGradient(const std::vector<Configuration>& sol,
                     for (int m=0; m<3; m++) {
 
                         double addend1 = du_dvij * hatq.director(m);
-                        double addend2 = darbouxCan * dd_dvij[m][i][j];
+                        double addend2 = darbouxCan * dd_dvj[m][j] * shapeFunction[i];
 
                         grad[globalDof][3+j] += weight * K_[m] 
                             * (strain[m+3]-referenceStrain[m+3]) * (addend1 + addend2);
diff --git a/src/rodassembler.hh b/src/rodassembler.hh
index 1f89df15fcffbcac524019bf7dd4e487d24953a1..22ab3991a477b5af6177e4d03b718a186627ce15 100644
--- a/src/rodassembler.hh
+++ b/src/rodassembler.hh
@@ -155,9 +155,6 @@ namespace Dune
         static FieldVector<T,3> darbouxCanonical(const Quaternion<T>& q, const FieldVector<T,4>& q_s) 
         {
             FieldVector<double,3> uCanonical;  // The Darboux vector
-//             uCanonical[0] = 2 * ( q[3]*q_s[0] + q[2]*q_s[1] - q[1]*q_s[2] - q[0]*q_s[3]);
-//             uCanonical[1] = 2 * (-q[2]*q_s[0] + q[3]*q_s[1] + q[0]*q_s[2] - q[1]*q_s[3]);
-//             uCanonical[2] = 2 * ( q[1]*q_s[0] - q[0]*q_s[1] + q[3]*q_s[2] - q[2]*q_s[3]);
 
             uCanonical[0] = 2 * (q.B(0) * q_s);
             uCanonical[1] = 2 * (q.B(1) * q_s);
@@ -167,8 +164,8 @@ namespace Dune
         }
         
         static void getFirstDerivativesOfDirectors(const Quaternion<double>& q, 
-                                                   Dune::FixedArray<Dune::FixedArray<Dune::FixedArray<Dune::FieldVector<double,3>, 3>, 2>, 3>& dd_dvij,
-                                                   const Dune::FixedArray<Dune::FixedArray<Quaternion<double>, 3>, 2>& dq_dvij);
+                                                   Dune::FixedArray<Dune::FixedArray<Dune::FieldVector<double,3>, 3>, 3>& dd_dvj,
+                                                   const Dune::FixedArray<Quaternion<double>, 3>& dq_dvj);
 
     }; // end class