From 09929cc35af78fe163de54381ccd391d9b2e8c52 Mon Sep 17 00:00:00 2001
From: podlesny <podlesny@mi.fu-berlin.de>
Date: Fri, 6 Sep 2019 19:24:02 +0200
Subject: [PATCH] towards crosspoints

---
 .../friction/globalratestatefriction.hh       |   4 +-
 .../data-structures/network/contactnetwork.cc |  28 ++-
 .../data-structures/network/contactnetwork.hh |   5 +-
 .../tectonic/data-structures/program_state.hh |   2 +-
 .../factories/stackedblocksfactory.hh         |   2 +-
 dune/tectonic/factories/threeblocksfactory.cc |   8 +-
 dune/tectonic/factories/threeblocksfactory.hh |   2 +-
 .../contact/dualmortarcoupling.cc             | 178 +++++++++++-------
 .../contact/dualmortarcoupling.hh             |  31 ++-
 .../spatial-solving/contact/nbodyassembler.cc |  70 +++++--
 .../spatial-solving/contact/nbodyassembler.hh |  41 ++--
 .../spatial-solving/fixedpointiterator.cc     |   2 +-
 .../fixedpointiterator_tmpl.cc                |   6 +-
 .../multilevelpatchpreconditioner.hh          |   2 +-
 .../time-stepping/adaptivetimestepper_tmpl.cc |   4 +-
 .../time-stepping/coupledtimestepper_tmpl.cc  |   6 +-
 dune/tectonic/time-stepping/state_tmpl.cc     |   3 +-
 src/multi-body-problem/multi-body-problem.cc  |   5 +-
 18 files changed, 256 insertions(+), 143 deletions(-)

diff --git a/dune/tectonic/data-structures/friction/globalratestatefriction.hh b/dune/tectonic/data-structures/friction/globalratestatefriction.hh
index 0d007d8e..ec42936b 100644
--- a/dune/tectonic/data-structures/friction/globalratestatefriction.hh
+++ b/dune/tectonic/data-structures/friction/globalratestatefriction.hh
@@ -10,7 +10,7 @@
 #include <dune/istl/bcrsmatrix.hh>
 #include <dune/istl/bvector.hh>
 
-#include <dune/contact/assemblers/dualmortarcoupling.hh>
+#include "../../spatial-solving/contact/dualmortarcoupling.hh"
 
 #include "globalfrictiondata.hh"
 #include "globalfriction.hh"
