diff --git a/AMDiS/src/Global.h b/AMDiS/src/Global.h index db5a51d373788af5c54b4918ed05f9889d773ccc..abfb3fbddc6d7593417582d5bb7b46aceadbd1d1 100644 --- a/AMDiS/src/Global.h +++ b/AMDiS/src/Global.h @@ -296,10 +296,8 @@ namespace AMDiS { /// Error stream static ostream *error; - /** \brief - * Remember funcName to avoid multiple output of funcName within the same - * function call - */ + /// Remember funcName to avoid multiple output of funcName within the same + /// function call static const char *oldFuncName; /// Global info level @@ -309,15 +307,12 @@ namespace AMDiS { static bool msgWait; }; - // ============================================================================ - // ===== message macros ======================================================= - // ============================================================================ - - /** \brief - * Should be the first call in every functions. It defines the current function - * name nn for message output via MSG, WARNING, ... - */ + // =========================================================================== + // ===== message macros ====================================================== + // =========================================================================== + /// Should be the first call in every functions. It defines the current + /// function name nn for message output via MSG, WARNING, ... #define FUNCNAME(nn) const char *funcName; funcName = nn; /// prints an error message @@ -365,25 +360,19 @@ namespace AMDiS { if (Msg::getMsgInfo() && (std::min(Msg::getMsgInfo(), (info)) >= (noinfo))) Msg::print - /** \brief - * If the value of Msg::wait is not zero the macro will produce the message - * 'wait for <enter> ...' and will continue after pressing the return or enter - * key. Otherwise the program continues without a message. - */ + /// If the value of Msg::wait is not zero the macro will produce the message + /// 'wait for <enter> ...' and will continue after pressing the return or enter + /// key. Otherwise the program continues without a message. #define WAIT Msg::wait(Msg::getMsgWait()) - /** \brief - * produces the message 'wait for <enter> ...' and will continue after pressing - * the return or enter key. - */ + /// produces the message 'wait for <enter> ...' and will continue after + /// pressing the return or enter key. #define WAIT_REALLY Msg::wait(true) #define TIME_USED(f,s) ((double)((s)-(f))/(double)CLOCKS_PER_SEC) - /** \brief - * internal used indices to represent the different geometrical objects. - * Used as parameter for getGeo() and as template parameter for FixVec. - */ + /// internal used indices to represent the different geometrical objects. + /// Used as parameter for getGeo() and as template parameter for FixVec. typedef enum { CENTER = 0, /**< in 1d the center is at the edge, in 2d at the face, in 3d @@ -424,10 +413,8 @@ namespace AMDiS { class Global { public: - /** \brief - * returns a pointer to \ref referenceElement [dim]. With this pointer you - * can get information about the element via Element's getGeo method. - */ + /// returns a pointer to \ref referenceElement [dim]. With this pointer you + /// can get information about the element via Element's getGeo method. static const Element *getReferenceElement(int dim) { FUNCNAME("Global::getReferenceElement()"); @@ -445,10 +432,8 @@ namespace AMDiS { return 0; } - /** \brief - * Returns geometrical information about elements of the dimension dim. - * getGeo(VERTEX, 3) returns 4 because a Tetrahedron has 4 vertices. - */ + /// Returns geometrical information about elements of the dimension dim. + /// getGeo(VERTEX, 3) returns 4 because a Tetrahedron has 4 vertices. static inline int getGeo(GeoIndex p, int dim) { TEST_EXIT_DBG(p >= MINPART && p <= MAXPART) @@ -467,23 +452,19 @@ namespace AMDiS { static void clear(); private: - /** \brief - * Global is a pure static class. So the constructor is private to avoid - * instantiation. - */ + /// Global is a pure static class. So the constructor is private to avoid + /// instantiation. Global(); private: /// Dimension of the simulated world static int dimOfWorld; - /** \brief - * contains a pointer to a Line, a Triangle, and a Tetrahedron. - * This allows the access to information of the concrete elements via - * the dimension index. - * referenceElement[3]->getGeo(VERTEX) gives the number of vertices of a - * Tetrahedron wich is 4 => no switch statement is necessary. - */ + /// contains a pointer to a Line, a Triangle, and a Tetrahedron. + /// This allows the access to information of the concrete elements via + /// the dimension index. + /// referenceElement[3]->getGeo(VERTEX) gives the number of vertices of a + /// Tetrahedron wich is 4 => no switch statement is necessary. static Element *referenceElement[4]; /// Stores the precalculated results that should be returned by Global::getGeo. diff --git a/AMDiS/src/parallel/ElementObjectDatabase.cc b/AMDiS/src/parallel/ElementObjectDatabase.cc index 0790142a4efc61141f9783e6900d15cfdfd2cda4..9ec7f81f731ce377bf575128efb8f1044c3359cf 100644 --- a/AMDiS/src/parallel/ElementObjectDatabase.cc +++ b/AMDiS/src/parallel/ElementObjectDatabase.cc @@ -499,6 +499,38 @@ namespace AMDiS { } + void ElementObjectDatabase::clear() + { + FUNCNAME("ElementObjectDatabase::clear()"); + + vertexElements.clear(); + edgeElements.clear(); + faceElements.clear(); + + vertexLocalMap.clear(); + edgeLocalMap.clear(); + faceLocalMap.clear(); + + vertexInRank.clear(); + edgeInRank.clear(); + faceInRank.clear(); + + bConnMap.clear(); + periodicVertices.clear(); + periodicEdges.clear(); + periodicFaces.clear(); + periodicDofAssoc.clear(); + periodicEdgeAssoc.clear(); + + edgeReverseMode.clear(); + faceReverseMode.clear(); + + macroElementRankMap = NULL; + macroElIndexMap.clear(); + macroElIndexTypeMap.clear(); + } + + void ElementObjectDatabase::createReverseModeData() { FUNCNAME("ElementObjectDatabase::createReverseModeData()"); diff --git a/AMDiS/src/parallel/ElementObjectDatabase.h b/AMDiS/src/parallel/ElementObjectDatabase.h index cc1fd8568a027a8f4a325090352c60446fbe86ee..69fb5224652d092972b047ccb86f1d0e31b7912d 100644 --- a/AMDiS/src/parallel/ElementObjectDatabase.h +++ b/AMDiS/src/parallel/ElementObjectDatabase.h @@ -135,6 +135,9 @@ namespace AMDiS { /// heighest rank number of all ranks where the object is part of. void updateRankData(); + /// All data from the database is dropped. + void clear(); + /** \brief * Iterates over all elements for one geometrical index, i.e., over all * vertices, edges or faces in the mesh. The function returns true, if the diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index 13fc20291689bc0023326966815aed1e8c3c4bbe..54473490792bef3a5b58443e42ed241e20cec518 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -89,7 +89,8 @@ namespace AMDiS { debugOutputDir(""), lastMeshChangeIndex(0), createBoundaryDofFlag(0), - boundaryDofInfo(1) + boundaryDofInfo(1), + meshAdaptivity(true) { FUNCNAME("MeshDistributor::ParalleDomainBase()"); @@ -101,6 +102,7 @@ namespace AMDiS { Parameters::get(name + "->debug output dir", debugOutputDir); Parameters::get(name + "->repartition ith change", repartitionIthChange); Parameters::get(name + "->log main rank", Msg::outputMainRank); + Parameters::get(name + "->mesh adaptivity", meshAdaptivity); string partStr = "parmetis"; Parameters::get(name + "->partitioner", partStr); @@ -352,6 +354,10 @@ namespace AMDiS { // Set DOF rank information to all matrices and vectors. setRankDofs(); + // And delete some data, we there is no mesh adaptivty. + if (meshAdaptivity) + elObjDb.clear(); + initialized = true; } @@ -938,13 +944,6 @@ namespace AMDiS { { FUNCNAME("MeshDistributor::checkMeshChange()"); - double vm, rss; - processMemUsage(vm, rss); - mpi::globalAdd(vm); - mpi::globalAdd(rss); - MSG("MEM-RSS 0 = %f\n", rss); - - MPI::COMM_WORLD.Barrier(); double first = MPI::Wtime(); @@ -1067,12 +1066,6 @@ namespace AMDiS { // === Print imbalance factor. === printImbalanceFactor(); - - processMemUsage(vm, rss); - mpi::globalAdd(vm); - mpi::globalAdd(rss); - MSG("MEM-RSS 1 = %f\n", rss); - } @@ -1606,6 +1599,10 @@ namespace AMDiS { elObjDb.create(partitionMap, levelData); elObjDb.updateRankData(); + unsigned long memsize = elObjDb.calculateMemoryUsage(); + MSG("Memory usage of element object database = %5.f KByte\n", + static_cast<double>(memsize / 1024)); + intBoundary.create(levelData, 0, elObjDb); ParallelDebug::printBoundaryInfo(intBoundary); diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h index 397eeef8b11b9510a9e3745061c4ef4b953aac21..48a39ee62a1f4f5c28c5e095d0e7cf6a61247dba 100644 --- a/AMDiS/src/parallel/MeshDistributor.h +++ b/AMDiS/src/parallel/MeshDistributor.h @@ -563,6 +563,12 @@ namespace AMDiS { MeshLevelData levelData; + /// If there is no mesh adaptivity, the mesh distributor can remove some + /// data structures which are only used if mesh changes or it must be + /// redistributed due to some local adaptivity. By default, this variable + /// is set to true, and thus no special assumption are made. + bool meshAdaptivity; + public: static bool sebastianMode; diff --git a/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.cc b/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.cc index dd47c383bd1de343516f15b115678ad99ec53eb6..cad7db04841f57c8601d404c89df93018e7605e7 100644 --- a/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.cc +++ b/AMDiS/src/parallel/ParallelCoarseSpaceMatVec.cc @@ -52,6 +52,10 @@ namespace AMDiS { coarseSpaceMap[component] = coarseDofs; } + + if (find(uniqueCoarseMap.begin(), uniqueCoarseMap.end(), coarseDofs) == + uniqueCoarseMap.end()) + uniqueCoarseMap.push_back(coarseDofs); } @@ -59,28 +63,8 @@ namespace AMDiS { { FUNCNAME("ParallelCoarseSpaceMatVec:prepare()"); - // === Create vector of unique pointers to all coarse space maps. === - - uniqueCoarseMap.clear(); - if (coarseSpaceMap.size()) { - std::set<ParallelDofMapping*> tmp; - for (map<int, ParallelDofMapping*>::iterator it = coarseSpaceMap.begin(); - it != coarseSpaceMap.end(); ++it) { - if (tmp.count(it->second) == 0) { - tmp.insert(it->second); - uniqueCoarseMap.push_back(it->second); - } - } - } - TEST_EXIT(uniqueCoarseMap.size() <= 2) ("Not yet implemented for more than two coarse spaces!\n"); - if (uniqueCoarseMap.size() == 2) { - if (uniqueCoarseMap[0]->getFeSpace()->getBasisFcts()->getDegree() < - uniqueCoarseMap[1]->getFeSpace()->getBasisFcts()->getDegree()) { - swap(uniqueCoarseMap[0], uniqueCoarseMap[1]); - } - } // === Create pointers to PETSc matrix and vector objects. === @@ -95,7 +79,7 @@ namespace AMDiS { // === Create map from component number to its coarse space map. === componentIthCoarseMap.resize(coarseSpaceMap.size()); - for (unsigned int i = 0; i < componentIthCoarseMap.size(); i++) { + for (unsigned int i = 0; i < coarseSpaceMap.size(); i++) { bool found = false; for (int j = 0; j < nCoarseMap; j++) { if (coarseSpaceMap[i] == uniqueCoarseMap[j]) { diff --git a/AMDiS/src/parallel/PetscSolverFetiOperators.cc b/AMDiS/src/parallel/PetscSolverFetiOperators.cc index 61f86cdcad2aec885139af2e7901033893046271..8a3dc324f43a85df455a3d3aaba12391e1ad5566 100644 --- a/AMDiS/src/parallel/PetscSolverFetiOperators.cc +++ b/AMDiS/src/parallel/PetscSolverFetiOperators.cc @@ -302,7 +302,7 @@ namespace AMDiS { VecCopy(x_interface, y_interface); - // VecScale(y_interface, 0.2519); + // VecScale(y_interface, 0.16); // Multiply with scaled Lagrange constraint matrix.