IterativeRunner.hpp 2 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
{
Praetorius, Simon's avatar
Praetorius, Simon committed
12
  template <class Mat, class Vec, class IterativeSolver>
13
  class IterativeRunner
Praetorius, Simon's avatar
Praetorius, Simon committed
14
      : public RunnerInterface<Mat,Vec>
15
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
16
17
18
19
    using M = typename Mat::BaseMatrix;
    using X = typename Vec::BaseVector;
    using Y = typename Vec::BaseVector;

20
21
22
23
    using SolverCfg = SolverConfig<IterativeSolver>;
    using PreconCfg = PreconConfig<typename IterativeSolver::Preconditioner>;

  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
    /// Implements \ref RunnerInterface::init()
Praetorius, Simon's avatar
Praetorius, Simon committed
33
    void init(M const& A) override
34
    {
35
36
37
38
39
      if (!reusePattern_ || !initialized_) {
        solver_.analyzePattern(A);
        initialized_ = true;
      }
      solver_.factorize(A);
Praetorius, Simon's avatar
Praetorius, Simon committed
40
41
42

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

45
    /// Implements \ref RunnerInterface::exit()
46
47
48
49
    void exit() override
    {
      initialized_ = false;
    }
50

51
    /// Implements \ref RunnerInterface::solve()
Praetorius, Simon's avatar
Praetorius, Simon committed
52
    int solve(M const& A, X& x, Y const& b, SolverInfo& solverInfo) override
53
    {
54
55
      DUNE_UNUSED_PARAMETER(A);

56
57
      x = solver_.solveWithGuess(b, x);

Praetorius, Simon's avatar
Praetorius, Simon committed
58
      Y r = b;
59
60
61
62
63
64
65
66
67
68
69
70
71
      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_;
72
73
    bool reusePattern_ = false;
    bool initialized_ = false;
74
75
76
  };

} // end namespace AMDiS