diff --git a/src/obstaclesolver.hh b/src/obstaclesolver.hh
deleted file mode 100644
index 49b4d7cb2c4c1d75055aec2bc12a22d28a1535e0..0000000000000000000000000000000000000000
--- a/src/obstaclesolver.hh
+++ /dev/null
@@ -1,48 +0,0 @@
-// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
-// vi: set et ts=4 sw=2 sts=2:
-#ifndef DUNE_TECTONIC_OBSTACLESOLVER_HH
-#define DUNE_TECTONIC_OBSTACLESOLVER_HH
-
-#include "spatial-solving/tnnmg/localproblem.hh"
-
-
-/**
- * \brief A local solver for quadratic obstacle problems
- *
- * \todo Add concept check for the function interface
- */
-class ObstacleSolver
-{
-public:
-  template<class Vector, class Functional, class BitVector>
-  constexpr void operator()(Vector& x, const Functional& f, const BitVector& ignore) const
-  {
-      auto& A = f.quadraticPart();
-      auto& r = f.linearPart();
-
-      LocalProblem<std::decay_t<decltype(A)> , std::decay_t<decltype(r)>> localProblem(A, r, ignore);
-      Vector newR;
-      localProblem.getLocalRhs(x, newR);
-
-      auto directSolver = Dune::Solvers::UMFPackSolver<std::decay_t<decltype(A)>, std::decay_t<decltype(r)>>();
-
-      directSolver->setProblem(localProblem.getMat(), x, newR);
-      directSolver->preprocess();
-      directSolver->solve();
-
-      const auto& lower = f.lowerObstacle();
-      const auto& upper = f.upperObstacle();
-
-      for (size_t i=0; i<x.size(); i++) {
-        if (ignore[i][0])
-            continue;
-
-        if (x[i] < lower[i])
-            x[i] = lower[i];
-        if (x[i] > upper[i])
-            x[i] = upper[i];
-      }
-  }
-};
-
-#endif
diff --git a/src/solverfactorytest.cc b/src/solverfactorytest.cc
index bbd7aeb09015b3d768a5724d391786d0b630805b..ef3ad5a509aabfe8c60df072fc3b5185cb3529f7 100644
--- a/src/solverfactorytest.cc
+++ b/src/solverfactorytest.cc
@@ -40,10 +40,8 @@
 
 #include "io/vtk.hh"
 
-#include "spatial-solving/tnnmg/tnnmgstep.hh"
 #include "spatial-solving/tnnmg/linesearchsolver.hh"
 #include "spatial-solving/preconditioners/nbodycontacttransfer.hh"
-#include "obstaclesolver.hh"
 
 #include "factories/stackedblocksfactory.hh"
 
diff --git a/src/spatial-solving/CMakeLists.txt b/src/spatial-solving/CMakeLists.txt
index 1970afe64c1da2c2152ba9de21234515d17472fc..e683042b12f4a2e84ed1ea781d911b427d878e63 100644
--- a/src/spatial-solving/CMakeLists.txt
+++ b/src/spatial-solving/CMakeLists.txt
@@ -1,3 +1,2 @@
 add_subdirectory("tnnmg")
-add_subdirectory("contact")
 add_subdirectory("preconditioners")
