diff --git a/dune/tectonic/spatial-solving/tnnmg/functional_old.hh b/dune/tectonic/spatial-solving/tnnmg/functional_old.hh
new file mode 100755
index 0000000000000000000000000000000000000000..15674fb378df4337709f4f3244f04a69cf76765e
--- /dev/null
+++ b/dune/tectonic/spatial-solving/tnnmg/functional_old.hh
@@ -0,0 +1,505 @@
+// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set ts=8 sw=2 et sts=2:
+#ifndef DUNE_TECTONIC_SPATIAL_SOLVING_FUNCTIONAL_HH
+#define DUNE_TECTONIC_SPATIAL_SOLVING_FUNCTIONAL_HH
+
+#include <cstddef>
+#include <type_traits>
+
+#include <dune/solvers/common/wrapownshare.hh>
+#include <dune/solvers/common/copyorreference.hh>
+#include <dune/solvers/common/interval.hh>
+#include <dune/solvers/common/resize.hh>
+
+#include <dune/matrix-vector/algorithm.hh>
+#include <dune/matrix-vector/axpy.hh>
+
+#include <dune/tnnmg/functionals/boxconstrainedquadraticfunctional.hh>
+
+#include "../../utils/maxeigenvalue.hh"
+#include "../../utils/debugutils.hh"
+
+template<class M, class V, class N, class L, class U, class R>
+class DirectionalRestriction;
+
+template<class M, class E, class V, class N, class L, class U, class O, class R>
+class ShiftedFunctional;
+
+template <class M, class V, class N, class L, class U, class R>
+class Functional;
+
+/** \brief Coordinate restriction of box constrained quadratic functional with nonlinearity;
+ *         mainly used for presmoothing in TNNMG algorithm
+ *
+ *  \tparam M global matrix type
+ *  \tparam V global vector type
+ *  \tparam V nonlinearity type
+ *  \tparam R Range type
+ */
+template<class M, class E, class V, class N, class L, class U, class O, class R>
+class ShiftedFunctional {
+
+public:
+  using Matrix = std::decay_t<M>;
+  using Eigenvalues = E;
+  using Vector = std::decay_t<V>;
+  using Nonlinearity = std::decay_t<N>;
+  using LowerObstacle = std::decay_t<L>;
+  using UpperObstacle = std::decay_t<U>;
+  using Origin = std::decay_t<O>;
+  using Range = R;
+
+  template <class MM, class VV, class LL, class UU, class OO>
+  ShiftedFunctional(MM&& matrix, const Eigenvalues& maxEigenvalues, VV&& linearPart, const Nonlinearity& phi,
+                    LL&& lower, UU&& upper, OO&& origin) :
+      quadraticPart_(std::forward<MM>(matrix)),
+      maxEigenvalues_(maxEigenvalues),
+      originalLinearPart_(std::forward<VV>(linearPart)),
+      phi_(phi),
+      originalLowerObstacle_(std::forward<LL>(lower)),
+      originalUpperObstacle_(std::forward<UU>(upper)),
+      origin_(std::forward<OO>(origin))
+  {}
+
+  Range operator()(const Vector& v) const
+  {
+    auto w = origin();
+    w += v;
+    if (Dune::TNNMG::checkInsideBox(w, originalLowerObstacle(), originalUpperObstacle())) {
+        Vector temp;
+        Dune::Solvers::resizeInitializeZero(temp,v);
+        quadraticPart().umv(w, temp);
+        temp *= 0.5;
+        temp -= originalLinearPart();
+        return temp*w + phi()(w);
+      }
+    return std::numeric_limits<Range>::max();
+
+    /*Vector temp;
+    Dune::Solvers::resizeInitializeZero(temp,v);
+    quadraticPart().umv(w, temp);
+    temp *= 0.5;
+    temp -= originalLinearPart();
+    return temp*w + phi()(w);*/
+  }
+
+  const Matrix& quadraticPart() const
+  {
+    return quadraticPart_.get();
+  }
+
+  const Vector& originalLinearPart() const
+  {
+    return originalLinearPart_.get();
+  }
+
+  const Origin& origin() const
+  {
+    return origin_.get();
+  }
+
+  void updateOrigin()
+  {}
+
+  void updateOrigin(std::size_t i)
+  {}
+
+  const LowerObstacle& originalLowerObstacle() const
+  {
+    return originalLowerObstacle_.get();
+  }
+
+  const UpperObstacle& originalUpperObstacle() const
+  {
+    return originalUpperObstacle_.get();
+  }
+
+  const auto& phi() const {
+      return phi_;
+  }
+
+  const auto& maxEigenvalues() const {
+    return maxEigenvalues_;
+  }
+
+protected:
+  Dune::Solvers::ConstCopyOrReference<M> quadraticPart_;
+  const Eigenvalues& maxEigenvalues_;
+
+  Dune::Solvers::ConstCopyOrReference<V> originalLinearPart_;
+  const Nonlinearity& phi_;
+
+  Dune::Solvers::ConstCopyOrReference<L> originalLowerObstacle_;
+  Dune::Solvers::ConstCopyOrReference<U> originalUpperObstacle_;
+
+  Dune::Solvers::ConstCopyOrReference<O> origin_;
+};
+
+/** \brief Coordinate restriction of box constrained quadratic functional with nonlinearity;
+ *         mainly used for line search step in TNNMG algorithm
+ *
+ *  \tparam M Global matrix type
+ *  \tparam V Global vector type
+ *  \tparam N nonlinearity type
+ *  \tparam L Global lower obstacle type
+ *  \tparam U Global upper obstacle type
+ *  \tparam R Range type
+ */
+template<class M, class V, class N, class L, class U, class R=double>
+class DirectionalRestriction :
+  public Dune::TNNMG::BoxConstrainedQuadraticDirectionalRestriction<M,V,L,U,R>
+{
+  using Base = Dune::TNNMG::BoxConstrainedQuadraticDirectionalRestriction<M,V,L,U,R>;
+  using Nonlinearity = N;
+  using Interval = typename Dune::Solvers::Interval<R>;
+
+public:
+  using GlobalMatrix = typename Base::GlobalMatrix;
+  using GlobalVector = typename Base::GlobalVector;
+  using GlobalLowerObstacle = typename Base::GlobalLowerObstacle;
+  using GlobalUpperObstacle = typename Base::GlobalUpperObstacle;
+
+  using Matrix = typename Base::Matrix;
+  using Vector = typename Base::Vector;
+
+  DirectionalRestriction(const GlobalMatrix& matrix, const GlobalVector& linearTerm, const Nonlinearity& phi, const GlobalLowerObstacle& lower, const GlobalLowerObstacle& upper, const GlobalVector& origin, const GlobalVector& direction, const double scaling) :
+    Base(matrix, linearTerm, lower, upper, origin, direction),
+    origin_(origin),
+    direction_(direction),
+    phi_(phi),
+    scaling_(scaling)
+  {
+    phi_.directionalDomain(origin_, direction_, domain_);
+
+    //std::cout << domain_[0] << " " << domain_[1] << "Phi domain:" << std::endl;
+    //std::cout << this->defectLower_ << " " << this->defectUpper_ << "defect obstacles:" << std::endl;
+
+    if (domain_[0] < this->defectLower_) {
+       domain_[0] = this->defectLower_;
+    }
+
+    if (domain_[1] > this->defectUpper_) {
+       domain_[1] = this->defectUpper_;
+    }
+  }
+
+    auto subDifferential(double x) const {
+      Interval D;
+      GlobalVector uxv = origin_;
+
+      Dune::MatrixVector::addProduct(uxv, x, direction_);
+      phi_.directionalSubDiff(uxv, direction_, D);
+      auto const Axmb = this->quadraticPart_ * x - this->linearPart_;
+      D[0] += Axmb;
+      D[1] += Axmb;
+
+      return D;
+    }
+
+    auto domain() const {
+      return domain_;
+    }
+
+    const GlobalVector& origin() const {
+        return origin_;
+    }
+
+    const GlobalVector& direction() const {
+        return direction_;
+    }
+
+    double scaling() const {
+        return scaling_;
+    }
+protected:
+  const GlobalVector& origin_;
+  GlobalVector direction_;
+
+  const Nonlinearity& phi_;
+  Interval domain_;
+
+  const double scaling_;
+};
+
+
+/** \brief Box constrained quadratic functional with nonlinearity
+ *         Note: call setIgnore() to set up functional in affine subspace with ignore information
+ *
+ *  \tparam V Vector type
+ *  \tparam N Nonlinearity type
+ *  \tparam L Lower obstacle type
+ *  \tparam U Upper obstacle type
+ *  \tparam R Range type
+ */
+template<class N, class V, class R>
+class FirstOrderFunctional {
+    using Interval = typename Dune::Solvers::Interval<R>;
+
+public:
+    using Nonlinearity = std::decay_t<N>;
+    using Vector = V;
+    using LowerObstacle = V;
+    using UpperObstacle = V;
+    using Range = R;
+
+    using field_type = typename V::field_type;
+public:
+    template <class LL, class UU, class OO, class DD>
+    FirstOrderFunctional(
+            const Range& maxEigenvalue,
+            const Range& linearPart,
+            const Nonlinearity& phi,
+            LL&& lower,
+            UU&& upper,
+            OO&& origin,
+            DD&& direction) :
+        quadraticPart_(maxEigenvalue),
+        linearPart_(linearPart),
+        lower_(std::forward<LL>(lower)),
+        upper_(std::forward<UU>(upper)),
+        origin_(std::forward<OO>(origin)),
+        direction_(std::forward<DD>(direction)),
+        phi_(phi) {
+
+        // set defect obstacles
+        defectLower_ = -std::numeric_limits<field_type>::max();
+        defectUpper_ = std::numeric_limits<field_type>::max();
+        Dune::TNNMG::directionalObstacles(origin_.get(), direction_.get(), lower_.get(), upper_.get(), defectLower_, defectUpper_);
+
+        // set domain
+        phi_.directionalDomain(origin_.get(), direction_.get(), domain_);
+
+        if (domain_[0] < defectLower_) {
+           domain_[0] = defectLower_;
+        }
+
+        if (domain_[1] > defectUpper_) {
+           domain_[1] = defectUpper_;
+        }
+    }
+
+  Range operator()(const Vector& v) const
+  {
+    DUNE_THROW(Dune::NotImplemented, "Evaluation of FirstOrderFunctional not implemented");
+  }
+
+  auto subDifferential(double x) const {
+    Interval Di;
+    Vector uxv = origin_.get();
+
+    Dune::MatrixVector::addProduct(uxv, x, direction_.get());
+    phi_.directionalSubDiff(uxv, direction_.get(), Di);
+
+    const auto Axmb = quadraticPart_ * x - linearPart_;
+    Di[0] += Axmb;
+    Di[1] += Axmb;
+
+    return Di;
+  }
+
+  const Interval& domain() const {
+    return domain_;
+  }
+
+  const auto& origin() const {
+      return origin_.get();
+  }
+
+  const auto& direction() const {
+      return direction_.get();
+  }
+
+  const auto& lowerObstacle() const {
+      return defectLower_;
+  }
+
+  const auto& upperObstacle() const {
+      return defectUpper_;
+  }
+
+  const auto& quadraticPart() const {
+      return quadraticPart_;
+  }
+
+  const auto& linearPart() const {
+      return linearPart_;
+  }
+private:
+  const Range quadraticPart_;
+  const Range linearPart_;
+
+  Dune::Solvers::ConstCopyOrReference<LowerObstacle> lower_;
+  Dune::Solvers::ConstCopyOrReference<UpperObstacle> upper_;
+
+  Dune::Solvers::ConstCopyOrReference<Vector> origin_;
+  Dune::Solvers::ConstCopyOrReference<Vector> direction_;
+
+  const Nonlinearity& phi_;
+
+  Interval domain_;
+
+  field_type defectLower_;
+  field_type defectUpper_;
+};
+
+// \ToDo This should be an inline friend of ShiftedBoxConstrainedQuadraticFunctional
+// but gcc-4.9.2 shipped with debian jessie does not accept
+// inline friends with auto return type due to bug-59766.
+// Notice, that this is fixed in gcc-4.9.3.
+template<class GlobalShiftedFunctional, class Index>
+auto coordinateRestriction(const GlobalShiftedFunctional& f, const Index& i)
+{
+  using Range = typename GlobalShiftedFunctional::Range;
+  using LocalMatrix = std::decay_t<decltype(f.quadraticPart()[i][i])>;
+  using LocalVector = std::decay_t<decltype(f.originalLinearPart()[i])>;
+  using LocalLowerObstacle = std::decay_t<decltype(f.originalLowerObstacle()[i])>;
+  using LocalUpperObstacle = std::decay_t<decltype(f.originalUpperObstacle()[i])>;
+
+  using namespace Dune::MatrixVector;
+  namespace H = Dune::Hybrid;
+
+  const LocalMatrix* Aii_p = nullptr;
+
+  //print(f.originalLinearPart(), "f.linearPart: ");
+  //print(f.quadraticPart(), "f.quadraticPart: ");
+
+  LocalVector ri = f.originalLinearPart()[i];
+  const auto& Ai = f.quadraticPart()[i];
+  sparseRangeFor(Ai, [&](auto&& Aij, auto&& j) {
+      // TODO Here we must implement a wrapper to guarantee that this will work with proxy matrices!
+      H::ifElse(H::equals(j, i), [&](auto&& id){
+        Aii_p = id(&Aij);
+      });
+      Dune::TNNMG::Imp::mmv(Aij, f.origin()[j], ri, Dune::PriorityTag<1>());
+  });
+
+  //print(*Aii_p, "Aii_p:");
+  //print(ri, "ri:");
+
+  //print(f.originalLowerObstacle()[i], "lower:");
+  //print(f.originalUpperObstacle()[i], "upper:");
+
+  auto& phii = f.phi().restriction(i);
+
+  return ShiftedFunctional<LocalMatrix&, Range, LocalVector, std::decay_t<decltype(phii)>, LocalLowerObstacle&, LocalUpperObstacle&, LocalVector&, Range>(*Aii_p, f.maxEigenvalues()[i], std::move(ri), phii, f.originalLowerObstacle()[i], f.originalUpperObstacle()[i], f.origin()[i]);
+}
+
+
+/** \brief Box constrained quadratic functional with nonlinearity
+ *
+ *  \tparam M Matrix type
+ *  \tparam V Vector type
+ *  \tparam L Lower obstacle type
+ *  \tparam U Upper obstacle type
+ *  \tparam R Range type
+ */
+template<class M, class V, class N, class L, class U, class R>
+class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L, U, R>
+{
+private:
+  using Base = Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L, U, R>;
+
+
+public:
+  using Nonlinearity = std::decay_t<N>;
+
+  using Matrix = typename Base::Matrix;
+  using Vector = typename Base::Vector;
+  using Range = typename Base::Range;
+  using LowerObstacle = typename Base::LowerObstacle;
+  using UpperObstacle = typename Base::UpperObstacle;
+
+  using Eigenvalues = std::vector<Range>;
+
+private:
+    Dune::Solvers::ConstCopyOrReference<N> phi_;
+    Eigenvalues maxEigenvalues_;
+
+public:
+
+  template <class MM, class VV, class NN, class LL, class UU>
+  Functional(
+          MM&& matrix,
+          VV&& linearPart,
+          NN&& phi,
+          LL&& lower,
+          UU&& upper) :
+    Base(std::forward<MM>(matrix), std::forward<VV>(linearPart), std::forward<LL>(lower), std::forward<UU>(upper)),
+    phi_(std::forward<NN>(phi)),
+    maxEigenvalues_(this->linearPart().size())
+  {
+     for (size_t i=0; i<this->quadraticPart().N(); ++i) {
+       const auto& Aii = this->quadraticPart()[i][i];
+       maxEigenvalues_[i] = maxEigenvalue(Aii);
+
+       // due to numerical imprecision, Aii might not be symmetric leading to complex eigenvalues
+       // consider Toeplitz decomposition of Aii and take only symmetric part
+
+       /*auto symBlock = Aii;
+
+       for (size_t j=0; j<symBlock.N(); j++) {
+           for (size_t k=0; k<symBlock.M(); k++) {
+               if (symBlock[j][k]/symBlock[j][j] < 1e-14)
+                symBlock[j][k] = 0;
+           }
+       }
+
+       try {
+       typename Vector::block_type eigenvalues;
+       Dune::FMatrixHelp::eigenValues(symBlock, eigenvalues);
+       maxEigenvalues_[i] =
+           *std::max_element(std::begin(eigenvalues), std::end(eigenvalues));
+       } catch (Dune::Exception &e) {
+            print(symBlock, "symBlock");
+            typename Vector::block_type eigenvalues;
+            Dune::FMatrixHelp::eigenValues(symBlock, eigenvalues);
+            std::cout << "complex eig in dof: " << i << std::endl;
+       } */
+     }
+  }
+
+  const Nonlinearity& phi() const {
+    return phi_.get();
+  }
+
+  const auto& maxEigenvalues() const {
+    return maxEigenvalues_;
+  }
+
+  Range operator()(const Vector& v) const
+  { 
+    //print(v, "v:");
+    //print(this->lowerObstacle(), "lower: ");
+    //print(this->upperObstacle(), "upper: ");
+    //std::cout << Dune::TNNMG::checkInsideBox(v, this->lowerObstacle(), this->upperObstacle()) << " " << Dune::TNNMG::QuadraticFunctional<M,V,R>::operator()(v) << " " << phi_.get().operator()(v) << std::endl;
+    if (Dune::TNNMG::checkInsideBox(v, this->lowerObstacle(), this->upperObstacle()))
+      return Dune::TNNMG::QuadraticFunctional<M,V,R>::operator()(v) + phi_.get()(v);
+    return std::numeric_limits<Range>::max();
+  }
+
+  friend auto directionalRestriction(const Functional& f, const Vector& origin, const Vector& direction)
+    -> DirectionalRestriction<Matrix, Vector, Nonlinearity, LowerObstacle, UpperObstacle, Range>
+  {
+    // rescale direction for numerical stability
+    auto dir = direction;
+    auto dirNorm = dir.two_norm();
+    if (dirNorm > 0.0)
+        dir /= dirNorm;
+    else {
+        dirNorm = 0.0;
+        dir = 0.0;
+    }
+
+
+    return DirectionalRestriction<Matrix, Vector, Nonlinearity, LowerObstacle, UpperObstacle, Range>(f.quadraticPart(), f.linearPart(), f.phi(), f.lowerObstacle(), f.upperObstacle(), origin, dir, dirNorm);
+  }
+
+  friend auto shift(const Functional& f, const Vector& origin)
+    -> ShiftedFunctional<Matrix&, Eigenvalues, Vector&, Nonlinearity&, LowerObstacle&, UpperObstacle&, Vector&, Range>
+  {
+    return ShiftedFunctional<Matrix&, Eigenvalues, Vector&, Nonlinearity&, LowerObstacle&, UpperObstacle&, Vector&, Range>(f.quadraticPart(), f.maxEigenvalues(), f.linearPart(), f.phi(), f.lowerObstacle(), f.upperObstacle(), origin);
+  }
+};
+
+
+#endif
diff --git a/dune/tectonic/spatial-solving/tnnmg/localbisectionsolver_old.hh b/dune/tectonic/spatial-solving/tnnmg/localbisectionsolver_old.hh
new file mode 100644
index 0000000000000000000000000000000000000000..454d898edba5f8f4de6f618e6899e50d449ed57a
--- /dev/null
+++ b/dune/tectonic/spatial-solving/tnnmg/localbisectionsolver_old.hh
@@ -0,0 +1,130 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_TECTONIC_LOCALBISECTIONSOLVER_HH
+#define DUNE_TECTONIC_LOCALBISECTIONSOLVER_HH
+
+#include <dune/matrix-vector/axpy.hh>
+
+#include <dune/tnnmg/localsolvers/scalarobstaclesolver.hh>
+#include <dune/tnnmg/problem-classes/bisection.hh>
+
+#include "functional.hh"
+
+#include "../../utils/debugutils.hh"
+
+/**
+ * \brief A local solver for quadratic obstacle problems with nonlinearity
+ * using bisection
+ */
+class LocalBisectionSolver
+{
+public:
+  template<class Vector, class Functional, class BitVector>
+  void operator()(Vector& x, const Functional& f, const BitVector& ignore) const {
+      double safety = 1e-14; //or (f.upperObstacle()-f.lowerObstacle()<safety)
+      if (ignore.all()) {
+          return;
+      }
+
+      auto maxEigenvalue = f.maxEigenvalues();
+
+      auto origin = f.origin();
+      auto linearPart = f.originalLinearPart();
+
+      Dune::MatrixVector::addProduct(linearPart, maxEigenvalue, origin);
+
+      for (size_t j = 0; j < ignore.size(); ++j)
+        if (ignore[j])
+          linearPart[j] = 0; // makes sure result remains in subspace after correction
+        else
+          origin[j] = 0; // shift affine offset
+
+      double const linearPartNorm = linearPart.two_norm();
+      if (linearPartNorm <= 0.0)
+        return;
+      linearPart /= linearPartNorm;
+
+      std::cout << "maxEigenvalue " << maxEigenvalue << std::endl;
+      print(linearPart, "linearPart:");
+      std::cout << "linearPartNorm " << linearPartNorm << std::endl;
+      print(origin, "origin:");
+
+      using Nonlinearity = std::decay_t<decltype(f.phi())>;
+      using Range = std::decay_t<decltype(f.maxEigenvalues())>;
+      using FirstOrderFunctional = FirstOrderFunctional<Nonlinearity, Vector, Range>;
+
+      auto lower = f.originalLowerObstacle();
+      auto upper = f.originalUpperObstacle();
+
+      //print(lower, "lower:");
+      //print(upper, "upper:");
+
+      FirstOrderFunctional firstOrderFunctional(maxEigenvalue, linearPartNorm, f.phi(),
+                                                lower, upper,
+                                                origin, linearPart);
+
+      //std::cout << "lower: " << firstOrderFunctional.lowerObstacle() << " upper: " << firstOrderFunctional.upperObstacle() << std::endl;
+
+      // scalar obstacle solver without nonlinearity
+      typename Functional::Range alpha;
+      //Dune::TNNMG::ScalarObstacleSolver obstacleSolver;
+      //obstacleSolver(alpha, firstOrderFunctional, false);
+
+      //direction *= alpha;
+
+      /*const auto& A = f.quadraticPart();
+      std::cout << "f.quadratic(): " << std::endl;
+      for (size_t i=0; i<A.N(); i++) {
+            for (size_t j=0; j<A.M(); j++) {
+                std::cout << A[i][j] << " ";
+            }
+            std::cout << std::endl;
+      }*/
+      //std::cout << f.quadraticPart() << std::endl;
+      //std::cout << "A: " << directionalF.quadraticPart() << " " << (directionalF.quadraticPart()==f.quadraticPart()[0][0]) << std::endl;
+      /*std::cout << "b: " << directionalF.linearPart() << std::endl;
+      std::cout << "domain: " << directionalF.domain()[0] << " " << directionalF.domain()[1] << std::endl;
+      auto D = directionalF.subDifferential(0);
+      std::cout << "subDiff at x: " << D[0] << " " << D[1] << std::endl;*/
+
+      //std::cout << "domain: " << firstOrderFunctional.domain()[0] << " " << firstOrderFunctional.domain()[1] << std::endl;
+
+
+      const auto& domain = firstOrderFunctional.domain();
+      if (std::abs(domain[0]-domain[1])>safety) {
+        int bisectionsteps = 0;
+        const Bisection globalBisection(0.0, 1.0, 0.0, 0.0);
+
+        alpha = globalBisection.minimize(firstOrderFunctional, 0.0, 0.0, bisectionsteps);
+      } else {
+          alpha = domain[0];
+      }
+
+      std::cout << "alpha: " << alpha << std::endl;
+      linearPart *= alpha;
+
+      std::cout << linearPart << std::endl;
+
+#ifdef NEW_TNNMG_COMPUTE_ITERATES_DIRECTLY
+      if (std::abs(alpha)> safety) {
+        x = origin;
+        x += linearPart;
+      } else {
+        x = f.origin();
+      }
+#else
+      if (std::abs(alpha)> safety) {
+        x = origin;
+        x += linearPart;
+        x -= f.origin();
+      }
+#endif
+      std::cout << "new x: " << x << std::endl;
+  }
+};
+
+#endif
+
+
+
+