Assembler.h 9.79 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
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  crystal growth group                                                  ==
// ==                                                                        ==
// ==  Stiftung caesar                                                       ==
// ==  Ludwig-Erhard-Allee 2                                                 ==
// ==  53175 Bonn                                                            ==
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  http://www.caesar.de/cg/AMDiS                                         ==
// ==                                                                        ==
// ============================================================================

/** \file Assembler.h */

/**
 * \defgroup Assembler Assembler module
 *
 * \brief
 * Contains the operator and assembler classes:
 * @{ <img src="assembler.png"> @}
 */

#ifndef AMDIS_ASSEMBLER_H
#define AMDIS_ASSEMBLER_H

#include <vector>
#include "FixVec.h"
#include "MemoryManager.h"
36
37
38
39
#include "ZeroOrderAssembler.h"
#include "FirstOrderAssembler.h"
#include "SecondOrderAssembler.h"
#include "ElInfo.h"
40
41
42

namespace AMDiS {

43
  //  class ElInfo;
44
45
46
47
  class Element;
  class Quadrature;
  class ElementMatrix;
  class ElementVector;
48
  class Operator;
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

  /**
   * \ingroup Assembler
   * 
   * \brief
   * Assembles element matrices and vectors for a given Operator. Uses
   * one SubAssembler for all second order terms of the Operator, one for all
   * first order terms, and one for all zero order terms.
   */
  class Assembler
  {
  public:
    MEMORY_MANAGED(Assembler);

    /** \brief
     * Constructor.
     */
66
67
68
    Assembler(Operator *op,
	      const FiniteElemSpace *rowFESpace,
	      const FiniteElemSpace *colFESpace = NULL);
69
70
71
72

    virtual ~Assembler() {};

    ElementMatrix *initElementMatrix(ElementMatrix *elMat, 
73
74
				     const ElInfo *rowElInfo,
				     const ElInfo *colElInfo = NULL);
75
76
77
78
79
80
81
82


    ElementVector *initElementVector(ElementVector *elVec,
				     const ElInfo *elInfo);

    /** \brief
     * Assembles the element matrix for the given ElInfo
     */
83
84
85
86
87
88
89
90
    void calculateElementMatrix(const ElInfo *elInfo, 
				ElementMatrix *userMat, 
				double factor = 1.0);

    void calculateElementMatrix(const ElInfo *rowElInfo,
				const ElInfo *colElInfo,
				ElementMatrix *userMat,
				double factor = 1.0);
91
92
93
94

    /** \brief
     * Assembles the element vector for the given ElInfo
     */
95
96
97
    void calculateElementVector(const ElInfo *elInfo, 
				ElementVector *userVec, 
				double factor = 1.0);
98
99
100
101

    /** \brief
     * Returns \ref rowFESpace.
     */
102
103
104
    inline const FiniteElemSpace* getRowFESpace() { 
      return rowFESpace; 
    };
105
106
107
108

    /** \brief
     * Returns \ref colFESpace.
     */
109
110
111
    inline const FiniteElemSpace* getColFESpace() { 
      return colFESpace; 
    };
112
113
114
115

    /** \brief
     * Returns \ref nRow.
     */
116
117
118
    inline int getNRow() { 
      return nRow; 
    };
119
120
121
122

    /** \brief
     * Returns \ref nCol.
     */
123
124
125
    inline int getNCol() { 
      return nCol; 
    };
126
127
128
129

    /** \brief
     * Sets \ref rememberElMat.
     */
130
131
132
    inline void rememberElementMatrix(bool rem) { 
      rememberElMat = rem; 
    };
133
134
135
136

    /** \brief
     * Sets \ref rememberElVec.
     */
137
138
139
    inline void rememberElementVector(bool rem) { 
      rememberElVec = rem; 
    };
140
141
142
143
144
145
146
147
148
149
150
151

    /** \brief
     * Returns \ref zeroOrderAssembler.
     */
    inline ZeroOrderAssembler* getZeroOrderAssembler() {
      return zeroOrderAssembler;
    };

    /** \brief
     * Returns \ref firstOrderAssemblerGrdPsi or \ref firstOrderAssemblerGrdPhi
     * depending on type.
     */
152
    inline FirstOrderAssembler* getFirstOrderAssembler(FirstOrderType type = GRD_PSI) 
153
    {
154
      return (type == GRD_PSI) ? 
155
156
157
158
159
160
161
162
163
164
165
166
167
168
	firstOrderAssemblerGrdPsi : 
	firstOrderAssemblerGrdPhi;
    };

    /** \brief
     * Returns \ref secondOrderAssembler.
     */
    inline SecondOrderAssembler* getSecondOrderAssembler() {
      return secondOrderAssembler;
    };

    /** \brief
     * Returns \ref operat;
     */
169
170
171
    inline Operator* getOperator() { 
      return operat; 
    };
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

    /** \brief
     * Initialisation for the given ElInfo. The call is deligated to
     * the sub assemblers.
     */
    void initElement(const ElInfo *elInfo,
		     Quadrature *quad = NULL);

