diff --git a/src/spatial-solving/solverfactory.cc b/src/spatial-solving/solverfactory.cc
index b289e96e01d807dfdd8b918a5f303e3dc17a8bd7..e0fa8ec1968ab6ed398baaa9d521e18e54a93188 100644
--- a/src/spatial-solving/solverfactory.cc
+++ b/src/spatial-solving/solverfactory.cc
@@ -6,54 +6,73 @@
 #undef HAVE_IPOPT
 #endif
 
+#include <dune/common/bitsetvector.hh>
+
 #include <dune/fufem/assemblers/transferoperatorassembler.hh>
 #include <dune/solvers/solvers/solver.hh>
 
 #include "solverfactory.hh"
 
-template <size_t dim, class BlockProblem, class DeformedGrid>
-SolverFactory<dim, BlockProblem, DeformedGrid>::SolverFactory(
+template <class DeformedGridTEMPLATE, class MatrixType, class VectorType>
+SolverFactory<DeformedGrid, Matrix, Vector>::SolverFactory(
     Dune::ParameterTree const &parset, const Dune::Contact::NBodyAssembler<DeformedGrid, Vector>& nBodyAssembler,
     Dune::BitSetVector<dim> const &ignoreNodes)
     : nBodyAssembler_(nBodyAssembler),
-      baseEnergyNorm(linearBaseSolverStep),
-      linearBaseSolver(&linearBaseSolverStep,
+      baseEnergyNorm_(baseSolverStep_),
+      baseSolver_(&baseSolverStep_,
                        parset.get<size_t>("linear.maxiumumIterations"),
-                       parset.get<double>("linear.tolerance"), &baseEnergyNorm,
-                       Solver::QUIET)/*,
-      transferOperators(grid.maxLevel()),
-      multigridStep(std::make_shared<Step>(linearIterationStep, nonlinearSmoother))*/ {
-
-  // linear iteration step
-  linearIterationStep.setMGType(parset.get<int>("linear.cycle"),
-                                parset.get<int>("linear.pre"),
-                                parset.get<int>("linear.post"));
-  //linearIterationStep.basesolver_ = &linearBaseSolver;
-  linearIterationStep.setSmoother(&linearPresmoother, &linearPostsmoother);
-
-  // transfer operators
-  for (auto &&x : transferOperators)
-    x = new CompressedMultigridTransfer<Vector>;
-  TransferOperatorAssembler<DeformedGrid>(grid).assembleOperatorPointerHierarchy(transferOperators);
-  linearIterationStep.setTransferOperators(transferOperators);
+                       parset.get<double>("linear.tolerance"), &baseEnergyNorm_,
+                       Solver::QUIET),
+      transferOperators_(nBodyAssembler.getGrids().at(0)->maxLevel()) {
 
   // tnnmg iteration step
-  /*multigridStep->setSmoothingSteps(parset.get<int>("main.pre"),
-                                   parset.get<int>("main.multi"),
-                                   parset.get<int>("main.post")); */
-  multigridStep->ignoreNodes_ = &ignoreNodes;
+  multigridStep_->setMGType(parset.get<int>("main.multi"), parset.get<int>("main.pre"), parset.get<int>("main.post"));
+  multigridStep_->setIgnore(ignoreNodes);
+  multigridStep_->setBaseSolver(baseSolver_);
+  multigridStep_->setSmoother(&presmoother_, &postsmoother_);
+  multigridStep_->setHasObstacle(nBodyAssembler_.totalHasObstacle_);
+  multigridStep_->setObstacles(nBodyAssembler_.totalObstacles_);
+
+  // create the transfer operators
+  const int nCouplings = nBodyAssembler_.nCouplings();
+  const auto grids = nBodyAssembler_.getGrids();
+  for (size_t i=0; i<transferOperators_.size(); i++) {
+    std::vector<const Dune::BitSetVector<1>*> coarseHasObstacle(nCouplings);
+    std::vector<const Dune::BitSetVector<1>*> fineHasObstacle(nCouplings);
+
+    std::vector<const Matrix*> mortarTransfer(nCouplings);
+    std::vector<std::array<int,2> > gridIdx(nCouplings);
+
+    for (int j=0; j<nCouplings; j++) {
+      coarseHasObstacle[j]  = nBodyAssembler_.nonmortarBoundary_[j][i].getVertices();
+      fineHasObstacle[j]    = nBodyAssembler_.nonmortarBoundary_[j][i+1].getVertices();
+
+      mortarTransfer[j] = &nBodyAssembler_.contactCoupling_[j].mortarLagrangeMatrix(i);
+      gridIdx[j]        = nBodyAssembler_.coupling_[j].gridIdx_;
+    }
+
+    transferOperators_[i] = new Dune::Contact::ContactMGTransfer<Vector>;
+    transferOperators_[i]->setup(grids, i, i+1,
+                                    nBodyAssembler_.localCoordSystems_[i],
+                                    nBodyAssembler_.localCoordSystems_[i+1],
+                                    coarseHasObstacle, fineHasObstacle,
+                                    mortarTransfer,
+                                    gridIdx);
+  }
+
+  multigridStep_->setTransferOperators(transferOperators_);
 }
 
-template <size_t dim, class BlockProblem, class DeformedGrid>
-SolverFactory<dim, BlockProblem, DeformedGrid>::~SolverFactory() {
-  for (auto &&x : transferOperators)
+template <class DeformedGridTEMPLATE, class MatrixType, class VectorType>
+SolverFactory<DeformedGrid, Matrix, Vector>::~SolverFactory() {
+  for (auto &&x : transferOperators_)
     delete x;
 }
 
-template <size_t dim, class BlockProblem, class DeformedGrid>
-auto SolverFactory<dim, BlockProblem, DeformedGrid>::getStep()
+template <class DeformedGridTEMPLATE, class MatrixType, class VectorType>
+auto SolverFactory<DeformedGrid, Matrix, Vector>::getStep()
     -> std::shared_ptr<Step> {
-  return multigridStep;
+  return multigridStep_;
 }
 
 #include "solverfactory_tmpl.cc"
diff --git a/src/spatial-solving/solverfactory.hh b/src/spatial-solving/solverfactory.hh
index 464ae5392a2b07eac6339bb91aca27a3c9f84935..ad6dbde284eda07e0d85364dfaf30beca03c257e 100644
--- a/src/spatial-solving/solverfactory.hh
+++ b/src/spatial-solving/solverfactory.hh
@@ -5,33 +5,37 @@
 #include <dune/common/parametertree.hh>
 
 #include <dune/solvers/iterationsteps/multigridstep.hh>
-#include <dune/solvers/iterationsteps/truncatedblockgsstep.hh>
+#include <dune/solvers/iterationsteps/projectedblockgsstep.hh>
 #include <dune/solvers/norms/energynorm.hh>
 #include <dune/solvers/solvers/loopsolver.hh>
-#include <dune/solvers/transferoperators/compressedmultigridtransfer.hh>
-#include <dune/tnnmg/iterationsteps/genericnonlineargs.hh>
+//#include <dune/solvers/transferoperators/compressedmultigridtransfer.hh>
+//#include <dune/tnnmg/iterationsteps/genericnonlineargs.hh>
 //#include <dune/tnnmg/iterationsteps/tnnmgstep.hh>
 
 #include <dune/contact/assemblers/nbodyassembler.hh>
 
+#include <dune/contact/estimators/hierarchiccontactestimator.hh>
+#include <dune/contact/solvers/nsnewtonmgstep.hh>
+#include <dune/contact/solvers/contacttransfer.hh>
+#include <dune/contact/solvers/contactobsrestrict.hh>
+#include <dune/contact/solvers/contacttransferoperatorassembler.hh>
+#include <dune/contact/solvers/nsnewtoncontacttransfer.hh>
+
 #define USE_OLD_TNNMG //needed for old bisection.hh in tnnmg
 
-template <size_t dim, class BlockProblemTEMPLATE, class DeformedGridTEMPLATE>
+template <class DeformedGridTEMPLATE, class MatrixType, class VectorType>
 class SolverFactory {
+protected:
+  const size_t dim = DeformedGrid::dimension;
+
 public:
-  using BlockProblem = BlockProblemTEMPLATE;
-  using ConvexProblem = typename BlockProblem::ConvexProblemType;
-  using Vector = typename BlockProblem::VectorType;
-  using Matrix = typename BlockProblem::MatrixType;
+  using Vector = VectorType;
+  using Matrix = MatrixType;
 
   using DeformedGrid = DeformedGridTEMPLATE;
 
-private:
-  using NonlinearSmoother = GenericNonlinearGS<BlockProblem>;
-
 public:
-  using Step = NonlinearSmoother;
-      //TruncatedNonsmoothNewtonMultigrid<BlockProblem, NonlinearSmoother>;
+  using Step = Dune::Contact::NonSmoothNewtonMGStep<Matrix, Vector>;
 
   SolverFactory(Dune::ParameterTree const &parset, const Dune::Contact::NBodyAssembler<DeformedGrid, Vector>& nBodyAssembler,
                 Dune::BitSetVector<dim> const &ignoreNodes);
@@ -43,14 +47,14 @@ class SolverFactory {
 private:
   const Dune::Contact::NBodyAssembler<DeformedGrid, Vector>& nBodyAssembler_;
 
-  TruncatedBlockGSStep<Matrix, Vector> linearBaseSolverStep;
-  EnergyNorm<Matrix, Vector> baseEnergyNorm;
-  LoopSolver<Vector> linearBaseSolver;
-  TruncatedBlockGSStep<Matrix, Vector> linearPresmoother;
-  TruncatedBlockGSStep<Matrix, Vector> linearPostsmoother;
-  MultigridStep<Matrix, Vector> linearIterationStep;
-  std::vector<CompressedMultigridTransfer<Vector> *> transferOperators;
-  NonlinearSmoother nonlinearSmoother;
-  std::shared_ptr<Step> multigridStep;
+  ProjectedBlockGSStep<Matrix, Vector> baseSolverStep_;
+  EnergyNorm<Matrix, Vector> baseEnergyNorm_;
+  LoopSolver<Vector> baseSolver_;
+
+  ProjectedBlockGSStep<Matrix, Vector> presmoother_;
+  ProjectedBlockGSStep<Matrix, Vector> postsmoother_;
+  std::shared_ptr<Step> multigridStep_;
+
+  std::vector<Dune::Contact::ContactMGTransfer<Vector>* > transferOperators_;
 };
 #endif