#include "Operator.h" #include "ElInfo.h" #include "Assembler.h" #include "FixVec.h" #include "DOFVector.h" #include "ElementMatrix.h" #include "ElementVector.h" #include "Quadrature.h" #include "OpenMP.h" namespace AMDiS { const Flag OperatorTerm::PW_CONST = 1; const Flag OperatorTerm::SYMMETRIC = 2; const Flag Operator::MATRIX_OPERATOR = 1; const Flag Operator::VECTOR_OPERATOR = 2; int Operator::getQuadratureDegree(int order, FirstOrderType firstOrderType) { ::std::vector* terms = NULL; int myRank = omp_get_thread_num(); switch(order) { case 0: terms = &zeroOrder[myRank]; break; case 1: if (firstOrderType == GRD_PHI) terms = &firstOrderGrdPhi[myRank]; else terms = &firstOrderGrdPsi[myRank]; break; case 2: terms = &secondOrder[myRank]; break; } const BasisFunction *psi = rowFESpace->getBasisFcts(); const BasisFunction *phi = colFESpace->getBasisFcts(); int psiDegree = psi->getDegree(); int phiDegree = phi->getDegree(); int maxTermDegree = 0; for (int i = 0; i < static_cast( terms->size()); i++) { OperatorTerm *term = (*terms)[i]; maxTermDegree = max(maxTermDegree, term->degree); } return psiDegree + phiDegree - order + maxTermDegree; } void OperatorTerm::setSymmetric(bool symm) { if (symm) { properties.setFlag(SYMMETRIC); } else { properties.unsetFlag(SYMMETRIC); } } bool OperatorTerm::isSymmetric() { return properties.isSet(SYMMETRIC); } void OperatorTerm::lalt(const DimVec >& Lambda, const WorldMatrix& matrix, DimMat& LALt, bool symm, double factor) { int i, j, k, l; static const int dimOfWorld = Global::getGeo(WORLD); int dim = LALt.getNumRows() - 1; double val = 0.0; if (symm) { for (i = 0; i <= dim; i++) { val = 0.0; for (k = 0; k < dimOfWorld; k++) for (l = 0; l < dimOfWorld; l++) val += Lambda[i][k] * matrix[k][l] * Lambda[i][l]; val *= factor; LALt[i][i] += val; for (j = i+1; j <= dim; j++) { val = 0.0; for (k = 0; k < dimOfWorld; k++) for (l = 0; l < dimOfWorld; l++) val += Lambda[i][k] * matrix[k][l] * Lambda[j][l]; val *= factor; LALt[i][j] += val; LALt[j][i] += val; } } } else { for (i = 0; i <= dim; i++) { for (j = 0; j <= dim; j++) { val = 0.0; for (k = 0; k < dimOfWorld; k++) for (l = 0; l < dimOfWorld; l++) val += Lambda[i][k] * matrix[k][l] * Lambda[j][l]; val *= factor; LALt[i][j] += val; } } } } void OperatorTerm::lalt_kl(const DimVec >& Lambda, int k, int l, DimMat& LALt, double factor) { int i, j; int dim = LALt.getNumRows() - 1; for (i = 0; i <= dim; i++) for (j = 0; j <= dim; j++) LALt[i][j] += factor * Lambda[i][k] * Lambda[j][l]; } void OperatorTerm::l1lt(const DimVec >& Lambda, DimMat& LALt, double factor) { static const int dimOfWorld = Global::getGeo(WORLD); int dim = LALt.getNumRows() - 1; double val = 0.0; for (int i = 0; i <= dim; i++) { val = 0.0; for (int k = 0; k < dimOfWorld; k++) val += Lambda[i][k] * Lambda[i][k]; val *= factor; LALt[i][i] += val; for (int j = i + 1; j <= dim; j++) { val = 0.0; for (int k = 0; k < dimOfWorld; k++) val += Lambda[i][k] * Lambda[j][k]; val *= factor; LALt[i][j] += val; LALt[j][i] += val; } } } void OperatorTerm::lb(const DimVec >& Lambda, const WorldVector& b, DimVec& Lb, double factor) { int i, j; int dim = Lb.getSize() - 1; static const int dimOfWorld = Global::getGeo(WORLD); double val = 0.0; for (i = 0; i <= dim; i++) { for (val = j = 0; j < dimOfWorld; j++) val += Lambda[i][j] * b[j]; val *= factor; Lb[i] += val; } } Operator::Operator(Flag operatorType, const FiniteElemSpace *rowFESpace_, const FiniteElemSpace *colFESpace_) : rowFESpace(rowFESpace_), colFESpace(colFESpace_ ? colFESpace_ : rowFESpace_), type(operatorType), fillFlag(Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA), uhOld(NULL), optimized(true) { int maxThreads = omp_get_max_threads(); assembler.resize(maxThreads); secondOrder.resize(maxThreads); firstOrderGrdPsi.resize(maxThreads); firstOrderGrdPhi.resize(maxThreads); zeroOrder.resize(maxThreads); for (int i = 0; i < maxThreads; i++) { assembler[i] = NULL; secondOrder[i].resize(0); firstOrderGrdPsi[i].resize(0); firstOrderGrdPhi[i].resize(0); zeroOrder[i].resize(0); } nRow = rowFESpace->getBasisFcts()->getNumber(); nCol = colFESpace->getBasisFcts()->getNumber(); }; void Operator::setUhOld(const DOFVectorBase *uhOld_) { uhOld = uhOld_; } void Operator::getElementMatrix(const ElInfo *elInfo, ElementMatrix *userMat, double factor) { int myRank = omp_get_thread_num(); if (!assembler[myRank]) { initAssembler(myRank, NULL, NULL, NULL, NULL); } assembler[myRank]->calculateElementMatrix(elInfo, userMat, factor); } void Operator::getElementVector(const ElInfo *elInfo, ElementVector *userVec, double factor) { int myRank = omp_get_thread_num(); if (!assembler[myRank]) { initAssembler(myRank, NULL, NULL, NULL, NULL); } assembler[myRank]->calculateElementVector(elInfo, userVec, factor); } void Operator::initAssembler(int rank, Quadrature *quad2, Quadrature *quad1GrdPsi, Quadrature *quad1GrdPhi, Quadrature *quad0) { if (!assembler[rank]) if (optimized) { assembler[rank] = NEW OptimizedAssembler(this, quad2, quad1GrdPsi, quad1GrdPhi, quad0, rowFESpace, colFESpace); } else { assembler[rank] = NEW StandardAssembler(this, quad2, quad1GrdPsi, quad1GrdPhi, quad0, rowFESpace, colFESpace); } } void MatrixFct_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); } void VecAtQP_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); } void CoordsAtQP_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void MatrixGradient_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); } void FctGradient_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); } void VecAndGradientAtQP_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); } void VecAndCoordsAtQP_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void MatrixGradientAndCoords_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void VecGradCoordsAtQP_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void VecAtQP_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); } void CoordsAtQP_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void VecCoordsAtQP_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void VectorGradient_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); } void VectorFct_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); } void VecFctAtQP_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void VecAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); } void MultVecAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs1 = subAssembler->getVectorAtQPs(vec1, elInfo, quad); vecAtQPs2 = subAssembler->getVectorAtQPs(vec2, elInfo, quad); } void Vec2AtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs1 = subAssembler->getVectorAtQPs(vec1, elInfo, quad); vecAtQPs2 = subAssembler->getVectorAtQPs(vec2, elInfo, quad); } void VecAndCoordsAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void FctGradientCoords_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void VecGradCoordsAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void VecAndGradAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); } void VecAndGradVecAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); gradAtQPs = subAssembler->getGradientsAtQPs(vecGrd, elInfo, quad); } void VecAndGradVec2AtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); grad1AtQPs = subAssembler->getGradientsAtQPs(vecGrd1, elInfo, quad); grad2AtQPs = subAssembler->getGradientsAtQPs(vecGrd2, elInfo, quad); } void FctGradient_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); } void CoordsAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void MatrixFct_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) { lalt(Lambda, (*matrixFct)(vecAtQPs[iq]), *(LALt[iq]), symmetric, 1.0); } } void VecAtQP_SOT::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]), (*f)(vecAtQPs[iq])); } } void CoordsAtQP_SOT::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]), (*g)(coordsAtQPs[iq])); } } void MatrixGradient_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) { lalt(Lambda, (*f)(gradAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); } } void FctGradient_SOT::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]), (*f)(gradAtQPs[iq])); } } void VecAndGradientAtQP_SOT::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]), (*f)(vecAtQPs[iq], gradAtQPs[iq])); } } void VecAndCoordsAtQP_SOT::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]), (*f)(vecAtQPs[iq], coordsAtQPs[iq])); } } void MatrixGradientAndCoords_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) { lalt(Lambda, (*f)(gradAtQPs[iq], coordsAtQPs[iq]), (*LALt[iq]), symmetric, 1.0); } } void VecGradCoordsAtQP_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) { l1lt(Lambda, *(LALt[iq]), (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq])); } } void VecAtQP_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) { if(b) lb(Lambda, *b, Lb[iq], (*f)(vecAtQPs[iq])); else l1(Lambda, Lb[iq], (*f)(vecAtQPs[iq])); } } void CoordsAtQP_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) { l1(Lambda, Lb[iq], (*g)(coordsAtQPs[iq])); } } void VecCoordsAtQP_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) { lb(Lambda, b, Lb[iq], (*g)(coordsAtQPs[iq])); } } void VectorGradient_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; if(f) { for(iq = 0; iq < numPoints; iq++) { lb(Lambda, (*f)(gradAtQPs[iq]), Lb[iq], 1.0); } } else { for(iq = 0; iq < numPoints; iq++) { lb(Lambda, gradAtQPs[iq], Lb[iq], 1.0); } } } void VectorFct_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) { lb(Lambda, (*vecFct)(vecAtQPs[iq]), Lb[iq], 1.0); } } void VecFctAtQP_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); int iq; for(iq = 0; iq < numPoints; iq++) { lb(Lambda, (*g)(coordsAtQPs[iq]), Lb[iq], 1.0); } } void VecAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { if (f) { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(vecAtQPs[iq]); } } else { for (int iq = 0; iq < numPoints; iq++) { C[iq] += vecAtQPs[iq]; } } } void VecAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(vecAtQPs[iq]) * uhAtQP[iq]; } } void MultVecAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f1)(vecAtQPs1[iq]) * (*f2)(vecAtQPs2[iq]); } } void MultVecAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f1)(vecAtQPs1[iq]) * (*f2)(vecAtQPs2[iq]) * uhAtQP[iq]; } } void Vec2AtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(vecAtQPs1[iq], vecAtQPs2[iq]); } } void Vec2AtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(vecAtQPs1[iq], vecAtQPs2[iq]) * uhAtQP[iq]; } } void VecAndCoordsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(vecAtQPs[iq], coordsAtQPs[iq]); } } void VecAndCoordsAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(vecAtQPs[iq], coordsAtQPs[iq]) * uhAtQP[iq]; } } void FctGradientCoords_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(gradAtQPs[iq], coordsAtQPs[iq]); } } void FctGradientCoords_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(gradAtQPs[iq], coordsAtQPs[iq]) * uhAtQP[iq]; } } void VecGradCoordsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); } } void VecGradCoordsAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]) * uhAtQP[iq]; } } // bis hierhin void VecAndGradAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq]); } } void VecAndGradAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(vecAtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq]; } } void VecAndGradVecAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(vecAtQPs[iq], gradAtQPs[iq]); } } void VecAndGradVecAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(vecAtQPs[iq], gradAtQPs[iq]) * uhAtQP[iq]; } } void VecAndGradVec2AtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(vecAtQPs[iq], grad1AtQPs[iq], grad2AtQPs[iq]); } } void VecAndGradVec2AtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(vecAtQPs[iq], grad1AtQPs[iq], grad2AtQPs[iq]) * uhAtQP[iq]; } } void FctGradient_ZOT::getC(const ElInfo *, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*f)(gradAtQPs[iq]); } } void FctGradient_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { for (int iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*f)(gradAtQPs[iq]) * uhAtQP[iq]; } } void CoordsAtQP_ZOT::getC(const ElInfo *elInfo, int numPoints, double *C) const { for (int iq = 0; iq < numPoints; iq++) { C[iq] += (*g)(coordsAtQPs[iq]); } } void CoordsAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { for (int iq = 0; iq < numPoints; iq++) { result[iq] += fac * (*g)(coordsAtQPs[iq]) * uhAtQP[iq]; } } void MatrixFct_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int i, j, dow = Global::getGeo(WORLD); int iq; for(iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; WorldMatrix A = (*matrixFct)(vecAtQPs[iq]); if(D2UhAtQP) { for(i=0; i < dow; i++) { for(j=0; j < dow; j++) { resultQP += A[i][j] * D2UhAtQP[iq][j][i]; } } } if(grdUhAtQP) { resultQP += (*divFct)(A) * grdUhAtQP[iq]; } result[iq] += resultQP * factor; } } void MatrixFct_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { int iq; if(grdUhAtQP) { WorldMatrix A; for(iq = 0; iq < numPoints; iq++) { A = (*matrixFct)(vecAtQPs[iq]); result[iq] += A * grdUhAtQP[iq]; } } } void Matrix_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int i, j, dow = Global::getGeo(WORLD); int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; for(i=0; i < dow; i++) { for(j=0; j < dow; j++) { resultQP += matrix[i][j] * D2UhAtQP[iq][j][i]; } } result[iq] += resultQP * factor; } } } void Matrix_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { result[iq] += matrix * grdUhAtQP[iq]; } } } void MatrixGradient_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int i, j, dow = Global::getGeo(WORLD); int iq; for(iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; WorldMatrix A = (*f)(gradAtQPs[iq]); if(D2UhAtQP) { for(i=0; i < dow; i++) { for(j=0; j < dow; j++) { resultQP += A[i][j] * D2UhAtQP[iq][j][i]; } } } if(grdUhAtQP) { resultQP += (*divFct)(A) * grdUhAtQP[iq]; } result[iq] += resultQP * factor; } }; void MatrixGradient_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; WorldMatrix A; for(iq = 0; iq < numPoints; iq++) { A = (*f)(gradAtQPs[iq]); result[iq] += A * grdUhAtQP[iq]; } } } void VecAtQP_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int i, dow = Global::getGeo(WORLD); int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += fac * factor * resultQP; } } } void VecAtQP_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq]); axpy(factor, grdUhAtQP[iq], result[iq]); } } } void CoordsAtQP_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, 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 factor = (*g)(coordsAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += factor * f * resultQP; } } } void CoordsAtQP_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { double factor = (*g)(coordsAtQPs[iq]); axpy(factor, grdUhAtQP[iq], result[iq]); } } } void FctGradient_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int i, dow = Global::getGeo(WORLD); int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(gradAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += fac * factor * resultQP; } } } void FctGradient_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(gradAtQPs[iq]); axpy(factor, grdUhAtQP[iq], result[iq]); } } } void VecAndGradientAtQP_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int i, dow = Global::getGeo(WORLD); int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += fac * factor * resultQP; } } } void VecAndGradientAtQP_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); axpy(factor, grdUhAtQP[iq], result[iq]); } } } void VecAndCoordsAtQP_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int i, dow = Global::getGeo(WORLD); int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq], coordsAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += fac * factor * resultQP; } } } void VecAndCoordsAtQP_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq], coordsAtQPs[iq]); axpy(factor, grdUhAtQP[iq], result[iq]); } } } void MatrixGradientAndCoords_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int i, j, dow = Global::getGeo(WORLD); int iq; for(iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; WorldMatrix A = (*f)(gradAtQPs[iq], coordsAtQPs[iq]); if(D2UhAtQP) { for(i=0; i < dow; i++) { for(j=0; j < dow; j++) { resultQP += A[i][j] * D2UhAtQP[iq][j][i]; } } } if(grdUhAtQP) { resultQP += (*divFct)(A) * grdUhAtQP[iq]; } result[iq] += resultQP * factor; } }; void MatrixGradientAndCoords_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; WorldMatrix A; for(iq = 0; iq < numPoints; iq++) { A = (*f)(gradAtQPs[iq], coordsAtQPs[iq]); result[iq] += A * grdUhAtQP[iq]; } } } void VecGradCoordsAtQP_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int i, dow = Global::getGeo(WORLD); int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += fac * factor * resultQP; } } } void VecGradCoordsAtQP_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq], coordsAtQPs[iq]); axpy(factor, grdUhAtQP[iq], result[iq]); } } } void VecAtQP_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int i, dow = Global::getGeo(WORLD); int iq; if(grdUhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += grdUhAtQP[iq][i]; } result[iq] += fac * factor * resultQP; } } } void CoordsAtQP_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double f) const { int i, dow = Global::getGeo(WORLD); int iq; if(grdUhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*g)(coordsAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += grdUhAtQP[iq][i]; } result[iq] += f * factor * resultQP; } } } void VecCoordsAtQP_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double f) const { int i, dow = Global::getGeo(WORLD); int iq; if(grdUhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*g)(coordsAtQPs[iq]); double resultQP = 0.0; for(i=0; i < dow; i++) { resultQP += grdUhAtQP[iq][i]; } result[iq] += f * factor * resultQP; } } } void VectorGradient_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int iq; if(grdUhAtQP) { if(f) { for(iq = 0; iq < numPoints; iq++) { WorldVector b = (*f)(gradAtQPs[iq]); result[iq] += b * grdUhAtQP[iq] * factor; } } else { for(iq = 0; iq < numPoints; iq++) { result[iq] += gradAtQPs[iq] * grdUhAtQP[iq] * factor; } } } } void VectorFct_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int iq; if(grdUhAtQP) { for(iq = 0; iq < numPoints; iq++) { WorldVector b = (*vecFct)(vecAtQPs[iq]); result[iq] += b * grdUhAtQP[iq] * factor; } } } void VecFctAtQP_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double f) const { int i, dow = Global::getGeo(WORLD); int iq; if(grdUhAtQP) { for(iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; const WorldVector &b = (*g)(coordsAtQPs[iq]); for(i=0; i < dow; i++) { resultQP += b[i] * grdUhAtQP[iq][i]; } result[iq] += f * resultQP; } } } Assembler *Operator::getAssembler(int rank) { if (!assembler[rank]) { initAssembler(rank, NULL, NULL, NULL, NULL); } return assembler[rank]; } void Operator::setAssembler(int rank, Assembler *a) { assembler[rank] = a; } void CoordsAtQP_IJ_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { coordsAtQPs = subAssembler->getCoordsAtQPs(elInfo, quad); } void CoordsAtQP_IJ_SOT::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]), (*g)(coordsAtQPs[iq])); } } void CoordsAtQP_IJ_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double f) const { int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*g)(coordsAtQPs[iq]); result[iq] = D2UhAtQP[iq][xi][xj] * factor * f; } } } void CoordsAtQP_IJ_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { double factor = (*g)(coordsAtQPs[iq]); result[iq][xi] += grdUhAtQP[iq][xj] * factor; } } } void VecAtQP_IJ_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); } void VecAtQP_IJ_SOT::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]), (*f)(vecAtQPs[iq])); } } void VecAtQP_IJ_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int iq; if(D2UhAtQP) { for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq]); result[iq] = D2UhAtQP[iq][xi][xj] * factor * fac; } } } void VecAtQP_IJ_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if(grdUhAtQP) { int iq; for(iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq]); result[iq][xi] += grdUhAtQP[iq][xj] * factor; } } } void VecOfDOFVecsAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int i ,size = static_cast(vecs.size()); for(i = 0; i < size; i++) { vecsAtQPs[i] = subAssembler->getVectorAtQPs(vecs[i], elInfo, quad); } } void VecOfDOFVecsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { int size = static_cast(vecs.size()); ::std::vector arg(size); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < size; i++) { arg[i] = vecsAtQPs[i][iq]; } C[iq] += (*f)(arg); } } void VecOfDOFVecsAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int i ,size = static_cast(vecs.size()); ::std::vector arg(size); int iq; for(iq = 0; iq < numPoints; iq++) { for(i = 0; i < size; i++) { arg[i] = vecsAtQPs[i][iq]; } result[iq] += fac * (*f)(arg) * uhAtQP[iq]; } } void VecOfGradientsAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int i ,size = static_cast(vecs.size()); for(i = 0; i < size; i++) { gradsAtQPs[i] = subAssembler->getGradientsAtQPs(vecs[i], elInfo, quad); } } void VecDivergence_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int i ,size = static_cast(vecs.size()); for(i = 0; i < size; i++) { gradsAtQPs[i] = subAssembler->getGradientsAtQPs(vecs[i], elInfo, quad); } } void VecOfGradientsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { int size = static_cast(vecs.size()); ::std::vector*> arg(size); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < size; i++) { arg[i] = &(gradsAtQPs[i][iq]); } C[iq] += (*f)(arg); } } void VecOfGradientsAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int size = static_cast(vecs.size()); ::std::vector*> arg(size); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < size; i++) { arg[i] = &(gradsAtQPs[i][iq]); } result[iq] += fac * (*f)(arg) * uhAtQP[iq]; } } void VecDivergence_ZOT::getC(const ElInfo *, int numPoints, double *C) const { int size = static_cast(vecs.size()); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < size; i++) { C[iq] += gradsAtQPs[i][iq][i]; } } } void VecDivergence_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int size = static_cast(vecs.size()); for (int iq = 0; iq < numPoints; iq++) { double d = 0.0; for (int i = 0; i < size; i++) { d += gradsAtQPs[i][iq][i]; } result[iq] += d * uhAtQP[iq] * fac; } } void VecAndGradAtQP_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int dow = Global::getGeo(WORLD); if (D2UhAtQP) { for (int iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); double resultQP = 0.0; for (int i = 0; i < dow; i++) { resultQP += D2UhAtQP[iq][i][i]; } result[iq] += fac * resultQP * factor; } } } void VecAndGradAtQP_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { if (grdUhAtQP) { for (int iq = 0; iq < numPoints; iq++) { double factor = (*f)(vecAtQPs[iq], gradAtQPs[iq]); axpy(factor, grdUhAtQP[iq], result[iq]); } } } void VecAndGradAtQP_SOT::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]), (*f)(vecAtQPs[iq], gradAtQPs[iq])); } } void VecAndGradAtQP_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); gradAtQPs = subAssembler->getGradientsAtQPs(vec, elInfo, quad); } void General_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); for (int i = 0; i < numVecs; i++) { vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); } for (int i = 0; i < numGrads; i++) { gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); } } void General_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } lalt(Lambda, (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg), *(LALt[iq]), symmetric_, 1.0); } } void General_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int dow = Global::getGeo(WORLD); int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); for (int iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } WorldMatrix A = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); if (D2UhAtQP) { for (int i = 0; i < dow; i++) { for (int j = 0; j < dow; j++) { resultQP += A[i][j] * D2UhAtQP[iq][j][i]; } } } if (grdUhAtQP) { resultQP += (*divFct_)(A) * grdUhAtQP[iq]; } result[iq] += resultQP * factor; } } void General_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); if (grdUhAtQP) { WorldMatrix A; for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } A = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); result[iq] += A * grdUhAtQP[iq]; } } } void General_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); for (int i = 0; i < numVecs; i++) { vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); } for (int i = 0; i < numGrads; i++) { gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); } } void General_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& result) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } lb(Lambda, (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg), result[iq], 1.0); } } void General_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int dow = Global::getGeo(WORLD); int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); if (grdUhAtQP) { for (int iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } const WorldVector &b = (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); for (int i = 0; i < dow; i++) { resultQP += grdUhAtQP[iq][i] * b[i]; } result[iq] += factor * resultQP; } } } void General_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); for (int i = 0; i < numVecs; i++) { vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); } for (int i = 0; i < numGrads; i++) { gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); } } void General_ZOT::getC(const ElInfo *, int numPoints, double *C) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } C[iq] += (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg); } } void General_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } result[iq] += fac * (*f_)(coordsAtQPs_[iq], vecsArg, gradsArg) * uhAtQP[iq]; } } //************************************ parametric general Operatorterms ***************** void GeneralParametric_SOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); elInfo->getElementNormal(elementNormal_); coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); for (int i = 0; i < numVecs; i++) { vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); } for (int i = 0; i < numGrads; i++) { gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); } } void GeneralParametric_SOT::getLALt(const ElInfo *elInfo, int numPoints, DimMat **LALt) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } lalt(Lambda, (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg), *(LALt[iq]), symmetric_, 1.0); } } void GeneralParametric_SOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int dow = Global::getGeo(WORLD); int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); for (int iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } WorldMatrix A = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); if (D2UhAtQP) { for (int i = 0; i < dow; i++) { for (int j = 0; j < dow; j++) { resultQP += A[i][j] * D2UhAtQP[iq][j][i]; } } } if (grdUhAtQP) { resultQP += (*divFct_)(A) * grdUhAtQP[iq]; } result[iq] += resultQP * factor; } } void GeneralParametric_SOT::weakEval(int numPoints, const WorldVector *grdUhAtQP, WorldVector *result) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); if (grdUhAtQP) { WorldMatrix A; for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } A = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); result[iq] += A * grdUhAtQP[iq]; } } } void GeneralParametric_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); elInfo->getElementNormal(elementNormal_); coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); for (int i = 0; i < numVecs; i++) { vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); } for (int i = 0; i < numGrads; i++) { gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); } } void GeneralParametric_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& result) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } lb(Lambda, (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg), result[iq], 1.0); } } void GeneralParametric_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { int dow = Global::getGeo(WORLD); int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); if (grdUhAtQP) { for (int iq = 0; iq < numPoints; iq++) { double resultQP = 0.0; for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } const WorldVector &b = (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); for (int i = 0; i < dow; i++) { resultQP += grdUhAtQP[iq][i] * b[i]; } result[iq] += factor * resultQP; } } } void GeneralParametric_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); elInfo->getElementNormal(elementNormal_); coordsAtQPs_ = subAssembler->getCoordsAtQPs(elInfo, quad); for (int i = 0; i < numVecs; i++) { vecsAtQPs_[i] = subAssembler->getVectorAtQPs(vecs_[i], elInfo, quad); } for (int i = 0; i < numGrads; i++) { gradsAtQPs_[i] = subAssembler->getGradientsAtQPs(grads_[i], elInfo, quad); } } void GeneralParametric_ZOT::getC(const ElInfo *, int numPoints, double *C) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } C[iq] += (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg); } } void GeneralParametric_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int numVecs = static_cast(vecs_.size()); int numGrads = static_cast(grads_.size()); ::std::vector vecsArg(numVecs); ::std::vector > gradsArg(numGrads); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < numVecs; i++) { vecsArg[i] = vecsAtQPs_[i][iq]; } for (int i = 0; i < numGrads; i++) { gradsArg[i] = gradsAtQPs_[i][iq]; } result[iq] += fac * (*f_)(coordsAtQPs_[iq], elementNormal_, vecsArg, gradsArg) * uhAtQP[iq]; } } void VecAndVecOfGradientsAtQP_ZOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { int size = static_cast(vecs.size()); for (int i = 0; i < size; i++) { gradsAtQPs[i] = subAssembler->getGradientsAtQPs(vecs[i], elInfo, quad); } vecAtQPs = subAssembler->getVectorAtQPs(vec, elInfo, quad); } void VecAndVecOfGradientsAtQP_ZOT::getC(const ElInfo *, int numPoints, double *C) const { int size = static_cast(vecs.size()); std::vector*> arg(size); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < size; i++) { arg[i] = &(gradsAtQPs[i][iq]); } C[iq] += (*f)(vecAtQPs[iq], arg); } } void VecAndVecOfGradientsAtQP_ZOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double fac) const { int size = static_cast(vecs.size()); std::vector*> arg(size); for (int iq = 0; iq < numPoints; iq++) { for (int i = 0; i < size; i++) { arg[i] = &(gradsAtQPs[i][iq]); } result[iq] += fac * (*f)(vecAtQPs[iq], arg) * uhAtQP[iq]; } } void VecGrad_FOT::initElement(const ElInfo* elInfo, SubAssembler* subAssembler, Quadrature *quad) { vecAtQPs = subAssembler->getVectorAtQPs(vec1, elInfo, quad); gradAtQPs = subAssembler->getGradientsAtQPs(vec2, elInfo, quad); } void VecGrad_FOT::getLb(const ElInfo *elInfo, int numPoints, VectorOfFixVecs >& Lb) const { const DimVec > &Lambda = elInfo->getGrdLambda(); for (int iq = 0; iq < numPoints; iq++) { lb(Lambda, (*vecFct)(vecAtQPs[iq], gradAtQPs[iq]), Lb[iq], 1.0); } } void VecGrad_FOT::eval(int numPoints, const double *uhAtQP, const WorldVector *grdUhAtQP, const WorldMatrix *D2UhAtQP, double *result, double factor) const { if (grdUhAtQP) { for (int iq = 0; iq < numPoints; iq++) { WorldVector b = (*vecFct)(vecAtQPs[iq], gradAtQPs[iq]); result[iq] += b * grdUhAtQP[iq] * factor; } } } }