// ============================================================================ // == == // == 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: * @{ @} */ #ifndef AMDIS_ASSEMBLER_H #define AMDIS_ASSEMBLER_H #include #include "FixVec.h" #include "MemoryManager.h" #include "ZeroOrderAssembler.h" #include "FirstOrderAssembler.h" #include "SecondOrderAssembler.h" #include "ElInfo.h" #include "OpenMP.h" namespace AMDiS { class Element; class Quadrature; class ElementMatrix; class ElementVector; class Operator; /** * \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); /// Constructor Assembler(Operator *op, const FiniteElemSpace *rowFESpace, const FiniteElemSpace *colFESpace = NULL); /// Destructor ~Assembler(); void initElementMatrix(ElementMatrix *elMat, const ElInfo *rowElInfo, const ElInfo *colElInfo = NULL); void initElementVector(ElementVector *elVec, const ElInfo *elInfo); /// 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; }; // ============================================================================ // ===== class StandardAssembler ============================================= // ============================================================================ /** * \ingroup Assembler * * \brief * Assembler using non optimized sub assemblers. */ class StandardAssembler : public Assembler { public: MEMORY_MANAGED(StandardAssembler); /// Constructor StandardAssembler(Operator *op, Quadrature *quad2, Quadrature *quad1GrdPsi, Quadrature *quad1GrdPhi, Quadrature *quad0, const FiniteElemSpace *rowFESpace, const FiniteElemSpace *colFESpace = NULL); }; // ============================================================================ // ===== class OptimizedAssembler ============================================= // ============================================================================ /** * \ingroup Assembler * * \brief * Assembler using optimized sub assemblers. */ class OptimizedAssembler : public Assembler { public: MEMORY_MANAGED(OptimizedAssembler); /// Constructor OptimizedAssembler(Operator *op, Quadrature *quad2, Quadrature *quad1GrdPsi, Quadrature *quad1GrdPhi, Quadrature *quad0, const FiniteElemSpace *rowFESpace, const FiniteElemSpace *colFESpace = NULL); }; } #endif // AMDIS_ASSEMBLER_H