diff --git a/src/Makefile.am b/src/Makefile.am
index 38eb13a84681803ea6f508bcb048b66888d68c9e..3a4555856fae0c9d5d9c2f1808d446f0d5d37f46 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,6 +11,6 @@ srcinclude_HEADERS = averagedistanceassembler.hh localgeodesicfefunction.hh \
                      geodesicdifference.hh makestraightrod.hh rigidbodymotion.hh \
                      rotation.hh geodesicfeassembler.hh maxnormtrustregion.hh \
                      rodassembler.hh svd.hh harmonicenergystiffness.hh \
-                     planarrodassembler.hh  rodlocalstiffness.hh  targetspacertrsolver.hh
+                     rodlocalstiffness.hh  targetspacertrsolver.hh
 
 include $(top_srcdir)/am/global-rules
diff --git a/src/planarrodassembler.cc b/src/planarrodassembler.cc
deleted file mode 100644
index a3ee6a92377eff6e1af14e5d18e38fd199ff2483..0000000000000000000000000000000000000000
--- a/src/planarrodassembler.cc
+++ /dev/null
@@ -1,437 +0,0 @@
-#include <dune/istl/bcrsmatrix.hh>
-#include <dune/common/fmatrix.hh>
-#include <dune/istl/matrixindexset.hh>
-#include <dune/istl/matrix.hh>
-
-#include <dune/grid/common/quadraturerules.hh>
-
-#include <dune/localfunctions/lagrange/p1.hh>
-
-template <class GridType, int polOrd>
-void Dune::PlanarRodAssembler<GridType, polOrd>::
-getNeighborsPerVertex(MatrixIndexSet& nb) const
-{
-    const int gridDim = GridType::dimension;
-    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
-    
-    int i, j;
-    int n = grid_->size(grid_->maxLevel(), gridDim);
-    
-    nb.resize(n, n);
-    
-    ElementIterator it    = grid_->template lbegin<0>( grid_->maxLevel() );
-    ElementIterator endit = grid_->template lend<0>  ( grid_->maxLevel() );
-    
-    for (; it!=endit; ++it) {
-        
-        for (i=0; i<it->template count<gridDim>(); i++) {
-            
-            for (j=0; j<it->template count<gridDim>(); j++) {
-                
-                int iIdx = indexSet.subIndex(*it,i,gridDim);
-                int jIdx = indexSet.subIndex(*it,j,gridDim);
-                
-                nb.add(iIdx, jIdx);
-                
-            }
-            
-        }
-        
-    }
-    
-}
-
-template <class GridType, int polOrd>
-void Dune::PlanarRodAssembler<GridType, polOrd>::
-assembleMatrix(const std::vector<RigidBodyMotion<2> >& sol,
-               BCRSMatrix<MatrixBlock>& matrix)
-{
-    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
-
-    MatrixIndexSet neighborsPerVertex;
-    getNeighborsPerVertex(neighborsPerVertex);
-    
-    matrix = 0;
-    
-    ElementIterator it    = grid_->template lbegin<0>( grid_->maxLevel() );
-    ElementIterator endit = grid_->template lend<0> ( grid_->maxLevel() );
-
-    Matrix<MatrixBlock> mat;
-    
-    for( ; it != endit; ++it ) {
-        
-        const int numOfBaseFct = 2;  
-        
-        mat.setSize(numOfBaseFct, numOfBaseFct);
-
-        // Extract local solution
-        std::vector<RigidBodyMotion<2> > localSolution(numOfBaseFct);
-        
-        for (int i=0; i<numOfBaseFct; i++)
-            localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
-
-        // setup matrix 
-        getLocalMatrix( *it, localSolution, numOfBaseFct, mat);
-        
-        // Add element matrix to global stiffness matrix
-        for(int i=0; i<numOfBaseFct; i++) { 
-            
-            int row = indexSet.subIndex(*it,i,gridDim);
-
-            for (int j=0; j<numOfBaseFct; j++ ) {
-                
-                int col = indexSet.subIndex(*it,j,gridDim);
-                matrix[row][col] += mat[i][j];
-                
-            }
-        }
-
-    }
-    
-}
-
-
-
-
-
-
-template <class GridType, int polOrd>
-template <class MatrixType>
-void Dune::PlanarRodAssembler<GridType, polOrd>::
-getLocalMatrix( EntityType &entity, 
-                const std::vector<RigidBodyMotion<2> >& localSolution,
-                const int matSize, MatrixType& localMat) const
-{
-    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
-
-    /* ndof is the number of vectors of the element */
-    int ndof = matSize;
-
-    for (int i=0; i<matSize; i++)
-        for (int j=0; j<matSize; j++)
-            localMat[i][j] = 0;
-    
-    P1LocalFiniteElement<double,double,gridDim> localFiniteElement;
-
-    // Get quadrature rule
-    const QuadratureRule<double, gridDim>& quad = QuadratureRules<double, gridDim>::rule(entity.type(), polOrd);
-    
-    /* Loop over all integration points */
-    for (int ip=0; ip<quad.size(); ip++) {
-        
-        // Local position of the quadrature point
-        const FieldVector<double,gridDim>& quadPos = quad[ip].position();
-
-        // calc Jacobian inverse before integration element is evaluated 
-        const FieldMatrix<double,gridDim,gridDim>& inv = entity.geometry().jacobianInverseTransposed(quadPos);
-        const double integrationElement = entity.geometry().integrationElement(quadPos);
-        
-        /* Compute the weight of the current integration point */
-        double weight = quad[ip].weight() * integrationElement;
-        
-        /**********************************************/
-        /* compute gradients of the shape functions   */
-        /**********************************************/
-        std::vector<FieldMatrix<double,1,gridDim> > referenceElementGradients(ndof);
-        localFiniteElement.localBasis().evaluateJacobian(quadPos,referenceElementGradients);
-
-        std::vector<FieldVector<double,gridDim> > shapeGrad(ndof);
-        
-        // multiply with jacobian inverse 
-        for (int dof=0; dof<ndof; dof++)
-            inv.mv(referenceElementGradients[dof][0], shapeGrad[dof]);
-        
-        
-        std::vector<FieldVector<double,1> > shapeFunction;
-        localFiniteElement.localBasis().evaluateFunction(quadPos,shapeFunction);
-
-        // //////////////////////////////////
-        //   Interpolate
-        // //////////////////////////////////
-        
-        double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
-        double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
-
-        double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
-
-        for (int i=0; i<matSize; i++) {
-
-            for (int j=0; j<matSize; j++) {
-
-                // \partial J^2 / \partial x_i \partial x_j
-                localMat[i][j][0][0] += weight * shapeGrad[i][0] * shapeGrad[j][0]
-                    * (A1 * cos(theta) * cos(theta) + A3 * sin(theta) * sin(theta));
-
-                // \partial J^2 / \partial x_i \partial y_j
-                localMat[i][j][0][1] += weight * shapeGrad[i][0] * shapeGrad[j][0]
-                    * (-A1 + A3) * sin(theta)* cos(theta);
-
-                // \partial J^2 / \partial x_i \partial theta_j
-                localMat[i][j][0][2] += weight * shapeGrad[i][0] * shapeFunction[j]
-                    * (-A1 * (x_s*sin(theta) + y_s*cos(theta)) * cos(theta)
-                       - A1* (x_s*cos(theta) - y_s*sin(theta)) * sin(theta)
-                       +A3 * (x_s*cos(theta) - y_s*sin(theta)) * sin(theta)
-                       +A3 * (x_s*sin(theta) + y_s*cos(theta) - 1) * cos(theta));
-
-                // \partial J^2 / \partial y_i \partial x_j
-                localMat[i][j][1][0] += weight * shapeGrad[i][0] * shapeGrad[j][0]
-                    * (-A1 * sin(theta)* cos(theta) + A3 * cos(theta) * sin(theta));
-
-                // \partial J^2 / \partial y_i \partial y_j
-                localMat[i][j][1][1] += weight * shapeGrad[i][0] * shapeGrad[j][0]
-                    * (A1 * sin(theta)*sin(theta) + A3 * cos(theta)*cos(theta));
-
-                // \partial J^2 / \partial y_i \partial theta_j
-                localMat[i][j][1][2] += weight * shapeGrad[i][0] * shapeFunction[j]
-                    * (A1  * (x_s * sin(theta) + y_s * cos(theta)) * sin(theta)
-                       -A1 * (x_s * cos(theta) - y_s * sin(theta)) * cos(theta)
-                       +A3 * (x_s * cos(theta) - y_s * sin(theta)) * cos(theta)
-                       -A3 * (x_s * sin(theta) + y_s * cos(theta) - 1) * sin(theta));
-
-                // \partial J^2 / \partial theta_i \partial x_j
-                localMat[i][j][2][0] += weight * shapeFunction[i] * shapeGrad[j][0]
-                    * (-A1 * (x_s*sin(theta) + y_s*cos(theta)) * cos(theta)
-                       - A1* (x_s*cos(theta) - y_s*sin(theta)) * sin(theta)
-                       +A3 * (x_s*cos(theta) - y_s*sin(theta)) * sin(theta)
-                       +A3 * (x_s*sin(theta) + y_s*cos(theta) - 1) * cos(theta));
-
-                // \partial J^2 / \partial theta_i \partial y_j
-                localMat[i][j][2][1] += weight * shapeFunction[i] * shapeGrad[j][0]
-                    * (A1  * (x_s * sin(theta) + y_s * cos(theta)) * sin(theta)
-                       -A1 * (x_s * cos(theta) - y_s * sin(theta)) * cos(theta)
-                       +A3 * (x_s * cos(theta) - y_s * sin(theta)) * cos(theta)
-                       -A3 * (x_s * sin(theta) + y_s * cos(theta) - 1) * sin(theta));
-
-                // \partial J^2 / \partial theta_i \partial theta_j
-                localMat[i][j][2][2] += weight * B * shapeGrad[i][0] * shapeGrad[j][0];
-                localMat[i][j][2][2] += weight * shapeFunction[i] * shapeFunction[j]
-                    * (+ A1 * (x_s*sin(theta) + y_s*cos(theta)) * (x_s*sin(theta) + y_s*cos(theta))
-                       + A1 * (x_s*cos(theta) - y_s*sin(theta)) * (-x_s*cos(theta)+ y_s*sin(theta))
-                       + A3 * (x_s*cos(theta) - y_s*sin(theta)) * (x_s*cos(theta) - y_s*sin(theta))
-                       - A3 * (x_s*sin(theta) + y_s*cos(theta) - 1) * (x_s*sin(theta) + y_s*cos(theta)));
-                                                
-
-
-            }
-        
-        }
-        
-        
-    }
-    
-#if 0
-    static int eleme = 0;
-    printf("********* Element %d **********\n", eleme++);
-    for (int row=0; row<matSize; row++) {
-        
-        for (int rcomp=0; rcomp<dim; rcomp++) {
-            
-            for (int col=0; col<matSize; col++) {
-                
-                for (int ccomp=0; ccomp<dim; ccomp++)
-                    std::cout << mat[row][col][rcomp][ccomp] << "  ";
-                
-                std::cout << "    ";
-                
-            }
-            
-            std::cout << std::endl;
-            
-        }
-        
-        std::cout << std::endl;
-        
-    }
-    exit(0);
-#endif
-    
-}
-
-template <class GridType, int polOrd>
-void Dune::PlanarRodAssembler<GridType, polOrd>::
-assembleGradient(const std::vector<RigidBodyMotion<2> >& sol,
-                 BlockVector<FieldVector<double, blocksize> >& grad) const
-{
-    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
-    const int maxlevel = grid_->maxLevel();
-
-    if (sol.size()!=grid_->size(maxlevel, gridDim))
-        DUNE_THROW(Exception, "Solution vector doesn't match the grid!");
-
-    grad.resize(sol.size());
-    grad = 0;
-
-    ElementIterator it    = grid_->template lbegin<0>(maxlevel);
-    ElementIterator endIt = grid_->template lend<0>(maxlevel);
-
-    // Loop over all elements
-    for (; it!=endIt; ++it) {
-
-        // Extract local solution on this element
-        P1LocalFiniteElement<double,double,gridDim> localFiniteElement;
-        const int numOfBaseFct = localFiniteElement.localBasis().size();  
-        
-        RigidBodyMotion<2> localSolution[numOfBaseFct];
-        
-        for (int i=0; i<numOfBaseFct; i++)
-            localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
-
-        // Get quadrature rule
-        const QuadratureRule<double, gridDim>& quad = QuadratureRules<double, gridDim>::rule(it->type(), polOrd);
-
-        for (int pt=0; pt<quad.size(); pt++) {
-
-            // Local position of the quadrature point
-            const FieldVector<double,gridDim>& quadPos = quad[pt].position();
-            
-            const FieldMatrix<double,1,1>& inv = it->geometry().jacobianInverseTransposed(quadPos);
-            const double integrationElement = it->geometry().integrationElement(quadPos);
-        
-            double weight = quad[pt].weight() * integrationElement;
-            
-            /**********************************************/
-            /* compute gradients of the shape functions   */
-            /**********************************************/
-            std::vector<FieldMatrix<double,1,gridDim> > referenceElementGradients(numOfBaseFct);
-            localFiniteElement.localBasis().evaluateJacobian(quadPos,referenceElementGradients);
-            
-            std::vector<FieldVector<double,gridDim> > shapeGrad(numOfBaseFct);
-            
-            // multiply with jacobian inverse 
-            for (int dof=0; dof<numOfBaseFct; dof++)
-                inv.mv(referenceElementGradients[dof][0], shapeGrad[dof]);
-
-            // Get the values of the shape functions
-            std::vector<FieldVector<double,1> > shapeFunction;
-            localFiniteElement.localBasis().evaluateFunction(quadPos,shapeFunction);
-
-            // //////////////////////////////////
-            //   Interpolate
-            // //////////////////////////////////
-
-            double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
-            double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
-            double theta_s = localSolution[0].q.angle_*shapeGrad[0][0] + localSolution[1].q.angle_*shapeGrad[1][0];
-
-            double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
-
-            // /////////////////////////////////////////////
-            //   Sum it all up
-            // /////////////////////////////////////////////
-
-            double partA1 = A1 * (x_s * cos(theta) - y_s * sin(theta));
-            double partA3 = A3 * (x_s * sin(theta) + y_s * cos(theta) - 1);
-
-            for (int dof=0; dof<numOfBaseFct; dof++) {
-
-                int globalDof = indexSet.subIndex(*it,dof,gridDim);
-
-                //printf("globalDof: %d   partA1: %g   partA3: %g\n", globalDof, partA1, partA3);
-
-                // \partial J / \partial x^i
-                grad[globalDof][0] += weight * (partA1 * cos(theta) + partA3 * sin(theta)) * shapeGrad[dof][0];
-
-                // \partial J / \partial y^i
-                grad[globalDof][1] += weight * (-partA1 * sin(theta) + partA3 * cos(theta)) * shapeGrad[dof][0];
-
-                // \partial J / \partial \theta^i
-                grad[globalDof][2] += weight * (B * theta_s * shapeGrad[dof][0]
-                                               + partA1 * (-x_s * sin(theta) - y_s * cos(theta)) * shapeFunction[dof]
-                                               + partA3 * ( x_s * cos(theta) - y_s * sin(theta)) * shapeFunction[dof]);
-
-            }
-
-
-        }
-
-    }
-
-}
-
-
-template <class GridType, int polOrd>
-double Dune::PlanarRodAssembler<GridType, polOrd>::
-computeEnergy(const std::vector<RigidBodyMotion<2> >& sol) const
-{
-    const int maxlevel = grid_->maxLevel();
-    double energy = 0;
-
-    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(maxlevel);
-
-    if (sol.size()!=grid_->size(maxlevel, gridDim))
-        DUNE_THROW(Exception, "Solution vector doesn't match the grid!");
-
-    ElementIterator it    = grid_->template lbegin<0>(maxlevel);
-    ElementIterator endIt = grid_->template lend<0>(maxlevel);
-
-    // Loop over all elements
-    for (; it!=endIt; ++it) {
-
-        // Extract local solution on this element
-        P1LocalFiniteElement<double,double,gridDim> localFiniteElement;
-
-        int numOfBaseFct = localFiniteElement.localBasis().size();
-
-        RigidBodyMotion<2> localSolution[numOfBaseFct];
-        
-        for (int i=0; i<numOfBaseFct; i++)
-            localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
-
-        // Get quadrature rule
-        const QuadratureRule<double, gridDim>& quad = QuadratureRules<double, gridDim>::rule(it->type(), polOrd);
-
-        for (int pt=0; pt<quad.size(); pt++) {
-
-            // Local position of the quadrature point
-            const FieldVector<double,gridDim>& quadPos = quad[pt].position();
-            
-            const FieldMatrix<double,1,1>& inv = it->geometry().jacobianInverseTransposed(quadPos);
-            const double integrationElement = it->geometry().integrationElement(quadPos);
-        
-            double weight = quad[pt].weight() * integrationElement;
-            
-            /**********************************************/
-            /* compute gradients of the shape functions   */
-            /**********************************************/
-            std::vector<FieldMatrix<double,1,gridDim> > referenceElementGradients(numOfBaseFct);
-            localFiniteElement.localBasis().evaluateJacobian(quadPos,referenceElementGradients);
-            
-            std::vector<FieldVector<double,gridDim> > shapeGrad(numOfBaseFct);
-            
-            // multiply with jacobian inverse 
-            for (int dof=0; dof<numOfBaseFct; dof++)
-                inv.mv(referenceElementGradients[dof][0], shapeGrad[dof]);
-
-            // Get the value of the shape functions
-            std::vector<FieldVector<double,1> > shapeFunction;
-            localFiniteElement.localBasis().evaluateFunction(quadPos,shapeFunction);
-
-            // //////////////////////////////////
-            //   Interpolate
-            // //////////////////////////////////
-
-            double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
-            double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
-            double theta_s = localSolution[0].q.angle_*shapeGrad[0][0] + localSolution[1].q.angle_*shapeGrad[1][0];
-
-            double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
-
-            // /////////////////////////////////////////////
-            //   Sum it all up
-            // /////////////////////////////////////////////
-
-            double partA1 = x_s * cos(theta) - y_s * sin(theta);
-            double partA3 = x_s * sin(theta) + y_s * cos(theta) - 1;
-
-
-            energy += 0.5 * weight * (B * theta_s * theta_s
-                                      + A1 * partA1 * partA1
-                                      + A3 * partA3 * partA3);
-
-        }
-
-    }
-
-    return energy;
-
-}
diff --git a/src/planarrodassembler.hh b/src/planarrodassembler.hh
deleted file mode 100644
index 20bf1a199aec3b04878a1936a41d013666717cf0..0000000000000000000000000000000000000000
--- a/src/planarrodassembler.hh
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef DUNE_PLANAR_ROD_ASSEMBLER_HH
-#define DUNE_PLANAR_ROD_ASSEMBLER_HH
-
-#include <dune/common/fmatrix.hh>
-
-#include <dune/istl/bcrsmatrix.hh>
-#include <dune/istl/matrixindexset.hh>
-#include <dune/istl/matrix.hh>
-
-#include "rigidbodymotion.hh"
-
-namespace Dune 
-{
-
-    /** \brief The FEM operator for an extensible, shearable rod
-     */
-    template <class GridType, int polOrd>
-    class PlanarRodAssembler {
-        
-        typedef typename GridType::template Codim<0>::Entity EntityType;
-        typedef typename GridType::template Codim<0>::LevelIterator ElementIterator;
-
-        //! Dimension of the grid.  This needs to be one!
-        enum { gridDim = GridType::dimension };
-
-        enum { elementOrder = 1};
-
-        //! Each block is x, y, theta
-        enum { blocksize = 3 };
-        
-        //!
-        typedef FieldMatrix<double, blocksize, blocksize> MatrixBlock;
-        
-        const GridType* grid_; 
-        
-        /** \brief Material constants */
-        double B;
-        double A1;
-        double A3;
-
-    public:
-        
-        //! ???
-        PlanarRodAssembler(const GridType &grid) : 
-            grid_(&grid)
-        { 
-            B = 1;
-            A1 = 1;
-            A3 = 1;
-        }
-
-        ~PlanarRodAssembler() {}
-
-        void setParameters(double b, double a1, double a3) {
-            B  = b;
-            A1 = a1;
-            A3 = a3;
-        }
-
-        /** \brief Assemble the tangent stiffness matrix and the right hand side
-         */
-        void assembleMatrix(const std::vector<RigidBodyMotion<2> >& sol,
-                            BCRSMatrix<MatrixBlock>& matrix);
-        
-        void assembleGradient(const std::vector<RigidBodyMotion<2> >& sol,
-                              BlockVector<FieldVector<double, blocksize> >& grad) const;
-
-        /** \brief Compute the energy of a deformation state */
-        double computeEnergy(const std::vector<RigidBodyMotion<2> >& sol) const;
-
-        void getNeighborsPerVertex(MatrixIndexSet& nb) const;
-        
-    protected:
-
-        /** \brief Compute the element tangent stiffness matrix  */
-        template <class MatrixType>
-        void getLocalMatrix( EntityType &entity, 
-                             const std::vector<RigidBodyMotion<2> >& localSolution, 
-                             const int matSize, MatrixType& mat) const;
-
-        
-        
-        
-        
-        
-        
-    }; // end class
-    
-} // end namespace 
-
-#include "planarrodassembler.cc"
-
-#endif
-
diff --git a/src/rodassembler.cc b/src/rodassembler.cc
index 4687812c31b94f189b6eea94e9068b770a18f035..47c1d20b563efc5587d9dee07707c95b57c0e622 100644
--- a/src/rodassembler.cc
+++ b/src/rodassembler.cc
@@ -6,6 +6,7 @@
 #include <dune/grid/common/quadraturerules.hh>
 
 #include <dune/disc/shapefunctions/lagrangeshapefunctions.hh>
