Commit 36a3ffe1 authored by Thomas Witkowski's avatar Thomas Witkowski

First working repartitioning of parallel distributed mesh.

parent b3de56bb
......@@ -180,6 +180,7 @@ if(ENABLE_PARALLEL_DOMAIN)
SET(PARALLEL_DOMAIN_AMDIS_SRC
${SOURCE_DIR}/parallel/ParMetisPartitioner.cc
${SOURCE_DIR}/parallel/MeshDistributor.cc
${SOURCE_DIR}/parallel/MeshManipulation.cc
${SOURCE_DIR}/parallel/StdMpi.cc
${SOURCE_DIR}/parallel/ParallelDebug.cc
${SOURCE_DIR}/parallel/MpiHelper.cc
......
......@@ -18,6 +18,7 @@ if USE_PARALLEL_DOMAIN_AMDIS
$(SOURCE_DIR)/parallel/StdMpi.h $(SOURCE_DIR)/parallel/StdMpi.cc \
$(SOURCE_DIR)/parallel/ParMetisPartitioner.h $(SOURCE_DIR)/parallel/ParMetisPartitioner.cc \
$(SOURCE_DIR)/parallel/MeshDistributor.h $(SOURCE_DIR)/parallel/MeshDistributor.cc \
$(SOURCE_DIR)/parallel/MeshManipulation.h $(SOURCE_DIR)/parallel/MeshManipulation.cc \
$(SOURCE_DIR)/parallel/ParallelDebug.h $(SOURCE_DIR)/parallel/ParallelDebug.cc \
$(SOURCE_DIR)/parallel/ParallelProblemStatBase.h \
$(SOURCE_DIR)/parallel/PetscSolver.h $(SOURCE_DIR)/parallel/PetscSolver.cc \
......
......@@ -38,6 +38,7 @@ host_triplet = @host@
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/StdMpi.h $(SOURCE_DIR)/parallel/StdMpi.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/ParMetisPartitioner.h $(SOURCE_DIR)/parallel/ParMetisPartitioner.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/MeshDistributor.h $(SOURCE_DIR)/parallel/MeshDistributor.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/MeshManipulation.h $(SOURCE_DIR)/parallel/MeshManipulation.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/ParallelDebug.h $(SOURCE_DIR)/parallel/ParallelDebug.cc \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/ParallelProblemStatBase.h \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ $(SOURCE_DIR)/parallel/PetscSolver.h $(SOURCE_DIR)/parallel/PetscSolver.cc \
......@@ -96,6 +97,8 @@ am__libamdis_la_SOURCES_DIST = $(SOURCE_DIR)/parallel/StdMpi.h \
$(SOURCE_DIR)/parallel/ParMetisPartitioner.cc \
$(SOURCE_DIR)/parallel/MeshDistributor.h \
$(SOURCE_DIR)/parallel/MeshDistributor.cc \
$(SOURCE_DIR)/parallel/MeshManipulation.h \
$(SOURCE_DIR)/parallel/MeshManipulation.cc \
$(SOURCE_DIR)/parallel/ParallelDebug.h \
$(SOURCE_DIR)/parallel/ParallelDebug.cc \
$(SOURCE_DIR)/parallel/ParallelProblemStatBase.h \
......@@ -260,6 +263,7 @@ am__libamdis_la_SOURCES_DIST = $(SOURCE_DIR)/parallel/StdMpi.h \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__objects_1 = libamdis_la-StdMpi.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-ParMetisPartitioner.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-ParallelDebug.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-PetscSolver.lo \
@USE_PARALLEL_DOMAIN_AMDIS_TRUE@ libamdis_la-MpiHelper.lo \
......@@ -820,6 +824,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Marker.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Mesh.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MeshDistributor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MeshManipulation.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MeshStructure.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-MpiHelper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-NonLinUpdater.Plo@am__quote@
......@@ -926,6 +931,13 @@ libamdis_la-MeshDistributor.lo: $(SOURCE_DIR)/parallel/MeshDistributor.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MeshDistributor.lo `test -f '$(SOURCE_DIR)/parallel/MeshDistributor.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/parallel/MeshDistributor.cc
libamdis_la-MeshManipulation.lo: $(SOURCE_DIR)/parallel/MeshManipulation.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-MeshManipulation.lo -MD -MP -MF $(DEPDIR)/libamdis_la-MeshManipulation.Tpo -c -o libamdis_la-MeshManipulation.lo `test -f '$(SOURCE_DIR)/parallel/MeshManipulation.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/parallel/MeshManipulation.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libamdis_la-MeshManipulation.Tpo $(DEPDIR)/libamdis_la-MeshManipulation.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$(SOURCE_DIR)/parallel/MeshManipulation.cc' object='libamdis_la-MeshManipulation.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-MeshManipulation.lo `test -f '$(SOURCE_DIR)/parallel/MeshManipulation.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/parallel/MeshManipulation.cc
libamdis_la-ParallelDebug.lo: $(SOURCE_DIR)/parallel/ParallelDebug.cc
@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ParallelDebug.lo -MD -MP -MF $(DEPDIR)/libamdis_la-ParallelDebug.Tpo -c -o libamdis_la-ParallelDebug.lo `test -f '$(SOURCE_DIR)/parallel/ParallelDebug.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/parallel/ParallelDebug.cc
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/libamdis_la-ParallelDebug.Tpo $(DEPDIR)/libamdis_la-ParallelDebug.Plo
......
......@@ -208,8 +208,8 @@ namespace AMDiS {
DegreeOfFreedom vertexDOF;
WorldVector<double> vertexCoords;
MSG("ELEMENT: %d\n", elInfo->getElement()->getIndex());
MSG("DOFs: %d %d %d\n", dof[0][0], dof[1][0], dof[2][0]);
// MSG("ELEMENT: %d\n", elInfo->getElement()->getIndex());
// MSG("DOFs: %d %d %d\n", dof[0][0], dof[1][0], dof[2][0]);
// create ElementInfo
ElementInfo elementInfo(dim);
......
......@@ -198,107 +198,78 @@ namespace AMDiS {
/* should be used only at the end of dof_compress()!!!!! */
/****************************************************************************/
/* CHANGE_DOFS_1 changes old dofs to NEGATIVE new dofs */
#define CHANGE_DOFS_1(el) \
ldof = el->dof[n0 + i] + nd0; \
for (j = 0; j < nd; j++) { \
if ((k = ldof[j]) >= 0) { \
/* do it only once! (dofs are visited more than once) */ \
ldof[j] = - admin->getMesh()->newDOF[k] - 1; \
} }
/* CHANGE_DOFS_2 changes NEGATIVE new dofs to POSITIVE */
#define CHANGE_DOFS_2(el) \
ldof = el->dof[n0+i] + nd0; \
for (j = 0; j < nd; j++) { \
if ((k = ldof[j]) < 0) { \
/* do it only once! (dofs are visited more than once) */ \
ldof[j] = - k - 1; \
} }
void Element::newDOFFct1(const DOFAdmin* admin)
void Element::newDofFct1(const DOFAdmin* admin)
{
int j, k, n0, nd, nd0;
DegreeOfFreedom *ldof;
int vertices = mesh->getGeo(VERTEX);
int edges = mesh->getGeo(EDGE);
int faces = mesh->getGeo(FACE);
int n0, nd, nd0;
if ((nd = admin->getNumberOfDofs(VERTEX))) {
int vertices = mesh->getGeo(VERTEX);
nd0 = admin->getNumberOfPreDOFs(VERTEX);
n0 = admin->getMesh()->getNode(VERTEX);
for (int i = 0; i < vertices; i++) {
CHANGE_DOFS_1(this);
}
for (int i = 0; i < vertices; i++)
changeDofs1(admin, n0, nd0, nd, i);
}
if (mesh->getDim() > 1) {
if ((nd = admin->getNumberOfDofs(EDGE))) {
int edges = mesh->getGeo(EDGE);
nd0 = admin->getNumberOfPreDOFs(EDGE);
n0 = admin->getMesh()->getNode(EDGE);
for (int i = 0; i < edges; i++) {
CHANGE_DOFS_1(this);
}
for (int i = 0; i < edges; i++)
changeDofs1(admin, n0, nd0, nd, i);
}
}
if (mesh->getDim() == 3) {
if ((nd = admin->getNumberOfDofs(FACE))) {
int faces = mesh->getGeo(FACE);
nd0 = admin->getNumberOfPreDOFs(FACE);
n0 = admin->getMesh()->getNode(FACE);
for (int i = 0; i < faces; i++) {
CHANGE_DOFS_1(this);
}
for (int i = 0; i < faces; i++)
changeDofs1(admin, n0, nd0, nd, i);
}
}
if ((nd = admin->getNumberOfDofs(CENTER))) {
nd0 = admin->getNumberOfPreDOFs(CENTER);
n0 = admin->getMesh()->getNode(CENTER);
int i = 0; /* only one center */
CHANGE_DOFS_1(this);
n0 = admin->getMesh()->getNode(CENTER);
changeDofs1(admin, n0, nd0, nd, 0);
}
}
void Element::newDOFFct2(const DOFAdmin* admin)
void Element::newDofFct2(const DOFAdmin* admin)
{
int j, k, n0, nd0;
DegreeOfFreedom *ldof;
int vertices = mesh->getGeo(VERTEX);
int edges = mesh->getGeo(EDGE);
int faces = mesh->getGeo(FACE);
int n0, nd0;
int nd = admin->getNumberOfDofs(VERTEX);
if (nd) {
int vertices = mesh->getGeo(VERTEX);
nd0 = admin->getNumberOfPreDOFs(VERTEX);
n0 = admin->getMesh()->getNode(VERTEX);
for (int i = 0; i < vertices; i++) {
CHANGE_DOFS_2(this);
}
for (int i = 0; i < vertices; i++)
changeDofs2(n0, nd0, nd, i);
}
if (mesh->getDim() > 1) {
nd = admin->getNumberOfDofs(EDGE);
if (nd) {
int edges = mesh->getGeo(EDGE);
nd0 = admin->getNumberOfPreDOFs(EDGE);
n0 = admin->getMesh()->getNode(EDGE);
for (int i = 0; i < edges; i++) {
CHANGE_DOFS_2(this);
}
for (int i = 0; i < edges; i++)
changeDofs2(n0, nd0, nd, i);
}
}
if (mesh->getDim() == 3) {
nd = admin->getNumberOfDofs(FACE);
if (nd) {
int faces = mesh->getGeo(FACE);
nd0 = admin->getNumberOfPreDOFs(FACE);
n0 = admin->getMesh()->getNode(FACE);
for (int i = 0; i < faces; i++) {
CHANGE_DOFS_2(this);
}
for (int i = 0; i < faces; i++)
changeDofs2(n0, nd0, nd, i);
}
}
......@@ -307,13 +278,31 @@ namespace AMDiS {
nd0 = admin->getNumberOfPreDOFs(CENTER);
n0 = admin->getMesh()->getNode(CENTER);
// only one center
int i = 0;
CHANGE_DOFS_2(this);
changeDofs2(n0, nd0, nd, 0);
}
}
#undef CHANGE_DOFS_1
#undef CHANGE_DOFS_2
void Element::changeDofs1(const DOFAdmin* admin, int n0, int nd0, int nd, int pos)
{
DegreeOfFreedom *ldof = dof[n0 + pos] + nd0;
for (int j = 0; j < nd; j++) {
int k = ldof[j];
if (k >= 0)
ldof[j] = -admin->getMesh()->newDOF[k] - 1;
}
}
void Element::changeDofs2(int n0, int nd0, int nd, int pos)
{
DegreeOfFreedom *ldof = dof[n0 + pos] + nd0;
for (int j = 0; j < nd; j++) {
int k = ldof[j];
if (k < 0)
ldof[j] = -k - 1;
}
}
/****************************************************************************/
......
......@@ -22,12 +22,12 @@
#ifndef AMDIS_ELEMENT_H
#define AMDIS_ELEMENT_H
#include "AMDiS_fwd.h"
#include "Global.h"
#include "RefinementManager.h"
#include "Serializable.h"
#include "ElementData.h"
#include "LeafData.h"
#include "AMDiS_fwd.h"
namespace AMDiS {
......@@ -521,10 +521,16 @@ namespace AMDiS {
}
/// Used by friend class Mesh while dofCompress
void newDOFFct1(const DOFAdmin*);
void newDofFct1(const DOFAdmin*);
/// Used by friend class Mesh while dofCompress
void newDOFFct2(const DOFAdmin*);
void newDofFct2(const DOFAdmin*);
/// Changes old dofs to negative new dofs
void changeDofs1(const DOFAdmin* admin, int n0, int nd0, int nd, int pos);
/// Changes negative new dofs to positive
void changeDofs2(int n0, int nd0, int nd, int pos);
protected:
/** \brief
......
......@@ -472,13 +472,13 @@ namespace AMDiS {
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(this, -1, fill_flag);
while (elInfo) {
elInfo->getElement()->newDOFFct1(compressAdmin);
elInfo->getElement()->newDofFct1(compressAdmin);
elInfo = stack.traverseNext(elInfo);
}
elInfo = stack.traverseFirst(this, -1, fill_flag);
while (elInfo) {
elInfo->getElement()->newDOFFct2(compressAdmin);
elInfo->getElement()->newDofFct2(compressAdmin);
elInfo = stack.traverseNext(elInfo);
}
......@@ -613,6 +613,7 @@ namespace AMDiS {
}
delete [] dof;
dof = NULL;
}
......
......@@ -880,8 +880,9 @@ namespace AMDiS {
friend class MacroWriter;
friend class MacroElement;
friend class Element;
friend void Element::newDOFFct1(const DOFAdmin*);
friend void Element::newDOFFct2(const DOFAdmin*);
friend void Element::newDofFct1(const DOFAdmin*);
friend void Element::newDofFct2(const DOFAdmin*);
friend void Element::changeDofs1(const DOFAdmin*, int, int, int, int);
};
}
......
......@@ -7,6 +7,7 @@
#include <boost/filesystem.hpp>
#include "parallel/MeshDistributor.h"
#include "parallel/MeshManipulation.h"
#include "parallel/ParallelDebug.h"
#include "parallel/StdMpi.h"
#include "parallel/ParMetisPartitioner.h"
......@@ -54,6 +55,7 @@ namespace AMDiS {
rstart(0),
deserialized(false),
writeSerializationFile(false),
repartitioningAllowed(false),
lastMeshChangeIndex(0),
macroElementStructureConsisten(false)
{
......@@ -62,6 +64,10 @@ namespace AMDiS {
mpiRank = MPI::COMM_WORLD.Get_rank();
mpiSize = MPI::COMM_WORLD.Get_size();
mpiComm = MPI::COMM_WORLD;
int tmp = 0;
GET_PARAMETER(0, name + "->repartitioning", "%d", &tmp);
repartitioningAllowed = (tmp > 0);
}
......@@ -566,7 +572,8 @@ namespace AMDiS {
// === The mesh has changed, so check if it is required to repartition the mesh. ===
repartitionMesh();
if (repartitioningAllowed)
repartitionMesh();
}
......@@ -981,8 +988,6 @@ namespace AMDiS {
if (repartitioning == 0)
return;
return;
DOFVector<double> tmpa(feSpace, "tmp");
tmpa.set(mpiRank);
VtkWriter::writeFile(tmpa, "before-repartition.vtu");
......@@ -1040,8 +1045,6 @@ namespace AMDiS {
for (std::set<MacroElement*>::iterator it = newMacroEl.begin();
it != newMacroEl.end(); ++it) {
MacroElement *mel = *it;
// MSG("NEW MACRO EL: %d\n", mel->getIndex());
for (int i = 0; i < mesh->getGeo(NEIGH); i++)
mel->setNeighbour(i, NULL);
......@@ -1059,7 +1062,6 @@ namespace AMDiS {
it != partitioner->getSendElements().end(); ++it) {
for (std::vector<int>::iterator elIt = it->second.begin();
elIt != it->second.end(); ++elIt) {
// MSG("MAKE EL-STRUC FOR EL %d TO RANK %d\n", *elIt, it->first);
MeshStructure elCode;
elCode.init(mesh, *elIt);
sendCodes[it->first].push_back(elCode);
......@@ -1083,16 +1085,10 @@ namespace AMDiS {
("Should not happen!\n");
for (std::vector<int>::iterator elIt = it->second.begin();
elIt != it->second.end(); ++elIt) {
// MSG("RECV EL-STRUC FOR EL %d FROM RANK %d\n", *elIt, it->first);
elIt != it->second.end(); ++elIt)
recvCodes[i++].fitMeshToStructure(mesh, refineManager, false, *elIt);
}
}
MSG("DAS IST FERTIG!\n");
// === Set correct neighbour information on macro elements. ===
......@@ -1120,120 +1116,24 @@ namespace AMDiS {
elIt != it->second.end(); ++elIt) {
TEST_EXIT_DBG(elIndexMap.count(*elIt) == 1)
("Could not find macro element %d\n", *elIt);
// MSG("DELETE MACRO %d\n", (*elIt));
deleteMacroElements.insert(elIndexMap[*elIt]);
}
}
// MSG("REMOVE MACRO ELEMENT!\n");
mesh->removeMacroElements(deleteMacroElements, feSpace);
// === Remove double DOFs. ===
std::map<int, MacroElement*> leafInMacroEl;
elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
while (elInfo) {
leafInMacroEl[elInfo->getElement()->getIndex()] = elInfo->getMacroElement();
elInfo = stack.traverseNext(elInfo);
}
std::map<const DegreeOfFreedom*, const DegreeOfFreedom*> mapDelDofs;
elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH);
while (elInfo) {
Element *el = elInfo->getElement();
for (int i = 0; i < mesh->getGeo(NEIGH); i++) {
Element *neigh = elInfo->getNeighbour(i);
if (!neigh)
continue;
if (leafInMacroEl[el->getIndex()] !=
leafInMacroEl[neigh->getIndex()] &&
newMacroEl.count(leafInMacroEl[el->getIndex()]) == 0 &&
newMacroEl.count(leafInMacroEl[neigh->getIndex()]) == 1) {
// MSG("EL: %d NEIGH: %d\n", el->getIndex(), neigh->getIndex());
int elEdgeIndex = i;
int neighEdgeIndex = elInfo->getOppVertex(i);
DofEdge elEdge = el->getEdge(elEdgeIndex);
DofEdge neighEdge = neigh->getEdge(neighEdgeIndex);
if (elEdge != neighEdge) {
int elEdgeIndex0 = el->getVertexOfEdge(elEdgeIndex, 0);
int elEdgeIndex1 = el->getVertexOfEdge(elEdgeIndex, 1);
int neighEdgeIndex0 = neigh->getVertexOfEdge(neighEdgeIndex, 0);
int neighEdgeIndex1 = neigh->getVertexOfEdge(neighEdgeIndex, 1);
DegreeOfFreedom elEdgeDof0 = el->getDof(elEdgeIndex0, 0);
DegreeOfFreedom elEdgeDof1 = el->getDof(elEdgeIndex1, 0);
DegreeOfFreedom neighEdgeDof0 = neigh->getDof(neighEdgeIndex0, 0);
DegreeOfFreedom neighEdgeDof1 = neigh->getDof(neighEdgeIndex1, 0);
if ((elEdgeDof0 < elEdgeDof1 && neighEdgeDof0 > neighEdgeDof1) ||
(elEdgeDof0 > elEdgeDof1 && neighEdgeDof0 < neighEdgeDof1)) {
std::swap(neighEdgeIndex0, neighEdgeIndex1);
std::swap(neighEdgeDof0, neighEdgeDof1);
}
if (neighEdgeDof0 != elEdgeDof0) {
mapDelDofs[neigh->getDof(neighEdgeIndex0)] = el->getDof(elEdgeIndex0);
// MSG("REPLACE DOF %d by %d\n", neigh->getDof(neighEdgeIndex0, 0), el->getDof(elEdgeIndex0, 0));
}
if (neighEdgeDof1 != elEdgeDof1) {
mapDelDofs[neigh->getDof(neighEdgeIndex1)] = el->getDof(elEdgeIndex1);
// MSG("REPLACE DOF %d by %d\n", neigh->getDof(neighEdgeIndex1, 0), el->getDof(elEdgeIndex1, 0));
}
}
}
}
elInfo = stack.traverseNext(elInfo);
}
elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
while (elInfo) {
for (int i = 0; i < mesh->getGeo(VERTEX); i++)
if (mapDelDofs.count(elInfo->getElement()->getDof(i)) == 1) {
// MSG("SET DOF %d TO DOF %d in EL %d\n",
// elInfo->getElement()->getDof(i, 0),
// *(mapDelDofs[elInfo->getElement()->getDof(i)]),
// elInfo->getElement()->getIndex());
elInfo->getElement()->setDof(i, const_cast<DegreeOfFreedom*>(mapDelDofs[elInfo->getElement()->getDof(i)]));
}
elInfo = stack.traverseNext(elInfo);
}
for (std::map<const DegreeOfFreedom*, const DegreeOfFreedom*>::iterator it = mapDelDofs.begin();
it != mapDelDofs.end(); ++it) {
// MSG("DOF TO DEL: %d\n", (*(it->first)));
mesh->freeDof(const_cast<DegreeOfFreedom*>(it->first), VERTEX);
}
MeshManipulation meshManipulation(mesh);
meshManipulation.deleteDoubleDofs(newMacroEl);
mesh->dofCompress();
MSG("WRITE OUTPUT\n");
DOFVector<double> tmp(feSpace, "tmp");
tmp.set(mpiRank);
VtkWriter::writeFile(tmp, "after-repartition.vtu");
MSG("DONE!\n");
MSG("USED-SIZE B: %d\n", mesh->getDofAdmin(0).getUsedDofs());
exit(0);
......
......@@ -107,13 +107,6 @@ namespace AMDiS {
/// Set for each element on the partitioning level the number of leaf elements.
void setInitialElementWeights();
/** \brief
* Checks if is required to repartition the mesh. If this is the case, a new
* partition will be created and the mesh will be redistributed between the
* ranks.
*/
void repartitionMesh();
inline virtual std::string getName()
{
return name;
......@@ -314,7 +307,14 @@ namespace AMDiS {
* should be checked.
*/
bool checkAndAdaptBoundary(RankToBoundMap &allBound);
/** \brief
* Checks if is required to repartition the mesh. If this is the case, a new
* partition will be created and the mesh will be redistributed between the
* ranks.
*/
void repartitionMesh();
/** \brief
* This functions create a Paraview file with the macro mesh where the elements
* are colored by the partition they are part of. This function can be used for
......@@ -576,6 +576,9 @@ namespace AMDiS {
/// Denotes whether there exists a filewriter for this object.
bool writeSerializationFile;
/// If true, it is possible to repartition the mesh during computations.
bool repartitioningAllowed;
/** \brief
* Stores the mesh change index. This is used to recognize changes in the mesh
* structure (e.g. through refinement or coarsening managers).
......
#include "parallel/MeshManipulation.h"
#include "Mesh.h"
#include "Traverse.h"
namespace AMDiS {
void MeshManipulation::deleteDoubleDofs(std::set<MacroElement*>& newMacroEl)
{
std::map<int, MacroElement*> leafInMacroEl;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
while (elInfo) {
leafInMacroEl[elInfo->getElement()->getIndex()] = elInfo->getMacroElement();
elInfo = stack.traverseNext(elInfo);
}
deleteDoubleDofs(leafInMacroEl, newMacroEl, 0);
deleteDoubleDofs(leafInMacroEl, newMacroEl, 1);
}
void MeshManipulation::deleteDoubleDofs(std::map<int, MacroElement*>& leafInMacroEl,
std::set<MacroElement*>& newMacroEl,
int mode)
{
FUNCNAME("MeshManipulation::deleteDoubleDofs()");
std::map<const DegreeOfFreedom*, const DegreeOfFreedom*> mapDelDofs;
std::map<const DegreeOfFreedom*, int> mapDofsMacro;
TraverseStack stack;
ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH);
while (elInfo) {
Element *el = elInfo->getElement();
for (int i = 0; i < mesh->getGeo(NEIGH); i++) {
Element *neigh = elInfo->getNeighbour(i);
if (!neigh)
continue;
int elMacroIndex = leafInMacroEl[el->getIndex()]->getIndex();
int neighMacroIndex = leafInMacroEl[neigh->getIndex()]->getIndex();
if (elMacroIndex == neighMacroIndex)
continue;
if ((mode == 0 &&
newMacroEl.count(leafInMacroEl[el->getIndex()]) == 1 &&
newMacroEl.count(leafInMacroEl[neigh->getIndex()]) == 1 &&
elMacroIndex > neighMacroIndex) ||
(mode == 1 &&
newMacroEl.count(leafInMacroEl[el->getIndex()]) == 0 &&
newMacroEl.count(leafInMacroEl[neigh->getIndex()]) == 1)) {
// MSG("EL: %d NEIGH: %d\n", el->getIndex(), neigh->getIndex());
if (el->getEdge(i) != neigh->getEdge(elInfo->getOppVertex(i))) {
std::vector<int> elEdgeIndex(2);
elEdgeIndex[0] = el->getVertexOfEdge(i, 0);
elEdgeIndex[1] = el->getVertexOfEdge(i, 1);
std::vector<int> neighEdgeIndex(2);
neighEdgeIndex[0] = neigh->getVertexOfEdge(elInfo->getOppVertex(i), 0);
neighEdgeIndex[1] = neigh->getVertexOfEdge(elInfo->getOppVertex(i), 1);
std::vector<DegreeOfFreedom> elEdgeDof(2);
elEdgeDof[0] = el->getDof(elEdgeIndex[0], 0);
elEdgeDof[1] = el->getDof(elEdgeIndex[1], 0);
std::vector<DegreeOfFreedom> neighEdgeDof(2);
neighEdgeDof[0] = neigh->getDof(neighEdgeIndex[0], 0);
neighEdgeDof[1] = neigh->getDof(neighEdgeIndex[1], 0);
// MSG("TEST DOFs %d %d <-> %d %d\n", elEdgeDof0, elEdgeDof1, neighEdgeDof0, neighEdgeDof1);