From 1f9daa76bc54b81ef8b05ac57b94134bf2bf6999 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Wed, 12 Jan 2011 09:18:19 +0000 Subject: [PATCH] Added some parallel debuging test for periodic boundary conditions. --- AMDiS/src/AdaptInfo.h | 4 +- AMDiS/src/Boundary.h | 2 +- AMDiS/src/CoarseningManager.cc | 4 +- AMDiS/src/CoarseningManager1d.cc | 2 +- AMDiS/src/DOFAdmin.cc | 6 +- AMDiS/src/DOFIterator.h | 2 +- AMDiS/src/Error.hh | 2 +- AMDiS/src/Global.h | 11 - AMDiS/src/MathFunctions.h | 14 +- AMDiS/src/Mesh.cc | 45 ++-- AMDiS/src/Mesh.h | 28 +++ AMDiS/src/Operator.cc | 2 +- AMDiS/src/Parameters.cc | 2 +- AMDiS/src/RefinementManager1d.cc | 2 +- AMDiS/src/RefinementManager2d.cc | 4 +- AMDiS/src/RefinementManager3d.cc | 7 +- AMDiS/src/ResidualEstimator.cc | 4 +- AMDiS/src/Tetrahedron.h | 2 +- AMDiS/src/Triangle.h | 2 +- AMDiS/src/VertexVector.cc | 8 +- AMDiS/src/io/MacroInfo.cc | 8 +- AMDiS/src/io/MacroReader.cc | 12 +- AMDiS/src/io/PovrayWriter.cc | 24 +- AMDiS/src/parallel/ElementObjectData.cc | 130 +++++++---- AMDiS/src/parallel/ElementObjectData.h | 22 +- AMDiS/src/parallel/InteriorBoundary.cc | 7 +- AMDiS/src/parallel/MeshDistributor.cc | 267 ++++++++++++---------- AMDiS/src/parallel/ParMetisPartitioner.cc | 8 +- AMDiS/src/parallel/ParallelDebug.cc | 96 +++++++- AMDiS/src/parallel/ParallelDebug.h | 5 + AMDiS/src/parallel/PetscSolver.cc | 11 +- 31 files changed, 479 insertions(+), 264 deletions(-) diff --git a/AMDiS/src/AdaptInfo.h b/AMDiS/src/AdaptInfo.h index 52b33ace..ac7b2f1c 100644 --- a/AMDiS/src/AdaptInfo.h +++ b/AMDiS/src/AdaptInfo.h @@ -367,7 +367,7 @@ namespace AMDiS { /// Sets \ref timestepNumber. inline void setTimestepNumber(int num) { - timestepNumber = AMDiS::min(nTimesteps,num); + timestepNumber = std::min(nTimesteps, num); } /// Returns \ref nTimesteps. @@ -379,7 +379,7 @@ namespace AMDiS { /// Sets \ref nTimesteps. inline void setNumberOfTimesteps(int num) { - nTimesteps = AMDiS::max(0,num); + nTimesteps = std::max(0, num); } /// Increments \ref timestepNumber by 1; diff --git a/AMDiS/src/Boundary.h b/AMDiS/src/Boundary.h index 4cd2f773..40c7634b 100644 --- a/AMDiS/src/Boundary.h +++ b/AMDiS/src/Boundary.h @@ -43,4 +43,4 @@ namespace AMDiS { } -#endif // _Boundary_H_ +#endif diff --git a/AMDiS/src/CoarseningManager.cc b/AMDiS/src/CoarseningManager.cc index 14b26a68..6ba5f78d 100644 --- a/AMDiS/src/CoarseningManager.cc +++ b/AMDiS/src/CoarseningManager.cc @@ -45,7 +45,7 @@ namespace AMDiS { if (el->getChild(0)) { // interior node of the tree - int mark = max(el->getChild(0)->getMark(), el->getChild(1)->getMark()); + int mark = std::max(el->getChild(0)->getMark(), el->getChild(1)->getMark()); el->setMark(std::min(mark + 1, 0)); } else { // leaf node of the tree @@ -63,7 +63,7 @@ namespace AMDiS { ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); while (elInfo) { Element *el = elInfo->getElement(); - el->setMark(max(el->getMark(), 0)); + el->setMark(std::max(el->getMark(), 0)); elInfo = stack.traverseNext(elInfo); } } diff --git a/AMDiS/src/CoarseningManager1d.cc b/AMDiS/src/CoarseningManager1d.cc index 37a62db0..8d4972d1 100644 --- a/AMDiS/src/CoarseningManager1d.cc +++ b/AMDiS/src/CoarseningManager1d.cc @@ -57,7 +57,7 @@ namespace AMDiS { int mark0 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>(parent->getChild(0)))); int mark1 = coarsenRecursive(dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1)))); - mark = max(mark0, mark1); + mark = std::max(mark0, mark1); child[0] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(0))); child[1] = dynamic_cast<Line*>(const_cast<Element*>( parent->getChild(1))); diff --git a/AMDiS/src/DOFAdmin.cc b/AMDiS/src/DOFAdmin.cc index dfc07484..67c604db 100644 --- a/AMDiS/src/DOFAdmin.cc +++ b/AMDiS/src/DOFAdmin.cc @@ -167,7 +167,7 @@ namespace AMDiS { usedCount++; if (holeCount > 0) holeCount--; - sizeUsed = max(sizeUsed, dof + 1); + sizeUsed = std::max(sizeUsed, dof + 1); return dof; } @@ -182,7 +182,7 @@ namespace AMDiS { if (old > minsize) return; - int newval = max(minsize, static_cast<int>((dofFree.size() + sizeIncrement))); + int newval = std::max(minsize, static_cast<int>((dofFree.size() + sizeIncrement))); size = newval; @@ -324,7 +324,7 @@ namespace AMDiS { for (std::list<DOFContainer*>::iterator dc = dofContainerList.begin(); dc != dofContainerList.end(); ++dc) - (*dc)->compressDofContainer(n, newDofIndex); + (*dc)->compressDofContainer(n, newDofIndex); } diff --git a/AMDiS/src/DOFIterator.h b/AMDiS/src/DOFIterator.h index ea97dcef..815fe658 100644 --- a/AMDiS/src/DOFIterator.h +++ b/AMDiS/src/DOFIterator.h @@ -173,7 +173,7 @@ namespace AMDiS { } /// Dereferntiation of the \ref dofFreeIterator - virtual bool isDOFFree() + virtual bool isDofFree() { return *dofFreeIterator; } diff --git a/AMDiS/src/Error.hh b/AMDiS/src/Error.hh index 7fcbaecd..ae26ec46 100644 --- a/AMDiS/src/Error.hh +++ b/AMDiS/src/Error.hh @@ -77,7 +77,7 @@ namespace AMDiS { for (int i = 0; i < nPoints; i++) { err = u_vec[i] > uh_vec[i] ? u_vec[i] - uh_vec[i] : uh_vec[i] - u_vec[i]; - maxErr = max(maxErr, err); + maxErr = std::max(maxErr, err); } elInfo = stack.traverseNext(elInfo); diff --git a/AMDiS/src/Global.h b/AMDiS/src/Global.h index ebefbcb1..64e17af7 100644 --- a/AMDiS/src/Global.h +++ b/AMDiS/src/Global.h @@ -117,17 +117,6 @@ namespace AMDiS { // ===== some simple template functions ====================================== - /// template<typename T> T max(T a,T b ) {return ((a) > (b) ? (a) : (b));} - template<typename T,typename S> inline T max(T a,S b ) - { - return ((a) > (b) ? (a) : (b)); - } - - template<typename T> inline T min(T a,T b) - { - return ((a) < (b)) ? (a) : (b); - } - template<typename T> inline T abs(T a) { return ((a) >= 0 ? (a) : -(a)); diff --git a/AMDiS/src/MathFunctions.h b/AMDiS/src/MathFunctions.h index 26063236..aa354f5e 100644 --- a/AMDiS/src/MathFunctions.h +++ b/AMDiS/src/MathFunctions.h @@ -42,15 +42,17 @@ namespace AMDiS { return 0; } - inline double Phi1ToR(double p1, double eps) { - double x = max(-1.0 + numeric_limits< double >::epsilon(), - min(1.0 - numeric_limits< double >::epsilon(), p1)); + inline double Phi1ToR(double p1, double eps) + { + double x = std::max(-1.0 + numeric_limits<double>::epsilon(), + std::min(1.0 - numeric_limits<double>::epsilon(), p1)); return eps / 3.0 * log((1 + x) / (1 - x)) * 0.5; } - inline double Phi2ToR(double p2, double eps) { - double x = max(-1.0 + numeric_limits< double >::epsilon(), - min(1.0 - numeric_limits< double >::epsilon(), 1 + 2 * p2)); + inline double Phi2ToR(double p2, double eps) + { + double x = std::max(-1.0 + numeric_limits<double>::epsilon(), + std::min(1.0 - numeric_limits<double>::epsilon(), 1 + 2 * p2)); return eps / 3.0 * log( (1 + x) / (1 - x) ); } diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc index cd2a656a..f140ca49 100644 --- a/AMDiS/src/Mesh.cc +++ b/AMDiS/src/Mesh.cc @@ -102,9 +102,12 @@ namespace AMDiS { changeIndex(0), final_lambda(dimension, DEFAULT_VALUE, 0.0) { - FUNCNAME("Mesh::Mesh()"); +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + nParallelPreRefinements = 0; +#endif + // set default element prototype switch(dim) { case 1: @@ -1248,42 +1251,41 @@ namespace AMDiS { // nMacroElements * 2^gr >= nProcs * 10 // => gr = log_2(nProcs * 10 / nMacroElements) - double tmp = 10.0 * MPI::COMM_WORLD.Get_size() / nMacroElements; - int nrRefine = ceil(log(tmp) / log(2)); - if (nrRefine < 0) - nrRefine = 0; + double scale = 10.0 * MPI::COMM_WORLD.Get_size() / nMacroElements; + nParallelPreRefinements = static_cast<int>(std::max(0.0, ceil(log(scale) / log(2)))); if (dim == 3) { - int newElType = (elType + nrRefine) % 3; + int newElType = (elType + nParallelPreRefinements) % 3; switch (newElType) { case 1: - if (nrRefine > 0) - nrRefine--; + if (nParallelPreRefinements > 0) + nParallelPreRefinements--; else - nrRefine = 2; + nParallelPreRefinements = 2; break; case 2: - nrRefine++; + nParallelPreRefinements++; break; } - TEST_EXIT((elType + nrRefine) % 3 == 0)("This should not happen!\n"); + TEST_EXIT((elType + nParallelPreRefinements) % 3 == 0) + ("This should not happen!\n"); } // === Check if number of pre refinements is set ini init file. === - int nPreRefine = 0; - GET_PARAMETER(0, "parallel->pre refine", "%d", &nPreRefine); - if (nPreRefine != 0) { + int tmp = 0; + GET_PARAMETER(0, "parallel->pre refine", "%d", &tmp); + if (tmp != 0) { MSG("Calculated %d pre refines to be useful, but %d are set in init file!\n", - nrRefine, nPreRefine); - nrRefine = nPreRefine; + nParallelPreRefinements, tmp); + nParallelPreRefinements = tmp; } // === If we do not need to refine the mesh, return back. === - if (nrRefine == 0) + if (nParallelPreRefinements == 0) return; @@ -1323,7 +1325,7 @@ namespace AMDiS { else refManager = new RefinementManager3d(); - refManager->globalRefine(&testMesh, nrRefine); + refManager->globalRefine(&testMesh, nParallelPreRefinements); delete refManager; Lagrange* basFcts = Lagrange::getLagrange(dim, 1); @@ -1348,21 +1350,20 @@ namespace AMDiS { int globalRefinements = 0; GET_PARAMETER(0, name + "->global refinements", "%d", &globalRefinements); - if (globalRefinements < nrRefine) + if (globalRefinements < nParallelPreRefinements) globalRefinements = 0; else - globalRefinements -= nrRefine; + globalRefinements -= nParallelPreRefinements; std::stringstream oss; oss << globalRefinements; - ADD_PARAMETER(0, name + "->global refinements", oss.str().c_str()); // === Print a note to the screen that another mesh file will be used. === MSG("The macro mesh file \"%s\" was refined %d times and stored to file \"%s\".\n", - macroFilename.c_str(), nrRefine, newMacroFilename.str().c_str()); + macroFilename.c_str(), nParallelPreRefinements, newMacroFilename.str().c_str()); macroFilename = newMacroFilename.str(); if (periodicFilename != "") diff --git a/AMDiS/src/Mesh.h b/AMDiS/src/Mesh.h index 93c9b8e7..0b0a0bea 100644 --- a/AMDiS/src/Mesh.h +++ b/AMDiS/src/Mesh.h @@ -608,6 +608,21 @@ namespace AMDiS { /// void deleteMeshStructure(); +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + /// In parallel computations the level of all macro elements is equal to the number + /// of global pre refinements, \ref nParallelPreRefinements. + inline int getMacroElementLevel() + { + return nParallelPreRefinements; + } +#else + /// In sequentiel computations the level of all macro elements is always 0. + inline int getMacroElementLevel() + { + return 0; + } +#endif + public: /// static const Flag FILL_NOTHING; @@ -702,6 +717,12 @@ namespace AMDiS { void checkParallelMacroFile(std::string ¯oFilename, std::string &periodicFilename, int check); + + /// Returns \ref nParallelPreRefinements + int getParallelPreRefinements() const + { + return nParallelPreRefinements; + } #endif protected: @@ -855,6 +876,13 @@ namespace AMDiS { */ long changeIndex; +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + /// In parallel computations the mesh may be globally prerefined to achieve a fine + /// enought starting mesh for the given number of ranks. The value of the variable + /// will be defined in function \ref checkParallelMacroFile. + int nParallelPreRefinements; +#endif + protected: /// for findElement-Fcts DimVec<double> final_lambda; diff --git a/AMDiS/src/Operator.cc b/AMDiS/src/Operator.cc index 6ef9f206..57b8d76d 100644 --- a/AMDiS/src/Operator.cc +++ b/AMDiS/src/Operator.cc @@ -53,7 +53,7 @@ namespace AMDiS { for (int i = 0; i < static_cast<int>(terms->size()); i++) { OperatorTerm *term = (*terms)[i]; - maxTermDegree = max(maxTermDegree, term->degree); + maxTermDegree = std::max(maxTermDegree, term->degree); } return psiDegree + phiDegree - order + maxTermDegree; diff --git a/AMDiS/src/Parameters.cc b/AMDiS/src/Parameters.cc index c04502a7..9559167c 100644 --- a/AMDiS/src/Parameters.cc +++ b/AMDiS/src/Parameters.cc @@ -50,7 +50,7 @@ namespace AMDiS { if (Parameters::singlett->paramInfo) { if (Parameters::singlett->paramInfo > 1) - info = max(info, Parameters::singlett->paramInfo - 1); + info = std::max(info, Parameters::singlett->paramInfo - 1); } else { info = 0; } diff --git a/AMDiS/src/RefinementManager1d.cc b/AMDiS/src/RefinementManager1d.cc index d26cf503..6bc99dad 100644 --- a/AMDiS/src/RefinementManager1d.cc +++ b/AMDiS/src/RefinementManager1d.cc @@ -41,7 +41,7 @@ namespace AMDiS { child[0] = dynamic_cast<Line*>(mesh->createNewElement(el)); child[1] = dynamic_cast<Line*>(mesh->createNewElement(el)); - int mark = max(0, el->getMark() - 1); + int mark = std::max(0, el->getMark() - 1); child[0]->setMark(mark); child[1]->setMark(mark); el->setMark(0); diff --git a/AMDiS/src/RefinementManager2d.cc b/AMDiS/src/RefinementManager2d.cc index d730ca9f..601a67cf 100644 --- a/AMDiS/src/RefinementManager2d.cc +++ b/AMDiS/src/RefinementManager2d.cc @@ -257,7 +257,7 @@ namespace AMDiS { child[0] = dynamic_cast<Triangle*>(mesh->createNewElement(el)); child[1] = dynamic_cast<Triangle*>(mesh->createNewElement(el)); - int newMark = max(0, el->getMark() - 1); + int newMark = std::max(0, el->getMark() - 1); child[0]->setMark(newMark); child[1]->setMark(newMark); el->setMark(0); @@ -334,7 +334,7 @@ namespace AMDiS { int opp_vertex = (*elInfo)->getOppVertex(2); ElInfo *neigh_info = stack->traverseNeighbour2d(*elInfo, 2); - neigh_info->getElement()->setMark(max(neigh_info->getElement()->getMark(), 1)); + neigh_info->getElement()->setMark(std::max(neigh_info->getElement()->getMark(), 1)); neigh_info = refineFunction(neigh_info); // === Now go back to the original element and refine the patch. === diff --git a/AMDiS/src/RefinementManager3d.cc b/AMDiS/src/RefinementManager3d.cc index b5f2ad0e..e3cde25c 100644 --- a/AMDiS/src/RefinementManager3d.cc +++ b/AMDiS/src/RefinementManager3d.cc @@ -25,6 +25,7 @@ #include "DOFVector.h" #include "PeriodicBC.h" #include "VertexVector.h" +#include "Debug.h" namespace AMDiS { @@ -41,7 +42,7 @@ namespace AMDiS { child[0] = dynamic_cast<Tetrahedron*>(mesh->createNewElement(el)); child[1] = dynamic_cast<Tetrahedron*>(mesh->createNewElement(el)); - int mark = max(0, el->getMark() - 1); + int mark = std::max(0, el->getMark() - 1); child[0]->setMark(mark); child[1]->setMark(mark); el->setMark(0); @@ -249,6 +250,8 @@ namespace AMDiS { int RefinementManager3d::newCoordsFct(ElInfo *el_info) { + FUNCNAME("RefinementManager3d::newCoordsFct()"); + Element *el = el_info->getElement(); DegreeOfFreedom *edge[2]; ElInfo *elinfo = el_info; @@ -474,7 +477,7 @@ namespace AMDiS { // Only 0 can be a compatible commen refinement edge. Thus, neigh has not // a compatible refinement edge. Refine it first. - neigh->setMark(max(neigh->getMark(), 1)); + neigh->setMark(std::max(neigh->getMark(), 1)); neighInfo = refineFunction(neighInfo); diff --git a/AMDiS/src/ResidualEstimator.cc b/AMDiS/src/ResidualEstimator.cc index 52f05c6b..2b9e8fbc 100644 --- a/AMDiS/src/ResidualEstimator.cc +++ b/AMDiS/src/ResidualEstimator.cc @@ -256,7 +256,7 @@ namespace AMDiS { el->setEstimation(est_el, row); el->setMark(0); est_sum += est_el; - est_max = max(est_max, est_el); + est_max = std::max(est_max, est_el); } @@ -295,7 +295,7 @@ namespace AMDiS { } double v = C3 * det * result; est_t_sum += v; - est_t_max = max(est_t_max, v); + est_t_max = std::max(est_t_max, v); } } } diff --git a/AMDiS/src/Tetrahedron.h b/AMDiS/src/Tetrahedron.h index 1a3f274f..0f77b8bd 100644 --- a/AMDiS/src/Tetrahedron.h +++ b/AMDiS/src/Tetrahedron.h @@ -274,7 +274,7 @@ namespace AMDiS { DegreeOfFreedom dof0 = dof[vertexOfEdge[localEdgeIndex][0]][0]; DegreeOfFreedom dof1 = dof[vertexOfEdge[localEdgeIndex][1]][0]; - DofEdge edge = std::make_pair(min(dof0, dof1), max(dof0, dof1)); + DofEdge edge = std::make_pair(std::min(dof0, dof1), std::max(dof0, dof1)); return edge; } diff --git a/AMDiS/src/Triangle.h b/AMDiS/src/Triangle.h index ef141a01..f6a7f045 100644 --- a/AMDiS/src/Triangle.h +++ b/AMDiS/src/Triangle.h @@ -178,7 +178,7 @@ namespace AMDiS { DegreeOfFreedom dof0 = dof[vertexOfEdge[localEdgeIndex][0]][0]; DegreeOfFreedom dof1 = dof[vertexOfEdge[localEdgeIndex][1]][0]; - DofEdge edge = std::make_pair(min(dof0, dof1), max(dof0, dof1)); + DofEdge edge = std::make_pair(std::min(dof0, dof1), std::max(dof0, dof1)); return edge; } diff --git a/AMDiS/src/VertexVector.cc b/AMDiS/src/VertexVector.cc index 3544a529..886baabd 100644 --- a/AMDiS/src/VertexVector.cc +++ b/AMDiS/src/VertexVector.cc @@ -26,29 +26,33 @@ namespace AMDiS { const_cast<DOFAdmin*>(admin)->addDOFContainer(this); } + VertexVector::~VertexVector() { const_cast<DOFAdmin*>(admin)->removeDOFIndexed(this); const_cast<DOFAdmin*>(admin)->removeDOFContainer(this); } + void VertexVector::set(DegreeOfFreedom val) { DOFIteratorBase it(const_cast<DOFAdmin*>(admin), USED_DOFS); for (it.reset(); !it.end(); ++it) - if (!it.isDOFFree()) + if (!it.isDofFree()) operator[](it.getDOFIndex()) = val; } + void VertexVector::print() { DOFIteratorBase it(const_cast<DOFAdmin*>(admin), USED_DOFS); for (it.reset(); !it.end(); ++it) - if (!it.isDOFFree()) + if (!it.isDofFree()) std::cout << "DOF " << it.getDOFIndex() << " -> " << operator[](it.getDOFIndex()) << "\n"; } + void VertexVector::changeDofIndices(std::map<int, int>& dofIndexMap) { FUNCNAME("VertexVector::changedofIndices()"); diff --git a/AMDiS/src/io/MacroInfo.cc b/AMDiS/src/io/MacroInfo.cc index c0ae8aea..a1a853ae 100644 --- a/AMDiS/src/io/MacroInfo.cc +++ b/AMDiS/src/io/MacroInfo.cc @@ -525,19 +525,19 @@ namespace AMDiS { int j1 = mel_vertex[i][(j + 1) % 3]; int j2 = mel_vertex[i][(j + 2) % 3]; - bound[j1] = max(bound[j1], (*melIt)->getBoundary(j)); - bound[j2] = max(bound[j2], (*melIt)->getBoundary(j)); + bound[j1] = std::max(bound[j1], (*melIt)->getBoundary(j)); + bound[j2] = std::max(bound[j2], (*melIt)->getBoundary(j)); } else if ((*melIt)->getBoundary(j) <= NEUMANN) { int j1 = mel_vertex[i][(j + 1) % 3]; int j2 = mel_vertex[i][(j + 2) % 3]; if (bound[j1] != INTERIOR) - bound[j1] = max(bound[j1], (*melIt)->getBoundary(j)); + bound[j1] = std::max(bound[j1], (*melIt)->getBoundary(j)); else bound[j1] = (*melIt)->getBoundary(j); if (bound[j2] != INTERIOR) - bound[j2] = max(bound[j2], (*melIt)->getBoundary(j)); + bound[j2] = std::max(bound[j2], (*melIt)->getBoundary(j)); else bound[j2] = (*melIt)->getBoundary(j); } diff --git a/AMDiS/src/io/MacroReader.cc b/AMDiS/src/io/MacroReader.cc index 31594995..484c6467 100644 --- a/AMDiS/src/io/MacroReader.cc +++ b/AMDiS/src/io/MacroReader.cc @@ -495,23 +495,19 @@ namespace AMDiS { periodic[it->elementSide] = true; } - for (k = 0; k < mesh->getGeo(EDGE); k++) { - /*********************************************************************/ - /* check for not counted edges */ - /*********************************************************************/ + for (k = 0; k < mesh->getGeo(EDGE); k++) { + // === Check for not counted edges. === n_neigh = 1; if (newEdge(mesh, (*(mel + i)), k, &n_neigh)) { mesh->incrementNumberOfEdges(1); - max_n_neigh = max(max_n_neigh, n_neigh); + max_n_neigh = std::max(max_n_neigh, n_neigh); } } for (k = 0; k < mesh->getGeo(NEIGH); k++) { neigh = (*(mel + i))->getNeighbour(k); - /*********************************************************************/ - /* face is counted and dof is added by the element with bigger index */ - /*********************************************************************/ + // === Face is counted and dof is added by the element with bigger index. === if (neigh && (neigh->getIndex() > (*(mel + i))->getIndex())) continue; diff --git a/AMDiS/src/io/PovrayWriter.cc b/AMDiS/src/io/PovrayWriter.cc index 32b94e8d..1c1d52c5 100644 --- a/AMDiS/src/io/PovrayWriter.cc +++ b/AMDiS/src/io/PovrayWriter.cc @@ -59,8 +59,8 @@ namespace AMDiS { min_value = max_value = (*values)[0]; for (int index = 1; index < values->getSize(); index++) { - min_value = min(min_value, (*values)[index]); - max_value = max(max_value, (*values)[index]); + min_value = std::min(min_value, (*values)[index]); + max_value = std::max(max_value, (*values)[index]); } /* map DOFs to values */ @@ -126,13 +126,13 @@ namespace AMDiS { for (it.reset(); !it.end(); ++it) { // initialize mit and max values with coordinates of first vertex std::list<VertexInfo>::iterator it2 = it->begin(); - bBox->minx = min(bBox->minx, it2->coords[0]); - bBox->maxx = max(bBox->maxx, it2->coords[0]); - bBox->miny = min(bBox->miny, it2->coords[1]); - bBox->maxy = max(bBox->maxy, it2->coords[1]); + bBox->minx = std::min(bBox->minx, it2->coords[0]); + bBox->maxx = std::max(bBox->maxx, it2->coords[0]); + bBox->miny = std::min(bBox->miny, it2->coords[1]); + bBox->maxy = std::max(bBox->maxy, it2->coords[1]); if (dow == 3) { - bBox->minz = min(bBox->minz, it2->coords[2]); - bBox->maxz = max(bBox->maxz, it2->coords[2]); + bBox->minz = std::min(bBox->minz, it2->coords[2]); + bBox->maxz = std::max(bBox->maxz, it2->coords[2]); } } @@ -149,8 +149,8 @@ namespace AMDiS { // determines the color for a given value/weight string getColorString(double &value) { - value = max(0.0, value); - value = min(value, 1.0); + value = std::max(0.0, value); + value = std::min(value, 1.0); // rot: 1,0,0 // blau: 0,0,1 @@ -324,8 +324,8 @@ namespace AMDiS { for (std::list<VertexInfo>::iterator it2 = it->begin(); it2 != it->end(); ++it2) { // test: use y-coordinate to compute color double redValue = it2->coords[1]; - redValue = max(0., redValue); - redValue = min(redValue, 1.); + redValue = std::max(0., redValue); + redValue = std::min(redValue, 1.); out << "\n\t\ttexture{ pigment{ rgb"<< getColorString(redValue) <<" } }" << ","; } diff --git a/AMDiS/src/parallel/ElementObjectData.cc b/AMDiS/src/parallel/ElementObjectData.cc index b005e1fc..a97b17e5 100644 --- a/AMDiS/src/parallel/ElementObjectData.cc +++ b/AMDiS/src/parallel/ElementObjectData.cc @@ -44,6 +44,8 @@ namespace AMDiS { if (mesh->isPeriodicAssociation(elInfo->getBoundary(EDGE, i))) { // The current element's i-th edge is periodic. Element *neigh = elInfo->getNeighbour(i); + + TEST_EXIT_DBG(neigh)("Should not happen!\n"); DofEdge edge0 = el->getEdge(i); DofEdge edge1 = neigh->getEdge(elInfo->getOppVertex(i)); @@ -72,6 +74,8 @@ namespace AMDiS { if (mesh->isPeriodicAssociation(elInfo->getBoundary(FACE, i))) { // The current element's i-th face is periodic. Element *neigh = elInfo->getNeighbour(i); + + TEST_EXIT_DBG(neigh)("Should not happen!\n"); DofFace face0 = el->getFace(i); DofFace face1 = neigh->getFace(elInfo->getOppVertex(i)); @@ -132,21 +136,8 @@ namespace AMDiS { if (periodicVertices.size() == 0) return; - - - // === Search for an unsed boundary index. === + - BoundaryType newPeriodicBoundaryType = 0; - for (map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); - it != mesh->getPeriodicAssociations().end(); ++it) - newPeriodicBoundaryType = min(newPeriodicBoundaryType, it->first); - - TEST_EXIT_DBG(newPeriodicBoundaryType < 0)("Should not happen!\n"); - newPeriodicBoundaryType--; - mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = - new VertexVector(feSpace->getAdmin(), ""); - - // === Get all vertex DOFs that have multiple periodic associations. === // We group all vertices together, that have either two or three periodic @@ -223,10 +214,12 @@ namespace AMDiS { ("Should not happen!\n"); TEST_EXIT_DBG(periodicVertices.count(make_pair(dof3, dof0)) == 0) ("Should not happen!\n"); - - periodicVertices[make_pair(dof0, dof3)] = newPeriodicBoundaryType; - periodicVertices[make_pair(dof3, dof0)] = newPeriodicBoundaryType; - + + periodicVertices[make_pair(dof0, dof3)] = + provideConnectedPeriodicBoundary(type0, type1); + periodicVertices[make_pair(dof3, dof0)] = + provideConnectedPeriodicBoundary(type0, type1); + for (unsigned int j = i + 1; j < multPeriodicDof2.size(); j++) if (multPeriodicDof2[j] == dof3) multPeriodicDof2[j] = -1; @@ -235,6 +228,7 @@ namespace AMDiS { if (multPeriodicDof3.size() > 0) { int nMultPeriodicDofs = multPeriodicDof3.size(); + for (int i = 0; i < nMultPeriodicDofs; i++) { for (int j = i + 1; j < nMultPeriodicDofs; j++) { pair<DegreeOfFreedom, DegreeOfFreedom> perDofs0 = @@ -243,20 +237,15 @@ namespace AMDiS { make_pair(multPeriodicDof3[j], multPeriodicDof3[i]); if (periodicVertices.count(perDofs0) == 0) { - TEST_EXIT_DBG(periodicVertices.count(perDofs1) == 0) - ("Should not happen!\n"); - - periodicVertices[perDofs0] = newPeriodicBoundaryType; - periodicVertices[perDofs1] = newPeriodicBoundaryType; - newPeriodicBoundaryType--; - mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = - new VertexVector(feSpace->getAdmin(), ""); + BoundaryType b = getNewBoundaryType(); + periodicVertices[perDofs0] = b; + periodicVertices[perDofs1] = b; } } } } - - + + // === Get all edges that have multiple periodic associations (3D only!). === for (map<DofEdge, std::set<DofEdge> >::iterator it = periodicEdgeAssoc.begin(); @@ -265,16 +254,24 @@ namespace AMDiS { TEST_EXIT_DBG(mesh->getDim() == 3)("Should not happen!\n"); TEST_EXIT_DBG(it->second.size() == 2)("Should not happen!\n"); - pair<DofEdge, DofEdge> perEdge0 = - make_pair(*(it->second.begin()), *(++(it->second.begin()))); - pair<DofEdge, DofEdge> perEdge1 = - make_pair(perEdge0.second, perEdge0.first); + DofEdge edge0 = it->first; + DofEdge edge1 = *(it->second.begin()); + DofEdge edge2 = *(++(it->second.begin())); - periodicEdges[perEdge0] = newPeriodicBoundaryType; - periodicEdges[perEdge1] = newPeriodicBoundaryType; - newPeriodicBoundaryType--; - mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = - new VertexVector(feSpace->getAdmin(), ""); + pair<DofEdge, DofEdge> perEdge0 = make_pair(edge1, edge2); + pair<DofEdge, DofEdge> perEdge1 = make_pair(edge2, edge1); + + TEST_EXIT_DBG(periodicEdges.count(make_pair(edge0, edge1)) == 1) + ("Should not happen!\n"); + TEST_EXIT_DBG(periodicEdges.count(make_pair(edge1, edge0)) == 1) + ("Should not happen!\n"); + + BoundaryType type0 = periodicEdges[make_pair(edge0, edge1)]; + BoundaryType type1 = periodicEdges[make_pair(edge0, edge2)]; + BoundaryType type2 = provideConnectedPeriodicBoundary(type0, type1); + + periodicEdges[perEdge0] = type2; + periodicEdges[perEdge1] = type2; } } @@ -314,6 +311,59 @@ namespace AMDiS { } + BoundaryType ElementObjects::getNewBoundaryType() + { + FUNCNAME("ElementObjects::getNewBoundaryType()"); + + BoundaryType newPeriodicBoundaryType = 0; + for (map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); + it != mesh->getPeriodicAssociations().end(); ++it) + newPeriodicBoundaryType = std::min(newPeriodicBoundaryType, it->first); + + TEST_EXIT_DBG(newPeriodicBoundaryType < 0)("Should not happen!\n"); + newPeriodicBoundaryType--; + + mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = + new VertexVector(feSpace->getAdmin(), ""); + + return newPeriodicBoundaryType; + } + + + BoundaryType ElementObjects::provideConnectedPeriodicBoundary(BoundaryType b0, + BoundaryType b1) + { + FUNCNAME("ElementObjects::provideConnectedPeriodicBoundary()"); + + std::pair<BoundaryType, BoundaryType> bConn = + (b0 <= b1 ? std::make_pair(b0, b1) : std::make_pair(b1, b0)); + + if (bConnMap.count(bConn) == 0) { + BoundaryType newPeriodicBoundaryType = getNewBoundaryType(); + + VertexVector &vecB0 = mesh->getPeriodicAssociations(b0); + VertexVector &vecB1 = mesh->getPeriodicAssociations(b1); + VertexVector &vecC = mesh->getPeriodicAssociations(newPeriodicBoundaryType); + + DOFIteratorBase it(const_cast<DOFAdmin*>(feSpace->getAdmin()), USED_DOFS); + + for (it.reset(); !it.end(); ++it) { + if (!it.isDofFree()) { + TEST_EXIT_DBG(vecB1[vecB0[it.getDOFIndex()]] == vecB0[vecB1[it.getDOFIndex()]]) + ("Should not happen!\n"); + + vecC[it.getDOFIndex()] = vecB1[vecB0[it.getDOFIndex()]]; + } + } + + bConnMap[bConn] = newPeriodicBoundaryType; + } + + + return bConnMap[bConn]; + } + + void ElementObjects::createRankData(map<int, int>& macroElementRankMap) { FUNCNAME("ElementObjects::createRankData()"); @@ -329,7 +379,7 @@ namespace AMDiS { if (it2->elIndex > vertexInRank[it->first][elementInRank].elIndex) vertexInRank[it->first][elementInRank] = *it2; - vertexOwner[it->first] = max(vertexOwner[it->first], elementInRank); + vertexOwner[it->first] = std::max(vertexOwner[it->first], elementInRank); } } @@ -345,7 +395,7 @@ namespace AMDiS { if (it2->elIndex > edgeInRank[it->first][elementInRank].elIndex) edgeInRank[it->first][elementInRank] = *it2; - edgeOwner[it->first] = max(edgeOwner[it->first], elementInRank); + edgeOwner[it->first] = std::max(edgeOwner[it->first], elementInRank); } } @@ -361,7 +411,7 @@ namespace AMDiS { if (it2->elIndex > faceInRank[it->first][elementInRank].elIndex) faceInRank[it->first][elementInRank] = *it2; - faceOwner[it->first] = max(faceOwner[it->first], elementInRank); + faceOwner[it->first] = std::max(faceOwner[it->first], elementInRank); } } } diff --git a/AMDiS/src/parallel/ElementObjectData.h b/AMDiS/src/parallel/ElementObjectData.h index bbe33bcc..716d4345 100644 --- a/AMDiS/src/parallel/ElementObjectData.h +++ b/AMDiS/src/parallel/ElementObjectData.h @@ -360,6 +360,21 @@ namespace AMDiS { return faceLocalMap[data]; } + PerBoundMap<DegreeOfFreedom>::type& getPeriodicVertices() + { + return periodicVertices; + } + + PerBoundMap<DofEdge>::type& getPeriodicEdges() + { + return periodicEdges; + } + + PerBoundMap<DofFace>::type& getPeriodicFaces() + { + return periodicFaces; + } + /// Write the element database to disk. void serialize(ostream &out); @@ -400,6 +415,10 @@ namespace AMDiS { faceLocalMap[elObj] = face; } + BoundaryType provideConnectedPeriodicBoundary(BoundaryType b0, + BoundaryType b1); + + BoundaryType getNewBoundaryType(); /// Some auxiliary function to write the element object database to disk. void serialize(ostream &out, vector<ElementObjectData>& elVec); @@ -480,7 +499,8 @@ namespace AMDiS { /// iterators, i.e., if no iteration is running. GeoIndex iterGeoPos; - public: + std::map<std::pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap; + // The following three data structures store periodic DOFs, edges and faces. PerBoundMap<DegreeOfFreedom>::type periodicVertices; PerBoundMap<DofEdge>::type periodicEdges; diff --git a/AMDiS/src/parallel/InteriorBoundary.cc b/AMDiS/src/parallel/InteriorBoundary.cc index 612d82d7..539a1519 100644 --- a/AMDiS/src/parallel/InteriorBoundary.cc +++ b/AMDiS/src/parallel/InteriorBoundary.cc @@ -57,12 +57,17 @@ namespace AMDiS { TEST_EXIT_DBG(localDofs0[el0_v1] == localDofs1[el1_v0] || localDofs0[el0_v1] == localDofs1[el1_v1]) ("This should not happen!\n"); - + if (localDofs0[el0_v0] != localDofs1[el1_v0]) otherMode = true; } else { if (mesh->associated(localDofs0[el0_v0], localDofs1[el1_v0]) == false) otherMode = true; + + if ((elIndex == 28 && otherBound.elIndex == 41) || + (elIndex == 41 && otherBound.elIndex == 28)) { + MSG("HERE TEST B (%d %d): %d\n", el0_v0, el1_v0, otherMode); + } } } diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index f3490093..cf1b28a7 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -47,6 +47,7 @@ namespace AMDiS { using boost::lexical_cast; using namespace boost::filesystem; + using namespace std; inline bool cmpDofsByValue(const DegreeOfFreedom* dof1, const DegreeOfFreedom* dof2) { @@ -54,7 +55,7 @@ namespace AMDiS { } - MeshDistributor::MeshDistributor(std::string str) + MeshDistributor::MeshDistributor(string str) : probStat(0), name(str), feSpace(NULL), @@ -118,15 +119,15 @@ namespace AMDiS { macroElIndexMap.clear(); macroElIndexTypeMap.clear(); - std::map<int, bool>& elementInRank = partitioner->getElementInRank(); - for (std::vector<MacroElement*>::iterator it = allMacroElements.begin(); + map<int, bool>& elementInRank = partitioner->getElementInRank(); + for (vector<MacroElement*>::iterator it = allMacroElements.begin(); it != allMacroElements.end(); ++it) { elementInRank[(*it)->getIndex()] = false; macroElIndexMap[(*it)->getIndex()] = (*it)->getElement(); macroElIndexTypeMap[(*it)->getIndex()] = (*it)->getElType(); } - for (std::deque<MacroElement*>::iterator it = mesh->getMacroElements().begin(); + for (deque<MacroElement*>::iterator it = mesh->getMacroElements().begin(); it != mesh->getMacroElements().end(); ++it) elementInRank[(*it)->getIndex()] = true; @@ -183,6 +184,33 @@ namespace AMDiS { ParallelDebug::printBoundaryInfo(*this); #endif + for (deque<MacroElement*>::iterator it = mesh->firstMacroElement(); + it != mesh->endOfMacroElements(); ++it) { + for (int i = 0; i < mesh->getGeo(NEIGH); i++) { + if ((*it)->getNeighbour(i) && + mesh->isPeriodicAssociation((*it)->getBoundary(i))) { + (*it)->getNeighbour(i)->setNeighbour((*it)->getOppVertex(i), NULL); + (*it)->setNeighbour(i, NULL); + (*it)->setBoundary(i, 0); + + macroElementNeighbours[(*it)->getIndex()][i] = -1; + } + } + } + + for (vector<MacroElement*>::iterator it = allMacroElements.begin(); + it != allMacroElements.end(); ++it) { + for (int i = 0; i < mesh->getGeo(NEIGH); i++) { + if ((*it)->getNeighbour(i) && + mesh->isPeriodicAssociation((*it)->getBoundary(i))) { + (*it)->getNeighbour(i)->setNeighbour((*it)->getOppVertex(i), NULL); + (*it)->setNeighbour(i, NULL); + (*it)->setBoundary(i, 0); + + macroElementNeighbours[(*it)->getIndex()][i] = -1; + } + } + } // === Remove all macro elements that are not part of the rank partition. === @@ -195,7 +223,7 @@ namespace AMDiS { // We have to remove the VertexVectors, which contain periodic assoiciations, // because they are not valid anymore after some macro elements have been removed // and the corresponding DOFs were deleted. - for (std::map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); + for (map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); it != mesh->getPeriodicAssociations().end(); ++it) const_cast<DOFAdmin&>(mesh->getDofAdmin(0)).removeDOFContainer(dynamic_cast<DOFContainer*>(it->second)); @@ -221,17 +249,14 @@ namespace AMDiS { // === Create periodic dof mapping, if there are periodic boundaries. === - createPeriodicMap(); + createPeriodicMap(); -#if (DEBUG != 0) - ParallelDebug::testPeriodicBoundary(*this); -#endif // === Global refinements. === - + int globalRefinement = 0; GET_PARAMETER(0, mesh->getName() + "->global refinements", "%d", &globalRefinement); - + if (globalRefinement > 0) { refineManager->globalRefine(mesh, globalRefinement); @@ -260,7 +285,7 @@ namespace AMDiS { FUNCNAME("MeshDistributor::addProblemVec()"); if (feSpace != NULL) { - std::vector<FiniteElemSpace*> feSpaces = probVec->getFeSpaces(); + vector<FiniteElemSpace*> feSpaces = probVec->getFeSpaces(); for (unsigned int i = 0; i < feSpaces.size(); i++) { TEST_EXIT(feSpace == feSpaces[i]) ("Parallelizaton is not supported for multiple FE spaces!\n"); @@ -294,7 +319,7 @@ namespace AMDiS { GET_PARAMETER(0, probVec->getName() + "->output->write serialization", "%d", &writeSerialization); if (writeSerialization && !writeSerializationFile) { - std::string filename = ""; + string filename = ""; GET_PARAMETER(0, name + "->output->serialization filename", &filename); TEST_EXIT(filename != "") @@ -312,11 +337,11 @@ namespace AMDiS { GET_PARAMETER(0, probVec->getName() + "->input->read serialization", "%d", &readSerialization); if (readSerialization) { - std::string filename = ""; + string filename = ""; GET_PARAMETER(0, probVec->getName() + "->input->serialization filename", &filename); - filename += ".p" + lexical_cast<std::string>(mpiRank); + filename += ".p" + lexical_cast<string>(mpiRank); MSG("Start deserialization with %s\n", filename.c_str()); - std::ifstream in(filename.c_str()); + ifstream in(filename.c_str()); TEST_EXIT(!in.fail())("Could not open deserialization file: %s\n", filename.c_str()); @@ -331,7 +356,7 @@ namespace AMDiS { TEST_EXIT(filename != "") ("No filename defined for parallel deserialization file!\n"); - std::string rankFilename = filename + ".p" + lexical_cast<std::string>(mpiRank); + string rankFilename = filename + ".p" + lexical_cast<string>(mpiRank); in.open(rankFilename.c_str()); TEST_EXIT(!in.fail())("Could not open parallel deserialization file: %s\n", @@ -378,11 +403,11 @@ namespace AMDiS { void MeshDistributor::synchVector(DOFVector<double> &vec) { - StdMpi<std::vector<double> > stdMpi(mpiComm); + StdMpi<vector<double> > stdMpi(mpiComm); for (RankToDofContainer::iterator sendIt = sendDofs.begin(); sendIt != sendDofs.end(); ++sendIt) { - std::vector<double> dofs; + vector<double> dofs; int nSendDofs = sendIt->second.size(); dofs.reserve(nSendDofs); @@ -408,11 +433,11 @@ namespace AMDiS { void MeshDistributor::synchVector(SystemVector &vec) { int nComponents = vec.getSize(); - StdMpi<std::vector<double> > stdMpi(mpiComm); + StdMpi<vector<double> > stdMpi(mpiComm); for (RankToDofContainer::iterator sendIt = sendDofs.begin(); sendIt != sendDofs.end(); ++sendIt) { - std::vector<double> dofs; + vector<double> dofs; int nSendDofs = sendIt->second.size(); dofs.reserve(nComponents * nSendDofs); @@ -517,10 +542,6 @@ namespace AMDiS { { FUNCNAME("MeshDistributor::checkMeshChange()"); -#if (DEBUG != 0) - debug::writeMesh(feSpace, -1, debugOutputDir + "before_check_mesh"); -#endif - double first = MPI::Wtime(); // === If mesh has not been changed on all ranks, return. === @@ -616,11 +637,11 @@ namespace AMDiS { // === Create mesh structure codes for all ranks boundary elements. === - std::map<int, MeshCodeVec> sendCodes; + map<int, MeshCodeVec> sendCodes; for (RankToBoundMap::iterator it = allBound.begin(); it != allBound.end(); ++it) { - for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin(); + for (vector<AtomicBoundary>::iterator boundIt = it->second.begin(); boundIt != it->second.end(); ++boundIt) { MeshStructure elCode; elCode.init(boundIt->rankObj); @@ -642,7 +663,7 @@ namespace AMDiS { MeshCodeVec &recvCodes = stdMpi.getRecvData()[it->first]; int i = 0; - for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin(); + for (vector<AtomicBoundary>::iterator boundIt = it->second.begin(); boundIt != it->second.end(); ++boundIt) { MeshStructure elCode; @@ -748,8 +769,8 @@ namespace AMDiS { Element *child0 = el->getFirstChild(); Element *child1 = el->getSecondChild(); if (reverseMode) { - std::swap(s0, s1); - std::swap(child0, child1); + swap(s0, s1); + swap(child0, child1); } // === We know that the edge/face is contained in only one of the children. === @@ -832,8 +853,8 @@ namespace AMDiS { Element *child0 = el->getFirstChild(); Element *child1 = el->getSecondChild(); if (reverseMode) { - std::swap(s0, s1); - std::swap(child0, child1); + swap(s0, s1); + swap(child0, child1); } @@ -889,7 +910,7 @@ namespace AMDiS { } - void MeshDistributor::serialize(std::ostream &out, DofContainer &data) + void MeshDistributor::serialize(ostream &out, DofContainer &data) { int vecSize = data.size(); SerUtil::serialize(out, vecSize); @@ -900,8 +921,8 @@ namespace AMDiS { } - void MeshDistributor::deserialize(std::istream &in, DofContainer &data, - std::map<int, const DegreeOfFreedom*> &dofMap) + void MeshDistributor::deserialize(istream &in, DofContainer &data, + map<int, const DegreeOfFreedom*> &dofMap) { FUNCNAME("MeshDistributor::deserialize()"); @@ -921,7 +942,7 @@ namespace AMDiS { } - void MeshDistributor::serialize(std::ostream &out, RankToDofContainer &data) + void MeshDistributor::serialize(ostream &out, RankToDofContainer &data) { int mapSize = data.size(); SerUtil::serialize(out, mapSize); @@ -933,8 +954,8 @@ namespace AMDiS { } - void MeshDistributor::deserialize(std::istream &in, RankToDofContainer &data, - std::map<int, const DegreeOfFreedom*> &dofMap) + void MeshDistributor::deserialize(istream &in, RankToDofContainer &data, + map<int, const DegreeOfFreedom*> &dofMap) { data.clear(); @@ -954,13 +975,13 @@ namespace AMDiS { elemWeights.clear(); - std::string filename = ""; + string filename = ""; GET_PARAMETER(0, mesh->getName() + "->macro weights", &filename); if (filename != "") { MSG("Read macro weights from %s\n", filename.c_str()); - std::ifstream infile; - infile.open(filename.c_str(), std::ifstream::in); + ifstream infile; + infile.open(filename.c_str(), ifstream::in); while (!infile.eof()) { int elNum, elWeight; infile >> elNum; @@ -993,13 +1014,13 @@ namespace AMDiS { int nDofs = mesh->getDofAdmin(0).getUsedDofs(); int repartitioning = 0; - std::vector<int> nDofsInRank(mpiSize); + vector<int> nDofsInRank(mpiSize); mpiComm.Gather(&nDofs, 1, MPI_INT, &(nDofsInRank[0]), 1, MPI_INT, 0); if (mpiRank == 0) { int nOverallDofs = 0; - int minDofs = std::numeric_limits<int>::max(); - int maxDofs = std::numeric_limits<int>::min(); + int minDofs = numeric_limits<int>::max(); + int maxDofs = numeric_limits<int>::min(); for (int i = 0; i < mpiSize; i++) { nOverallDofs += nDofsInRank[i]; minDofs = std::min(minDofs, nDofsInRank[i]); @@ -1027,7 +1048,7 @@ namespace AMDiS { ParallelDebug::testDoubleDofs(mesh); if (repartCounter == 0) { - std::stringstream oss; + stringstream oss; oss << debugOutputDir << "partitioning-" << repartCounter << ".vtu"; MSG("Write partitioning to %s\n", oss.str().c_str()); DOFVector<double> tmpa(feSpace, "tmp"); @@ -1063,8 +1084,8 @@ namespace AMDiS { // === Create map that maps macro element indices to pointers to the === // === macro elements. === - std::map<int, MacroElement*> elIndexMap; - for (std::vector<MacroElement*>::iterator it = allMacroElements.begin(); + map<int, MacroElement*> elIndexMap; + for (vector<MacroElement*>::iterator it = allMacroElements.begin(); it != allMacroElements.end(); ++it) elIndexMap[(*it)->getIndex()] = *it; @@ -1073,9 +1094,9 @@ namespace AMDiS { // === other ranks. === std::set<MacroElement*> newMacroEl; - for (std::map<int, std::vector<int> >::iterator it = partitioner->getRecvElements().begin(); + for (map<int, vector<int> >::iterator it = partitioner->getRecvElements().begin(); it != partitioner->getRecvElements().end(); ++it) { - for (std::vector<int>::iterator elIt = it->second.begin(); + for (vector<int>::iterator elIt = it->second.begin(); elIt != it->second.end(); ++elIt) { TEST_EXIT_DBG(elIndexMap.count(*elIt) == 1) ("Could not find macro element %d\n", *elIt); @@ -1089,7 +1110,7 @@ namespace AMDiS { it != newMacroEl.end(); ++it) allMacroEl.insert(*it); - for (std::deque<MacroElement*>::iterator it = mesh->firstMacroElement(); + for (deque<MacroElement*>::iterator it = mesh->firstMacroElement(); it != mesh->endOfMacroElements(); ++it) allMacroEl.insert(*it); @@ -1118,19 +1139,19 @@ namespace AMDiS { // === Send and receive mesh structure codes. === - std::map<int, MeshCodeVec> sendCodes; - std::map<int, std::vector<std::vector<double> > > sendValues; + map<int, MeshCodeVec> sendCodes; + map<int, vector<vector<double> > > sendValues; - for (std::map<int, std::vector<int> >::iterator it = partitioner->getSendElements().begin(); + for (map<int, vector<int> >::iterator it = partitioner->getSendElements().begin(); it != partitioner->getSendElements().end(); ++it) { - for (std::vector<int>::iterator elIt = it->second.begin(); + for (vector<int>::iterator elIt = it->second.begin(); elIt != it->second.end(); ++elIt) { MeshStructure elCode; elCode.init(mesh, *elIt); sendCodes[it->first].push_back(elCode); for (unsigned int i = 0; i < testVec.size(); i++) { - std::vector<double> valVec; + vector<double> valVec; elCode.getMeshStructureValues(mesh, *elIt, testVec[i], valVec); sendValues[it->first].push_back(valVec); } @@ -1142,24 +1163,24 @@ namespace AMDiS { stdMpi.recv(partitioner->getRecvElements()); stdMpi.startCommunication<uint64_t>(MPI_UNSIGNED_LONG); - StdMpi<std::vector<std::vector<double> > > stdMpi2(mpiComm, true); + StdMpi<vector<vector<double> > > stdMpi2(mpiComm, true); stdMpi2.send(sendValues); stdMpi2.recv(partitioner->getRecvElements()); stdMpi2.startCommunication<double>(MPI_DOUBLE); // === Adapte the new macro elements due to the received mesh structure codes. === - for (std::map<int, std::vector<int> >::iterator it = partitioner->getRecvElements().begin(); + for (map<int, vector<int> >::iterator it = partitioner->getRecvElements().begin(); it != partitioner->getRecvElements().end(); ++it) { MeshCodeVec &recvCodes = stdMpi.getRecvData()[it->first]; - std::vector<std::vector<double> > &recvValues = stdMpi2.getRecvData()[it->first]; + vector<vector<double> > &recvValues = stdMpi2.getRecvData()[it->first]; int i = 0; int j = 0; TEST_EXIT_DBG(recvCodes.size() == it->second.size()) ("Should not happen!\n"); - for (std::vector<int>::iterator elIt = it->second.begin(); + for (vector<int>::iterator elIt = it->second.begin(); elIt != it->second.end(); ++elIt) { recvCodes[i].fitMeshToStructure(mesh, refineManager, false, *elIt); @@ -1202,9 +1223,9 @@ namespace AMDiS { std::set<MacroElement*> deleteMacroElements; - for (std::map<int, std::vector<int> >::iterator it = partitioner->getSendElements().begin(); + for (map<int, vector<int> >::iterator it = partitioner->getSendElements().begin(); it != partitioner->getSendElements().end(); ++it) { - for (std::vector<int>::iterator elIt = it->second.begin(); + for (vector<int>::iterator elIt = it->second.begin(); elIt != it->second.end(); ++elIt) { TEST_EXIT_DBG(elIndexMap.count(*elIt) == 1) ("Could not find macro element %d\n", *elIt); @@ -1227,7 +1248,7 @@ namespace AMDiS { mesh->dofCompress(); #if (DEBUG != 0) - std::stringstream oss; + stringstream oss; oss << debugOutputDir << "partitioning-" << repartCounter << ".vtu"; DOFVector<double> tmpa(feSpace, "tmp"); tmpa.set(mpiRank); @@ -1331,7 +1352,7 @@ namespace AMDiS { GeoIndex geoIndex = INDEX_OF_DIM(geoPos, mesh->getDim()); while (elObjects.iterate(geoIndex)) { - std::map<int, ElementObjectData>& objData = elObjects.getIterateData(); + map<int, ElementObjectData>& objData = elObjects.getIterateData(); if (objData.count(mpiRank) && objData.size() > 1) { int owner = elObjects.getIterateOwner(); ElementObjectData& rankBoundEl = objData[mpiRank]; @@ -1350,13 +1371,13 @@ namespace AMDiS { int edgeOfFace = bound.rankObj.el->getEdgeOfFace(bound.rankObj.ithObj, edgeNo); - bound.rankObj.excludedSubstructures.push_back(std::make_pair(EDGE, edgeOfFace)); + bound.rankObj.excludedSubstructures.push_back(make_pair(EDGE, edgeOfFace)); } } if (owner == mpiRank) { - for (std::map<int, ElementObjectData>::iterator it2 = objData.begin(); + for (map<int, ElementObjectData>::iterator it2 = objData.begin(); it2 != objData.end(); ++it2) { if (it2->first == mpiRank) continue; @@ -1399,8 +1420,8 @@ namespace AMDiS { // === Create periodic boundary data structure. === - for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.periodicVertices.begin(); - it != elObjects.periodicVertices.end(); ++it) { + for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.getPeriodicVertices().begin(); + it != elObjects.getPeriodicVertices().end(); ++it) { if (elObjects.isInRank(it->first.first, mpiRank) == false) continue; @@ -1413,7 +1434,7 @@ namespace AMDiS { ElementObjectData& perDofEl0 = elObjects.getElementsInRank(it->first.first)[mpiRank]; // MSG("DATA: %d %d %d\n", perDofEl0.elIndex, VERTEX, perDofEl0.ithObject); - for (std::map<int, ElementObjectData>::iterator elIt = elObjects.getElementsInRank(it->first.second).begin(); + for (map<int, ElementObjectData>::iterator elIt = elObjects.getElementsInRank(it->first.second).begin(); elIt != elObjects.getElementsInRank(it->first.second).end(); ++elIt) { int otherElementRank = elIt->first; @@ -1440,14 +1461,14 @@ namespace AMDiS { } - for (PerBoundMap<DofEdge>::iterator it = elObjects.periodicEdges.begin(); - it != elObjects.periodicEdges.end(); ++it) { + for (PerBoundMap<DofEdge>::iterator it = elObjects.getPeriodicEdges().begin(); + it != elObjects.getPeriodicEdges().end(); ++it) { if (elObjects.isInRank(it->first.first, mpiRank) == false) continue; ElementObjectData& perEdgeEl0 = elObjects.getElementsInRank(it->first.first)[mpiRank]; - for (std::map<int, ElementObjectData>::iterator elIt = elObjects.getElementsInRank(it->first.second).begin(); + for (map<int, ElementObjectData>::iterator elIt = elObjects.getElementsInRank(it->first.second).begin(); elIt != elObjects.getElementsInRank(it->first.second).end(); ++elIt) { int otherElementRank = elIt->first; @@ -1479,8 +1500,8 @@ namespace AMDiS { } - for (PerBoundMap<DofFace>::iterator it = elObjects.periodicFaces.begin(); - it != elObjects.periodicFaces.end(); ++it) { + for (PerBoundMap<DofFace>::iterator it = elObjects.getPeriodicFaces().begin(); + it != elObjects.getPeriodicFaces().end(); ++it) { if (elObjects.isInRank(it->first.first, mpiRank) == false) continue; @@ -1491,7 +1512,7 @@ namespace AMDiS { ElementObjectData& perEdgeEl0 = elObjects.getElementsInRank(it->first.first)[mpiRank]; - for (std::map<int, ElementObjectData>::iterator elIt = elObjects.getElementsInRank(it->first.second).begin(); + for (map<int, ElementObjectData>::iterator elIt = elObjects.getElementsInRank(it->first.second).begin(); elIt != elObjects.getElementsInRank(it->first.second).end(); ++elIt) { int otherElementRank = elIt->first; @@ -1527,7 +1548,7 @@ namespace AMDiS { // === bounds in the three boundary handling object. Eventually all the bound- === // === aries have to be in the same order on both ranks that share the bounday. === - StdMpi<std::vector<AtomicBoundary> > stdMpi(mpiComm); + StdMpi<vector<AtomicBoundary> > stdMpi(mpiComm); stdMpi.send(myIntBoundary.boundary); stdMpi.recv(otherIntBoundary.boundary); stdMpi.startCommunication<int>(MPI_INT); @@ -1649,7 +1670,7 @@ namespace AMDiS { FUNCNAME("MeshDistributor::removeMacroElements()"); std::set<MacroElement*> macrosToRemove; - for (std::deque<MacroElement*>::iterator it = mesh->firstMacroElement(); + for (deque<MacroElement*>::iterator it = mesh->firstMacroElement(); it != mesh->endOfMacroElements(); ++it) if (partitioner->getElementInRank()[(*it)->getIndex()] == false) macrosToRemove.insert(*it); @@ -1760,7 +1781,7 @@ namespace AMDiS { #endif int i = 0; - StdMpi<std::vector<DegreeOfFreedom> > stdMpi(mpiComm, false); + StdMpi<vector<DegreeOfFreedom> > stdMpi(mpiComm, false); for (RankToDofContainer::iterator sendIt = sendDofs.begin(); sendIt != sendDofs.end(); ++sendIt, i++) { stdMpi.getSendData(sendIt->first).resize(0); @@ -1804,7 +1825,7 @@ namespace AMDiS { #if (DEBUG != 0) - std::stringstream oss; + stringstream oss; oss << debugOutputDir << "elementIndex-" << mpiRank << ".vtu"; debug::writeElementIndexMesh(mesh, oss.str()); @@ -1813,7 +1834,7 @@ namespace AMDiS { ParallelDebug::testGlobalIndexByCoords(*this); ParallelDebug::writeDebugFile(*this, debugOutputDir + "mpi-dbg", "dat"); -#if 0 +#if 1 MSG("------------- Debug information -------------\n"); MSG("nRankDofs = %d\n", nRankDofs); MSG("nOverallDofs = %d\n", nOverallDofs); @@ -1850,18 +1871,18 @@ namespace AMDiS { periodicDof.clear(); periodicDofAssociations.clear(); - StdMpi<std::vector<int> > stdMpi(mpiComm, false); + StdMpi<vector<int> > stdMpi(mpiComm, false); // === Each rank traverse its periodic boundaries and sends the dof indices === // === to the rank "on the other side" of the periodic boundary. === RankToDofContainer rankPeriodicDofs; - std::map<int, std::vector<int> > rankToDofType; + map<int, vector<int> > rankToDofType; for (RankToBoundMap::iterator it = periodicBoundary.boundary.begin(); it != periodicBoundary.boundary.end(); ++it) { - MSG("------------- WITH RANK %d ------------------\n", it->first); +// MSG("------------- WITH RANK %d ------------------\n", it->first); if (it->first == mpiRank) { TEST_EXIT_DBG(it->second.size() % 2 == 0)("Should not happen!\n"); @@ -1874,9 +1895,9 @@ namespace AMDiS { bound.neighObj.el->getVertexDofs(feSpace, bound.neighObj, dofs1); bound.neighObj.el->getNonVertexDofs(feSpace, bound.neighObj, dofs1); - MSG("BOUND-I %d-%d-%d WITH %d-%d-%d\n", - bound.rankObj.elIndex, bound.rankObj.subObj, bound.rankObj.ithObj, - bound.neighObj.elIndex, bound.neighObj.subObj, bound.neighObj.ithObj); +// MSG("BOUND-I %d-%d-%d WITH %d-%d-%d\n", +// bound.rankObj.elIndex, bound.rankObj.subObj, bound.rankObj.ithObj, +// bound.neighObj.elIndex, bound.neighObj.subObj, bound.neighObj.ithObj); TEST_EXIT_DBG(dofs0.size() == dofs1.size())("Should not happen!\n"); @@ -1890,7 +1911,7 @@ namespace AMDiS { periodicDof[type][globalDof0] = globalDof1; periodicDofAssociations[globalDof0].insert(type); - MSG("SET(A TYPE %d) DOF %d -> %d\n", type, globalDof0, globalDof1); +// MSG("SET(A TYPE %d) DOF %d -> %d\n", type, globalDof0, globalDof1); } } } @@ -1898,22 +1919,24 @@ namespace AMDiS { } else { // Create DOF indices on the boundary. DofContainer& dofs = rankPeriodicDofs[it->first]; - for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin(); + for (vector<AtomicBoundary>::iterator boundIt = it->second.begin(); boundIt != it->second.end(); ++boundIt) { int nDofs = dofs.size(); - MSG("BOUND-R (T = %d) %d-%d-%d WITH %d-%d-%d\n", - boundIt->type, - boundIt->rankObj.elIndex, boundIt->rankObj.subObj, boundIt->rankObj.ithObj, - boundIt->neighObj.elIndex, boundIt->neighObj.subObj, boundIt->neighObj.ithObj); +// MSG("BOUND-R (T = %d) %d-%d-%d WITH %d-%d-%d\n", +// boundIt->type, +// boundIt->rankObj.elIndex, boundIt->rankObj.subObj, boundIt->rankObj.ithObj, +// boundIt->neighObj.elIndex, boundIt->neighObj.subObj, boundIt->neighObj.ithObj); boundIt->rankObj.el->getVertexDofs(feSpace, boundIt->rankObj, dofs); boundIt->rankObj.el->getNonVertexDofs(feSpace, boundIt->rankObj, dofs); for (unsigned int i = 0; i < (dofs.size() - nDofs); i++) { - MSG(" i = %d DOF = %d\n", nDofs + i, mapLocalGlobalDofs[*(dofs[nDofs + i])]); +// WorldVector<double> c; +// mesh->getDofIndexCoords(*(dofs[nDofs + i]), feSpace, c); +// MSG(" SEND i = %d DOF = %d (%f %f %f)\n", nDofs + i, mapLocalGlobalDofs[*(dofs[nDofs + i])], c[0], c[1], c[2]); rankToDofType[it->first].push_back(boundIt->type); } } @@ -1921,7 +1944,7 @@ namespace AMDiS { // Send the global indices to the rank on the other side. stdMpi.getSendData(it->first).reserve(dofs.size()); for (unsigned int i = 0; i < dofs.size(); i++) - stdMpi.getSendData(it->first).push_back(mapLocalGlobalDofs[*(dofs[i])]); + stdMpi.getSendData(it->first).push_back(mapLocalGlobalDofs[*(dofs[i])]); // Receive from this rank the same number of dofs. stdMpi.recv(it->first, dofs.size()); @@ -1932,8 +1955,6 @@ namespace AMDiS { stdMpi.startCommunication<int>(MPI_INT); - MSG("===============================\n"); - // === The rank has received the dofs from the rank on the other side of === // === the boundary. Now it can use them to create the mapping between === // === the periodic dofs in this rank and the corresponding periodic === @@ -1943,10 +1964,10 @@ namespace AMDiS { for (RankToBoundMap::iterator it = periodicBoundary.boundary.begin(); it != periodicBoundary.boundary.end(); ++it) { - MSG("------------- WITH RANK %d ------------------\n", it->first); +// MSG("------------- WITH RANK %d ------------------\n", it->first); DofContainer& dofs = rankPeriodicDofs[it->first]; - std::vector<int>& types = rankToDofType[it->first]; + vector<int>& types = rankToDofType[it->first]; TEST_EXIT_DBG(dofs.size() == types.size())("Should not happen!\n"); @@ -1956,31 +1977,28 @@ namespace AMDiS { int mapGlobalDofIndex = stdMpi.getRecvData(it->first)[i]; BoundaryType type = types[i]; +// WorldVector<double> c; +// mesh->getDofIndexCoords(*(dofs[i]), feSpace, c); +// MSG(" RECV i = %d DOF = %d (%f %f %f)\n", i, *(dofs[i]), c[0], c[1], c[2]); + + // Check if this global dof with the corresponding boundary type was // not added before by another periodic boundary from other rank. if (periodicDofAssociations[globalDofIndex].count(type) == 0) { - MSG("SET(B-%d TYPE %d) DOF %d -> %d\n", i, type, globalDofIndex, mapGlobalDofIndex); +// MSG("SET(B-%d TYPE %d) DOF %d -> %d\n", i, type, globalDofIndex, mapGlobalDofIndex); periodicDof[type][globalDofIndex] = mapGlobalDofIndex; periodicDofAssociations[globalDofIndex].insert(type); } else { - MSG("ASSOC ALREADY SET FOR %d TYPE %d\n", i, type); + // MSG("ASSOC ALREADY SET FOR %d TYPE %d\n", i, type); } } } #if (DEBUG != 0) - for (std::map<int, std::set<BoundaryType> >::iterator it = periodicDofAssociations.begin(); - it != periodicDofAssociations.end(); ++it) { - WorldVector<double> c; - mesh->getDofIndexCoords(it->first, feSpace, c); - int nAssoc = it->second.size(); - TEST_EXIT_DBG(nAssoc == 1 || nAssoc == 3 || (mesh->getDim() == 3 && nAssoc == 7)) - ("Should not happen! DOF %d (%e %e %e) has %d periodic associations!\n", - it->first, c[0], c[1], (mesh->getDim() == 2 ? 0.0 : c[2]), nAssoc); - } + ParallelDebug::testPeriodicBoundary(*this); #endif } @@ -1989,8 +2007,9 @@ namespace AMDiS { { FUNCNAME("MeshDistributor::createMacroElementInfo()"); - for (std::deque<MacroElement*>::iterator it = mesh->firstMacroElement(); + for (deque<MacroElement*>::iterator it = mesh->firstMacroElement(); it != mesh->endOfMacroElements(); ++it) { + allMacroElements.push_back(*it); macroElementNeighbours[(*it)->getIndex()].resize(mesh->getGeo(NEIGH)); @@ -2003,10 +2022,10 @@ namespace AMDiS { void MeshDistributor::updateMacroElementInfo() { - std::deque<MacroElement*>& meshMacros = mesh->getMacroElements(); + deque<MacroElement*>& meshMacros = mesh->getMacroElements(); for (unsigned int i = 0; i < allMacroElements.size(); i++) { - for (std::deque<MacroElement*>::iterator it = meshMacros.begin(); + for (deque<MacroElement*>::iterator it = meshMacros.begin(); it != meshMacros.end(); ++it) { if ((*it)->getIndex() == allMacroElements[i]->getIndex() && *it != allMacroElements[i]) { @@ -2018,7 +2037,7 @@ namespace AMDiS { } - void MeshDistributor::serialize(std::ostream &out) + void MeshDistributor::serialize(ostream &out) { FUNCNAME("MeshDistributor::serialize()"); @@ -2059,7 +2078,7 @@ namespace AMDiS { } - void MeshDistributor::deserialize(std::istream &in) + void MeshDistributor::deserialize(istream &in) { FUNCNAME("MeshDistributor::deserialize()"); @@ -2071,8 +2090,8 @@ namespace AMDiS { // Create two maps: one from from element indices to the corresponding element // pointers, and one map from Dof indices to the corresponding dof pointers. - std::map<int, Element*> elIndexMap; - std::map<int, const DegreeOfFreedom*> dofMap; + map<int, Element*> elIndexMap; + map<int, const DegreeOfFreedom*> dofMap; ElementDofIterator elDofIter(feSpace); TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_EVERY_EL_PREORDER); @@ -2114,7 +2133,7 @@ namespace AMDiS { allMacroElements.resize(nSize); for (int i = 0; i < nSize; i++) { // We do not need the neighbour indices, but must still read them. - std::vector<int> indices; + vector<int> indices; allMacroElements[i] = new MacroElement(mesh->getDim()); allMacroElements[i]->writeNeighboursTo(&indices); allMacroElements[i]->deserialize(in); @@ -2128,7 +2147,7 @@ namespace AMDiS { } - void MeshDistributor::serialize(std::ostream &out, PeriodicDofMap &data) + void MeshDistributor::serialize(ostream &out, PeriodicDofMap &data) { int mapSize = data.size(); SerUtil::serialize(out, mapSize); @@ -2143,12 +2162,12 @@ namespace AMDiS { } - void MeshDistributor::serialize(std::ostream &out, std::map<int, std::set<int> >& data) + void MeshDistributor::serialize(ostream &out, map<int, std::set<int> >& data) { int mapSize = data.size(); SerUtil::serialize(out, mapSize); - for (std::map<int, std::set<int> >::iterator it = data.begin(); it != data.end(); ++it) { + for (map<int, std::set<int> >::iterator it = data.begin(); it != data.end(); ++it) { int dof = it->first; std::set<int> typeSet = it->second; @@ -2158,7 +2177,7 @@ namespace AMDiS { } - void MeshDistributor::deserialize(std::istream &in, PeriodicDofMap &data) + void MeshDistributor::deserialize(istream &in, PeriodicDofMap &data) { data.clear(); @@ -2177,8 +2196,8 @@ namespace AMDiS { } - void MeshDistributor::deserialize(std::istream &in, - std::map<int, std::set<int> >& data) + void MeshDistributor::deserialize(istream &in, + map<int, std::set<int> >& data) { data.clear(); @@ -2197,11 +2216,11 @@ namespace AMDiS { } - void MeshDistributor::writePartitioningMesh(std::string filename) + void MeshDistributor::writePartitioningMesh(string filename) { FUNCNAME("MeshDistributor::writePartitioningMesh()"); - std::map<int, double> vec; + map<int, double> vec; TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); diff --git a/AMDiS/src/parallel/ParMetisPartitioner.cc b/AMDiS/src/parallel/ParMetisPartitioner.cc index 78d4d3f5..0c0181e6 100644 --- a/AMDiS/src/parallel/ParMetisPartitioner.cc +++ b/AMDiS/src/parallel/ParMetisPartitioner.cc @@ -288,7 +288,7 @@ namespace AMDiS { if (elementInRank[index]) { // get weight float wgt = static_cast<float>(elemWeights[index]); - maxWgt = max(wgt, maxWgt); + maxWgt = std::max(wgt, maxWgt); // write float weight TEST_EXIT_DBG(floatWgtsPos < floatWgts.size())("Should not happen!\n"); @@ -352,7 +352,7 @@ namespace AMDiS { int kpartMax = 0; for (int i = 0; i < nElements; i++) if (wgts[i] < kpart) - kpartMax = max(kpartMax, wgts[i]); + kpartMax = std::max(kpartMax, wgts[i]); mpi::globalMax(kpartMax); @@ -363,8 +363,8 @@ namespace AMDiS { ssum = 0; for (int i = 0; i < nElements; i++) { - wgts[i] = min(wgts[i], kpartMax); - wgts[i] = max(wgts[i], 1); + wgts[i] = std::min(wgts[i], kpartMax); + wgts[i] = std::max(wgts[i], 1); smin = std::min(smin, wgts[i]); smax = std::max(smax, wgts[i]); diff --git a/AMDiS/src/parallel/ParallelDebug.cc b/AMDiS/src/parallel/ParallelDebug.cc index f8cf20b6..4013113c 100644 --- a/AMDiS/src/parallel/ParallelDebug.cc +++ b/AMDiS/src/parallel/ParallelDebug.cc @@ -143,6 +143,24 @@ namespace AMDiS { { FUNCNAME("ParallelDebug::testPeriodicBoundary()"); + + // === 1. check: All periodic DOFs should have at least a correct number === + // === of periodic associations. === + + for (map<int, std::set<BoundaryType> >::iterator it = pdb.periodicDofAssociations.begin(); + it != pdb.periodicDofAssociations.end(); ++it) { + WorldVector<double> c; + pdb.mesh->getDofIndexCoords(it->first, pdb.feSpace, c); + int nAssoc = it->second.size(); + TEST_EXIT_DBG(nAssoc == 1 || nAssoc == 3 || (pdb.mesh->getDim() == 3 && nAssoc == 7)) + ("Should not happen! DOF %d (%e %e %e) has %d periodic associations!\n", + it->first, c[0], c[1], (pdb.mesh->getDim() == 2 ? 0.0 : c[2]), nAssoc); + } + + + // === 2. check: All periodic DOFs must be symmetric, i.e., if A is mapped === + // === to B, then B must be mapped to A. === + typedef MeshDistributor::PeriodicDofMap PeriodicDofMap; StdMpi<PeriodicDofMap> stdMpi(pdb.mpiComm, true); @@ -219,6 +237,80 @@ namespace AMDiS { mpi::globalAdd(foundError); TEST_EXIT(foundError == 0)("Error found on at least on rank!\n"); + + + // === 3. check: On all edge and face periodic DOFs, at least on coordinate of === + // === each periodic DOF pair must be equal (at least as long we consider === + // === periodic boundaries only on rectangulars and boxes. === + + RankToCoords sendCoords; + std::map<int, std::vector<BoundaryType> > rankToDofType; + + for (InteriorBoundary::RankToBoundMap::iterator it = pdb.periodicBoundary.boundary.begin(); + it != pdb.periodicBoundary.boundary.end(); ++it) { + if (it->first == pdb.mpiRank) + continue; + + for (vector<AtomicBoundary>::iterator boundIt = it->second.begin(); + boundIt != it->second.end(); ++boundIt) { + if (boundIt->rankObj.subObj == VERTEX) + continue; + + DofContainer dofs; + boundIt->rankObj.el->getVertexDofs(pdb.feSpace, boundIt->rankObj, dofs); + boundIt->rankObj.el->getNonVertexDofs(pdb.feSpace, boundIt->rankObj, dofs); + + for (unsigned int i = 0; i < dofs.size(); i++) { + WorldVector<double> c; + pdb.mesh->getDofIndexCoords(*(dofs[i]), pdb.feSpace, c); + sendCoords[it->first].push_back(c); + rankToDofType[it->first].push_back(boundIt->type); + } + } + } + + // Each rank must receive exactly the same number of coordinates as it sends + // to another rank. + RankToCoords recvCoords; + for (RankToCoords::iterator it = sendCoords.begin(); + it != sendCoords.end(); ++it) + recvCoords[it->first].resize(it->second.size()); + + + StdMpi<CoordsVec> stdMpiCoords(pdb.mpiComm, true); + stdMpiCoords.send(sendCoords); + stdMpiCoords.recv(recvCoords); + stdMpiCoords.startCommunication<double>(MPI_DOUBLE); + + + for (RankToCoords::iterator it = sendCoords.begin(); + it != sendCoords.end(); ++it) { + for (unsigned int i = 0; i < it->second.size(); i++) { + WorldVector<double> &c0 = it->second[i]; + WorldVector<double> &c1 = stdMpiCoords.getRecvData(it->first)[i]; + + + int nEqual = 0; + for (int j = 0; j < pdb.mesh->getDim(); j++) + if (c0[j] == c1[j]) + nEqual++; + + if ((rankToDofType[it->first][i] >= -3 && nEqual < 2) || + (rankToDofType[it->first][i] < -3 && nEqual == 0)) { + MSG("[DBG] %d-ith periodic DOF in boundary between ranks %d <-> %d is not correct!\n", + i, pdb.mpiRank, it->first); + MSG("[DBG] Coords on rank %d: %f %f %f\n", + pdb.mpiRank, c0[0], c0[1], (pdb.mesh->getDim() == 3 ? c0[2] : 0.0)); + MSG("[DBG] Coords on rank %d: %f %f %f\n", + it->first, c1[0], c1[1], (pdb.mesh->getDim() == 3 ? c1[2] : 0.0)); + + foundError = 1; + } + } + } + + mpi::globalAdd(foundError); + TEST_EXIT(foundError == 0)("Wrond periodic coordinates found on at least on rank!\n"); } @@ -235,9 +327,6 @@ namespace AMDiS { return; } - /// Defines a mapping type from rank numbers to sets of coordinates. - typedef std::map<int, std::vector<WorldVector<double> > > RankToCoords; - /// Defines a mapping type from rank numbers to sets of DOFs. typedef std::map<int, DofContainer> RankToDofContainer; @@ -316,7 +405,6 @@ namespace AMDiS { // === So we can check if also the coordinates of the communicated DOFs are === // === the same on both corresponding ranks. === - typedef std::vector<WorldVector<double> > CoordsVec; StdMpi<CoordsVec> stdMpi(pdb.mpiComm, true); stdMpi.send(sendCoords); stdMpi.recv(recvCoords); diff --git a/AMDiS/src/parallel/ParallelDebug.h b/AMDiS/src/parallel/ParallelDebug.h index 101d2f21..1dc7e315 100644 --- a/AMDiS/src/parallel/ParallelDebug.h +++ b/AMDiS/src/parallel/ParallelDebug.h @@ -32,6 +32,11 @@ namespace AMDiS { protected: typedef MeshDistributor::RankToDofContainer RankToDofContainer; + typedef std::vector<WorldVector<double> > CoordsVec; + + /// Defines a mapping type from rank numbers to sets of coordinates. + typedef std::map<int, CoordsVec> RankToCoords; + public: /** \brief * Tests the interior and the periodic boundaries on all ranks if their order diff --git a/AMDiS/src/parallel/PetscSolver.cc b/AMDiS/src/parallel/PetscSolver.cc index 202b77aa..652863ad 100644 --- a/AMDiS/src/parallel/PetscSolver.cc +++ b/AMDiS/src/parallel/PetscSolver.cc @@ -67,6 +67,8 @@ namespace AMDiS { std::vector<double> values; cols.reserve(300); values.reserve(300); + + std::vector<int> globalCols; // === Traverse all rows of the dof matrix and insert row wise the values === // === to the petsc matrix. === @@ -123,6 +125,7 @@ namespace AMDiS { // The col dof index is not periodic, simple add entry. cols.push_back(colIndex); values.push_back(value(*icursor)); + globalCols.push_back(globalColDof); } } } @@ -136,7 +139,7 @@ namespace AMDiS { std::set<int>& perAsc = meshDistributor->getPerDofAssociations(globalRowDof); double scalFactor = 1.0 / (perAsc.size() + 1.0); - + for (unsigned int i = 0; i < values.size(); i++) values[i] *= scalFactor; @@ -150,13 +153,15 @@ namespace AMDiS { perCols.reserve(300); std::vector<double> perValues; perValues.reserve(300); + for (unsigned int i = 0; i < cols.size(); i++) { int tmp = (cols[i] - dispAddCol) / dispMult; - if (meshDistributor->isPeriodicDof(tmp, *perIt)) + if (meshDistributor->isPeriodicDof(tmp, *perIt)) { perCols.push_back((meshDistributor->getPeriodicMapping(*perIt, tmp) * dispMult) + dispAddCol); - else + } else { perCols.push_back(cols[i]); + } perValues.push_back(values[i]); } -- GitLab