KrylovRunner.hpp 3.84 KB
Newer Older
1
2
#pragma once

3
4
#include <string>

5
6
7
8
9
// MTL4 headers
#include <boost/numeric/itl/itl.hpp>
#include <boost/numeric/mtl/mtl.hpp>

// AMDiS headers
10
11
12
#include <amdis/linearalgebra/PreconditionerInterface.hpp>
#include <amdis/linearalgebra/RunnerInterface.hpp>
#include <amdis/linearalgebra/SolverInfo.hpp>
13

14
#include <amdis/linearalgebra/mtl/ITL_Preconditioner.hpp>
15
16
17
18
19
20
21

namespace AMDiS
{
  /** \ingroup Solver
   *
   * \brief
   * Wrapper class for different MTL4 itl-solvers. These solvers
22
   * are parametrized by Matrix and Vector.
23
24
   **/
  template <class ITLSolver, class Matrix, class Vector>
25
26
  class KrylovRunner
      : public RunnerInterface<Matrix, Vector>
27
  {
28
29
    using Super = RunnerInterface<Matrix, Vector>;
    using PreconBase = typename Super::PreconBase;
30

31
32
  public:
    /// Constructor.
Praetorius, Simon's avatar
Praetorius, Simon committed
33
    explicit KrylovRunner(std::string const& prefix)
34
      : itlSolver_(prefix)
35
36
    {
      initPrecon(prefix);
37

38
39
      Parameters::get(prefix + "->max iteration", maxIter_);
      Parameters::get(prefix + "->print cycle", printCycle_);
40
41
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
42
    /// Implements \ref RunnerInterface::lLeftPrecon(), Returns \ref L_
43
    std::shared_ptr<PreconBase> leftPrecon() override
44
    {
45
      return L_;
46
47
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
48
    /// Implements \ref RunnerInterface::rightPrecon(), Returns \ref R_
49
    std::shared_ptr<PreconBase> rightPrecon() override
50
    {
51
      return R_;
52
    }
53

54
    /// Set a new left preconditioner \ref L_
55
    void setLeftPrecon(std::shared_ptr<PreconBase> const& precon)
56
    {
57
      L_ = precon;
58
    }
59

60
    /// Set a new right preconditioner \ref R_
61
    void setRightPrecon(std::shared_ptr<PreconBase> const& precon)
62
    {
63
      R_ = precon;
64
    }
65
66

    /// Implementation of \ref RunnerInterface::init()
67
    void init(Matrix const& A) override
68
    {
69
70
      L_->init(A);
      R_->init(A);
71
    }
72

73
    /// Implementation of \ref RunnerInterface::exit()
74
    void exit() override
75
    {
76
77
      L_->exit();
      R_->exit();
78
79
80
    }

    /// Implementation of \ref RunnerInterface::solve()
81
82
    int solve(Matrix const& A, Vector& x, Vector const& b,
              SolverInfo& solverInfo) override
83
    {
84
85
      test_exit(bool(L_), "There is no left preconditioner");
      test_exit(bool(R_), "There is no right preconditioner");
86

87
      auto r = Vector(b);
88
89
      if (two_norm(x) != 0)
        r -= A * x;
90

91
      // print information about the solution process
Praetorius, Simon's avatar
Praetorius, Simon committed
92
93
      itl::cyclic_iteration<double> iter(r, maxIter_, solverInfo.relTolerance(),
                                                      solverInfo.absTolerance(),
94
                                                      printCycle_);
Praetorius, Simon's avatar
Praetorius, Simon committed
95
96
      iter.set_quite(solverInfo.info() == 0);
      iter.suppress_resume(solverInfo.info() == 0);
97

98
      int error = itlSolver_(A, x, b, *L_, *R_, iter);
99
100
      solverInfo.setAbsResidual(iter.resid());
      solverInfo.setRelResidual(iter.relresid());
101
102
103
104

      return error;
    }

105
  private:
106
    /// Create left/right preconditioners from parameters given in the init-file
Praetorius, Simon's avatar
Praetorius, Simon committed
107
    void initPrecon(std::string const& prefix)
108
    {
109
      // Creator for the left preconditioner
Praetorius, Simon's avatar
Praetorius, Simon committed
110
111
112
      std::string leftPreconName = "", rightPreconName = "";
      Parameters::get(prefix + "->left precon", leftPreconName);
      Parameters::get(prefix + "->right precon", rightPreconName);
113

114
      auto leftCreator
Praetorius, Simon's avatar
Praetorius, Simon committed
115
        = CreatorMap<PreconBase>::getCreator(leftPreconName, prefix + "->left precon");
116
      auto rightCreator
Praetorius, Simon's avatar
Praetorius, Simon committed
117
        = CreatorMap<PreconBase>::getCreator(rightPreconName, prefix + "->right precon");
118

119
120
      L_ = leftCreator->create();
      R_ = rightCreator->create();
121
122
    }

123
  private:
124
    /// The itl solver object that performes the actual solve
125
    ITLSolver itlSolver_;
126

127
    /// Pointer to the left and right preconditioner
128
    std::shared_ptr<PreconBase> L_, R_;
129

130
    /// The maximal number of iterations
131
    std::size_t maxIter_ = 1000;
132

133
    /// Print solver residuals every \ref printCycle 's iteration
134
    std::size_t printCycle_ = 100;
135
136
137
  };

} // end namespace AMDiS