#include #include "DOFVector.h" #include "Traverse.h" #include "DualTraverse.h" #include "FixVec.h" namespace AMDiS { template<> void DOFVector::coarseRestrict(RCNeighbourList& list, int n) { switch (coarsenOperation) { case NO_OPERATION: return; break; case COARSE_RESTRICT: (const_cast(feSpace->getBasisFcts()))->coarseRestr(this, &list, n); break; case COARSE_INTERPOL: if (feSpace == NULL || !feSpace) ERROR_EXIT("ERR1\n"); if (feSpace->getBasisFcts() == NULL || !(feSpace->getBasisFcts())) ERROR_EXIT("ERR2\n"); (const_cast(feSpace->getBasisFcts()))->coarseInter(this, &list, n); break; default: ERROR_EXIT("invalid coarsen operation\n"); } } template<> void DOFVector::refineInterpol(RCNeighbourList& list, int n) { (const_cast(feSpace->getBasisFcts()))->refineInter(this, &list, n); } template<> void DOFVector >::refineInterpol(RCNeighbourList& list, int n) { if (n < 1) return; Element *el = list.getElement(0); int n0 = feSpace->getAdmin()->getNumberOfPreDOFs(VERTEX); DegreeOfFreedom dof0 = el->getDOF(0, n0); DegreeOfFreedom dof1 = el->getDOF(1, n0); DegreeOfFreedom dof_new = el->getChild(0)->getDOF(feSpace->getMesh()->getDim(), n0); vec[dof_new] = vec[dof0]; vec[dof_new] += vec[dof1]; vec[dof_new] *= 0.5; } template<> DOFVector >* DOFVector::getGradient(DOFVector > *grad) const { FUNCNAME("DOFVector::getGradient()"); // define result vector static DOFVector > *result = NULL; if (grad) { result = grad; } else { if(result && result->getFESpace() != feSpace) { delete result; result = new DOFVector >(feSpace, "gradient"); } } Mesh *mesh = feSpace->getMesh(); int dim = mesh->getDim(); const BasisFunction *basFcts = feSpace->getBasisFcts(); DOFAdmin *admin = feSpace->getAdmin(); // count number of nodes and dofs per node std::vector numNodeDOFs; std::vector numNodePreDOFs; std::vector*> bary; int numNodes = 0; int numDOFs = 0; for (int i = 0; i < dim + 1; i++) { GeoIndex geoIndex = INDEX_OF_DIM(i, dim); int numPositionNodes = mesh->getGeo(geoIndex); int numPreDOFs = admin->getNumberOfPreDOFs(i); for (int j = 0; j < numPositionNodes; j++) { int dofs = basFcts->getNumberOfDOFs(geoIndex); numNodeDOFs.push_back(dofs); numDOFs += dofs; numNodePreDOFs.push_back(numPreDOFs); } numNodes += numPositionNodes; } // TEST_EXIT_DBG(numNodes == mesh->getNumberOfNodes()) // ("invalid number of nodes\n"); TEST_EXIT_DBG(numDOFs == basFcts->getNumber()) ("number of dofs != number of basis functions\n"); for (int i = 0; i < numDOFs; i++) { bary.push_back(basFcts->getCoords(i)); } // traverse mesh std::vector visited(getUsedSize(), false); TraverseStack stack; Flag fillFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_GRD_LAMBDA | Mesh::FILL_COORDS; ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); while (elInfo) { const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); const double *localUh = getLocalVector(elInfo->getElement(), NULL); const DimVec > &grdLambda = elInfo->getGrdLambda(); int localDOFNr = 0; for (int i = 0; i < numNodes; i++) { // for all nodes for (int j = 0; j < numNodeDOFs[i]; j++) { // for all dofs at this node DegreeOfFreedom dofIndex = dof[i][numNodePreDOFs[localDOFNr] + j]; if (!visited[dofIndex]) { basFcts->evalGrdUh(*(bary[localDOFNr]), grdLambda, localUh, &((*result)[dofIndex])); visited[dofIndex] = true; } localDOFNr++; } } elInfo = stack.traverseNext(elInfo); } return result; } template<> DOFVector >* DOFVector::getRecoveryGradient(DOFVector > *grad) const { FUNCNAME("DOFVector::getRecoveryGradient()"); // define result vector static DOFVector > *vec = NULL; DOFVector > *result = grad; if (!result) { if (vec && vec->getFESpace() != feSpace) { delete vec; vec = NULL; } if (!vec) { vec = new DOFVector >(feSpace, "gradient"); } result = vec; } result->set(WorldVector(DEFAULT_VALUE, 0.0)); DOFVector volume(feSpace, "volume"); volume.set(0.0); const BasisFunction *basFcts = feSpace->getBasisFcts(); int nPreDOFs = feSpace->getAdmin()->getNumberOfPreDOFs(0); DimVec bary(dim, DEFAULT_VALUE, (1.0 / (dim + 1.0))); WorldVector grd; // traverse mesh Mesh *mesh = feSpace->getMesh(); TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA | Mesh::FILL_COORDS); while (elInfo) { double det = elInfo->getDet(); const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); const double *localUh = getLocalVector(elInfo->getElement(), NULL); const DimVec > &grdLambda = elInfo->getGrdLambda(); basFcts->evalGrdUh(bary, grdLambda, localUh, &grd); for (int i = 0; i < dim + 1; i++) { DegreeOfFreedom dofIndex = dof[i][nPreDOFs]; (*result)[dofIndex] += grd * det; volume[dofIndex] += det; } elInfo = stack.traverseNext(elInfo); } DOFVector::Iterator volIt(&volume, USED_DOFS); DOFVector >::Iterator grdIt(result, USED_DOFS); for (volIt.reset(), grdIt.reset(); !volIt.end(); ++volIt, ++grdIt) { if (*volIt != 0.0) { *grdIt *= 1.0 / (*volIt); } } return result; } template<> const WorldVector *DOFVectorBase::getGrdAtQPs(const ElInfo *elInfo, const Quadrature *quad, const FastQuadrature *quadFast, WorldVector *grdAtQPs) const { FUNCNAME("DOFVector::getGrdAtQPs()"); TEST_EXIT_DBG(quad || quadFast)("neither quad nor quadFast defined\n"); if (quad && quadFast) { TEST_EXIT_DBG(quad == quadFast->getQuadrature()) ("quad != quadFast->quadrature\n"); } TEST_EXIT_DBG(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) ("invalid basis functions"); int dow = Global::getGeo(WORLD); int myRank = omp_get_thread_num(); int nPoints = quadFast ? quadFast->getQuadrature()->getNumPoints() : quad->getNumPoints(); static WorldVector *grd = NULL; WorldVector *result; if (grdAtQPs) { result = grdAtQPs; } else { if (grd) delete [] grd; grd = new WorldVector[nPoints]; for (int i = 0; i < nPoints; i++) { grd[i].set(0.0); } result = grd; } double *localVec = localVectors[myRank]; getLocalVector(elInfo->getElement(), localVec); DimVec &grd1 = *grdTmp[myRank]; int parts = Global::getGeo(PARTS, dim); const DimVec > &grdLambda = elInfo->getGrdLambda(); if (quadFast) { for (int i = 0; i < nPoints; i++) { for (int j = 0; j < dim + 1; j++) grd1[j] = 0.0; for (int j = 0; j < nBasFcts; j++) for (int k = 0; k < parts; k++) grd1[k] += quadFast->getGradient(i, j, k) * localVec[j]; for (int l=0; l < dow; l++) { result[i][l] = 0.0; for (int k = 0; k < parts; k++) result[i][l] += grdLambda[k][l] * grd1[k]; } } } else { const BasisFunction *basFcts = feSpace->getBasisFcts(); DimVec* grdPhi = grdPhis[myRank]; for (int i = 0; i < nPoints; i++) { for (int j = 0; j < dim + 1; j++) grd1[j] = 0.0; for (int j = 0; j < nBasFcts; j++) { (*(basFcts->getGrdPhi(j)))(quad->getLambda(i), *grdPhi); for (int k = 0; k < parts; k++) grd1[k] += (*grdPhi)[k] * localVec[j]; } for (int l = 0; l < dow; l++) { result[i][l] = 0.0; for (int k = 0; k < parts; k++) result[i][l] += grdLambda[k][l] * grd1[k]; } } } return const_cast*>(result); } template<> const WorldVector *DOFVectorBase::getGrdAtQPs(const ElInfo *smallElInfo, const ElInfo *largeElInfo, const Quadrature *quad, const FastQuadrature *quadFast, WorldVector *grdAtQPs) const { FUNCNAME("DOFVector::getGrdAtQPs()"); TEST_EXIT_DBG(quad || quadFast)("neither quad nor quadFast defined\n"); if (quad && quadFast) TEST_EXIT_DBG(quad == quadFast->getQuadrature())("quad != quadFast->quadrature\n"); TEST_EXIT_DBG(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) ("invalid basis functions"); int dow = Global::getGeo(WORLD); int myRank = omp_get_thread_num(); int nPoints = quadFast ? quadFast->getQuadrature()->getNumPoints() : quad->getNumPoints(); static WorldVector *grd = NULL; WorldVector *result; if (grdAtQPs) { result = grdAtQPs; } else { if (grd) delete [] grd; grd = new WorldVector[nPoints]; for (int i = 0; i < nPoints; i++) grd[i].set(0.0); result = grd; } double *localVec = localVectors[myRank]; getLocalVector(largeElInfo->getElement(), localVec); const BasisFunction *basFcts = feSpace->getBasisFcts(); mtl::dense2D m(nBasFcts, nBasFcts); smallElInfo->getSubElemCoordsMat(m, basFcts->getDegree()); DimVec &grd1 = *grdTmp[myRank]; int parts = Global::getGeo(PARTS, dim); const DimVec > &grdLambda = largeElInfo->getGrdLambda(); DimVec* grdPhi = grdPhis[myRank]; DimVec tmp(dim, DEFAULT_VALUE, 0.0); for (int i = 0; i < nPoints; i++) { for (int j = 0; j < dim + 1; j++) grd1[j] = 0.0; for (int j = 0; j < nBasFcts; j++) { grdPhi->set(0.0); for (int k = 0; k < nBasFcts; k++) { (*(basFcts->getGrdPhi(k)))(quad->getLambda(i), tmp); tmp *= m[j][k]; *grdPhi += tmp; } for (int k = 0; k < parts; k++) grd1[k] += (*grdPhi)[k] * localVec[j]; } for (int l = 0; l < dow; l++) { result[i][l] = 0.0; for (int k = 0; k < parts; k++) result[i][l] += grdLambda[k][l] * grd1[k]; } } return const_cast*>(result); } template<> const WorldMatrix *DOFVectorBase::getD2AtQPs(const ElInfo *elInfo, const Quadrature *quad, const FastQuadrature *quadFast, WorldMatrix *d2AtQPs) const { FUNCNAME("DOFVector::getD2AtQPs()"); TEST_EXIT_DBG(quad || quadFast)("neither quad nor quadFast defined\n"); if (quad && quadFast) { TEST_EXIT_DBG(quad == quadFast->getQuadrature()) ("quad != quadFast->quadrature\n"); } TEST_EXIT_DBG(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) ("invalid basis functions"); Element *el = elInfo->getElement(); int myRank = omp_get_thread_num(); int dow = Global::getGeo(WORLD); int nPoints = quadFast ? quadFast->getQuadrature()->getNumPoints() : quad->getNumPoints(); static WorldMatrix *vec = NULL; WorldMatrix *result; if (d2AtQPs) { result = d2AtQPs; } else { if(vec) delete [] vec; vec = new WorldMatrix[nPoints]; for (int i = 0; i < nPoints; i++) { vec[i].set(0.0); } result = vec; } double *localVec = localVectors[myRank]; getLocalVector(el, localVec); DimMat D2Tmp(dim, DEFAULT_VALUE, 0.0); int parts = Global::getGeo(PARTS, dim); const DimVec > &grdLambda = elInfo->getGrdLambda(); if (quadFast) { for (int iq = 0; iq < nPoints; iq++) { for (int k = 0; k < parts; k++) for (int l = 0; l < parts; l++) D2Tmp[k][l] = 0.0; for (int i = 0; i < nBasFcts; i++) { for (int k = 0; k < parts; k++) for (int l = 0; l < parts; l++) D2Tmp[k][l] += localVec[i] * quadFast->getSecDer(iq, i, k, l); } for (int i = 0; i < dow; i++) for (int j = 0; j < dow; j++) { result[iq][i][j] = 0.0; for (int k = 0; k < parts; k++) for (int l = 0; l < parts; l++) result[iq][i][j] += grdLambda[k][i]*grdLambda[l][j]*D2Tmp[k][l]; } } } else { const BasisFunction *basFcts = feSpace->getBasisFcts(); DimMat* D2Phi = D2Phis[omp_get_thread_num()]; for (int iq = 0; iq < nPoints; iq++) { for (int k = 0; k < parts; k++) for (int l = 0; l < parts; l++) D2Tmp[k][l] = 0.0; for (int i = 0; i < nBasFcts; i++) { WARNING("not tested after index correction\n"); (*(basFcts->getD2Phi(i)))(quad->getLambda(iq), *D2Phi); for (int k = 0; k < parts; k++) for (int l = 0; l < parts; l++) D2Tmp[k][l] += localVec[i] * (*D2Phi)[k][l]; } for (int i = 0; i < dow; i++) for (int j = 0; j < dow; j++) { result[iq][i][j] = 0.0; for (int k = 0; k < parts; k++) for (int l = 0; l < parts; l++) result[iq][i][j] += grdLambda[k][i] * grdLambda[l][j] * D2Tmp[k][l]; } } } return const_cast*>(result); } template<> void DOFVector::interpol(DOFVector *source, double factor) { FUNCNAME("DOFVector::interpol()"); const FiniteElemSpace *sourceFeSpace = source->getFESpace(); const BasisFunction *basisFcts = feSpace->getBasisFcts(); const BasisFunction *sourceBasisFcts = sourceFeSpace->getBasisFcts(); int nBasisFcts = basisFcts->getNumber(); int nSourceBasisFcts = sourceBasisFcts->getNumber(); this->set(0.0); DegreeOfFreedom *myLocalIndices = localIndices[omp_get_thread_num()]; double *sourceLocalCoeffs = new double[nSourceBasisFcts]; if (feSpace->getMesh() == sourceFeSpace->getMesh()) { DimVec *coords = NULL; TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); while (elInfo) { Element *el = elInfo->getElement(); basisFcts->getLocalIndices(el, feSpace->getAdmin(), myLocalIndices); source->getLocalVector(el, sourceLocalCoeffs); for (int i = 0; i < nBasisFcts; i++) { if (vec[myLocalIndices[i]] == 0.0) { coords = basisFcts->getCoords(i); vec[myLocalIndices[i]] = sourceBasisFcts->evalUh(*coords, sourceLocalCoeffs) * factor; } } elInfo = stack.traverseNext(elInfo); } } else { DimVec coords2(feSpace->getMesh()->getDim(), NO_INIT); DualTraverse dualStack; ElInfo *elInfo1, *elInfo2; ElInfo *elInfoSmall, *elInfoLarge; WorldVector worldVec; bool nextTraverse = dualStack.traverseFirst(feSpace->getMesh(), sourceFeSpace->getMesh(), -1, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS, &elInfo1, &elInfo2, &elInfoSmall, &elInfoLarge); while (nextTraverse) { basisFcts->getLocalIndices(elInfo1->getElement(), feSpace->getAdmin(), myLocalIndices); source->getLocalVector(elInfo2->getElement(), sourceLocalCoeffs); for (int i = 0; i < nBasisFcts; i++) { if (vec[myLocalIndices[i]] == 0.0) { elInfo1->coordToWorld(*(basisFcts->getCoords(i)), worldVec); elInfo2->worldToCoord(worldVec, &coords2); bool isPositive = true; for (int j = 0; j < coords2.size(); j++) { if (coords2[j] < 0) { isPositive = false; break; } } if (isPositive) { vec[myLocalIndices[i]] = sourceBasisFcts->evalUh(coords2, sourceLocalCoeffs); } } } nextTraverse = dualStack.traverseNext(&elInfo1, &elInfo2, &elInfoSmall, &elInfoLarge); } } delete [] sourceLocalCoeffs; } template<> void DOFVector >::interpol(DOFVector > *v, double factor) { WorldVector nul(DEFAULT_VALUE,0.0); this->set(nul); DimVec *coords = NULL; const FiniteElemSpace *vFESpace = v->getFESpace(); if (feSpace == vFESpace) WARNING("same FE-spaces\n"); const BasisFunction *basFcts = feSpace->getBasisFcts(); const BasisFunction *vBasFcts = vFESpace->getBasisFcts(); int numBasFcts = basFcts->getNumber(); int vNumBasFcts = vBasFcts->getNumber(); if (feSpace->getMesh() == vFESpace->getMesh()) { DegreeOfFreedom *myLocalIndices = localIndices[omp_get_thread_num()]; WorldVector *vLocalCoeffs = new WorldVector[vNumBasFcts]; Mesh *mesh = feSpace->getMesh(); TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); while (elInfo) { Element *el = elInfo->getElement(); basFcts->getLocalIndices(el, feSpace->getAdmin(), myLocalIndices); v->getLocalVector(el, vLocalCoeffs); for (int i = 0; i < numBasFcts; i++) { if (vec[myLocalIndices[i]] == nul) { coords = basFcts->getCoords(i); vec[myLocalIndices[i]] += vBasFcts->evalUh(*coords, vLocalCoeffs, NULL) * factor; } } elInfo = stack.traverseNext(elInfo); } delete [] vLocalCoeffs; } else { ERROR_EXIT("not yet for dual traverse\n"); } } template<> WorldVector*> *DOFVector::getGradient(WorldVector*> *grad) const { FUNCNAME("DOFVector::getGradient()"); Mesh *mesh = feSpace->getMesh(); int dim = mesh->getDim(); int dow = Global::getGeo(WORLD); const BasisFunction *basFcts = feSpace->getBasisFcts(); DOFAdmin *admin = feSpace->getAdmin(); // define result vector static WorldVector*> *result = NULL; if (grad) { result = grad; } else { if (!result) { result = new WorldVector*>; result->set(NULL); } for (int i = 0; i < dow; i++) { if ((*result)[i] && (*result)[i]->getFESpace() != feSpace) { delete (*result)[i]; (*result)[i] = new DOFVector(feSpace, "gradient"); } } } // count number of nodes and dofs per node std::vector numNodeDOFs; std::vector numNodePreDOFs; std::vector*> bary; int numNodes = 0; int numDOFs = 0; for (int i = 0; i < dim + 1; i++) { GeoIndex geoIndex = INDEX_OF_DIM(i, dim); int numPositionNodes = mesh->getGeo(geoIndex); int numPreDOFs = admin->getNumberOfPreDOFs(i); for (int j = 0; j < numPositionNodes; j++) { int dofs = basFcts->getNumberOfDOFs(geoIndex); numNodeDOFs.push_back(dofs); numDOFs += dofs; numNodePreDOFs.push_back(numPreDOFs); } numNodes += numPositionNodes; } // TEST_EXIT_DBG(numNodes == mesh->getNumberOfNodes()) // ("invalid number of nodes\n"); TEST_EXIT_DBG(numDOFs == basFcts->getNumber()) ("number of dofs != number of basis functions\n"); for (int i = 0; i < numDOFs; i++) { bary.push_back(basFcts->getCoords(i)); } // traverse mesh std::vector visited(getUsedSize(), false); TraverseStack stack; Flag fillFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_GRD_LAMBDA | Mesh::FILL_COORDS; ElInfo *elInfo = stack.traverseFirst(mesh, -1, fillFlag); WorldVector grd; while (elInfo) { const DegreeOfFreedom **dof = elInfo->getElement()->getDOF(); const double *localUh = getLocalVector(elInfo->getElement(), NULL); const DimVec > &grdLambda = elInfo->getGrdLambda(); int localDOFNr = 0; for (int i = 0; i < numNodes; i++) { // for all nodes for (int j = 0; j < numNodeDOFs[i]; j++) { // for all dofs at this node DegreeOfFreedom dofIndex = dof[i][numNodePreDOFs[localDOFNr] + j]; if (!visited[dofIndex]) { basFcts->evalGrdUh(*(bary[localDOFNr]), grdLambda, localUh, &grd); for (int k = 0; k < dow; k++) { (*(*result)[k])[dofIndex] = grd[k]; } visited[dofIndex] = true; } localDOFNr++; } } elInfo = stack.traverseNext(elInfo); } return result; } DOFVectorDOF::DOFVectorDOF() : DOFVector() {} void DOFVectorDOF::freeDOFContent(DegreeOfFreedom dof) { std::vector::iterator it; std::vector::iterator end = vec.end(); DegreeOfFreedom pos = 0; for (it = vec.begin(); it != end; ++it, ++pos) if (*it == dof) *it = pos; } WorldVector*> *transform(DOFVector > *vec, WorldVector*> *res) { FUNCNAME("DOFVector::transform()"); TEST_EXIT_DBG(vec)("no vector\n"); int dow = Global::getGeo(WORLD); static WorldVector*> *result = NULL; if (!res && !result) { result = new WorldVector*>; for (int i = 0; i < dow; i++) (*result)[i] = new DOFVector(vec->getFESpace(), "transform"); } WorldVector*> *r = res ? res : result; int vecSize = vec->getSize(); for (int i = 0; i < vecSize; i++) for (int j = 0; j < dow; j++) (*((*r)[j]))[i] = (*vec)[i][j]; return r; } template<> const double *DOFVectorBase::getVecAtQPs(const ElInfo *smallElInfo, const ElInfo *largeElInfo, const Quadrature *quad, const FastQuadrature *quadFast, double *vecAtQPs) const { FUNCNAME("DOFVector::getVecAtQPs()"); TEST_EXIT_DBG(quad || quadFast)("neither quad nor quadFast defined\n"); if (quad && quadFast) { TEST_EXIT_DBG(quad == quadFast->getQuadrature()) ("quad != quadFast->quadrature\n"); } TEST_EXIT_DBG(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) ("invalid basis functions"); const BasisFunction *basFcts = feSpace->getBasisFcts(); int nPoints = quadFast ? quadFast->getQuadrature()->getNumPoints() : quad->getNumPoints(); static double *localvec = NULL; double *result; if (vecAtQPs) { result = vecAtQPs; } else { if (localvec) delete [] localvec; localvec = new double[nPoints]; for (int i = 0; i < nPoints; i++) { localvec[i] = 0.0; } result = localvec; } double *localVec = localVectors[omp_get_thread_num()]; getLocalVector(largeElInfo->getElement(), localVec); mtl::dense2D m(nBasFcts, nBasFcts); smallElInfo->getSubElemCoordsMat(m, basFcts->getDegree()); for (int i = 0; i < nPoints; i++) { result[i] = 0.0; for (int j = 0; j < nBasFcts; j++) { double val = 0.0; for (int k = 0; k < nBasFcts; k++) { val += m[j][k] * (*(basFcts->getPhi(k)))(quad->getLambda(i)); } result[i] += localVec[j] * val; } } return const_cast(result); } template<> void DOFVectorBase::assemble(double factor, ElInfo *elInfo, const BoundaryType *bound, Operator *op) { FUNCNAME("DOFVector::assemble()"); if (!(op || this->operators.size())) return; set_to_zero(this->elementVector); if (op) { op->getElementVector(elInfo, this->elementVector); } else { std::vector::iterator it; std::vector::iterator factorIt; for (it = this->operators.begin(), factorIt = this->operatorFactor.begin(); it != this->operators.end(); ++it, ++factorIt) if ((*it)->getNeedDualTraverse() == false) (*it)->getElementVector(elInfo, this->elementVector, *factorIt ? **factorIt : 1.0); } addElementVector(factor, this->elementVector, bound, elInfo); } template<> void DOFVectorBase::assemble2(double factor, ElInfo *mainElInfo, ElInfo *auxElInfo, ElInfo *smallElInfo, ElInfo *largeElInfo, const BoundaryType *bound, Operator *op) { FUNCNAME("DOFVector::assemble2()"); if (!(op || this->operators.size())) return; set_to_zero(this->elementVector); if (op) { ERROR_EXIT("TODO"); // op->getElementVector(mainElInfo, this->elementVector); } else { std::vector::iterator it; std::vector::iterator factorIt; for (it = this->operators.begin(), factorIt = this->operatorFactor.begin(); it != this->operators.end(); ++it, ++factorIt) { if ((*it)->getNeedDualTraverse()) { (*it)->getElementVector(mainElInfo, auxElInfo, smallElInfo, largeElInfo, this->elementVector, *factorIt ? **factorIt : 1.0); } } } addElementVector(factor, this->elementVector, bound, mainElInfo); } }