Preconditioner.h 7.41 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  crystal growth group                                                  ==
// ==                                                                        ==
// ==  Stiftung caesar                                                       ==
// ==  Ludwig-Erhard-Allee 2                                                 ==
// ==  53175 Bonn                                                            ==
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  http://www.caesar.de/cg/AMDiS                                         ==
// ==                                                                        ==
// ============================================================================

/** \file Preconditioner.h */

#ifndef AMDIS_PRECONDITIONER_H
#define AMDIS_PRECONDITIONER_H

#include <vector>

#include "DOFVector.h"
#include "MatrixVector.h"
#include "SystemVector.h"
#include <string>

namespace AMDiS {

  // ============================================================================
  // ===== class Preconditioner =================================================
  // ============================================================================

  /**
   * \ingroup Solver
   * 
   * \brief
   * Pure virtual base class for all preconditioners. 
   * A Preconditioner is used by an OEMSolver before solving the linear system to
   * reduce the number of needed iterations.
   */
  template<typename Vector>
  class Preconditioner
  {
  public:
    /** \brief
     * Destructor.
     */
    virtual ~Preconditioner() {};

    /** \brief
     * Initialisation of the preconditioner
     */
    virtual void init() = 0;

    /** \brief
     * Precondition function which should be implemented.
     */
    virtual void precon(Vector *x) = 0;

    /** \brief
     * Frees needed memory.
     */
    virtual void  exit() = 0;
  };

  // ============================================================================
  // ===== class PreconditionerScal =============================================
  // ============================================================================

  /**
   * \ingroup Solver
   * 
   * Base class for DOFVector preconditioners.
   */
  class PreconditionerScal : public Preconditioner<DOFVector<double> >
  {
  public:
    /** \brife
     * Constructor.
     */
    PreconditionerScal(int numSystems = 1, int r = 0) 
      : matrix(numSystems), 
	bound(NULL), 
	row(r)
    {
      TEST_EXIT(r < numSystems)("r must be smaller than numSystems\n");
      matrix.set(NULL);
    };

    /** \brief
     * Sets \ref matrix.
     */
    inline void setMatrix(DOFMatrix **m, int system = 0) { 
      TEST_EXIT(system < matrix.getSize())("invalid system number\n");
      matrix[system] = m; 
    };

    /** \brief
     * Sets \ref bound.
     */
106
107
108
    inline void setBound(DOFVector<BoundaryType> *b) { 
      bound = b; 
    };
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

  protected:
    /** \brief
     * Matrix used for preconditioning.
     */
    Vector<DOFMatrix**> matrix;

    /** \brief
     * Boundary vector
     */
    DOFVector<BoundaryType> *bound;

    /** \brief
     * Row of the component in vector valued problems.
     */
    int row;
  };



  // ============================================================================
  // ===== class PreconditionerScalStd ==========================================
  // ============================================================================

  /**
   * \ingroup Solver
   * 
   * Base class for DOFVector preconditioners.
   */
  class PreconditionerScalStd : public Preconditioner< ::std::vector<double> >
  {
  public:
    /** \brife
     * Constructor.
     */
    PreconditionerScalStd() 
    {};

    /** \brief
     * Sets \ref matrix.
     */
    inline void setMatrix(::std::vector< ::std::vector<MatEntry> > *m) { 
      matrix = m;
    };

  protected:
    /** \brief
     * Matrix used for preconditioning.
     */

    ::std::vector< ::std::vector<MatEntry> > *matrix;
  };


  // ============================================================================
  // ===== PreconditionerScalCreator ============================================
  // ============================================================================

  /** 
   * \ingroup Solver
   *
   * \brief
   * Interface for creators of concrete scalar preconditioners. 
   */
  class PreconditionerScalCreator 
    : public CreatorInterface<PreconditionerScal>
  { 
  public:
    PreconditionerScalCreator() 
      : size(1), row(0)
    {};

    virtual ~PreconditionerScalCreator() {};

    /** \brief
     * Sets \ref problem
     */
    void setSizeAndRow(int size_, int row_) { 
      size = size_;
      row = row_;
    };

    /** \brief
     * Sets \ref problem
     */
    void setName(::std::string name) { 
      name_ = name;
    };

  protected:
    int size;
    int row;

    ::std::string name_;
  };



  // ============================================================================
  // ===== class PreconditionerVec ==============================================
  // ============================================================================

  /**
   * \ingroup Solver
   * 
   * \brief
   * Base class for vector valued preconditioners.
   */
  class PreconditionerVec : public Preconditioner<SystemVector>
  {
  public:
    MEMORY_MANAGED(PreconditionerVec);

    /** \brief
     * Constructor.
     */
    PreconditionerVec(int numSystems)  
      : scalPrecons(numSystems)
    {
      scalPrecons.set(NULL);
    };

    /** \brief
     * Destructor.
     */
    virtual ~PreconditionerVec() {};

    /** \brief
     * Initialisation of the preconditioner
     */
    virtual void init() {
240
241
242
      int i;
      int size = scalPrecons.getSize();

243
#ifdef _OPENMP
244
#pragma omp parallel for num_threads(size)
245
#endif
246
      for (i = 0; i < size; i++) {
247
248
249
250
251
252
253
254
	scalPrecons[i]->init();
      }
    };

    /** \brief
     * Preconditioning method
     */
    virtual void precon(SystemVector *x) {
255
256
      int i;
      int size = scalPrecons.getSize();
257
#ifdef _OPENMP
258
#pragma omp parallel for num_threads(size)
259
#endif
260
      for (i = 0; i < size; i++) {
261
262
263
264
265
266
267
268
	scalPrecons[i]->precon(x->getDOFVector(i));
      }
    };

    /** \brief
     * Frees needed memory.
     */
    virtual void  exit() {
269
      int size = scalPrecons.getSize();
270
      for (int i = 0; i < size; i++) {
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
	scalPrecons[i]->exit();
      }
    };

    /** \brief
     * Sets scalar preconditioner for system i.
     */
    inline void setScalarPrecon(int i, PreconditionerScal *p) {
      scalPrecons[i] = p;
    };

    /** \brief
     * Gets i-th scalar preconditioner.
     */
    inline PreconditionerScal *getScalarPrecon(int i) {
      return scalPrecons[i];
    };

  protected:
    /** \brief
     * Scalar Preconditioners.
     */
    Vector<PreconditionerScal*> scalPrecons;
  };

}

#endif  // AMDIS_PRECONDITIONER_H