IterativeRunner.hpp 1.96 KB
Newer Older
1
2
3
4
#pragma once

#include <dune/istl/preconditioner.hh>

5
6
7
8
#include <amdis/linearalgebra/RunnerInterface.hpp>
#include <amdis/linearalgebra/SolverInfo.hpp>
#include <amdis/linearalgebra/eigen/PreconConfig.hpp>
#include <amdis/linearalgebra/eigen/SolverConfig.hpp>
9
10
11
12
13
14
15
16
17
18
19

namespace AMDiS
{
  template <class IterativeSolver, class Matrix, class VectorX, class VectorB>
  class IterativeRunner
      : public RunnerInterface<Matrix, VectorX, VectorB>
  {
    using SolverCfg = SolverConfig<IterativeSolver>;
    using PreconCfg = PreconConfig<typename IterativeSolver::Preconditioner>;

  public:
Praetorius, Simon's avatar
Praetorius, Simon committed
20
    IterativeRunner(std::string const& prefix)
21
22
23
24
      : solver_{}
    {
      SolverCfg::init(prefix, solver_);
      PreconCfg::init(prefix + "->precon", solver_.preconditioner());
25
      Parameters::get(prefix + "->reuse pattern", reusePattern_);
26
27
28
29
    }


    /// Implementes \ref RunnerInterface::init()
30
    void init(Matrix const& A) override
31
    {
32
33
34
35
36
      if (!reusePattern_ || !initialized_) {
        solver_.analyzePattern(A);
        initialized_ = true;
      }
      solver_.factorize(A);
Praetorius, Simon's avatar
Praetorius, Simon committed
37
38
39

      test_exit(solver_.info() == Eigen::Success,
        "Error in solver.compute(matrix)");
40
41
42
    }

    /// Implementes \ref RunnerInterface::exit()
43
    void exit() override {}
44
45

    /// Implementes \ref RunnerInterface::solve()
46
47
    int solve(Matrix const& A, VectorX& x, VectorB const& b,
              SolverInfo& solverInfo) override
48
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
49
      solver_.setTolerance(solverInfo.relTolerance());
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
      x = solver_.solveWithGuess(b, x);

      auto r = VectorB(b);
      if (x.norm() != 0)
        r -= A * x;

      solverInfo.setAbsResidual(r.norm());
      solverInfo.setRelResidual(solver_.error());
      solverInfo.setError(solver_.info());
      msg("number of iteration: {}", solver_.iterations());

      return solver_.info() == Eigen::Success ? 0 : int(solver_.info());
    }

  private:
    IterativeSolver solver_;
66
67
    bool reusePattern_ = false;
    bool initialized_ = false;
68
69
70
  };

} // end namespace AMDiS