// ============================================================================ // == == // == 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 Operator.h */ #ifndef AMDIS_OPERATOR_H #define AMDIS_OPERATOR_H #include #include "AMDiS_fwd.h" #include "FixVec.h" #include "Flag.h" #include "MatrixVector.h" #include "ElInfo.h" #include "AbstractFunction.h" #include "OpenMP.h" #include "SubAssembler.h" namespace AMDiS { /** * \ingroup Assembler * * \brief * Base class for ZeroOrderTerm, FirstOrderTerm and SecondOrderTerm. * OperatorTerms are the building blocks of an Operator. Each OperatorTerm * has its properties which are regarded, when constructing * an Assembler for the corresponding Operator. */ class OperatorTerm { public: /** \brief * Constructs an OperatorTerm with initially no properties. * degree_ is used to determine the degree of the needed quadrature * for the assemblage. */ OperatorTerm(int deg) : properties(0), degree(deg), auxFESpaces(0) {} /// Destructor. virtual ~OperatorTerm() {} /** \brief * Virtual method. It's called by SubAssembler::initElement() for * each OperatorTerm belonging to this SubAssembler. E.g., vectors * and coordinates at quadrature points can be calculated here. */ virtual void initElement(const ElInfo*, SubAssembler*, Quadrature *quad = NULL) {} virtual void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo, SubAssembler*, Quadrature *quad = NULL) {} /// Returs \auxFESpaces, the list of all aux fe spaces the operator makes use off. std::vector& getAuxFESpaces() { return auxFESpaces; } /// Specifies whether the matrix of the term is symmetric void setSymmetric(bool symm); /// Returns true, if the term is piecewise constant, returns false otherwise inline bool isPWConst() { return (degree == 0); } /// Returns true, if the term has a symmetric matrix, returns false otherwise. bool isSymmetric(); /// Returns \ref degree. inline int getDegree() { return degree; } /// Evaluation of the OperatorTerm at all quadrature points. virtual void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const = 0; /** \brief * Determines the value of a dof vector at the quadrature points of a given * element. It is used by all VecAtQP like operator terms. */ double *getVectorAtQPs(DOFVectorBase* vec, const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad); /** \brief * Determines the value of a dof vector at the quadrature points of a given * element. This function is used, if an operator is assembled on two different * meshes using the dual traverse. The element, i.e. the small or the large one, * is choosen, which corresponds to the mesh the dof vector is defined on. */ double *getVectorAtQPs(DOFVectorBase* vec, const ElInfo* smallElInfo, const ElInfo* largeElInfo, SubAssembler* subAssembler, Quadrature *quad); /// WorldVector* getGradientsAtQPs(DOFVectorBase* vec, const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad); /// WorldVector* getGradientsAtQPs(DOFVectorBase* vec, const ElInfo* smallElInfo, const ElInfo* largeElInfo, SubAssembler* subAssembler, Quadrature *quad); protected: /// Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$. void lalt(const DimVec >& Lambda, const WorldMatrix& matrix, DimMat& LALt, bool symm, double factor) const; /** \brief * Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for \f$ A \f$ * the matrix having a ONE in the position \f$ (K,L) \f$ * and ZEROS in all other positions. */ static void lalt_kl(const DimVec >& Lambda, int k, int l, DimMat& LALt, double factor); /// Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for A equal to the identity. void l1lt(const DimVec >& Lambda, DimMat& LALt, double factor) const; /// Evaluation of \f$ \Lambda \cdot b\f$. static inline void lb(const DimVec >& Lambda, const WorldVector& b, DimVec& Lb, double factor) { const int dimOfWorld = Global::getGeo(WORLD); const int dim = Lambda.size() - 1; for (int i = 0; i <= dim; i++) { double val = 0.0; for (int j = 0; j < dimOfWorld; j++) val += Lambda[i][j] * b[j]; Lb[i] += val * factor; } } /** \brief * Evaluation of \f$ \Lambda \cdot b\f$ if b contains the value 1.0 in * each component. */ static inline void l1(const DimVec >& Lambda, DimVec& Lb, double factor) { const int dimOfWorld = Global::getGeo(WORLD); const int dim = Lambda.size() - 1; for (int i = 0; i <= dim; i++) { double val = 0.0; for (int j = 0; j < dimOfWorld; j++) val += Lambda[i][j]; Lb[i] += val * factor; } } protected: /// Stores the properties of this OperatorTerm Flag properties; /// Polynomial degree of the term. Used to detemine the degree of the quadrature. int degree; /// List off all fe spaces, the operator term makes use off. std::vector auxFESpaces; /// Pointer to the Operator this OperatorTerm belongs to. Operator* operat; /// Flag for piecewise constant terms static const Flag PW_CONST; /// Flag for symmetric terms static const Flag SYMMETRIC; friend class SubAssembler; friend class ZeroOrderAssembler; friend class FirstOrderAssembler; friend class SecondOrderAssembler; friend class Operator; }; /** * \ingroup Assembler * * \brief * Describes the second order terms: \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ */ class SecondOrderTerm : public OperatorTerm { public: /// Constructor. SecondOrderTerm(int deg) : OperatorTerm(deg) {} /// Destructor. virtual ~SecondOrderTerm() {} /// Evaluation of \f$ \Lambda A \Lambda^t \f$ at all quadrature points. virtual void getLALt(const ElInfo *elInfo, int nPoints, DimMat **result) const = 0; /// Evaluation of \f$ A \nabla u(\vec{x}) \f$ at all quadrature points. virtual void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const = 0; }; /** * \ingroup Assembler * * \brief * Implements the laplace operator: \f$ \Delta u(\vec{x}) \f$ */ class Laplace_SOT : public SecondOrderTerm { public: /// Constructor. Laplace_SOT() : SecondOrderTerm(0) { setSymmetric(true); } /// Implenetation of SecondOrderTerm::getLALt(). inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < nPoints; iq++) l1lt(Lambda, *(LALt[iq]), 1.0); } /// Implementation of SecondOrderTerm::eval(). inline void eval(int nPoints, const double *, const WorldVector *, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int dow = Global::getGeo(WORLD); if (D2UhAtQP) { for (int iq = 0; iq < nPoints; iq++) { double resultQP = 0.0; for (int i = 0; i < dow; i++) resultQP += D2UhAtQP[iq][i][i]; result[iq] += factor * resultQP; } } } /// Implenetation of SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if (grdUhAtQP) for (int iq = 0; iq < nPoints; iq++) result[iq] += grdUhAtQP[iq]; } }; /** * \ingroup Assembler * * \brief * Implements the laplace operator multiplied with a scalar factor: * \f$ f \cdot \Delta u(\vec{x}) \f$ */ class FactorLaplace_SOT : public SecondOrderTerm { public: /// Constructor. FactorLaplace_SOT(double f) : SecondOrderTerm(0) { factor = new double; *factor = f; setSymmetric(true); } /// Constructor. FactorLaplace_SOT(double *fptr) : SecondOrderTerm(0), factor(fptr) { setSymmetric(true); } /// Implements SecondOrderTerm::getLALt(). inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < nPoints; iq++) l1lt(Lambda, *(LALt[iq]), (*factor)); } /// Implenetation of SecondOrderTerm::eval(). void eval(int nPoints, const double *, const WorldVector *, const WorldMatrix *D2UhAtQP, double *result, double f) const { int dow = Global::getGeo(WORLD); if (D2UhAtQP) { for (int iq = 0; iq < nPoints; iq++) { double resultQP = 0.0; for (int i = 0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += resultQP * f * (*factor); } } } /// Implenetation of SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if (grdUhAtQP) for (int iq = 0; iq < nPoints; iq++) axpy(*factor, grdUhAtQP[iq], result[iq]); } private: /// Pointer to the factor. double *factor; }; /** * \ingroup Assembler * * \brief * SecondOrderTerm where A is a function which maps a DOFVector evaluated at * a given quadrature point to a WolrdMatrix: * \f$ \nabla \cdot A(v(\vec{x})) \nabla u(\vec{x}) \f$ */ class MatrixFct_SOT : public SecondOrderTerm { public: /// Constructor. MatrixFct_SOT(DOFVectorBase *dv, AbstractFunction, double> *fct, AbstractFunction, WorldMatrix > *div, bool sym = false); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements SecondOrderTerm::getLALt(). void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /// Implenetation of SecondOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /// Implenetation of SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /// DOFVector to be evaluated at quadrature points. DOFVectorBase* vec; /// Pointer to the values of the DOFVector at quadrature points. double* vecAtQPs; /// Function for A. AbstractFunction, double>* matrixFct; /// AbstractFunction, WorldMatrix >* divFct; /// True, if \ref matrixFct produces always symmetric matrices. bool symmetric; }; /** * \ingroup Assembler * * \brief * SecondOrderTerm where A is a given fixed WorldMatrix: * \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ */ class Matrix_SOT : public SecondOrderTerm { public: /// Constructor Matrix_SOT(WorldMatrix mat) : SecondOrderTerm(0), matrix(mat) { symmetric = matrix.isSymmetric(); setSymmetric(symmetric); } /// Implements SecondOrderTerm::getLALt(). inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const { const DimVec >& Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < nPoints; iq++) lalt(Lambda, matrix, *(LALt[iq]), symmetric, 1.0); } /// Implenetation of SecondOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /// Implenetation of SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /// Matrix stroring A. WorldMatrix matrix; /// True, if \ref matrix is symmetric. bool symmetric; }; /** * \ingroup Assembler * * \brief * SecondOrderTerm where A is a WorldMatrix having a ONE in position IJ * and ZERO in all other positions * \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ */ class FactorIJ_SOT : public SecondOrderTerm { public: /// Constructor. FactorIJ_SOT(int x_i, int x_j, double f) : SecondOrderTerm(0), xi(x_i), xj(x_j) { factor = new double; *factor = f; setSymmetric(xi == xj); } /// Constructor. FactorIJ_SOT(int x_i, int x_j, double *fptr) : SecondOrderTerm(0), xi(x_i), xj(x_j), factor(fptr) { setSymmetric(xi == xj); } /// Implements SecondOrderTerm::getLALt(). inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < nPoints; iq++) lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*factor)); } /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *, const WorldVector *, const WorldMatrix *D2UhAtQP, double *result, double fac) const { if (D2UhAtQP) for (int iq = 0; iq < nPoints; iq++) result[iq] += (*factor) * D2UhAtQP[iq][xi][xj] * fac; } /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if (grdUhAtQP) for (int iq = 0; iq < nPoints; iq++) result[iq][xi] += (*factor) * grdUhAtQP[iq][xj]; } private: /** \brief * Directions for the derivatives. */ int xi, xj; /** \brief * Pointer to the factor. */ double *factor; }; /** * \ingroup Assembler * * \brief * Laplace operator multiplied with a function evaluated at the quadrature * points of a given DOFVector: * \f$ f(v(\vec{x})) \Delta u(\vec{x}) \f$ */ class VecAtQP_SOT : public SecondOrderTerm { public: /// Constructor. VecAtQP_SOT(DOFVectorBase *dv, AbstractFunction *af); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. void initElement(const ElInfo* smallElInfo, const ElInfo* largeElInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements SecondOrderTerm::getLALt(). void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /// Implenetation of SecondOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /// Implenetation of SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /// DOFVector to be evaluated at quadrature points. DOFVectorBase* vec; /// Pointer to an array containing the DOFVector evaluated at quadrature points. double* vecAtQPs; /// Function evaluated at \ref vecAtQPs. AbstractFunction *f; }; /** * \ingroup Assembler * * \brief * Laplace operator multiplied with a function evaluated at the quadrature * points of a given DOFVector: * \f$ f(v(\vec{x}), w(\vec{x})) \Delta u(\vec{x}) \f$ */ class Vec2AtQP_SOT : public SecondOrderTerm { public: /// Constructor. Vec2AtQP_SOT(DOFVectorBase *dv1, DOFVectorBase *dv2, BinaryAbstractFunction *af); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements SecondOrderTerm::getLALt(). void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /// Implenetation of SecondOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /// Implenetation of SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /// DOFVector to be evaluated at quadrature points. DOFVectorBase* vec1; DOFVectorBase* vec2; /// Pointer to an array containing the DOFVector evaluated at quadrature points. double* vecAtQPs1; double* vecAtQPs2; /// Function evaluated at \ref vecAtQPs. BinaryAbstractFunction *f; }; /** * \ingroup Assembler * * \brief * Laplace multiplied with a function evaluated at each quadrature point: * \f$ f(\vec{x}) \Delta u(\vec{x}) \f$ */ class CoordsAtQP_SOT : public SecondOrderTerm { public: /// Constructor. CoordsAtQP_SOT(AbstractFunction > *af) : SecondOrderTerm(af->getDegree()), g(af) { setSymmetric(true); } /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /** \brief * Stores coordinates at quadrature points. Set in \ref initElement(). */ WorldVector* coordsAtQPs; /** \brief * Function evaluated at quadrature points. */ AbstractFunction > *g; }; /** * \ingroup Assembler * * \brief * SecondOrderTerm where A is a function which maps the gradient of a * DOFVector at each quadrature point to WorldMatrix: * \f$ \nabla \cdot A(\nabla v(\vec{x})) \nabla u(\vec{x})\f$ */ class MatrixGradient_SOT : public SecondOrderTerm { public: /// Constructor. MatrixGradient_SOT(DOFVectorBase *dv, AbstractFunction, WorldVector > *af, AbstractFunction, WorldMatrix > *divAf, bool symm = false); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: DOFVectorBase* vec; /** \brief * Function which maps each entry in \ref gradAtQPs to a WorldMatrix. */ AbstractFunction, WorldVector > *f; AbstractFunction, WorldMatrix > *divFct; /** \brief * Pointer to a WorldVector array containing the gradients of the DOFVector * at each quadrature point. */ WorldVector* gradAtQPs; /** \brief * True, if \ref f provides always a symmetric WorldMatrix. */ bool symmetric; }; /** * \ingroup Assembler * * \brief * Laplace multiplied with a function which maps the gradient of a DOFVector * at each quadrature point to a double: * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ */ class FctGradient_SOT : public SecondOrderTerm { public: /// Constructor. FctGradient_SOT(DOFVectorBase *dv, AbstractFunction > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: DOFVectorBase* vec; /** \brief * Function wich maps \ref gradAtQPs to a double. */ AbstractFunction > *f; /** \brief * Pointer to a WorldVector array containing the gradients of the DOFVector * at each quadrature point. */ WorldVector* gradAtQPs; }; /** * \ingroup Assembler * * \brief * Laplace multiplied with a function which maps the gradient of a DOFVector * at each quadrature point to a double: * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ */ class VecAndGradientAtQP_SOT : public SecondOrderTerm { public: /// Constructor. VecAndGradientAtQP_SOT(DOFVectorBase *dv, BinaryAbstractFunction > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: DOFVectorBase* vec; /** \brief * Function wich maps \ref gradAtQPs to a double. */ BinaryAbstractFunction > *f; /** \brief * Pointer to a WorldVector array containing the gradients of the DOFVector * at each quadrature point. */ double* vecAtQPs; WorldVector* gradAtQPs; }; /** * \ingroup Assembler * * \brief * Laplace multiplied with a function which maps the gradient of a DOFVector * at each quadrature point to a double: * \f$ \nabla \cdot A(v(\vec{x}), \nabla v(\vec{x})) \nabla u(\vec{x}) \f$ */ class VecMatrixGradientAtQP_SOT : public SecondOrderTerm { public: /// Constructor. VecMatrixGradientAtQP_SOT(DOFVectorBase *dv, BinaryAbstractFunction, double, WorldVector > *af, AbstractFunction, WorldMatrix > *divAf, bool symm = false); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: DOFVectorBase* vec; /** \brief * Function wich maps \ref gradAtQPs to a double. */ BinaryAbstractFunction, double, WorldVector > *f; AbstractFunction, WorldMatrix > *divFct; /** \brief * Pointer to a WorldVector array containing the gradients of the DOFVector * at each quadrature point. */ double* vecAtQPs; WorldVector* gradAtQPs; bool symmetric; }; /** * \ingroup Assembler * * \brief * Laplace multiplied with a function which maps the gradient of a DOFVector * at each quadrature point to a double: * \f$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ */ class VecGradCoordsAtQP_SOT : public SecondOrderTerm { public: /// Constructor. VecGradCoordsAtQP_SOT(DOFVectorBase *dv, TertiaryAbstractFunction, WorldVector > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: DOFVectorBase* vec; /** \brief * Function wich maps \ref gradAtQPs to a double. */ TertiaryAbstractFunction, WorldVector > *f; /** \brief * Pointer to a WorldVector array containing the gradients of the DOFVector * at each quadrature point. */ double* vecAtQPs; WorldVector* gradAtQPs; WorldVector* coordsAtQPs; }; /** * \ingroup Assembler * * \brief * Laplace operator multiplied with a function evaluated at the quadrature * points of a given DOFVector: * \f$ -f(v(\vec{x})) \Delta u(\vec{x}) \f$ */ class VecAndCoordsAtQP_SOT : public SecondOrderTerm { public: /// Constructor. VecAndCoordsAtQP_SOT(DOFVectorBase *dv, BinaryAbstractFunction > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::eval(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Pointer to an array containing the DOFVector evaluated at quadrature * points. */ double* vecAtQPs; WorldVector* coordsAtQPs; /** \brief * Function evaluated at \ref vecAtQPs. */ BinaryAbstractFunction > *f; }; /** * \ingroup Assembler * * \brief * SecondOrderTerm where A is a function which maps the gradient of a * DOFVector at each quadrature point to WorldMatrix: * \f$ \nabla \cdot A(\nabla v(\vec{x})) \nabla u(\vec{x})\f$ */ class MatrixGradientAndCoords_SOT : public SecondOrderTerm { public: /// Constructor. MatrixGradientAndCoords_SOT(DOFVectorBase *dv, BinaryAbstractFunction, WorldVector , WorldVector > *af, AbstractFunction, WorldMatrix > *divAf, bool symm = false); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: DOFVectorBase* vec; /** \brief * Function which maps each entry in \ref gradAtQPs to a WorldMatrix. */ BinaryAbstractFunction, WorldVector, WorldVector > *f; AbstractFunction, WorldMatrix > *divFct; /** \brief * Pointer to a WorldVector array containing the gradients of the DOFVector * at each quadrature point. */ WorldVector* gradAtQPs; WorldVector* coordsAtQPs; /** \brief * True, if \ref f provides always a symmetric WorldMatrix. */ bool symmetric; }; class MatrixVec2_SOT : public SecondOrderTerm { public: /// Constructor. MatrixVec2_SOT(DOFVectorBase *dv1, DOFVectorBase *dv2, BinaryAbstractFunction *f, WorldMatrix Af, bool sym = false); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements SecondOrderTerm::getLALt(). void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /// Implenetation of SecondOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /// Implenetation of SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /// DOFVector to be evaluated at quadrature points. DOFVectorBase* vec1; DOFVectorBase* vec2; /// Pointer to the values of the DOFVector at quadrature points. double* vec1AtQPs; double* vec2AtQPs; /// Function for A. BinaryAbstractFunction * fct; /// WorldMatrix A; /// True, if \ref matrixFct produces always symmetric matrices. bool symmetric; }; class General_SOT : public SecondOrderTerm { public: /// Constructor. General_SOT(std::vector*> vecs, std::vector*> grads, TertiaryAbstractFunction, WorldVector, std::vector, std::vector > > *f, AbstractFunction, WorldMatrix > *divFct, bool symmetric); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo*, SubAssembler*, Quadrature *quad= NULL); /// Implements SecondOrderTerm::getLALt(). void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /// Implenetation of SecondOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /// Implenetation of SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: std::vector*> vecs_; std::vector*> grads_; TertiaryAbstractFunction, WorldVector, std::vector, std::vector > > *f_; AbstractFunction, WorldMatrix > *divFct_; WorldVector *coordsAtQPs_; std::vector vecsAtQPs_; std::vector*> gradsAtQPs_; bool symmetric_; }; class GeneralParametric_SOT : public SecondOrderTerm { public: /// Constructor. GeneralParametric_SOT(std::vector*> vecs, std::vector*> grads, QuartAbstractFunction, WorldVector, WorldVector, std::vector, std::vector > > *f, AbstractFunction, WorldMatrix > *divFct, bool symmetric); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo*, SubAssembler* , Quadrature *quad= NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: std::vector*> vecs_; std::vector*> grads_; QuartAbstractFunction, WorldVector, WorldVector, std::vector, std::vector > > *f_; AbstractFunction, WorldMatrix > *divFct_; WorldVector *coordsAtQPs_; WorldVector elementNormal_; std::vector vecsAtQPs_; std::vector*> gradsAtQPs_; bool symmetric_; }; // ============================================================================ // ===== class FirstOrderTerm ================================================= // ============================================================================ /** * \ingroup Assembler * * \brief * Describes the first order terms: \f$ b \cdot \nabla u(\vec{x}) \f$ */ class FirstOrderTerm : public OperatorTerm { public: /// Constructor. FirstOrderTerm(int deg) : OperatorTerm(deg) {} /// Destructor. virtual ~FirstOrderTerm() {} /// Evaluation of \f$ \Lambda b \f$. virtual void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& result) const = 0; /// Implenetation of FirstOrderTerm::eval(). void eval(int nPoints, const double *, const WorldVector *grdUhAtQP, const WorldMatrix *, double *result, double factor) const { int dow = Global::getGeo(WORLD); if (grdUhAtQP) { for (int iq = 0; iq < nPoints; iq++) { double resultQP = 0.0; for (int i = 0; i < dow; i++) resultQP += grdUhAtQP[iq][i]; result[iq] += resultQP * factor; } } } }; /** * \ingroup Assembler * * \brief * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a vector b which * only consits of entries equal to one. */ class Simple_FOT : public FirstOrderTerm { public: /// Constructor. Simple_FOT() : FirstOrderTerm(0) {} /// Implements FirstOrderTerm::getLb(). inline void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < nPoints; iq++) l1(Lambda, Lb[iq], 1.0); } }; /** * \ingroup Assembler * * \brief * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a vector b which * only consits of entries equal to one. */ class FactorSimple_FOT : public FirstOrderTerm { public: /// Constructor. FactorSimple_FOT(double f) : FirstOrderTerm(0) { factor = new double; *factor = f; } /// Constructor. FactorSimple_FOT(double *fptr) : FirstOrderTerm(0), factor(fptr) {} /** \brief * Implements FirstOrderTerm::getLb(). */ inline void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < nPoints; iq++) l1(Lambda, Lb[iq], (*factor)); } private: /** \brief * Pointer to the factor. */ double *factor; }; /** * \ingroup Assembler * * \brief * First order term: \f$ b \cdot \nabla u(\vec{x}) \f$ with a given vector b. */ class Vector_FOT : public FirstOrderTerm { public: /// Constructor. Vector_FOT(WorldVector wv) : FirstOrderTerm(0), b(wv) {} /** \brief * Implements FirstOrderTerm::getLb(). */ inline void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >&Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < nPoints; iq++) lb(Lambda, b, Lb[iq], 1.0); } /// Implements FirstOrderTerm::eval(). void eval(int nPoints, const double *, const WorldVector *grdUhAtQP, const WorldMatrix *, double *result, double factor) const { if (grdUhAtQP) for (int iq = 0; iq < nPoints; iq++) result[iq] += b * grdUhAtQP[iq] * factor; } protected: /// Vector which is multiplied with \f$ \nabla u(\vec{x}) \f$ WorldVector b; }; /** * \ingroup Assembler * * \brief * Simple_FOT multiplied with \f$ f(v(\vec{x})) \f$. */ class VecAtQP_FOT : public FirstOrderTerm { public: /// Constructor. VecAtQP_FOT(DOFVectorBase *dv, AbstractFunction *af, WorldVector *wv); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements FirstOrderTerm::getLb(). void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const; /// Implements FirstOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: /// DOFVector to be evaluated at quadrature points. DOFVectorBase* vec; /// v at quadrature points. double *vecAtQPs; /// Function f. AbstractFunction *f; /// WorldVector *b; }; /** * \ingroup Assembler * * \brief * Simple_FOT multiplied with \f$ f(\vec{x}) \f$. */ class CoordsAtQP_FOT : public FirstOrderTerm { public: /// Constructor. CoordsAtQP_FOT(AbstractFunction > *af) : FirstOrderTerm(af->getDegree()), g(af) {} /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements FistOrderTerm::getLb(). */ void getLb(const ElInfo *elInfo, int nPoints,VectorOfFixVecs >&Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: /** \brief * Stores coordinates at quadrature points. Set in \ref initElement(). */ WorldVector* coordsAtQPs; /** \brief * Function avaluated at world coordinates. */ AbstractFunction > *g; }; /** * \ingroup Assembler * * \brief * Vector_FOT multiplied with \f$ f(\vec{x}) \f$. */ class VecCoordsAtQP_FOT : public FirstOrderTerm { public: /// Constructor. VecCoordsAtQP_FOT(AbstractFunction > *af, WorldVector wv) : FirstOrderTerm(af->getDegree()), g(af), b(wv) {} /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements FistOrderTerm::getLb(). */ void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: /** \brief * Stores coordinates at quadrature points. Set in \ref initElement(). */ WorldVector* coordsAtQPs; /** \brief * Function evaluated at world coordinates. */ AbstractFunction > *g; /** \brief * Coefficient vector. */ WorldVector b; }; /** * \ingroup Assembler * * \brief * First order term: \f$ b(\nabla v(\vec{x})) \cdot \nabla u(\vec{x})\f$. */ class VectorGradient_FOT : public FirstOrderTerm { public: /// Constructor. VectorGradient_FOT(DOFVectorBase *dv, AbstractFunction, WorldVector > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements FirstOrderTerm::getLb(). */ void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: DOFVectorBase* vec; /** \brief * Function for b. */ AbstractFunction, WorldVector > *f; /** \brief * Gradient of v at quadrature points. */ WorldVector *gradAtQPs; }; /** * \ingroup Assembler * * \brief * First order term: \f$ b(v(\vec{x})) \cdot \nabla u(\vec{x})\f$. */ class VectorFct_FOT : public FirstOrderTerm { public: /// Constructor. VectorFct_FOT(DOFVectorBase *dv, AbstractFunction, double> *fct); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements FirstOrderTerm::getLb(). */ void getLb(const ElInfo *elInfo, int qPoint, VectorOfFixVecs >& Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; /** \brief * Function for b. */ AbstractFunction, double> *vecFct; }; /** * \ingroup Assembler * * \brief * */ class VecFctAtQP_FOT : public FirstOrderTerm { public: /// Constructor. VecFctAtQP_FOT(AbstractFunction, WorldVector > *af) : FirstOrderTerm(af->getDegree()), g(af) {} /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements FistOrderTerm::getLb(). */ void getLb(const ElInfo *elInfo, int nPoints,VectorOfFixVecs >&Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: /** \brief * Stores coordinates at quadrature points. Set in \ref initElement(). */ WorldVector* coordsAtQPs; /** \brief * Function avaluated at world coordinates. */ AbstractFunction, WorldVector > *g; }; /** * \ingroup Assembler * * \brief * First order term: \f$ b(v(\vec{x}), \nabla w(\vec{x})) \cdot \nabla u(\vec{x})\f$. */ class VecGrad_FOT : public FirstOrderTerm { public: /// Constructor. VecGrad_FOT(DOFVectorBase *dv1, DOFVectorBase *dv2, BinaryAbstractFunction, double, WorldVector > *fct); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. void initElement(const ElInfo* smallElInfo, const ElInfo* largeElInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements FirstOrderTerm::getLb(). void getLb(const ElInfo *elInfo, int qPoint, VectorOfFixVecs >& Lb) const; /// Implements FirstOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec1; DOFVectorBase* vec2; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; WorldVector *gradAtQPs; /** \brief * Function for b. */ BinaryAbstractFunction, double, WorldVector > *vecFct; }; /** * \ingroup Assembler * * \brief * First order term: \f$ b(\nabla v(\vec{x}), \nabla w(\vec{x})) \cdot \nabla u(\vec{x})\f$. */ class FctGrad2_FOT : public FirstOrderTerm { public: /// Constructor FctGrad2_FOT(DOFVectorBase *dv1, DOFVectorBase *dv2, BinaryAbstractFunction, WorldVector, WorldVector > *vecFct_) : FirstOrderTerm(vecFct_->getDegree()), vec1(dv1), vec2(dv2), vecFct(vecFct_) {} /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements FirstOrderTerm::getLb(). void getLb(const ElInfo *elInfo, int qPoint, VectorOfFixVecs >& Lb) const; /// Implements FirstOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: /// DOFVector to be evaluated at quadrature points. DOFVectorBase* vec1; /// DOFVector to be evaluated at quadrature points. DOFVectorBase* vec2; /// Gradient v at quadrature points. WorldVector *grad1AtQPs; /// Gradient v at quadrature points. WorldVector *grad2AtQPs; /// Function for b. BinaryAbstractFunction, WorldVector, WorldVector > *vecFct; }; class Vec2AndGradAtQP_FOT : public FirstOrderTerm { public: Vec2AndGradAtQP_FOT(DOFVectorBase *dv1, DOFVectorBase *dv2, TertiaryAbstractFunction > *f_, WorldVector *b_); void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const; void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: DOFVectorBase* vec1; DOFVectorBase* vec2; double *vec1AtQPs; double *vec2AtQPs; WorldVector *gradAtQPs1; TertiaryAbstractFunction > *f; WorldVector *b; }; class FctVecAtQP_FOT : public FirstOrderTerm { public: FctVecAtQP_FOT(DOFVectorBase *dv, AbstractFunction > *f_, WorldVector *b_); void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const; void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: DOFVectorBase* vec; double *vecAtQPs; WorldVector *coordsAtQPs; AbstractFunction > *f; WorldVector *b; }; class Vec2AtQP_FOT : public FirstOrderTerm { public: Vec2AtQP_FOT(DOFVectorBase *dv1, DOFVectorBase *dv2, WorldVector *b_); void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const; void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: DOFVectorBase* vec1; DOFVectorBase* vec2; double *vec1AtQPs; double *vec2AtQPs; WorldVector *b; }; class Vec3FctAtQP_FOT : public FirstOrderTerm { public: Vec3FctAtQP_FOT(DOFVectorBase *dv1, DOFVectorBase *dv2,DOFVectorBase *dv3, BinaryAbstractFunction *f_, WorldVector *b_); void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const; void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: DOFVectorBase* vec1; DOFVectorBase* vec2; DOFVectorBase* vec3; BinaryAbstractFunction* f; double *vec1AtQPs; double *vec2AtQPs; double *vec3AtQPs; WorldVector *b; }; class General_FOT : public FirstOrderTerm { public: /// Constructor General_FOT(std::vector*> vecs, std::vector*> grads, TertiaryAbstractFunction, WorldVector, std::vector, std::vector > > *f); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo*, SubAssembler* , Quadrature *quad= NULL); /// Implements FirstOrderTerm::getLb(). void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& result) const; /// Implenetation of FirstOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: std::vector*> vecs_; std::vector*> grads_; TertiaryAbstractFunction, WorldVector, std::vector, std::vector > > *f_; WorldVector *coordsAtQPs_; std::vector vecsAtQPs_; std::vector*> gradsAtQPs_; }; class GeneralParametric_FOT : public FirstOrderTerm { public: /// Constructor GeneralParametric_FOT(std::vector*> vecs, std::vector*> grads, QuartAbstractFunction, WorldVector, WorldVector, std::vector, std::vector > > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo*, SubAssembler*, Quadrature *quad= NULL); /** \brief * Implements FirstOrderTerm::getLb(). */ void getLb(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& result) const; /** \brief * Implenetation of FirstOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; protected: std::vector*> vecs_; std::vector*> grads_; QuartAbstractFunction, WorldVector, WorldVector, std::vector, std::vector > > *f_; WorldVector *coordsAtQPs_; WorldVector elementNormal_; std::vector vecsAtQPs_; std::vector*> gradsAtQPs_; }; // ============================================================================ // ===== class ZeroOrderTerm ================================================== // ============================================================================ /** * \ingroup Assembler * * \brief * Describes zero order terms: \f$ cu(\vec{x}) \f$. */ class ZeroOrderTerm : public OperatorTerm { public: /// Constructor. ZeroOrderTerm(int deg) : OperatorTerm(deg) {} /** \brief * Destructor. */ virtual ~ZeroOrderTerm() {} /** \brief * Evaluates \f$ c \f$ */ virtual void getC(const ElInfo *elInfo, int nPoints, std::vector &C) const = 0; }; /** * \ingroup Assembler * * \brief * Simple zero order term */ class Simple_ZOT : public ZeroOrderTerm { public: /// Constructor. Simple_ZOT(double f = 1.0) : ZeroOrderTerm(0), factor(f) {} /// Implements ZeroOrderTerm::getC(). inline void getC(const ElInfo *, int nPoints, std::vector &C) const { for (int iq = 0; iq < nPoints; iq++) C[iq] += factor; } /// Implements ZeroOrderTerm::eval(). inline void eval(int nPoints, const double *uhAtQP, const WorldVector *, const WorldMatrix *, double *result, double fac) const { for (int iq = 0; iq < nPoints; iq++) result[iq] += fac * factor * uhAtQP[iq]; } protected: /// Constant factor of zero order term. double factor; }; /** * \ingroup Assembler * * \brief * Zero order term: \f$ f(v(\vec{x})) u(\vec{x})\f$ */ class VecAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecAtQP_ZOT(DOFVectorBase *dv, AbstractFunction *ab); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. void initElement(const ElInfo* smallElInfo, const ElInfo* largeElInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements ZeroOrderTerm::getC(). void getC(const ElInfo *, int nPoints, std::vector &C) const; /// Implements ZeroOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /// DOFVector to be evaluated at quadrature points. DOFVectorBase* vec; /// Vector v at quadrature points. double *vecAtQPs; /// Function for c. AbstractFunction *f; }; /** * \ingroup Assembler * * \brief * Zero order term: \f$ f(v(\vec{x})) g(w(\vec{x})) u(\vec{x})\f$ */ class MultVecAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. MultVecAtQP_ZOT(DOFVectorBase *dv1, DOFVectorBase *dv2, AbstractFunction *f1, AbstractFunction *f2); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVectorBase to be evaluated at quadrature points. */ DOFVectorBase* vec1; DOFVectorBase* vec2; /** \brief * Vector v at quadrature points. */ double *vecAtQPs1; double *vecAtQPs2; /** \brief * Function for c. */ AbstractFunction *f1; AbstractFunction *f2; }; /** * \ingroup Assembler * * \brief * Zero order term: \f$ f(v(\vec{x}), w(\vec{x})) u(\vec{x})\f$ */ class Vec2AtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. Vec2AtQP_ZOT(DOFVectorBase *dv1, DOFVectorBase *dv2, BinaryAbstractFunction *f); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implementation of \ref OperatorTerm::initElement() for multilpe meshes. void initElement(const ElInfo* smallElInfo, const ElInfo* largeElInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements ZeroOrderTerm::getC(). void getC(const ElInfo *, int nPoints, std::vector &C) const; /// Implements ZeroOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /// First DOFVector to be evaluated at quadrature points. DOFVectorBase* vec1; /// Second DOFVector to be evaluated at quadrature points. DOFVectorBase* vec2; /// Values of the first DOFVector at the quadrature points. double *vecAtQPs1; /// Values of the second DOFVector at the quadrature points. double *vecAtQPs2; /// Function for c. BinaryAbstractFunction *f; }; /** * \ingroup Assembler * * \brief * Zero order term: \f$ f(v(\vec{x}), w(\vec{x})) u(\vec{x})\f$ */ class Vec3AtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. Vec3AtQP_ZOT(DOFVectorBase *dv1, DOFVectorBase *dv2, DOFVectorBase *dv3, TertiaryAbstractFunction *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec1; DOFVectorBase* vec2; DOFVectorBase* vec3; /** \brief * Vector v at quadrature points. */ double *vecAtQPs1; double *vecAtQPs2; double *vecAtQPs3; /** \brief * Function for c. */ TertiaryAbstractFunction *f; }; /** * \ingroup Assembler * * \brief * */ class FctGradientCoords_ZOT : public ZeroOrderTerm { public: /// Constructor. FctGradientCoords_ZOT(DOFVectorBase *dv, BinaryAbstractFunction, WorldVector > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getC(). */ void getC(const ElInfo *elInfo, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: DOFVectorBase* vec; /** \brief * Function wich maps \ref gradAtQPs to a double. */ BinaryAbstractFunction, WorldVector > *f; /** \brief * Pointer to a WorldVector array containing the gradients of the DOFVector * at each quadrature point. */ WorldVector* gradAtQPs; WorldVector* coordsAtQPs; }; /** * \ingroup Assembler * * \brief */ class VecGradCoordsAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecGradCoordsAtQP_ZOT(DOFVectorBase *dv, TertiaryAbstractFunction, WorldVector > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; /** \brief * Gradient at quadrature points. */ WorldVector* gradAtQPs; WorldVector* coordsAtQPs; /** \brief * Function for c. */ TertiaryAbstractFunction, WorldVector > *f; }; /** * \ingroup Assembler * * \brief */ class VecAndCoordsAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecAndCoordsAtQP_ZOT(DOFVectorBase *dv, BinaryAbstractFunction > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; /** \brief * Gradient at quadrature points. */ WorldVector* coordsAtQPs; /** \brief * Function for c. */ BinaryAbstractFunction > *f; }; /** * \ingroup Assembler * * \brief */ class Vec2AndGradAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. Vec2AndGradAtQP_ZOT(DOFVectorBase *dv1, DOFVectorBase *dv2, TertiaryAbstractFunction, double > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec1; DOFVectorBase* vec2; /** \brief * Vector v at quadrature points. */ double *vecAtQPs1; double *vecAtQPs2; /** \brief * Gradient at quadrature points. */ WorldVector *gradAtQPs; /** \brief * Function for c. */ TertiaryAbstractFunction, double > *f; }; /** * \ingroup Assembler * * \brief * */ class FctGradient_ZOT : public ZeroOrderTerm { public: /// Constructor. FctGradient_ZOT(DOFVectorBase *dv, AbstractFunction > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getC(). */ void getC(const ElInfo *elInfo, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: DOFVectorBase* vec; /** \brief * Function wich maps \ref gradAtQPs to a double. */ AbstractFunction > *f; /** \brief * Pointer to a WorldVector array containing the gradients of the DOFVector * at each quadrature point. */ WorldVector* gradAtQPs; }; /** * \ingroup Assembler * * \brief */ class VecAndGradAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecAndGradAtQP_ZOT(DOFVectorBase *dv, BinaryAbstractFunction > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; /** \brief * Gradient at quadrature points. */ WorldVector *gradAtQPs; /** \brief * Function for c. */ BinaryAbstractFunction > *f; }; /** * \ingroup Assembler * * \brief */ class VecAndGradAtQP_SOT : public SecondOrderTerm { public: /// Constructor. VecAndGradAtQP_SOT(DOFVectorBase *dv, BinaryAbstractFunction > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implements SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implements SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; /** \brief * Gradient at quadrature points. */ WorldVector *gradAtQPs; /** \brief * Function for c. */ BinaryAbstractFunction > *f; }; /** * \ingroup Assembler * * \brief * Second order term: \f$ f(v(\vec{x}),\nabla w(\vec{x})) \Delta u(\vec{x})\f$ */ class VecGrad_SOT : public SecondOrderTerm { public: /// Constructor. VecGrad_SOT( DOFVectorBase *dv1, DOFVectorBase *dv2, BinaryAbstractFunction > *f_) : SecondOrderTerm(f_->getDegree()), vec1(dv1), vec2(dv2), f(f_) {} /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements SecondOrderTerm::getLALt(). inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /// Implements SecondOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /// Implements SecondOrderTerm::weakEval(). void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /// DOFVectors to be evaluated at quadrature points. DOFVectorBase* vec1; DOFVectorBase* vec2; /// Vector v at quadrature points. double *vecAtQPs; /// Gradient at quadrature points. WorldVector *gradAtQPs; /// Function for c. BinaryAbstractFunction > *f; }; /* * \ingroup Assembler * * \brief * Zero order term: \f$ f(\vec{x}) u(\vec{x})\f$ */ class CoordsAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. CoordsAtQP_ZOT(AbstractFunction > *af) : ZeroOrderTerm(af->getDegree()), g(af) {} /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * Stores coordinates at quadrature points. Set in \ref initElement(). */ WorldVector* coordsAtQPs; /** \brief * Function for c. */ AbstractFunction > *g; }; /** * \ingroup Assembler * * \brief * SecondOrderTerm where A(x) is a WorldMatrix having a in all positions * except possibly the position IJ * \f$ \nabla \cdot A(x) \nabla u(\vec{x}) \f$ */ class CoordsAtQP_IJ_SOT : public SecondOrderTerm { public: /// Constructor. CoordsAtQP_IJ_SOT(AbstractFunction > *af, int x_i, int x_j) : SecondOrderTerm(af->getDegree()), g(af), xi(x_i), xj(x_j) { setSymmetric(xi == xj); } /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ inline void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implements SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implements SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; private: /** \brief * Stores coordinates at quadrature points. Set in \ref initElement(). */ WorldVector* coordsAtQPs; /** \brief * Function evaluated at quadrature points. */ AbstractFunction > *g; /** \brief * Directions for the derivatives. */ int xi, xj; }; /** * \ingroup Assembler * * \brief * SecondOrderTerm where A is a WorldMatrix having a in all positions * except possibly the position IJ, multiplied with a function * evaluated at the quadrature points of a given DOFVector: * \f$ \nabla \cdot f(v(\vec{x})) A \nabla u(\vec{x}) \f$ */ class VecAtQP_IJ_SOT : public SecondOrderTerm { public: /// Constructor. VecAtQP_IJ_SOT(DOFVectorBase *dv, AbstractFunction *af, int x_i, int x_j); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const; /** \brief * Implements SecondOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implements SecondOrderTerm::weakEval(). */ void weakEval(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Pointer to an array containing the DOFVector evaluated at quadrature * points. */ double* vecAtQPs; /** \brief * Function evaluated at \ref vecAtQPs. */ AbstractFunction *f; private: /** \brief * Directions for the derivatives. */ int xi, xj; }; class VecAndGradVecAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecAndGradVecAtQP_ZOT(DOFVectorBase *dv, DOFVectorBase *dGrd, BinaryAbstractFunction > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; /** \brief * First DOFVector whose gradient is evaluated at quadrature points. */ DOFVectorBase* vecGrd; /** \brief * Gradient of first vector at quadrature points. */ WorldVector *gradAtQPs; /** \brief * Function for c. */ BinaryAbstractFunction > *f; }; class VecAndGradVec2AtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecAndGradVec2AtQP_ZOT(DOFVectorBase *dv, DOFVectorBase *dGrd1, DOFVectorBase *dGrd2, TertiaryAbstractFunction, WorldVector > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; /** \brief * First DOFVector whose gradient is evaluated at quadrature points. */ DOFVectorBase* vecGrd1; /** \brief * Gradient of first vector at quadrature points. */ WorldVector *grad1AtQPs; /** \brief * Second DOFVector whose gradient is evaluated at quadrature points. */ DOFVectorBase* vecGrd2; /** \brief * Gradient of second vector at quadrature points. */ WorldVector *grad2AtQPs; /** \brief * Function for c. */ TertiaryAbstractFunction, WorldVector > *f; }; class VecOfDOFVecsAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecOfDOFVecsAtQP_ZOT(const std::vector*>& dv, AbstractFunction > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * Vector of DOFVectors to be evaluated at quadrature points. */ std::vector*> vecs; /** \brief * Vectors at quadrature points. */ std::vector vecsAtQPs; /** \brief * Function for c. */ AbstractFunction > *f; }; class VecOfGradientsAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecOfGradientsAtQP_ZOT(const std::vector*>& dv, AbstractFunction*> > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * Vector of DOFVectors to be evaluated at quadrature points. */ std::vector*> vecs; /** \brief * Vectors at quadrature points. */ std::vector*> gradsAtQPs; /** \brief * Function for c. */ AbstractFunction*> > *f; }; class VecDivergence_ZOT : public ZeroOrderTerm { public: /// Constructor. VecDivergence_ZOT(int nComponents, DOFVectorBase *vec0, DOFVectorBase *vec1 = NULL, DOFVectorBase *vec2 = NULL); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * Vector of DOFVectors to be evaluated at quadrature points. */ std::vector*> vecs; /** \brief * Vectors at quadrature points. */ std::vector*> gradsAtQPs; }; class VecAndVecOfGradientsAtQP_ZOT : public ZeroOrderTerm { public: /// Constructor. VecAndVecOfGradientsAtQP_ZOT(DOFVector *v, const std::vector*>& dv, BinaryAbstractFunction*> > *af); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /// DOFVector to be evaluated at quadrature points. DOFVector* vec; /// Vector v at quadrature points. double *vecAtQPs; /// Vector of DOFVectors to be evaluated at quadrature points. std::vector*> vecs; /// Vectors at quadrature points. std::vector*> gradsAtQPs; /// Function for c. BinaryAbstractFunction*> > *f; }; class Vec2AndGrad2AtQP_ZOT : public ZeroOrderTerm { public: Vec2AndGrad2AtQP_ZOT(DOFVectorBase *dv1, DOFVectorBase *dv2, QuartAbstractFunction, WorldVector > *af); void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); void getC(const ElInfo *, int nPoints, std::vector &C) const; void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: DOFVectorBase* vec1; DOFVectorBase* vec2; double *vecAtQPs1; double *vecAtQPs2; WorldVector *gradAtQPs1; WorldVector *gradAtQPs2; QuartAbstractFunction,WorldVector > *f; }; class Vec2AndGradVecAtQP_ZOT : public ZeroOrderTerm { public: Vec2AndGradVecAtQP_ZOT(DOFVectorBase *dv1, DOFVectorBase *dv2, DOFVectorBase *dGrd, TertiaryAbstractFunction > *f); void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); void getC(const ElInfo *, int nPoints, std::vector &C) const; void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: DOFVectorBase* vec1; DOFVectorBase* vec2; double *vec1AtQPs; double *vec2AtQPs; DOFVectorBase* vecGrd; WorldVector *gradAtQPs; TertiaryAbstractFunction > *f; }; class General_ZOT : public ZeroOrderTerm { public: /// Constructor. General_ZOT(std::vector*> vecs, std::vector*> grads, TertiaryAbstractFunction, std::vector, std::vector > > *f); /// Implementation of \ref OperatorTerm::initElement(). void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /// Implements ZeroOrderTerm::getC(). void getC(const ElInfo *, int nPoints, std::vector &C) const; /// Implements ZeroOrderTerm::eval(). void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: std::vector*> vecs_; std::vector*> grads_; TertiaryAbstractFunction, std::vector, std::vector > > *f_; WorldVector *coordsAtQPs_; std::vector vecsAtQPs_; std::vector*> gradsAtQPs_; }; class GeneralParametric_ZOT : public ZeroOrderTerm { public: /// Constructor. GeneralParametric_ZOT(std::vector*> vecs, std::vector*> grads, QuartAbstractFunction, WorldVector, std::vector, std::vector > > *f); /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad = NULL); /** \brief * Implements ZeroOrderTerm::getC(). */ void getC(const ElInfo *, int nPoints, std::vector &C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: std::vector*> vecs_; std::vector*> grads_; QuartAbstractFunction, WorldVector, std::vector, std::vector > > *f_; WorldVector *coordsAtQPs_; WorldVector elementNormal_; std::vector vecsAtQPs_; std::vector*> gradsAtQPs_; }; /** \brief * An Operator holds all information needed to assemble the system matrix * and the right hand side. It consists of four OperatorTerm lists each storing * Terms of a specific order and type. You can define your own Operator by * creating an empty Operator and than adding OperatorTerms to it. * An Operator can by of type MATRIX_OPERATOR, if it's used to assemble the * system matrix on the left hand side, or it can be of type VECTOR_OPERATOR, * if it's used to assemble the right hand side vector. If an Operator gives * contributions to both sides of the system it is a MATRIX_OPERATOR and a * VECTOR_OPERATOR in one instance. This allows to efficiently reuse element * matrices once calculated. * By calling \ref getElementMatrix() or \ref getElementVector() one can * initiate the assembling procedure. Therefor each Operator has its own * Assembler, especially created for this Operator, by the first call of * \ref getElementMatrix() or \ref getElementVector(). */ class Operator { public: /** \brief * Constructs an empty Operator of type operatorType for the given * FiniteElemSpace. * The type is given by a Flag that can contain the values MATRIX_OPERATOR, * VECTOR_OPERATOR, or MATRIX_OPERATOR | VECTOR_OPERATOR. This type specifies * whether the Operator is used on the left hand side, the right hand side, * or on both sides of the system. */ Operator(Flag operatorType, const FiniteElemSpace *rowFESpace, const FiniteElemSpace *colFESpace = NULL); /** \brief * Destructor. */ virtual ~Operator() {} /** \brief * Sets \ref optimized. */ inline void useOptimizedAssembler(bool opt) { optimized = opt; } /** \brief * Returns \ref optimized. */ inline bool isOptimized() { return optimized; } /** \brief * Adds a SecondOrderTerm to the Operator */ template void addSecondOrderTerm(T *term); /** \brief * Adds a FirstOrderTerm to the Operator */ template void addFirstOrderTerm(T *term, FirstOrderType type = GRD_PHI); /** \brief * Adds a ZeroOrderTerm to the Operator */ template void addZeroOrderTerm(T *term); /** \brief * Calculates the element matrix for this ElInfo and adds it multiplied by * factor to userMat. */ virtual void getElementMatrix(const ElInfo *elInfo, ElementMatrix& userMat, double factor = 1.0); virtual void getElementMatrix(const ElInfo *rowElInfo, const ElInfo *colElInfo, const ElInfo *smallElInfo, const ElInfo *largeElInfo, ElementMatrix& userMat, double factor = 1.0); /** \brief * Calculates the element vector for this ElInfo and adds it multiplied by * factor to userVec. */ virtual void getElementVector(const ElInfo *elInfo, ElementVector& userVec, double factor = 1.0); virtual void getElementVector(const ElInfo *mainElInfo, const ElInfo *auxElInfo, const ElInfo *smallElInfo, const ElInfo *largeElInfo, ElementVector& userVec, double factor = 1.0); /// That function must be called after one assembling cycle has been finished. void finishAssembling(); /// Returns \ref rowFESpace. inline const FiniteElemSpace *getRowFESpace() { return rowFESpace; } /// Returns \ref colFESpace. inline const FiniteElemSpace *getColFESpace() { return colFESpace; } /// Returns \ref auxFESpaces. inline std::vector getAuxFESpaces() { return auxFESpaces; } /** \brief * Sets \ref uhOld. */ void setUhOld(const DOFVectorBase *uhOld); /** \brief * Returns \ref uhOld. */ inline const DOFVectorBase *getUhOld() { return uhOld; } /// Returns \ref assembler Assembler *getAssembler(int rank); /// Sets \ref assembler void setAssembler(int rank, Assembler *ass); /// Returns whether this is a matrix operator. inline const bool isMatrixOperator() { return type.isSet(MATRIX_OPERATOR); } /// Returns whether this is a vector operator inline const bool isVectorOperator() { return type.isSet(VECTOR_OPERATOR); } /// Sets \ref fillFlag, the flag used for this Operator while mesh traversal. inline void setFillFlag(Flag f) { fillFlag = f; } /// Sets \ref needDualTraverse. void setNeedDualTraverse(bool b) { needDualTraverse = b; } /// Returns \ref fillFlag inline Flag getFillFlag() { return fillFlag; } /// Returns \ref needDualTraverse bool getNeedDualTraverse() { return needDualTraverse; } /// Initialization of the needed SubAssemblers using the given quadratures. void initAssembler(int rank, Quadrature *quad2, Quadrature *quad1GrdPsi, Quadrature *quad1GrdPhi, Quadrature *quad0); /// Calculates the needed quadrature degree for the given order. int getQuadratureDegree(int order, FirstOrderType firstOrderType = GRD_PHI); /// Evaluation of all terms in \ref zeroOrder. void evalZeroOrder(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = zeroOrder[myRank].begin(); termIt != zeroOrder[myRank].end(); ++termIt) (*termIt)->eval(nPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); } /// Evaluation of all terms in \ref firstOrderGrdPsi. void evalFirstOrderGrdPsi(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = firstOrderGrdPsi[myRank].begin(); termIt != firstOrderGrdPsi[myRank].end(); ++termIt) (*termIt)->eval(nPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); } /// Evaluation of all terms in \ref firstOrderGrdPhi. void evalFirstOrderGrdPhi(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = firstOrderGrdPhi[myRank].begin(); termIt != firstOrderGrdPhi[myRank].end(); ++termIt) (*termIt)->eval(nPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); } /// Evaluation of all terms in \ref secondOrder. void evalSecondOrder(int nPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = secondOrder[myRank].begin(); termIt != secondOrder[myRank].end(); ++termIt) (*termIt)->eval(nPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); } /// Weak evaluation of all terms in \ref secondOrder. void weakEvalSecondOrder(int nPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = secondOrder[myRank].begin(); termIt != secondOrder[myRank].end(); ++termIt) static_cast(*termIt)->weakEval(nPoints, grdUhAtQP, result); } /// Calls getLALt() for each term in \ref secondOrder and adds the results to LALt. void getLALt(const ElInfo *elInfo, int nPoints, DimMat **LALt) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = secondOrder[myRank].begin(); termIt != secondOrder[myRank].end(); ++termIt) static_cast(*termIt)->getLALt(elInfo, nPoints, LALt); } /// Calls getLb() for each term in \ref firstOrderGrdPsi and adds the results to Lb. void getLbGrdPsi(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = firstOrderGrdPsi[myRank].begin(); termIt != firstOrderGrdPsi[myRank].end(); ++termIt) static_cast(*termIt)->getLb(elInfo, nPoints, Lb); } /// Calls getLb() for each term in \ref firstOrderGrdPhi and adds the results to Lb. void getLbGrdPhi(const ElInfo *elInfo, int nPoints, VectorOfFixVecs >& Lb) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = firstOrderGrdPhi[myRank].begin(); termIt != firstOrderGrdPhi[myRank].end(); ++termIt) static_cast(*termIt)->getLb(elInfo, nPoints, Lb); } /// Calls getC() for each term in \ref zeroOrder and adds the results to c. void getC(const ElInfo *elInfo, int nPoints, std::vector &c) const { int myRank = omp_get_thread_num(); std::vector::const_iterator termIt; for (termIt = zeroOrder[myRank].begin(); termIt != zeroOrder[myRank].end(); ++termIt) static_cast(*termIt)->getC(elInfo, nPoints, c); } /// Returns true, if there are second order terms. Returns false otherwise. inline bool secondOrderTerms() { return secondOrder[omp_get_thread_num()].size() != 0; } /// Returns true, if there are first order terms (grdPsi). Returns false otherwise. inline bool firstOrderTermsGrdPsi() { return firstOrderGrdPsi[omp_get_thread_num()].size() != 0; } /// Returns true, if there are first order terms (grdPhi). Returns false otherwise. inline bool firstOrderTermsGrdPhi() { return firstOrderGrdPhi[omp_get_thread_num()].size() != 0; } /// Returns true, if there are zero order terms. Returns false otherwise. inline bool zeroOrderTerms() { return zeroOrder[omp_get_thread_num()].size() != 0; } public: /// Constant type flag for matrix operators static const Flag MATRIX_OPERATOR; /// Constant type flag for vector operators static const Flag VECTOR_OPERATOR; protected: /// FiniteElemSpace for matrix rows and element vector const FiniteElemSpace *rowFESpace; /// FiniteElemSpace for matrix columns. Can be equal to \rowFESpace. const FiniteElemSpace *colFESpace; /// List of aux fe spaces, e.g., if a term is multiplied with a DOF vector std::vector auxFESpaces; /// Number of rows in the element matrix int nRow; /// Number of columns in the element matrix int nCol; /// Type of this Operator. Flag type; /// Flag for mesh traversal Flag fillFlag; /// If true, the operator needs a dual traverse over two meshes for assembling. bool needDualTraverse; /** \brief * Calculates the element matrix and/or the element vector. It is * created especially for this Operator, when \ref getElementMatrix() * or \ref getElementVector is called for the first time. */ std::vector assembler; /// List of all second order terms std::vector< std::vector > secondOrder; /// List of all first order terms derived to psi std::vector< std::vector > firstOrderGrdPsi; /// List of all first order terms derived to phi std::vector< std::vector > firstOrderGrdPhi; /// List of all zero order terms std::vector< std::vector > zeroOrder; /** \brief * Pointer to the solution of the last timestep. Can be used if the * Operator is MATRIX_OPERATOR and VECTOR_OPERATOR for a more efficient * assemblage of the element vector when the element matrix was already * computed. */ const DOFVectorBase *uhOld; /// Spezifies whether optimized assemblers are used or not. bool optimized; friend class Assembler; friend class SubAssembler; friend class ZeroOrderAssembler; friend class FirstOrderAssembler; friend class SecondOrderAssembler; }; } #include "Operator.hh" #endif // AMDIS_OPERATOR_H