diff --git a/dune/tectonic/ellipticenergy.hh b/dune/tectonic/ellipticenergy.hh
index d64b8ab123d864462ac1c2c8ae318334e27c8922..97e44277e435b3f5463494da1eb0b44597615450 100644
--- a/dune/tectonic/ellipticenergy.hh
+++ b/dune/tectonic/ellipticenergy.hh
@@ -52,6 +52,24 @@ template <int dim> class EllipticEnergy {
   }
 
   // returns false if the direction is tangential
+  void descentDirectionNew(SmallVector const &x, SmallVector &ret) const {
+    SmallVector pg;
+    upperGradient(x, pg);
+    SmallVector mg;
+    lowerGradient(x, mg);
+    double const pgx = pg * x;
+    double const mgx = mg * x;
+    if (pgx >= 0 && mgx >= 0) {
+      ret = pg;
+      ret *= -1;
+    } else if (pgx <= 0 && mgx <= 0) {
+      ret = mg;
+      ret *= -1;
+    } else {
+      assert(false);
+    }
+  }
+
   bool descentDirection(SmallVector const &x, SmallVector &ret) const {
     // Check the squared norm rather than each component because
     // complementaryProjection() divides by it
@@ -234,5 +252,65 @@ void minimise(Functional const &J, typename Functional::SmallVector &x,
     }
   }
 }
+
+// NOTE: only works for the 2D case
+template <class Functional>
+void minimise2(Functional const &J, typename Functional::SmallVector &x,
+               size_t steps, Bisection const &bisection) {
+  typedef typename Functional::SmallVector SmallVector;
+  minimisationInitialiser(J, bisection, x);
+
+  { // Make a single step where we already know we're not differentiable
+    SmallVector descDir;
+    if (x == SmallVector(0))
+      J.descentAtZero(descDir);
+    else
+      J.descentDirectionNew(x, descDir);
+    descentMinimisation(J, x, descDir, bisection);
+  }
+
+  // From here on, we're in a C1 region and stay there.
+  for (size_t i = 1; i < steps; ++i) {
+    SmallVector descDir;
+    J.descentDirectionNew(x, descDir);
+    descentMinimisation(J, x, descDir, bisection);
+  }
+}
+
+template <class Functional>
+void minimisationInitialiser(Functional const &J, Bisection const &bisection,
+                             typename Functional::SmallVector &startingPoint) {
+  typedef typename Functional::SmallVector SmallVector;
+
+  std::vector<double> const kinks = { 5, 10,
+                                      15 }; // FIXME: We happen to know these
+
+  SmallVector x_old(0);
+  double Jx_old = J(x_old);
+
+  for (auto &kink : kinks) {
+    SmallVector x1 = { kink, 0 }; // Random vector that has the right norm
+    SmallVector const descDir1 = { x1[1], -x1[0] };
+    tangentialMinimisation(J, x1, descDir1, bisection);
+    double const Jx1 = J(x1);
+
+    SmallVector x2 = { -x1[0], -x1[1] };
+    SmallVector const descDir2 = { x2[1], -x2[0] };
+    tangentialMinimisation(J, x2, descDir2, bisection);
+    double const Jx2 = J(x2);
+
+    double const Jx = (Jx2 < Jx1 ? Jx2 : Jx1);
+    SmallVector const x = (Jx2 < Jx1 ? x2 : x1);
+
+    if (Jx >= Jx_old) {
+      startingPoint = x_old;
+      return;
+    }
+
+    Jx_old = Jx;
+    x_old = x;
+  }
+  startingPoint = x_old;
+}
 }
 #endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 974967c314653e3b70eda30d7f46284513e3db2a..2467aafbdfe3640ba86b5db998b0fa8ee7df0d13 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,7 +13,8 @@ check_PROGRAMS = \
 	test-gradient-sample-steep2 \
 	test-gradient-sample-verysteep \
 	test-gradient-sample2 \
-	test-gradient-trivial
+	test-gradient-trivial \
+	test-minimise2
 
 test_circle_1_SOURCES                      = test-circle.cc
 test_circle_1_CPPFLAGS                     = $(AM_CPPFLAGS) -DDUNE_TECTONIC_TEST_CIRCLE_SCALE=1
@@ -32,6 +33,7 @@ test_gradient_sample_steep2_SOURCES        = test-gradient-sample-steep2.cc
 test_gradient_sample_verysteep_SOURCES     = test-gradient-sample-verysteep.cc
 test_gradient_sample2_SOURCES              = test-gradient-sample2.cc
 test_gradient_trivial_SOURCES              = test-gradient-trivial.cc
+test_minimise2_SOURCES                     = test-minimise2.cc
 
 bin_PROGRAMS = \
 	one-body-sample-2D \
diff --git a/src/test-minimise2.cc b/src/test-minimise2.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1646bc0ce53733cace53a0cad91256996f5788ba
--- /dev/null
+++ b/src/test-minimise2.cc
@@ -0,0 +1,58 @@
+/* Check that minimise2 always produces better results than minimise
+   when the latter starts from 0 */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cassert>
+
+#include <boost/format.hpp>
+
+#include <dune/common/shared_ptr.hh>
+
+#include <dune/tectonic/ellipticenergy.hh>
+
+#include "test-gradient-method-nicefunction.hh"
+#include "test-gradient-method-helper.hh"
+
+int main() {
+  int const dim = 2;
+  typedef Dune::EllipticEnergy<dim> Functional;
+  typedef Functional::SmallMatrix SmallMatrix;
+  typedef Functional::SmallVector SmallVector;
+
+  SmallMatrix const A = { { 4, 1.5 }, { 1.5, 3 } };
+
+  std::vector<SmallVector> const bs = {
+    { 1, 2 }, { -8, -14 }, { -16, -28 }, { -24, -42 }, { -32, -56 },
+  };
+
+  auto const f = Dune::make_shared<Dune::ThreeKinkFunction const>();
+  auto const phi = Dune::make_shared<Functional::NonlinearityType const>(f);
+
+  std::vector<Functional> const Js = { Functional(A, bs[0], phi),
+                                       Functional(A, bs[1], phi),
+                                       Functional(A, bs[2], phi),
+                                       Functional(A, bs[3], phi),
+                                       Functional(A, bs[4], phi) };
+
+  Bisection const bisection(0.0, 1.0, 1e-12, false, 0);
+
+  size_t const runs = 5;
+
+  SmallVector x;
+
+  for (auto const &J : Js) {
+    x = { 0, 0 };
+    Dune::minimise(J, x, runs, bisection);
+    double const xmin = J(x);
+
+    x = { 0, 0 };
+    Dune::minimise2(J, x, runs, bisection);
+    double const xmin2 = J(x);
+    std::cout << xmin << std::endl;
+    std::cout << xmin2 << std::endl << std::endl;
+    assert(xmin2 <= xmin);
+  }
+}