From 74b7b0b0fcfe40718fe44994cefa14e3e515da4c Mon Sep 17 00:00:00 2001
From: Uli Sack <usack@math.fu-berlin.de>
Date: Tue, 23 Oct 2012 10:13:48 +0000
Subject: [PATCH] introduced rudimentary highly experimental feature of a
 SolverResult class to contain result related information such as for example
 number of performed iterations, convergence rates etc; NOTE: the
 implementation and interface will change w/o further notice

[[Imported from SVN: r7084]]
---
 dune/solvers/solvers/iterativesolver.hh |  4 +-
 dune/solvers/solvers/loopsolver.cc      | 12 ++++--
 dune/solvers/solvers/loopsolver.hh      |  2 +-
 dune/solvers/solvers/solver.hh          | 50 ++++++++++++++++++++++---
 4 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/dune/solvers/solvers/iterativesolver.hh b/dune/solvers/solvers/iterativesolver.hh
index b982a748..0df872b0 100644
--- a/dune/solvers/solvers/iterativesolver.hh
+++ b/dune/solvers/solvers/iterativesolver.hh
@@ -26,7 +26,7 @@
         /** \brief Constructor taking all relevant data */
         IterativeSolver(int maxIterations,
                         double tolerance,
-                        Norm<VectorType>* errorNorm,
+                        const Norm<VectorType>* errorNorm,
                         VerbosityMode verbosity,
                         bool useRelativeError=true)
             : Solver(verbosity), 
@@ -54,7 +54,7 @@
         int maxIterations_;
 
         //! The norm used to measure convergence
-        Norm<VectorType>* errorNorm_;
+        const Norm<VectorType>* errorNorm_;
 
         /** \brief If this string is nonempty it is expected to contain a valid
             directory name.  All intermediate iterates are then written there. */
diff --git a/dune/solvers/solvers/loopsolver.cc b/dune/solvers/solvers/loopsolver.cc
index 62a3b8f5..bf98e042 100644
--- a/dune/solvers/solvers/loopsolver.cc
+++ b/dune/solvers/solvers/loopsolver.cc
@@ -2,6 +2,7 @@
 #include <limits>
 #include <iostream>
 #include <iomanip>
+#include <dune/solvers/solvers/solver.hh>
 
 template <class VectorType, class BitVectorType>
 void ::LoopSolver<VectorType, BitVectorType>::check() const
@@ -16,7 +17,7 @@ void ::LoopSolver<VectorType, BitVectorType>::check() const
 }
 
 template <class VectorType, class BitVectorType>
-void ::LoopSolver<VectorType, BitVectorType>::solve()
+void LoopSolver<VectorType, BitVectorType>::solve()
 {
 
     int i;
@@ -70,8 +71,8 @@ void ::LoopSolver<VectorType, BitVectorType>::solve()
     int convRateCounter = 0;
 
     // Loop until desired tolerance or maximum number of iterations is reached
-    for (i=0; i<this->maxIterations_ && (error>this->tolerance_ || std::isnan(error)); i++) {
-
+    for (i=0; i<this->maxIterations_ && (error>this->tolerance_ || std::isnan(error)); i++) 
+    {
         // Backup of the current solution for the error computation later on
         VectorType oldSolution = iterationStep_->getSol();
 
@@ -107,7 +108,8 @@ void ::LoopSolver<VectorType, BitVectorType>::solve()
         if (this->useRelativeError_ && !std::isnan(error/oldNorm))
             error = error / oldNorm;
 
-        if (!isinf(convRate) && !isnan(convRate) && i>0) {
+        if (!isinf(convRate) && !isnan(convRate) && i>0)
+        {
             totalConvRate *= convRate;
             this->maxTotalConvRate_ = std::max(this->maxTotalConvRate_, std::pow(totalConvRate, 1/((double)convRateCounter+1)));
             convRateCounter++;
@@ -155,4 +157,6 @@ void ::LoopSolver<VectorType, BitVectorType>::solve()
         std::cout << "--------------------\n";
     }
 
+    this->setResult(i,error<=this->tolerance_,totalConvRate);
+
 }
diff --git a/dune/solvers/solvers/loopsolver.hh b/dune/solvers/solvers/loopsolver.hh
index 5cbbb675..7bb4185b 100644
--- a/dune/solvers/solvers/loopsolver.hh
+++ b/dune/solvers/solvers/loopsolver.hh
@@ -19,7 +19,7 @@ public:
     LoopSolver(IterationStep<VectorType, BitVectorType>* iterationStep,
                int maxIterations,
                double tolerance,
-               Norm<VectorType>* errorNorm,
+               const Norm<VectorType>* errorNorm,
                Solver::VerbosityMode verbosity,
                bool useRelativeError=true,
                const VectorType* referenceSolution=0)
diff --git a/dune/solvers/solvers/solver.hh b/dune/solvers/solvers/solver.hh
index caa6dd80..a5859567 100644
--- a/dune/solvers/solvers/solver.hh
+++ b/dune/solvers/solvers/solver.hh
@@ -3,11 +3,32 @@
 
 #include <dune/solvers/common/numproc.hh>
 
-    /** \brief The base class for all sorts of solver algorithms */
-    class Solver : public NumProc
-    {
+/**  \brief struct to store result related information such as for example number of iterations etc.
+  *
+  *  \warning The interface and implementation is so far highly experimental and will change without further notice!
+  */
+struct SolverResult
+{
+    size_t iterations;
+    bool converged;
+    double conv_rate;
+//  double reduction;
+//  double elapsed;
+    SolverResult(){}
+
+    SolverResult(size_t iter, bool conv, double rate):
+        iterations(iter),
+        converged(conv),
+        conv_rate(rate)
+    {}
+
+};
+
+/** \brief The base class for all sorts of solver algorithms */
+class Solver : public NumProc
+{
     public:
-        Solver(VerbosityMode verbosity)
+        Solver(VerbosityMode verbosity=FULL)
             : NumProc(verbosity)
         {}
 
@@ -24,5 +45,24 @@
          * solution algorithm */
         virtual void solve() = 0;
 
-    };
+        SolverResult& getResult()
+        {
+            return result;
+        }
+
+        void setResult(const SolverResult& new_result)
+        {
+            result = new_result;
+        }
+
+        void setResult(size_t iter, bool conv, double rate)
+        {
+            result.iterations = iter;
+            result.converged = conv;
+            result.conv_rate = rate;
+        }
+
+    private:
+        SolverResult result;
+};
 #endif
-- 
GitLab