diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt index e895215e7e3817c411efb96180e58b9d8601656e..ee38f54ebfc6a3945ed60472000d6156b7c04377 100644 --- a/AMDiS/CMakeLists.txt +++ b/AMDiS/CMakeLists.txt @@ -197,6 +197,7 @@ if(ENABLE_PARALLEL_DOMAIN) find_package(PETSc REQUIRED) include_directories(${PETSC_DIR}/include ${PETSC_DIR}/${PETSC_ARCH}/include) SET(PARALLEL_DOMAIN_AMDIS_SRC + ${SOURCE_DIR}/parallel/CheckerPartitioner.cc ${SOURCE_DIR}/parallel/ElementObjectData.cc ${SOURCE_DIR}/parallel/MeshDistributor.cc ${SOURCE_DIR}/parallel/MeshManipulation.cc diff --git a/AMDiS/other/include/Makefile_AMDiS.mk b/AMDiS/other/include/Makefile_AMDiS.mk index b001345d5fa8047fa9825633be72c8ebda197cda..0488e77964842b0fdf524a0afc0579eaf00fd56d 100644 --- a/AMDiS/other/include/Makefile_AMDiS.mk +++ b/AMDiS/other/include/Makefile_AMDiS.mk @@ -77,7 +77,7 @@ ifeq ($(strip $(USE_PARALLEL_AMDIS)), 1) endif CPPFLAGS += -DHAVE_PARALLEL_DOMAIN_AMDIS - INCLUDES += $(PETSC_INCLUDE) + INCLUDES += $(PETSC_CC_INCLUDES) LIBS += $(PARMETIS_LIB) -lmpi $(PETSC_LIB) LIBS += $(ZOLTAN_LIB) else diff --git a/AMDiS/src/Element.cc b/AMDiS/src/Element.cc index 7a5e20579965e2bee92026bf344ead165f639527..5631f9c1714f9925964421010f5e3e0c7449efbb 100644 --- a/AMDiS/src/Element.cc +++ b/AMDiS/src/Element.cc @@ -18,6 +18,7 @@ #include "ElementRegion_ED.h" #include "Serializer.h" #include "MeshStructure.h" +#include "BasisFunction.h" namespace AMDiS { @@ -622,4 +623,15 @@ namespace AMDiS { file.close(); } + + void Element::getAllDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) + { + getNodeDofs(feSpace, bound, dofs); + + if (feSpace->getBasisFcts()->getDegree() > 1) + getHigherOrderDofs(feSpace, bound, dofs); + } + } diff --git a/AMDiS/src/Element.h b/AMDiS/src/Element.h index 68a437019e58573a67fd47b090065f0307458f68..edc2656473a606817ac53eb4560be32f6a95341e 100644 --- a/AMDiS/src/Element.h +++ b/AMDiS/src/Element.h @@ -411,32 +411,38 @@ namespace AMDiS { virtual int getChildType(int elType) const = 0; /** \brief - * Traverses an edge/face of a given element (this includes also all children of - * the element having the same edge/face). All vertex dofs alonge this edge/face - * are assembled and put together to a list. + * Traverses a vertex/edge/face of a given element (this includes also all + * children of the element having the same edge/face). All DOFs on mesh + * nodes alonge this vertex/edge/face are assembled and put together to + * a list. * * \param[in] feSpace FE space which is used to get the dofs. - * \param[in] bound Defines the edge/face of the element on which - * all vertex dofs are assembled. + * \param[in] bound Defines the vertex/edge/face of the element on + * which all vertex dofs are assembled. * \param[out] dofs List of dofs, where the result is stored. */ - virtual void getVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const = 0; + virtual void getNodeDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const = 0; /** \brief - * Traverses an edge/face of a given element (this includes also all children of - * the element having the same edge/face). All non vertex dofs alonge this edge/face - * are assembled and put together to a list. + * Traverses a vertex/edge/face of a given element (this includes also all + * children of the element having the same edge/face). All DOFs belonging + * to higher order basis functions alonge this vertex/edge/face are + * assembled and put together to a list. * * \param[in] feSpace FE space which is used to get the dofs. * \param[in] bound Defines the edge/face of the element on which * all non vertex dofs are assembled. * \param[out] dofs All dofs are put to this dof list. */ - virtual void getNonVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const = 0; + virtual void getHigherOrderDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const = 0; + + void getAllDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs); /** \} */ diff --git a/AMDiS/src/Line.h b/AMDiS/src/Line.h index f41e9bec05e8651b7c70385cbd0ebd57b92f5fb5..3b7c58a45b036e6a18bc7d040cd7bfeb6a454385 100644 --- a/AMDiS/src/Line.h +++ b/AMDiS/src/Line.h @@ -173,15 +173,15 @@ namespace AMDiS { return "Line"; } - void getVertexDofs(FiniteElemSpace*, BoundaryObject, DofContainer&) const + void getNodeDofs(FiniteElemSpace*, BoundaryObject, DofContainer&) const { - FUNCNAME("Line::getVertexDofs()"); + FUNCNAME("Line::getNodeDofs()"); ERROR_EXIT("Not yet implemented!\n"); } - void getNonVertexDofs(FiniteElemSpace*, BoundaryObject, DofContainer&) const + void getHigherOrderDofs(FiniteElemSpace*, BoundaryObject, DofContainer&) const { - FUNCNAME("Line::getNonVertexDofs()"); + FUNCNAME("Line::getHigherOrderDofs()"); ERROR_EXIT("Not yet implemented!\n"); } diff --git a/AMDiS/src/Makefile.am b/AMDiS/src/Makefile.am index c85b4be8584bd07c8152e01f11e3ee1e4c2b44fa..fc437c35a3cbfd62828f531da89fa72afb0d7d43 100644 --- a/AMDiS/src/Makefile.am +++ b/AMDiS/src/Makefile.am @@ -12,6 +12,7 @@ PARALLEL_INCLUDES = if USE_PARALLEL_DOMAIN_AMDIS PARALLEL_AMDIS_SOURCES += \ + parallel/CheckerPartitioner.cc \ parallel/ElementObjectData.cc \ parallel/MeshDistributor.cc \ parallel/MeshManipulation.cc \ @@ -247,6 +248,7 @@ io/ValueWriter.h \ io/VtkWriter.h \ io/VtkWriter.hh \ itl/minres.hpp \ +parallel/CheckerPartitioner.h \ parallel/ElementObjectData.h \ parallel/InteriorBoundary.h \ parallel/MeshDistributor.h \ diff --git a/AMDiS/src/Makefile.in b/AMDiS/src/Makefile.in index 5cea50252713046e1b49eded18401973625a68da..3f5a03d0d712122addd4bb48f0e41ad1be9f9e0e 100644 --- a/AMDiS/src/Makefile.in +++ b/AMDiS/src/Makefile.in @@ -38,6 +38,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__append_1 = \ +@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ parallel/CheckerPartitioner.cc \ @USE_PARALLEL_DOMAIN_AMDIS_TRUE@ parallel/ElementObjectData.cc \ @USE_PARALLEL_DOMAIN_AMDIS_TRUE@ parallel/MeshDistributor.cc \ @USE_PARALLEL_DOMAIN_AMDIS_TRUE@ parallel/MeshManipulation.cc \ @@ -88,10 +89,11 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libamdis_la_LIBADD = -am__libamdis_la_SOURCES_DIST = parallel/ElementObjectData.cc \ - parallel/MeshDistributor.cc parallel/MeshManipulation.cc \ - parallel/MeshPartitioner.cc parallel/MpiHelper.cc \ - parallel/ParallelDebug.cc parallel/ParallelProblemStatBase.cc \ +am__libamdis_la_SOURCES_DIST = parallel/CheckerPartitioner.cc \ + parallel/ElementObjectData.cc parallel/MeshDistributor.cc \ + parallel/MeshManipulation.cc parallel/MeshPartitioner.cc \ + parallel/MpiHelper.cc parallel/ParallelDebug.cc \ + parallel/ParallelProblemStatBase.cc \ parallel/ParMetisPartitioner.cc parallel/PetscProblemStat.cc \ parallel/PetscSolver.cc parallel/StdMpi.cc \ parallel/ZoltanPartitioner.cc AdaptBase.cc AdaptInfo.cc \ @@ -130,7 +132,8 @@ am__libamdis_la_SOURCES_DIST = parallel/ElementObjectData.cc \ io/ValueWriter.cc io/VtkWriter.cc parallel/InteriorBoundary.cc \ time/RosenbrockAdaptInstationary.cc time/RosenbrockMethod.cc \ time/RosenbrockStationary.cc -@USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__objects_1 = libamdis_la-ElementObjectData.lo \ +@USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__objects_1 = libamdis_la-CheckerPartitioner.lo \ +@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-ElementObjectData.lo \ @USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-MeshDistributor.lo \ @USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-MeshManipulation.lo \ @USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-MeshPartitioner.lo \ @@ -568,6 +571,7 @@ io/ValueWriter.h \ io/VtkWriter.h \ io/VtkWriter.hh \ itl/minres.hpp \ +parallel/CheckerPartitioner.h \ parallel/ElementObjectData.h \ parallel/InteriorBoundary.h \ parallel/MeshDistributor.h \ @@ -822,6 +826,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-BasisFunction.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Boundary.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-BoundaryManager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-CheckerPartitioner.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Cholesky.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-CoarseningManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-CoarseningManager1d.Plo@am__quote@ @@ -976,6 +981,13 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< +libamdis_la-CheckerPartitioner.lo: parallel/CheckerPartitioner.cc +@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-CheckerPartitioner.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-CheckerPartitioner.Tpo" -c -o libamdis_la-CheckerPartitioner.lo `test -f 'parallel/CheckerPartitioner.cc' || echo '$(srcdir)/'`parallel/CheckerPartitioner.cc; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-CheckerPartitioner.Tpo" "$(DEPDIR)/libamdis_la-CheckerPartitioner.Plo"; else rm -f "$(DEPDIR)/libamdis_la-CheckerPartitioner.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='parallel/CheckerPartitioner.cc' object='libamdis_la-CheckerPartitioner.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-CheckerPartitioner.lo `test -f 'parallel/CheckerPartitioner.cc' || echo '$(srcdir)/'`parallel/CheckerPartitioner.cc + libamdis_la-ElementObjectData.lo: parallel/ElementObjectData.cc @am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ElementObjectData.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ElementObjectData.Tpo" -c -o libamdis_la-ElementObjectData.lo `test -f 'parallel/ElementObjectData.cc' || echo '$(srcdir)/'`parallel/ElementObjectData.cc; \ @am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libamdis_la-ElementObjectData.Tpo" "$(DEPDIR)/libamdis_la-ElementObjectData.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ElementObjectData.Tpo"; exit 1; fi diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc index 0cb7333953cc3a0683f4d7f232a4b0ddfb259280..13acef6b185c3adf76e6e32b3d5e408a23e493ea 100644 --- a/AMDiS/src/Mesh.cc +++ b/AMDiS/src/Mesh.cc @@ -77,11 +77,11 @@ namespace AMDiS { const Flag Mesh::CALL_REVERSE_MODE = 0X8000L; - std::vector<DegreeOfFreedom> Mesh::dof_used; + vector<DegreeOfFreedom> Mesh::dof_used; const int Mesh::MAX_DOF = 100; - std::map<std::pair<DegreeOfFreedom, int>, DegreeOfFreedom*> Mesh::serializedDOFs; + map<pair<DegreeOfFreedom, int>, DegreeOfFreedom*> Mesh::serializedDOFs; - Mesh::Mesh(std::string aName, int dimension) + Mesh::Mesh(string aName, int dimension) : name(aName), dim(dimension), nVertices(0), @@ -186,7 +186,7 @@ namespace AMDiS { // mapIndex[i] is the index of the MacroElement element in the vector // macroElements, for which holds: element->getIndex() = i - std::map<int, int> mapIndex; + map<int, int> mapIndex; // We use this map for coping the DOFs of the Elements within the // MacroElements objects. @@ -198,7 +198,7 @@ namespace AMDiS { // Go through all MacroElements of mesh m, and create for every a new // MacroElement in this mesh. - for (std::deque<MacroElement*>::const_iterator it = m.macroElements.begin(); + for (deque<MacroElement*>::const_iterator it = m.macroElements.begin(); it != m.macroElements.end(); ++it, insertCounter++) { // Create new MacroElement. @@ -214,13 +214,13 @@ namespace AMDiS { macroElements.push_back(el); // Update the index map. - mapIndex.insert(std::pair<int, int>(el->getIndex(), insertCounter)); + mapIndex.insert(pair<int, int>(el->getIndex(), insertCounter)); } // Now we have to go through all the new MacroElements, and update the neighbour // connections. insertCounter = 0; - for (std::deque<MacroElement*>::const_iterator it = m.macroElements.begin(); + for (deque<MacroElement*>::const_iterator it = m.macroElements.begin(); it != m.macroElements.end(); ++it, insertCounter++) { // Go through all neighbours. @@ -275,8 +275,8 @@ namespace AMDiS { { FUNCNAME("Mesh::removeMacroElement()"); - typedef std::map<const DegreeOfFreedom*, std::set<MacroElement*> > DofElMap; - typedef std::map<const DegreeOfFreedom*, GeoIndex> DofPosMap; + typedef map<const DegreeOfFreedom*, std::set<MacroElement*> > DofElMap; + typedef map<const DegreeOfFreedom*, GeoIndex> DofPosMap; TEST_EXIT(admin.size() == 1)("Not yet implemented for multiple admins!\n"); TEST_EXIT(admin[0])("There is something wrong!\n"); @@ -305,12 +305,12 @@ namespace AMDiS { // === Remove macro elements from mesh macro element list. === - // Removing arbitrary elements from an std::deque is very slow. Therefore, we + // Removing arbitrary elements from an deque is very slow. Therefore, we // create a new deque with all macro elements that should not be deleted. The // macro element deque is than replaced by the new created one. - std::deque<MacroElement*> newMacroElements; - for (std::deque<MacroElement*>::iterator elIter = macroElements.begin(); + deque<MacroElement*> newMacroElements; + for (deque<MacroElement*>::iterator elIter = macroElements.begin(); elIter != macroElements.end(); ++elIter) { // If the current mesh macro element should not be deleted, i.e., it is not a // member of the list of macro elements to be deleted, is is inserted to the new @@ -416,7 +416,7 @@ namespace AMDiS { localAdmin->setMesh(this); - TEST_EXIT(std::find(admin.begin(), admin.end(), localAdmin) == admin.end()) + TEST_EXIT(find(admin.begin(), admin.end(), localAdmin) == admin.end()) ("admin %s is already associated to mesh %s\n", localAdmin->getName().c_str(), this->getName().c_str()); @@ -479,7 +479,7 @@ namespace AMDiS { compressAdmin->getHoleCount() < 1) continue; - std::vector<int> newDofIndex(size); + vector<int> newDofIndex(size); compressAdmin->compress(newDofIndex); Flag fill_flag = (preserveCoarseDOFs ? @@ -559,7 +559,7 @@ namespace AMDiS { } - const DOFAdmin *Mesh::createDOFAdmin(std::string lname, DimVec<int> lnDof) + const DOFAdmin *Mesh::createDOFAdmin(string lname, DimVec<int> lnDof) { FUNCNAME("Mesh::createDOFAdmin()"); @@ -905,10 +905,12 @@ namespace AMDiS { const FiniteElemSpace* feSpace, WorldVector<double>& coords) { + FUNCNAME("Mesh::getDofIndexCoords()"); + DimVec<double>* baryCoords; bool found = false; TraverseStack stack; - std::vector<DegreeOfFreedom> dofVec(feSpace->getBasisFcts()->getNumber()); + vector<DegreeOfFreedom> dofVec(feSpace->getBasisFcts()->getNumber()); ElInfo *elInfo = stack.traverseFirst(this, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); @@ -938,9 +940,11 @@ namespace AMDiS { void Mesh::getDofIndexCoords(const FiniteElemSpace* feSpace, DOFVector<WorldVector<double> >& coords) { + FUNCNAME("Mesh::getDofIndexCoords()"); + const BasisFunction* basFcts = feSpace->getBasisFcts(); int nBasFcts = basFcts->getNumber(); - std::vector<DegreeOfFreedom> dofVec(nBasFcts); + vector<DegreeOfFreedom> dofVec(nBasFcts); TraverseStack stack; ElInfo *elInfo = @@ -958,6 +962,27 @@ namespace AMDiS { } + void Mesh::getAllDofs(FiniteElemSpace *feSpace, + std::set<const DegreeOfFreedom*>& allDofs) + { + FUNCNAME("Mesh::getAllDofs()"); + + ElementDofIterator elDofIt(feSpace); + allDofs.clear(); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(this, -1, Mesh::CALL_LEAF_EL); + while (elInfo) { + elDofIt.reset(elInfo->getElement()); + do { + allDofs.insert(elDofIt.getDofPtr()); + } while(elDofIt.next()); + + elInfo = stack.traverseNext(elInfo); + } + } + + void Mesh::setDiameter(const WorldVector<double>& w) { diam = w; @@ -970,7 +995,7 @@ namespace AMDiS { } - void Mesh::serialize(std::ostream &out) + void Mesh::serialize(ostream &out) { serializedDOFs.clear(); @@ -1022,7 +1047,7 @@ namespace AMDiS { // === Write periodic associations. === int mapSize = periodicAssociations.size(); SerUtil::serialize(out, mapSize); - for (std::map<BoundaryType, VertexVector*>::iterator it = periodicAssociations.begin(); + for (map<BoundaryType, VertexVector*>::iterator it = periodicAssociations.begin(); it != periodicAssociations.end(); ++it) { BoundaryType b = it->first; @@ -1046,7 +1071,7 @@ namespace AMDiS { } - void Mesh::deserialize(std::istream &in) + void Mesh::deserialize(istream &in) { FUNCNAME("Mesh::deserialize()"); @@ -1100,7 +1125,7 @@ namespace AMDiS { } SerUtil::deserialize(in, size); - std::vector< std::vector<int> > neighbourIndices(size); + vector< vector<int> > neighbourIndices(size); deleteMeshStructure(); @@ -1110,7 +1135,7 @@ namespace AMDiS { // decomposition based parallelization. Therefore we create a temporary map // from macro element indices to the continous index of \ref macroElements. This // will be used later to find the correct neighbours of the macro elements. - std::map<int, int> elIndexVecIndex; + map<int, int> elIndexVecIndex; macroElements.resize(size); for (int i = 0; i < size; i++) { @@ -1177,9 +1202,9 @@ namespace AMDiS { TEST_EXIT(admin.size() > 0)("No DOF admin defined!\n"); - std::string macroFilename(""); - std::string valueFilename(""); - std::string periodicFilename(""); + string macroFilename(""); + string valueFilename(""); + string periodicFilename(""); int check = 1; GET_PARAMETER(0, name + "->macro file name", ¯oFilename); @@ -1206,8 +1231,8 @@ namespace AMDiS { #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - void Mesh::checkParallelMacroFile(std::string ¯oFilename, - std::string &periodicFilename, + void Mesh::checkParallelMacroFile(string ¯oFilename, + string &periodicFilename, int check) { FUNCNAME("Mesh::checkParallelMacroFile()"); @@ -1260,7 +1285,8 @@ namespace AMDiS { // => gr = log_2(nProcs * 10 / nMacroElements) double scale = 10.0 * MPI::COMM_WORLD.Get_size() / nMacroElements; - nParallelPreRefinements = static_cast<int>(std::max(0.0, ceil(log(scale) / log(2)))); + nParallelPreRefinements = + static_cast<int>(std::max(0.0, ceil(log(scale) / log(2)))); if (dim == 3) { int newElType = (elType + nParallelPreRefinements) % 3; @@ -1299,7 +1325,7 @@ namespace AMDiS { // === If macro weights are explicitly given, we cannot change the mesh. === - std::string macroWeightsFilename = ""; + string macroWeightsFilename = ""; GET_PARAMETER(0, name + "->macro weights", ¯oWeightsFilename); if (macroWeightsFilename != "") { ERROR_EXIT("Should not happen!\n"); @@ -1315,12 +1341,14 @@ namespace AMDiS { srand(time(NULL)); filenameRandomNumber = rand() % 1000000; } + MPI::COMM_WORLD.Barrier(); MPI::COMM_WORLD.Bcast(&filenameRandomNumber, 1, MPI_INT, 0); + MPI::COMM_WORLD.Barrier(); - std::stringstream newMacroFilename; + stringstream newMacroFilename; newMacroFilename << macroFilename << "." << filenameRandomNumber << ".tmp"; - std::stringstream newPeriodicFilename; + stringstream newPeriodicFilename; newPeriodicFilename << periodicFilename << "." << filenameRandomNumber << ".tmp"; @@ -1363,7 +1391,7 @@ namespace AMDiS { else globalRefinements -= nParallelPreRefinements; - std::stringstream oss; + stringstream oss; oss << globalRefinements; ADD_PARAMETER(0, name + "->global refinements", oss.str().c_str()); @@ -1382,8 +1410,8 @@ namespace AMDiS { bool Mesh::associated(DegreeOfFreedom dof1, DegreeOfFreedom dof2) { - std::map<BoundaryType, VertexVector*>::iterator it; - std::map<BoundaryType, VertexVector*>::iterator end = periodicAssociations.end(); + map<BoundaryType, VertexVector*>::iterator it; + map<BoundaryType, VertexVector*>::iterator end = periodicAssociations.end(); for (it = periodicAssociations.begin(); it != end; ++it) if ((*(it->second))[dof1] == dof2) return true; @@ -1394,9 +1422,9 @@ namespace AMDiS { bool Mesh::indirectlyAssociated(DegreeOfFreedom dof1, DegreeOfFreedom dof2) { - std::vector<DegreeOfFreedom> associatedToDOF1; - std::map<BoundaryType, VertexVector*>::iterator it; - std::map<BoundaryType, VertexVector*>::iterator end = periodicAssociations.end(); + vector<DegreeOfFreedom> associatedToDOF1; + map<BoundaryType, VertexVector*>::iterator it; + map<BoundaryType, VertexVector*>::iterator end = periodicAssociations.end(); DegreeOfFreedom dof, assDOF; associatedToDOF1.push_back(dof1); @@ -1444,7 +1472,7 @@ namespace AMDiS { { Element::deletedDOFs.clear(); - for (std::deque<MacroElement*>::const_iterator it = macroElements.begin(); + for (deque<MacroElement*>::const_iterator it = macroElements.begin(); it != macroElements.end(); ++it) { (*it)->getElement()->deleteElementDOFs(); delete *it; diff --git a/AMDiS/src/Mesh.h b/AMDiS/src/Mesh.h index 0a86767c50fe162b6d40c4ef2aebec324a15ab5c..c7f1d729bf6683725b877797eb9410ed6da0ddac 100644 --- a/AMDiS/src/Mesh.h +++ b/AMDiS/src/Mesh.h @@ -50,6 +50,9 @@ namespace AMDiS { + using namespace std; + + /** \ingroup Triangulation * \brief * A Mesh holds all information about a triangulation. @@ -58,7 +61,7 @@ namespace AMDiS { { public: /// Creates a mesh with the given name of dimension dim - Mesh(std::string name, int dim); + Mesh(string name, int dim); /// Destructor virtual ~Mesh(); @@ -83,7 +86,7 @@ namespace AMDiS { } /// Returns \ref name of the mesh - inline std::string getName() const + inline string getName() const { return name; } @@ -197,7 +200,7 @@ namespace AMDiS { * are needed at the different positions (see \ref DOFAdmin::nrDOF). * A pointer to the created DOFAdmin is returned. */ - const DOFAdmin* createDOFAdmin(std::string lname, DimVec<int> nDof); + const DOFAdmin* createDOFAdmin(string lname, DimVec<int> nDof); /** \brief * Returns the size of \ref admin which is the number of the DOFAdmins @@ -230,7 +233,7 @@ namespace AMDiS { } /// Returns an iterator to the begin of \ref macroElements - inline std::deque<MacroElement*>::iterator firstMacroElement() + inline deque<MacroElement*>::iterator firstMacroElement() { return macroElements.begin(); } @@ -242,13 +245,13 @@ namespace AMDiS { } /// Returns an iterator to the end of \ref macroElements - inline std::deque<MacroElement*>::iterator endOfMacroElements() + inline deque<MacroElement*>::iterator endOfMacroElements() { return macroElements.end(); } /// Returns \ref macroElements, the list of all macro elements in the mesh. - std::deque<MacroElement*>& getMacroElements() + deque<MacroElement*>& getMacroElements() { return macroElements; } @@ -260,7 +263,7 @@ namespace AMDiS { */ /// Sets \ref name of the mesh - inline void setName(std::string aName) + inline void setName(string aName) { name = aName; } @@ -496,16 +499,25 @@ namespace AMDiS { WorldVector<double>& coords); /** \brief - * Traverse the whole mesh and stores to each DOF of the given finite element space - * the coordinates in a given DOFVector. Works in the same way as the function - * \ref getDofIndexCoords defined above. + * Traverse the whole mesh and stores to each DOF of the given finite + * element space the coordinates in a given DOFVector. Works in the same + * way as the function \ref getDofIndexCoords defined above. * - * @param[in] feSpace The fe soace to be used for the search. - * @param[out] coords DOF vector that stores the coordinates to each dof. + * @param[in] feSpace The FE space to be used for the search. + * @param[out] coords DOF vector that stores the coordinates to each DOF. */ void getDofIndexCoords(const FiniteElemSpace* feSpace, DOFVector<WorldVector<double> >& coords); + /** \brief + * Traverse the mesh and get all DOFs in this mesh for a given FE space. + * + * @param[in] feSpace The FE space to be used for collecting DOFs. + * @param[out] allDofs The set which is filled with all DOFs. + */ + void getAllDofs(FiniteElemSpace *feSpace, + std::set<const DegreeOfFreedom*>& allDofs); + /// Returns FILL_ANY_?D inline static const Flag& getFillAnyFlag(int dim) { @@ -526,10 +538,10 @@ namespace AMDiS { } /// Serialize the mesh to a file. - void serialize(std::ostream &out); + void serialize(ostream &out); /// Deserialize a mesh from a file. - void deserialize(std::istream &in); + void deserialize(istream &in); /// Returns \ref elementIndex and increments it by 1. inline int getNextElementIndex() @@ -544,7 +556,7 @@ namespace AMDiS { } /// - inline std::map<BoundaryType, VertexVector*>& getPeriodicAssociations() + inline map<BoundaryType, VertexVector*>& getPeriodicAssociations() { return periodicAssociations; } @@ -707,8 +719,8 @@ namespace AMDiS { * AMDiS macro mesh, the value must be 1 and 0 * otherwise. */ - void checkParallelMacroFile(std::string ¯oFilename, - std::string &periodicFilename, + void checkParallelMacroFile(string ¯oFilename, + string &periodicFilename, int check); #endif @@ -717,7 +729,7 @@ namespace AMDiS { static const int MAX_DOF; /// Name of this Mesh - std::string name; + string name; /// Dimension of this Mesh. Doesn't have to be equal to dimension of world. int dim; @@ -810,13 +822,13 @@ namespace AMDiS { DimVec<int> node; /// List of all DOFAdmins - std::vector<DOFAdmin*> admin; + vector<DOFAdmin*> admin; /// List of all MacroElements of this Mesh - std::deque<MacroElement*> macroElements; + deque<MacroElement*> macroElements; /// Used by check functions - static std::vector<DegreeOfFreedom> dof_used; + static vector<DegreeOfFreedom> dof_used; /** \brief * This map is used for serialization and deserialization of mesh elements. @@ -828,7 +840,7 @@ namespace AMDiS { * When a state should be deserialized, the information can be used to construct * exactly the same dof structure. */ - static std::map<std::pair<DegreeOfFreedom, int>, DegreeOfFreedom*> serializedDOFs; + static map<pair<DegreeOfFreedom, int>, DegreeOfFreedom*> serializedDOFs; /** \brief * Used while mesh refinement. To create new elements @@ -848,7 +860,7 @@ namespace AMDiS { bool initialized; /// Map of managed periodic vertex associations. - std::map<BoundaryType, VertexVector*> periodicAssociations; + map<BoundaryType, VertexVector*> periodicAssociations; /** \brief * If the mesh has been created by reading a macro file, here the information are diff --git a/AMDiS/src/Tetrahedron.cc b/AMDiS/src/Tetrahedron.cc index f2b40d1a3b70c42ade49f334a7e007fb8a8221f2..605c8fa769ecd296588ed1c00cc6a87e20a0770f 100644 --- a/AMDiS/src/Tetrahedron.cc +++ b/AMDiS/src/Tetrahedron.cc @@ -200,21 +200,21 @@ namespace AMDiS { } - void Tetrahedron::getVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const + void Tetrahedron::getNodeDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const { - FUNCNAME("Tetrahedron::getVertexDofs()"); + FUNCNAME("Tetrahedron::getNodeDofs()"); switch (bound.subObj) { case VERTEX: dofs.push_back(dof[bound.ithObj]); break; case EDGE: - getVertexDofsAtEdge(feSpace, bound, dofs); + getNodeDofsAtEdge(feSpace, bound, dofs); break; case FACE: - getVertexDofsAtFace(feSpace, bound, dofs); + getNodeDofsAtFace(feSpace, bound, dofs); break; default: ERROR_EXIT("Should not happen!\n"); @@ -222,13 +222,11 @@ namespace AMDiS { } - void Tetrahedron::getVertexDofsAtFace(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const + void Tetrahedron::getNodeDofsAtFace(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const { - FUNCNAME("Tetrahedron::getVertexDofsAtFace()"); - - // MSG("go at el %d with face %d\n", this->getIndex(), bound.ithObj); + FUNCNAME("Tetrahedron::getNodeDofsAtFace()"); if (!child[0]) return; @@ -238,14 +236,14 @@ namespace AMDiS { { BoundaryObject nextBound = bound; prepareNextBound(nextBound, 1); - child[1]->getVertexDofs(feSpace, nextBound, dofs); + child[1]->getNodeDofs(feSpace, nextBound, dofs); } break; case 1: { BoundaryObject nextBound = bound; prepareNextBound(nextBound, 0); - child[0]->getVertexDofs(feSpace, nextBound, dofs); + child[0]->getNodeDofs(feSpace, nextBound, dofs); } break; @@ -265,19 +263,19 @@ namespace AMDiS { addDof = false; if (bound.reverseMode) { - child[1]->getVertexDofs(feSpace, nextBound1, dofs); + child[1]->getNodeDofs(feSpace, nextBound1, dofs); if (addDof) dofs.push_back(child[0]->getDof(3)); - child[0]->getVertexDofs(feSpace, nextBound0, dofs); + child[0]->getNodeDofs(feSpace, nextBound0, dofs); } else { - child[0]->getVertexDofs(feSpace, nextBound0, dofs); + child[0]->getNodeDofs(feSpace, nextBound0, dofs); if (addDof) dofs.push_back(child[0]->getDof(3)); - child[1]->getVertexDofs(feSpace, nextBound1, dofs); + child[1]->getNodeDofs(feSpace, nextBound1, dofs); } } break; @@ -287,11 +285,11 @@ namespace AMDiS { } - void Tetrahedron::getVertexDofsAtEdge(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const + void Tetrahedron::getNodeDofsAtEdge(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const { - FUNCNAME("Tetrahedron::getVertexDofsAtEdge()"); + FUNCNAME("Tetrahedron::getNodeDofsAtEdge()"); if (!child[0]) return; @@ -306,13 +304,13 @@ namespace AMDiS { nextBound1.reverseMode = false; if (bound.reverseMode) { - child[1]->getVertexDofs(feSpace, nextBound0, dofs); + child[1]->getNodeDofs(feSpace, nextBound0, dofs); dofs.push_back(child[0]->getDof(3)); - child[0]->getVertexDofs(feSpace, nextBound1, dofs); + child[0]->getNodeDofs(feSpace, nextBound1, dofs); } else { - child[0]->getVertexDofs(feSpace, nextBound0, dofs); + child[0]->getNodeDofs(feSpace, nextBound0, dofs); dofs.push_back(child[0]->getDof(3)); - child[1]->getVertexDofs(feSpace, nextBound1, dofs); + child[1]->getNodeDofs(feSpace, nextBound1, dofs); } break; @@ -320,17 +318,17 @@ namespace AMDiS { TEST_EXIT_DBG(nextBound0.ithObj == nextBound1.ithObj)("Should not happen!\n"); if (nextBound0.ithObj != -1) - child[0]->getVertexDofs(feSpace, nextBound0, dofs); + child[0]->getNodeDofs(feSpace, nextBound0, dofs); break; default: TEST_EXIT_DBG(nextBound0.ithObj == -1 || nextBound1.ithObj == -1) ("This should not happen!\n"); if (nextBound0.ithObj != -1) - child[0]->getVertexDofs(feSpace, nextBound0, dofs); + child[0]->getNodeDofs(feSpace, nextBound0, dofs); if (nextBound1.ithObj != -1) - child[1]->getVertexDofs(feSpace, nextBound1, dofs); + child[1]->getNodeDofs(feSpace, nextBound1, dofs); } } @@ -361,11 +359,11 @@ namespace AMDiS { } - void Tetrahedron::getNonVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const + void Tetrahedron::getHigherOrderDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const { - FUNCNAME("Tetrahedron::getNonVertexDofs()"); + FUNCNAME("Tetrahedron::getHigherOrderDofs()"); switch (bound.subObj) { case VERTEX: @@ -387,12 +385,12 @@ namespace AMDiS { if (childFace0 != -1) { nextBound.ithObj = childFace0; - child[0]->getNonVertexDofs(feSpace, nextBound, dofs); + child[0]->getHigherOrderDofs(feSpace, nextBound, dofs); } if (childFace1 != -1) { nextBound.ithObj = childFace1; - child[1]->getNonVertexDofs(feSpace, nextBound, dofs); + child[1]->getHigherOrderDofs(feSpace, nextBound, dofs); } } else { ElementDofIterator elDofIter(feSpace, true); diff --git a/AMDiS/src/Tetrahedron.h b/AMDiS/src/Tetrahedron.h index 9adb1c6594e8cea4c11d617063369de269dec82b..07984d3c8091da53721522633db203710b72ed57 100644 --- a/AMDiS/src/Tetrahedron.h +++ b/AMDiS/src/Tetrahedron.h @@ -136,21 +136,21 @@ namespace AMDiS { return "Tetrahedron"; } - void getVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const; + void getNodeDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const; - void getVertexDofsAtFace(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const; + void getNodeDofsAtFace(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const; - void getVertexDofsAtEdge(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const; + void getNodeDofsAtEdge(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const; - void getNonVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const; + void getHigherOrderDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const; void prepareNextBound(BoundaryObject &bound, int ithChild) const; diff --git a/AMDiS/src/Triangle.cc b/AMDiS/src/Triangle.cc index a60cc4368630ed93e3c939aa38c62ca1eab04a71..fec3579d7ba9b12dc5b9311301e82fc0fbfbe06e 100644 --- a/AMDiS/src/Triangle.cc +++ b/AMDiS/src/Triangle.cc @@ -87,11 +87,11 @@ namespace AMDiS { } - void Triangle::getVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const + void Triangle::getNodeDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const { - FUNCNAME("Triangle::getVertexDofs()"); + FUNCNAME("Triangle::getNodeDofs()"); if (bound.subObj == VERTEX) { dofs.push_back(dof[bound.ithObj]); @@ -108,16 +108,16 @@ namespace AMDiS { if (child[1] && child[1]->getFirstChild()) { if (bound.reverseMode) { nextBound.ithObj = 1; - child[1]->getSecondChild()->getVertexDofs(feSpace, nextBound, dofs); + child[1]->getSecondChild()->getNodeDofs(feSpace, nextBound, dofs); dofs.push_back(child[1]->getFirstChild()->getDof(2)); nextBound.ithObj = 0; - child[1]->getFirstChild()->getVertexDofs(feSpace, nextBound, dofs); + child[1]->getFirstChild()->getNodeDofs(feSpace, nextBound, dofs); } else { nextBound.ithObj = 0; - child[1]->getFirstChild()->getVertexDofs(feSpace, nextBound, dofs); + child[1]->getFirstChild()->getNodeDofs(feSpace, nextBound, dofs); dofs.push_back(child[1]->getFirstChild()->getDof(2)); nextBound.ithObj = 1; - child[1]->getSecondChild()->getVertexDofs(feSpace, nextBound, dofs); + child[1]->getSecondChild()->getNodeDofs(feSpace, nextBound, dofs); } } } @@ -127,16 +127,16 @@ namespace AMDiS { if (child[0] && child[0]->getFirstChild()) { if (bound.reverseMode) { nextBound.ithObj = 1; - child[0]->getSecondChild()->getVertexDofs(feSpace, nextBound, dofs); + child[0]->getSecondChild()->getNodeDofs(feSpace, nextBound, dofs); dofs.push_back(child[0]->getFirstChild()->getDof(2)); nextBound.ithObj = 0; - child[0]->getFirstChild()->getVertexDofs(feSpace, nextBound, dofs); + child[0]->getFirstChild()->getNodeDofs(feSpace, nextBound, dofs); } else { nextBound.ithObj = 0; - child[0]->getFirstChild()->getVertexDofs(feSpace, nextBound, dofs); + child[0]->getFirstChild()->getNodeDofs(feSpace, nextBound, dofs); dofs.push_back(child[0]->getFirstChild()->getDof(2)); nextBound.ithObj = 1; - child[0]->getSecondChild()->getVertexDofs(feSpace, nextBound, dofs); + child[0]->getSecondChild()->getNodeDofs(feSpace, nextBound, dofs); } } } @@ -145,16 +145,16 @@ namespace AMDiS { if (child[0]) { if (bound.reverseMode) { nextBound.ithObj = 1; - child[1]->getVertexDofs(feSpace, nextBound, dofs); + child[1]->getNodeDofs(feSpace, nextBound, dofs); dofs.push_back(child[0]->getDof(2)); nextBound.ithObj = 0; - child[0]->getVertexDofs(feSpace, nextBound, dofs); + child[0]->getNodeDofs(feSpace, nextBound, dofs); } else { nextBound.ithObj = 0; - child[0]->getVertexDofs(feSpace, nextBound, dofs); + child[0]->getNodeDofs(feSpace, nextBound, dofs); dofs.push_back(child[0]->getDof(2)); nextBound.ithObj = 1; - child[1]->getVertexDofs(feSpace, nextBound, dofs); + child[1]->getNodeDofs(feSpace, nextBound, dofs); } } break; @@ -164,11 +164,11 @@ namespace AMDiS { } - void Triangle::getNonVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const + void Triangle::getHigherOrderDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const { - FUNCNAME("Triange::getNonVertexDofs()"); + FUNCNAME("Triange::getHigherOrderDofs()"); if (bound.subObj == VERTEX) return; @@ -182,7 +182,7 @@ namespace AMDiS { case 0: if (child[1]) { nextBound.ithObj = 2; - child[1]->getNonVertexDofs(feSpace, nextBound, dofs); + child[1]->getHigherOrderDofs(feSpace, nextBound, dofs); } else { addThisEdge = true; } @@ -191,7 +191,7 @@ namespace AMDiS { case 1: if (child[0]) { nextBound.ithObj = 2; - child[0]->getNonVertexDofs(feSpace, nextBound, dofs); + child[0]->getHigherOrderDofs(feSpace, nextBound, dofs); } else { addThisEdge = true; } @@ -201,14 +201,14 @@ namespace AMDiS { if (child[0]) { if (bound.reverseMode) { nextBound.ithObj = 1; - child[1]->getNonVertexDofs(feSpace, nextBound, dofs); + child[1]->getHigherOrderDofs(feSpace, nextBound, dofs); nextBound.ithObj = 0; - child[0]->getNonVertexDofs(feSpace, nextBound, dofs); + child[0]->getHigherOrderDofs(feSpace, nextBound, dofs); } else { nextBound.ithObj = 0; - child[0]->getNonVertexDofs(feSpace, nextBound, dofs); + child[0]->getHigherOrderDofs(feSpace, nextBound, dofs); nextBound.ithObj = 1; - child[1]->getNonVertexDofs(feSpace, nextBound, dofs); + child[1]->getHigherOrderDofs(feSpace, nextBound, dofs); } } else { addThisEdge = true; diff --git a/AMDiS/src/Triangle.h b/AMDiS/src/Triangle.h index f6a7f0450e80013269fc82e845aeb3f1f791e58f..4af74f260a22e46b550c76bbffc5bd786410f36e 100644 --- a/AMDiS/src/Triangle.h +++ b/AMDiS/src/Triangle.h @@ -194,13 +194,13 @@ namespace AMDiS { return "Triangle"; } - void getVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const; - - void getNonVertexDofs(FiniteElemSpace* feSpace, - BoundaryObject bound, - DofContainer& dofs) const; + void getNodeDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const; + + void getHigherOrderDofs(FiniteElemSpace* feSpace, + BoundaryObject bound, + DofContainer& dofs) const; protected: /** \brief diff --git a/AMDiS/src/parallel/CheckerPartitioner.cc b/AMDiS/src/parallel/CheckerPartitioner.cc new file mode 100644 index 0000000000000000000000000000000000000000..f4db85177909e7d57a773f913c2b95d34e7d6db6 --- /dev/null +++ b/AMDiS/src/parallel/CheckerPartitioner.cc @@ -0,0 +1,41 @@ +// +// Software License for AMDiS +// +// Copyright (c) 2010 Dresden University of Technology +// All rights reserved. +// Authors: Simon Vey, Thomas Witkowski et al. +// +// This file is part of AMDiS +// +// See also license.opensource.txt in the distribution. + + +#include "parallel/CheckerPartitioner.h" +#include "Traverse.h" + + +namespace AMDiS { + + void CheckerPartitioner::createInitialPartitioning() + { + FUNCNAME("CheckerPartitioner::createInitialPartitioning()"); + + int mpiRank = mpiComm->Get_rank(); + int mpiSize = mpiComm->Get_size(); + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL); + while (elInfo) { + Element *el = elInfo->getElement(); + int elIndex = el->getIndex(); + int elInRank = elIndex / 2; + TEST_EXIT_DBG(elInRank < mpiSize)("Should not happen!\n"); + + elementInRank[elIndex] = (elInRank == mpiRank); + partitionMap[elIndex] = elInRank; + + elInfo = stack.traverseNext(elInfo); + } + } + +} diff --git a/AMDiS/src/parallel/CheckerPartitioner.h b/AMDiS/src/parallel/CheckerPartitioner.h new file mode 100644 index 0000000000000000000000000000000000000000..26fc87e19283e985f01ae4c28bf47f5a0b297916 --- /dev/null +++ b/AMDiS/src/parallel/CheckerPartitioner.h @@ -0,0 +1,56 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// == http://www.amdis-fem.org == +// == == +// ============================================================================ +// +// Software License for AMDiS +// +// Copyright (c) 2010 Dresden University of Technology +// All rights reserved. +// Authors: Simon Vey, Thomas Witkowski et al. +// +// This file is part of AMDiS +// +// See also license.opensource.txt in the distribution. + + + +/** \file CheckerPartitioner.h */ + +#ifndef AMDIS_CHECKER_PARTITIONER_H +#define AMDIS_CHECKER_PARTITIONER_H + +#include "AMDiS_fwd.h" +#include "Global.h" +#include "parallel/MeshPartitioner.h" + +namespace AMDiS { + + class CheckerPartitioner : public MeshPartitioner + { + public: + CheckerPartitioner(MPI::Intracomm *comm) + : MeshPartitioner(comm) + {} + + ~CheckerPartitioner() {} + + void createInitialPartitioning(); + + /// \ref MeshPartitioner::partition + bool partition(map<int, double> &elemWeights, PartitionMode mode = INITIAL) + { + return true; + } + + void createPartitionMap(map<int, int>& pMap) + { + pMap = partitionMap; + } + }; +} + +#endif diff --git a/AMDiS/src/parallel/InteriorBoundary.cc b/AMDiS/src/parallel/InteriorBoundary.cc index 0e70b9e555b68474087ef3c2936aa3fafa5fbf72..2413e3f9f267cb2ee869691dfa2063e6a850c584 100644 --- a/AMDiS/src/parallel/InteriorBoundary.cc +++ b/AMDiS/src/parallel/InteriorBoundary.cc @@ -18,6 +18,27 @@ namespace AMDiS { + BoundaryObject::BoundaryObject() + : elType(0), + reverseMode(false), + excludedSubstructures(0) + {} + + + BoundaryObject::BoundaryObject(Element *e, + int eType, + GeoIndex sObj, + int iObj, + bool rMode) + : el(e), + elIndex(e->getIndex()), + elType(eType), + subObj(sObj), + ithObj(iObj), + reverseMode(rMode), + excludedSubstructures(0) + {} + bool BoundaryObject::computeReverseMode(BoundaryObject &obj0, BoundaryObject &obj1, diff --git a/AMDiS/src/parallel/InteriorBoundary.h b/AMDiS/src/parallel/InteriorBoundary.h index a8b805b5aeada30a8e3ae56181786c5d5cab3b24..0b5a7fc3a9ec765fbdb10bab4735509db9555603 100644 --- a/AMDiS/src/parallel/InteriorBoundary.h +++ b/AMDiS/src/parallel/InteriorBoundary.h @@ -38,21 +38,13 @@ namespace AMDiS { /// Defines the geometrical objects that forms the boundary; struct BoundaryObject { - BoundaryObject() - : elType(0), - reverseMode(false), - excludedSubstructures(0) - {} + BoundaryObject(); - BoundaryObject(Element *e, int eType, GeoIndex sObj, int iObj, bool rMode = false) - : el(e), - elIndex(e->getIndex()), - elType(eType), - subObj(sObj), - ithObj(iObj), - reverseMode(rMode), - excludedSubstructures(0) - {} + BoundaryObject(Element *e, + int eType, + GeoIndex sObj, + int iObj, + bool rMode = false); static bool computeReverseMode(BoundaryObject &obj0, BoundaryObject &obj1, diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index d85c82c6a49ce9bdb80fae252f5579b4cdcba420..07866cfdf642031a07732e1a4b97623a252a86a7 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -26,6 +26,7 @@ #include "parallel/ParMetisPartitioner.h" #include "parallel/ZoltanPartitioner.h" #include "parallel/SimplePartitioner.h" +#include "parallel/CheckerPartitioner.h" #include "parallel/MpiHelper.h" #include "io/ElementFileWriter.h" #include "io/MacroInfo.h" @@ -112,6 +113,9 @@ namespace AMDiS { #endif } + if (partStr == "checker") + partitioner = new CheckerPartitioner(&mpiComm); + if (partStr == "simple") partitioner = new SimplePartitioner(&mpiComm); @@ -1658,43 +1662,25 @@ namespace AMDiS { debug::createSortedDofs(mesh, elMap); #endif - typedef std::set<const DegreeOfFreedom*> DofSet; - - // === Get all DOFs in ranks partition. === + sendDofs.clear(); + recvDofs.clear(); - ElementDofIterator elDofIt(feSpace); - DofSet rankDofSet; - - TraverseStack stack; - ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL); - while (elInfo) { - elDofIt.reset(elInfo->getElement()); - do { - rankDofSet.insert(elDofIt.getDofPtr()); - } while(elDofIt.next()); - elInfo = stack.traverseNext(elInfo); - } + // === Get all DOFs in ranks partition. === + std::set<const DegreeOfFreedom*> rankDofSet; + mesh->getAllDofs(feSpace, rankDofSet); - DofContainer rankDofs; - for (DofSet::iterator it = rankDofSet.begin(); it != rankDofSet.end(); ++it) - rankDofs.push_back(*it); + DofContainer rankDofs(rankDofSet.begin(), rankDofSet.end()); sort(rankDofs.begin(), rankDofs.end(), cmpDofsByValue); int nRankAllDofs = rankDofs.size(); - // === Traverse on interior boundaries and move all not ranked owned DOFs from === - // === rankDofs to boundaryDofs. === - - sendDofs.clear(); - recvDofs.clear(); - + // === Traverse interior boundaries and get all DOFs on them. === for (InteriorBoundary::iterator it(myIntBoundary); !it.end(); ++it) { DofContainer dofs; - it->rankObj.el->getVertexDofs(feSpace, it->rankObj, dofs); - it->rankObj.el->getNonVertexDofs(feSpace, it->rankObj, dofs); + it->rankObj.el->getAllDofs(feSpace, it->rankObj, dofs); for (unsigned int i = 0; i < dofs.size(); i++) sendDofs[it.getRank()].push_back(dofs[i]); @@ -1703,8 +1689,7 @@ namespace AMDiS { for (InteriorBoundary::iterator it(otherIntBoundary); !it.end(); ++it) { DofContainer dofs; - it->rankObj.el->getVertexDofs(feSpace, it->rankObj, dofs); - it->rankObj.el->getNonVertexDofs(feSpace, it->rankObj, dofs); + it->rankObj.el->getAllDofs(feSpace, it->rankObj, dofs); for (unsigned int i = 0; i < dofs.size(); i++) { DofContainer::iterator eraseIt = @@ -1717,32 +1702,26 @@ namespace AMDiS { } - nRankDofs = rankDofs.size(); - - // === Get starting position for global rank dof ordering. ==== + // === Get starting position for global rank DOF ordering. ==== + nRankDofs = rankDofs.size(); mpiComm.Scan(&nRankDofs, &rstart, 1, MPI_INT, MPI_SUM); rstart -= nRankDofs; + // === Stores for all rank owned DOFs a new global index. === + DofIndexMap rankDofsNewGlobalIndex; + for (int i = 0; i < nRankDofs; i++) + rankDofsNewGlobalIndex[rankDofs[i]] = i + rstart; + + // === Calculate number of overall DOFs of all partitions. === nOverallDofs = 0; mpiComm.Allreduce(&nRankDofs, &nOverallDofs, 1, MPI_INT, MPI_SUM); - // First, we set all dofs in ranks partition to be owend by the rank. Later, - // the dofs in ranks partition that are owned by other rank are set to false. - isRankDof.clear(); - for (int i = 0; i < nRankAllDofs; i++) - isRankDof[i] = true; - // Stores for all rank owned dofs a new global index. - DofIndexMap rankDofsNewGlobalIndex; - for (int i = 0; i < nRankDofs; i++) - rankDofsNewGlobalIndex[rankDofs[i]] = i + rstart; - - - // === Send new DOF indices. === + // === Send and receive new DOF indices. === #if (DEBUG != 0) ParallelDebug::testDofContainerCommunication(*this, sendDofs, recvDofs); @@ -1763,6 +1742,13 @@ namespace AMDiS { stdMpi.startCommunication(); + // First, we set all DOFs in ranks partition to be owend by the rank. Than, + // the DOFs in ranks partition that are owned by other rank are set to false. + isRankDof.clear(); + for (int i = 0; i < nRankAllDofs; i++) + isRankDof[i] = true; + + for (RankToDofContainer::iterator recvIt = recvDofs.begin(); recvIt != recvDofs.end(); ++recvIt) { int j = 0; @@ -1774,7 +1760,7 @@ namespace AMDiS { } - // === Create now the local to global index and local to dof index mappings. === + // === Create now the local to global index and local to DOF index mappings. === mapLocalGlobalDofs.clear(); mapLocalDofIndex.clear(); @@ -1784,10 +1770,10 @@ namespace AMDiS { mapLocalGlobalDofs[*(dofIt->first)] = dofIt->second; for (int i = 0; i < nRankDofs; i++) - mapLocalDofIndex[i] = *(rankDofs[i]); + mapLocalDofIndex[i] = *(rankDofs[i]); - // === Update dof admins due to new number of dofs. === + // === Update dof admins due to new number of DOFs. === lastMeshChangeIndex = mesh->getChangeIndex(); @@ -1849,10 +1835,8 @@ namespace AMDiS { TEST_EXIT_DBG(bound.neighObj.el)("No neigh object!\n"); DofContainer dofs0, dofs1; - bound.rankObj.el->getVertexDofs(feSpace, bound.rankObj, dofs0); - bound.rankObj.el->getNonVertexDofs(feSpace, bound.rankObj, dofs0); - bound.neighObj.el->getVertexDofs(feSpace, bound.neighObj, dofs1); - bound.neighObj.el->getNonVertexDofs(feSpace, bound.neighObj, dofs1); + bound.rankObj.el->getAllDofs(feSpace, bound.rankObj, dofs0); + bound.neighObj.el->getAllDofs(feSpace, bound.neighObj, dofs1); TEST_EXIT_DBG(dofs0.size() == dofs1.size()) ("Number of DOFs does not fit together: %d %d\n", @@ -1878,8 +1862,7 @@ namespace AMDiS { boundIt != it->second.end(); ++boundIt) { int nDofs = dofs.size(); - boundIt->rankObj.el->getVertexDofs(feSpace, boundIt->rankObj, dofs); - boundIt->rankObj.el->getNonVertexDofs(feSpace, boundIt->rankObj, dofs); + boundIt->rankObj.el->getAllDofs(feSpace, boundIt->rankObj, dofs); for (unsigned int i = 0; i < (dofs.size() - nDofs); i++) rankToDofType[it->first].push_back(boundIt->type); @@ -1931,7 +1914,6 @@ namespace AMDiS { StdMpi<PeriodicDofMap> stdMpi2(mpiComm); - for (RankToBoundMap::iterator it = periodicBoundary.boundary.begin(); it != periodicBoundary.boundary.end(); ++it) { if (it->first == mpiRank) @@ -1945,8 +1927,7 @@ namespace AMDiS { continue; DofContainer dofs; - boundIt->rankObj.el->getVertexDofs(feSpace, boundIt->rankObj, dofs); - boundIt->rankObj.el->getNonVertexDofs(feSpace, boundIt->rankObj, dofs); + boundIt->rankObj.el->getAllDofs(feSpace, boundIt->rankObj, dofs); for (unsigned int i = 0; i < dofs.size(); i++) { DegreeOfFreedom globalDof = mapLocalGlobalDofs[*dofs[i]]; diff --git a/AMDiS/src/parallel/MeshManipulation.cc b/AMDiS/src/parallel/MeshManipulation.cc index e17f001194de3a3b01f6d01e5ea24d34f66b4934..b0439acfaa7877af20cca2b4bcb3f462784d1e1c 100644 --- a/AMDiS/src/parallel/MeshManipulation.cc +++ b/AMDiS/src/parallel/MeshManipulation.cc @@ -135,10 +135,8 @@ namespace AMDiS { DofContainer dofs0, dofs1; - el0->getVertexDofs(feSpace, b0, dofs0); - el0->getNonVertexDofs(feSpace, b0, dofs0); - el1->getVertexDofs(feSpace, b1, dofs1); - el1->getNonVertexDofs(feSpace, b1, dofs1); + el0->getAllDofs(feSpace, b0, dofs0); + el1->getAllDofs(feSpace, b1, dofs1); #if (DEBUG != 0) debug::testDofsByCoords(feSpace, dofs0, dofs1); @@ -177,10 +175,8 @@ namespace AMDiS { DofContainer dofs0, dofs1; - el0->getVertexDofs(feSpace, b0, dofs0); - el0->getNonVertexDofs(feSpace, b0, dofs0); - el1->getVertexDofs(feSpace, b1, dofs1); - el1->getNonVertexDofs(feSpace, b1, dofs1); + el0->getAllDofs(feSpace, b0, dofs0); + el1->getAllDofs(feSpace, b1, dofs1); #if (DEBUG != 0) debug::testDofsByCoords(feSpace, dofs0, dofs1); diff --git a/AMDiS/src/parallel/MeshPartitioner.cc b/AMDiS/src/parallel/MeshPartitioner.cc index fb832a2810764108a9b1d6538447e3c123237a7e..5d29a67be68e0d54f592f31d00dd3dbdf874fb57 100644 --- a/AMDiS/src/parallel/MeshPartitioner.cc +++ b/AMDiS/src/parallel/MeshPartitioner.cc @@ -34,7 +34,7 @@ namespace AMDiS { TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, 0, - Mesh::CALL_EL_LEVEL | Mesh::FILL_NEIGH | Mesh::FILL_COORDS | Mesh::FILL_BOUND); + Mesh::CALL_EL_LEVEL | Mesh::FILL_NEIGH | Mesh::FILL_BOUND); while (elInfo) { Element *el = elInfo->getElement(); int elIndex = el->getIndex(); @@ -51,7 +51,6 @@ namespace AMDiS { elementInRank[elIndex] = (elInRank == mpiRank); partitionMap[elIndex] = elInRank; } - elInfo = stack.traverseNext(elInfo); } diff --git a/AMDiS/src/parallel/MeshPartitioner.h b/AMDiS/src/parallel/MeshPartitioner.h index c8db60cec4cb4f23c9d565285bcecdd171af894f..e5e2f4fcbb706e776c6c4b6920d359a9286cf74f 100644 --- a/AMDiS/src/parallel/MeshPartitioner.h +++ b/AMDiS/src/parallel/MeshPartitioner.h @@ -60,7 +60,7 @@ namespace AMDiS { virtual ~MeshPartitioner() {} /// Creates an initial paritioning of the AMDiS mesh. - void createInitialPartitioning(); + virtual void createInitialPartitioning(); virtual bool partition(map<int, double> &elemWeights, PartitionMode mode = INITIAL) = 0; diff --git a/AMDiS/src/parallel/ParallelDebug.cc b/AMDiS/src/parallel/ParallelDebug.cc index 904b70872cb5d1a6306ff806957a97d7de298532..d7b5e06aa173ea50733e011e28902589c9c066db 100644 --- a/AMDiS/src/parallel/ParallelDebug.cc +++ b/AMDiS/src/parallel/ParallelDebug.cc @@ -260,8 +260,7 @@ namespace AMDiS { continue; DofContainer dofs; - boundIt->rankObj.el->getVertexDofs(pdb.feSpace, boundIt->rankObj, dofs); - boundIt->rankObj.el->getNonVertexDofs(pdb.feSpace, boundIt->rankObj, dofs); + boundIt->rankObj.el->getAllDofs(pdb.feSpace, boundIt->rankObj, dofs); for (unsigned int i = 0; i < dofs.size(); i++) { WorldVector<double> c; diff --git a/AMDiS/src/parallel/PetscProblemStat.cc b/AMDiS/src/parallel/PetscProblemStat.cc index ea6b54372d7b90922f65bb753199e2d375da18e4..a5566466ef0ef75462d1eaa047f6973ddee9de3d 100644 --- a/AMDiS/src/parallel/PetscProblemStat.cc +++ b/AMDiS/src/parallel/PetscProblemStat.cc @@ -587,7 +587,6 @@ namespace AMDiS { FUNCNAME("PetscProblemStat::solvePetscMatrix()"); // === Set old solution to be initiual guess for PETSc solver. === - if (!zeroStartVector) { VecSet(petscSolVec, 0.0); @@ -598,7 +597,6 @@ namespace AMDiS { VecAssemblyEnd(petscSolVec); } - // === Init PETSc solver. === KSP solver; @@ -611,6 +609,7 @@ namespace AMDiS { // Do not delete the solution vector, use it for the initial guess. if (!zeroStartVector) KSPSetInitialGuessNonzero(solver, PETSC_TRUE); + // === Run PETSc. === diff --git a/AMDiS/src/parallel/PetscSolver.cc b/AMDiS/src/parallel/PetscSolver.cc index 0522681d5b8ea8e3b676181911bf475141889687..680cab4f92ed4d69c3b0fc350fd795226370d78c 100644 --- a/AMDiS/src/parallel/PetscSolver.cc +++ b/AMDiS/src/parallel/PetscSolver.cc @@ -67,7 +67,7 @@ namespace AMDiS { void PetscSolverSchur::providePetscSolver(KSP &solver, PC &pc) { FUNCNAME("PetscSolverSchur::providePetscProblemStat()"); - + typedef map<int, DofContainer> RankToDofContainer; typedef map<DegreeOfFreedom, bool> DofIndexToBool;