diff --git a/dune/gfe/coupling/rodcontinuumsteklovpoincarestep.hh b/dune/gfe/coupling/rodcontinuumsteklovpoincarestep.hh
index d50e3a2bafb0e0e8896dd871da70e68a071f5d8c..c0c755334cd65c54947507f95825e41771019e7b 100644
--- a/dune/gfe/coupling/rodcontinuumsteklovpoincarestep.hh
+++ b/dune/gfe/coupling/rodcontinuumsteklovpoincarestep.hh
@@ -139,7 +139,17 @@ public:
      * \param[in,out] lambda The old and new iterate
      */
     void iterate(std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >& lambda);
-    
+
+    /** \brief Do one Steklov-Poincare step
+     * \param[in,out] lambda The old and new iterate
+     */
+    void iterateWithContact(std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >& lambda,
+                            LoopSolver<VectorType>* contactSolver,
+                            const MatrixType* totalStiffnessMatrix,
+                            const NBodyAssembler<ContinuumGridType, VectorType>* contactAssembler,
+                            const std::vector<std::string>& continuumName
+                           );
+
 private:
     
     std::map<std::pair<std::string,std::string>,RigidBodyMotion<3>::TangentVector> 
@@ -995,4 +1005,325 @@ iterate(std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >& lambd
     }
 }
 