diff --git a/src/spatial-solving/contact/CMakeLists.txt b/src/spatial-solving/contact/CMakeLists.txt
deleted file mode 100644
index 05ec76c58ad389b8aac6c0368f6f551825f2ccb3..0000000000000000000000000000000000000000
--- a/src/spatial-solving/contact/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-add_custom_target(dune-tectonic_spatial-solving_contact_src SOURCES
-  dualmortarcoupling.cc
-  dualmortarcoupling.hh
-  nbodyassembler.cc
-  nbodyassembler.hh
-)
diff --git a/src/spatial-solving/contact/dualmortarcoupling.cc b/src/spatial-solving/contact/dualmortarcoupling.cc
deleted file mode 100644
index 96ca666c521a49612d334915f26adf359af422fa..0000000000000000000000000000000000000000
--- a/src/spatial-solving/contact/dualmortarcoupling.cc
+++ /dev/null
@@ -1,333 +0,0 @@
-// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-// vi: set ts=8 sw=4 et sts=4:
-#include <dune/common/exceptions.hh>
-
-#include <dune/istl/matrixindexset.hh>
-#include <dune/istl/io.hh>
-
-#include <dune/geometry/quadraturerules.hh>
-#include <dune/geometry/type.hh>
-#include <dune/geometry/referenceelements.hh>
-
-#include <dune/localfunctions/lagrange/pqkfactory.hh>
-
-
-#include <dune/grid-glue/merging/contactmerge.hh>
-//#include <dune/grid-glue/adapter/gridgluevtkwriter.hh>
-//#include <dune/grid-glue/adapter/gridglueamirawriter.hh>
-
-#include <dune/contact/common/dualbasisadapter.hh>
-#include <dune/matrix-vector/addtodiagonal.hh>
-
-
-template <class field_type, class GridView0, class GridView1>
-void DualMortarCoupling<field_type, GridView0, GridView1>::assembleNonmortarLagrangeMatrix()
-{
-    // Create mapping from the global set of block dofs to the ones on the contact boundary
-    std::vector<int> globalToLocal;
-    nonmortarBoundary_.makeGlobalToLocal(globalToLocal);
-
-    // clear matrix
-    nonmortarLagrangeMatrix_ = Dune::BDMatrix<MatrixBlock>(nonmortarBoundary_.numVertices());
-    nonmortarLagrangeMatrix_ = 0;
-
-    const auto& indexSet = gridView0_.indexSet();
-
-    // loop over all faces of the boundary patch
-    for (const auto& nIt : nonmortarBoundary_) {
-
-        const auto& geometry = nIt.geometry();
-        const field_type numCorners = geometry.corners();
-
-        ctype intElem = geometry.integrationElement(Dune::FieldVector<ctype,dim-1>(0));
-
-        field_type sfI = (numCorners==3) ? intElem/6.0 : intElem/numCorners;
-
-        // turn scalar element mass matrix into vector-valued one
-        // and add element mass matrix to the global matrix
-
-        // Get global node ids
-        const auto& inside = nIt.inside();
-        const auto& refElement = Dune::ReferenceElements<ctype, dim>::general(inside.type());
-
-        // Add localMatrix to nonmortarLagrangeMat
-        for (int i=0; i<refElement.size(nIt.indexInInside(),1,dim); i++) {
-            // we can use subEntity here because we add all indices anyway
-            int v = globalToLocal[indexSet.subIndex(inside,refElement.subEntity(nIt.indexInInside(),1,
-                                                                          i,dim),dim)];
-                Dune::MatrixVector::addToDiagonal(nonmortarLagrangeMatrix_[v][v],sfI);
-        }
-
-    }
-
-}
-
-template <class field_type, class GridView0, class GridView1>
-void DualMortarCoupling<field_type, GridView0, GridView1>::setup()
-{
-    typedef Dune::PQkLocalFiniteElementCache<typename GridType1::ctype, field_type, GridType1::dimension,1> FiniteElementCache1;
-
-    // cache for the dual functions on the boundary
-    using DualCache = Dune::Contact::DualBasisAdapter<GridView0, field_type>;
-
-    using Element0 = typename GridView0::template Codim<0>::Entity;
-    using Element1 = typename GridView1::template Codim<0>::Entity;
-
-    auto desc0 = [&] (const Element0& e, unsigned int face) {
-        return nonmortarBoundary_.contains(e,face);
-    };
-
-    auto desc1 = [&] (const Element1& e, unsigned int face) {
-        return mortarBoundary_.contains(e,face);
-    };
-
-    auto extract0 = std::make_shared<Extractor0>(gridView0_,desc0);
-    auto extract1 = std::make_shared<Extractor1>(gridView1_,desc1);
-
-    if (!gridGlueBackend_)
-        gridGlueBackend_ = std::make_shared< Dune::GridGlue::ContactMerge<dimworld, ctype> >(overlap_);
-    glue_ = std::make_shared<Glue>(extract0, extract1, gridGlueBackend_);
-    auto& glue = *glue_;
-    glue.build();
-
-    std::cout << glue.size() << " remote intersections found." << std::endl;
-    //GridGlueAmiraWriter::write<GlueType>(glue,debugPath_);
-
-    // Restrict the hasObstacle fields to the part of the nonmortar boundary
-    // where we could actually create a contact mapping
-    BoundaryPatch0 boundaryWithMapping(gridView0);
-
-    const auto& indexSet0 = gridView0_.indexSet();
-    const auto& indexSet1 = gridView1_.indexSet();
-
-    ///////////////////////////////////
-    //  reducing nonmortar boundary
-    /////////////////////////////////
-
-    // Get all fine grid boundary segments that are totally covered by the grid-glue segments
-    typedef std::pair<int,int> Pair;
-    std::map<Pair,ctype> coveredArea, fullArea;
-
-    // initialize with area of boundary faces
-    for (const auto& bIt : nonmortarBoundary_) {
-        const Pair p(indexSet0.index(bIt.inside()),bIt.indexInInside());
-        fullArea[p] = bIt.geometry().volume();
-        coveredArea[p] = 0;
-    }
-
-    // sum up the remote intersection areas to find out which are totally covered
-    for (const auto& rIs : intersections(glue))
-        coveredArea[Pair(indexSet0.index(rIs.inside()),rIs.indexInInside())] += rIs.geometry().volume();
-
-    // add all fine grid faces that are totally covered by the contact mapping
-    for (const auto& bIt : nonmortarBoundary_) {
-        const auto& inside = bIt.inside();
-        if(coveredArea[Pair(indexSet0.index(inside),bIt.indexInInside())]/
-            fullArea[Pair(indexSet0.index(inside),bIt.indexInInside())] >= coveredArea_)
-            boundaryWithMapping.addFace(inside, bIt.indexInInside());
-    }
-
-    //writeBoundary(boundaryWithMapping,debugPath_ + "relevantNonmortar");
-
-
-    /** \todo replace by all fine grid segments which are totally covered by the RemoteIntersections. */
-    //for (const auto& rIs : intersections(glue))
-    //    boundaryWithMapping.addFace(rIs.inside(),rIs.indexInInside());
-
-    printf("contact mapping could be built for %d of %d boundary segments.\n",
-           boundaryWithMapping.numFaces(), nonmortarBoundary_.numFaces());
-
-    nonmortarBoundary_ = boundaryWithMapping;
-    mortarBoundary_.setup(gridView1_);
-    for (const auto& rIs : intersections(glue))
-        if (nonmortarBoundary_.contains(rIs.inside(),rIs.indexInInside()))
-            mortarBoundary_.addFace(rIs.outside(),rIs.indexInOutside());
-
-
-    // Assemble the diagonal matrix coupling the nonmortar side with the lagrange multiplyers there
-    assembleNonmortarLagrangeMatrix();
-
-    // The weak obstacle vector
-    weakObstacle_.resize(nonmortarBoundary_.numVertices());
-    weakObstacle_ = 0;
-
-    // ///////////////////////////////////////////////////////////
-    //   Get the occupation structure for the mortar matrix
-    // ///////////////////////////////////////////////////////////
-
-    /** \todo Also restrict mortar indices and don't use the whole grid level. */
-    Dune::MatrixIndexSet mortarIndices(nonmortarBoundary_.numVertices(), grid1_->size(dim));
-
-    // Create mapping from the global set of block dofs to the ones on the contact boundary
-    std::vector<int> globalToLocal;
-    nonmortarBoundary_.makeGlobalToLocal(globalToLocal);
-
-    // loop over all intersections
-    for (const auto& rIs : intersections(glue)) {
-
-        if (!nonmortarBoundary_.contains(rIs.inside(),rIs.indexInInside()))
-            continue;
-
-        const auto& inside = rIs.inside();
-        const auto& outside = rIs.outside();
-
-        const auto& domainRefElement = Dune::ReferenceElements<ctype, dim>::general(inside.type());
-        const auto& targetRefElement = Dune::ReferenceElements<ctype, dim>::general(outside.type());
-
-        int nDomainVertices = domainRefElement.size(dim);
-        int nTargetVertices = targetRefElement.size(dim);
-
-        for (int j=0; j<nDomainVertices; j++) {
-
-            int localDomainIdx = globalToLocal[indexSet0.subIndex(inside,j,dim)];
-
-            // if the vertex is not contained in the restricted contact boundary then dismiss it
-            if (localDomainIdx == -1)
-                continue;
-
-            for (int k=0; k<nTargetVertices; k++) {
-                int globalTargetIdx = indexSet1.subIndex(outside,k,dim);
-                if (!mortarBoundary_.containsVertex(globalTargetIdx))
-                    continue;
-
-                mortarIndices.add(localDomainIdx, globalTargetIdx);
-            }
-        }
-    }
-
-    mortarIndices.exportIdx(mortarLagrangeMatrix_);
-
-    // Clear it
-    mortarLagrangeMatrix_ = 0;
-
-
-    //cache of local bases
-    FiniteElementCache1 cache1;
-
-    std::unique_ptr<DualCache> dualCache;
-    dualCache = std::make_unique< Dune::Contact::DualBasisAdapterGlobal<GridView0, field_type> >();
-
-    std::vector<Dune::FieldVector<ctype,dim> > avNormals;
-    avNormals = nonmortarBoundary_.getNormals();
-
-    // loop over all intersections and compute the matrix entries
-    for (const auto& rIs : intersections(glue)) {
-
-
-        const auto& inside = rIs.inside();
-
-        if (!nonmortarBoundary_.contains(rIs.inside(),rIs.indexInInside()))
-            continue;
-
-        const auto& outside = rIs.outside();
-
-        // types of the elements supporting the boundary segments in question
-        Dune::GeometryType nonmortarEType = inside.type();
-        Dune::GeometryType mortarEType    = outside.type();
-
-        const auto& domainRefElement = Dune::ReferenceElements<ctype, dim>::general(nonmortarEType);
-
-        const auto& targetRefElement = Dune::ReferenceElements<ctype, dim>::general(mortarEType);
-
-        int noOfMortarVec = targetRefElement.size(dim);
-
-        Dune::GeometryType nmFaceType = domainRefElement.type(rIs.indexInInside(),1);
-        Dune::GeometryType mFaceType  = targetRefElement.type(rIs.indexInOutside(),1);
-
-        // Select a quadrature rule
-        // 2 in 2d and for integration over triangles in 3d.  If one (or both) of the two faces involved
-        // are quadrilaterals, then the quad order has to be risen to 3 (4).
-        int quadOrder = 2 + (!nmFaceType.isSimplex()) + (!mFaceType.isSimplex());
-        const auto& quadRule = Dune::QuadratureRules<ctype, dim-1>::rule(rIs.type(), quadOrder);
-
-        //const typename FiniteElementCache0::FiniteElementType& nonmortarFiniteElement = cache0.get(nonmortarEType);
-        const auto& mortarFiniteElement = cache1.get(mortarEType);
-        dualCache->bind(inside, rIs.indexInInside());
-
-        std::vector<Dune::FieldVector<field_type,1> > mortarQuadValues, dualQuadValues;
-
-        const auto& rGeom = rIs.geometry();
-        const auto& rGeomOutside = rIs.geometryOutside();
-        const auto& rGeomInInside = rIs.geometryInInside();
-        const auto& rGeomInOutside = rIs.geometryInOutside();
-
-        int nNonmortarFaceNodes = domainRefElement.size(rIs.indexInInside(),1,dim);
-        std::vector<int> nonmortarFaceNodes;
-        for (int i=0; i<nNonmortarFaceNodes; i++) {
-          int faceIdxi = domainRefElement.subEntity(rIs.indexInInside(), 1, i, dim);
-          nonmortarFaceNodes.push_back(faceIdxi);
-        }
-
-        for (const auto& quadPt : quadRule) {
-
-            // compute integration element of overlap
-            ctype integrationElement = rGeom.integrationElement(quadPt.position());
-
-            // quadrature point positions on the reference element
-            Dune::FieldVector<ctype,dim> nonmortarQuadPos = rGeomInInside.global(quadPt.position());
-            Dune::FieldVector<ctype,dim> mortarQuadPos    = rGeomInOutside.global(quadPt.position());
-
-            // The current quadrature point in world coordinates
-            Dune::FieldVector<field_type,dim> nonmortarQpWorld = rGeom.global(quadPt.position());
-            Dune::FieldVector<field_type,dim> mortarQpWorld    = rGeomOutside.global(quadPt.position());;
-
-            // the gap direction (normal * gapValue)
-            Dune::FieldVector<field_type,dim> gapVector = mortarQpWorld  - nonmortarQpWorld;
-
-            //evaluate all shapefunctions at the quadrature point
-            //nonmortarFiniteElement.localBasis().evaluateFunction(nonmortarQuadPos,nonmortarQuadValues);
-            mortarFiniteElement.localBasis().evaluateFunction(mortarQuadPos,mortarQuadValues);
-            dualCache->evaluateFunction(nonmortarQuadPos,dualQuadValues);
-
-            // loop over all Lagrange multiplier shape functions
-            for (int j=0; j<nNonmortarFaceNodes; j++) {
-
-                int globalDomainIdx = indexSet0.subIndex(inside,nonmortarFaceNodes[j],dim);
-                int rowIdx = globalToLocal[globalDomainIdx];
-
-                weakObstacle_[rowIdx][0] += integrationElement * quadPt.weight()
-                    * dualQuadValues[nonmortarFaceNodes[j]] * (gapVector*avNormals[globalDomainIdx]);
-
-                // loop over all mortar shape functions
-                for (int k=0; k<noOfMortarVec; k++) {
-
-                    int colIdx  = indexSet1.subIndex(outside, k, dim);
-                    if (!mortarBoundary_.containsVertex(colIdx))
-                        continue;
-
-                    // Integrate over the product of two shape functions
-                    field_type mortarEntry =  integrationElement* quadPt.weight()* dualQuadValues[nonmortarFaceNodes[j]]* mortarQuadValues[k];
-
-                    Dune::MatrixVector::addToDiagonal(mortarLagrangeMatrix_[rowIdx][colIdx], mortarEntry);
-
-                }
-
-            }
-
-        }
-
-    }
-
-    // ///////////////////////////////////////
-    //    Compute M = D^{-1} \hat{M}
-    // ///////////////////////////////////////
-
-    Dune::BCRSMatrix<MatrixBlock>& M  = mortarLagrangeMatrix_;
-    Dune::BDMatrix<MatrixBlock>& D    = nonmortarLagrangeMatrix_;
-
-    // First compute D^{-1}
-    D.invert();
-
-    // Then the matrix product D^{-1} \hat{M}
-    for (auto rowIt = M.begin(); rowIt != M.end(); ++rowIt) {
-        const auto rowIndex = rowIt.index();
-        for (auto& entry : *rowIt)
-            entry.leftmultiply(D[rowIndex][rowIndex]);
-    }
-
-    // weakObstacles in transformed basis = D^{-1}*weakObstacle_
-    for(size_t rowIdx=0; rowIdx<weakObstacle_.size(); rowIdx++)
-        weakObstacle_[rowIdx] *= D[rowIdx][rowIdx][0][0];
-
-    gridGlueBackend_->clear();
-}
diff --git a/src/spatial-solving/contact/dualmortarcoupling.hh b/src/spatial-solving/contact/dualmortarcoupling.hh
deleted file mode 100644
index 81c6e628ecd8146abe3847818843aff9a78d9500..0000000000000000000000000000000000000000
--- a/src/spatial-solving/contact/dualmortarcoupling.hh
+++ /dev/null
@@ -1,199 +0,0 @@
-// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-// vi: set ts=8 sw=4 et sts=4:
-#ifndef DUNE_CONTACT_ASSEMBLERS_DUAL_MORTAR_COUPLING_HH
-#define DUNE_CONTACT_ASSEMBLERS_DUAL_MORTAR_COUPLING_HH
-
-#include <memory>
-
-#include <dune/istl/bcrsmatrix.hh>
-#include <dune/istl/bdmatrix.hh>
-#include <dune/istl/bvector.hh>
-
-#include <dune/fufem/boundarypatch.hh>
-#include <dune/fufem/boundarypatchprolongator.hh>
-
-#include <dune/grid-glue/gridglue.hh>
-#include <dune/grid-glue/extractors/codim1extractor.hh>
-#include <dune/grid-glue/merging/merger.hh>
-
-
-/** \brief Extension of Dune::Contact::DualMortarCoupling that works on
- *         any GridView (not just LeafGridView) and allows crosspoints.
- *
- *         Assembles the transfer operator for two-body contact
- */
-template<class field_type, class GridView0, class GridView1=GridView0>
-class DualMortarCoupling {
-
-    // /////////////////////
-    // private types
-    // /////////////////////
-
-    enum {dim = GridView0::dimension};
-
-    enum {dimworld = GridView0::dimensionworld};
-
-  protected:
-    using MatrixBlock = Dune::FieldMatrix<field_type, dim, dim>;
-    using MatrixType = Dune::BCRSMatrix<MatrixBlock>;
-    using ObstacleVector = Dune::BlockVector<Dune::FieldVector<field_type, 1> >;
-
-    using ctype = typename GridView0::ctype;
-
-    using GridType0 = typename GridView0::Grid;
-    using GridType1 = typename GridView1::Grid;
-
-    using BoundaryPatch0 = BoundaryPatch<GridView0>;
-    using BoundaryPatch1 = BoundaryPatch<GridView1>;
-
-    using LevelBoundaryPatch0 = BoundaryPatch<typename GridType0::LevelGridView>;
-    using LevelBoundaryPatch1 = BoundaryPatch<typename GridType1::LevelGridView>;
-
-    using Extractor0 = Dune::GridGlue::Codim1Extractor<GridView0>;
-    using Extractor1 = Dune::GridGlue::Codim1Extractor<GridView1>;
-
-public:
-
-    using Glue = Dune::GridGlue::GridGlue<Extractor0, Extractor1>;
-
-    DualMortarCoupling(field_type overlap = 1e-2, field_type coveredArea = 1.0 - 1e-2)
-        : overlap_(overlap), gridGlueBackend_(nullptr), coveredArea_(coveredArea)
-    {}
-
-    DualMortarCoupling(GridView0&& gridView0, GridView0&& gridView1,
-                       field_type overlap = 1e-2, field_type coveredArea = 1.0 - 1e-2)
-        : overlap_(overlap), gridGlueBackend_(nullptr), coveredArea_(coveredArea)
-    {
-        setGrids(gridView0, gridView1);
-    }
-
-    virtual ~DualMortarCoupling() {
-        /* Nothing. */
-    }
-
-    /** \brief Sets up the contact coupling operator on the grid leaf level */
-    virtual void setup();
-
-    /** \brief Assemble nonmortar matrix on the leaf level. */
-    void assembleNonmortarLagrangeMatrix();
-
-    /** \brief Get the dual mortar coupling matrix of the leaf level. */
-    virtual const MatrixType& mortarLagrangeMatrix() const {
-        return mortarLagrangeMatrix_;
-    }
-
-    /** \brief Get the dual mortar coupling matrix of the leaf level. */
-    virtual MatrixType& mortarLagrangeMatrix() {
-        return mortarLagrangeMatrix_;
-    }
-
-    /** \brief Get the non-mortar matrix. */
-    const BDMatrix<MatrixBlock>& nonmortarLagrangeMatrix() const {
-        return nonmortarLagrangeMatrix_;
-    }
-
-    /** \brief Setup leaf nonmortar and mortar patches. */
-    virtual void setupContactPatch(const LevelBoundaryPatch0& coarseNonmortar,
-                           const LevelBoundaryPatch1& coarseMortar) {
-
-        BoundaryPatchProlongator<GridType0>::prolong(coarseNonmortar,nonmortarBoundary_);
-        BoundaryPatchProlongator<GridType1>::prolong(coarseMortar,mortarBoundary_);
-    }
-
-    /** \brief Return the nonmortar boundary. */
-    const BoundaryPatch0& nonmortarBoundary() const {
-        return nonmortarBoundary_;
-    }
-
-    /** \brief Return the mortar boundary. */
-    const BoundaryPatch1& mortarBoundary() const {
-        return mortarBoundary_;
-    }
-
-    /** \brief Set the non-mortar and mortar grid. */
-    void setGrids(GridView0&& gridView0, GridView1&& gridView1) {
-        gridView0_ = std::forward<GridView0>(gridView0);
-        gridView1_ = std::forward<GridView1>(gridView1);
-
-        grid0_ = &gridView0_.grid();
-        grid1_ = &gridView1_.grid();
-    }
-
-    /** \brief Get non-mortar grid. */
-    const GridType0* getGrid0() const {
-        return grid0_;
-    }
-
-    /** \brief Get mortar grid. */
-    const GridType1* getGrid1() const {
-        return grid1_;
-    }
-
-    /** \brief Set the percentage of covered area each face must at least have
-     *         by the grid-glue projection.
-     */
-    void setCoveredArea(field_type coveredArea) {
-        coveredArea_ = coveredArea;
-    }
-
-    void setOverlap(field_type overlap) {
-        overlap_ = overlap;
-    }
-
-    /** \brief Get the GridGlue. */
-    std::shared_ptr<Glue> getGlue() {
-        return glue_;
-    }
-
-    const ObstacleVector& getWeakObstacle() const {
-        return weakObstacle_;
-    }
-
-
-    // /////////////////////////////////////////////
-    //   Data members
-    // /////////////////////////////////////////////
-private:
-    /** \brief The two grids involved in the two-body contact problem. */
-    const GridView0& gridView0_;
-    const GridView1& gridView1_;
-
-    const GridType0* grid0_;
-    const GridType1* grid1_;
-
-    /** \brief For each dof a bit specifying whether the dof carries an obstacle or not. */
-    BoundaryPatch0 nonmortarBoundary_;
-
-    /** \brief The mortar boundary. */
-    BoundaryPatch1 mortarBoundary_;
-
-    /** \brief The matrix coupling mortar side and Lagrange multipliers. */
-    MatrixType mortarLagrangeMatrix_;
-
-    /** \brief The diagonal matrix coupling nonmortar side and Lagrange multipliers */
-    Dune::BDMatrix<MatrixBlock> nonmortarLagrangeMatrix_;
-
-    /** \brief The weak obstacles. */
-    ObstacleVector weakObstacle_;
-
-    /** \brief Allow some small penetration of the bodies. */
-    field_type overlap_;
-
-    /** \brief A grid-glue merger. If this is not set ContactMerge is used. */
-    std::shared_ptr< Dune::GridGlue::Merger<field_type,dim-1,dim-1,dim> > gridGlueBackend_;
-
-    // Path where to write the merged grids and the reduced contact boundaries
-    //std::string debugPath_;
-
-    std::shared_ptr<Glue> glue_;
-
-    /** \brief Dismiss all faces that are not at least covered by the grid-glue projection for this
-     *         much percentage ranging between one - for total coverage and zero for taking all faces.
-     */
-    field_type coveredArea_;
-};
-
-
-#include "dualmortarcoupling.cc"
-
-#endif
diff --git a/src/spatial-solving/contact/nbodyassembler.cc b/src/spatial-solving/contact/nbodyassembler.cc
deleted file mode 100644
index d8ee25a45d13da8fdaa6f5810937c09631388b64..0000000000000000000000000000000000000000
--- a/src/spatial-solving/contact/nbodyassembler.cc
+++ /dev/null
@@ -1,519 +0,0 @@
-// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-// vi: set ts=8 sw=4 et sts=4:
-#include <memory>
-
-#include <dune/istl/preconditioners.hh>
-#include <dune/istl/solvers.hh>
-#include <dune/matrix-vector/transpose.hh>
-#include <dune/matrix-vector/blockmatrixview.hh>
-
-#include <dune/fufem/boundarypatchprolongator.hh>
-#include <dune/contact/projections/normalprojection.hh>
-
-namespace Dune {
-namespace Contact {
-
-template <class GridType, class VectorType>
-void NBodyAssembler<GridType, VectorType>::assembleTransferOperator()
-{
-
-    // /////////////////////////////////////////////////////////////////
-    //   Check if contact data is present
-    // /////////////////////////////////////////////////////////////////
-
-    for (int i=0; i<nCouplings(); i++) {
-
-
-         if (!coupling_[i].obsPatch_)
-             DUNE_THROW(Dune::Exception, "You have to supply a nonmortar patch for the " << i << "-th coupling!");
-
-         if (!coupling_[i].mortarPatch_)
-             DUNE_THROW(Dune::Exception, "You have to supply a mortar patch for the " << i << "-th coupling!");
-    }
-
-    // ////////////////////////////////////////////////////
-    //   Set up Mortar element transfer operators
-    // ///////////////////////////////////////////////////
-
-    std::cout<<"Setup mortar transfer operators\n";
-
-    for (size_t i=0; i<contactCoupling_.size(); i++) {
-        contactCoupling_[i]->setGrids(*grids_[coupling_[i].gridIdx_[0]],*grids_[coupling_[i].gridIdx_[1]]);
-        contactCoupling_[i]->setupContactPatch(*coupling_[i].patch0(),*coupling_[i].patch1());
-        contactCoupling_[i]->gridGlueBackend_ = coupling_[i].backend();
-        contactCoupling_[i]->setCoveredArea(coveredArea_);
-        contactCoupling_[i]->setup();
-    }
-
-    // setup Householder reflections
-    assembleHouseholderReflections();
-
-    // compute the mortar transformation matrix
-    computeTransformationMatrix();
-}
-
-template <class GridType, class VectorType>
-void NBodyAssembler<GridType, VectorType>::assembleHouseholderReflections()
-{
-    // //////////////////////////////////////////////////////////////////
-    //   Compute local coordinate systems for the dofs with obstacles
-    // //////////////////////////////////////////////////////////////////
-
-    std::vector<std::vector<MatrixBlock> > coordinateSystems(nCouplings());
-
-    for (int i=0; i<nCouplings(); i++) {
-
-        double dist = coupling_[i].obsDistance_;
-        auto projection = coupling_[i].projection();
-
-        if (!projection)
-            DUNE_THROW(Dune::Exception, "You have to supply a contact projection for the " << i << "-th coupling!");
-
-        std::vector<Dune::FieldVector<field_type,dim> > directions;
-
-        const auto& nonmortarBoundary = contactCoupling_[i]->nonmortarBoundary();
-        const auto& mortarBoundary    = contactCoupling_[i]->mortarBoundary();
-
-        projection->project(nonmortarBoundary, mortarBoundary,dist);
-        projection->getObstacleDirections(directions);
-
-        this->computeLocalCoordinateSystems(nonmortarBoundary,coordinateSystems[i], directions);
-    }
-
-    // ///////////////////////////////////////////////////////////////
-    // Combine the coordinate systems for each grid to one long array
-    // ///////////////////////////////////////////////////////////////
-    this->localCoordSystems_.resize(numDofs());
-
-    // initialise with identity
-    Dune::ScaledIdentityMatrix<field_type,dim> id(1);
-    for (size_t i=0; i<this->localCoordSystems_.size(); i++)
-        this->localCoordSystems_[i] = id;
-
-    for (int j=0; j<nCouplings(); j++) {
-
-        int grid0Idx = coupling_[j].gridIdx_[0];
-
-        // compute offset
-        int idx = 0;
-        for (int k=0;k<grid0Idx;k++)
-            idx += grids_[k]->size(dim);
-
-        const auto& nonmortarBoundary = contactCoupling_[j]->nonmortarBoundary();
-
-        // if a body is non-mortar more then once, one has to be careful with not overwriting entries
-        for (std::size_t k=0; k<coordinateSystems[j].size(); k++)
-          if(nonmortarBoundary.containsVertex(k))
-            this->localCoordSystems_[idx+k] = coordinateSystems[j][k];
-    }
-}
-
-template <class GridType, class VectorType>
-void NBodyAssembler<GridType, VectorType>::assembleObstacle()
-{
-
-    std::vector<std::vector<int> > globalToLocals(nCouplings());
-    for (std::size_t i = 0; i < globalToLocals.size(); ++i)
-        contactCoupling_[i]->nonmortarBoundary().makeGlobalToLocal(globalToLocals[i]);
-
-    ///////////////////////////////////////
-    //  Set the obstacle values
-    ///////////////////////////////////////
-
-    totalHasObstacle_.resize(numDofs(),false);
-
-    for (int j=0; j<nCouplings(); j++) {
-
-        int grid0Idx = coupling_[j].gridIdx_[0];
-        const auto& nonmortarBoundary = contactCoupling_[j]->nonmortarBoundary();
-
-        // compute offset
-        int idx = 0;
-        for (int k=0;k<grid0Idx;k++)
-            idx += grids_[k]->size(dim);
-
-        for (int k=0; k<grids_[grid0Idx]->size(dim); k++)
-            if (nonmortarBoundary.containsVertex(k))
-                totalHasObstacle_[idx+k] = true;
-    }
-
-    // //////////////////////////////////////////////////////////////////
-    //   Set the obstacle distances
-    // //////////////////////////////////////////////////////////////////
-
-    // Combine the obstacle values for each grid to one long array
-    totalObstacles_.resize(numDofs());
-
-    for (size_t j=0; j<totalObstacles_.size(); j++)
-        totalObstacles_[j].clear();
-
-    // Init the obstacle values
-    for (int i=0; i<nCouplings(); i++) {
-
-        int grid0Idx = coupling_[i].gridIdx_[0];
-
-        // compute offset
-        int idx = 0;
-        for (int k=0;k<grid0Idx;k++)
-            idx += grids_[k]->size(dim);
-
-        // The grids involved in this coupling
-        const auto& indexSet = grids_[grid0Idx]->leafIndexSet();
-
-        // the obstacles are stored using local indices
-        const std::vector<int>& globalToLocal = globalToLocals[i];
-
-        // the weak obstacles
-        const auto& obs = contactCoupling_[i]->weakObstacle_;
-
-        // get strong obstacles, the projection method of the correct level has already been called
-        //std::vector<field_type> obs;
-        //coupling_[i].projection()->getObstacles(obs);
-
-        const auto& leafView = grids_[grid0Idx]->leafGridView();
-
-        for (const auto& v : vertices(leafView)) {
-
-            int vIdx = indexSet.index(v);
-            if (globalToLocal[vIdx]<0)
-                continue;
-
-            // Set the obstacle
-            switch (coupling_[i].type_) {
-
-            case CouplingPairBase::CONTACT:
-                totalObstacles_[idx+vIdx].upper(0) = obs[globalToLocal[vIdx]];
-                break;
-
-            case CouplingPairBase::STICK_SLIP:
-                totalObstacles_[idx+vIdx].lower(0) = 0;
-                totalObstacles_[idx+vIdx].upper(0) = 0;
-                break;
-
-            case CouplingPairBase::GLUE:
-                for (int j=0; j<dim; j++) {
-                    totalObstacles_[idx+vIdx].lower(j) = 0;
-                    totalObstacles_[idx+vIdx].upper(j) = 0;
-                }
-                break;
-
-            case CouplingPairBase::NONE:
-                break;
-            default:
-                DUNE_THROW(Dune::NotImplemented, "Coupling type not handled yet!");
-            }
-        }
-    }
-
-}
-
-template <class GridType, class VectorType>
-void NBodyAssembler<GridType, VectorType>::
-assembleJacobian(const std::vector<const MatrixType*>& submat,
-                 MatrixType& totalMatrix) const
-{
-    // Create a block view of the grand matrix
-    Dune::MatrixVector::BlockMatrixView<MatrixType> blockView(submat);
-
-    int nRows = blockView.nRows();
-    int nCols = blockView.nCols();
-
-    // Create the index set of B \hat{A} B^T
-    Dune::MatrixIndexSet indicesBABT(nRows, nCols);
-
-    for (int i=0; i<nGrids(); i++) {
-
-        for (size_t iRow = 0; iRow<submat[i]->N(); iRow++) {
-
-            const RowType& row = (*submat[i])[iRow];
-
-            // Loop over all columns of the stiffness matrix
-            ConstColumnIterator j    = row.begin();
-            ConstColumnIterator jEnd = row.end();
-
-            for (; j!=jEnd; ++j) {
-
-                ConstColumnIterator k    = BT_[blockView.row(i,iRow)].begin();
-                ConstColumnIterator kEnd = BT_[blockView.row(i,iRow)].end();
-                for (; k!=kEnd; ++k) {
-
-                    ConstColumnIterator l    = BT_[blockView.col(i,j.index())].begin();
-                    ConstColumnIterator lEnd = BT_[blockView.col(i,j.index())].end();
-
-                    for (; l!=lEnd; ++l)
-                        indicesBABT.add(k.index(), l.index());
-
-                }
-
-            }
-
-        }
-
-    }
-
-    // ////////////////////////////////////////////////////////////////////
-    //   Multiply transformation matrix to the global stiffness matrix
-    // ////////////////////////////////////////////////////////////////////
-
-    indicesBABT.exportIdx(totalMatrix);
-    totalMatrix = 0;
-
-    for (int i=0; i<nGrids(); i++) {
-
-        for (size_t iRow = 0; iRow<submat[i]->N(); iRow++) {
-
-            const RowType& row = (*submat[i])[iRow];
-
-            // Loop over all columns of the stiffness matrix
-            ConstColumnIterator j    = row.begin();
-            ConstColumnIterator jEnd = row.end();
-
-            for (; j!=jEnd; ++j) {
-
-                ConstColumnIterator k    = BT_[blockView.row(i,iRow)].begin();
-                ConstColumnIterator kEnd = BT_[blockView.row(i,iRow)].end();
-
-                for (; k!=kEnd; ++k) {
-
-                    ConstColumnIterator l    = BT_[blockView.col(i,j.index())].begin();
-                    ConstColumnIterator lEnd = BT_[blockView.col(i,j.index())].end();
-
-                    for (; l!=lEnd; ++l) {
-
-                        //BABT[k][l] += BT[i][k] * mat_[i][j] * BT[j][l];
-                        MatrixBlock m_ij = *j;
-
-                        MatrixBlock BT_ik_trans;
-                        Dune::MatrixVector::transpose(*k, BT_ik_trans);
-
-                        m_ij.leftmultiply(BT_ik_trans);
-                        m_ij.rightmultiply(*l);
-
-                        totalMatrix[k.index()][l.index()] += m_ij;
-
-                    }
-
-                }
-
-            }
-
-        }
-
-    }
-}
-
-template <class GridType, class VectorType>
-template <class VectorTypeContainer>
-void NBodyAssembler<GridType, VectorType>::
-assembleRightHandSide(const VectorTypeContainer& rhs,
-               VectorType& totalRhs) const
-{
-    // Concatenate the two rhs vectors to a large one
-    VectorType untransformedTotalRhs(BT_.M());
-
-    int idx = 0;
-
-    for (size_t i=0; i<rhs.size(); i++) {
-
-        for (size_t j=0; j<rhs[i].size(); j++)
-            untransformedTotalRhs[idx++] = rhs[i][j];
-
-    }
-
-    if ((int) BT_.M() != idx)
-        DUNE_THROW(Dune::Exception, "assembleRightHandSide: vector size and matrix size don't match!");
-
-    // Transform the basis of the ansatz space
-    totalRhs.resize(untransformedTotalRhs.size());
-    totalRhs = 0;
-    BT_.umtv(untransformedTotalRhs, totalRhs);
-}
-
-
-template <class GridType, class VectorType>
-template <class VectorTypeContainer>
-void NBodyAssembler<GridType, VectorType>::
-postprocess(const VectorType& totalX, VectorTypeContainer& x) const
-{
-    // ///////////////////////////////////////////////////////
-    //   Transform the solution vector to the nodal basis
-    // ///////////////////////////////////////////////////////
-
-    VectorType nodalBasisTotalX(totalX.size());
-    BT_.mv(totalX, nodalBasisTotalX);
-
-
-    // ///////////////////////////////////////////////////////
-    //   Split the total solution vector into the parts
-    //   corresponding to the grids.
-    // ///////////////////////////////////////////////////////
-
-    int idx = 0;
-    for (int i=0; i<nGrids(); i++) {
-
-        x[i].resize(grids_[i]->size(dim));
-
-        for (size_t j=0; j<x[i].size(); j++, idx++)
-            x[i][j] = nodalBasisTotalX[idx];
-    }
-}
-
-template <class GridType, class VectorType>
-template <class VectorTypeContainer>
-void NBodyAssembler<GridType, VectorType>::
-concatenateVectors(const VectorTypeContainer& parts, VectorType& whole)
-{
-    int totalSize = 0;
-    for (size_t i=0; i<parts.size(); i++)
-        totalSize += parts[i].size();
-
-    whole.resize(totalSize);
-
-    int idx = 0;
-    for (size_t i=0; i<parts.size(); i++)
-        for (size_t j=0; j<parts[i].size(); j++)
-            whole[idx++] = parts[i][j];
-
-}
-
-// ////////////////////////////////////////////////////////////////////////////
-//   Turn the initial solutions from the nodal basis to the transformed basis
-// ////////////////////////////////////////////////////////////////////////////
-template <class GridType, class VectorType>
-template <class VectorTypeContainer>
-void NBodyAssembler<GridType, VectorType>::
-nodalToTransformed(const VectorTypeContainer& x,
-                   VectorType& transformedX) const
-{
-    VectorType canonicalTotalX;
-
-    concatenateVectors(x, canonicalTotalX);
-
-    // Make small cg solver
-    Dune::MatrixAdapter<MatrixType,VectorType,VectorType> op(getTransformationMatrix());
-
-    // A preconditioner
-    Dune::SeqILU<MatrixType,VectorType,VectorType> ilu0(getTransformationMatrix(),1.0);
-
-    // A cg solver for nonsymmetric matrices
-    Dune::BiCGSTABSolver<VectorType> bicgstab(op,ilu0,1E-4,100,0);
-
-    // Object storing some statistics about the solving process
-    Dune::InverseOperatorResult statistics;
-
-    // Solve!
-    transformedX = canonicalTotalX;  // seems to be a good initial value
-    bicgstab.apply(transformedX, canonicalTotalX, statistics);
-}
-
-template <class GridType, class VectorType>
-void NBodyAssembler<GridType, VectorType>::
-computeTransformationMatrix()
-{
-    std::cout<<"Setup transformation matrix...";
-    // compute offsets for the different grids
-    std::vector<int> offsets(grids_.size());
-    offsets[0] = 0;
-
-    // P1 elements are hard-wired here
-    size_t k;
-    for (k=0; k<grids_.size()-1; k++)
-        offsets[k+1] = offsets[k] + grids_[k]->size(dim);
-
-    int nRows = offsets[k] + grids_[k]->size(dim);
-    int nCols = nRows;
-
-    // /////////////////////////////////////////////////////////////////
-    //   First create the index structure
-    // /////////////////////////////////////////////////////////////////
-
-    Dune::MatrixIndexSet indicesBT(nRows, nCols);
-
-    // BT_ is the identity plus some off-diagonal elements
-    for (size_t i=0; i<indicesBT.rows(); i++)
-        indicesBT.add(i,i);
-
-    std::vector<std::vector<int> > nonmortarToGlobal(nCouplings());
-    // Enter all the off-diagonal entries
-    for (int i=0; i<nCouplings(); i++) {
-
-        const auto& nonmortarBoundary = contactCoupling_[i]->nonmortarBoundary();
-        // If the contact mapping could not be built at all then skip this coupling
-        if (nonmortarBoundary.numVertices() == 0)
-            continue;
-
-        // The grids involved in this coupling
-        int grid0Idx = coupling_[i].gridIdx_[0];
-        int grid1Idx = coupling_[i].gridIdx_[1];
-
-        // The mapping from nonmortar vertex indices to grid indices
-        nonmortarToGlobal[i].resize(nonmortarBoundary.numVertices());
-        int idx = 0;
-        for (int j=0; j<grids_[grid0Idx]->size(dim); j++)
-            if (nonmortarBoundary.containsVertex(j))
-                nonmortarToGlobal[i][idx++] = j;
-
-        // the off-diagonal part
-        const MatrixType& M = contactCoupling_[i]->mortarLagrangeMatrix();
-        for (size_t j=0; j<M.N(); j++) {
-
-            const RowType& row = M[j];
-
-            ConstColumnIterator cIt    = row.begin();
-            ConstColumnIterator cEndIt = row.end();
-
-            for (; cIt!=cEndIt; ++cIt)
-                indicesBT.add(offsets[grid0Idx] + nonmortarToGlobal[i][j],
-                              offsets[grid1Idx] + cIt.index());
-
-        }
-
-    }
-
-    // ////////////////////////////////////////////////////////////
-    //   Enter the values of the different couplings
-    // ////////////////////////////////////////////////////////////
-
-    indicesBT.exportIdx(BT_);
-    BT_ = 0;
-
-    // Enter identity part
-    for (int i=0; i<nRows; i++)
-        for (int j=0; j<dim; j++)
-            BT_[i][i][j][j] = 1;
-
-    for (int i=0; i<nCouplings(); i++) {
-
-        const auto& nonmortarBoundary = contactCoupling_[i]->nonmortarBoundary();
-        if (nonmortarBoundary.numVertices() == 0)
-            continue;
-
-        // The grids involved in this coupling
-        int grid0Idx = coupling_[i].gridIdx_[0];
-        int grid1Idx = coupling_[i].gridIdx_[1];
-
-        // the off-diagonal part
-        const MatrixType& M = contactCoupling_[i]->mortarLagrangeMatrix();
-        for (size_t j=0; j<M.N(); j++) {
-
-            const RowType& row = M[j];
-
-            ConstColumnIterator cIt    = row.begin();
-            ConstColumnIterator cEndIt = row.end();
-
-            for (; cIt!=cEndIt; ++cIt)
-                BT_[offsets[grid0Idx] + nonmortarToGlobal[i][j]][offsets[grid1Idx] +cIt.index()] = *cIt;
-
-        }
-
-        int offset = offsets[grid0Idx];
-
-        // modify non-mortar dofs and rotate them in normal and tangential coordinates
-        for (int k=0; k<grids_[grid0Idx]->size(dim); k++)
-            if(nonmortarBoundary.containsVertex(k))
-                BT_[offset + k][offset+k] =this->localCoordSystems_[offset + k];
-    }
-}
-
-} /* namespace Contact */
-} /* namespace Dune */
diff --git a/src/spatial-solving/contact/nbodyassembler.hh b/src/spatial-solving/contact/nbodyassembler.hh
deleted file mode 100644
index ae1db365287d1355a56753b509f3d6bc4e717395..0000000000000000000000000000000000000000
--- a/src/spatial-solving/contact/nbodyassembler.hh
+++ /dev/null
@@ -1,200 +0,0 @@
-// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-// vi: set ts=8 sw=4 et sts=4:
-#ifndef DUNE_CONTACT_ASSEMBLERS_N_BODY_MORTAR_ASSEMBLER_HH
-#define DUNE_CONTACT_ASSEMBLERS_N_BODY_MORTAR_ASSEMBLER_HH
-
-#include <dune/common/bitsetvector.hh>
-#include <dune/common/promotiontraits.hh>
-#include <dune/common/fmatrix.hh>
-#include <dune/istl/bcrsmatrix.hh>
-#include <dune/solvers/common/boxconstraint.hh>
-#include <dune/fufem/boundarypatch.hh>
-#include <dune/contact/assemblers/contactassembler.hh>
-#include <dune/contact/common/couplingpair.hh>
-#include <dune/contact/projections/contactprojection.hh>
-#include <dune/contact/assemblers/dualmortarcoupling.hh>
-
-#include "dualmortarcoupling.hh"
-
-#ifdef HAVE_DUNE_GRID_GLUE
-#include <dune/grid-glue/merging/merger.hh>
-#endif
-
-/**  \brief Assembler for mortar discretized contact problems with arbitrary number of bodies.
- *
- *  \tparam GridType Type of the corresponding grids.
- *  \tparam VectorType The vector type for the displacements.
- */
-template <class GridType, class VectorType>
-class NBodyAssembler : public Dune::Contact::ContactAssembler<GridType::dimension, typename VectorType::field_type>
-{
-protected:
-    enum {dim = GridType::dimension};
-
-    using field_type = typename Dune::PromotionTraits<typename VectorType::field_type,
-                                                typename GridType::ctype>::PromotedType;
-
-    using CouplingType = DualMortarCoupling<field_type, GridType>;
-
-    using MatrixBlock = Dune::FieldMatrix<field_type, dim, dim>;
-    using MatrixType = Dune::BCRSMatrix<MatrixBlock>;
-
-    using RowType =  typename MatrixType::row_type;
-    using ConstColumnIterator = typename RowType::ConstIterator;
-
-    using LeafBoundaryPatch = BoundaryPatch<typename GridType::LeafGridView>;
-
-public:
-    /** \brief Construct assembler from number of couplings and grids.
-     *
-     *  \param nGrids The number of involved bodies.
-     *  \param nCouplings The number of couplings.
-     *   \param hierarchyCoupling This boolean determines if the whole hierarchy of mortar matrices should be setup
-     */
-    NBodyAssembler(int nGrids, int nCouplings, bool hierarchyCoupling=false, field_type coveredArea = 0.99) :
-      coveredArea_(coveredArea)
-    {
-        grids_.resize(nGrids);
-
-        coupling_.resize(nCouplings);
-        contactCoupling_.resize(nCouplings);
-        // initialise the couplings with DualMortarCoupling
-        for (int i=0; i<nCouplings; i++)
-            if (hierarchyCoupling)
-                contactCoupling_[i] = std::make_shared<HierarchyCouplingType>();
-            else
-                contactCoupling_[i] = std::make_shared<CouplingType>();
-    }
-
-    /** \brief Get the number of couplings.*/
-    int nCouplings() const {return coupling_.size();}
-
-    /** \brief Get the number of involved bodies.*/
-    int nGrids() const {return grids_.size();}
-
-    /** \brief Get the total number of degrees of freedom of the leaf grids. */
-    int numDofs() const {
-        int n=0;
-        for (int i=0; i<nGrids(); i++)
-            n += grids_[i]->size(dim);
-        return n;
-    }
-
-    /** \brief Setup the patches for the contact boundary and compute the obstacles. */
-    void assembleObstacle();
-
-    /** \brief Assemble the mortar matrices and compute the basis transformation.*/
-    void assembleTransferOperator();
-
-    /** \brief Turn initial solutions from nodal basis to the transformed basis.
-     *         i.e. transformedX = O*B^{-T}nodalX
-     *  \param x Initial solution vector containing nodal coefficients.
-     *  \param transformedX Coefficient vector for all bodies in mortar transformed coordinates.
-     */
-    template <class VectorTypeContainer>
-    void nodalToTransformed(const VectorTypeContainer& x,
-                            VectorType& transformedX) const;
-
-    /** \brief Compute stiffness matrices in mortar transformed coordinates.
-     *         i.e. transformedA = O*B*nodalA*B^T*O^T
-     *  \param submat Stiffness matrices w.r.t the nodal finite element basis.
-     *  \param totalMatrix Reference to mortar transformed stiffness matrix for all bodies.
-     */
-    void assembleJacobian(const std::vector<const MatrixType*>& submat,
-                          MatrixType& totalMatrix) const;
-
-    /** \brief Compute the right hand side in mortar transformed coordinates.
-     *         i.e. totalRhs = O*B*nodalRhs
-     *  \param  rhs Right hand side coefficients w.r.t. the nodal finite element basis.
-     *  \param  totalRhs Reference to coefficient vector w.r.t. the transformed basis.
-     */
-    template <class VectorTypeContainer>
-    void assembleRightHandSide(const VectorTypeContainer& rhs,
-                               VectorType& totalRhs) const;
-
-    /** \brief Transform a vector from local coordinates to canonical coordinates.
-     *
-     *  \param totalX Coefficient vector of the mortar transformed basis.
-     *  \param x    Reference to target vector for the standard nodal coefficients of each body.
-     */
-    template <class VectorTypeContainer>
-    void postprocess(const VectorType& totalX, VectorTypeContainer& x) const;
-
-    /** \brief Concatenate a family of vectors .
-     *
-     * \param parts A vector of vectors.
-     * \param whole The vector to contain the concatenated family
-     */
-    template <class VectorTypeContainer>
-    static void concatenateVectors(const VectorTypeContainer& parts, VectorType& whole);
-
-    /** \brief Get the contact couplings. */
-    const auto& getContactCouplings() const {
-        return contactCoupling_;
-    }
-
-    /** \brief Get the contact couplings. */
-    auto& getContactCouplings() {
-        return contactCoupling_;
-    }
-
-    /** \brief Set the contact couplings. */
-    void setContactCouplings(std::vector<std::shared_ptr<CouplingType> >& contactCouplings) {
-
-        contactCoupling_.resize(contactCouplings.size());
-        for (size_t i=0; i<contactCouplings.size(); i++)
-            contactCoupling_[i] = contactCouplings[i];
-    }
-
-    /** \brief Get the transposed of the mortar transformation matrix B^T.*/
-    const MatrixType& getTransformationMatrix() const {return BT_;}
-
-    /** \brief Get the grids. */
-    const std::vector<const GridType*> getGrids() const { return grids_; }
-
-    /** \brief Set the grids. */
-    void setGrids(const std::vector<const GridType*>& grids) {grids_ = grids;}
-
-    /** \brief Set grids. */
-    void setCoupling(const CouplingPair<GridType, GridType, field_type>& coupling, size_t i) {
-        coupling_[i] = coupling;
-    }
-
-    /** \brief Get reference to i'th coupling. */
-    const auto& getCoupling(size_t i) const {return coupling_[i];}
-
-protected:
-    /** \brief Compute the transposed mortar transformation matrix. */
-    void computeTransformationMatrix();
-
-    /** \brief Setup the Householder reflections. */
-    void assembleHouseholderReflections();
-
-public:
-    /** \brief Bitvector for all bodies whose flags are set if a dof has an obstacle.*/
-    Dune::BitSetVector<dim> totalHasObstacle_;
-
-    /** \brief Obstacles for all bodies on the leafview.*/
-    std::vector<BoxConstraint<field_type,dim> > totalObstacles_;
-
-    /** \brief The mortar couplings between grid pairs */
-    std::vector<std::shared_ptr<CouplingType> > contactCoupling_;
-
-    /** \brief The coupling pairs. */
-    std::vector<CouplingPair<GridType,GridType,field_type> > coupling_;
-
-    /** \brief Vector containing the involved grids. */
-    std::vector<const GridType*> grids_;
-
-    /** \brief The transposed of the mortar transformation matrix. */
-    MatrixType BT_;
-
-    /** \brief Dismiss all faces that are not at least covered by the grid-glue projection for this
-     *         much percentage ranging between one - for total coverage and zero for taking all faces.
-     */
-    field_type coveredArea_;
-};
-
-#include "nbodyassembler.cc"
-
-#endif
diff --git a/src/spatial-solving/preconditioners/CMakeLists.txt b/src/spatial-solving/preconditioners/CMakeLists.txt
index c5f8a1b52872ab6b9de00bebca17b7077454e541..00e132a99faa7bc54408ea5df6ead98b1a9c4cd5 100644
--- a/src/spatial-solving/preconditioners/CMakeLists.txt
+++ b/src/spatial-solving/preconditioners/CMakeLists.txt
@@ -1,7 +1,7 @@
 add_custom_target(dune-tectonic_spatial-solving_preconditioners_src SOURCES
   hierarchicleveliterator.hh
-  levelglobalpreconditioner.hh
   levelpatchpreconditioner.hh
+  localproblem.hh
   multilevelpatchpreconditioner.hh
   nbodycontacttransfer.hh
   supportpatchfactory.hh
diff --git a/src/spatial-solving/preconditioners/levelglobalpreconditioner.hh b/src/spatial-solving/preconditioners/levelglobalpreconditioner.hh
deleted file mode 100644
index e593c60daee0051737b80ee1e7d3ee558ba4bcad..0000000000000000000000000000000000000000
--- a/src/spatial-solving/preconditioners/levelglobalpreconditioner.hh
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef LEVEL_GLOBAL_PRECONDITIONER_HH
-#define LEVEL_GLOBAL_PRECONDITIONER_HH
-
-#include <string>
-
-#include <dune/common/timer.hh>
-#include <dune/common/fvector.hh>
-
-#include <dune/solvers/iterationsteps/lineariterationstep.hh>
-
-//#include <dune/istl/superlu.hh>
-#include <dune/istl/umfpack.hh>
-
-#include "../../data-structures/levelcontactnetwork.hh"
-
-
-template <class LevelContactNetwork, class Solver, class MatrixType, class VectorType>
-class LevelGlobalPreconditioner : public LinearIterationStep<MatrixType, VectorType> {
-
-private:
-    using Base = LinearIterationStep<MatrixType, VectorType>;
-
-    using ctype = typename LevelContactNetwork::ctype;
-
-    const LevelContactNetwork& levelContactNetwork_;
-    const int level_;
-
-    std::shared_ptr<Solver> solver_;
-
-public:
-
-    LevelGlobalPreconditioner(const LevelContactNetwork& levelContactNetwork, const int level = 0) :
-          levelContactNetwork_(levelContactNetwork),
-          level_(level) {
-
-        this->verbosity_ = QUIET;
-    }
-
-    void setSolver(Solver&& patchSolver) {
-        solver_ = Dune::Solvers::wrap_own_share<PatchSolver>(std::forward<PatchSolver>(patchSolver));
-    }
-
-    void iterate() override {
-        Dune::Timer timer;
-
-        if (this->verbosity_ == FULL) {
-            timer.reset();
-            timer.start();
-        }
-
-        *(this->x_) = 0;
-
-        auto& step = solver_->getIterationStep();
-        step.setProblem(this->mat_, this->x_, this->rhs_);
-        step.setIgnore(this->ignoreNodes_);
-
-        solver_->check();
-        solver_->preprocess();
-        solver_->solve();
-
-        *(this->x_) = solver_->getSol();
-
-        if (this->verbosity_ == FULL) {
-            std::cout << "LevelGlobalPreconditioner::iterate() Solving global problem took: " << timer.stop() << " seconds" << std::endl;
-        }
-    }
-
-    /*void iterate() override {
-        Dune::Timer timer;
-        timer.reset();
-        timer.start();
-
-        this->x_->resize(matrix_.M());
-        *(this->x_) = 0;
-
-        #if HAVE_SUPERLU
-        Dune::InverseOperatorResult res;
-        VectorType rhsCopy(rhs_);
-
-        Dune::UMFPack<MatrixType> solver(matrix_);
-        solver.apply(*(this->x_), rhsCopy, res);
-
-        #else
-        #error No SuperLU!
-        #endif
-
-        //std::cout << "LevelGlobalPreconditioner::iterate() Solving global problem took: " << timer.elapsed() << " seconds" << std::endl;
-
-    }*/
-
-};
-#endif
-
diff --git a/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh
index 6135de9c97dab8a8e4d575718cc54f67f1af10ed..a515f6e5b6405f767168c5734995a0ccca108095 100644
--- a/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh
+++ b/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh
@@ -13,7 +13,6 @@
 #include "../../data-structures/levelcontactnetwork.hh"
 
 #include "supportpatchfactory.hh"
-#include "../tnnmg/localproblem.hh"
 
 #include <dune/localfunctions/lagrange/pqkfactory.hh>
 
@@ -120,27 +119,6 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy
                     if (!vertexVisited[globalIdx][0]) {
                         vertexVisited[globalIdx][0] = true;
                         patchFactory_.build(bodyIdx, e, i, patches_[globalIdx], patchDepth_);
-
-                        /*print(patches_[globalIdx], "patch:");
-
-                        size_t c = 0;
-                        for (size_t j=0; j<levelContactNetwork_.nBodies(); j++) {
-                            const auto& gv = fineContactNetwork_.body(j)->gridView();
-
-                            printDofLocation(gv);
-
-                            Dune::BlockVector<Dune::FieldVector<ctype, 1>> patchVec(gv.size(dim));
-                            for (size_t l=0; l<patchVec.size(); l++) {
-                                if (patches_[globalIdx][c++][0]) {
-                                    patchVec[l][0] = 1;
-                                }
-                            }
-
-                            //print(patchVec, "patchVec");
-
-                            // output patch
-                            writeToVTK(gv, patchVec, "", "level_" + std::to_string(level_) + "_patch_" + std::to_string(globalIdx) + "_body_" + std::to_string(j));
-                        }*/
                     }
                 }
             }
@@ -201,27 +179,14 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy
             patchSolver_->solve();
 
             *(this->x_) += x;
-
-
-
-            /*LocalProblem<MatrixType, VectorType> localProblem(*this->mat_, *this->rhs_, ignore);
-            Vector newR;
-            localProblem.getLocalRhs(x, newR); */
-
-            /*print(ignore, "ignore:");
-            print(*this->mat_, "Mat:");
-            print(localProblem.getMat(), "localMat:");*/
-
-            /*patchSolver_->setProblem(localProblem.getMat(), x, newR);
-            patchSolver_->preprocess();
-            patchSolver_->solve();
-
-            *(this->x_) += x;*/
         }
     }
 
     void iterateMult() {
         *(this->x_) = 0;
+
+        DUNE_THROW(Dune::Exception, "Not implemented!");
+
 /*
         VectorType x = *(this->x_);
         for (size_t i=0; i<patches_.size(); i++) {
diff --git a/src/spatial-solving/tnnmg/localproblem.hh b/src/spatial-solving/preconditioners/localproblem.hh
similarity index 100%
rename from src/spatial-solving/tnnmg/localproblem.hh
rename to src/spatial-solving/preconditioners/localproblem.hh
diff --git a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
index 9d6d64e6eaf8391c6fe6e88290c3a76140130ee1..b187da5372f084a446c27b99205c71db66d73d4f 100644
--- a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
+++ b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
@@ -19,8 +19,7 @@
 
 #include "nbodycontacttransfer.hh"
 #include "levelpatchpreconditioner.hh"
-
-#include "../../utils/debugutils.hh"
+#include "localproblem.hh"
 
 template <class ContactNetwork, class MatrixType, class VectorType>
 class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorType> {
diff --git a/src/spatial-solving/preconditioners/test/CMakeLists.txt b/src/spatial-solving/preconditioners/test/CMakeLists.txt
deleted file mode 100644
index 3a5964adeb30007351d7b9a5c14236191cbe0222..0000000000000000000000000000000000000000
--- a/src/spatial-solving/preconditioners/test/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# Put your test in here if it needs access to external grids
-set(FAULTNETWORKS_PRECONDITIONERS_TESTS
-  levelfaultpreconditionertest
-  )
-
-set(TESTS ${FAULTNETWORKS_PRECONDITIONERS_TESTS})
-
-# Setup targets, register tests, and add dune flags
-foreach(_test ${TESTS})
-  #dune_add_test(SOURCES ${_test}.cc)
-endforeach()
-
diff --git a/src/spatial-solving/preconditioners/test/Makefile.am b/src/spatial-solving/preconditioners/test/Makefile.am
deleted file mode 100644
index a4c19c2c84cac95071500f9fa9c79aa2677057d1..0000000000000000000000000000000000000000
--- a/src/spatial-solving/preconditioners/test/Makefile.am
+++ /dev/null
@@ -1,42 +0,0 @@
-# which tests where program to build and run are equal
-NORMALTESTS = levelfaultpreconditionertest
-
-# list of tests to run 
-TESTS = $(NORMALTESTS)
-
-# programs just to build when "make check" is used
-check_PROGRAMS = $(NORMALTESTS)
-
-# define the programs
-levelfaultpreconditionertest_SOURCES = levelfaultpreconditionertest.cc
-
-
-levelfaultpreconditionertest_CPPFLAGS = $(AM_CPPFLAGS) \
-	$(DUNEMPICPPFLAGS) \
-	$(UG_CPPFLAGS)
-	
-# The libraries have to be given in reverse order (most basic libraries
-# last).  Also, due to some misunderstanding, a lot of libraries include the
-# -L option in LDFLAGS instead of LIBS -- so we have to include the LDFLAGS
-# here as well.
-levelfaultpreconditionertest_LDADD = \
-	$(DUNE_LDFLAGS) $(DUNE_LIBS) \
-	$(UG_LDFLAGS) $(UG_LIBS) \
-	$(DUNEMPILIBS)	\
-	$(LDADD)
-levelfaultpreconditionertest_LDFLAGS = $(AM_LDFLAGS) \
-	$(DUNEMPILDFLAGS) \
-	$(UG_LDFLAGS) \
-	$(DUNE_LDFLAGS)
-
-# don't follow the full GNU-standard
-# we need automake 1.9
-AUTOMAKE_OPTIONS = foreign 1.9
-
-# pass most important options when "make distcheck" is used
-DISTCHECK_CONFIGURE_FLAGS = --with-dune-common=$(DUNE_COMMON_ROOT) --with-dune-geometry=$(DUNE_GEOMETRY_ROOT) --with-dune-grid=$(DUNE_GRID_ROOT) --with-dune-istl=$(DUNE_ISTL_ROOT) --with-dune-localfunctions=$(DUNE_LOCALFUNCTIONS_ROOT) --with-dune-solvers=$(DUNE_SOLVERS_ROOT) --with-dune-fufem=$(DUNE_FUFEM_ROOT)  CXX="$(CXX)" CC="$(CC)"
-
-EXTRA_DIST = CMakeLists.txt
-
-include $(top_srcdir)/am/global-rules
-
diff --git a/src/spatial-solving/preconditioners/test/levelfaultpreconditionertest.cc b/src/spatial-solving/preconditioners/test/levelfaultpreconditionertest.cc
deleted file mode 100644
index 69b2283a34652d187aa57bf7bb0623e0168cb519..0000000000000000000000000000000000000000
--- a/src/spatial-solving/preconditioners/test/levelfaultpreconditionertest.cc
+++ /dev/null
@@ -1,274 +0,0 @@
-#include <config.h>
-
-#include <dune/common/parallel/mpihelper.hh>
-
-#include <dune/grid/uggrid.hh>
-#include <dune/grid/common/mcmgmapper.hh>
-
-#include <dune/fufem/assemblers/localassemblers/laplaceassembler.hh>
-
-#include <dune/faultnetworks/interfacenetwork.hh>
-#include <dune/faultnetworks/faultfactories/multileveluniformfaultfactory.hh>
-#include <dune/faultnetworks/preconditioners/levelfaultpreconditioner.hh>
-#include <dune/faultnetworks/preconditioners/multilevelfaultpreconditioner.hh>
-#include <dune/faultnetworks/assemblers/intersectionjumpmassassembler.hh>
-#include <dune/faultnetworks/faultp1nodalbasis.hh>
-#include <dune/faultnetworks/utils/debugutils.hh>
-
-const int dim = 2;
-
-const int coarseResolution = 2;
-const int fineResolution = 3;
-const int exactResolution = 4;
-
-const int faultCount = 3;
-
-
-typedef typename Dune::UGGrid<dim> GridType;
-typedef typename GridType::LevelGridView GridView;
-typedef typename GridType::LevelIntersection Intersection;
-typedef typename GridType::template Codim<0>::Entity Element;
-
-static const int dimElement = Element::dimension;
-
-void gridLevelOutput(const GridType& grid, const int level) {
-    std::cout << "Grid elements on lvl " << level << std::endl << std::endl;
-
-    typedef typename GridView::template Codim<0>::Iterator ElementLevelIterator;
-    GridView gridView(grid.levelGridView(level));
-
-    //Dune::LevelMultipleCodimMultipleGeomTypeMapper <GridType,  Dune::MCMGElementLayout > mapper(grid, level);
-    Dune::LevelMultipleCodimMultipleGeomTypeMapper <GridType, Dune::MCMGVertexLayout > vMapper(grid, level);
-
-    Dune::BitSetVector<1> vertexPrinted(vMapper.size(), false);
-
-    ElementLevelIterator elemIt = gridView.template begin<0>();
-    ElementLevelIterator elemEndIt = gridView.template end<0>();
-    for (; elemIt!=elemEndIt; ++elemIt) {
-        const Element& elem = *elemIt;
-        const auto& geometry = elem.geometry();
-
-        for(int i=0; i<geometry.corners(); ++i) {
-            size_t globalIdx = gridView.indexSet().subIndex(elem, i, Element::dimension);
-            if (!vertexPrinted[globalIdx][0]) {
-                const auto& vertex = geometry.corner(i);
-                print(vertex, "elem corner:" + std::to_string(globalIdx));
-                vertexPrinted[globalIdx][0] = true;
-            }
-        }
-    }
-    std::cout << "----------------" << std::endl << std::endl;
-	
-    /*
-    ElementLevelIterator elemIt = gridView.template begin<0>();
-    ElementLevelIterator elemEndIt = gridView.template end<0>();
-    for (; elemIt!=elemEndIt; ++elemIt) {
-        const Element& elem = *elemIt;
-        const auto& geometry = elem.geometry();
-
-        std::cout << "Element idx: " << mapper.index(elem) << std::endl;
-
-        for(int i=0; i<geometry.corners(); ++i) {
-            size_t globalIdx = gridView.indexSet().subIndex(elem, i, Element::dimension);
-            const auto& vertex = geometry.corner(i);
-            print(vertex, "elem corner:" + std::to_string(globalIdx));
-        }
-        std::cout << "----------------" << std::endl << std::endl;
-    }*/
-
-}
-
-
-void faultInterfaceOutput(const FaultInterface<GridView>& faultInterface) {
-    std::cout << "Level: " << faultInterface.level() << "  global faultID: " << faultInterface.id() << std::endl;
-
-    const std::set<size_t>& interfaceDofs = faultInterface.getInterfaceDofs();
-    print(interfaceDofs, "");
-}
-
-void interfaceNetworkLevelOutput(const InterfaceNetwork<GridType>& interfaceNetwork, const int level) {
-    const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork = interfaceNetwork.levelInterfaceNetwork(level);
-
-    std::cout << "LevelInterfaceNetwork level: " << level << std::endl;
-    for (size_t i=0; i<levelInterfaceNetwork.size(); i++) {
-        std::cout << "local faultID : " << i << "  ";
-        faultInterfaceOutput(*(levelInterfaceNetwork.getInterface(i)));
-    }
-
-    std::cout << "------------------------------" << std::endl << std::endl;
-}
-
-void computeIntersectionDofs(const GridView& gridView, const Intersection& intersection, std::set<size_t>& intersectionDofs) {
-    intersectionDofs.clear();
-
-    // loop over all vertices of the intersection
-    const Element& insideElement = intersection.inside();
-			
-    const auto& refElement = Dune::ReferenceElements<double,dimElement>::general(insideElement.type());
-    for (int i=0; i<refElement.size(intersection.indexInInside(), 1, dimElement); i++) {
-        size_t idxInElement = refElement.subEntity(intersection.indexInInside(), 1, i, dimElement);
-        size_t globalIdx = gridView.indexSet().subIndex(insideElement, idxInElement, dimElement);
-        intersectionDofs.insert(globalIdx);
-     }
-}
-
-void prolongFaultDofs(const GridType& grid, const FaultInterface<GridView>& faultInterface, const int toLevel, std::set<size_t>& prolongedDofs) {
-    prolongedDofs.clear();
-
-    const std::vector<Intersection>& faces = faultInterface.faces();
-    const GridView gridView(grid.levelGridView(toLevel));
-
-    for (size_t i=0; i<faces.size(); i++) {
-        const Intersection& intersection = faces[i];
-        Face<GridType> face(grid, intersection.inside(), intersection.indexInInside());
-
-        typename Face<GridType>::HierarchicIterator exactIt = face.hbegin(toLevel);
-        typename Face<GridType>::HierarchicIterator exactEnd = face.hend(toLevel);
-        for(; exactIt!=exactEnd; ++exactIt) {
-            if (exactIt->level() == toLevel) {
-                std::set<size_t> faceDofs;
-                computeIntersectionDofs(gridView, *(exactIt->intersection()), faceDofs);
-
-                prolongedDofs.insert(faceDofs.begin(), faceDofs.end());
-            }
-        }
-    }
-}
-
-void prolongInterfaceNetworkLevelDofs(const GridType& grid, const InterfaceNetwork<GridType>& interfaceNetwork, const int level, const int toLevel, std::vector<std::set<size_t>>& prolongedFaultDofs) {
-    prolongedFaultDofs.resize(0);
-
-    const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork = interfaceNetwork.levelInterfaceNetwork(level);
-
-    std::cout << "Correct prolonged LevelInterfaceNetwork level " << level << " to level " << toLevel << std::endl;
-    for (size_t i=0; i<levelInterfaceNetwork.size(); i++) {
-        std::set<size_t> prolongedDofs;
-        prolongFaultDofs(grid, *(levelInterfaceNetwork.getInterface(i)), toLevel, prolongedDofs);
-
-        print(prolongedDofs, "local faultID: " + std::to_string(i));
-        prolongedFaultDofs.push_back(prolongedDofs);
-    }
-
-    std::cout << "------------------------------" << std::endl << std::endl;
-}
-
-int main(int argc, char** argv) try
-{
-    typedef double ctype;
-
-    Dune::MPIHelper::instance(argc, argv);
-
-    std::ofstream out("/home/mi/podlesny/software/dune/faultnetworks/dune/faultnetworks/preconditioners/test/levelfaultpreconditionertest.log");
-    std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
-    std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
-
-    const int fineLevelIdx = fineResolution - coarseResolution;
-    const int exactLevelIdx = exactResolution - coarseResolution;
-
-    std::vector<int> faultToLevel(faultCount);
-    for (size_t i=0; i<faultToLevel.size(); ) {
-        for (int j=fineLevelIdx; j>0 && i<faultToLevel.size(); j--) {
-            faultToLevel[i] = j;
-            i++;
-        }
-
-        for (int j=0; j<fineLevelIdx && i<faultToLevel.size(); j++) {
-            faultToLevel[i] = j;
-            i++;
-        }
-    }
-
-    print(faultToLevel, "faultToLevel: ");
-
-    MultilevelUniformFaultFactory<GridType> faultFactory(faultCount, faultToLevel, coarseResolution, exactLevelIdx);
-    const InterfaceNetwork<GridType>& interfaceNetwork = faultFactory.interfaceNetwork();
-
-    /*
-    const GridType& grid = faultFactory.grid();
-
-    gridLevelOutput(grid, 0);
-    gridLevelOutput(grid, fineLevelIdx);
-    gridLevelOutput(grid, exactLevelIdx);
-
-    interfaceNetworkLevelOutput(interfaceNetwork, 0);
-    interfaceNetworkLevelOutput(interfaceNetwork, fineLevelIdx);
-    interfaceNetworkLevelOutput(interfaceNetwork, exactLevelIdx); */
-
-    typedef typename Dune::BlockVector<Dune::FieldVector<ctype,1>> VectorType;
-    typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<ctype, 1, 1>> MatrixType;
-
-    typedef FaultP1NodalBasis<GridView, ctype> DGBasis;
-    typedef typename DGBasis::LocalFiniteElement DGFE;
-
-    typedef IntersectionJumpMassAssembler<GridView, DGFE, DGFE> LocalInterfaceAssembler;
-    typedef Dune::Matrix<Dune::FieldMatrix<double,1,1>, std::allocator<Dune::FieldMatrix<double,1,1>>> OscMatrixType;
-    OscMatrixType B(2,2);
-    B[0][0] = 1;
-    B[1][1] = 1;
-    B[0][1] = -1;
-    B[1][0] = -1;
-
-    //--------------------------------------------------------------
-    // Multilevelfaultpreconditioner
-    //--------------------------------------------------------------
-
-    // setting local assemblers for laplace operator
-    LocalInterfaceAssembler localInterfaceAssembler(B);
-    typedef LaplaceAssembler<GridType, DGFE, DGFE> LocalLaplaceAssembler;
-    LocalLaplaceAssembler localAssembler;
-
-    Dune::BitSetVector<1> activeLevels(fineLevelIdx+1, true);
-    print(activeLevels, "activeLevels: ");
-
-    std::vector<std::shared_ptr<LocalLaplaceAssembler>> localAssemblers;
-    std::vector<std::shared_ptr<LocalInterfaceAssembler>> localIntersectionAssemblers;
-
-    localAssemblers.resize(activeLevels.size());
-    localIntersectionAssemblers.resize(activeLevels.size());
-
-    for (size_t i=0; i<activeLevels.size(); i++) {
-        localAssemblers[i] = std::make_shared<LocalLaplaceAssembler>(localAssembler);
-        localIntersectionAssemblers[i] = std::make_shared<LocalInterfaceAssembler>(localInterfaceAssembler);
-    }
-
-    MultilevelFaultPreconditioner<DGBasis, LocalLaplaceAssembler, LocalInterfaceAssembler, MatrixType, VectorType> preconditioner(interfaceNetwork, activeLevels, localAssemblers, localIntersectionAssemblers);
-
-    MatrixType matrix;
-    VectorType mgX(preconditioner.basis().size());
-    VectorType mgRhs(preconditioner.basis().size());
-    mgRhs = 0;
-
-    preconditioner.setProblem(matrix, mgX, mgRhs);
-    preconditioner.iterate();
-
-    const VectorType& mgSol = preconditioner.getSol();
-    print(mgSol, "mgSol: ");
-
-    step(0);
-
-    const LevelInterfaceNetwork<GridView>& levelInterfaceNetwork = interfaceNetwork.levelInterfaceNetwork(1);
-    LevelFaultPreconditioner<DGBasis, LocalLaplaceAssembler, LocalInterfaceAssembler, MatrixType, VectorType> levelFaultPreconditioner(levelInterfaceNetwork, localAssembler, localInterfaceAssembler);
-
-    step(1);
-
-    VectorType x(levelFaultPreconditioner.basis().size());
-    VectorType rhs(levelFaultPreconditioner.basis().size());
-    rhs = 0;
-
-    step(2);
-
-
-    levelFaultPreconditioner.setProblem(matrix, x, rhs);
-
-    step(3);
-
-    levelFaultPreconditioner.iterate();
-
-    const VectorType& sol = levelFaultPreconditioner.getSol();
-
-    print(sol, "sol: ");
-
-    std::cout.rdbuf(coutbuf);
-} catch (Dune::Exception e){
-  std::cout << e << std::endl;
-}
diff --git a/src/spatial-solving/preconditioners/test/levelfaultpreconditionertest.log b/src/spatial-solving/preconditioners/test/levelfaultpreconditionertest.log
deleted file mode 100644
index a66d14bfdf5e4aed77911c4071d9eda95e757075..0000000000000000000000000000000000000000
--- a/src/spatial-solving/preconditioners/test/levelfaultpreconditionertest.log
+++ /dev/null
@@ -1,26 +0,0 @@
-faultToLevel: 
-1 0 1 
-
-Coarse and fine grid were generated!
-activeLevels: 
-1 1 
-
-Initializing local fine grid corrections! 
-
-Total setup time: 0.000599407 seconds.
-Initializing local fine grid corrections! 
-
-Total setup time: 0.00250133 seconds.
-mgSol: 
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
-
- Step 0!
-Initializing local fine grid corrections! 
-
-Total setup time: 0.00260553 seconds.
- Step 1!
- Step 2!
- Step 3!
-sol: 
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
-
diff --git a/src/spatial-solving/tnnmg/CMakeLists.txt b/src/spatial-solving/tnnmg/CMakeLists.txt
index 698f4e86b7c4c100104d4aa3372ac418b0f7f20e..d32080a39f211c3f91f60516d56274e94808dd29 100644
--- a/src/spatial-solving/tnnmg/CMakeLists.txt
+++ b/src/spatial-solving/tnnmg/CMakeLists.txt
@@ -4,7 +4,5 @@ add_custom_target(dune-tectonic_spatial-solving_tnnmg_src SOURCES
   linearcorrection.hh
   linesearchsolver.hh
   localbisectionsolver.hh
-  localproblem.hh
-  tnnmgstep.hh
   zerononlinearity.hh
 )
