From 26317b1df71a3717063d0a9af36bcee8614c532e Mon Sep 17 00:00:00 2001
From: Elias Pipping <elias.pipping@fu-berlin.de>
Date: Wed, 26 Oct 2011 15:19:10 +0200
Subject: [PATCH] Add MyBlockProblem class

based on blocknonlineargsproblem
---
 src/myblockproblem.hh | 160 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 160 insertions(+)
 create mode 100644 src/myblockproblem.hh

diff --git a/src/myblockproblem.hh b/src/myblockproblem.hh
new file mode 100644
index 00000000..a7c535f3
--- /dev/null
+++ b/src/myblockproblem.hh
@@ -0,0 +1,160 @@
+// Based on dune/tnnmg/problem-classes/blocknonlineargsproblem.hh
+
+// #include <dune/common/parametertree.hh>
+#include <dune/common/bitsetvector.hh>
+
+#include <dune/tnnmg/problem-classes/bisection.hh>
+#include <dune/tnnmg/problem-classes/convexproblem.hh>
+#include <dune/tnnmg/problem-classes/nonlinearity.hh>
+#include <dune/tnnmg/problem-classes/onedconvexfunction.hh>
+
+/** \brief Base class for problems where each block can be solved with a scalar
+ * Gauss-Seidel method */
+template <class ConvexProblemTypeTEMPLATE> class MyBlockProblem {
+public:
+  typedef ConvexProblemTypeTEMPLATE ConvexProblemType;
+  typedef typename ConvexProblemType::NonlinearityType NonlinearityType;
+  typedef typename ConvexProblemType::VectorType VectorType;
+  typedef typename ConvexProblemType::MatrixType MatrixType;
+  typedef typename ConvexProblemType::LocalVectorType LocalVectorType;
+  typedef typename ConvexProblemType::LocalMatrixType LocalMatrixType;
+
+  static const int block_size = ConvexProblemType::block_size;
+
+  /** \brief Solves one local system using a scalar Gauss-Seidel method */
+  class IterateObject;
+
+  MyBlockProblem(ConvexProblemType& problem) : problem(problem) {
+    bisection = Bisection(0.0, 1.0, 1e-15, true, 1e-14);
+  };
+
+  /** \brief Constructs and returns an iterate object */
+  IterateObject getIterateObject() { return IterateObject(bisection, problem); }
+
+private:
+  // problem data
+  ConvexProblemType& problem;
+
+  // commonly used minimization stuff
+  Bisection bisection;
+};
+
+/** \brief Solves one local system using a scalar Gauss-Seidel method */
+template <class ConvexProblemTypeTEMPLATE>
+class MyBlockProblem<ConvexProblemTypeTEMPLATE>::IterateObject {
+  friend class MyBlockProblem;
+
+protected:
+  /** \brief Constructor, protected so only friends can instantiate it
+   * \param bisection The class used to do a scalar bisection
+   * \param problem The problem including quadratic part and nonlinear/nonsmooth
+   * part
+   */
+  IterateObject(const Bisection& bisection, ConvexProblemType& problem)
+      : problem(problem),
+        bisection(bisection),
+        local_J(1.0, 0.0, problem.phi, 0, 0) {};
+
+public:
+  /** \brief Set the current iterate */
+  void setIterate(VectorType& u) {
+    // TODO How should the rang-1 term be handled
+    // ????????????????????????????????
+    // s = problem.Am*u;
+    problem.phi.setVector(u);
+
+    this->u = u;
+    return;
+  };
+
+  /** \brief Update the i-th block of the current iterate */
+  void updateIterate(const LocalVectorType& ui, int i) {
+    // TODO How should the rang-1 term be handled
+    // ????????????????????????????????
+    // s += (ui-u[i]) * problem.Am[i];
+
+    for (size_t j = 0; j < block_size; ++j)
+      problem.phi.updateEntry(i, ui[j], j);
+
+    u[i] = ui;
+    return;
+  };
+
+  /** \brief Minimize a local problem using a scalar Gauss-Seidel method
+   * \param[out] ui The solution
+   * \param i Block number
+   * \param ignore Set of degrees of freedom to leave untouched
+   *
+   * \return The minimizer of the local functional in the variable ui
+   */
+  void solveLocalProblem(
+      LocalVectorType& ui, int i,
+      const typename Dune::BitSetVector<block_size>::const_reference ignore) {
+    const LocalMatrixType* Aii;
+    LocalVectorType b(0.0);
+
+    typename MatrixType::row_type::ConstIterator it = problem.A[i].begin();
+    typename MatrixType::row_type::ConstIterator end = problem.A[i].end();
+    for (; it != end; ++it) {
+      int col = it.index();
+      if (col == i)
+        Aii = &(*it);
+      else
+        it->mmv(u[col], b);
+    }
+    b *= problem.a;
+    b += problem.f[i];
+    // TODO How should the rang-1 term be handled
+    // ????????????????????????????????
+
+    ui = u[i];
+    LocalVectorType ui_old = ui;
+    local_J.i = i;
+    for (size_t j = 0; j < block_size; ++j) {
+      if (ignore.test(j))
+        continue;
+
+      local_J.A = problem.a * (*Aii)[j][j];
+      local_J.b = b[j];
+      local_J.j = j;
+
+      typename LocalMatrixType::row_type::ConstIterator it = (*Aii)[j].begin();
+      typename LocalMatrixType::row_type::ConstIterator end = (*Aii)[j].end();
+      for (; it != end; ++it)
+        if (it.index() != j)
+          local_J.b -= (*it) * problem.a * ui[it.index()];
+
+      ui[j] = bisection.minimize(local_J, ui[j], ui[j], bisectionsteps);
+
+      // we need to update the intermediate local values ...
+      problem.phi.updateEntry(i, ui[j], j);
+    }
+    // ... and to restore the old ones after computation
+    for (int j = 0; j < block_size; ++j)
+      problem.phi.updateEntry(i, ui_old[j], j);
+
+    //            local_J.A += problem.am*problem.Am[i]*problem.Am[i];
+    //            local_J.b = problem.f[i] + problem.a*local_J.b;
+    //            local_J.b -= (s-u[i]*problem.Am[i])*problem.am*problem.Am[i];
+
+    //            ui = bisection.minimize<OneDConvexFunction>(local_J, u[i],
+    // u[i], bisectionsteps);
+    return;
+  };
+
+private:
+  // problem data
+  ConvexProblemType& problem;
+
+  // commonly used minimization stuff
+  Bisection bisection;
+  OneDConvexFunction<NonlinearityType> local_J;
+
+  // state data for smoothing procedure used by:
+  // setIterate, updateIterate, solveLocalProblem
+  VectorType u;
+
+  /** \brief Keeps track of the total number of bisection steps that were
+   * performed */
+  int bisectionsteps;
+};
-- 
GitLab