diff --git a/dune-solvers/solvers/iterativesolver.cc b/dune-solvers/solvers/iterativesolver.cc new file mode 100644 index 0000000000000000000000000000000000000000..d7ba9e16856309ca05a31ad4981d443b696c0e56 --- /dev/null +++ b/dune-solvers/solvers/iterativesolver.cc @@ -0,0 +1,31 @@ +#include <cmath> +#include <limits> +#include <iostream> +#include <iomanip> +#include <fstream> + +#include "dune/ag-common/genericvectortools.hh" + +template <class VectorType, class BitVectorType> +void IterativeSolver<VectorType, BitVectorType>::check() const +{ + if (!errorNorm_) + DUNE_THROW(SolverError, "You need to supply a norm-computing routine to an iterative solver!"); +} + +template <class VectorType, class BitVectorType> +void IterativeSolver<VectorType, BitVectorType>::writeIterate(const VectorType& iterate, + int iterationNumber) const +{ + std::stringstream iSolFilename; + iSolFilename << historyBuffer_ << "/intermediatesolution_" + << std::setw(4) << std::setfill('0') << iterationNumber; + + std::ofstream file(iSolFilename.str().c_str(), std::ios::out|std::ios::binary); + if (not(file)) + DUNE_THROW(SolverError, "Couldn't open file " << iSolFilename.str() << " for writing"); + + GenericVector::writeBinary(file, iterate); + + file.close(); +} diff --git a/dune-solvers/solvers/iterativesolver.hh b/dune-solvers/solvers/iterativesolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..6c29545305cb8e3516b447e92d15b69517d33bfa --- /dev/null +++ b/dune-solvers/solvers/iterativesolver.hh @@ -0,0 +1,75 @@ +#ifndef ITERATIVE_SOLVER_HH +#define ITERATIVE_SOLVER_HH + +#include "solver.hh" +#include "iterationstep.hh" +#include "norms/norm.hh" + + /** \brief A generic iterative solver + * + * This class basically implements a loop that calls + * an iteration procedure (which is to be supplied be + * the user). It also monitors convergence. */ + template <class VectorType, class BitVectorType = Dune::BitSetVector<VectorType::block_type::dimension> > + class IterativeSolver : public Solver + { + public: + + /** \brief Constructor taking all relevant data */ + IterativeSolver(double tolerance, + int maxIterations, + VerbosityMode verbosity, + bool useRelativeError=true) + : Solver(verbosity), + tolerance_(tolerance), + maxIterations_(maxIterations), errorNorm_(NULL), + historyBuffer_(""), + useRelativeError_(useRelativeError) + {} + + /** \brief Constructor taking all relevant data */ + IterativeSolver(int maxIterations, + double tolerance, + Norm<VectorType>* errorNorm, + VerbosityMode verbosity, + bool useRelativeError=true) + : Solver(verbosity), + tolerance_(tolerance), + maxIterations_(maxIterations), errorNorm_(errorNorm), + historyBuffer_(""), + useRelativeError_(useRelativeError) + {} + + /** \brief Loop, call the iteration procedure + * and monitor convergence */ + virtual void solve() = 0; + + /** \brief Checks whether all relevant member variables are set + */ + virtual void check() const; + + /** \brief Write the current iterate to disk (for convergence measurements) */ + void writeIterate(const VectorType& iterate, int iterationNumber) const; + + /** \brief The requested tolerance of the solver */ + double tolerance_; + + //! The maximum number of iterations + int maxIterations_; + + //! The norm used to measure convergence + 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. */ + std::string historyBuffer_; + + double maxTotalConvRate_; + + bool useRelativeError_; + + }; + +#include "iterativesolver.cc" + +#endif