From 1f5d18b6a6987c31554b650eb20e7b7eeebcb6b6 Mon Sep 17 00:00:00 2001 From: Oliver Sander <oliver.sander@tu-dresden.de> Date: Fri, 13 Jan 2017 20:24:06 +0100 Subject: [PATCH] Move the iterationStep_ member into the IterativeSolver class Before, it was in the LoopSolver class, which derives directly from IterativeSolver. I think the original idea was that anything that is an iterative solver in the mathematical sense should derive from IterativeSolver. This includes things like the QuadraticIPOptSolver, which is the implementation of an iterative algorithm, inherits from Iterative- Solver, but where you cannot get the individual iteration step as a dune-solvers object. I started to think that this is the wrong approach. The inheritance should be governed less by what an object 'is' in the mathematical sense, but rather by the kind of API it provides. And I would expect an IterativeSolver to provide an IterationStep. --- dune/solvers/solvers/iterativesolver.cc | 5 +++++ dune/solvers/solvers/iterativesolver.hh | 3 +++ dune/solvers/solvers/loopsolver.cc | 22 +++++----------------- dune/solvers/solvers/loopsolver.hh | 13 +++---------- 4 files changed, 16 insertions(+), 27 deletions(-) diff --git a/dune/solvers/solvers/iterativesolver.cc b/dune/solvers/solvers/iterativesolver.cc index 604fefd6..419b6a14 100644 --- a/dune/solvers/solvers/iterativesolver.cc +++ b/dune/solvers/solvers/iterativesolver.cc @@ -12,6 +12,11 @@ template <class VectorType, class BitVectorType> void IterativeSolver<VectorType, BitVectorType>::check() const { + if (!iterationStep_) + DUNE_THROW(SolverError, "You need to supply an iteration step to an iterative solver!"); + + iterationStep_->check(); + if (!errorNorm_) DUNE_THROW(SolverError, "You need to supply a norm-computing routine to an iterative solver!"); } diff --git a/dune/solvers/solvers/iterativesolver.hh b/dune/solvers/solvers/iterativesolver.hh index 86047e06..edb2d25f 100644 --- a/dune/solvers/solvers/iterativesolver.hh +++ b/dune/solvers/solvers/iterativesolver.hh @@ -59,6 +59,9 @@ namespace Dune { /** \brief Write the current iterate to disk (for convergence measurements) */ void writeIterate(const VectorType& iterate, int iterationNumber) const; + //! The iteration step used by the algorithm + IterationStep<VectorType, BitVectorType>* iterationStep_; + /** \brief The requested tolerance of the solver */ double tolerance_; diff --git a/dune/solvers/solvers/loopsolver.cc b/dune/solvers/solvers/loopsolver.cc index 4f076874..24856187 100644 --- a/dune/solvers/solvers/loopsolver.cc +++ b/dune/solvers/solvers/loopsolver.cc @@ -7,18 +7,6 @@ #include <iomanip> #include <dune/solvers/solvers/solver.hh> -template <class VectorType, class BitVectorType> -void Dune::Solvers::LoopSolver<VectorType, BitVectorType>::check() const -{ - if (!iterationStep_) - DUNE_THROW(SolverError, "You need to supply an iteration step to an iterative solver!"); - - iterationStep_->check(); - - // check base class - IterativeSolver<VectorType,BitVectorType>::check(); -} - template <class VectorType, class BitVectorType> void Dune::Solvers::LoopSolver<VectorType, BitVectorType>::preprocess() { @@ -93,14 +81,14 @@ void Dune::Solvers::LoopSolver<VectorType, BitVectorType>::solve() iter_ = i; // Backup of the current solution for the error computation later on - VectorType oldSolution = iterationStep_->getSol(); + VectorType oldSolution = this->iterationStep_->getSol(); // Perform one iteration step - iterationStep_->iterate(); + this->iterationStep_->iterate(); // write iteration to file, if requested if (this->historyBuffer_!="") - this->writeIterate(iterationStep_->getSol(), i); + this->writeIterate(this->iterationStep_->getSol(), i); // Compute error real_type oldNorm = this->errorNorm_->operator()(oldSolution); @@ -109,7 +97,7 @@ void Dune::Solvers::LoopSolver<VectorType, BitVectorType>::solve() // Please don't replace this call to 'diff' by computing the norm of the difference. // In some nonlinear DD applications the 'diff' method may be nonlinear. - real_type normOfCorrection = this->errorNorm_->diff(oldSolution,iterationStep_->getSol()); + real_type normOfCorrection = this->errorNorm_->diff(oldSolution,this->iterationStep_->getSol()); real_type convRate = (normOfOldCorrection > 0) ? normOfCorrection / normOfOldCorrection : 0.0; error = normOfCorrection; @@ -118,7 +106,7 @@ void Dune::Solvers::LoopSolver<VectorType, BitVectorType>::solve() // If a reference solution has been provided compute the error with respect to it if (referenceSolution_) { - normOfError = this->errorNorm_->diff(iterationStep_->getSol(), *referenceSolution_); + normOfError = this->errorNorm_->diff(this->iterationStep_->getSol(), *referenceSolution_); convRate = (normOfOldError > 0) ? normOfError / normOfOldError : 0.0; error = normOfError; normOfOldError = normOfError; diff --git a/dune/solvers/solvers/loopsolver.hh b/dune/solvers/solvers/loopsolver.hh index 41e784ef..bb9c11c8 100644 --- a/dune/solvers/solvers/loopsolver.hh +++ b/dune/solvers/solvers/loopsolver.hh @@ -42,14 +42,10 @@ public: errorNorm, verbosity, useRelativeError), - iterationStep_(iterationStep), referenceSolution_(referenceSolution) - {} - - /** \brief Checks whether all relevant member variables are set - * \exception SolverError if the iteration step is not set up properly - */ - virtual void check() const; + { + this->iterationStep_ = iterationStep; + } /** * \brief Add a convergence criterion @@ -95,9 +91,6 @@ public: */ virtual void solve(); - //! The iteration step used by the algorithm - IterationStep<VectorType, BitVectorType>* iterationStep_; - const VectorType* referenceSolution_; protected: std::vector<Dune::Solvers::Criterion> criteria_; -- GitLab