+#include <dune/localfunctions/lagrange/p1.hh>
 
 #include "src/rodlocalstiffness.hh"
 
@@ -251,3 +252,431 @@ getResultantForce(const BoundaryPatchBase<PatchGridView>& boundary,
     return canonicalStress;
 }
 
+
+template <class GridType, int polOrd>
+void PlanarRodAssembler<GridType, polOrd>::getNeighborsPerVertex(Dune::MatrixIndexSet& nb) const
+{
+    const int gridDim = GridType::dimension;
+    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
+    
+    int i, j;
+    int n = grid_->size(grid_->maxLevel(), gridDim);
+    
+    nb.resize(n, n);
+    
+    ElementIterator it    = grid_->template lbegin<0>( grid_->maxLevel() );
+    ElementIterator endit = grid_->template lend<0>  ( grid_->maxLevel() );
+    
+    for (; it!=endit; ++it) {
+        
+        for (i=0; i<it->template count<gridDim>(); i++) {
+            
+            for (j=0; j<it->template count<gridDim>(); j++) {
+                
+                int iIdx = indexSet.subIndex(*it,i,gridDim);
+                int jIdx = indexSet.subIndex(*it,j,gridDim);
+                
+                nb.add(iIdx, jIdx);
+                
+            }
+            
+        }
+        
+    }
+    
+}
+
+template <class GridType, int polOrd>
+void PlanarRodAssembler<GridType, polOrd>::
+assembleMatrix(const std::vector<RigidBodyMotion<2> >& sol,
+               Dune::BCRSMatrix<MatrixBlock>& matrix)
+{
+    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
+
+    Dune::MatrixIndexSet neighborsPerVertex;
+    getNeighborsPerVertex(neighborsPerVertex);
+    
+    matrix = 0;
+    
+    ElementIterator it    = grid_->template lbegin<0>( grid_->maxLevel() );
+    ElementIterator endit = grid_->template lend<0> ( grid_->maxLevel() );
+
+    Dune::Matrix<MatrixBlock> mat;
+    
+    for( ; it != endit; ++it ) {
+        
+        const int numOfBaseFct = 2;  
+        
+        mat.setSize(numOfBaseFct, numOfBaseFct);
+
+        // Extract local solution
+        std::vector<RigidBodyMotion<2> > localSolution(numOfBaseFct);
+        
+        for (int i=0; i<numOfBaseFct; i++)
+            localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
+
+        // setup matrix 
+        getLocalMatrix( *it, localSolution, numOfBaseFct, mat);
+        
+        // Add element matrix to global stiffness matrix
+        for(int i=0; i<numOfBaseFct; i++) { 
+            
+            int row = indexSet.subIndex(*it,i,gridDim);
+
+            for (int j=0; j<numOfBaseFct; j++ ) {
+                
+                int col = indexSet.subIndex(*it,j,gridDim);
+                matrix[row][col] += mat[i][j];
+                
+            }
+        }
+
+    }
+    
+}
+
+
+
+
+
+
+template <class GridType, int polOrd>
+template <class MatrixType>
+void PlanarRodAssembler<GridType, polOrd>::
+getLocalMatrix( EntityType &entity, 
+                const std::vector<RigidBodyMotion<2> >& localSolution,
+                const int matSize, MatrixType& localMat) const
+{
+    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
+
+    /* ndof is the number of vectors of the element */
+    int ndof = matSize;
+
+    for (int i=0; i<matSize; i++)
+        for (int j=0; j<matSize; j++)
+            localMat[i][j] = 0;
+    
+    Dune::P1LocalFiniteElement<double,double,gridDim> localFiniteElement;
+
+    // Get quadrature rule
+    const Dune::QuadratureRule<double, gridDim>& quad = Dune::QuadratureRules<double, gridDim>::rule(entity.type(), polOrd);
+    
+    /* Loop over all integration points */
+    for (int ip=0; ip<quad.size(); ip++) {
+        
+        // Local position of the quadrature point
+        const Dune::FieldVector<double,gridDim>& quadPos = quad[ip].position();
+
+        // calc Jacobian inverse before integration element is evaluated 
+        const Dune::FieldMatrix<double,gridDim,gridDim>& inv = entity.geometry().jacobianInverseTransposed(quadPos);
+        const double integrationElement = entity.geometry().integrationElement(quadPos);
+        
+        /* Compute the weight of the current integration point */
+        double weight = quad[ip].weight() * integrationElement;
+        
+        /**********************************************/
+        /* compute gradients of the shape functions   */
+        /**********************************************/
+        std::vector<Dune::FieldMatrix<double,1,gridDim> > referenceElementGradients(ndof);
+        localFiniteElement.localBasis().evaluateJacobian(quadPos,referenceElementGradients);
+
+        std::vector<Dune::FieldVector<double,gridDim> > shapeGrad(ndof);
+        
+        // multiply with jacobian inverse 
+        for (int dof=0; dof<ndof; dof++)
+            inv.mv(referenceElementGradients[dof][0], shapeGrad[dof]);
+        
+        
+        std::vector<Dune::FieldVector<double,1> > shapeFunction;
+        localFiniteElement.localBasis().evaluateFunction(quadPos,shapeFunction);
+
+        // //////////////////////////////////
+        //   Interpolate
+        // //////////////////////////////////
+        
+        double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
+        double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
+
+        double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
+
+        for (int i=0; i<matSize; i++) {
+
+            for (int j=0; j<matSize; j++) {
+
+                // \partial J^2 / \partial x_i \partial x_j
+                localMat[i][j][0][0] += weight * shapeGrad[i][0] * shapeGrad[j][0]
+                    * (A1 * cos(theta) * cos(theta) + A3 * sin(theta) * sin(theta));
+
+                // \partial J^2 / \partial x_i \partial y_j
+                localMat[i][j][0][1] += weight * shapeGrad[i][0] * shapeGrad[j][0]
+                    * (-A1 + A3) * sin(theta)* cos(theta);
+
+                // \partial J^2 / \partial x_i \partial theta_j
+                localMat[i][j][0][2] += weight * shapeGrad[i][0] * shapeFunction[j]
+                    * (-A1 * (x_s*sin(theta) + y_s*cos(theta)) * cos(theta)
+                       - A1* (x_s*cos(theta) - y_s*sin(theta)) * sin(theta)
+                       +A3 * (x_s*cos(theta) - y_s*sin(theta)) * sin(theta)
+                       +A3 * (x_s*sin(theta) + y_s*cos(theta) - 1) * cos(theta));
+
+                // \partial J^2 / \partial y_i \partial x_j
+                localMat[i][j][1][0] += weight * shapeGrad[i][0] * shapeGrad[j][0]
+                    * (-A1 * sin(theta)* cos(theta) + A3 * cos(theta) * sin(theta));
+
+                // \partial J^2 / \partial y_i \partial y_j
+                localMat[i][j][1][1] += weight * shapeGrad[i][0] * shapeGrad[j][0]
+                    * (A1 * sin(theta)*sin(theta) + A3 * cos(theta)*cos(theta));
+
+                // \partial J^2 / \partial y_i \partial theta_j
+                localMat[i][j][1][2] += weight * shapeGrad[i][0] * shapeFunction[j]
+                    * (A1  * (x_s * sin(theta) + y_s * cos(theta)) * sin(theta)
+                       -A1 * (x_s * cos(theta) - y_s * sin(theta)) * cos(theta)
+                       +A3 * (x_s * cos(theta) - y_s * sin(theta)) * cos(theta)
+                       -A3 * (x_s * sin(theta) + y_s * cos(theta) - 1) * sin(theta));
+
+                // \partial J^2 / \partial theta_i \partial x_j
+                localMat[i][j][2][0] += weight * shapeFunction[i] * shapeGrad[j][0]
+                    * (-A1 * (x_s*sin(theta) + y_s*cos(theta)) * cos(theta)
+                       - A1* (x_s*cos(theta) - y_s*sin(theta)) * sin(theta)
+                       +A3 * (x_s*cos(theta) - y_s*sin(theta)) * sin(theta)
+                       +A3 * (x_s*sin(theta) + y_s*cos(theta) - 1) * cos(theta));
+
+                // \partial J^2 / \partial theta_i \partial y_j
+                localMat[i][j][2][1] += weight * shapeFunction[i] * shapeGrad[j][0]
+                    * (A1  * (x_s * sin(theta) + y_s * cos(theta)) * sin(theta)
+                       -A1 * (x_s * cos(theta) - y_s * sin(theta)) * cos(theta)
+                       +A3 * (x_s * cos(theta) - y_s * sin(theta)) * cos(theta)
+                       -A3 * (x_s * sin(theta) + y_s * cos(theta) - 1) * sin(theta));
+
+                // \partial J^2 / \partial theta_i \partial theta_j
+                localMat[i][j][2][2] += weight * B * shapeGrad[i][0] * shapeGrad[j][0];
+                localMat[i][j][2][2] += weight * shapeFunction[i] * shapeFunction[j]
+                    * (+ A1 * (x_s*sin(theta) + y_s*cos(theta)) * (x_s*sin(theta) + y_s*cos(theta))
+                       + A1 * (x_s*cos(theta) - y_s*sin(theta)) * (-x_s*cos(theta)+ y_s*sin(theta))
+                       + A3 * (x_s*cos(theta) - y_s*sin(theta)) * (x_s*cos(theta) - y_s*sin(theta))
+                       - A3 * (x_s*sin(theta) + y_s*cos(theta) - 1) * (x_s*sin(theta) + y_s*cos(theta)));
+                                                
+
+
+            }
+        
+        }
+        
+        
+    }
+    
+#if 0
+    static int eleme = 0;
+    printf("********* Element %d **********\n", eleme++);
+    for (int row=0; row<matSize; row++) {
+        
+        for (int rcomp=0; rcomp<dim; rcomp++) {
+            
+            for (int col=0; col<matSize; col++) {
+                
+                for (int ccomp=0; ccomp<dim; ccomp++)
+                    std::cout << mat[row][col][rcomp][ccomp] << "  ";
+                
+                std::cout << "    ";
+                
+            }
+            
+            std::cout << std::endl;
+            
+        }
+        
+        std::cout << std::endl;
+        
+    }
+    exit(0);
+#endif
+    
+}
+
+template <class GridType, int polOrd>
+void PlanarRodAssembler<GridType, polOrd>::
+assembleGradient(const std::vector<RigidBodyMotion<2> >& sol,
+                 Dune::BlockVector<Dune::FieldVector<double, blocksize> >& grad) const
+{
+    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
+    const int maxlevel = grid_->maxLevel();
+
+    if (sol.size()!=grid_->size(maxlevel, gridDim))
+        DUNE_THROW(Dune::Exception, "Solution vector doesn't match the grid!");
+
+    grad.resize(sol.size());
+    grad = 0;
+
+    ElementIterator it    = grid_->template lbegin<0>(maxlevel);
+    ElementIterator endIt = grid_->template lend<0>(maxlevel);
+
+    // Loop over all elements
+    for (; it!=endIt; ++it) {
+
+        // Extract local solution on this element
+        Dune::P1LocalFiniteElement<double,double,gridDim> localFiniteElement;
+        const int numOfBaseFct = localFiniteElement.localBasis().size();  
+        
+        RigidBodyMotion<2> localSolution[numOfBaseFct];
+        
+        for (int i=0; i<numOfBaseFct; i++)
+            localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
+
+        // Get quadrature rule
+        const Dune::QuadratureRule<double, gridDim>& quad = Dune::QuadratureRules<double, gridDim>::rule(it->type(), polOrd);
+
+        for (int pt=0; pt<quad.size(); pt++) {
+
+            // Local position of the quadrature point
+            const Dune::FieldVector<double,gridDim>& quadPos = quad[pt].position();
+            
+            const Dune::FieldMatrix<double,1,1>& inv = it->geometry().jacobianInverseTransposed(quadPos);
+            const double integrationElement = it->geometry().integrationElement(quadPos);
+        
+            double weight = quad[pt].weight() * integrationElement;
+            
+            /**********************************************/
+            /* compute gradients of the shape functions   */
+            /**********************************************/
+            std::vector<Dune::FieldMatrix<double,1,gridDim> > referenceElementGradients(numOfBaseFct);
+            localFiniteElement.localBasis().evaluateJacobian(quadPos,referenceElementGradients);
+            
+            std::vector<Dune::FieldVector<double,gridDim> > shapeGrad(numOfBaseFct);
+            
+            // multiply with jacobian inverse 
+            for (int dof=0; dof<numOfBaseFct; dof++)
+                inv.mv(referenceElementGradients[dof][0], shapeGrad[dof]);
+
+            // Get the values of the shape functions
+            std::vector<Dune::FieldVector<double,1> > shapeFunction;
+            localFiniteElement.localBasis().evaluateFunction(quadPos,shapeFunction);
+
+            // //////////////////////////////////
+            //   Interpolate
+            // //////////////////////////////////
+
+            double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
+            double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
+            double theta_s = localSolution[0].q.angle_*shapeGrad[0][0] + localSolution[1].q.angle_*shapeGrad[1][0];
+
+            double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
+
+            // /////////////////////////////////////////////
+            //   Sum it all up
+            // /////////////////////////////////////////////
+
+            double partA1 = A1 * (x_s * cos(theta) - y_s * sin(theta));
+            double partA3 = A3 * (x_s * sin(theta) + y_s * cos(theta) - 1);
+
+            for (int dof=0; dof<numOfBaseFct; dof++) {
+
+                int globalDof = indexSet.subIndex(*it,dof,gridDim);
+
+                //printf("globalDof: %d   partA1: %g   partA3: %g\n", globalDof, partA1, partA3);
+
+                // \partial J / \partial x^i
+                grad[globalDof][0] += weight * (partA1 * cos(theta) + partA3 * sin(theta)) * shapeGrad[dof][0];
+
+                // \partial J / \partial y^i
+                grad[globalDof][1] += weight * (-partA1 * sin(theta) + partA3 * cos(theta)) * shapeGrad[dof][0];
+
+                // \partial J / \partial \theta^i
+                grad[globalDof][2] += weight * (B * theta_s * shapeGrad[dof][0]
+                                               + partA1 * (-x_s * sin(theta) - y_s * cos(theta)) * shapeFunction[dof]
+                                               + partA3 * ( x_s * cos(theta) - y_s * sin(theta)) * shapeFunction[dof]);
+
+            }
+
+
+        }
+
+    }
+
+}
+
+
+template <class GridType, int polOrd>
+double PlanarRodAssembler<GridType, polOrd>::
+computeEnergy(const std::vector<RigidBodyMotion<2> >& sol) const
+{
+    const int maxlevel = grid_->maxLevel();
+    double energy = 0;
+
+    const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(maxlevel);
+
+    if (sol.size()!=grid_->size(maxlevel, gridDim))
+        DUNE_THROW(Dune::Exception, "Solution vector doesn't match the grid!");
+
+    ElementIterator it    = grid_->template lbegin<0>(maxlevel);
+    ElementIterator endIt = grid_->template lend<0>(maxlevel);
+
+    // Loop over all elements
+    for (; it!=endIt; ++it) {
+
+        // Extract local solution on this element
+        Dune::P1LocalFiniteElement<double,double,gridDim> localFiniteElement;
+
+        int numOfBaseFct = localFiniteElement.localBasis().size();
+
+        RigidBodyMotion<2> localSolution[numOfBaseFct];
+        
+        for (int i=0; i<numOfBaseFct; i++)
+            localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
+
+        // Get quadrature rule
+        const Dune::QuadratureRule<double, gridDim>& quad = Dune::QuadratureRules<double, gridDim>::rule(it->type(), polOrd);
+
+        for (int pt=0; pt<quad.size(); pt++) {
+
+            // Local position of the quadrature point
+            const Dune::FieldVector<double,gridDim>& quadPos = quad[pt].position();
+            
+            const Dune::FieldMatrix<double,1,1>& inv = it->geometry().jacobianInverseTransposed(quadPos);
+            const double integrationElement = it->geometry().integrationElement(quadPos);
+        
+            double weight = quad[pt].weight() * integrationElement;
+            
+            /**********************************************/
+            /* compute gradients of the shape functions   */
+            /**********************************************/
+            std::vector<Dune::FieldMatrix<double,1,gridDim> > referenceElementGradients(numOfBaseFct);
+            localFiniteElement.localBasis().evaluateJacobian(quadPos,referenceElementGradients);
+            
+            std::vector<Dune::FieldVector<double,gridDim> > shapeGrad(numOfBaseFct);
+            
+            // multiply with jacobian inverse 
+            for (int dof=0; dof<numOfBaseFct; dof++)
+                inv.mv(referenceElementGradients[dof][0], shapeGrad[dof]);
+
+            // Get the value of the shape functions
+            std::vector<Dune::FieldVector<double,1> > shapeFunction;
+            localFiniteElement.localBasis().evaluateFunction(quadPos,shapeFunction);
+
+            // //////////////////////////////////
+            //   Interpolate
+            // //////////////////////////////////
+
+            double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
+            double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
+            double theta_s = localSolution[0].q.angle_*shapeGrad[0][0] + localSolution[1].q.angle_*shapeGrad[1][0];
+
+            double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
+
+            // /////////////////////////////////////////////
+            //   Sum it all up
+            // /////////////////////////////////////////////
+
+            double partA1 = x_s * cos(theta) - y_s * sin(theta);
+            double partA3 = x_s * sin(theta) + y_s * cos(theta) - 1;
+
+
+            energy += 0.5 * weight * (B * theta_s * theta_s
+                                      + A1 * partA1 * partA1
+                                      + A3 * partA3 * partA3);
+
+        }
+
+    }
+
+    return energy;
+
+}
diff --git a/src/rodassembler.hh b/src/rodassembler.hh
index 8814c87c0af30d830732030db99b8f3be8fd208e..6f275383558f7c845f9172c9ed9c36961457cc67 100644
--- a/src/rodassembler.hh
+++ b/src/rodassembler.hh
@@ -103,6 +103,75 @@ class RodAssembler : public GeodesicFEAssembler<GridView, RigidBodyMotion<3> >
 
     }; // end class
 
