DirectRunner.hpp 1.89 KB
Newer Older
1
2
3
4
5
#pragma once

#include <algorithm>
#include <string>

6
7
8
#include <amdis/linearalgebra/RunnerInterface.hpp>
#include <amdis/linearalgebra/SolverInfo.hpp>
#include <amdis/linearalgebra/eigen/SolverConfig.hpp>
9
10
11
12

namespace AMDiS
{
  /**
13
14
15
16
  * \ingroup Solver
  * \class AMDiS::DirectRunner
  * \brief \implements RunnerInterface for the (external) direct solvers
  */
17
  template <template <class> class Solver, class Traits>
18
  class DirectRunner
19
      : public RunnerInterface<Traits>
20
21
  {
  protected:
22
23
24
25
26
27
    using Super = RunnerInterface<Traits>;
    using Mat = typename Traits::Mat;
    using Sol = typename Traits::Sol;
    using Rhs = typename Traits::Rhs;
    using Comm = typename Traits::Comm;
    using EigenSolver = Solver<Mat>;
28
29
30

  public:
    /// Constructor.
Praetorius, Simon's avatar
Praetorius, Simon committed
31
    DirectRunner(std::string const& prefix)
32
33
      : solver_{}
    {
34
      SolverConfig<Solver>::init(prefix, solver_);
35
      Parameters::get(prefix + "->reuse pattern", reusePattern_);
36
37
    }

38
39
    /// Implements \ref RunnerInterface::init()
    void init(Mat const& A, Comm& comm) override
40
    {
41
42
      DUNE_UNUSED_PARAMETER(comm);

43
44
45
46
47
      if (!reusePattern_ || !initialized_) {
        solver_.analyzePattern(A);
        initialized_ = true;
      }
      solver_.factorize(A);
Praetorius, Simon's avatar
Praetorius, Simon committed
48
49
50

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

Praetorius, Simon's avatar
Praetorius, Simon committed
53

54
    /// Implements \ref RunnerInterface::exit()
55
    void exit() override {}
56

57
58
    /// Implements \ref RunnerInterface::solve()
    int solve(Mat const& A, Sol& x, Rhs const& b, SolverInfo& solverInfo) override
59
    {
60
61
      DUNE_UNUSED_PARAMETER(A);

62
63
      x = solver_.solve(b);

64
      auto r = Rhs(b);
65
66
67
68
69
70
71
72
73
74
      if (x.norm() != 0)
        r -= A * x;

      solverInfo.setAbsResidual(r.norm());
      solverInfo.setError(solver_.info());

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

  private:
75
    EigenSolver solver_;
76
77
    bool reusePattern_ = false;
    bool initialized_ = false;
78
79
  };
}