IterativeRunner.hpp 2.1 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

namespace AMDiS
{
12
  template <class IterativeSolver, class Traits>
13
  class IterativeRunner
14
      : public RunnerInterface<Traits>
15
16
17
  {
    using SolverCfg = SolverConfig<IterativeSolver>;
    using PreconCfg = PreconConfig<typename IterativeSolver::Preconditioner>;
18
19
20
21
    using Mat = typename Traits::Mat;
    using Sol = typename Traits::Sol;
    using Rhs = typename Traits::Rhs;
    using Comm = typename Traits::Comm;
22
23

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


33
34
    /// Implements \ref RunnerInterface::init()
    void init(Mat const& A, Comm& comm) override
35
    {
36
37
      DUNE_UNUSED_PARAMETER(comm);

38
39
40
41
42
      if (!reusePattern_ || !initialized_) {
        solver_.analyzePattern(A);
        initialized_ = true;
      }
      solver_.factorize(A);
Praetorius, Simon's avatar
Praetorius, Simon committed
43
44
45

      test_exit(solver_.info() == Eigen::Success,
        "Error in solver.compute(matrix)");
46
47
    }

48
    /// Implements \ref RunnerInterface::exit()
49
    void exit() override {}
50

51
52
    /// Implements \ref RunnerInterface::solve()
    int solve(Mat const& A, Sol& x, Rhs const& b, SolverInfo& solverInfo) override
53
    {
54
55
      DUNE_UNUSED_PARAMETER(A);

Praetorius, Simon's avatar
Praetorius, Simon committed
56
      solver_.setTolerance(solverInfo.relTolerance());
57
58
      x = solver_.solveWithGuess(b, x);

59
      auto r = Rhs(b);
60
61
62
63
64
65
66
67
68
69
70
71
72
      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_;
73
74
    bool reusePattern_ = false;
    bool initialized_ = false;
75
76
77
  };

} // end namespace AMDiS