@@ -33,7 +33,7 @@ class GlobalRateStateFriction : public GlobalFriction<Matrix, Vector> {
   using typename Base::LocalVectorType;
 
   using FrictionCoupling = FrictionCouplingPair<GridType, LocalVectorType, field_type>;
-  using ContactCoupling =  Dune::Contact::DualMortarCoupling<field_type, GridType>;
+  using ContactCoupling =  DualMortarCoupling<field_type, GridType>;
 
   size_t bodyIndex(const size_t globalIdx) {
      size_t i=0;
diff --git a/dune/tectonic/data-structures/network/contactnetwork.cc b/dune/tectonic/data-structures/network/contactnetwork.cc
index e369614c..d9779a74 100644
--- a/dune/tectonic/data-structures/network/contactnetwork.cc
+++ b/dune/tectonic/data-structures/network/contactnetwork.cc
@@ -26,7 +26,7 @@ ContactNetwork<HostGridType, VectorType>::ContactNetwork(
     couplings_(nCouplings),
     frictionBoundaries_(nBodies),
     stateEnergyNorms_(nBodies),
-    nBodyAssembler_(nBodies, nCouplings, false, 0.0)
+    nBodyAssembler_(nBodies, nCouplings, 0.0)
 {}
 
 template <class HostGridType, class VectorType>
@@ -79,6 +79,28 @@ void ContactNetwork<HostGridType, VectorType>::assemble() {
       nBodyAssembler_.setCoupling(*couplings_[i], i);
     }
 
+    std::vector<std::shared_ptr<Dune::BitSetVector<1>>> dirichletVertices(nBodies());
+    for (size_t i=0; i<nBodies(); i++) {
+        const auto& body = this->body(i);
+        std::vector<std::shared_ptr<typename LeafBody::BoundaryCondition>> boundaryConditions;
+        body->boundaryConditions("dirichlet", boundaryConditions);
+
+        dirichletVertices[i] = std::make_shared<Dune::BitSetVector<1>>(body->nVertices());
+        auto& vertices = *dirichletVertices[i];
+        vertices.unsetAll();
+
+        if (boundaryConditions.size()<1)
+            continue;
+
+        for (size_t bc = 0; bc<boundaryConditions.size(); bc++) {
+           const auto& boundaryVertices = *boundaryConditions[bc]->boundaryPatch()->getVertices();
+           for (size_t j=0; j<boundaryVertices.size(); j++) {
+               vertices[j][0] = vertices[j][0] or boundaryVertices[j][0];
+           }
+        }
+    }
+
+    nBodyAssembler_.setDirichletVertices(dirichletVertices);
     nBodyAssembler_.assembleTransferOperator();
     nBodyAssembler_.assembleObstacle();
 
@@ -263,14 +285,14 @@ auto ContactNetwork<HostGridType, VectorType>::couplings() const
 
 template <class HostGridType, class VectorType>
 auto ContactNetwork<HostGridType, VectorType>::nBodyAssembler()
--> Dune::Contact::NBodyAssembler<GridType, VectorType>& {
+-> NBodyAssembler& {
 
     return nBodyAssembler_;
 }
 
 template <class HostGridType, class VectorType>
 auto ContactNetwork<HostGridType, VectorType>::nBodyAssembler() const
--> const Dune::Contact::NBodyAssembler<GridType, VectorType>& {
+-> const NBodyAssembler& {
 
     return nBodyAssembler_;
 }
diff --git a/dune/tectonic/data-structures/network/contactnetwork.hh b/dune/tectonic/data-structures/network/contactnetwork.hh
index fc9f554c..87b01365 100644
--- a/dune/tectonic/data-structures/network/contactnetwork.hh
+++ b/dune/tectonic/data-structures/network/contactnetwork.hh
@@ -5,8 +5,7 @@
 
 #include <dune/common/promotiontraits.hh>
 
-#include <dune/contact/assemblers/nbodyassembler.hh>
-
+#include "../../spatial-solving/contact/nbodyassembler.hh"
 #include "../../assemblers.hh"
 #include "../enums.hh"
 #include "../matrices.hh"
@@ -54,7 +53,7 @@ class ContactNetwork {
     using StateEnergyNorms = std::vector<std::unique_ptr<typename LeafBody::StateEnergyNorm> >;
     using ExternalForces = std::vector<std::unique_ptr<const typename LeafBody::ExternalForce> >;
 
-    using NBodyAssembler = Dune::Contact::NBodyAssembler<GridType, VectorType>;
+    using NBodyAssembler = NBodyAssembler<GridType, VectorType>;
 
     using LevelContactNetwork = LevelContactNetwork<GridType, FrictionCouplingPair, field_type>;
     using Body = typename LevelContactNetwork::Body;
diff --git a/dune/tectonic/data-structures/program_state.hh b/dune/tectonic/data-structures/program_state.hh
index 05198b41..9e1f63f5 100644
--- a/dune/tectonic/data-structures/program_state.hh
+++ b/dune/tectonic/data-structures/program_state.hh
@@ -29,7 +29,7 @@
 #include <dune/solvers/iterationsteps/truncatedblockgsstep.hh>
 #include <dune/solvers/iterationsteps/multigridstep.hh>
 
-#include "../spatial-solving/preconditioners/nbodycontacttransfer.hh"
+#include "../spatial-solving/contact/nbodycontacttransfer.hh"
 
 template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class BodyState {
 public:
diff --git a/dune/tectonic/factories/stackedblocksfactory.hh b/dune/tectonic/factories/stackedblocksfactory.hh
index e8f9454f..fb21774a 100644
--- a/dune/tectonic/factories/stackedblocksfactory.hh
+++ b/dune/tectonic/factories/stackedblocksfactory.hh
@@ -54,7 +54,7 @@ template <class HostGridType, class VectorType> class StackedBlocksFactory : pub
 public:
     StackedBlocksFactory(const Dune::ParameterTree& parset) :
         Base(parset, parset.get<size_t>("problem.bodyCount"), parset.get<size_t>("problem.bodyCount")-1),
-        bodyData_(std::make_shared<MyBodyData<dim>>(this->parset_, zenith_())),
+        bodyData_(std::make_shared<MyBodyData<dim>>(this->parset_.sub("body"), this->parset_.template get<double>("gravity"), zenith_())),
         cuboidGeometries_(this->bodyCount_),
         leafFaces_(this->bodyCount_),
         levelFaces_(this->bodyCount_),
diff --git a/dune/tectonic/factories/threeblocksfactory.cc b/dune/tectonic/factories/threeblocksfactory.cc
index 61275c63..6c395565 100644
--- a/dune/tectonic/factories/threeblocksfactory.cc
+++ b/dune/tectonic/factories/threeblocksfactory.cc
@@ -116,10 +116,10 @@ void ThreeBlocksFactory<HostGridType, VectorTEMPLATE>::setCouplings() {
 
     std::array<std::array<size_t, 2>, 3> couplingIndices;
 
-    nonmortarPatch_[0] = std::make_shared<LevelBoundaryPatch>(levelFaces_[0]->upper);
-    mortarPatch_[0] = std::make_shared<LevelBoundaryPatch>(levelFaces_[1]->lower);
-    weakPatches_[0] = std::make_shared<WeakeningRegion>(cuboidGeometries_[0]->weakeningRegions()[0]);
-    couplingIndices[0] = {0, 1};
+    nonmortarPatch_[0] = std::make_shared<LevelBoundaryPatch>(levelFaces_[1]->lower);
+    mortarPatch_[0] = std::make_shared<LevelBoundaryPatch>(levelFaces_[0]->upper);
+    weakPatches_[0] = std::make_shared<WeakeningRegion>(cuboidGeometries_[1]->weakeningRegions()[0]);
+    couplingIndices[0] = {1, 0};
 
     nonmortarPatch_[1] = std::make_shared<LevelBoundaryPatch>(levelFaces_[2]->lower);
     mortarPatch_[1] = std::make_shared<LevelBoundaryPatch>(levelFaces_[0]->upper);
diff --git a/dune/tectonic/factories/threeblocksfactory.hh b/dune/tectonic/factories/threeblocksfactory.hh
index e72c7f1c..b846f9f3 100644
--- a/dune/tectonic/factories/threeblocksfactory.hh
+++ b/dune/tectonic/factories/threeblocksfactory.hh
@@ -55,7 +55,7 @@ class ThreeBlocksFactory : public ContactNetworkFactory<HostGridType, VectorType
 public:
     ThreeBlocksFactory(const Dune::ParameterTree& parset) :
         Base(parset, 3, 3),
-        bodyData_(std::make_shared<MyBodyData<dim>>(this->parset_, zenith_())),
+        bodyData_(std::make_shared<MyBodyData<dim>>(this->parset_.sub("body"), this->parset_.template get<double>("gravity"), zenith_())),
         cuboidGeometries_(3),
         leafFaces_(3),
         levelFaces_(3),
diff --git a/dune/tectonic/spatial-solving/contact/dualmortarcoupling.cc b/dune/tectonic/spatial-solving/contact/dualmortarcoupling.cc
index 9f4daa82..7fb4bd30 100644
--- a/dune/tectonic/spatial-solving/contact/dualmortarcoupling.cc
+++ b/dune/tectonic/spatial-solving/contact/dualmortarcoupling.cc
@@ -19,62 +19,11 @@
 #include <dune/contact/common/dualbasisadapter.hh>
 #include <dune/matrix-vector/addtodiagonal.hh>
 
-namespace Dune {
-namespace Contact {
-
-template <class field_type, class GridType0, class GridType1>
-void DualMortarCoupling<field_type, GridType0, GridType1>::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 = grid0_->leafIndexSet();
-
-    // 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 GridType0, class GridType1>
-void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
-{
+void DualMortarCoupling<field_type, GridType0, GridType1>::reducePatches() {
     typedef typename GridType0::LeafGridView GridView0;
     typedef typename GridType1::LeafGridView GridView1;
 
-    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;
 
@@ -150,13 +99,95 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
     for (const auto& rIs : intersections(glue))
         if (nonmortarBoundary_.contains(rIs.inside(),rIs.indexInInside()))
             mortarBoundary_.addFace(rIs.outside(),rIs.indexInOutside());
+}
+
+template <class field_type, class GridType0, class GridType1>
+void DualMortarCoupling<field_type, GridType0, GridType1>::setCrosspoints(const std::set<size_t>& allCrosspoints) {
+    crosspoints_.clear();
+
+    if (!allCrosspoints.empty()) {
+        Dune::BitSetVector<1> nonmortarPatchBoundary;
+        nonmortarBoundary_.getPatchBoundaryVertices(nonmortarPatchBoundary);
+
+        for (auto p : allCrosspoints) {
+            if (nonmortarPatchBoundary[p][0]) {
+                crosspoints_.emplace(p);
+            }
+        }
+    }
+}
+
+template <class field_type, class GridType0, class GridType1>
+void DualMortarCoupling<field_type, GridType0, GridType1>::assembleNonmortarLagrangeMatrix()
+{  
+    // clear matrix
+    const auto nNonmortarVertices = nonmortarBoundary_.numVertices() - crosspoints_.size();
+    nonmortarLagrangeMatrix_ = Dune::BDMatrix<MatrixBlock>(nNonmortarVertices);
+    nonmortarLagrangeMatrix_ = 0;
+
+    const auto& indexSet = grid0_->leafIndexSet();
+
+    // 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 GridType0, class GridType1>
+void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
+{
+    typedef typename GridType0::LeafGridView GridView0;
+    typedef typename GridType1::LeafGridView GridView1;
+
+    using FiniteElementCache1 = Dune::PQkLocalFiniteElementCache<typename GridType1::ctype, field_type, GridType1::dimension,1>;
+
+    // cache for the dual functions on the boundary
+    using DualCache = Dune::Contact::DualBasisAdapter<GridView0, field_type>;
+    using ConstantDualCache = Dune::PQkLocalFiniteElementCache<typename GridType0::ctype, field_type, GridType0::dimension, 0>;
+
+    GridView0 gridView0 = grid0_->leafGridView();
+    GridView1 gridView1 = grid1_->leafGridView();
+
+    const auto& indexSet0 = gridView0.indexSet();
+    const auto& indexSet1 = gridView1.indexSet();
+
+    // Create mapping from the global set of block dofs to the ones on the contact boundary
+    const auto& vertices = *nonmortarBoundary_.getVertices();
+
+    globalToLocal_.resize(vertices.size());
+    int idx = 0;
+    for (size_t i=0; i<globalToLocal_.size(); i++)
+        globalToLocal_[i] = (vertices[i][0] and crosspoints_.count(i)==0) ? idx++ : -1;
 
     // Assemble the diagonal matrix coupling the nonmortar side with the lagrange multiplyers there
     assembleNonmortarLagrangeMatrix();
 
     // The weak obstacle vector
-    weakObstacle_.resize(nonmortarBoundary_.numVertices());
+    const auto nNonmortarVertices = nonmortarBoundary_.numVertices()-crosspoints_.size();
+    weakObstacle_.resize(nNonmortarVertices);
     weakObstacle_ = 0;
 
     // ///////////////////////////////////////////////////////////
@@ -164,14 +195,10 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
     // ///////////////////////////////////////////////////////////
 
     /** \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);
+    Dune::MatrixIndexSet mortarIndices(nNonmortarVertices, grid1_->size(dim));
 
     // loop over all intersections
-    for (const auto& rIs : intersections(glue)) {
+    for (const auto& rIs : intersections(*glue_)) {
 
         if (!nonmortarBoundary_.contains(rIs.inside(),rIs.indexInInside()))
             continue;
@@ -187,9 +214,9 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
 
         for (int j=0; j<nDomainVertices; j++) {
 
-            int localDomainIdx = globalToLocal[indexSet0.subIndex(inside,j,dim)];
+            int localDomainIdx = globalToLocal_[indexSet0.subIndex(inside,j,dim)];
 
-            // if the vertex is not contained in the restricted contact boundary then dismiss it
+            // if the vertex is not contained in the restricted contact boundary or a crosspoint, then dismiss it
             if (localDomainIdx == -1)
                 continue;
 
@@ -208,18 +235,20 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
     // 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> >();
 
+    // adapt dual basis close to crosspoints using ConstantDualCache
+    ConstantDualCache constantDualCache;
+
     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)) {
+    for (const auto& rIs : intersections(*glue_)) {
 
 
         const auto& inside = rIs.inside();
@@ -250,6 +279,8 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
 
         //const typename FiniteElementCache0::FiniteElementType& nonmortarFiniteElement = cache0.get(nonmortarEType);
         const auto& mortarFiniteElement = cache1.get(mortarEType);
+
+        const auto& constantDualFE = constantDualCache.get(nonmortarEType);
         dualCache->bind(inside, rIs.indexInInside());
 
         std::vector<Dune::FieldVector<field_type,1> > mortarQuadValues, dualQuadValues;
@@ -259,11 +290,18 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
         const auto& rGeomInInside = rIs.geometryInInside();
         const auto& rGeomInOutside = rIs.geometryInOutside();
 
+        bool isCrosspointFace = false;
         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);
+          int globalIdx = indexSet0.subIndex(inside,faceIdxi,dim);
+
+          if (crosspoints_.count(globalIdx)>0) {
+            isCrosspointFace = true;
+          } else {
+            nonmortarFaceNodes.push_back(faceIdxi);
+          }
         }
 
         for (const auto& quadPt : quadRule) {
@@ -285,13 +323,18 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
             //evaluate all shapefunctions at the quadrature point
             //nonmortarFiniteElement.localBasis().evaluateFunction(nonmortarQuadPos,nonmortarQuadValues);
             mortarFiniteElement.localBasis().evaluateFunction(mortarQuadPos,mortarQuadValues);
-            dualCache->evaluateFunction(nonmortarQuadPos,dualQuadValues);
+
+            if (isCrosspointFace) {
+              constantDualFE.localBasis().evaluateFunction(nonmortarQuadPos,dualQuadValues);
+            } else {
+              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];
+                int rowIdx = globalToLocal_[globalDomainIdx];
 
                 weakObstacle_[rowIdx][0] += integrationElement * quadPt.weight()
                     * dualQuadValues[nonmortarFaceNodes[j]] * (gapVector*avNormals[globalDomainIdx]);
@@ -339,6 +382,3 @@ void DualMortarCoupling<field_type, GridType0,GridType1>::setup()
 
     gridGlueBackend_->clear();
 }
-
-} /* namespace Contact */
-} /* namespace Dune */
diff --git a/dune/tectonic/spatial-solving/contact/dualmortarcoupling.hh b/dune/tectonic/spatial-solving/contact/dualmortarcoupling.hh
index cfd8ed5f..04782aab 100644
--- a/dune/tectonic/spatial-solving/contact/dualmortarcoupling.hh
+++ b/dune/tectonic/spatial-solving/contact/dualmortarcoupling.hh
@@ -1,7 +1,7 @@
 // -*- 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
+#ifndef DUNE_TECTONIC_SPATIAL_SOLVING_CONTACT_DUAL_MORTAR_COUPLING_HH
+#define DUNE_TECTONIC_SPATIAL_SOLVING_CONTACT_DUAL_MORTAR_COUPLING_HH
 
 #include <memory>
 
@@ -16,10 +16,9 @@
 #include <dune/grid-glue/extractors/codim1extractor.hh>
 #include <dune/grid-glue/merging/merger.hh>
 
-namespace Dune {
-namespace Contact {
-
-/** \brief Assembles the transfer operator for two-body contact
+/** \brief Assembles the transfer operator for two-body contact.
+ * Extension of Dune::Contact::DualMortarCoupling by crosspoints.
+ * Note: so war only works in 2D!
  */
 template<class field_type, class GridType0, class GridType1=GridType0>
 class DualMortarCoupling {
@@ -66,6 +65,10 @@ class DualMortarCoupling {
         /* Nothing. */
     }
 
+    void reducePatches();
+
+    void setCrosspoints(const std::set<size_t>& allCrosspoints);
+
     /** \brief Sets up the contact coupling operator on the grid leaf level */
     virtual void setup();
 
@@ -83,7 +86,7 @@ class DualMortarCoupling {
     }
 
     /** \brief Get the non-mortar matrix. */
-    const BDMatrix<MatrixBlock>& nonmortarLagrangeMatrix() const {
+    const Dune::BDMatrix<MatrixBlock>& nonmortarLagrangeMatrix() const {
         return nonmortarLagrangeMatrix_;
     }
 
@@ -141,6 +144,14 @@ class DualMortarCoupling {
         return weakObstacle_;
     }
 
+    const std::vector<int>& globalToLocal() const {
+        return globalToLocal_;
+    }
+
+   /* const auto& crosspoints() const {
+        return crosspoints_;
+    }*/
+
     // /////////////////////////////////////////////
     //   Data members
     // /////////////////////////////////////////////
@@ -158,6 +169,9 @@ class DualMortarCoupling {
     /** \brief The crosspoints of the nonmortar body. */
     std::set<size_t> crosspoints_;
 
+    /** \brief Nonmortar boundary patch global to local map. */
+    std::vector<int> globalToLocal_;
+
     /** \brief The matrix coupling mortar side and Lagrange multipliers. */
     MatrixType mortarLagrangeMatrix_;
 
@@ -184,9 +198,6 @@ class DualMortarCoupling {
     field_type coveredArea_;
 };
 
-} /* namespace Contact */
-} /* namespace Dune */
-
 #include "dualmortarcoupling.cc"
 
 #endif
diff --git a/dune/tectonic/spatial-solving/contact/nbodyassembler.cc b/dune/tectonic/spatial-solving/contact/nbodyassembler.cc
index 2d75582f..13cee857 100644
--- a/dune/tectonic/spatial-solving/contact/nbodyassembler.cc
+++ b/dune/tectonic/spatial-solving/contact/nbodyassembler.cc
@@ -10,8 +10,34 @@
 #include <dune/fufem/boundarypatchprolongator.hh>
 #include <dune/contact/projections/normalprojection.hh>
 
-namespace Dune {
-namespace Contact {
+
+#include "../../utils/debugutils.hh"
+
+template <class GridType, class VectorType>
+void NBodyAssembler<GridType, VectorType>::setCrosspoints() {
+    std::vector<Dune::BitSetVector<1>> bodywiseBoundaries(nGrids());
+    for (size_t i=0; i<nGrids(); i++) {
+        bodywiseBoundaries[i] = *dirichletVertices_[i];
+    }
+
+    for (size_t i=0; i<nCouplings(); i++) {
+        auto& coupling = coupling_[i];
+        const auto& contactCoupling = contactCoupling_[i]; // dual mortar object holding boundary patches
+        const auto nonmortarIdx = coupling.gridIdx_[0];
+        //const auto mortarIdx = coupling->gridIdx_[1];
+
+        auto& bodywiseBoundary = bodywiseBoundaries[nonmortarIdx];
+        auto& crosspoints = crosspoints_[nonmortarIdx];
+        const auto& nmBoundaryVertices = *contactCoupling->nonmortarBoundary().getVertices();
+        for (size_t j=0; j<nmBoundaryVertices.size(); j++) {
+            if (bodywiseBoundary[j][0] and nmBoundaryVertices[j][0]) {
+                crosspoints.emplace(j);
+            }
+            bodywiseBoundary[j][0] = bodywiseBoundary[j][0] or nmBoundaryVertices[j][0];
+        }
+
+    }
+}
 
 template <class GridType, class VectorType>
 void NBodyAssembler<GridType, VectorType>::assembleTransferOperator()
@@ -42,6 +68,17 @@ void NBodyAssembler<GridType, VectorType>::assembleTransferOperator()
         contactCoupling_[i]->setupContactPatch(*coupling_[i].patch0(),*coupling_[i].patch1());
         contactCoupling_[i]->gridGlueBackend_ = coupling_[i].backend();
         contactCoupling_[i]->setCoveredArea(coveredArea_);
+        contactCoupling_[i]->reducePatches();
+    }
+
+    setCrosspoints();
+
+    for (size_t i=0; i<nGrids(); i++) {
+        print(crosspoints_[i], "crosspoints " + std::to_string(i));
+    }
+
+    for (size_t i=0; i<contactCoupling_.size(); i++) {
+        contactCoupling_[i]->setCrosspoints(crosspoints_[coupling_[i].gridIdx_[0]]);
         contactCoupling_[i]->setup();
     }
 
@@ -91,7 +128,6 @@ void NBodyAssembler<GridType, VectorType>::assembleHouseholderReflections()
         this->localCoordSystems_[i] = id;
 
     for (int j=0; j<nCouplings(); j++) {
-
         int grid0Idx = coupling_[j].gridIdx_[0];
 
         // compute offset
@@ -100,10 +136,11 @@ void NBodyAssembler<GridType, VectorType>::assembleHouseholderReflections()
             idx += grids_[k]->size(dim);
 
         const auto& nonmortarBoundary = contactCoupling_[j]->nonmortarBoundary();
+        const auto& globalToLocal = contactCoupling_[j]->globalToLocal();
 
-        // if a body is non-mortar more then once, one has to be careful with not overwriting entries
+        // if a body is non-mortar more than 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))
+          if(globalToLocal[k] > -1)
             this->localCoordSystems_[idx+k] = coordinateSystems[j][k];
     }
 }
@@ -114,7 +151,7 @@ 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]);
+        globalToLocals[i] = contactCoupling_[i]->globalToLocal();
 
     ///////////////////////////////////////
     //  Set the obstacle values
@@ -126,6 +163,7 @@ void NBodyAssembler<GridType, VectorType>::assembleObstacle()
 
         int grid0Idx = coupling_[j].gridIdx_[0];
         const auto& nonmortarBoundary = contactCoupling_[j]->nonmortarBoundary();
+        const auto& globalToLocal = globalToLocals[j];
 
         // compute offset
         int idx = 0;
@@ -133,7 +171,7 @@ void NBodyAssembler<GridType, VectorType>::assembleObstacle()
             idx += grids_[k]->size(dim);
 
         for (int k=0; k<grids_[grid0Idx]->size(dim); k++)
-            if (nonmortarBoundary.containsVertex(k))
+            if (globalToLocal[k] > -1)
                 totalHasObstacle_[idx+k] = true;
     }
 
@@ -181,23 +219,23 @@ void NBodyAssembler<GridType, VectorType>::assembleObstacle()
             // Set the obstacle
             switch (coupling_[i].type_) {
 
-            case CouplingPairBase::CONTACT:
+            case Dune::Contact::CouplingPairBase::CONTACT:
                 totalObstacles_[idx+vIdx].upper(0) = obs[globalToLocal[vIdx]];
                 break;
 
-            case CouplingPairBase::STICK_SLIP:
+            case Dune::Contact::CouplingPairBase::STICK_SLIP:
                 totalObstacles_[idx+vIdx].lower(0) = 0;
                 totalObstacles_[idx+vIdx].upper(0) = 0;
                 break;
 
-            case CouplingPairBase::GLUE:
+            case Dune::Contact::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:
+            case Dune::Contact::CouplingPairBase::NONE:
                 break;
             default:
                 DUNE_THROW(Dune::NotImplemented, "Coupling type not handled yet!");
@@ -438,6 +476,7 @@ computeTransformationMatrix()
     for (int i=0; i<nCouplings(); i++) {
 
         const auto& nonmortarBoundary = contactCoupling_[i]->nonmortarBoundary();
+        const auto& globalToLocal = contactCoupling_[i]->globalToLocal();
         // If the contact mapping could not be built at all then skip this coupling
         if (nonmortarBoundary.numVertices() == 0)
             continue;
@@ -450,8 +489,9 @@ computeTransformationMatrix()
         nonmortarToGlobal[i].resize(nonmortarBoundary.numVertices());
         int idx = 0;
         for (int j=0; j<grids_[grid0Idx]->size(dim); j++)
-            if (nonmortarBoundary.containsVertex(j))
+            if (globalToLocal[j] > -1)
                 nonmortarToGlobal[i][idx++] = j;
+        nonmortarToGlobal[i].resize(idx);
 
         // the off-diagonal part
         const MatrixType& M = contactCoupling_[i]->mortarLagrangeMatrix();
@@ -485,6 +525,7 @@ computeTransformationMatrix()
     for (int i=0; i<nCouplings(); i++) {
 
         const auto& nonmortarBoundary = contactCoupling_[i]->nonmortarBoundary();
+        const auto& globalToLocal = contactCoupling_[i]->globalToLocal();
         if (nonmortarBoundary.numVertices() == 0)
             continue;
 
@@ -510,10 +551,7 @@ computeTransformationMatrix()
 
         // 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))
+            if(globalToLocal[k] > -1)
                 BT_[offset + k][offset+k] =this->localCoordSystems_[offset + k];
     }
 }
-
-} /* namespace Contact */
-} /* namespace Dune */
diff --git a/dune/tectonic/spatial-solving/contact/nbodyassembler.hh b/dune/tectonic/spatial-solving/contact/nbodyassembler.hh
index 55a5d633..e197497e 100644
--- a/dune/tectonic/spatial-solving/contact/nbodyassembler.hh
+++ b/dune/tectonic/spatial-solving/contact/nbodyassembler.hh
@@ -1,7 +1,7 @@
 // -*- 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
+#ifndef DUNE_TECTONIC_SPATIAL_SOLVING_CONTACT_N_BODY_MORTAR_ASSEMBLER_HH
+#define DUNE_TECTONIC_SPATIAL_SOLVING_CONTACT_N_BODY_MORTAR_ASSEMBLER_HH
 
 #include <dune/common/bitsetvector.hh>
 #include <dune/common/promotiontraits.hh>
@@ -9,18 +9,16 @@
 #include <dune/istl/bcrsmatrix.hh>
 #include <dune/solvers/common/boxconstraint.hh>
 #include <dune/fufem/boundarypatch.hh>
-#include <dune/contact/assemblers/dualmortarcouplinghierarchy.hh>
-#include <dune/contact/assemblers/dualmortarcoupling.hh>
 #include <dune/contact/assemblers/contactassembler.hh>
 #include <dune/contact/common/couplingpair.hh>
 #include <dune/contact/projections/contactprojection.hh>
 
+#include "dualmortarcoupling.hh"
+
 #ifdef HAVE_DUNE_GRID_GLUE
 #include <dune/grid-glue/merging/merger.hh>
 #endif
 
-namespace Dune {
-namespace Contact {
 
 /**  \brief Assembler for mortar discretized contact problems with arbitrary number of bodies.
  *
@@ -28,16 +26,15 @@ namespace Contact {
  *  \tparam VectorType The vector type for the displacements.
  */
 template <class GridType, class VectorType>
-class NBodyAssembler : public ContactAssembler<GridType::dimension, typename VectorType::field_type>
+class NBodyAssembler : public Dune::Contact::ContactAssembler<GridType::dimension, typename VectorType::field_type>
 {
 protected:
     enum {dim = GridType::dimension};
 
-    using field_type = typename PromotionTraits<typename VectorType::field_type,
+    using field_type = typename Dune::PromotionTraits<typename VectorType::field_type,
                                                 typename GridType::ctype>::PromotedType;
 
     using CouplingType = DualMortarCoupling<field_type, GridType>;
-    using HierarchyCouplingType = DualMortarCouplingHierarchy<field_type, GridType>;
 
     using MatrixBlock = Dune::FieldMatrix<field_type, dim, dim>;
     using MatrixType = Dune::BCRSMatrix<MatrixBlock>;
@@ -52,21 +49,19 @@ class NBodyAssembler : public ContactAssembler<GridType::dimension, typename Vec
      *
      *  \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) :
+    NBodyAssembler(int nGrids, int nCouplings, field_type coveredArea = 0.99) :
       coveredArea_(coveredArea)
     {
         grids_.resize(nGrids);
 
+        crosspoints_.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>();
+            contactCoupling_[i] = std::make_shared<CouplingType>();
     }
 
     /** \brief Get the number of couplings.*/
@@ -83,6 +78,8 @@ class NBodyAssembler : public ContactAssembler<GridType::dimension, typename Vec
         return n;
     }
 
+    void setCrosspoints();
+
     /** \brief Setup the patches for the contact boundary and compute the obstacles. */
     void assembleObstacle();
 
@@ -159,13 +156,16 @@ class NBodyAssembler : public ContactAssembler<GridType::dimension, typename Vec
     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) {
+    void setCoupling(const Dune::Contact::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];}
 
+    void setDirichletVertices(std::vector<std::shared_ptr<Dune::BitSetVector<1>>> dirichletVertices) {
+        dirichletVertices_ = dirichletVertices;
+    }
 protected:
     /** \brief Compute the transposed mortar transformation matrix. */
     void computeTransformationMatrix();
@@ -174,17 +174,21 @@ class NBodyAssembler : public ContactAssembler<GridType::dimension, typename Vec
     void assembleHouseholderReflections();
 
 public:
+    std::vector<std::shared_ptr<Dune::BitSetVector<1>>> dirichletVertices_;
+
     /** \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_;
 
+    std::vector<std::set<size_t>> crosspoints_;
+
     /** \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_;
+    std::vector<Dune::Contact::CouplingPair<GridType,GridType,field_type> > coupling_;
 
     /** \brief Vector containing the involved grids. */
     std::vector<const GridType*> grids_;
@@ -198,9 +202,6 @@ class NBodyAssembler : public ContactAssembler<GridType::dimension, typename Vec
     field_type coveredArea_;
 };
 
-} /* namespace Contact */
-} /* namespace Dune */
-
 #include "nbodyassembler.cc"
 
 #endif
diff --git a/dune/tectonic/spatial-solving/fixedpointiterator.cc b/dune/tectonic/spatial-solving/fixedpointiterator.cc
index 298e2f94..39610f48 100644
--- a/dune/tectonic/spatial-solving/fixedpointiterator.cc
+++ b/dune/tectonic/spatial-solving/fixedpointiterator.cc
@@ -34,7 +34,7 @@
 #include <dune/solvers/iterationsteps/truncatedblockgsstep.hh>
 #include <dune/solvers/iterationsteps/multigridstep.hh>
 
-#include "../spatial-solving/preconditioners/nbodycontacttransfer.hh"
+#include "../spatial-solving/contact/nbodycontacttransfer.hh"
 
 #include "tnnmg/functional.hh"
 #include "tnnmg/zerononlinearity.hh"
diff --git a/dune/tectonic/spatial-solving/fixedpointiterator_tmpl.cc b/dune/tectonic/spatial-solving/fixedpointiterator_tmpl.cc
index bae2cc32..c434a9b2 100644
--- a/dune/tectonic/spatial-solving/fixedpointiterator_tmpl.cc
+++ b/dune/tectonic/spatial-solving/fixedpointiterator_tmpl.cc
@@ -29,13 +29,13 @@ using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>;
 
 using LinearSolver = Dune::Solvers::LoopSolver<Vector>;
 using ErrorNorms = typename MyContactNetwork::StateEnergyNorms;
-using NBodyAssembler = typename MyContactNetwork::NBodyAssembler;
+using MyNBodyAssembler = typename MyContactNetwork::NBodyAssembler;
 
 using MyGlobalFriction = GlobalFriction<Matrix, Vector>;
 using MyFunctional = Functional<Matrix&, Vector&, MyGlobalFriction&, Vector&, Vector&, double>;
 using MySolverFactory = SolverFactory<MyFunctional, BitVector>;
 
-template class FixedPointIterator<MySolverFactory, NBodyAssembler, MyUpdaters, ErrorNorms>;
+template class FixedPointIterator<MySolverFactory, MyNBodyAssembler, MyUpdaters, ErrorNorms>;
 
-template FixedPointIterationCounter FixedPointIterator<MySolverFactory, NBodyAssembler, MyUpdaters, ErrorNorms>::run<LinearSolver>(
+template FixedPointIterationCounter FixedPointIterator<MySolverFactory, MyNBodyAssembler, MyUpdaters, ErrorNorms>::run<LinearSolver>(
     MyUpdaters, std::shared_ptr<LinearSolver>&, const std::vector<Matrix>&, const std::vector<Vector>&, std::vector<Vector>&);
diff --git a/dune/tectonic/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh b/dune/tectonic/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
index 88de3c32..e67dfe55 100644
--- a/dune/tectonic/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
+++ b/dune/tectonic/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh
@@ -15,7 +15,7 @@
 #include <dune/solvers/iterationsteps/lineariterationstep.hh>
 #include <dune/solvers/iterationsteps/truncatedblockgsstep.hh>
 
-#include "nbodycontacttransfer.hh"
+#include "../contact/nbodycontacttransfer.hh"
 #include "levelpatchpreconditioner.hh"
 
 template <class ContactNetwork, class MatrixType, class VectorType>
diff --git a/dune/tectonic/time-stepping/adaptivetimestepper_tmpl.cc b/dune/tectonic/time-stepping/adaptivetimestepper_tmpl.cc
index 0e7cd4f9..64155c96 100644
--- a/dune/tectonic/time-stepping/adaptivetimestepper_tmpl.cc
+++ b/dune/tectonic/time-stepping/adaptivetimestepper_tmpl.cc
@@ -29,7 +29,7 @@ using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>;
 
 using LinearSolver = Dune::Solvers::LoopSolver<Vector>;
 using ErrorNorms = typename MyContactNetwork::StateEnergyNorms;
-using NBodyAssembler = typename MyContactNetwork::NBodyAssembler;
+using MyNBodyAssembler = typename MyContactNetwork::NBodyAssembler;
 
 using MyGlobalFriction = GlobalFriction<Matrix, Vector>;
 using MyFunctional = Functional<Matrix&, Vector&, MyGlobalFriction&, Vector&, Vector&, double>;
@@ -39,4 +39,4 @@ template class AdaptiveTimeStepper<MySolverFactory, MyContactNetwork, MyUpdaters
 
 template typename AdaptiveTimeStepper<MySolverFactory, MyContactNetwork, MyUpdaters, ErrorNorms>::UpdatersWithCount
 AdaptiveTimeStepper<MySolverFactory, MyContactNetwork, MyUpdaters, ErrorNorms>::step<LinearSolver>(
-        const MyUpdaters&, const NBodyAssembler&, std::shared_ptr<LinearSolver>&, double, double);
+        const MyUpdaters&, const MyNBodyAssembler&, std::shared_ptr<LinearSolver>&, double, double);
diff --git a/dune/tectonic/time-stepping/coupledtimestepper_tmpl.cc b/dune/tectonic/time-stepping/coupledtimestepper_tmpl.cc
index e09f3f89..a2b7fc84 100644
--- a/dune/tectonic/time-stepping/coupledtimestepper_tmpl.cc
+++ b/dune/tectonic/time-stepping/coupledtimestepper_tmpl.cc
@@ -29,12 +29,12 @@ using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>;
 
 using LinearSolver = Dune::Solvers::LoopSolver<Vector>;
 using ErrorNorms = typename MyContactNetwork::StateEnergyNorms;
-using NBodyAssembler = typename MyContactNetwork::NBodyAssembler;
+using MyNBodyAssembler = typename MyContactNetwork::NBodyAssembler;
 
 using MyGlobalFriction = GlobalFriction<Matrix, Vector>;
 using MyFunctional = Functional<Matrix&, Vector&, MyGlobalFriction&, Vector&, Vector&, double>;
 using MySolverFactory = SolverFactory<MyFunctional, BitVector>;
 
-template class CoupledTimeStepper<MySolverFactory, NBodyAssembler, MyUpdaters, ErrorNorms>;
+template class CoupledTimeStepper<MySolverFactory, MyNBodyAssembler, MyUpdaters, ErrorNorms>;
 
-template FixedPointIterationCounter CoupledTimeStepper<MySolverFactory, NBodyAssembler, MyUpdaters, ErrorNorms>::step<LinearSolver>(std::shared_ptr<LinearSolver>&, double, double);
+template FixedPointIterationCounter CoupledTimeStepper<MySolverFactory, MyNBodyAssembler, MyUpdaters, ErrorNorms>::step<LinearSolver>(std::shared_ptr<LinearSolver>&, double, double);
diff --git a/dune/tectonic/time-stepping/state_tmpl.cc b/dune/tectonic/time-stepping/state_tmpl.cc
index d4d99038..89834f69 100644
--- a/dune/tectonic/time-stepping/state_tmpl.cc
+++ b/dune/tectonic/time-stepping/state_tmpl.cc
@@ -5,11 +5,12 @@
 #include <dune/contact/assemblers/dualmortarcoupling.hh>
 
 #include "../data-structures/friction/frictioncouplingpair.hh"
+#include "../spatial-solving/contact/dualmortarcoupling.hh"
 
 using field_type = typename Dune::PromotionTraits<typename Vector::field_type,
                                             typename DeformedGrid::ctype>::PromotedType;
 
-using MyContactCoupling = Dune::Contact::DualMortarCoupling<field_type, DeformedGrid>;
+using MyContactCoupling = DualMortarCoupling<field_type, DeformedGrid>;
 using MyFrictionCouplingPair = FrictionCouplingPair<DeformedGrid, LocalVector, field_type>;
 
 template std::shared_ptr<StateUpdater<ScalarVector, Vector>>
diff --git a/src/multi-body-problem/multi-body-problem.cc b/src/multi-body-problem/multi-body-problem.cc
index 715acca3..30fc02b3 100644
--- a/src/multi-body-problem/multi-body-problem.cc
+++ b/src/multi-body-problem/multi-body-problem.cc
@@ -110,7 +110,7 @@ int main(int argc, char *argv[]) {
         std::cout << argv[0] << std::endl;
     }
 
-    std::ofstream out("../log.txt");
+    std::ofstream out("multi-body-problem.log");
     std::streambuf *coutbuf = std::cout.rdbuf(); //save old buffer
     std::cout.rdbuf(out.rdbuf()); //redirect std::cout to log.txt
 
@@ -132,7 +132,7 @@ int main(int argc, char *argv[]) {
     using ContactNetwork = typename ThreeBlocksFactory<Grid, Vector>::ContactNetwork;
     threeBlocksFactory.build();
 
-    ContactNetwork& contactNetwork = threeBlocksFactory.contactNetwork(); */
+    ContactNetwork& contactNetwork = threeBlocksFactory.contactNetwork();*/
 
     const size_t bodyCount = contactNetwork.nBodies();
 
@@ -224,6 +224,7 @@ int main(int argc, char *argv[]) {
     std::vector<const MyCellBasis* > cellBases(bodyCount);
 
     auto& wPatches = stackedBlocksFactory.weakPatches();
+    //auto& wPatches = threeBlocksFactory.weakPatches();
     std::vector<std::vector<const ConvexPolyhedron<LocalVector>*>> weakPatches(bodyCount);
 
 
-- 
GitLab