Commit 747241d3 authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

Fixed small problem with periodic boundary conditions in 2D, thanks to Simon for bug reporting.

parent d1c7c9da
...@@ -28,7 +28,7 @@ namespace AMDiS { ...@@ -28,7 +28,7 @@ namespace AMDiS {
ElInfo* TraverseStack::traverseFirst(Mesh *mesh, int level, Flag fill_flag) ElInfo* TraverseStack::traverseFirst(Mesh *mesh, int level, Flag fill_flag)
{ {
FUNCNAME("TraverseStack::traverseFirst()"); FUNCNAME("TraverseStack::traverseFirst()");
TEST_EXIT_DBG(fill_flag.isSet(Mesh::CALL_REVERSE_MODE) == false || TEST_EXIT_DBG(fill_flag.isSet(Mesh::CALL_REVERSE_MODE) == false ||
fill_flag.isSet(Mesh::CALL_EVERY_EL_PREORDER)) fill_flag.isSet(Mesh::CALL_EVERY_EL_PREORDER))
("Not yet implemented!\n"); ("Not yet implemented!\n");
......
...@@ -159,14 +159,6 @@ namespace AMDiS { ...@@ -159,14 +159,6 @@ namespace AMDiS {
// vtkVectorWriter.setWriteAs3dVector(writeAs3dVector); // vtkVectorWriter.setWriteAs3dVector(writeAs3dVector);
// vtkVectorWriter.writeFile(fn + paraviewFileExt); // vtkVectorWriter.writeFile(fn + paraviewFileExt);
#if HAVE_PARALLEL_DOMAIN_AMDIS
ERROR_EXIT("Simon must make some work in this, does not compile in parallel!\n");
// if (MPI::COMM_WORLD.Get_rank() == 0)
// vtkVectorWriter.writeParallelFile(paraFilename + paraviewParallelFileExt,
// MPI::COMM_WORLD.Get_size(),
// filename, postfix);
#endif
MSG("ParaView file written to %s\n", (fn + paraviewFileExt).c_str()); MSG("ParaView file written to %s\n", (fn + paraviewFileExt).c_str());
} }
......
...@@ -140,6 +140,12 @@ namespace AMDiS { ...@@ -140,6 +140,12 @@ namespace AMDiS {
if (periodicVertices.size() == 0) if (periodicVertices.size() == 0)
return; return;
// === Calculate smallest periodic boundary ID in mesh. ===
smallestPeriodicBcType = 0;
for (map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin();
it != mesh->getPeriodicAssociations().end(); ++it)
smallestPeriodicBcType = std::min(smallestPeriodicBcType, it->first);
// === Get all vertex DOFs that have multiple periodic associations. === // === Get all vertex DOFs that have multiple periodic associations. ===
......
...@@ -450,6 +450,14 @@ namespace AMDiS { ...@@ -450,6 +450,14 @@ namespace AMDiS {
return (periodicVertices.size() != 0); return (periodicVertices.size() != 0);
} }
/// Returns true if the given boundary type is larger or equal to the smallest
/// periodic boundary ID in mesh. See \ref smallestPeriodicBcType for more
/// information.
bool isValidPeriodicType(BoundaryType t) const
{
return (t >= smallestPeriodicBcType);
}
/// Write the element database to disk. /// Write the element database to disk.
void serialize(ostream &out); void serialize(ostream &out);
...@@ -574,15 +582,21 @@ namespace AMDiS { ...@@ -574,15 +582,21 @@ namespace AMDiS {
map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap; map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
// The following three data structures store periodic DOFs, edges and faces. /// The following three data structures store periodic DOFs, edges and faces.
PerBoundMap<DegreeOfFreedom>::type periodicVertices; PerBoundMap<DegreeOfFreedom>::type periodicVertices;
PerBoundMap<DofEdge>::type periodicEdges; PerBoundMap<DofEdge>::type periodicEdges;
PerBoundMap<DofFace>::type periodicFaces; PerBoundMap<DofFace>::type periodicFaces;
// Stores to each vertex all its periodic associations. /// Defines the smallest boudary ID for periodic boundary conditions. This is
/// required to distinguish between "real" periodic boundaries and periodic
/// boundary IDs that are set by the parallel algorithm for indirectly
/// connected boundaries.
BoundaryType smallestPeriodicBcType;
/// Stores to each vertex all its periodic associations.
map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc; map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
// Stores to each edge all its periodic associations. /// Stores to each edge all its periodic associations.
map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc; map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;
map<pair<ElementObjectData, ElementObjectData>, bool> edgeReverseMode; map<pair<ElementObjectData, ElementObjectData>, bool> edgeReverseMode;
......
...@@ -132,6 +132,8 @@ namespace AMDiS { ...@@ -132,6 +132,8 @@ namespace AMDiS {
{ {
FUNCNAME("MeshDistributor::initParallelization()"); FUNCNAME("MeshDistributor::initParallelization()");
MSG("RUN INIT\n");
if (initialized) if (initialized)
return; return;
...@@ -2067,13 +2069,6 @@ namespace AMDiS { ...@@ -2067,13 +2069,6 @@ namespace AMDiS {
{ {
FUNCNAME("MeshDistributor::createPeriodicMap()"); FUNCNAME("MeshDistributor::createPeriodicMap()");
// vector<ElementObjectData> objs = elObjDb.getElements(0);
// MSG("SIZE OF 0-DOF is: %d\n", objs.size());
// for (int i = 0; i < objs.size(); i++)
// MSG("0-DOF IN EL %d - %d\n", objs[i].elIndex, objs[i].ithObject);
StdMpi<vector<int> > stdMpi(mpiComm, false); StdMpi<vector<int> > stdMpi(mpiComm, false);
// === Each rank traverse its periodic boundaries and sends the DOF === // === Each rank traverse its periodic boundaries and sends the DOF ===
...@@ -2112,15 +2107,8 @@ namespace AMDiS { ...@@ -2112,15 +2107,8 @@ namespace AMDiS {
DegreeOfFreedom globalDof1 = DegreeOfFreedom globalDof1 =
dofFeData[feSpace].mapDofToGlobal[*(dofs1[j])]; dofFeData[feSpace].mapDofToGlobal[*(dofs1[j])];
if (!periodicMap.isPeriodicOnBound(feSpace, type, globalDof0)) { if (!periodicMap.isPeriodicOnBound(feSpace, type, globalDof0))
// if (globalDof0 == 0) {
// MSG("A-ADD DOF 0 at BOUND: %d %d %d <-> %d %d %d \n",
// bound.rankObj.elIndex, bound.rankObj.subObj, bound.rankObj.ithObj,
// bound.neighObj.elIndex, bound.neighObj.subObj, bound.neighObj.ithObj);
// }
periodicMap.add(feSpace, type, globalDof0, globalDof1); periodicMap.add(feSpace, type, globalDof0, globalDof1);
}
} }
} }
...@@ -2132,9 +2120,6 @@ namespace AMDiS { ...@@ -2132,9 +2120,6 @@ namespace AMDiS {
for (vector<AtomicBoundary>::iterator boundIt = it->second.begin(); for (vector<AtomicBoundary>::iterator boundIt = it->second.begin();
boundIt != it->second.end(); ++boundIt) { boundIt != it->second.end(); ++boundIt) {
// MSG(" NOW ADD DOFS ON PER BOUND EL %d %d with rank %d\n",
// boundIt->rankObj.elIndex, boundIt->rankObj.subObj, it->first);
int nDofs = dofs.size(); int nDofs = dofs.size();
boundIt->rankObj.el->getAllDofs(feSpace, boundIt->rankObj, dofs); boundIt->rankObj.el->getAllDofs(feSpace, boundIt->rankObj, dofs);
...@@ -2177,14 +2162,8 @@ namespace AMDiS { ...@@ -2177,14 +2162,8 @@ namespace AMDiS {
// Check if this global DOF with the corresponding boundary type was // Check if this global DOF with the corresponding boundary type was
// not added before by another periodic boundary from other rank. // not added before by another periodic boundary from other rank.
if (!periodicMap.isPeriodicOnBound(feSpace, type, globalDofIndex)) { if (!periodicMap.isPeriodicOnBound(feSpace, type, globalDofIndex))
// MSG("B-ADD DOF %d -> %d at BOUND from rank %d\n",
// globalDofIndex,
// mapGlobalDofIndex,
// it->first);
periodicMap.add(feSpace, type, globalDofIndex, mapGlobalDofIndex); periodicMap.add(feSpace, type, globalDofIndex, mapGlobalDofIndex);
}
} }
} }
...@@ -2201,7 +2180,9 @@ namespace AMDiS { ...@@ -2201,7 +2180,9 @@ namespace AMDiS {
for (vector<AtomicBoundary>::iterator boundIt = it->second.begin(); for (vector<AtomicBoundary>::iterator boundIt = it->second.begin();
boundIt != it->second.end(); ++boundIt) { boundIt != it->second.end(); ++boundIt) {
if (boundIt->type >= -3) // If the boundary type is a normal periodic BC, continue. We just
// operate on indirectly connected periodic boundaries.
if (elObjDb.isValidPeriodicType(boundIt->type))
continue; continue;
DofContainer dofs; DofContainer dofs;
...@@ -2217,15 +2198,9 @@ namespace AMDiS { ...@@ -2217,15 +2198,9 @@ namespace AMDiS {
for (std::set<BoundaryType>::iterator perAscIt = assoc.begin(); for (std::set<BoundaryType>::iterator perAscIt = assoc.begin();
perAscIt != assoc.end(); ++perAscIt) perAscIt != assoc.end(); ++perAscIt)
if (*perAscIt >= -3) { if (elObjDb.isValidPeriodicType(*perAscIt))
// MSG(" add map DOF %d -> %d (%d)\n",
// globalDof,
// periodicMap.map(feSpace, *perAscIt, globalDof),
// *perAscIt);
perObjMap[*perAscIt][globalDof] = perObjMap[*perAscIt][globalDof] =
periodicMap.map(feSpace, *perAscIt, globalDof); periodicMap.map(feSpace, *perAscIt, globalDof);
}
} }
} }
...@@ -2240,7 +2215,7 @@ namespace AMDiS { ...@@ -2240,7 +2215,7 @@ namespace AMDiS {
// DOFs. I'm note sure what is correct here. // DOFs. I'm note sure what is correct here.
for (map<int, PeriodicDofMap>::iterator it = stdMpi2.getRecvData().begin(); for (map<int, PeriodicDofMap>::iterator it = stdMpi2.getRecvData().begin();
it != stdMpi2.getRecvData().end(); ++it) it != stdMpi2.getRecvData().end(); ++it)
periodicMap.add(feSpace, it->second); periodicMap.add(feSpace, it->second, false);
} }
......
...@@ -443,11 +443,13 @@ namespace AMDiS { ...@@ -443,11 +443,13 @@ namespace AMDiS {
void getAllBoundaryDofs(const FiniteElemSpace *feSpace, void getAllBoundaryDofs(const FiniteElemSpace *feSpace,
DofContainer& dofs); DofContainer& dofs);
const ElementObjectDatabase& getElementObjectDb()
{
return elObjDb;
}
public:
/// Adds a stationary problem to the global mesh distributor objects. /// Adds a stationary problem to the global mesh distributor objects.
static void addProblemStatGlobal(ProblemStatSeq *probStat); static void addProblemStatGlobal(ProblemStatSeq *probStat);
protected: protected:
void addProblemStat(ProblemStatSeq *probStat); void addProblemStat(ProblemStatSeq *probStat);
......
...@@ -16,14 +16,15 @@ ...@@ -16,14 +16,15 @@
namespace AMDiS { namespace AMDiS {
void PeriodicMap::add(const FiniteElemSpace *feSpace, void PeriodicMap::add(const FiniteElemSpace *feSpace,
PeriodicDofMap &newMap) PeriodicDofMap &newMap,
bool a)
{ {
FUNCNAME("PeriodicMap::add()"); FUNCNAME("PeriodicMap::add()");
for (PeriodicDofMap::iterator it = newMap.begin(); it != newMap.end(); ++it) for (PeriodicDofMap::iterator it = newMap.begin(); it != newMap.end(); ++it)
for (DofMap::iterator dofIt =it->second.begin(); for (DofMap::iterator dofIt =it->second.begin();
dofIt != it->second.end(); ++dofIt) dofIt != it->second.end(); ++dofIt)
add(feSpace, it->first, dofIt->second, dofIt->first); add(feSpace, it->first, dofIt->second, dofIt->first, a);
} }
......
...@@ -101,7 +101,8 @@ namespace AMDiS { ...@@ -101,7 +101,8 @@ namespace AMDiS {
/// this DOFs that maps to a different DOF index than the given one. /// this DOFs that maps to a different DOF index than the given one.
inline void add(const FiniteElemSpace *feSpace, inline void add(const FiniteElemSpace *feSpace,
BoundaryType type, BoundaryType type,
DegreeOfFreedom dof0, DegreeOfFreedom dof1) DegreeOfFreedom dof0, DegreeOfFreedom dof1,
bool a = true)
{ {
FUNCNAME("PeriodicMap::map()"); FUNCNAME("PeriodicMap::map()");
...@@ -110,12 +111,13 @@ namespace AMDiS { ...@@ -110,12 +111,13 @@ namespace AMDiS {
("Should not happen!\n"); ("Should not happen!\n");
periodicDofMap[feSpace][type][dof0] = dof1; periodicDofMap[feSpace][type][dof0] = dof1;
periodicDofAssociations[feSpace][dof0].insert(type); if (a)
periodicDofAssociations[feSpace][dof0].insert(type);
} }
/// Adds a whole periodic mapping to the current one. /// Adds a whole periodic mapping to the current one.
void add(const FiniteElemSpace *feSpace, PeriodicDofMap &newMap); void add(const FiniteElemSpace *feSpace, PeriodicDofMap &newMap, bool a = true);
/// For a given global DOF index, this function returns the set of periodic /// For a given global DOF index, this function returns the set of periodic
......
...@@ -307,7 +307,7 @@ namespace AMDiS { ...@@ -307,7 +307,7 @@ namespace AMDiS {
std::set<int>& perColAsc = perMap.getAssociations(colFe, globalColDof); std::set<int>& perColAsc = perMap.getAssociations(colFe, globalColDof);
for (std::set<int>::iterator it = perColAsc.begin(); for (std::set<int>::iterator it = perColAsc.begin();
it != perColAsc.end(); ++it) it != perColAsc.end(); ++it)
if (*it >= -3) if (meshDistributor->getElementObjectDb().isValidPeriodicType(*it))
perAsc.insert(*it); perAsc.insert(*it);
// Scale value to the number of periodic associations of the column index. // Scale value to the number of periodic associations of the column index.
...@@ -322,7 +322,7 @@ namespace AMDiS { ...@@ -322,7 +322,7 @@ namespace AMDiS {
// First, add the original matrix index. // First, add the original matrix index.
newCols.push_back(globalColDof); newCols.push_back(globalColDof);
// And add all periodic matrix indices. // And add all periodic matrix indices.
for (std::set<int>::iterator it = perAsc.begin(); for (std::set<int>::iterator it = perAsc.begin();
it != perAsc.end(); ++it) { it != perAsc.end(); ++it) {
...@@ -377,14 +377,14 @@ namespace AMDiS { ...@@ -377,14 +377,14 @@ namespace AMDiS {
std::set<int>& perColAsc = perMap.getAssociations(colFe, globalColDof); std::set<int>& perColAsc = perMap.getAssociations(colFe, globalColDof);
for (std::set<int>::iterator it = perColAsc.begin(); for (std::set<int>::iterator it = perColAsc.begin();
it != perColAsc.end(); ++it) it != perColAsc.end(); ++it)
if (*it >= -3) if (meshDistributor->getElementObjectDb().isValidPeriodicType(*it))
perAsc.insert(*it); perAsc.insert(*it);
} }
std::set<int>& perRowAsc = perMap.getAssociations(rowFe, globalRowDof); std::set<int>& perRowAsc = perMap.getAssociations(rowFe, globalRowDof);
for (std::set<int>::iterator it = perRowAsc.begin(); for (std::set<int>::iterator it = perRowAsc.begin();
it != perRowAsc.end(); ++it) it != perRowAsc.end(); ++it)
if (*it >= -3) if (meshDistributor->getElementObjectDb().isValidPeriodicType(*it))
perAsc.insert(*it); perAsc.insert(*it);
// Scale the value with respect to the number of periodic associations. // Scale the value with respect to the number of periodic associations.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment