Assembler.h 8.06 KB
Newer Older
1 2 3 4
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
5
// ==  http://www.amdis-fem.org                                              ==
6 7
// ==                                                                        ==
// ============================================================================
8 9 10 11 12 13 14 15 16 17 18 19
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.


20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

/** \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"
36 37 38 39
#include "ZeroOrderAssembler.h"
#include "FirstOrderAssembler.h"
#include "SecondOrderAssembler.h"
#include "ElInfo.h"
40
#include "OpenMP.h"
41
#include "AMDiS_fwd.h"
42 43 44 45 46 47 48 49 50 51 52 53 54 55

namespace AMDiS {

  /**
   * \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:
Thomas Witkowski's avatar
Thomas Witkowski committed
56
    /// Constructor
57
    Assembler(Operator *op,
58 59
	      const FiniteElemSpace *rowFeSpace,
	      const FiniteElemSpace *colFeSpace = NULL);
60

Thomas Witkowski's avatar
Thomas Witkowski committed
61 62
    /// Destructor
    ~Assembler();
63

Thomas Witkowski's avatar
Thomas Witkowski committed
64
    /// Assembles the element matrix for the given ElInfo
65
    void calculateElementMatrix(const ElInfo *elInfo, 
66
				ElementMatrix& userMat, 
67 68 69 70
				double factor = 1.0);

    void calculateElementMatrix(const ElInfo *rowElInfo,
				const ElInfo *colElInfo,
71 72
				const ElInfo *smallElInfo,
				const ElInfo *largeElInfo,
73
				bool rowColFeSpaceEqual,
74
				ElementMatrix& userMat,
75
				double factor = 1.0);
76

Thomas Witkowski's avatar
Thomas Witkowski committed
77
    /// Assembles the element vector for the given ElInfo
78
    void calculateElementVector(const ElInfo *elInfo, 
79
				ElementVector& userVec, 
80
				double factor = 1.0);
81

Thomas Witkowski's avatar
Thomas Witkowski committed
82 83 84 85 86

    void calculateElementVector(const ElInfo *mainElInfo, 
				const ElInfo *auxElInfo,
				const ElInfo *smallElInfo,
				const ElInfo *largeElInfo,
87
				ElementVector& userVec, 
Thomas Witkowski's avatar
Thomas Witkowski committed
88 89
				double factor = 1.0);

90 91
    /// Returns \ref rowFeSpace.
    inline const FiniteElemSpace* getRowFeSpace() 
92
    { 
93
      return rowFeSpace; 
94
    }
95

96 97
    /// Returns \ref colFeSpace.
    inline const FiniteElemSpace* getColFeSpace() 
98
    { 
99
      return colFeSpace; 
100
    }
101

Thomas Witkowski's avatar
Thomas Witkowski committed
102
    /// Returns \ref nRow.
103 104
    inline int getNRow() 
    { 
105
      return nRow; 
106
    }
107

Thomas Witkowski's avatar
Thomas Witkowski committed
108
    /// Returns \ref nCol.
109 110
    inline int getNCol() 
    { 
111
      return nCol; 
112
    }
113

Thomas Witkowski's avatar
Thomas Witkowski committed
114
    /// Sets \ref rememberElMat.
115 116
    inline void rememberElementMatrix(bool rem) 
    { 
117
      rememberElMat = rem; 
118
    }
119

Thomas Witkowski's avatar
Thomas Witkowski committed
120
    /// Sets \ref rememberElVec.
121 122
    inline void rememberElementVector(bool rem) 
    { 
123
      rememberElVec = rem; 
124
    }
125

Thomas Witkowski's avatar
Thomas Witkowski committed
126
    /// Returns \ref zeroOrderAssembler.
127 128
    inline ZeroOrderAssembler* getZeroOrderAssembler() 
    {
129
      return zeroOrderAssembler;
130
    }
131 132 133 134 135

    /** \brief
     * Returns \ref firstOrderAssemblerGrdPsi or \ref firstOrderAssemblerGrdPhi
     * depending on type.
     */