-#endif
\ No newline at end of file
+/** \brief One preconditioned Richardson step plus a continuum contact problem
+*/
+template <class RodGridType, class ContinuumGridType>
+void RodContinuumSteklovPoincareStep<RodGridType,ContinuumGridType>::
+iterateWithContact(std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >& lambda,
+                   LoopSolver<VectorType>* contactSolver,
+                   const MatrixType* totalStiffnessMatrix,
+                   const NBodyAssembler<ContinuumGridType, VectorType>* contactAssembler,
+                   const std::vector<std::string>& continuumName
+)
+{
+    ///////////////////////////////////////////////////////////////////
+    //  Evaluate the Dirichlet-to-Neumann maps for the rods
+    ///////////////////////////////////////////////////////////////////
+
+    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> rodForceTorque;
+    
+    for (RodIterator it = rods_.begin(); it != rods_.end(); ++it) {
+        
+        const std::string& rodName = it->first;
+    
+        std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> forceTorque = rodDirichletToNeumannMap(rodName, lambda);
+
+        insert(rodForceTorque, forceTorque);
+        
+    }
+
+    std::cout << "resultant rod forces and torques: "  << std::endl;
+    typedef typename std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector>::iterator ForceIterator;
+    for (ForceIterator it = rodForceTorque.begin(); it != rodForceTorque.end(); ++it)
+        std::cout << "    [" << it->first.first << ", " << it->first.second << "] -- "
+                  << it->second << std::endl;
+
+    ///////////////////////////////////////////////////////////////////
+    //  Evaluate the Dirichlet-to-Neumann map for the continuum
+    ///////////////////////////////////////////////////////////////////
+    
+    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> continuumForceTorque; 
+    
+    LinearIterationStep<MatrixType,VectorType>* multigridStep = dynamic_cast<LinearIterationStep<MatrixType,VectorType>*>(contactSolver->iterationStep_);
+
+    // Make initial iterate: we start from zero
+    std::map<std::string,VectorType> x;
+
+    for (typename RodContinuumComplex<RodGridType,ContinuumGridType>::ConstContinuumIterator it = complex_.continua_.begin();
+         it != complex_.continua_.end(); ++it) {
+        
+        // Copy the true Dirichlet values into it
+        const LeafBoundaryPatch<ContinuumGridType>& dirichletBoundary = complex_.continuum(it->first).dirichletBoundary_;
+        const VectorType& dirichletValues = complex_.continuum(it->first).dirichletValues_;
+
+        VectorType& thisX = x[it->first];
+        
+        thisX.resize(dirichletValues.size());
+        
+        for (size_t i=0; i<thisX.size(); i++)
+        if (dirichletBoundary.containsVertex(i))
+            thisX[i] = dirichletValues[i];
+        
+    }
+    
+    typename std::map<std::pair<std::string,std::string>,RigidBodyMotion<3> >::const_iterator it = lambda.begin();
+    for (; it!=lambda.end(); ++it) {
+        
+        const std::pair<std::string,std::string>& couplingName = it->first;
+
+        // Turn \lambda \in TSE(3) into a Dirichlet value for the continuum
+        const LeafBoundaryPatch<ContinuumGridType>& interfaceBoundary = complex_.coupling(couplingName).continuumInterfaceBoundary_;
+        const RigidBodyMotion<dim>& referenceInterface = complex_.coupling(couplingName).referenceInterface_;
+        
+        setRotation(interfaceBoundary, x[couplingName.second], referenceInterface, it->second);
+    
+    }
+
+    VectorType totalX3d;
+    std::vector<VectorType> xVector(continuumName.size());
+    for (int i=0; i<continuumName.size(); i++)
+        xVector[i] = x[continuumName[i]];
+    NBodyAssembler<ContinuumGridType, VectorType>::concatenateVectors(xVector, totalX3d);
+    
+    // Make the set off all Dirichlet nodes
+    Dune::BitSetVector<dim> totalDirichletNodes(totalStiffnessMatrix->N());
+
+    int offset = 0;
+    for (int i=0; i<continuumName.size(); i++) {
+        const Dune::BitSetVector<dim>& ignoreNodes = continuum(continuumName[i]).dirichletAndCouplingNodes_;
+        for (int j=0; j<ignoreNodes.size(); j++)
+            totalDirichletNodes[offset + j] = ignoreNodes[j];
+        offset += ignoreNodes.size();
+    }
+
+
+    // separate, untransformed weak volume and Neumann terms
+    /** \todo Not implemented yet */
+    std::map<std::string,VectorType> rhs3d;
+    for (size_t i=0; i<continuumName.size(); i++) {
+        rhs3d[continuumName[i]].resize(continuum(continuumName[i]).stiffnessMatrix_->N());
+        rhs3d[continuumName[i]] = 0;
+    }
+    VectorType totalRhs3d(totalStiffnessMatrix->N());
+    totalRhs3d = 0;
+    
+    multigridStep->setProblem(*totalStiffnessMatrix, totalX3d, totalRhs3d);
+            
+    contactSolver->preprocess();
+    multigridStep->preprocess();
+            
+    contactSolver->solve();
+            
+    totalX3d = multigridStep->getSol();
+
+    // Separate 3d solution vector
+    std::vector<VectorType> x3d;
+    contactAssembler->postprocess(totalX3d, x3d);
+    
+    // the subdomain solutions in canonical coordinates, stored in a map
+    for (size_t i=0; i<x3d.size(); i++)
+        x[continuumName[i]] = x3d[i];
+    
+    //////////////////////////////////////////////////////////////////////////////
+    //  Extract the residual stresses
+    //////////////////////////////////////////////////////////////////////////////
+
+    // compute the residual for each continuum
+    std::map<std::string,VectorType> residual = rhs3d;
+    for (typename std::map<std::string,VectorType>::iterator it = residual.begin(); it != residual.end(); ++it)
+        continuum(it->first).stiffnessMatrix_->mmv(x[it->first], it->second);
+    
+    // Integrate over the residual on the coupling boundary to obtain
+    // an element of T^*SE.
+    for (typename std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >::iterator it = lambda.begin(); it!=lambda.end(); ++it) {
+        
+        const std::pair<std::string,std::string>& couplingName = it->first;
+        
+        /** \todo Is referenceInterface.r the correct center of rotation? */
+        const RigidBodyMotion<dim>& referenceInterface = complex_.coupling(couplingName).referenceInterface_;
+
+        Dune::FieldVector<double,3> continuumForce, continuumTorque;
+            
+        computeTotalForceAndTorque(complex_.coupling(couplingName).continuumInterfaceBoundary_, 
+                                   residual[it->first.second], 
+                                   complex_.coupling(couplingName).referenceInterface_.r,
+                                   continuumForce, continuumTorque);
+
+        continuumForceTorque[couplingName][0] = continuumForce[0];
+        continuumForceTorque[couplingName][1] = continuumForce[1];
+        continuumForceTorque[couplingName][2] = continuumForce[2];
+        continuumForceTorque[couplingName][3] = continuumTorque[0];
+        continuumForceTorque[couplingName][4] = continuumTorque[1];
+        continuumForceTorque[couplingName][5] = continuumTorque[2];
+    
+    }
+
+
+    std::cout << "resultant continuum force and torque: " << std::endl;
+    for (ForceIterator it = continuumForceTorque.begin(); it != continuumForceTorque.end(); ++it)
+        std::cout << "    [" << it->first.first << ", " << it->first.second << "] -- "
+                  << it->second << std::endl;
+
+    ///////////////////////////////////////////////////////////////
+    //  Compute the overall Steklov-Poincare residual
+    ///////////////////////////////////////////////////////////////
+
+    // Flip orientation of all rod forces, to account for opposing normals.
+    for (ForceIterator it = rodForceTorque.begin(); it != rodForceTorque.end(); ++it)
+        it->second *= -1;
+
+    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> residualForceTorque = rodForceTorque;
+    
+    for (ForceIterator it = residualForceTorque.begin(), it2 = continuumForceTorque.begin(); 
+         it != residualForceTorque.end(); 
+         ++it, ++it2) {
+        assert(it->first == it2->first);
+        it->second += it2->second;
+    }
+            
+    ///////////////////////////////////////////////////////////////
+    //  Apply the preconditioner
+    ///////////////////////////////////////////////////////////////
+            
+    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> interfaceCorrection;
+            
+    if (preconditioner_=="DirichletNeumann") {
+                
+        ////////////////////////////////////////////////////////////////////
+        //  Preconditioner is the linearized Neumann-to-Dirichlet map
+        //  of the continuum.
+        ////////////////////////////////////////////////////////////////////
+
+#warning Neumann-to-Dirichlet map not implemented yet
+#if 0
+        for (ContinuumIterator it = continua_.begin(); it != continua_.end(); ++it) {
+        
+            const std::string& continuumName = it->first;
+    
+            std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> continuumInterfaceCorrection
+                    = linearizedContinuumNeumannToDirichletMap(continuumName,
+                                                               continuumSubdomainSolutions_[continuumName], 
+                                                               residualForceTorque,
+                                                               lambda);
+
+            insert(interfaceCorrection, continuumInterfaceCorrection);
+        
+        }
+#endif
+        std::cout << "resultant continuum interface corrections: " << std::endl;
+        for (ForceIterator it = interfaceCorrection.begin(); it != interfaceCorrection.end(); ++it)
+        std::cout << "    [" << it->first.first << ", " << it->first.second << "] -- "
+                  << it->second << std::endl;
+
+
+    } else if (preconditioner_=="NeumannDirichlet") {
+            
+        ////////////////////////////////////////////////////////////////////
+        //  Preconditioner is the linearized Neumann-to-Dirichlet map
+        //  of the rod.
+        ////////////////////////////////////////////////////////////////////
+        
+        for (RodIterator it = rods_.begin(); it != rods_.end(); ++it) {
+        
+            const std::string& rodName = it->first;
+    
+            std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> rodInterfaceCorrection
+                    = linearizedRodNeumannToDirichletMap(rodName,
+                                                         rodSubdomainSolutions_[rodName], 
+                                                         residualForceTorque,
+                                                         lambda);
+
+            insert(interfaceCorrection, rodInterfaceCorrection);
+        
+        }
+
+        std::cout << "resultant rod interface corrections: " << std::endl;
+        for (ForceIterator it = interfaceCorrection.begin(); it != interfaceCorrection.end(); ++it)
+        std::cout << "    [" << it->first.first << ", " << it->first.second << "] -- "
+                  << it->second << std::endl;
+
+    } else if (preconditioner_=="NeumannNeumann") {
+            
+        ////////////////////////////////////////////////////////////////////
+        //  Preconditioner is a convex combination of the linearized
+        //  Neumann-to-Dirichlet map of the continuum and the linearized
+        //  Neumann-to-Dirichlet map of the rod.
+        ////////////////////////////////////////////////////////////////////
+
+        // First the rod preconditioners
+        std::map<std::pair<std::string,std::string>,RigidBodyMotion<3>::TangentVector> rodCorrection;
+        
+        for (RodIterator it = rods_.begin(); it != rods_.end(); ++it) {
+        
+            const std::string& rodName = it->first;
+    
+            std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> tmp
+                    = linearizedRodNeumannToDirichletMap(rodName,
+                                                         rodSubdomainSolutions_[rodName], 
+                                                         residualForceTorque,
+                                                         lambda);
+
+            insert(rodCorrection, tmp);
+        
+        }
+
+        // Then the continuum preconditioners
+        std::map<std::pair<std::string,std::string>,RigidBodyMotion<3>::TangentVector> continuumCorrection;
+        
+#warning Neumann-to-Dirichlet map not implemented yet
+#if 0
+        for (ContinuumIterator it = continua_.begin(); it != continua_.end(); ++it) {
+        
+            const std::string& continuumName = it->first;
+    
+            std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> tmp
+                    = linearizedContinuumNeumannToDirichletMap(continuumName,
+                                                               continuumSubdomainSolutions_[continuumName], 
+                                                               residualForceTorque,
+                                                               lambda);
+
+            insert(continuumCorrection,tmp);
+        
+        }
+#endif
+        std::cout << "resultant interface corrections: " << std::endl;
+        for (ForceIterator it = rodCorrection.begin(); it != rodCorrection.end(); ++it) {
+
+            const std::pair<std::string,std::string> interfaceName = it->first;
+        
+            std::cout << "    [" << interfaceName.first << ", " << interfaceName.second << "]"
+                      << "  -- " << it->second 
+                      << "  -- " << continuumCorrection[interfaceName] << std::endl;
+
+            // Compute weighted combination of both
+            RigidBodyMotion<3>::TangentVector& correction = interfaceCorrection[interfaceName];
+            for (int j=0; j<6; j++)
+                correction[j] = (alpha_[0] * continuumCorrection[interfaceName][j] + alpha_[1] * rodCorrection[interfaceName][j])
+                                            / alpha_[0] + alpha_[1];
+                
+        }
+        
+    } else if (preconditioner_=="RobinRobin") {
+            
+        DUNE_THROW(Dune::NotImplemented, "Robin-Robin preconditioner not implemented yet");
+                
+    } else
+        DUNE_THROW(Dune::NotImplemented, preconditioner_ << " is not a known preconditioner");
+            
+    ///////////////////////////////////////////////////////////////////////////////
+    //  Apply the damped correction to the current interface value
+    ///////////////////////////////////////////////////////////////////////////////
+                
+    
+    ForceIterator fIt = interfaceCorrection.begin();
+    for (typename std::map<std::pair<std::string,std::string>,RigidBodyMotion<3> >::iterator it = lambda.begin(); 
+         it!=lambda.end(); 
+         ++it, ++fIt) {
+        assert(it->first == fIt->first);
+        fIt->second *= richardsonDamping_;
+        it->second = RigidBodyMotion<3>::exp(it->second, fIt->second);
+    }
+}
+
+
+#endif