diff --git a/src/spatial-solving/tnnmg/linearcorrection.hh b/src/spatial-solving/tnnmg/linearcorrection.hh
index 188d580fa41d56f4d32220591fc502d91a1e2e73..5cf2eae90d6404fa6fb3cf821e1f42797fe742dd 100644
--- a/src/spatial-solving/tnnmg/linearcorrection.hh
+++ b/src/spatial-solving/tnnmg/linearcorrection.hh
@@ -11,7 +11,6 @@
 
 #include <dune/solvers/common/resize.hh>
 #include <dune/solvers/solvers/umfpacksolver.hh>
-#include "localproblem.hh"
 
 /**
  * \brief linear correction step for use by \ref TNNMGStep
diff --git a/src/spatial-solving/tnnmg/tnnmgstep.hh b/src/spatial-solving/tnnmg/tnnmgstep.hh
deleted file mode 100644
index 1d43966459194bd613a121eb2d020869551ad39d..0000000000000000000000000000000000000000
--- a/src/spatial-solving/tnnmg/tnnmgstep.hh
+++ /dev/null
@@ -1,286 +0,0 @@
-#ifndef DUNE_TECTONIC_TRUNCATED_NONSMOOTH_NEWTON_MULTIGRID_HH
-#define DUNE_TECTONIC_TRUNCATED_NONSMOOTH_NEWTON_MULTIGRID_HH
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <iomanip>
-
-#include <dune/common/timer.hh>
-
-#include <dune/solvers/common/resize.hh>
-#include "dune/solvers/iterationsteps/iterationstep.hh"
-#include "dune/solvers/iterationsteps/lineariterationstep.hh"
-#include <dune/solvers/solvers/iterativesolver.hh>
-#include <dune/solvers/solvers/linearsolver.hh>
-#include <dune/solvers/common/canignore.hh>
-
-#include <dune/solvers/solvers/umfpacksolver.hh>
-
-#include "localproblem.hh"
-
-#include "linearcorrection.hh"
-//#include <dune/tnnmg/iterationsteps/linearcorrection.hh>
-
-#include <dune/tectonic/../../src/utils/debugutils.hh>
-
-
-/**
- * \brief One iteration of the TNNMG method
- *
- * \tparam F Functional to minimize
- * \tparam BV Bit-vector type for marking ignored components
- */
-template<class F, class BV, class Linearization,
-                                  class DefectProjection,
-                                  class LineSearchSolver>
-class TNNMGStep :
-  public IterationStep<typename F::Vector, BV>
-{
-  using Base = IterationStep<typename F::Vector, BV>;
-
-public:
-
-  using Vector = typename F::Vector;
-  using ConstrainedVector = typename Linearization::ConstrainedVector;
-  using ConstrainedMatrix = typename Linearization::ConstrainedMatrix;
-  using BitVector = typename Base::BitVector;
-  using ConstrainedBitVector = typename Linearization::ConstrainedBitVector;
-  using Functional = F;
-  using IterativeSolver = Dune::Solvers::IterativeSolver< ConstrainedVector, Dune::Solvers::DefaultBitVector_t<ConstrainedVector> >;
-  using LinearSolver = Dune::Solvers::LinearSolver< ConstrainedMatrix,  ConstrainedVector >;
-
-  /** \brief Constructor with an iterative solver object for the linear correction
-   * \param iterativeSolver This is a callback used to solve the constrained linearized system
-   * \param projection This is a callback used to compute a projection into a defect-admissible set
-   * \param lineSolver This is a callback used to minimize a directional restriction of the functional
-   *        for computing a damping parameter
-   */
-  TNNMGStep(const Functional& f,
-            Vector& x,
-            std::shared_ptr<IterationStep<Vector,BitVector> > nonlinearSmoother,
-            std::shared_ptr<IterativeSolver> iterativeSolver,
-            const DefectProjection& projection,
-            const LineSearchSolver& lineSolver)
-  : Base(x),
-    f_(&f),
-    nonlinearSmoother_(nonlinearSmoother),
-    linearCorrection_(buildLinearCorrection<ConstrainedMatrix>(iterativeSolver)),
-    projection_(projection),
-    lineSolver_(lineSolver)
-  {}
-
-  /** \brief Constructor with a linear solver object for the linear correction
-   * \param linearSolver This is a callback used to solve the constrained linearized system
-   * \param projection This is a callback used to compute a projection into a defect-admissible set
-   * \param lineSolver This is a callback used to minimize a directional restriction of the functional
-   *        for computing a damping parameter
-   */
-  TNNMGStep(const Functional& f,
-            Vector& x,
-            std::shared_ptr<IterationStep<Vector,BitVector> > nonlinearSmoother,
-            std::shared_ptr<LinearSolver> linearSolver,
-            const DefectProjection& projection,
-            const LineSearchSolver& lineSolver)
-  : Base(x),
-    f_(&f),
-    nonlinearSmoother_(nonlinearSmoother),
-    linearCorrection_(buildLinearCorrection(linearSolver)),
-    projection_(projection),
-    lineSolver_(lineSolver)
-  {}
-
-  /** \brief Constructor with a LinearIterationStep object for the linear correction
-   * \param linearIterationStep This is a callback used to solve the constrained linearized system
-   * \param projection This is a callback used to compute a projection into a defect-admissible set
-   * \param lineSolver This is a callback used to minimize a directional restriction of the functional
-   *        for computing a damping parameter
-   */
-  TNNMGStep(const Functional& f,
-            Vector& x,
-            std::shared_ptr<Dune::Solvers::IterationStep<Vector,BitVector> > nonlinearSmoother,
-            std::shared_ptr<Dune::Solvers::LinearIterationStep<ConstrainedMatrix,ConstrainedVector> > linearIterationStep,
-            unsigned int noOfLinearIterationSteps,
-            const DefectProjection& projection,
-            const LineSearchSolver& lineSolver)
-  : Base(x),
-    f_(&f),
-    nonlinearSmoother_(nonlinearSmoother),
-    linearCorrection_(buildLinearCorrection(linearIterationStep, noOfLinearIterationSteps)),
-    projection_(projection),
-    lineSolver_(lineSolver)
-  {}
-
-  using Base::getIterate;
-
-  void preprocess() override
-  {
-    nonlinearSmoother_->setIgnore(this->ignore());
-    nonlinearSmoother_->preprocess();
-  }
-
-  void setPreSmoothingSteps(std::size_t i)
-  {
-    preSmoothingSteps_ = i;
-  }
-
-  auto energy(const Vector& v) const {
-      Vector temp;
-      Dune::Solvers::resizeInitializeZero(temp, v);
-      f_->quadraticPart().umv(v, temp);
-      temp *= 0.5;
-      temp -= f_->linearPart();
-      return temp*v;
-  }
-
-  /**
-   * \brief Do one TNNMG step
-   */
-  void iterate() override
-  {
-
-    const auto& f = *f_;
-    const auto& ignore = (*this->ignoreNodes_);
-    auto& x = *getIterate();
-
-    //std::cout << "TNNMGStep::iterate " << std::endl;
-
-    //print(f.quadraticPart(), "f.quadraticPart():");
-
-    //print(f.linearPart(), "f.linearPart():");
-
-    //std::cout << "-- energy before smoothing: " << f(x) << std::endl;
-
-    //print(x, "TNNMG iterate after smoothing:");
-
-    // Nonlinear presmoothing
-    for (std::size_t i=0; i<preSmoothingSteps_; ++i)
-        nonlinearSmoother_->iterate();
-
-    //std::cout << "- nonlinear presmoothing: success" << std::endl;
-    //print(x, "TNNMG iterate after smoothing:");
-
-    //std::cout << "-- energy after presmoothing: " << f(x) << std::endl;
-
-    // Compute constraint/truncated linearization
-    if (not linearization_)
-      linearization_ = std::make_shared<Linearization>(f, ignore);
-
-    linearization_->bind(x);
-
-    auto&& A = linearization_->hessian();
-    auto&& r = linearization_->negativeGradient();
-
-    /*print(A, "TNNMG Linear problem matrix:");
-    print(r, "TNNMG Linear problem rhs:");
-    print(ignore, "ignore:");
-    print(linearization_->truncated(), "truncation:");*/
-
-    // Compute inexact solution of the linearized problem
-    Dune::Solvers::resizeInitializeZero(correction_, x);
-    Dune::Solvers::resizeInitializeZero(constrainedCorrection_, r);
-
-
-
-    //print(constrainedCorrection_compare, "direct solver solution:");
-
-    //std::cout << "- computing linear correction..." << std::endl;
-
-    //linearCorrection_(A, constrainedCorrection_, r, ignore);
-
-    //DUNE_THROW(Dune::Exception, "TNNMGStep: Just need to terminate here!");
-
-    linearCorrection_(A, constrainedCorrection_, r, ignore);
-
-    //std::cout << "- linear correction: success" << std::endl;
-
-    //print(constrainedCorrection_, "contrained correction:");
-
-    linearization_->extendCorrection(constrainedCorrection_, correction_);
-
-    /*Vector h = x;
-    h += correction_;
-    std::cout << "-- energy after linear correction: " << energy(h) << std::endl;*/
-
-    //std::cout << "- extended correction: success" << std::endl;
-    //print(correction_, "correction:");
-
-    //std::cout << "-- energy before projection: " << f(x) << std::endl;
-
-    // Project onto admissible set
-    projection_(f, x, correction_);
-
-    //std::cout << "-- energy after projection: " << f(x) << std::endl;
-
-    //std::cout << "- projection onto admissible set: success" << std::endl;
-
-    //print(correction_, "correction:");
-
-    double const correctionNorm = correction_.two_norm();
-    correction_ /= correctionNorm;
-
-
-    // Line search
-    auto fv = directionalRestriction(f, x, correction_);
-
-   /* std::cout << fv.quadraticPart() << " f.quadraticPart():"  << std::endl;
-    std::cout << fv.linearPart() << " f.linearPart():" << std::endl;
-    std::cout << fv.subDifferential(0) << " f.subDifferential(0):" << std::endl;
-    std::cout << fv.domain()[0] << " " << fv.domain()[0] << " f.domain():" << std::endl;
-
-    std::cout << "- setup directional restriction: success" << std::endl; */
-
-    dampingFactor_ = 0;
-    lineSolver_(dampingFactor_, fv, false);
-
-    //std::cout << "damping factor: " << dampingFactor_ << std::endl;
-
-   // std::cout << "- computing damping factor: success" << std::endl;
-    if (std::isnan(dampingFactor_))
-      dampingFactor_ = 0;
-    correction_ *= dampingFactor_;
-
-    //std::cout << "damping factor: " << dampingFactor_ << std::endl;
-
-    x += correction_;
-
-    //std::cout << "-- energy after correction: " << energy(x) << std::endl;
-  }
-
-  /**
-   * \brief Export the last computed damping factor
-   */
-  double lastDampingFactor() const
-  {
-    return dampingFactor_;
-  }
-
-  /**
-   * \brief Export the last used linearization
-   */
-  const Linearization& linearization() const
-  {
-    return *linearization_;
-  }
-
-private:
-
-  const Functional* f_;
-
-  std::shared_ptr<IterationStep<Vector,BitVector> > nonlinearSmoother_;
-  std::size_t preSmoothingSteps_ = 1;
-
-  std::shared_ptr<Linearization> linearization_;
-
-  //! \brief linear correction
-  LinearCorrection<ConstrainedMatrix, ConstrainedVector> linearCorrection_;
-
-  typename Linearization::ConstrainedVector constrainedCorrection_;
-  Vector correction_;
-  DefectProjection projection_;
-  LineSearchSolver lineSolver_;
-  double dampingFactor_;
-};
-
-
-#endif