#include #include #include #include "FixVec.h" #include "Boundary.h" #include "DOFAdmin.h" #include "ElInfo.h" #include "Error.h" #include "FiniteElemSpace.h" #include "Global.h" #include "Mesh.h" #include "Quadrature.h" #include "AbstractFunction.h" #include "BoundaryManager.h" #include "ElementVector.h" #include "Assembler.h" #include "OpenMP.h" #include "Operator.h" #include "Parameters.h" #include "Traverse.h" #include #include #include #include // Defining the interface for MTL4 namespace mtl { // Let MTL4 know that DOFVector it is a column vector namespace traits { template struct category< AMDiS::DOFVector > { typedef tag::dense_col_vector type; }; } namespace ashape { template struct ashape< AMDiS::DOFVector > { typedef cvec::type> type; }; } // Modelling Collection and MutableCollection template struct Collection< AMDiS::DOFVector > { typedef T value_type; typedef const T& const_reference; typedef std::size_t size_type; }; template struct MutableCollection< AMDiS::DOFVector > : public Collection< AMDiS::DOFVector > { typedef T& reference; }; } // namespace mtl namespace AMDiS { template DOFVectorBase::DOFVectorBase(const FiniteElemSpace *f, std::string n) : feSpace(f), name(n), elementVector(NULL), boundaryManager(NULL) { nBasFcts = feSpace->getBasisFcts()->getNumber(); dim = feSpace->getMesh()->getDim(); localIndices.resize(omp_get_overall_max_threads()); localVectors.resize(omp_get_overall_max_threads()); grdPhis.resize(omp_get_overall_max_threads()); grdTmp.resize(omp_get_overall_max_threads()); D2Phis.resize(omp_get_overall_max_threads()); for (int i = 0; i < omp_get_overall_max_threads(); i++) { localIndices[i] = GET_MEMORY(DegreeOfFreedom, this->nBasFcts); localVectors[i] = GET_MEMORY(T, this->nBasFcts); grdPhis[i] = NEW DimVec(dim, DEFAULT_VALUE, 0.0); grdTmp[i] = NEW DimVec(dim, DEFAULT_VALUE, 0.0); D2Phis[i] = NEW DimMat(dim, NO_INIT); } elementVector = NEW ElementVector(this->nBasFcts); } template DOFVectorBase::~DOFVectorBase() { for (int i = 0; i < static_cast(localIndices.size()); i++) { FREE_MEMORY(localIndices[i], DegreeOfFreedom, this->nBasFcts); FREE_MEMORY(localVectors[i], T, this->nBasFcts); DELETE grdPhis[i]; DELETE grdTmp[i]; DELETE D2Phis[i]; } } template DOFVector::DOFVector(const FiniteElemSpace* f, std::string n) : DOFVectorBase(f, n), //elementVector(NULL), coarsenOperation(NO_OPERATION) { init(f, n); #ifdef HAVE_PARALLEL_DOMAIN_AMDIS applicationOrdering = NULL; #endif } template void DOFVector::init(const FiniteElemSpace* f, std::string n) { name = n; feSpace = f; if(feSpace && feSpace->getAdmin()) { (feSpace->getAdmin())->addDOFIndexed(this); } this->boundaryManager = NEW BoundaryManager(f); } template DOFVector::~DOFVector() { if (feSpace && feSpace->getAdmin()) (feSpace->getAdmin())->removeDOFIndexed(this); if (this->boundaryManager) DELETE this->boundaryManager; vec.clear(); } template DOFVector * DOFVector::traverseVector = NULL; template FastQuadrature *DOFVector::quad_fast = NULL; template double DOFVector::norm = 0.0; template void DOFVectorBase::addElementVector(T factor, const ElementVector &elVec, const BoundaryType *bound, bool add) { FUNCNAME("DOFVector::addElementVector()"); int n_row = elVec.getSize(); for (DegreeOfFreedom i = 0; i < n_row; i++) { BoundaryCondition *condition = bound ? this->getBoundaryManager()->getBoundaryCondition(bound[i]) : NULL; if (!(condition && condition->isDirichlet())) { DegreeOfFreedom irow = elVec.dofIndices[i]; (*this)[irow] = (add ? (*this)[irow] : 0.0); (*this)[irow] += factor * elVec[i]; } } } template double DOFVector::nrm2() const { FUNCNAME("DOFVector::nrm2()"); TEST_EXIT_DBG(feSpace)("feSpace is NULL\n"); TEST_EXIT_DBG(feSpace->getAdmin())("admin is NULL\n"); TEST_EXIT_DBG(static_cast(vec.size()) >= feSpace->getAdmin()->getUsedSize()) ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), feSpace->getAdmin()->getUsedSize()); double nrm = 0.0; Iterator vecIterator(dynamic_cast*>(const_cast*>(this)), USED_DOFS); for (vecIterator.reset(); !vecIterator.end(); ++vecIterator) nrm += (*vecIterator) * (*vecIterator); return(sqrt(nrm)); } template double DOFVector::squareNrm2() const { FUNCNAME("DOFVector::nrm2()"); TEST_EXIT_DBG(feSpace)("feSpace is NULL\n"); TEST_EXIT_DBG(feSpace->getAdmin())("admin is NULL\n"); TEST_EXIT_DBG(static_cast(vec.size()) >= feSpace->getAdmin()->getUsedSize()) ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), feSpace->getAdmin()->getUsedSize()); double nrm = 0.0; Iterator vecIterator(dynamic_cast*>(const_cast*>(this)), USED_DOFS); for (vecIterator.reset(); !vecIterator.end(); ++vecIterator) nrm += (*vecIterator) * (*vecIterator); return nrm; } template T DOFVector::asum() const { FUNCNAME("DOFVector::asum()"); TEST_EXIT_DBG(feSpace)("feSpace is NULL\n"); TEST_EXIT_DBG(feSpace->getAdmin())("admin is NULL\n"); TEST_EXIT_DBG(static_cast(vec.size()) >= feSpace->getAdmin()->getUsedSize()) ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), feSpace->getAdmin()->getUsedSize()); double nrm = 0.0; Iterator vecIterator(dynamic_cast*>(const_cast*>(this)), USED_DOFS); for (vecIterator.reset(); !vecIterator.end(); ++vecIterator) nrm += abs(*vecIterator); return(nrm); } template T DOFVector::sum() const { FUNCNAME("DOFVector::sum()"); TEST_EXIT_DBG(feSpace)("feSpace is NULL\n"); TEST_EXIT_DBG(feSpace->getAdmin())("admin is NULL\n"); TEST_EXIT_DBG(static_cast(vec.size()) >= feSpace->getAdmin()->getUsedSize()) ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), feSpace->getAdmin()->getUsedSize()); double nrm = 0.0; Iterator vecIterator(dynamic_cast*>(const_cast*>(this)), USED_DOFS); for (vecIterator.reset(); !vecIterator.end(); ++vecIterator) nrm += *vecIterator; return(nrm); } template void DOFVector::set(T alpha) { FUNCNAME("DOFVector::set()"); TEST_EXIT_DBG(feSpace)("feSpace is NULL\n"); TEST_EXIT_DBG(feSpace->getAdmin())("admin is NULL\n"); TEST_EXIT_DBG(static_cast(vec.size()) >= feSpace->getAdmin()->getUsedSize()) ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), feSpace->getAdmin()->getUsedSize()); Iterator vecIterator(dynamic_cast*>(this), USED_DOFS); for (vecIterator.reset(); !vecIterator.end(); ++vecIterator) { *vecIterator = alpha ; } } template void DOFVector::copy(const DOFVector& x) { FUNCNAME("DOFVector::copy()"); TEST_EXIT_DBG(feSpace && x.feSpace) ("feSpace is NULL: %8X, %8X\n", feSpace, x.feSpace); TEST_EXIT_DBG(feSpace->getAdmin() && (feSpace->getAdmin() == x.feSpace->getAdmin())) ("no admin or different admins: %8X, %8X\n", feSpace->getAdmin(), x.feSpace->getAdmin()); TEST_EXIT_DBG(static_cast(vec.size()) >= feSpace->getAdmin()->getUsedSize()) ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), feSpace->getAdmin()->getUsedSize()); TEST_EXIT_DBG(static_cast(x.vec.size()) >= feSpace->getAdmin()->getUsedSize()) ("x.size = %d too small: admin->sizeUsed = %d\n", x.vec.size(), feSpace->getAdmin()->getUsedSize()); Iterator vecIterator(dynamic_cast*>(this), USED_DOFS); Iterator xIterator(dynamic_cast*>(const_cast*>(&x)), USED_DOFS); for (vecIterator.reset(), xIterator.reset(); !vecIterator.end(); ++vecIterator, ++xIterator) { *vecIterator = *xIterator; } } template T DOFVector::min() const { FUNCNAME("DOFVector::min()"); TEST_EXIT_DBG(feSpace && feSpace->getAdmin()) ("pointer is NULL: %8X, %8X\n", this, feSpace->getAdmin()); TEST_EXIT_DBG((static_cast(vec.size())) >= feSpace->getAdmin()->getUsedSize()) ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), feSpace->getAdmin()->getUsedSize()); T m; Iterator vecIterator(const_cast*>(dynamic_cast*>(this)), USED_DOFS); for (vecIterator.reset(), m = *vecIterator; !vecIterator.end(); ++vecIterator) { m = std::min(m, *vecIterator); } return m; } template T DOFVector::max() const { FUNCNAME("DOFVector::max()"); TEST_EXIT_DBG(feSpace && feSpace->getAdmin()) ("pointer is NULL: %8X, %8X\n", this, feSpace->getAdmin()); TEST_EXIT_DBG((static_cast(vec.size())) >= feSpace->getAdmin()->getUsedSize()) ("size = %d too small: admin->sizeUsed = %d\n", vec.size(), feSpace->getAdmin()->getUsedSize()); T m; Iterator vecIterator(const_cast*>(dynamic_cast*>(this)), USED_DOFS); for (vecIterator.reset(), m = *vecIterator; !vecIterator.end(); ++vecIterator) { m = std::max(m, *vecIterator); } return m; } template T DOFVector::absMax() const { return std::max(abs(max()), abs(min())); } template void DOFVector::print() const { FUNCNAME("DOFVector::print()"); const DOFAdmin *admin = NULL; const char *format; if (feSpace) admin = feSpace->getAdmin(); MSG("Vec `%s':\n", name.c_str()); int j = 0; if (admin) { if (admin->getUsedSize() > 100) format = "%s(%3d,%10.5le)"; else if (admin->getUsedSize() > 10) format = "%s(%2d,%10.5le)"; else format = "%s(%1d,%10.5le)"; Iterator vecIterator(dynamic_cast*>(const_cast*>(this)), USED_DOFS); for (vecIterator.reset(); !vecIterator.end(); ++vecIterator) { if ((j % 3) == 0) { if (j) Msg::print("\n"); MSG(format, "", vecIterator.getDOFIndex(), *vecIterator); } else { Msg::print(format, " ", vecIterator.getDOFIndex(), *vecIterator); } j++; } Msg::print("\n"); } else { MSG("no DOFAdmin, print whole vector.\n"); for (int i = 0; i < static_cast( vec.size()); i++) { if ((j % 3) == 0) { if (j) Msg::print("\n"); MSG("(%d,%10.5e)",i,vec[i]); } else { Msg::print(" (%d,%10.5e)",i,vec[i]); } j++; } Msg::print("\n"); } return; } template int DOFVector::calcMemoryUsage() const { int result = 0; result += sizeof(DOFVector); result += vec.size() * sizeof(T); return result; } template T DOFVectorBase::evalUh(const DimVec& lambda, DegreeOfFreedom* dof_indices) { BasisFunction* phi = const_cast(this->getFESpace()->getBasisFcts()); int numberOfBasFcts = phi->getNumber(); T val = 0.0; for (int i = 0; i < numberOfBasFcts; i++) val += (*this)[dof_indices[i]]*(*phi->getPhi(i))(lambda); return val; } template void DOFVector::interpol(AbstractFunction > *fct) { FUNCNAME("interpol"); TEST_EXIT_DBG(fct)("no function to interpolate\n"); interFct = fct; if (!this->getFESpace()) { MSG("no dof admin in vec %s, skipping interpolation\n", this->getName().c_str()); return; } if (!(this->getFESpace()->getAdmin())) { MSG("no dof admin in feSpace %s, skipping interpolation\n", this->getFESpace()->getName().c_str()); return; } if (!(this->getFESpace()->getBasisFcts())) { MSG("no basis functions in admin of vec %s, skipping interpolation\n", this->getName().c_str()); return; } if (!(fct)) { MSG("function that should be interpolated only pointer to NULL, "); Msg::print("skipping interpolation\n"); return; } traverseVector = this; TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(this->getFESpace()->getMesh(), -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); while (elInfo) { interpolFct(elInfo); elInfo = stack.traverseNext(elInfo); } } template int DOFVector::interpolFct(ElInfo* elinfo) { const BasisFunction *basFct = traverseVector->getFESpace()->getBasisFcts(); const DOFAdmin* admin = traverseVector->getFESpace()->getAdmin(); const DegreeOfFreedom *dof = basFct->getLocalIndices(const_cast(elinfo->getElement()), admin, NULL); const T *inter_val = const_cast(basFct)->interpol(elinfo, 0, NULL, traverseVector->interFct, NULL); int number = basFct->getNumber(); for (int i = 0; i < number; i++) (*traverseVector)[dof[i]] = inter_val[i]; return 0; } template double DOFVector::Int(Quadrature* q) const { FUNCNAME("DOFVector::Int()"); Mesh* mesh = feSpace->getMesh(); if (!q) { int deg = 2 * feSpace->getBasisFcts()->getDegree(); q = Quadrature::provideQuadrature(this->dim, deg); } quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *q, INIT_PHI); norm = 0.0; traverseVector = const_cast*>(this); mesh->traverse(-1, Mesh::CALL_LEAF_EL| Mesh::FILL_COORDS | Mesh::FILL_DET, Int_fct); return norm; } template int DOFVector::Int_fct(ElInfo *elinfo) { double det, normT; const T *uh_vec; int iq; det = elinfo->getDet(); uh_vec = traverseVector->getVecAtQPs(elinfo, NULL, quad_fast, NULL); int numPoints = quad_fast->getNumPoints(); for (normT = iq = 0; iq < numPoints; iq++) { normT += quad_fast->getWeight(iq)*(uh_vec[iq]); } norm += det*normT; return 0; } template double DOFVector::L1Norm(Quadrature* q) const { FUNCNAME("DOFVector::L1Norm()"); if (!q) { int deg = 2 * feSpace->getBasisFcts()->getDegree(); q = Quadrature::provideQuadrature(this->dim, deg); } quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(),*q,INIT_PHI); norm = 0.0; traverseVector = const_cast*>(this); Mesh* mesh = feSpace->getMesh(); mesh->traverse(-1, Mesh::CALL_LEAF_EL| Mesh::FILL_COORDS | Mesh::FILL_DET, L1Norm_fct); return norm; } template int DOFVector::L1Norm_fct(ElInfo *elinfo) { double det, normT; const T *uh_loc, *uh_vec; int iq; det = elinfo->getDet(); uh_vec = traverseVector->getVecAtQPs(elinfo, NULL, quad_fast, NULL); int numPoints = quad_fast->getNumPoints(); for (normT = iq = 0; iq < numPoints; iq++) { normT += quad_fast->getWeight(iq)*abs(uh_vec[iq]); } norm += det*normT; return 0; } template double DOFVector::L2NormSquare(Quadrature* q) const { FUNCNAME("DOFVector::L2NormSquare()"); if (!q) { int deg = 2 * feSpace->getBasisFcts()->getDegree(); q = Quadrature::provideQuadrature(this->dim, deg); } quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *q, INIT_PHI); norm = 0.0; traverseVector = const_cast*>(this); Mesh* mesh = feSpace->getMesh(); mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET, L2Norm_fct); return norm; } template int DOFVector::L2Norm_fct(ElInfo *elinfo) { double det, normT; const T *uh_vec; int iq; det = elinfo->getDet(); uh_vec = traverseVector->getVecAtQPs(elinfo, NULL, quad_fast, NULL); int numPoints = quad_fast->getNumPoints(); for (normT = iq = 0; iq < numPoints; iq++) { normT += quad_fast->getWeight(iq)*sqr(uh_vec[iq]); } norm += det*normT; return 0; } template int DOFVector::H1Norm_fct(ElInfo *elinfo) { double norm2, normT; const WorldVector *grduh_vec; int iq, j; double det = elinfo->getDet(); grduh_vec = traverseVector->getGrdAtQPs(elinfo, NULL, quad_fast, NULL); int dimOfWorld = Global::getGeo(WORLD); int numPoints = quad_fast->getNumPoints(); for (normT = iq = 0; iq < numPoints; iq++) { for (norm2 = j = 0; j < dimOfWorld; j++) norm2 += sqr(grduh_vec[iq][j]); normT += quad_fast->getWeight(iq)*norm2; } norm += det*normT; return 0; } template double DOFVector::H1NormSquare(Quadrature *q) const { FUNCNAME("DOFVector::H1NormSquare()"); if (!q) { int deg = 2 * feSpace->getBasisFcts()->getDegree() - 2; q = Quadrature::provideQuadrature(this->dim, deg); } quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *q, INIT_GRD_PHI); norm = 0.0; traverseVector = const_cast*>(this); Mesh *mesh = feSpace->getMesh(); mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET | Mesh::FILL_GRD_LAMBDA, H1Norm_fct); return norm; } template void DOFVector::compressDOFIndexed(int first, int last, std::vector &newDOF) { for (int i = first; i <= last; i++) if (newDOF[i] >= 0) vec[newDOF[i]] = vec[i]; } template Flag DOFVectorBase::getAssembleFlag() { Flag fillFlag(0); for (std::vector::iterator op = this->operators.begin(); op != this->operators.end(); ++op) { fillFlag |= (*op)->getFillFlag(); } return fillFlag; } template void DOFVectorBase::finishAssembling() { // call the operatos cleanup procedures for (std::vector::iterator it = this->operators.begin(); it != this->operators.end(); ++it) { (*it)->finishAssembling(); } } template DOFVector& DOFVector::operator=(const DOFVector& rhs ) { feSpace = rhs.feSpace; DOFVectorBase::feSpace = rhs.feSpace; this->nBasFcts = rhs.nBasFcts; vec = rhs.vec; this->elementVector = new ElementVector(this->nBasFcts); interFct = rhs.interFct; coarsenOperation = rhs.coarsenOperation; this->operators = rhs.operators; this->operatorFactor = rhs.operatorFactor; if (rhs.boundaryManager) { if (this->boundaryManager) delete this->boundaryManager; this->boundaryManager = new BoundaryManager(*rhs.boundaryManager); // boundaryManager->setDOFVector(this); } else { this->boundaryManager = NULL; } return *this; } template const DOFVector& operator*=(DOFVector& x, T scal) { FUNCNAME("DOFVector::operator*=(DOFVector& x, T scal)"); TEST_EXIT_DBG(x.getFESpace() && x.getFESpace()->getAdmin()) ("pointer is NULL: %8X, %8X\n", x.getFESpace(), x.getFESpace()->getAdmin()); typename DOFVector::Iterator vecIterator(dynamic_cast*>(&x), USED_DOFS); for (vecIterator.reset(); !vecIterator.end(); ++vecIterator) { (*vecIterator) *= scal; } return x; } template const DOFVector& operator+=(DOFVector& x, const DOFVector& y) { FUNCNAME("DOFVector::operator+=(DOFVector& x, const DOFVector& y)"); TEST_EXIT_DBG(x.getFESpace() && y.getFESpace()) ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); TEST_EXIT_DBG(x.getFESpace()->getAdmin() && (x.getFESpace()->getAdmin() == y.getFESpace()->getAdmin())) ("no admin or different admins: %8X, %8X\n", x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); TEST_EXIT_DBG(x.getSize() == y.getSize())("different sizes\n"); typename DOFVector::Iterator xIterator(dynamic_cast*>(&x), USED_DOFS); typename DOFVector::Iterator yIterator(dynamic_cast*>(const_cast*>(&y)), USED_DOFS); for (xIterator.reset(), yIterator.reset(); !xIterator.end(); ++xIterator, ++yIterator) { *xIterator += *yIterator; } return x; } template const DOFVector& operator-=(DOFVector& x, const DOFVector& y) { FUNCNAME("DOFVector::operator-=(DOFVector& x, const DOFVector& y)"); TEST_EXIT_DBG(x.getFESpace() && y.getFESpace()) ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); TEST_EXIT_DBG(x.getFESpace()->getAdmin() && (x.getFESpace()->getAdmin() == y.getFESpace()->getAdmin())) ("no admin or different admins: %8X, %8X\n", x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); TEST_EXIT_DBG(x.getSize() == y.getSize())("different sizes\n"); typename DOFVector::Iterator xIterator(dynamic_cast*>(&x), USED_DOFS); typename DOFVector::Iterator yIterator(dynamic_cast*>(const_cast*>(&y)), USED_DOFS); for (xIterator.reset(), yIterator.reset(); !xIterator.end(); ++xIterator, ++yIterator) { *xIterator -= *yIterator; } return x; } template const DOFVector& operator*=(DOFVector& x, const DOFVector& y) { FUNCNAME("DOFVector::operator*=(DOFVector& x, const DOFVector& y)"); TEST_EXIT_DBG(x.getFESpace() && y.getFESpace()) ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); TEST_EXIT_DBG(x.getFESpace()->getAdmin() && (x.getFESpace()->getAdmin() == y.getFESpace()->getAdmin())) ("no admin or different admins: %8X, %8X\n", x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); TEST_EXIT_DBG(x.getSize() == y.getSize())("different sizes\n"); typename DOFVector::Iterator xIterator(dynamic_cast*>(&x), USED_DOFS); typename DOFVector::Iterator yIterator(dynamic_cast*>(const_cast*>(&y)), USED_DOFS); for (xIterator.reset(), yIterator.reset(); !xIterator.end(); ++xIterator, ++yIterator) { *xIterator *= *yIterator; } return x; } template T operator*(DOFVector& x, DOFVector& y) { FUNCNAME("DOFVector::operator*(DOFVector& x, DOFVector& y)"); T dot; const DOFAdmin *admin = NULL; TEST_EXIT(x.getFESpace() && y.getFESpace()) ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); TEST_EXIT((admin = x.getFESpace()->getAdmin()) && (admin == y.getFESpace()->getAdmin())) ("no admin or different admins: %8X, %8X\n", x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); TEST_EXIT(x.getSize() == y.getSize())("different sizes\n"); dot = 0; typename DOFVector::Iterator xIterator(dynamic_cast*>(&x), USED_DOFS); typename DOFVector::Iterator yIterator(dynamic_cast*>(&y), USED_DOFS); for (xIterator.reset(), yIterator.reset(); !xIterator.end(); ++xIterator, ++yIterator) { dot += (*xIterator) * (*yIterator); }; return(dot); } template void mv(MatrixTranspose transpose, const DOFMatrix &a, const DOFVector&x, DOFVector &result, bool add) { // Unfortunately needed using namespace mtl; FUNCNAME("DOFVector::mv()"); TEST_EXIT(a.getRowFESpace() && a.getColFESpace() && x.getFESpace() && result.getFESpace()) ("getFESpace() is NULL: %8X, %8X, %8X, %8X\n", a.getRowFESpace(), a.getColFESpace(), x.getFESpace(), result.getFESpace()); const DOFAdmin *rowAdmin = a.getRowFESpace()->getAdmin(); const DOFAdmin *colAdmin = a.getColFESpace()->getAdmin(); TEST_EXIT((rowAdmin && colAdmin) && (((transpose == NoTranspose) && (colAdmin == x.getFESpace()->getAdmin()) && (rowAdmin == result.getFESpace()->getAdmin()))|| ((transpose == Transpose) && (rowAdmin == x.getFESpace()->getAdmin()) && (colAdmin == result.getFESpace()->getAdmin())))) ("no admin or different admins: %8X, %8X, %8X, %8X\n", a.getRowFESpace()->getAdmin(), a.getColFESpace()->getAdmin(), x.getFESpace()->getAdmin(), result.getFESpace()->getAdmin()); if (transpose == NoTranspose) mult(a.getBaseMatrix(), x, result); else if (transpose == Transpose) mult(trans(const_cast(a.getBaseMatrix())), x, result); else ERROR_EXIT("transpose = %d\n", transpose); } template void axpy(double alpha, const DOFVector& x, DOFVector& y) { FUNCNAME("DOFVector::axpy()"); TEST_EXIT(x.getFESpace() && y.getFESpace()) ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); const DOFAdmin *admin = x.getFESpace()->getAdmin(); TEST_EXIT((admin) && (admin == y.getFESpace()->getAdmin())) ("no admin or different admins: %8X, %8X\n", x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); TEST_EXIT(static_cast(x.getSize()) >= admin->getUsedSize()) ("size = %d too small: admin->size = %d\n", x.getSize(), admin->getUsedSize()); TEST_EXIT(static_cast(y.getSize()) >= admin->getUsedSize()) ("y.size = %d too small: admin->size = %d\n", y.getSize(), admin->getUsedSize()); // This is the old implementation of the mv-multiplication. It have been changed // because of the OpenMP-parallelization: // typename DOFVector::Iterator xIterator(dynamic_cast*>(const_cast*>(&x)), USED_DOFS); // typename DOFVector::Iterator yIterator(dynamic_cast*>(&y), USED_DOFS); // for(xIterator.reset(), yIterator.reset(); // !xIterator.end(); // ++xIterator, ++yIterator) // { // *yIterator += alpha * (*xIterator); // }; int i; int maxI = y.getSize(); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 25000) default(shared) private(i) #endif for (i = 0; i < maxI; i++) { if (!admin->isDOFFree(i)) { y[i] += alpha * x[i]; } } } template const DOFVector& operator*(const DOFVector& v, double d) { static DOFVector result; return mult(d, v, result); } template const DOFVector& operator*(double d, const DOFVector& v) { static DOFVector result; return mult(d, v, result); } template const DOFVector& operator+(const DOFVector &v1 , const DOFVector &v2) { static DOFVector result; return add(v1, v2, result); } template void xpay(double alpha, const DOFVector& x, DOFVector& y) { FUNCNAME("DOFVector::xpay()"); TEST_EXIT(x.getFESpace() && y.getFESpace()) ("feSpace is NULL: %8X, %8X\n", x.getFESpace(), y.getFESpace()); const DOFAdmin *admin = x.getFESpace()->getAdmin(); TEST_EXIT(admin && (admin == y.getFESpace()->getAdmin())) ("no admin or different admins: %8X, %8X\n", x.getFESpace()->getAdmin(), y.getFESpace()->getAdmin()); TEST_EXIT(static_cast(x.getSize()) >= admin->getUsedSize()) ("size = %d too small: admin->size = %d\n", x.getSize(), admin->getUsedSize()); TEST_EXIT(static_cast(y.getSize()) >= admin->getUsedSize()) ("y.size = %d too small: admin->size = %d\n", y.getSize(), admin->getUsedSize()); // This is the old implementation of the mv-multiplication. It have been changed // because of the OpenMP-parallelization: // typename DOFVector::Iterator xIterator(dynamic_cast*>(const_cast*>(&x)), USED_DOFS); // typename DOFVector::Iterator yIterator(dynamic_cast*>(&y), USED_DOFS); // for(xIterator.reset(), yIterator.reset(); // !xIterator.end(); // ++xIterator, ++yIterator) // { // *yIterator = alpha *(*yIterator)+ (*xIterator); // }; int i; int maxI = y.getSize(); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 25000) default(shared) private(i) #endif for (i = 0; i < maxI; i++) { if (!admin->isDOFFree(i)) { y[i] = alpha * y[i] + x[i]; } } } template inline const DOFVector& mult(double scal, const DOFVector& v, DOFVector& result) { typename DOFVector::Iterator vIterator(dynamic_cast*>(const_cast*>(&v)), USED_DOFS); typename DOFVector::Iterator rIterator(dynamic_cast*>(&result), USED_DOFS); for(vIterator.reset(), rIterator.reset(); !vIterator.end(); ++vIterator, ++rIterator) { *rIterator = scal * (*vIterator); }; return result; } template inline const DOFVector& add(const DOFVector& v, double scal, DOFVector& result) { typename DOFVector::Iterator vIterator(dynamic_cast*>(const_cast*>(&v)), USED_DOFS); typename DOFVector::Iterator rIterator(dynamic_cast*>(&result), USED_DOFS); for(vIterator.reset(), rIterator.reset(); !vIterator.end(); ++vIterator, ++rIterator) { *rIterator = (*vIterator) + scal; }; return result; } template inline const DOFVector& add(const DOFVector& v1, const DOFVector& v2, DOFVector& result) { typename DOFVector::Iterator v1Iterator(dynamic_cast*>(const_cast*>(&v1)), USED_DOFS); typename DOFVector::Iterator v2Iterator(dynamic_cast*>(const_cast*>(&v2)), USED_DOFS); typename DOFVector::Iterator rIterator(dynamic_cast*>(&result), USED_DOFS); for(v1Iterator.reset(), v2Iterator.reset(), rIterator.reset(); !v1Iterator.end(); ++v1Iterator, ++v2Iterator, ++rIterator) { *rIterator = (*v1Iterator) + (*v2Iterator); }; return result; } template const T *DOFVectorBase::getLocalVector(const Element *el, T *d) const { static T* localVec = NULL; const DOFAdmin* admin = feSpace->getAdmin(); int i; int nBasFcts = feSpace->getBasisFcts()->getNumber(); T *result; if(d) { result = d; } else { if(localVec) delete [] localVec; localVec = new T[nBasFcts]; result = localVec; } const DegreeOfFreedom *localIndices = feSpace->getBasisFcts()->getLocalIndices(el, admin, NULL); for(i = 0; i < nBasFcts; i++) { result[i] = (*this)[localIndices[i]]; } return result; } template const T *DOFVectorBase::getVecAtQPs(const ElInfo *elInfo, const Quadrature *quad, const FastQuadrature *quadFast, T *vecAtQPs) const { FUNCNAME("DOFVector::getVecAtQPs()"); TEST_EXIT(quad || quadFast)("neither quad nor quadFast defined\n"); if(quad && quadFast) { TEST_EXIT(quad == quadFast->getQuadrature()) ("quad != quadFast->quadrature\n"); } TEST_EXIT(!quadFast || quadFast->getBasisFunctions() == feSpace->getBasisFcts()) ("invalid basis functions"); Element *el = elInfo->getElement(); const Quadrature *quadrature = quadFast ? quadFast->getQuadrature() : quad; const BasisFunction *basFcts = feSpace->getBasisFcts(); int numPoints = quadrature->getNumPoints(); int nBasFcts = basFcts->getNumber(); int i, j; static T *localvec = NULL; T *result; if (vecAtQPs) { result = vecAtQPs; } else { if(localvec) delete [] localvec; localvec = new T[numPoints]; for(i = 0; i < numPoints; i++) { localvec[i] = 0.0; } result = localvec; } const T *localVec = getLocalVector(el, NULL); for(i = 0; i < numPoints; i++) { for(result[i] = j = 0; j < nBasFcts; j++) { result[i] += localVec[j] * (quadFast ? (quadFast->getPhi(i, j)) : ((*(basFcts->getPhi(j)))(quad->getLambda(i)))); } } return const_cast(result); } // Some free functions used in MTL4 template inline std::size_t size(const AMDiS::DOFVector& v) { return v.getSize(); } template inline std::size_t num_rows(const AMDiS::DOFVector& v) { return v.getSize(); } template inline std::size_t num_cols(const AMDiS::DOFVector& v) { return 1; } template inline void set_to_zero(AMDiS::DOFVector& v) { using math::zero; T ref, my_zero(zero(ref)); std::fill(v.begin(), v.end(), my_zero); } template double DOFVector::DoubleWell(Quadrature* q) const { FUNCNAME("DOFVector::DoubleWell()"); if (!q) { int deg = 2 * feSpace->getBasisFcts()->getDegree(); q = Quadrature::provideQuadrature(this->dim, deg); } quad_fast = FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *q, INIT_PHI); norm = 0.0; traverseVector = const_cast*>(this); Mesh* mesh = feSpace->getMesh(); mesh->traverse(-1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET, DoubleWell_fct); return norm; } template int DOFVector::DoubleWell_fct(ElInfo *elinfo) { const T *uh_vec = traverseVector->getVecAtQPs(elinfo, NULL, quad_fast, NULL); int nPoints = quad_fast->getNumPoints(); double normT = 0.0; for (int iq = 0; iq < nPoints; iq++) { normT += quad_fast->getWeight(iq) * sqr(uh_vec[iq]) * sqr(1.0 - uh_vec[iq]); } norm += elinfo->getDet() * normT; return 0; } }