// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == TU Dresden == // == == // == Institut f�r Wissenschaftliches Rechnen == // == Zellescher Weg 12-14 == // == 01069 Dresden == // == germany == // == == // ============================================================================ // == == // == https://gforge.zih.tu-dresden.de/projects/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 "ZeroOrderAssembler.h" #include "FirstOrderAssembler.h" #include "SecondOrderAssembler.h" #include "ElInfo.h" #include "OpenMP.h" #include "AMDiS_fwd.h" 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: /// Constructor Assembler(Operator *op, const FiniteElemSpace *rowFESpace, const FiniteElemSpace *colFESpace = NULL); /// Destructor ~Assembler(); /// Assembles the element matrix for the given ElInfo void calculateElementMatrix(const ElInfo *elInfo, ElementMatrix& userMat, double factor = 1.0); void calculateElementMatrix(const ElInfo *rowElInfo, const ElInfo *colElInfo, const ElInfo *smallElInfo, const ElInfo *largeElInfo, ElementMatrix& userMat, double factor = 1.0); /// Assembles the element vector for the given ElInfo void calculateElementVector(const ElInfo *elInfo, ElementVector& userVec, double factor = 1.0); void calculateElementVector(const ElInfo *mainElInfo, const ElInfo *auxElInfo, const ElInfo *smallElInfo, const ElInfo *largeElInfo, ElementVector& userVec, double factor = 1.0); /// Returns \ref rowFESpace. inline const FiniteElemSpace* getRowFESpace() { return rowFESpace; } /// Returns \ref colFESpace. inline const FiniteElemSpace* getColFESpace() { return colFESpace; } /// Returns \ref nRow. inline int getNRow() { return nRow; } /// Returns \ref nCol. inline int getNCol() { return nCol; } /// Sets \ref rememberElMat. inline void rememberElementMatrix(bool rem) { rememberElMat = rem; } /// Sets \ref rememberElVec. inline void rememberElementVector(bool rem) { rememberElVec = rem; } /// Returns \ref zeroOrderAssembler. inline ZeroOrderAssembler* getZeroOrderAssembler() { return zeroOrderAssembler; } /** \brief * Returns \ref firstOrderAssemblerGrdPsi or \ref firstOrderAssemblerGrdPhi * depending on type. */ inline FirstOrderAssembler* getFirstOrderAssembler(FirstOrderType type = GRD_PSI) { return (type == GRD_PSI) ? firstOrderAssemblerGrdPsi : firstOrderAssemblerGrdPhi; } /// Returns \ref secondOrderAssembler. inline SecondOrderAssembler* getSecondOrderAssembler() { return secondOrderAssembler; } /// Returns \ref operat; inline Operator* getOperator() { return operat; } /// Initialisation for the given ElInfo. The call is deligated to the sub assemblers. void initElement(const ElInfo *smallElInfo, const ElInfo *largeElInfo = NULL, Quadrature *quad = NULL); /// Sets quadratures of all sub assemblers. void setQuadratures(Quadrature *quad2, Quadrature *quad1GrdPsi, Quadrature *quad1GrdPhi, Quadrature *quad0) { if (secondOrderAssembler) { TEST_EXIT(!secondOrderAssembler->getQuadrature()) ("quadrature already existing\n"); secondOrderAssembler->setQuadrature(quad2); } if (firstOrderAssemblerGrdPsi) { TEST_EXIT(!firstOrderAssemblerGrdPsi->getQuadrature()) ("quadrature already existing\n"); firstOrderAssemblerGrdPsi->setQuadrature(quad1GrdPsi); } if (firstOrderAssemblerGrdPhi) { TEST_EXIT(!firstOrderAssemblerGrdPhi->getQuadrature()) ("quadrature already existing\n"); firstOrderAssemblerGrdPhi->setQuadrature(quad1GrdPhi); } if (zeroOrderAssembler) { TEST_EXIT(!zeroOrderAssembler->getQuadrature()) ("quadrature already existing\n"); zeroOrderAssembler->setQuadrature(quad0); } } /// That function must be called after one assembling cycle has been finished. void finishAssembling(); protected: /** \brief * Vector assembling by element matrix-vector multiplication. * Usefull if an element matrix was already calculated. */ void matVecAssemble(const ElInfo *elInfo, ElementVector& vec); /// void matVecAssemble(const ElInfo *mainElInfo, const ElInfo *auxElInfo, const ElInfo *smallElInfo, const ElInfo *largeElInfo, ElementVector& vec); /** \brief * Checks whether quadratures for subassemblers are already set. * If not they will be created. */ void checkQuadratures(); protected: /// Operator this Assembler belongs to. Operator *operat; /// Row FiniteElemSpace. const FiniteElemSpace *rowFESpace; /// Column FiniteElemSpace. const FiniteElemSpace *colFESpace; /// Number of rows. int nRow; /// Number of columns. int nCol; /// SubAssembler for the second order terms SecondOrderAssembler *secondOrderAssembler; /// SubAssembler for the first order terms (grdPsi) FirstOrderAssembler *firstOrderAssemblerGrdPsi; /// SubAssembler for the first order terms (grdPhi) FirstOrderAssembler *firstOrderAssemblerGrdPhi; /// SubAssembler for the zero order terms ZeroOrderAssembler *zeroOrderAssembler; /// bool remember; /// Determines whether the element matrix should be stored locally. bool rememberElMat; /// Determines whether the element vector should be stored locally. bool rememberElVec; /// Locally stored element matrix ElementMatrix elementMatrix; /// 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; /// Used to check for new traverse. 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: /// Constructor StandardAssembler(Operator *op, Quadrature *quad2, Quadrature *quad1GrdPsi, Quadrature *quad1GrdPhi, Quadrature *quad0, const FiniteElemSpace *rowFESpace, const FiniteElemSpace *colFESpace = NULL); }; /** * \ingroup Assembler * * \brief * Assembler using optimized sub assemblers. */ class OptimizedAssembler : public Assembler { public: /// Constructor OptimizedAssembler(Operator *op, Quadrature *quad2, Quadrature *quad1GrdPsi, Quadrature *quad1GrdPhi, Quadrature *quad0, const FiniteElemSpace *rowFESpace, const FiniteElemSpace *colFESpace = NULL); }; } #endif // AMDIS_ASSEMBLER_H