LinearSolver.hpp 2.34 KB
Newer Older
1
#pragma once
2

3
4
#include <string>

5
6
#include <dune/common/timer.hh>

7
// AMDiS includes
8
9
10
11
#include <amdis/CreatorInterface.hpp>
#include <amdis/Output.hpp>
#include <amdis/linear_algebra/LinearSolverInterface.hpp>
#include <amdis/linear_algebra/mtl/BlockMTLVector.hpp>
12

13
14
namespace AMDiS
{
15
16
17
18
19
20
21
22
23
24
  /** \ingroup Solver
   *
   * \brief
   * Wrapper class for various MTL4 solvers. These solvers
   * are parametrized by MatrixType and VectorType. The different
   * algorithms, like krylov subspace methods or other external
   * solvers where MTL4 provides an interface, can be assigned
   * by different Runner objects.
   **/
  template <class Matrix, class Vector, class Runner>
25
  class LinearSolver
26
      : public LinearSolverInterface<Matrix, Vector, Vector>
27
  {
28
    using Self = LinearSolver;
29
30
    using Super = LinearSolverInterface<Matrix, Vector, Vector>;
    using RunnerBase = typename Super::RunnerBase;
31

32
33
34
35
  public:
    /// A creator to be used instead of the constructor.
    struct Creator : CreatorInterfaceName<Super>
    {
36
      virtual std::shared_ptr<Super> create(std::string prefix) override
37
      {
38
        return std::make_shared<Self>(prefix);
39
40
      }
    };
41

42
  public:
43
    /// Constructor
44
    explicit LinearSolver(std::string prefix)
45
      : runner(std::make_shared<Runner>(prefix))
46
    {}
47

48
    /// Implements \ref LinearSolverInterface::getRunner()
49
    virtual std::shared_ptr<RunnerBase> getRunner() override
50
51
52
    {
      return runner;
    }
53
54
55
56

  private:
    /// Implements \ref LinearSolverInterface::solveSystemImpl()
    virtual void solveImpl(Matrix const& A, Vector& x, Vector const& b,
57
                           SolverInfo& solverInfo) override
58
    {
59
      Dune::Timer t;
60
      if (solverInfo.doCreateMatrixData()) {
61
        // init matrix or wrap block-matrix or ...
62
        runner->init(A);
63
      }
64

65
66
67
      // wrappers copy the data back on destruction
      auto X = blockWrapper(x);
      auto B = blockWrapper(b);
68

69
      if (solverInfo.getInfo() > 0) {
70
        msg("fill MTL4 matrix needed ", t.elapsed(), " seconds");
71
      }
72

73
74
      int error = runner->solve(A, X.getVector(), B.getVector(), solverInfo);
      solverInfo.setError(error);
75

76
77
      if (!solverInfo.doStoreMatrixData())
        runner->exit();
78
    }
79

80
  private:
81
    /// redirect the implementation to a runner. Implements a \ref RunnerInterface
82
    std::shared_ptr<Runner> runner;
83
84
85
  };

} // end namespace AMDiS