    /** \brief
     * Sets quadratures of all sub assemblers.
     */
    void setQuadratures(Quadrature *quad2,
			Quadrature *quad1GrdPsi,
			Quadrature *quad1GrdPhi,
			Quadrature *quad0) 
    {
188
      if (secondOrderAssembler) {
189
190
191
192
	TEST_EXIT(!secondOrderAssembler->getQuadrature())
	  ("quadrature already existing\n");
	secondOrderAssembler->setQuadrature(quad2);
      }
193
      if (firstOrderAssemblerGrdPsi) {
194
195
196
197
	TEST_EXIT(!firstOrderAssemblerGrdPsi->getQuadrature())
	  ("quadrature already existing\n");
	firstOrderAssemblerGrdPsi->setQuadrature(quad1GrdPsi);
      }
198
      if (firstOrderAssemblerGrdPhi) {
199
200
201
202
	TEST_EXIT(!firstOrderAssemblerGrdPhi->getQuadrature())
	  ("quadrature already existing\n");
	firstOrderAssemblerGrdPhi->setQuadrature(quad1GrdPhi);
      }
203
      if (zeroOrderAssembler) {
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
	TEST_EXIT(!zeroOrderAssembler->getQuadrature())
	  ("quadrature already existing\n");
	zeroOrderAssembler->setQuadrature(quad0);
      }
    };

  protected:
    /** \brief
     * Vector assembling by element matrix-vector multiplication. 
     * Usefull if an element matrix was already calculated.
     */
    void matVecAssemble(const ElInfo *elInfo, ElementVector *vec);

    /** \brief
     * Checks whether this is a new travese.
     */
    inline void checkForNewTraverse() {
221
      if (lastTraverseId != ElInfo::traverseId) {
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
	lastVecEl = lastMatEl = NULL;
	lastTraverseId = ElInfo::traverseId;
      }
    };

    /** \brief
     * Checks whether quadratures for sub assemblers are already set.
     * If not they will be created.
     */
    void checkQuadratures();

  protected:
    /** \brief
     * Operator this Assembler belongs to.
     */
    Operator *operat;

    /** \brief
     * Row FiniteElemSpace.
     */
    const FiniteElemSpace *rowFESpace;

    /** \brief
     * Column FiniteElemSpace.
     */
    const FiniteElemSpace *colFESpace;

    /** \brief
     * Number of rows.
     */
    int nRow;

    /** \brief
     * Number of columns.
     */
    int nCol;

    /** \brief
     * SubAssembler for the second order terms
     */
    SecondOrderAssembler *secondOrderAssembler;

    /** \brief
     * SubAssembler for the first order terms (grdPsi)
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
267
    FirstOrderAssembler *firstOrderAssemblerGrdPsi;
268
269
270
271

    /** \brief
     * SubAssembler for the first order terms (grdPhi)
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
272
    FirstOrderAssembler *firstOrderAssemblerGrdPhi;  
273
274
275
276

    /** \brief
     * SubAssembler for the zero order terms
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
277
    ZeroOrderAssembler *zeroOrderAssembler;
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

    bool remember;

    /** \brief
     * Determines whether the element matrix should be stored locally.
     */
    bool rememberElMat;

    /** \brief
     * Determines whether the element vector should be stored locally.
     */
    bool rememberElVec;

    /** \brief
     * locally stored element matrix
     */
    ElementMatrix* elementMatrix;

    /** \brief
     * locally stored element vector
     */
    ElementVector* elementVector;
  
    /** \brief
     * Used to check whether \ref initElement() must be called, because
     * a new Element is visited.
     */
    Element* lastMatEl;

    /** \brief
     * Used to check whether \ref initElement() must be called, because
     * a new Element is visited.
     */
    Element* lastVecEl;

    /** \brief
     * Used to check for new traverse.
     */
    int lastTraverseId;

    friend class SubAssembler;
    friend class ZeroOrderAssembler;
    friend class FirstOrderAssembler;
    friend class SecondOrderAssembler;
  };

  // ============================================================================
  // ===== class StandardAssembler =============================================
  // ============================================================================

  /**
   * \ingroup Assembler
   *
   * \brief
   * Assembler using non optimized sub assemblers.
   */
  class StandardAssembler : public Assembler
  {
  public:
    MEMORY_MANAGED(StandardAssembler);

    /** \brief
     * Constructor.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
342
    StandardAssembler(Operator *op,
343
344
345
346
		      Quadrature *quad2,
		      Quadrature *quad1GrdPsi,
		      Quadrature *quad1GrdPhi,
		      Quadrature *quad0,
Thomas Witkowski's avatar
Thomas Witkowski committed
347
348
		      const FiniteElemSpace *rowFESpace,
		      const FiniteElemSpace *colFESpace = NULL);
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  };

  // ============================================================================
  // ===== class OptimizedAssembler =============================================
  // ============================================================================

  /**
   * \ingroup Assembler
   *
   * \brief
   * Assembler using optimized sub assemblers.
   */
  class OptimizedAssembler : public Assembler
  {
  public:
    MEMORY_MANAGED(OptimizedAssembler);

    /** \brief
     * Constructor.
     */
Thomas Witkowski's avatar
Thomas Witkowski committed
369
    OptimizedAssembler(Operator *op,
370
371
372
373
		       Quadrature *quad2,
		       Quadrature *quad1GrdPsi,
		       Quadrature *quad1GrdPhi,
		       Quadrature *quad0,
Thomas Witkowski's avatar
Thomas Witkowski committed
374
375
		       const FiniteElemSpace *rowFESpace,
		       const FiniteElemSpace *colFESpace = NULL);
376
377
378
379
380
  };

}

#endif // AMDIS_ASSEMBLER_H