136
    inline FirstOrderAssembler* getFirstOrderAssembler(FirstOrderType type = GRD_PSI) 
137
    {
138
      return (type == GRD_PSI) ? 
139 140
	firstOrderAssemblerGrdPsi : 
	firstOrderAssemblerGrdPhi;
141
    }
142

Thomas Witkowski's avatar
Thomas Witkowski committed
143
    /// Returns \ref secondOrderAssembler.
144 145
    inline SecondOrderAssembler* getSecondOrderAssembler() 
    {
146
      return secondOrderAssembler;
147
    }
148

Thomas Witkowski's avatar
Thomas Witkowski committed
149
    /// Returns \ref operat;
150 151
    inline Operator* getOperator() 
    { 
152
      return operat; 
153
    }
154

Thomas Witkowski's avatar
Thomas Witkowski committed
155
    /// Initialisation for the given ElInfo. The call is deligated to the sub assemblers.
Thomas Witkowski's avatar
Thomas Witkowski committed
156 157
    void initElement(const ElInfo *smallElInfo,
		     const ElInfo *largeElInfo = NULL,
158 159
		     Quadrature *quad = NULL);

Thomas Witkowski's avatar
Thomas Witkowski committed
160
    /// Sets quadratures of all sub assemblers.
161 162 163 164 165
    void setQuadratures(Quadrature *quad2,
			Quadrature *quad1GrdPsi,
			Quadrature *quad1GrdPhi,
			Quadrature *quad0) 
    {
166
      if (secondOrderAssembler) {
167 168 169 170
	TEST_EXIT(!secondOrderAssembler->getQuadrature())
	  ("quadrature already existing\n");
	secondOrderAssembler->setQuadrature(quad2);
      }
171
      if (firstOrderAssemblerGrdPsi) {
172 173 174 175
	TEST_EXIT(!firstOrderAssemblerGrdPsi->getQuadrature())
	  ("quadrature already existing\n");
	firstOrderAssemblerGrdPsi->setQuadrature(quad1GrdPsi);
      }
176
      if (firstOrderAssemblerGrdPhi) {
177 178 179 180
	TEST_EXIT(!firstOrderAssemblerGrdPhi->getQuadrature())
	  ("quadrature already existing\n");
	firstOrderAssemblerGrdPhi->setQuadrature(quad1GrdPhi);
      }
181
      if (zeroOrderAssembler) {
182 183 184 185
	TEST_EXIT(!zeroOrderAssembler->getQuadrature())
	  ("quadrature already existing\n");
	zeroOrderAssembler->setQuadrature(quad0);
      }
Thomas Witkowski's avatar
Thomas Witkowski committed
186 187 188 189
    }

    /// That function must be called after one assembling cycle has been finished.
    void finishAssembling();
190 191 192 193 194 195

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

Thomas Witkowski's avatar
Thomas Witkowski committed
198

Thomas Witkowski's avatar
Thomas Witkowski committed
199
    ///
Thomas Witkowski's avatar
Thomas Witkowski committed
200 201
    void matVecAssemble(const ElInfo *mainElInfo, const ElInfo *auxElInfo,
			const ElInfo *smallElInfo, const ElInfo *largeElInfo,
202
			ElementVector& vec);
Thomas Witkowski's avatar
Thomas Witkowski committed
203

204
    /** \brief
Thomas Witkowski's avatar
Thomas Witkowski committed
205
     * Checks whether quadratures for subassemblers are already set.
206 207 208 209 210
     * If not they will be created.
     */
    void checkQuadratures();

  protected:
Thomas Witkowski's avatar
Thomas Witkowski committed
211
    /// Operator this Assembler belongs to.
212 213
    Operator *operat;

Thomas Witkowski's avatar
Thomas Witkowski committed
214
    /// Row FiniteElemSpace.
