diff --git a/dune/solvers/solvers/iterativesolver.hh b/dune/solvers/solvers/iterativesolver.hh index edb2d25fb46a4326b933785471b8d53e14631c54..05447ca0ced4e9ffa1cb65ce39b8bb37116183c0 100644 --- a/dune/solvers/solvers/iterativesolver.hh +++ b/dune/solvers/solvers/iterativesolver.hh @@ -6,6 +6,7 @@ #include <dune/common/ftraits.hh> #include <dune/solvers/common/defaultbitvector.hh> +#include <dune/solvers/common/wrapownshare.hh> #include <dune/solvers/solvers/solver.hh> #include <dune/solvers/iterationsteps/iterationstep.hh> #include <dune/solvers/norms/norm.hh> @@ -19,7 +20,9 @@ namespace Dune { class IterativeSolver : public Solver { // For norms and convergence rates - typedef typename Dune::FieldTraits<VectorType>::real_type real_type; + using real_type = typename Dune::FieldTraits<VectorType>::real_type; + using ItStep = IterationStep<VectorType, BitVectorType>; + using ErrorNorm = Norm<VectorType>; public: @@ -30,12 +33,13 @@ namespace Dune { bool useRelativeError=true) : Solver(verbosity), tolerance_(tolerance), - maxIterations_(maxIterations), errorNorm_(NULL), + maxIterations_(maxIterations), errorNorm_(nullptr), historyBuffer_(""), useRelativeError_(useRelativeError) {} /** \brief Constructor taking all relevant data */ + DUNE_DEPRECATED_MSG("Handing over raw pointer in the constructor is deprecated!") IterativeSolver(int maxIterations, double tolerance, const Norm<VectorType>* errorNorm, @@ -43,7 +47,23 @@ namespace Dune { bool useRelativeError=true) : Solver(verbosity), tolerance_(tolerance), - maxIterations_(maxIterations), errorNorm_(errorNorm), + maxIterations_(maxIterations), + errorNorm_(Dune::stackobject_to_shared_ptr(*errorNorm)), + historyBuffer_(""), + useRelativeError_(useRelativeError) + {} + + /** \brief Constructor taking all relevant data */ + template <class NormT, class Enable = std::enable_if_t<not std::is_pointer<NormT>::value> > + IterativeSolver(int maxIterations, + double tolerance, + NormT&& errorNorm, + VerbosityMode verbosity, + bool useRelativeError=true) + : Solver(verbosity), + tolerance_(tolerance), + maxIterations_(maxIterations), + errorNorm_(wrap_own_share<const ErrorNorm>(std::forward<NormT>(errorNorm))), historyBuffer_(""), useRelativeError_(useRelativeError) {} @@ -59,8 +79,37 @@ 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 Set iteration step */ + template <class Step> + void setIterationStep(Step&& iterationStep) + { + iterationStep_ = wrap_own_share<ItStep>(std::forward<Step>(iterationStep)); + } + + /** \brief Get iteration step */ + const ItStep& getIterationStep() const + { + return *iterationStep_; + } + + /** \brief Get iteration step */ + ItStep& getIterationStep() + { + return *iterationStep_; + } + + /** \brief Set the error norm */ + template <class NormT> + void setErrorNorm(NormT&& errorNorm) + { + errorNorm_ = wrap_own_share<ErrorNorm>(std::forward<NormT>(errorNorm)); + } + + /** \brief Get error norm */ + const ItStep& getErrorNorm() const + { + return *errorNorm_; + } /** \brief The requested tolerance of the solver */ double tolerance_; @@ -68,9 +117,14 @@ namespace Dune { //! The maximum number of iterations int maxIterations_; + protected: + //! The iteration step used by the algorithm + std::shared_ptr<IterationStep<VectorType, BitVectorType> > iterationStep_; + //! The norm used to measure convergence - const Norm<VectorType>* errorNorm_; + std::shared_ptr<const Norm<VectorType> > errorNorm_; + public: /** \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_;