KrylovPreconditioner.h 5.11 KB
Newer Older
1
2
3
4
5
6
7
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
8
 * Authors:
9
10
11
12
13
14
15
16
17
 * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *
 * This file is part of AMDiS
 *
 * See also license.opensource.txt in the distribution.
18
 *
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 ******************************************************************************/


/** \file KrylovPreconditioner.h */

#ifndef AMDIS_KRYLOV_PRECONDITIONER_H
#define AMDIS_KRYLOV_PRECONDITIONER_H

#include "solver/ITL_Preconditioner.h"
#ifdef HAVE_PARALLEL_MTL4
#include "parallel/PITL_Solver.h"
#endif

namespace AMDiS {

  /**
   * \ingroup Solver
36
   *
37
   * \brief Implements an inner solver for (flexible) krylov subspace solvers
38
   *
39
40
41
42
43
44
45
46
   * Any AMDiS solver can be used as preconditioner for any other AMDiS solver.
   * Initfile-syntax:<br />
   * [...]->solver: any-krylov-solver<br />
   * [...]->solver->left precon: [krylov|solver]<br />
   * [...]->solver->left precon->solver: any-amdis-solver<br />
   * [...]->solver->left precon->solver->parameter1: ...<br />
   * [...]->solver->left precon->solver->parameter2: ...<br />
   * [...]->solver->left precon->solver->parameter3: ...
47
   *
48
49
50
51
52
   * This Krylov-Preconditioner can also be used as preconditioner for the inner solver, so
   * that a sequence of iner-inner-solver can be loaded.
   **/

  template< typename MatrixType, typename VectorType >
53
  struct KrylovPreconditioner : ITL_PreconditionerBase< MatrixType, VectorType >
54
  {
55
56
    typedef ITL_PreconditionerBase< MatrixType, VectorType >  precon_base;
    typedef KrylovPreconditioner< MatrixType, VectorType >    self;
57

58
    class Creator : public CreatorInterfaceName<precon_base>
59
60
61
    {
    public:
      virtual ~Creator() {}
62
63

      precon_base* create() {
64
	return new self(this->name);
65
66
      }
    };
67
68
69
70

    KrylovPreconditioner(std::string name)
      : fullMatrix(NULL),
	solver(NULL),
71
	runner(NULL)
72
73
    {

74
#if defined HAVE_PARALLEL_PETSC
75
      std::string backend("p_petsc");
76
#elif defined HAVE_PARALLEL_MTL
77
      std::string backend("p_mtl");
78
#elif defined HAVE_PETSC || defined HAVE_SEQ_PETSC
79
      std::string backend("petsc");
80
#else
81
      std::string backend("mtl");
82
#endif
83

84
      // === read backend-name ===
85
      std::string initFileStr = name + "->solver";
86
87
88
      Parameters::get(initFileStr + "->backend", backend);

      // === read solver-name ===
89
      std::string solverType("0");
90
      Parameters::get(initFileStr, solverType);
91

92
93
      if (backend != "0" && backend != "no" && backend != "")
	solverType = backend + "_" + solverType;
94
95

      LinearSolverCreator *solverCreator =
96
	dynamic_cast<LinearSolverCreator*>(CreatorMap<LinearSolverInterface>::getCreator(solverType, initFileStr));
97
98
99
100
      TEST_EXIT(solverCreator)
	("No valid solver type found in parameter \"%s\"\n", initFileStr.c_str());
      solverCreator->setName(initFileStr);
      solver = solverCreator->create();
101

102
      runner = dynamic_cast<RunnerBase< MatrixType, VectorType >*>(solver->getRunner());
103
    }
104

105
106
107
108
    virtual ~KrylovPreconditioner()
    {
      delete solver;
    }
109

110
    /// Implementation of \ref ITL_PreconditionerBase::init()
111
    virtual void init(const SolverMatrix<Matrix<DOFMatrix*> >& A, const MatrixType& fullMatrix_) override
112
113
114
115
    {
      fullMatrix = &fullMatrix_;
      runner->init(A, fullMatrix_);
    }
116

117
    /// Implementation of \ref PreconditionerInterface::init()
118
    virtual void exit() override
119
120
121
    {
      runner->exit();
    }
122

123
    /// Implementation of \ref ITL_PreconditionerBase::solve()
124
    virtual void solve(const VectorType& b, VectorType& x) const override
125
126
127
128
    {
      initVector(x);
      runner->solve(*fullMatrix, x, b);
    }
129

130
    /// Implementation of \ref ITL_PreconditionerBase::adjoint_solve()
131
    virtual void adjoint_solve(const VectorType& b, VectorType& x) const override
132
133
134
135
    {
      initVector(x);
      runner->adjoint_solve(*fullMatrix, x, b);
    }
136

137
  protected: // methods
138

139
140
141
142
143
144
145
146
147
    template<typename VectorT>
    typename boost::enable_if< mtl::traits::is_distributed<VectorT>, void >::type
    initVector(VectorT& x) const
    {
#ifdef HAVE_PARALLEL_MTL4
      x.init_distribution(col_distribution(*fullMatrix), num_cols(*fullMatrix));
#endif
      set_to_zero(x);
    }
148

149
150
151
152
153
154
155
    template<typename VectorT>
    typename boost::disable_if< mtl::traits::is_distributed<VectorT>, void >::type
    initVector(VectorT& x) const
    {
      x.change_dim(num_cols(*fullMatrix));
      set_to_zero(x);
    }
156

157
158
159
  protected: // member variables

    const MatrixType* fullMatrix;
160

161
162
    LinearSolverInterface* solver;
    RunnerBase< MatrixType, VectorType >* runner;
163
  };
164
165


166
167
168
169
170
#ifdef HAVE_PARALLEL_MTL4
  typedef KrylovPreconditioner<MTLTypes::PMTLMatrix, MTLTypes::PMTLVector> KrylovPreconditionerParallel;
#endif
  typedef KrylovPreconditioner<MTLTypes::MTLMatrix, MTLTypes::MTLVector> KrylovPreconditionerSeq;

171

172
173
174
} // end namespace AMDiS

#endif // AMDIS_KRYLOV_PRECONDITIONER_H