// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == crystal growth group == // == == // == Stiftung caesar == // == Ludwig-Erhard-Allee 2 == // == 53175 Bonn == // == germany == // == == // ============================================================================ // == == // == http://www.caesar.de/cg/AMDiS == // == == // ============================================================================ /** \file Operator.h */ #ifndef AMDIS_OPERATOR_H #define AMDIS_OPERATOR_H #include #include "FixVec.h" #include "Flag.h" #include "MemoryManager.h" #include "MatrixVector.h" #include "ElInfo.h" #include "AbstractFunction.h" #include "OpenMP.h" namespace AMDiS { class Assembler; class ElInfo; class FiniteElemSpace; class Operator; class SubAssembler; class ElementMatrix; class ElementVector; class Quadrature; template class DOFVectorBase; /** * \ingroup Assembler * \brief * Specifies the type of a FirstOrderTerm */ enum FirstOrderType { GRD_PSI, GRD_PHI }; // ============================================================================ // ===== class OperatorTerm =================================================== // ============================================================================ /** * \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: MEMORY_MANAGED(OperatorTerm); /** \brief * Constructs an OperatorTerm with initially no properties. * degree_ is used to determine the degree of the needed quadrature * for the assemblage. */ OperatorTerm(int degree_) : properties(0), degree(degree_) {}; /** \brief * Destructor. */ virtual ~OperatorTerm() {}; /** \brief * Virtual method. It's called by SubAssembler::initElement() for * each OperatorTerm belonging to this SubAssembler. Here e.g. vectors * and coordinates at quadrature points can be calculated. */ virtual void initElement(const ElInfo*, SubAssembler* , Quadrature *quad= NULL) {}; /** \brief * Specifies whether the matrix of the term is symmetric */ void setSymmetric(bool symm); /** \brief * Returns true, if the term is piecewise constant, returns false otherwise */ inline bool isPWConst() { return (degree == 0); }; /** \brief * Returns true, if the term has a symmetric matrix, * returns false otherwise. */ bool isSymmetric(); /** \brief * Returns \ref degree. */ inline int getDegree() { return degree; }; /** \brief * Evaluation of the OperatorTerm at all quadrature points. */ virtual void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const = 0; protected: /** \brief * Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$. */ static void lalt(const DimVec >& Lambda, const WorldMatrix& matrix, DimMat& LALt, bool symm, double factor); /** \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); /** \brief * Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for A equal to the * identity. */ static void l1lt(const DimVec >& Lambda, DimMat& LALt, double factor); /** \brief * Evaluation of \f$ \Lambda \cdot b\f$. */ static void lb(const DimVec >& Lambda, const WorldVector& b, DimVec& Lb, double factor); /** \brief * Evaluation of \f$ \Lambda \cdot b\f$ if b contains the value 1.0 in * each component. */ static void l1(const DimVec >& Lambda, DimVec& Lb, double factor) { int dim = Lb.getSize() - 1; static const int dimOfWorld = Global::getGeo(WORLD); for (int i = 0; i <= dim; i++) { double val = 0.0; for (int j = 0; j < dimOfWorld; j++) { val += Lambda[i][j]; } val *= factor; Lb[i] += val; } }; protected: /** \brief * Stores the properties of this OperatorTerm */ Flag properties; /** \brief * Polynomial degree of the term. Used to detemine the degree of the * quadrature. */ int degree; /** \brief * Pointer to the Operator this OperatorTerm belongs to. */ Operator* operat; /** \brief * Constant Flag for piecewise constant terms */ static const Flag PW_CONST; /** \brief * Constant Flag for symmetric terms */ static const Flag SYMMETRIC; friend class SubAssembler; friend class ZeroOrderAssembler; friend class FirstOrderAssembler; friend class SecondOrderAssembler; friend class Operator; }; // ============================================================================ // ===== class SecondOrderTerm =============================================== // ============================================================================ /** * \ingroup Assembler * * \brief * Describes the second order terms: \f$ \nabla \cdot A \nabla u(\vec{x}) \f$ */ class SecondOrderTerm : public OperatorTerm { public: /** \brief * Constructor. */ SecondOrderTerm(int deg) : OperatorTerm(deg) {}; /** \brief * Destructor. */ virtual ~SecondOrderTerm() {}; /** \brief * Evaluation of \f$ \Lambda A \Lambda^t \f$ at all quadrature points. */ virtual void getLALt(const ElInfo *elInfo, int numPoints, DimMat **result) const = 0; /** \brief * Evaluation of \f$ A \nabla u(\vec{x}) \f$ at all quadrature points. */ virtual void weakEval(int numPoints, 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: /** \brief * Constructor. */ Laplace_SOT() : SecondOrderTerm(0) { setSymmetric(true); }; /** \brief * Implenetation of SecondOrderTerm::getLALt(). */ inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) { l1lt(Lambda, *(LALt[iq]), 1.0); } }; /** \brief * Implementation of SecondOrderTerm::eval(). */ inline void eval(int numPoints, const double * // uhAtQP , const WorldVector*// grdUhAtQP , const WorldMatrix *D2UhAtQP, double *result, double factor) const { int dow = Global::getGeo(WORLD); if (D2UhAtQP) { for (int iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; for (int i = 0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += factor * resultQP; } } }; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if (grdUhAtQP) { for (int iq = 0; iq < numPoints; 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: /** \brief * Constructor. */ FactorLaplace_SOT(double f) : SecondOrderTerm(0) { factor = new double; *factor = f; setSymmetric(true); }; /** \brief * Constructor. */ FactorLaplace_SOT(double *fptr) : SecondOrderTerm(0), factor(fptr) { setSymmetric(true); }; /** \brief * Implements SecondOrderTerm::getLALt(). */ inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) l1lt(Lambda, *(LALt[iq]), (*factor)); }; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *, const WorldVector *, const WorldMatrix *D2UhAtQP, double *result, double f) const { int i, dow = Global::getGeo(WORLD); int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += resultQP * f * (*factor); } } }; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { int iq; if(grdUhAtQP) { for(iq = 0; iq < numPoints; iq++) { axpy(*factor, grdUhAtQP[iq], result[iq]); } } }; private: /** \brief * 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: /** \brief * Constructor. */ MatrixFct_SOT(DOFVectorBase *dv, AbstractFunction, double> *fct, AbstractFunction, WorldMatrix > *div, bool sym = false) : SecondOrderTerm(fct->getDegree()), vec(dv), matrixFct(fct), divFct(div), symmetric(sym) { setSymmetric(symmetric); }; /** \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 numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVectorBase* vec; /** \brief * Pointer to the values of the DOFVector at quadrature points. */ double* vecAtQPs; /** \brief * Function for A. */ AbstractFunction, double>* matrixFct; AbstractFunction, WorldMatrix >* divFct; /** \brief * 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: /** \brief * Constructor */ Matrix_SOT(WorldMatrix mat) : SecondOrderTerm(0), matrix(mat) { symmetric = matrix.isSymmetric(); setSymmetric(symmetric); }; /** \brief * Implements SecondOrderTerm::getLALt(). */ inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const{ const DimVec >& Lambda = elInfo->getGrdLambda(); //double det = elInfo->getDet(); int iq; for(iq = 0; iq < numPoints; iq++) lalt(Lambda, matrix, *(LALt[iq]), symmetric, 1.0); }; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const; protected: /** \brief * Matrix stroring A. */ WorldMatrix matrix; /** \brief * 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: /** \brief * 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); }; /** \brief * Constructor. */ FactorIJ_SOT(int x_i, int x_j, double *fptr) : SecondOrderTerm(0), xi(x_i), xj(x_j), factor(fptr) { setSymmetric(xi == xj); }; /** \brief * Implements SecondOrderTerm::getLALt(). */ inline void getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) lalt_kl(Lambda, xi, xj, *(LALt[iq]), (*factor)); }; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *, const WorldVector *, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { result[iq] += (*factor) * D2UhAtQP[iq][xi][xj] * fac; } } }; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; 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: /** \brief * Constructor. */ VecAtQP_SOT(DOFVectorBase *dv, AbstractFunction *f_) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) { 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 numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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; }; // ============================================================================ /** * \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: /** \brief * Constructor. */ CoordsAtQP_SOT(AbstractFunction > *g_) : SecondOrderTerm(g_->getDegree()), g(g_) { 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 numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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: /** \brief * Constructor. */ MatrixGradient_SOT(DOFVectorBase *dv, AbstractFunction, WorldVector > *f_, AbstractFunction, WorldMatrix > *divFct_, bool symm = false) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_), divFct(divFct_), symmetric(symm) { setSymmetric(symmetric); }; /** \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 numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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: /** \brief * Constructor. */ FctGradient_SOT(DOFVectorBase *dv, AbstractFunction > *f_) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) { }; /** \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 numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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; }; // Ergaenzung Andreas // ============================================================================ /** * \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: /** \brief * Constructor. */ VecAndGradientAtQP_SOT(DOFVectorBase *dv, BinaryAbstractFunction > *f_) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) { }; /** \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 numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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$ f(\nabla v(\vec{x})) \Delta u(\vec{x}) \f$ */ class VecGradCoordsAtQP_SOT : public SecondOrderTerm { public: /** \brief * Constructor. */ VecGradCoordsAtQP_SOT(DOFVectorBase *dv, TertiaryAbstractFunction, WorldVector > *f_) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) { }; /** \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 numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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: /** \brief * Constructor. */ VecAndCoordsAtQP_SOT(DOFVectorBase *dv, BinaryAbstractFunction > *f_) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) { setSymmetric(true); }; /** \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 numPoints, DimMat **LALt) const; void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; void weakEval(int numPoints, 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: /** \brief * Constructor. */ MatrixGradientAndCoords_SOT(DOFVectorBase *dv, BinaryAbstractFunction, WorldVector , WorldVector > *f_, AbstractFunction, WorldMatrix > *divFct_, bool symm = false) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_), divFct(divFct_), symmetric(symm) { setSymmetric(symmetric); }; /** \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 numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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; }; // Ende Andreas Ergaenzung // ============================================================================ class General_SOT : public SecondOrderTerm { public: General_SOT(::std::vector*> vecs, ::std::vector*> grads, TertiaryAbstractFunction, WorldVector, ::std::vector, ::std::vector > > *f, AbstractFunction, WorldMatrix > *divFct, bool symmetric) : SecondOrderTerm(f->getDegree()), vecs_(vecs), grads_(grads), f_(f), divFct_(divFct), symmetric_(symmetric) { vecsAtQPs_.resize(vecs_.size()); gradsAtQPs_.resize(grads_.size()); }; /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo*, SubAssembler* , Quadrature *quad= NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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: GeneralParametric_SOT(::std::vector*> vecs, ::std::vector*> grads, QuartAbstractFunction, WorldVector, WorldVector, ::std::vector, ::std::vector > > *f, AbstractFunction, WorldMatrix > *divFct, bool symmetric) : SecondOrderTerm(f->getDegree()), vecs_(vecs), grads_(grads), f_(f), divFct_(divFct), symmetric_(symmetric) { vecsAtQPs_.resize(vecs_.size()); gradsAtQPs_.resize(grads_.size()); }; /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo*, SubAssembler* , Quadrature *quad= NULL); /** \brief * Implements SecondOrderTerm::getLALt(). */ void getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const; /** \brief * Implenetation of SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implenetation of SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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: /** \brief * Constructor. */ FirstOrderTerm(int deg) : OperatorTerm(deg) {}; /** \brief * Destructor. */ virtual ~FirstOrderTerm() {}; /** \brief * Evaluation of \f$ \Lambda b \f$. */ virtual void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& result) const = 0; /** \brief * Implenetation of FirstOrderTerm::eval(). */ void eval(int numPoints, const double *, const WorldVector *grdUhAtQP, const WorldMatrix *, double *result, double factor) const { int dow = Global::getGeo(WORLD); if (grdUhAtQP) { for (int iq = 0; iq < numPoints; 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: /** \brief * Constructor. */ Simple_FOT() : FirstOrderTerm(0) {}; /** \brief * Implements FirstOrderTerm::getLb(). */ inline void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; 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: /** \brief * Constructors. */ FactorSimple_FOT(double f) : FirstOrderTerm(0) { factor = NEW double; *factor = f; }; FactorSimple_FOT(double *fptr) : FirstOrderTerm(0), factor(fptr) {}; /** \brief * Implements FirstOrderTerm::getLb(). */ inline void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; 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: /** \brief * Constructor. */ Vector_FOT(WorldVector b_) : FirstOrderTerm(0), b(b_) { }; /** \brief * Implements FirstOrderTerm::getLb(). */ inline void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >&Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) { lb(Lambda, b, Lb[iq], 1.0); } }; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int numPoints, const double *, const WorldVector *grdUhAtQP, const WorldMatrix *, double *result, double factor) const { if (grdUhAtQP) { for(int iq = 0; iq < numPoints; iq++) { result[iq] += b * grdUhAtQP[iq] * factor; } } }; protected: /** \brief * 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: /** \brief * Constructor. */ VecAtQP_FOT(DOFVectorBase *dv, AbstractFunction *f_, WorldVector *b_) : FirstOrderTerm(f_->getDegree()), vec(dv), f(f_), b(b_) { }; /** \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 numPoints, VectorOfFixVecs >& Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int numPoints, 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 * v at quadrature points. */ double *vecAtQPs; /** \brief * Function f. */ AbstractFunction *f; /** */ WorldVector *b; }; // ============================================================================ /** * \ingroup Assembler * * \brief * Simple_FOT multiplied with \f$ f(\vec{x}) \f$. */ class CoordsAtQP_FOT : public FirstOrderTerm { public: /** \brief * Constructor. */ CoordsAtQP_FOT(AbstractFunction > *g_) : FirstOrderTerm(g_->getDegree()), g(g_) { }; /** \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 numPoints,VectorOfFixVecs >&Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecCoordsAtQP_FOT(AbstractFunction > *g_, WorldVector b_) : FirstOrderTerm(g_->getDegree()), g(g_), b(b_) {}; /** \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 numPoints,VectorOfFixVecs >& Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VectorGradient_FOT(DOFVectorBase *dv, AbstractFunction, WorldVector > *f_) : FirstOrderTerm(f_->getDegree()), vec(dv), f(f_) { }; /** \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 numPoints, VectorOfFixVecs >& Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VectorFct_FOT(DOFVectorBase *dv, AbstractFunction, double> *vecFct_) : FirstOrderTerm(vecFct_->getDegree()), vec(dv), vecFct(vecFct_) { }; /** \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 numPoints, 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: /** \brief * Constructor. */ VecFctAtQP_FOT(AbstractFunction, WorldVector > *g_) : FirstOrderTerm(g_->getDegree()), g(g_) { }; /** \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 numPoints,VectorOfFixVecs >&Lb) const; /** \brief * Implements FirstOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecGrad_FOT(DOFVectorBase *dv1, DOFVectorBase *dv2, BinaryAbstractFunction, double, WorldVector > *vecFct_) : FirstOrderTerm(vecFct_->getDegree()), vec1(dv1), vec2(dv2), vecFct(vecFct_) {}; /** \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 numPoints, 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; }; // ============================================================================ class General_FOT : public FirstOrderTerm { public: /** /brief * Constructor */ General_FOT(::std::vector*> vecs, ::std::vector*> grads, TertiaryAbstractFunction, WorldVector, ::std::vector, ::std::vector > > *f) : FirstOrderTerm(f->getDegree()), vecs_(vecs), grads_(grads), f_(f) { vecsAtQPs_.resize(vecs_.size()); gradsAtQPs_.resize(grads_.size()); }; /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo*, SubAssembler* , Quadrature *quad= NULL); /** \brief * Implements FirstOrderTerm::getLb(). */ void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& result) const; /** \brief * Implenetation of FirstOrderTerm::eval(). */ void eval(int numPoints, 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: /** /brief * Constructor */ GeneralParametric_FOT(::std::vector*> vecs, ::std::vector*> grads, QuartAbstractFunction, WorldVector, WorldVector, ::std::vector, ::std::vector > > *f) : FirstOrderTerm(f->getDegree()), vecs_(vecs), grads_(grads), f_(f) { vecsAtQPs_.resize(vecs_.size()); gradsAtQPs_.resize(grads_.size()); }; /** \brief * Implementation of \ref OperatorTerm::initElement(). */ void initElement(const ElInfo*, SubAssembler* , Quadrature *quad= NULL); /** \brief * Implements FirstOrderTerm::getLb(). */ void getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& result) const; /** \brief * Implenetation of FirstOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ ZeroOrderTerm(int deg) : OperatorTerm(deg) {}; /** \brief * Destructor. */ virtual ~ZeroOrderTerm() {}; /** \brief * Evaluates \f$ c \f$ */ virtual void getC(const ElInfo *elInfo, int numPoints, double *result) const = 0; }; // ============================================================================ /** * \ingroup Assembler * * \brief * Simple zero order term */ class Simple_ZOT : public ZeroOrderTerm { public: /** \brief * Constructor. */ Simple_ZOT(double f = 1.0) : ZeroOrderTerm(0), factor(f) {}; /** \brief * Implements ZeroOrderTerm::getC(). */ inline void getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += factor; } }; /** \brief * Implements ZeroOrderTerm::eval(). */ inline void eval(int numPoints, const double *uhAtQP, const WorldVector *, const WorldMatrix *, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * factor * uhAtQP[iq]; } }; protected: /** \brief * 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: /** \brief * Constructor. */ VecAtQP_ZOT(DOFVectorBase *dv, AbstractFunction *f_) : ZeroOrderTerm(f_ ? f_->getDegree() : 0), vec(dv), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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 * Function for c. */ AbstractFunction *f; }; // Andreas ergaenzt: /** * \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: /** \brief * Constructor. */ MultVecAtQP_ZOT(DOFVectorBase *dv1, DOFVectorBase *dv2, AbstractFunction *f1_, AbstractFunction *f2_) : ZeroOrderTerm(f1->getDegree()+f2_->getDegree()), vec1(dv1), vec2(dv2), f1(f1_), f2(f2_) { }; /** \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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ Vec2AtQP_ZOT(DOFVectorBase *dv1, DOFVectorBase *dv2, BinaryAbstractFunction *f_) : ZeroOrderTerm(f_->getDegree()), vec1(dv1), vec2(dv2), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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 * Function for c. */ BinaryAbstractFunction *f; }; // ============================================================================ /** * \ingroup Assembler * * \brief * */ class FctGradientCoords_ZOT : public ZeroOrderTerm { public: /** \brief * Constructor. */ FctGradientCoords_ZOT(DOFVectorBase *dv, BinaryAbstractFunction, WorldVector > *f_) : ZeroOrderTerm(f_->getDegree()), vec(dv), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecGradCoordsAtQP_ZOT(DOFVectorBase *dv, TertiaryAbstractFunction, WorldVector > *f_) : ZeroOrderTerm(f_->getDegree()), vec(dv), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecAndCoordsAtQP_ZOT(DOFVectorBase *dv, BinaryAbstractFunction > *f_) : ZeroOrderTerm(f_->getDegree()), vec(dv), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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; }; // Ende Andreas Ergaenzungen // ============================================================================ /** * \ingroup Assembler * * \brief * */ class FctGradient_ZOT : public ZeroOrderTerm { public: /** \brief * Constructor. */ FctGradient_ZOT(DOFVectorBase *dv, AbstractFunction > *f_) : ZeroOrderTerm(f_->getDegree()), vec(dv), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecAndGradAtQP_ZOT(DOFVectorBase *dv, BinaryAbstractFunction > *f_) : ZeroOrderTerm(f_->getDegree()), vec(dv), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecAndGradAtQP_SOT(DOFVectorBase *dv, BinaryAbstractFunction > *f_) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_) { }; /** \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 numPoints, DimMat **LALt) const; /** \brief * Implements SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implements SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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 * Zero order term: \f$ f(\vec{x}) u(\vec{x})\f$ */ class CoordsAtQP_ZOT : public ZeroOrderTerm { public: /** \brief * Constructor. */ CoordsAtQP_ZOT(AbstractFunction > *g_) : ZeroOrderTerm(g_->getDegree()), g(g_) {}; /** \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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ CoordsAtQP_IJ_SOT(AbstractFunction > *g_, int x_i, int x_j) : SecondOrderTerm(g_->getDegree()), g(g_), 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 numPoints, DimMat **LALt) const; /** \brief * Implements SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implements SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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: /** \brief * Constructor. */ VecAtQP_IJ_SOT(DOFVectorBase *dv, AbstractFunction *f_, int x_i, int x_j) : SecondOrderTerm(f_->getDegree()), vec(dv), f(f_), 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(). */ void getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const; /** \brief * Implements SecondOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const; /** \brief * Implements SecondOrderTerm::weakEval(). */ void weakEval(int numPoints, 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: /** \brief * Constructor. */ VecAndGradVecAtQP_ZOT(DOFVectorBase *dv, DOFVectorBase *dGrd, BinaryAbstractFunction > *f_) : ZeroOrderTerm(f_->getDegree()), vec(dv), vecGrd(dGrd), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecAndGradVec2AtQP_ZOT(DOFVectorBase *dv, DOFVectorBase *dGrd1, DOFVectorBase *dGrd2, TertiaryAbstractFunction, WorldVector > *f_) : ZeroOrderTerm(f_->getDegree()), vec(dv), vecGrd1(dGrd1), vecGrd2(dGrd2), f(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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecOfDOFVecsAtQP_ZOT(const ::std::vector*>& dv, AbstractFunction > *f_) : ZeroOrderTerm(f_->getDegree()), vecs(dv), f(f_) { vecsAtQPs.resize(vecs.size()); }; /** \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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecOfGradientsAtQP_ZOT(const ::std::vector*>& dv, AbstractFunction*> > *f_) : ZeroOrderTerm(f_->getDegree()), vecs(dv), f(f_) { gradsAtQPs.resize(vecs.size()); }; /** \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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecDivergence_ZOT(int numComponents, DOFVectorBase *vec0, DOFVectorBase *vec1 = NULL, DOFVectorBase *vec2 = NULL) : ZeroOrderTerm(0) { vecs.resize(numComponents); gradsAtQPs.resize(numComponents); vecs[0] = vec0; vecs[1] = vec1; vecs[2] = vec2; }; /** \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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ VecAndVecOfGradientsAtQP_ZOT(DOFVector *vec_, const std::vector*>& dv, BinaryAbstractFunction*> > *f_) : ZeroOrderTerm(f_->getDegree()), vec(vec_), vecs(dv), f(f_) { gradsAtQPs.resize(vecs.size()); }; /** \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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const; protected: /** \brief * DOFVector to be evaluated at quadrature points. */ DOFVector* vec; /** \brief * Vector v at quadrature points. */ double *vecAtQPs; /** \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. */ BinaryAbstractFunction*> > *f; }; // ============================================================================ class General_ZOT : public ZeroOrderTerm { public: /** \brief * Constructor. */ General_ZOT(::std::vector*> vecs, ::std::vector*> grads, TertiaryAbstractFunction, ::std::vector, ::std::vector > > *f) : ZeroOrderTerm(f->getDegree()), vecs_(vecs), grads_(grads), f_(f) { vecsAtQPs_.resize(vecs_.size()); gradsAtQPs_.resize(grads_.size()); }; /** \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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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: /** \brief * Constructor. */ GeneralParametric_ZOT(::std::vector*> vecs, ::std::vector*> grads, QuartAbstractFunction, WorldVector, ::std::vector, ::std::vector > > *f) : ZeroOrderTerm(f->getDegree()), vecs_(vecs), grads_(grads), f_(f) { vecsAtQPs_.resize(vecs_.size()); gradsAtQPs_.resize(grads_.size()); }; /** \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 numPoints, double *C) const; /** \brief * Implements ZeroOrderTerm::eval(). */ void eval(int numPoints, 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_; }; /*****************************************************************************/ /****** Operators for the least-square finite element method *******/ /*****************************************************************************/ // ============================================================================ // ===== class Operator ======================================================= // ============================================================================ /** \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: MEMORY_MANAGED(Operator); /** \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); /** \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); /** \brief * Returns \ref rowFESpace */ inline const FiniteElemSpace *getRowFESpace() { return rowFESpace; }; /** \brief * Returns \ref colFESpace */ inline const FiniteElemSpace *getColFESpace() { return colFESpace; }; /** \brief * Sets \ref uhOld. */ void setUhOld(const DOFVectorBase *uhOld); /** \brief * Returns \ref uhOld. */ inline const DOFVectorBase *getUhOld() { return uhOld; }; /** \brief * Returns \ref assembler */ Assembler *getAssembler(int rank); /** \brief * Sets \ref assembler */ void setAssembler(int rank, Assembler *ass); /** \brief * Returns whether this is a matrix operator. */ inline const bool isMatrixOperator() { return type.isSet(MATRIX_OPERATOR); }; /** \brief * Returns whether this is a vector operator */ inline const bool isVectorOperator() { return type.isSet(VECTOR_OPERATOR); }; /** \brief * Sets \ref fillFlag, the flag used for this Operator while mesh traversal. */ inline void setFillFlag(Flag f) { fillFlag = f; }; /** \brief * Returns \ref fillFlag */ inline Flag getFillFlag() { return fillFlag; }; /** \brief * Initialization of the needed SubAssemblers using the given quadratures. */ void initAssembler(int rank, Quadrature *quad2, Quadrature *quad1GrdPsi, Quadrature *quad1GrdPhi, Quadrature *quad0); /** \brief * Calculates the needed quadrature degree for the given order. */ int getQuadratureDegree(int order, FirstOrderType firstOrderType = GRD_PHI); /** \brief * Evaluation of all terms in \ref zeroOrder. */ void evalZeroOrder(int numPoints, 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(numPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); } }; /** \brief * Evaluation of all terms in \ref firstOrderGrdPsi. */ void evalFirstOrderGrdPsi(int numPoints, 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(numPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); } }; /** \brief * Evaluation of all terms in \ref firstOrderGrdPhi. */ void evalFirstOrderGrdPhi(int numPoints, 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(numPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); } }; /** \brief * Evaluation of all terms in \ref secondOrder. */ void evalSecondOrder(int numPoints, 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(numPoints, uhAtQP, grdUhAtQP, D2UhAtQP, result, factor); } }; /** \brief * Weak evaluation of all terms in \ref secondOrder. */ void weakEvalSecondOrder(int numPoints, 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(numPoints, grdUhAtQP, result); } }; /** \brief * Calls getLALt() for each term in \ref secondOrder * and adds the results to LALt. */ void getLALt(const ElInfo *elInfo, int numPoints, 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, numPoints, LALt); } }; /** \brief * Calls getLb() for each term in \ref firstOrderGrdPsi * and adds the results to Lb. */ void getLbGrdPsi(const ElInfo *elInfo, int numPoints, 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, numPoints, Lb); } }; /** \brief * Calls getLb() for each term in \ref firstOrderGrdPhi * and adds the results to Lb. */ void getLbGrdPhi(const ElInfo *elInfo, int numPoints, 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, numPoints, Lb); } }; /** \brief * Calls getC() for each term in \ref zeroOrder * and adds the results to c. */ void getC(const ElInfo *elInfo, int numPoints, double *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, numPoints, c); } }; /** \brief * Returns true, if there are second order terms. Returns false otherwise. */ inline bool secondOrderTerms() { return secondOrder[omp_get_thread_num()].size() != 0; }; /** \brief * Returns true, if there are first order terms (grdPsi). * Returns false otherwise. */ inline bool firstOrderTermsGrdPsi() { return firstOrderGrdPsi[omp_get_thread_num()].size() != 0; }; /** \brief * Returns true, if there are first order terms (grdPhi). * Returns false otherwise. */ inline bool firstOrderTermsGrdPhi() { return firstOrderGrdPhi[omp_get_thread_num()].size() != 0; }; /** \brief * Returns true, if there are zero order terms. * Returns false otherwise. */ inline bool zeroOrderTerms() { return zeroOrder[omp_get_thread_num()].size() != 0; }; public: /** \brief * Constant type flag for matrix operators */ static const Flag MATRIX_OPERATOR; /** \brief * Constant type flag for vector operators */ static const Flag VECTOR_OPERATOR; protected: /** \brief * FiniteElemSpace for matrix rows and element vector */ const FiniteElemSpace *rowFESpace; /** \brief * FiniteElemSpace for matrix columns. Can be equal to \rowFESpace. */ const FiniteElemSpace *colFESpace; /** \brief * Number of rows in the element matrix */ int nRow; /** \brief * Number of columns in the element matrix */ int nCol; /** \brief * Type of this Operator. */ Flag type; /** \brief * Flag for mesh traversal */ Flag fillFlag; /** \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; /** \brief * List of all second order terms */ ::std::vector< ::std::vector > secondOrder; /** \brief * List of all first order terms derived to psi */ ::std::vector< ::std::vector > firstOrderGrdPsi; /** \brief * List of all first order terms derived to phi */ ::std::vector< ::std::vector > firstOrderGrdPhi; /** \brief * 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; /** \brief * 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