diff --git a/AMDiS/src/DOFVector.cc b/AMDiS/src/DOFVector.cc index 1e165be5f1962c64751fa1e461cf6f9d4fd8b7a6..4006a1960044397128ff294e4b4f88d06d659e8c 100644 --- a/AMDiS/src/DOFVector.cc +++ b/AMDiS/src/DOFVector.cc @@ -892,6 +892,112 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + double localValue = value; + MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM); +#endif + + return value; + } + + + + double integrateGeneral(const std::vector*> &vecs, + AbstractFunction > *fct) + { + FUNCNAME("integrateGeneral()"); + + TEST_EXIT(fct)("No function defined!\n"); + TEST_EXIT(vecs.size()>0)("No DOFVectors provided!\n"); + + int deg = std::max(fct->getDegree(), + 2 * vecs[0].getFeSpace()->getBasisFcts()->getDegree()); + Quadrature* quad = + Quadrature::provideQuadrature(vecs[0].getFeSpace()->getMesh()->getDim(), deg); + FastQuadrature *fastQuad = + FastQuadrature::provideFastQuadrature(vecs[0].getFeSpace()->getBasisFcts(), *quad, INIT_PHI); + + std::vector > qp(vecs.size()); + std::vector qp_local(vecs.size()); + for (size_t i = 0; i < vecs.size(); i++) + qp[i].change_dim(fastQuad->getNumPoints()); + + double value = 0.0; + Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(vec1.getFeSpace()->getMesh(), -1, traverseFlag); + while (elInfo) { + for (size_t i = 0; i < vecs.size(); i++) + vecs[i].getVecAtQPs(elInfo, quad, fastQuad, qp[i]); + + double tmp = 0.0; + for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) { + for (size_t i = 0; i < vecs.size(); i++) + qp_local[i] = qp[i][iq]; + tmp += fastQuad->getWeight(iq) * (*fct)(qp_local); + } + value += tmp * elInfo->getDet(); + + elInfo = stack.traverseNext(elInfo); + } + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + double localValue = value; + MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM); +#endif + + return value; + } + + double integrateGeneralGradient(const std::vector*> &vecs, + const std::vector*> &grds, + BinaryAbstractFunction, std::vector > *fct) + { + FUNCNAME("integrateGeneral()"); + + TEST_EXIT(fct)("No function defined!\n"); + TEST_EXIT(vecs.size()>0)("No DOFVectors provided!\n"); + TEST_EXIT(grds.size()>0)("No DOFVectors for gradients provided!\n"); + + int deg = std::max(fct->getDegree(), + 2 * vecs[0].getFeSpace()->getBasisFcts()->getDegree()); + Quadrature* quad = + Quadrature::provideQuadrature(vecs[0].getFeSpace()->getMesh()->getDim(), deg); + FastQuadrature *fastQuad = + FastQuadrature::provideFastQuadrature(vecs[0].getFeSpace()->getBasisFcts(), *quad, INIT_PHI); + + std::vector > qp(vecs.size()); + std::vector > > qpGrd(vecs.size()); + std::vector qp_local(vecs.size()); + std::vector > grd_local(grds.size()); + for (size_t i = 0; i < vecs.size(); i++) + qp[i].change_dim(fastQuad->getNumPoints()); + for (size_t i = 0; i < grds.size(); i++) + qpGrd[i].change_dim(fastQuad->getNumPoints()); + + double value = 0.0; + Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET; + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(vec1.getFeSpace()->getMesh(), -1, traverseFlag); + while (elInfo) { + for (size_t i = 0; i < vecs.size(); i++) + vecs[i].getVecAtQPs(elInfo, quad, fastQuad, qp[i]); + for (size_t i = 0; i < grds.size(); i++) + grds[i].getGradientAtQPs(elInfo, quad, fastQuad, qpGrd[i]); + + double tmp = 0.0; + for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) { + for (size_t i = 0; i < vecs.size(); i++) + qp_local[i] = qp[i][iq]; + for (size_t i = 0; i < grds.size(); i++) + grd_local[i] = qpGrd[i][iq]; + tmp += fastQuad->getWeight(iq) * (*fct)(qp_local, grd_local); + } + value += tmp * elInfo->getDet(); + + elInfo = stack.traverseNext(elInfo); + } + #ifdef HAVE_PARALLEL_DOMAIN_AMDIS double localValue = value; MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM); diff --git a/AMDiS/src/DOFVector.h b/AMDiS/src/DOFVector.h index 2e32398985252bce68775fd4f2b82aa826c03785..533c611817b87d269f8b0fa056f9cf549b5c6634 100644 --- a/AMDiS/src/DOFVector.h +++ b/AMDiS/src/DOFVector.h @@ -578,6 +578,9 @@ namespace AMDiS { TEST_EXIT(false)("Please implement your evaluation\n"); } + const bool getDOFidxAtPoint(WorldVector &p, DegreeOfFreedom &idx, ElInfo *oldElInfo = NULL, bool useOldElInfo = false); + + /// Writes the data of the DOFVector to an output stream. void serialize(std::ostream &out) { @@ -865,8 +868,13 @@ namespace AMDiS { double integrate(const FiniteElemSpace* feSpace, AbstractFunction > *fct); - - + + double integrateGeneral(const std::vector*> &vecs, + AbstractFunction > *fct); + + double integrateGeneralGradient(const std::vector*> &vecs, + const std::vector*> &grds, + BinaryAbstractFunction, std::vector > *fct); } #include "DOFVector.hh" diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh index d0757085cb53cd9a8a915fae03a02859cb5baa36..0e8a98c8ccc82b8dc1488af0806f746fbe181b2d 100644 --- a/AMDiS/src/DOFVector.hh +++ b/AMDiS/src/DOFVector.hh @@ -676,6 +676,59 @@ namespace AMDiS { } + + template + bool DOFVector::getDOFidxAtPoint(WorldVector &p, DegreeOfFreedom &idx, ElInfo *oldElInfo, bool useOldElInfo) + { FUNCNAME("DOFVector::getDOFidxAtPoint()"); + + Mesh *mesh = feSpace->getMesh(); + const BasisFunction *basFcts = feSpace->getBasisFcts(); + + int dim = mesh->getDim(); + int numBasFcts = basFcts->getNumber(); + + std::vector localIndices(numBasFcts); + DimVec lambda(dim, NO_INIT); + + ElInfo *elInfo = mesh->createNewElInfo(); + idx = 0; + inside = false; + + if (oldElInfo && useOldElInfo && oldElInfo->getMacroElement()) { + inside = mesh->findElInfoAtPoint(p, elInfo, lambda, oldElInfo->getMacroElement(), NULL, NULL); + delete oldElInfo; + } else { + inside = mesh->findElInfoAtPoint(p, elInfo, lambda, NULL, NULL, NULL); + } + + if (oldElInfo) + oldElInfo = elInfo; + + if (!inside) + return false; + + basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), localIndices); + FixVec, VERTEX> coords = elInfo->getCoords(); + int minIdx = -1; + double minDist = 1.e15; + + for (int i = 0; i < coords.size(); i++) { + WorldVector dist = coords[i] - p; + double newDist = norm(dist); + if (newDist < minDist) { + minIdx = i; + minDist = newDist; + } + } + + if (minIdx >= 0) + idx = localIndices[minIdx]; + + if(!oldElInfo) delete elInfo; + return inside; + }; + + template void DOFVector::compressDOFIndexed(int first, int last, std::vector &newDOF) diff --git a/AMDiS/src/Initfile.h b/AMDiS/src/Initfile.h index 3e901be29890dec3f2c547e14efaac3031de9131..23c9e3615a0b8b01f44725e3a1582cf1cabe7889 100644 --- a/AMDiS/src/Initfile.h +++ b/AMDiS/src/Initfile.h @@ -168,18 +168,18 @@ namespace AMDiS { // accepted brackets and delimiters for vector input std::string begBrackets= "{[("; std::string endBrackets= "}])"; - std::string delims= ",;"; + std::string delims= ";,"; c.clear(); - std::string val = trim(val_); + std::string val = trim(val_); + bool hasBrackets = true; size_t pos = begBrackets.find(val[0]); if (pos == std::string::npos) - throw WrongVectorFormat("cannot convert " - "'" + val + "' into a list. No leading bracket found!"); - if (val[val.length() - 1] != endBrackets[pos]) + hasBrackets = false; + if (hasBrackets && val[val.length() - 1] != endBrackets[pos]) throw WrongVectorFormat("begin and end bracket are different in" " value '" + val + "'"); - size_t oldPos = 1; + size_t oldPos = (hasBrackets ? 1 : 0); size_t curDelim = 0; typedef typename Container::value_type ValueType; ValueType swap; @@ -194,11 +194,11 @@ namespace AMDiS { pos = val.find(delims[curDelim], oldPos); } //last entry - std::string curWord = val.substr(oldPos, val.length() - 1 - oldPos); + std::string curWord = val.substr(oldPos, val.length() - (hasBrackets ? 1 : 0) - oldPos); convert(curWord, swap); c.push_back(swap); } catch (NoDelim nd) { - std::string curWord = val.substr(1, val.length() - 2); + std::string curWord = val.substr(oldPos, val.length() - (hasBrackets ? 2 : 0)); curWord = trim(curWord); if (curWord.length() > 0) { // container with one entry diff --git a/AMDiS/src/SystemVector.h b/AMDiS/src/SystemVector.h index 0289c1b594a38468d75e4e39ad384ec396b34fbf..cd413fa0f43ecf9026c33f5f6a6ac5418a9ec0e5 100644 --- a/AMDiS/src/SystemVector.h +++ b/AMDiS/src/SystemVector.h @@ -49,13 +49,13 @@ namespace AMDiS { /// Copy Constructor. SystemVector(const SystemVector& rhs) - : name(rhs.name), - feSpace(rhs.feSpace), - vectors(rhs.vectors.getSize()) + : name(rhs.getName()), + feSpace(rhs.getFeSpaces()), + vectors(rhs.getNumVectors()) { for (int i = 0; i < vectors.getSize(); i++) - vectors[i] = new DOFVector(*rhs.vectors[i]); + vectors[i] = new DOFVector(*rhs.getDOFVector(i)); } ~SystemVector() @@ -91,6 +91,11 @@ namespace AMDiS { return vectors[index]; } + inline std::string getName() const + { + return name; + } + /// Returns sum of used vector sizes. inline int getUsedSize() const {