From c32fa7880110481d779b142f62ddf81e59f5f2c5 Mon Sep 17 00:00:00 2001
From: Elias Pipping <elias.pipping@fu-berlin.de>
Date: Fri, 3 Aug 2012 20:48:32 +0200
Subject: [PATCH] Kinks: New Function and test

---
 src/Makefile.am                          |  2 +
 src/test-gradient-kinks.cc               | 57 ++++++++++++++++++++++++
 src/test-gradient-method-nicefunction.hh | 40 +++++++++++++++++
 3 files changed, 99 insertions(+)
 create mode 100644 src/test-gradient-kinks.cc

diff --git a/src/Makefile.am b/src/Makefile.am
index 86c0159d..974967c3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,6 +4,7 @@ check_PROGRAMS = \
 	test-gradient-horrible \
 	test-gradient-horrible-logarithmic \
 	test-gradient-identity \
+	test-gradient-kinks \
 	test-gradient-parabola \
 	test-gradient-sample \
 	test-gradient-sample-3d \
@@ -21,6 +22,7 @@ test_circle_10_CPPFLAGS                    = $(AM_CPPFLAGS) -DDUNE_TECTONIC_TEST
 test_gradient_horrible_SOURCES             = test-gradient-horrible.cc
 test_gradient_horrible_logarithmic_SOURCES = test-gradient-horrible-logarithmic.cc
 test_gradient_identity_SOURCES             = test-gradient-identity.cc
+test_gradient_kinks_SOURCES                = test-gradient-kinks.cc
 test_gradient_parabola_SOURCES             = test-gradient-parabola.cc
 test_gradient_sample_SOURCES               = test-gradient-sample.cc
 test_gradient_sample_3d_SOURCES            = test-gradient-sample-3d.cc
diff --git a/src/test-gradient-kinks.cc b/src/test-gradient-kinks.cc
new file mode 100644
index 00000000..a4d17e23
--- /dev/null
+++ b/src/test-gradient-kinks.cc
@@ -0,0 +1,57 @@
+/* Checks if the algorithm converges regardless of where it starts */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cassert>
+
+#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 } };
+  SmallVector const b = { -8, 14 };
+
+  auto const f = Dune::make_shared<Dune::ThreeKinkFunction const>();
+  auto const phi = Dune::make_shared<Functional::NonlinearityType const>(f);
+  Functional const J(A, b, phi);
+
+  size_t runs = 5;
+
+  double ret1;
+  {
+    SmallVector start = { 17, 34 };
+    ret1 = functionTester(J, start, runs);
+  }
+
+  double ret2;
+  {
+    SmallVector start = { 1, 0 };
+    ret2 = functionTester(J, start, runs);
+  }
+  assert(std::abs(ret1 - ret2) < 1e-5);
+
+  double ret3;
+  {
+    SmallVector start = { 0, 1 };
+    ret3 = functionTester(J, start, runs);
+  }
+  assert(std::abs(ret1 - ret3) < 1e-5);
+
+  double ret4;
+  {
+    SmallVector start = { 0, 0 };
+    ret4 = functionTester(J, start, runs);
+  }
+  assert(std::abs(ret1 - ret4) < 1e-5);
+}
diff --git a/src/test-gradient-method-nicefunction.hh b/src/test-gradient-method-nicefunction.hh
index bb80dc7b..091826fd 100644
--- a/src/test-gradient-method-nicefunction.hh
+++ b/src/test-gradient-method-nicefunction.hh
@@ -129,5 +129,45 @@ class HorribleFunctionLogarithmic : public MyFunction {
       return std::log(c + 1);
   }
 };
+
+class ThreeKinkFunction : public MyFunction {
+private:
+  std::vector<double> kinks = { 5, 10, 15 };
+
+public:
+  double virtual evaluate(double x) const {
+    double acc = 0;
+    double last_kink = 0;
+    int i;
+    for (i = 0; i < kinks.size(); ++i) {
+      if (x <= kinks[i])
+        break;
+
+      acc += (i + 1) * (kinks[i] - last_kink);
+      last_kink = kinks[i];
+    }
+    return acc + (i + 1) * (x - last_kink);
+  }
+
+  double virtual leftDifferential(double x) const {
+    if (x <= 5)
+      return 1;
+    if (x <= 10)
+      return 2;
+    if (x <= 15)
+      return 3;
+    return 4;
+  }
+
+  double virtual rightDifferential(double x) const {
+    if (x < 5)
+      return 1;
+    if (x < 10)
+      return 2;
+    if (x < 15)
+      return 3;
+    return 4;
+  }
+};
 }
 #endif
-- 
GitLab