+
+/** \brief The FEM operator for a 2D extensible, shearable rod
+ */
+template <class GridType, int polOrd>
+class PlanarRodAssembler {
+    
+    typedef typename GridType::template Codim<0>::Entity EntityType;
+    typedef typename GridType::template Codim<0>::LevelIterator ElementIterator;
+    
+    //! Dimension of the grid.  This needs to be one!
+    enum { gridDim = GridType::dimension };
+    
+    enum { elementOrder = 1};
+    
+    //! Each block is x, y, theta
+    enum { blocksize = 3 };
+    
+    //!
+    typedef Dune::FieldMatrix<double, blocksize, blocksize> MatrixBlock;
+    
+    const GridType* grid_; 
+    
+    /** \brief Material constants */
+    double B;
+    double A1;
+    double A3;
+    
+public:
+    
+    //! ???
+    PlanarRodAssembler(const GridType &grid) : 
+        grid_(&grid)
+    { 
+        B = 1;
+        A1 = 1;
+        A3 = 1;
+    }
+    
+    ~PlanarRodAssembler() {}
+    
+    void setParameters(double b, double a1, double a3) {
+        B  = b;
+        A1 = a1;
+        A3 = a3;
+    }
+    
+    /** \brief Assemble the tangent stiffness matrix and the right hand side
+     */
+    void assembleMatrix(const std::vector<RigidBodyMotion<2> >& sol,
+                        Dune::BCRSMatrix<MatrixBlock>& matrix);
+    
+    void assembleGradient(const std::vector<RigidBodyMotion<2> >& sol,
+                          Dune::BlockVector<Dune::FieldVector<double, blocksize> >& grad) const;
+    
+    /** \brief Compute the energy of a deformation state */
+    double computeEnergy(const std::vector<RigidBodyMotion<2> >& sol) const;
+    
+    void getNeighborsPerVertex(Dune::MatrixIndexSet& nb) const;
+    
+protected:
+    
+    /** \brief Compute the element tangent stiffness matrix  */
+    template <class MatrixType>
+    void getLocalMatrix( EntityType &entity, 
+                         const std::vector<RigidBodyMotion<2> >& localSolution, 
+                         const int matSize, MatrixType& mat) const;
+    
+}; // end class
+
 #include "rodassembler.cc"
 
 #endif