215
    const FiniteElemSpace *rowFeSpace;
216

Thomas Witkowski's avatar
Thomas Witkowski committed
217
    /// Column FiniteElemSpace.
218
    const FiniteElemSpace *colFeSpace;
219

Thomas Witkowski's avatar
Thomas Witkowski committed
220
    /// Number of rows.
221 222
    int nRow;

Thomas Witkowski's avatar
Thomas Witkowski committed
223
    /// Number of columns.
224 225
    int nCol;

Thomas Witkowski's avatar
Thomas Witkowski committed
226
    /// SubAssembler for the second order terms
227 228
    SecondOrderAssembler *secondOrderAssembler;

Thomas Witkowski's avatar
Thomas Witkowski committed
229
    /// SubAssembler for the first order terms (grdPsi)
Thomas Witkowski's avatar
Thomas Witkowski committed
230
    FirstOrderAssembler *firstOrderAssemblerGrdPsi;
231

Thomas Witkowski's avatar
Thomas Witkowski committed
232
    /// SubAssembler for the first order terms (grdPhi)
Thomas Witkowski's avatar
Thomas Witkowski committed
233
    FirstOrderAssembler *firstOrderAssemblerGrdPhi;  
234

Thomas Witkowski's avatar
Thomas Witkowski committed
235
    /// SubAssembler for the zero order terms
Thomas Witkowski's avatar
Thomas Witkowski committed
236
    ZeroOrderAssembler *zeroOrderAssembler;
237

Thomas Witkowski's avatar
Thomas Witkowski committed
238
    ///
239 240
    bool remember;

Thomas Witkowski's avatar
Thomas Witkowski committed
241
    /// Determines whether the element matrix should be stored locally.
242 243
    bool rememberElMat;

Thomas Witkowski's avatar
Thomas Witkowski committed
244
    /// Determines whether the element vector should be stored locally.
245 246
    bool rememberElVec;

Thomas Witkowski's avatar
Thomas Witkowski committed
247
    /// Locally stored element matrix
248
    ElementMatrix elementMatrix;
249

Thomas Witkowski's avatar
Thomas Witkowski committed
250
    /// Locally stored element vector
251
    ElementVector elementVector;
252 253 254

    ///
    ElementMatrix tmpMat;
255 256 257 258 259 260 261 262 263 264 265 266 267
  
    /** \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;

Thomas Witkowski's avatar
Thomas Witkowski committed
268
    /// Used to check for new traverse.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
    int lastTraverseId;

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

  /**
   * \ingroup Assembler
   *
   * \brief
   * Assembler using non optimized sub assemblers.
   */
  class StandardAssembler : public Assembler
  {
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
286
    /// Constructor
Thomas Witkowski's avatar
Thomas Witkowski committed
287
    StandardAssembler(Operator *op,
288 289 290 291
		      Quadrature *quad2,
		      Quadrature *quad1GrdPsi,
		      Quadrature *quad1GrdPhi,
		      Quadrature *quad0,
292 293
		      const FiniteElemSpace *rowFeSpace,
		      const FiniteElemSpace *colFeSpace = NULL);
294 295 296 297 298 299 300 301 302 303 304
  };

  /**
   * \ingroup Assembler
   *
   * \brief
   * Assembler using optimized sub assemblers.
   */
  class OptimizedAssembler : public Assembler
  {
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
305
    /// Constructor
Thomas Witkowski's avatar
Thomas Witkowski committed
306
    OptimizedAssembler(Operator *op,
307 308 309 310
		       Quadrature *quad2,
		       Quadrature *quad1GrdPsi,
		       Quadrature *quad1GrdPhi,
		       Quadrature *quad0,
311 312
		       const FiniteElemSpace *rowFeSpace,
		       const FiniteElemSpace *colFeSpace = NULL);
313 314 315 316 317
  };

}

#endif // AMDIS_ASSEMBLER_H