diff --git a/AMDiS/src/parallel/ElementObjectData.cc b/AMDiS/src/parallel/ElementObjectData.cc index 3e22eaa18b969f02cdbc71f849b58005512bb2b2..b005e1fc1f723881237ad4ea6cb94eff493ecbd8 100644 --- a/AMDiS/src/parallel/ElementObjectData.cc +++ b/AMDiS/src/parallel/ElementObjectData.cc @@ -11,69 +11,369 @@ #include "ElementObjectData.h" +#include "VertexVector.h" namespace AMDiS { - void ElementObjects::createRankData(std::map<int, int>& macroElementRankMap) + void ElementObjects::addElement(ElInfo *elInfo) + { + FUNCNAME("ElementObjects::addElement()"); + + TEST_EXIT_DBG(mesh)("Mesh not set!\n"); + + Element *el = elInfo->getElement(); + + + // === First, add all element objects to the database. === + + for (int i = 0; i < el->getGeo(VERTEX); i++) + addVertex(el, i); + + for (int i = 0; i < el->getGeo(EDGE); i++) + addEdge(el, i); + + for (int i = 0; i < el->getGeo(FACE); i++) + addFace(el, i); + + + // === Get periodic boundary information. === + + switch (mesh->getDim()) { + case 2: + for (int i = 0; i < el->getGeo(EDGE); i++) { + if (mesh->isPeriodicAssociation(elInfo->getBoundary(EDGE, i))) { + // The current element's i-th edge is periodic. + Element *neigh = elInfo->getNeighbour(i); + + DofEdge edge0 = el->getEdge(i); + DofEdge edge1 = neigh->getEdge(elInfo->getOppVertex(i)); + BoundaryType boundaryType = elInfo->getBoundary(EDGE, i); + + // Add the periodic edge. + periodicEdges[make_pair(edge0, edge1)] = boundaryType; + periodicEdgeAssoc[edge0].insert(edge1); + + // Add both vertices of the edge to be periodic. + periodicVertices[make_pair(edge0.first, edge1.first)] = boundaryType; + periodicVertices[make_pair(edge0.second, edge1.second)] = boundaryType; + periodicDofAssoc[edge0.first].insert(boundaryType); + periodicDofAssoc[edge0.second].insert(boundaryType); + + TEST_EXIT_DBG(edge0.first == + mesh->getPeriodicAssociations(boundaryType)[edge1.first] && + edge0.second == + mesh->getPeriodicAssociations(boundaryType)[edge1.second]) + ("Should not happen!\n"); + } + } + break; + case 3: + for (int i = 0; i < el->getGeo(FACE); i++) { + if (mesh->isPeriodicAssociation(elInfo->getBoundary(FACE, i))) { + // The current element's i-th face is periodic. + Element *neigh = elInfo->getNeighbour(i); + + DofFace face0 = el->getFace(i); + DofFace face1 = neigh->getFace(elInfo->getOppVertex(i)); + BoundaryType boundaryType = elInfo->getBoundary(FACE, i); + + // Add the periodic face. + periodicFaces[make_pair(face0, face1)] = elInfo->getBoundary(i); + + /// Add all three vertices of the face to be periodic. + periodicVertices[make_pair(face0.get<0>(), face1.get<0>())] = boundaryType; + periodicVertices[make_pair(face0.get<1>(), face1.get<1>())] = boundaryType; + periodicVertices[make_pair(face0.get<2>(), face1.get<2>())] = boundaryType; + + periodicDofAssoc[face0.get<0>()].insert(boundaryType); + periodicDofAssoc[face0.get<1>()].insert(boundaryType); + periodicDofAssoc[face0.get<2>()].insert(boundaryType); + + TEST_EXIT_DBG(face0.get<0>() == + mesh->getPeriodicAssociations(boundaryType)[face1.get<0>()] && + face0.get<1>() == + mesh->getPeriodicAssociations(boundaryType)[face1.get<1>()] && + face0.get<2>() == + mesh->getPeriodicAssociations(boundaryType)[face1.get<2>()]) + ("Should not happen!\n"); + + // Create all three edges of the element and add them to be periodic. + DofEdge elEdge0 = make_pair(face0.get<0>(), face0.get<1>()); + DofEdge elEdge1 = make_pair(face0.get<0>(), face0.get<2>()); + DofEdge elEdge2 = make_pair(face0.get<1>(), face0.get<2>()); + DofEdge neighEdge0 = make_pair(face1.get<0>(), face1.get<1>()); + DofEdge neighEdge1 = make_pair(face1.get<0>(), face1.get<2>()); + DofEdge neighEdge2 = make_pair(face1.get<1>(), face1.get<2>()); + + periodicEdges[make_pair(elEdge0, neighEdge0)] = boundaryType; + periodicEdges[make_pair(elEdge1, neighEdge1)] = boundaryType; + periodicEdges[make_pair(elEdge2, neighEdge2)] = boundaryType; + + periodicEdgeAssoc[elEdge0].insert(neighEdge0); + periodicEdgeAssoc[elEdge1].insert(neighEdge1); + periodicEdgeAssoc[elEdge2].insert(neighEdge2); + } + } + break; + default: + ERROR_EXIT("Should not happen!\n"); + } + } + + + void ElementObjects::createPeriodicData() + { + FUNCNAME("ElementObjects::createPeriodicData()"); + + TEST_EXIT_DBG(mesh)("Mesh not set!\n"); + + // === Return, if there are no periodic vertices, i.e., there are no no === + // === periodic boundaries in the mesh. === + + if (periodicVertices.size() == 0) + return; + + + // === Search for an unsed boundary index. === + + BoundaryType newPeriodicBoundaryType = 0; + for (map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); + it != mesh->getPeriodicAssociations().end(); ++it) + newPeriodicBoundaryType = min(newPeriodicBoundaryType, it->first); + + TEST_EXIT_DBG(newPeriodicBoundaryType < 0)("Should not happen!\n"); + newPeriodicBoundaryType--; + mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = + new VertexVector(feSpace->getAdmin(), ""); + + + // === Get all vertex DOFs that have multiple periodic associations. === + + // We group all vertices together, that have either two or three periodic + // associations. For rectangular domains in 2D, the four corner vertices have all + // two periodic associations. For box domains in 3D, the eight corner vertices + // have all three periodic associations. + + vector<DegreeOfFreedom> multPeriodicDof2, multPeriodicDof3; + for (map<DegreeOfFreedom, std::set<BoundaryType> >::iterator it = periodicDofAssoc.begin(); + it != periodicDofAssoc.end(); ++it) { + TEST_EXIT_DBG((mesh->getDim() == 2 && it->second.size() <= 2) || + (mesh->getDim() == 3 && it->second.size() <= 3)) + ("Should not happen!\n"); + + if (it->second.size() == 2) + multPeriodicDof2.push_back(it->first); + if (it->second.size() == 3) + multPeriodicDof3.push_back(it->first); + } + + + if (mesh->getDim() == 2) { + TEST_EXIT_DBG(multPeriodicDof2.size() == 0 || + multPeriodicDof2.size() == 4) + ("Should not happen (%d)!\n", multPeriodicDof2.size()); + TEST_EXIT_DBG(multPeriodicDof3.size() == 0)("Should not happen!\n"); + } + if (mesh->getDim() == 3) { + TEST_EXIT_DBG(multPeriodicDof3.size() == 0 || + multPeriodicDof3.size() == 8) + ("Should not happen (%d)!\n", multPeriodicDof3.size()); + } + + + if (multPeriodicDof2.size() > 0) { + for (unsigned int i = 0; i < multPeriodicDof2.size(); i++) { + DegreeOfFreedom dof0 = multPeriodicDof2[i]; + if (dof0 == -1) + continue; + + DegreeOfFreedom dof1 = -1; + DegreeOfFreedom dof2 = -1; + BoundaryType type0 = *(periodicDofAssoc[dof0].begin()); + BoundaryType type1 = *(++(periodicDofAssoc[dof0].begin())); + + for (PerBoundMap<DegreeOfFreedom>::iterator it = periodicVertices.begin(); + it != periodicVertices.end(); ++it) { + if (it->first.first == dof0 && it->second == type0) + dof1 = it->first.second; + if (it->first.first == dof0 && it->second == type1) + dof2 = it->first.second; + + if (dof1 != -1 && dof2 != -1) + break; + } + + TEST_EXIT_DBG(dof1 != -1 && dof2 != -1)("Should not happen!\n"); + + DegreeOfFreedom dof3 = -1; + for (PerBoundMap<DegreeOfFreedom>::iterator it = periodicVertices.begin(); + it != periodicVertices.end(); ++it) { + if (it->first.first == dof1 && it->second == type1) { + dof3 = it->first.second; + + TEST_EXIT_DBG(periodicVertices[make_pair(dof2, dof3)] == type0) + ("Should not happen!\n"); + + break; + } + } + + TEST_EXIT_DBG(dof3 != -1)("Should not happen!\n"); + TEST_EXIT_DBG(periodicVertices.count(make_pair(dof0, dof3)) == 0) + ("Should not happen!\n"); + TEST_EXIT_DBG(periodicVertices.count(make_pair(dof3, dof0)) == 0) + ("Should not happen!\n"); + + periodicVertices[make_pair(dof0, dof3)] = newPeriodicBoundaryType; + periodicVertices[make_pair(dof3, dof0)] = newPeriodicBoundaryType; + + for (unsigned int j = i + 1; j < multPeriodicDof2.size(); j++) + if (multPeriodicDof2[j] == dof3) + multPeriodicDof2[j] = -1; + } + } + + if (multPeriodicDof3.size() > 0) { + int nMultPeriodicDofs = multPeriodicDof3.size(); + for (int i = 0; i < nMultPeriodicDofs; i++) { + for (int j = i + 1; j < nMultPeriodicDofs; j++) { + pair<DegreeOfFreedom, DegreeOfFreedom> perDofs0 = + make_pair(multPeriodicDof3[i], multPeriodicDof3[j]); + pair<DegreeOfFreedom, DegreeOfFreedom> perDofs1 = + make_pair(multPeriodicDof3[j], multPeriodicDof3[i]); + + if (periodicVertices.count(perDofs0) == 0) { + TEST_EXIT_DBG(periodicVertices.count(perDofs1) == 0) + ("Should not happen!\n"); + + periodicVertices[perDofs0] = newPeriodicBoundaryType; + periodicVertices[perDofs1] = newPeriodicBoundaryType; + newPeriodicBoundaryType--; + mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = + new VertexVector(feSpace->getAdmin(), ""); + } + } + } + } + + + // === Get all edges that have multiple periodic associations (3D only!). === + + for (map<DofEdge, std::set<DofEdge> >::iterator it = periodicEdgeAssoc.begin(); + it != periodicEdgeAssoc.end(); ++it) { + if (it->second.size() > 1) { + TEST_EXIT_DBG(mesh->getDim() == 3)("Should not happen!\n"); + TEST_EXIT_DBG(it->second.size() == 2)("Should not happen!\n"); + + pair<DofEdge, DofEdge> perEdge0 = + make_pair(*(it->second.begin()), *(++(it->second.begin()))); + pair<DofEdge, DofEdge> perEdge1 = + make_pair(perEdge0.second, perEdge0.first); + + periodicEdges[perEdge0] = newPeriodicBoundaryType; + periodicEdges[perEdge1] = newPeriodicBoundaryType; + newPeriodicBoundaryType--; + mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = + new VertexVector(feSpace->getAdmin(), ""); + } + } + + + // === In debug mode we make some tests, if the periodic structures are set === + // === in a symmetric way, i.e., if A -> B for a specific boundary type, === + // === there must be a mapping B -> A with the same boundary type. === + +#if (DEBUG != 0) + for (PerBoundMap<DegreeOfFreedom>::iterator it = periodicVertices.begin(); + it != periodicVertices.end(); ++it) { + pair<DegreeOfFreedom, DegreeOfFreedom> testVertex = + make_pair(it->first.second, it->first.first); + + TEST_EXIT_DBG(periodicVertices.count(testVertex) == 1)("Should not happen!\n"); + TEST_EXIT_DBG(periodicVertices[testVertex] == it->second)("Should not happen!\n"); + } + + for (PerBoundMap<DofEdge>::iterator it = periodicEdges.begin(); + it != periodicEdges.end(); ++it) { + pair<DofEdge, DofEdge> testEdge = + make_pair(it->first.second, it->first.first); + + TEST_EXIT_DBG(periodicEdges.count(testEdge) == 1)("Should not happen!\n"); + TEST_EXIT_DBG(periodicEdges[testEdge] == it->second)("Should not happen!\n"); + } + + for (PerBoundMap<DofFace>::iterator it = periodicFaces.begin(); + it != periodicFaces.end(); ++it) { + pair<DofFace, DofFace> testFace = + make_pair(it->first.second, it->first.first); + + TEST_EXIT_DBG(periodicFaces.count(testFace) == 1)("Should not happen!\n"); + TEST_EXIT_DBG(periodicFaces[testFace] == it->second)("Should not happen!\n"); + } +#endif + } + + + void ElementObjects::createRankData(map<int, int>& macroElementRankMap) { FUNCNAME("ElementObjects::createRankData()"); vertexOwner.clear(); vertexInRank.clear(); - for (std::map<DegreeOfFreedom, std::vector<ElementObjectData> >::iterator it = vertexElements.begin(); + for (map<DegreeOfFreedom, vector<ElementObjectData> >::iterator it = vertexElements.begin(); it != vertexElements.end(); ++it) { - for (std::vector<ElementObjectData>::iterator it2 = it->second.begin(); + for (vector<ElementObjectData>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) { int elementInRank = macroElementRankMap[it2->elIndex]; if (it2->elIndex > vertexInRank[it->first][elementInRank].elIndex) vertexInRank[it->first][elementInRank] = *it2; - vertexOwner[it->first] = std::max(vertexOwner[it->first], elementInRank); + vertexOwner[it->first] = max(vertexOwner[it->first], elementInRank); } } edgeOwner.clear(); edgeInRank.clear(); - for (std::map<DofEdge, std::vector<ElementObjectData> >::iterator it = edgeElements.begin(); + for (map<DofEdge, vector<ElementObjectData> >::iterator it = edgeElements.begin(); it != edgeElements.end(); ++it) { - for (std::vector<ElementObjectData>::iterator it2 = it->second.begin(); + for (vector<ElementObjectData>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) { int elementInRank = macroElementRankMap[it2->elIndex]; if (it2->elIndex > edgeInRank[it->first][elementInRank].elIndex) edgeInRank[it->first][elementInRank] = *it2; - edgeOwner[it->first] = std::max(edgeOwner[it->first], elementInRank); + edgeOwner[it->first] = max(edgeOwner[it->first], elementInRank); } } faceOwner.clear(); faceInRank.clear(); - for (std::map<DofFace, std::vector<ElementObjectData> >::iterator it = faceElements.begin(); + for (map<DofFace, vector<ElementObjectData> >::iterator it = faceElements.begin(); it != faceElements.end(); ++it) { - for (std::vector<ElementObjectData>::iterator it2 = it->second.begin(); + for (vector<ElementObjectData>::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) { int elementInRank = macroElementRankMap[it2->elIndex]; if (it2->elIndex > faceInRank[it->first][elementInRank].elIndex) faceInRank[it->first][elementInRank] = *it2; - faceOwner[it->first] = std::max(faceOwner[it->first], elementInRank); + faceOwner[it->first] = max(faceOwner[it->first], elementInRank); } } } - void ElementObjects::serialize(std::ostream &out) + void ElementObjects::serialize(ostream &out) { FUNCNAME("ElementObjects::serialize()"); int nSize = vertexElements.size(); SerUtil::serialize(out, nSize); - for (std::map<DegreeOfFreedom, std::vector<ElementObjectData> >::iterator it = vertexElements.begin(); + for (map<DegreeOfFreedom, vector<ElementObjectData> >::iterator it = vertexElements.begin(); it != vertexElements.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -81,7 +381,7 @@ namespace AMDiS { nSize = edgeElements.size(); SerUtil::serialize(out, nSize); - for (std::map<DofEdge, std::vector<ElementObjectData> >::iterator it = edgeElements.begin(); + for (map<DofEdge, vector<ElementObjectData> >::iterator it = edgeElements.begin(); it != edgeElements.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -89,7 +389,7 @@ namespace AMDiS { nSize = faceElements.size(); SerUtil::serialize(out, nSize); - for (std::map<DofFace, std::vector<ElementObjectData> >::iterator it = faceElements.begin(); + for (map<DofFace, vector<ElementObjectData> >::iterator it = faceElements.begin(); it != faceElements.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -99,7 +399,7 @@ namespace AMDiS { nSize = vertexLocalMap.size(); SerUtil::serialize(out, nSize); - for (std::map<ElementObjectData, DegreeOfFreedom>::iterator it = vertexLocalMap.begin(); + for (map<ElementObjectData, DegreeOfFreedom>::iterator it = vertexLocalMap.begin(); it != vertexLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); @@ -107,7 +407,7 @@ namespace AMDiS { nSize = edgeLocalMap.size(); SerUtil::serialize(out, nSize); - for (std::map<ElementObjectData, DofEdge>::iterator it = edgeLocalMap.begin(); + for (map<ElementObjectData, DofEdge>::iterator it = edgeLocalMap.begin(); it != edgeLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); @@ -115,7 +415,7 @@ namespace AMDiS { nSize = faceLocalMap.size(); SerUtil::serialize(out, nSize); - for (std::map<ElementObjectData, DofFace>::iterator it = faceLocalMap.begin(); + for (map<ElementObjectData, DofFace>::iterator it = faceLocalMap.begin(); it != faceLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); @@ -130,7 +430,7 @@ namespace AMDiS { nSize = vertexInRank.size(); SerUtil::serialize(out, nSize); - for (std::map<DegreeOfFreedom, std::map<int, ElementObjectData> >::iterator it = vertexInRank.begin(); + for (map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator it = vertexInRank.begin(); it != vertexInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -138,7 +438,7 @@ namespace AMDiS { nSize = edgeInRank.size(); SerUtil::serialize(out, nSize); - for (std::map<DofEdge, std::map<int, ElementObjectData> >::iterator it = edgeInRank.begin(); + for (map<DofEdge, map<int, ElementObjectData> >::iterator it = edgeInRank.begin(); it != edgeInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -146,7 +446,7 @@ namespace AMDiS { nSize = faceInRank.size(); SerUtil::serialize(out, nSize); - for (std::map<DofFace, std::map<int, ElementObjectData> >::iterator it = faceInRank.begin(); + for (map<DofFace, map<int, ElementObjectData> >::iterator it = faceInRank.begin(); it != faceInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); @@ -158,7 +458,7 @@ namespace AMDiS { } - void ElementObjects::deserialize(std::istream &in) + void ElementObjects::deserialize(istream &in) { FUNCNAME("ElementObjects::deserialize()"); @@ -167,7 +467,7 @@ namespace AMDiS { vertexElements.clear(); for (int i = 0; i < nSize; i++) { DegreeOfFreedom dof; - std::vector<ElementObjectData> data; + vector<ElementObjectData> data; SerUtil::deserialize(in, dof); deserialize(in, data); vertexElements[dof] = data; @@ -177,7 +477,7 @@ namespace AMDiS { edgeElements.clear(); for (int i = 0; i < nSize; i++) { DofEdge edge; - std::vector<ElementObjectData> data; + vector<ElementObjectData> data; SerUtil::deserialize(in, edge); deserialize(in, data); edgeElements[edge] = data; @@ -187,7 +487,7 @@ namespace AMDiS { faceElements.clear(); for (int i = 0; i < nSize; i++) { DofFace face; - std::vector<ElementObjectData> data; + vector<ElementObjectData> data; SerUtil::deserialize(in, face); deserialize(in, data); faceElements[face] = data; @@ -235,7 +535,7 @@ namespace AMDiS { vertexInRank.clear(); for (int i = 0; i < nSize; i++) { DegreeOfFreedom dof; - std::map<int, ElementObjectData> data; + map<int, ElementObjectData> data; SerUtil::deserialize(in, dof); deserialize(in, data); vertexInRank[dof] = data; @@ -245,7 +545,7 @@ namespace AMDiS { edgeInRank.clear(); for (int i = 0; i < nSize; i++) { DofEdge edge; - std::map<int, ElementObjectData> data; + map<int, ElementObjectData> data; SerUtil::deserialize(in, edge); deserialize(in, data); edgeInRank[edge] = data; @@ -255,7 +555,7 @@ namespace AMDiS { faceInRank.clear(); for (int i = 0; i < nSize; i++) { DofFace face; - std::map<int, ElementObjectData> data; + map<int, ElementObjectData> data; SerUtil::deserialize(in, face); deserialize(in, data); faceInRank[face] = data; @@ -267,7 +567,7 @@ namespace AMDiS { } - void ElementObjects::serialize(std::ostream &out, std::vector<ElementObjectData>& elVec) + void ElementObjects::serialize(ostream &out, vector<ElementObjectData>& elVec) { int nSize = elVec.size(); SerUtil::serialize(out, nSize); @@ -276,7 +576,7 @@ namespace AMDiS { } - void ElementObjects::deserialize(std::istream &in, std::vector<ElementObjectData>& elVec) + void ElementObjects::deserialize(istream &in, vector<ElementObjectData>& elVec) { int nSize; SerUtil::deserialize(in, nSize); @@ -286,11 +586,11 @@ namespace AMDiS { } - void ElementObjects::serialize(std::ostream &out, std::map<int, ElementObjectData>& data) + void ElementObjects::serialize(ostream &out, map<int, ElementObjectData>& data) { int nSize = data.size(); SerUtil::serialize(out, nSize); - for (std::map<int, ElementObjectData>::iterator it = data.begin(); + for (map<int, ElementObjectData>::iterator it = data.begin(); it != data.end(); ++it) { SerUtil::serialize(out, it->first); it->second.serialize(out); @@ -298,7 +598,7 @@ namespace AMDiS { } - void ElementObjects::deserialize(std::istream &in, std::map<int, ElementObjectData>& data) + void ElementObjects::deserialize(istream &in, map<int, ElementObjectData>& data) { int nSize; SerUtil::deserialize(in, nSize); diff --git a/AMDiS/src/parallel/ElementObjectData.h b/AMDiS/src/parallel/ElementObjectData.h index 6c900bff56210e1c7bced53e91bcbcb9d3e40cce..bbe33bccc09cf95e183cdfd576749dc37e451ed2 100644 --- a/AMDiS/src/parallel/ElementObjectData.h +++ b/AMDiS/src/parallel/ElementObjectData.h @@ -31,138 +31,137 @@ #include "Global.h" #include "Boundary.h" #include "Serializer.h" +#include "FiniteElemSpace.h" namespace AMDiS { using namespace std; + /// Just to templatize the typedef. template<typename T> - struct PerBoundMap - { + struct PerBoundMap { typedef map<pair<T, T>, BoundaryType> type; typedef typename type::iterator iterator; }; + + /// Defines one element object. This may be either a vertex, edge or face. struct ElementObjectData { - ElementObjectData(int a = -1, int b = 0, BoundaryType c = INTERIOR) + ElementObjectData(int a = -1, int b = 0) : elIndex(a), - ithObject(b), - boundaryType(c) + ithObject(b) {} - + + /// Index of the element this object is part of. int elIndex; + /// Index of the object within the element. int ithObject; - BoundaryType boundaryType; - - + /// Write this element object to disk. void serialize(ostream &out) const { SerUtil::serialize(out, elIndex); SerUtil::serialize(out, ithObject); - SerUtil::serialize(out, boundaryType); } - + /// Read this element object from disk. void deserialize(istream &in) { SerUtil::deserialize(in, elIndex); SerUtil::deserialize(in, ithObject); - SerUtil::deserialize(in, boundaryType); } - + /// Compare this element object with another one. bool operator==(ElementObjectData& cmp) const { - return (elIndex == cmp.elIndex && - ithObject == cmp.ithObject && - boundaryType == cmp.boundaryType); + return (elIndex == cmp.elIndex && ithObject == cmp.ithObject); } + /// Define a strict order on element objects. bool operator<(const ElementObjectData& rhs) const { - return (elIndex < rhs.elIndex || - (elIndex == rhs.elIndex && - ithObject < rhs.ithObject)); + return (elIndex < rhs.elIndex || + (elIndex == rhs.elIndex && ithObject < rhs.ithObject)); } }; + /** \brief + * This class is a database of element objects. An element object is either a + * vertex, edge or the face of a specific element. This database is used to store + * all objects of all elements of a mesh. The information is stored in a way that + * makes it possible to identify all elements, which have a given vertex, edge or + * face in common. If is is known which element is owned by which rank in parallel + * computations, it is thus possible to get all interior boundaries on object + * level. This is required, because two elements may share a common vertex without + * beging neighbours in the definition of AMDiS. + */ class ElementObjects { public: ElementObjects() - : iterGeoPos(CENTER) + : feSpace(NULL), + mesh(NULL), + iterGeoPos(CENTER) {} - void addVertex(Element *el, int ith, BoundaryType bound = INTERIOR) - { - DegreeOfFreedom vertex = el->getDof(ith, 0); - int elIndex = el->getIndex(); - ElementObjectData elObj(elIndex, ith, bound); - - vertexElements[vertex].push_back(elObj); - vertexLocalMap[elObj] = vertex; - } - - - void addEdge(Element *el, int ith, BoundaryType bound = INTERIOR) + /// Set the finite element space that should be used for the database (especially + /// the mesh is of interest). + void setFeSpace(FiniteElemSpace *fe) { - DofEdge edge = el->getEdge(ith); - int elIndex = el->getIndex(); - ElementObjectData elObj(elIndex, ith, bound); - - edgeElements[edge].push_back(elObj); - edgeLocalMap[elObj] = edge; + feSpace = fe; + mesh = feSpace->getMesh(); } - void addFace(Element *el, int ith, BoundaryType bound = INTERIOR) - { - DofFace face = el->getFace(ith); - int elIndex = el->getIndex(); - ElementObjectData elObj(elIndex, ith, bound); - - faceElements[face].push_back(elObj); - faceLocalMap[elObj] = face; - } - - - void addElement(Element *el, BoundaryType bound = INTERIOR) - { - for (int i = 0; i < el->getGeo(VERTEX); i++) - addVertex(el, i); - - for (int i = 0; i < el->getGeo(EDGE); i++) - addEdge(el, i); - - for (int i = 0; i < el->getGeo(FACE); i++) - addFace(el, i); - } - - void addPeriodicVertex(pair<DegreeOfFreedom, DegreeOfFreedom> perVertex, - BoundaryType bType) - { - periodicVertices[perVertex] = bType; - } - - void addPeriodicEdge(pair<DofEdge, DofEdge> perEdge, BoundaryType bType) - { - periodicEdges[perEdge] = bType; - } - - void addPeriodicFace(pair<DofFace, DofFace> perFace, BoundaryType bType) - { - periodicFaces[perFace] = bType; - } - + /** \brief + * Adds an element to the object database. If the element is part of a periodic + * boundary, all information about subobjects of the element on this boundary + * are collected. + * + * \param[in] elInfo ElInfo object of the element. + */ + void addElement(ElInfo *elInfo); + + + /** \brief + * Creates final data of the periodic boundaries. Must be called after all + * elements of the mesh are added to the object database. Then this functions + * search for interectly connected vertices in periodic boundaries. This is only + * the case, if there are more than one boundary conditions. Then, e.g., in 2D, + * all edges of a square are iterectly connected. In 3D, if the macro mesh is a + * box, all eight vertex nodes and always four of the 12 edges are iterectly + * connected. + */ + void createPeriodicData(); + + + /** \brief + * Create for a filled object database the membership information for all element + * objects. An object is owned by a rank, if the rank has the heighest rank + * number of all ranks where the object is part of. + * + * \param[in] macroElementRankMap Maps to each macro element of the mesh the + * rank that owns this macro element. + */ void createRankData(map<int, int>& macroElementRankMap); + /** \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 result is valid. + * Otherwise the iterator is at the end position. + * + * \param[in] pos Must be either VERTEX, EDGE or FACE and defines the elements + * that should be traversed. + */ bool iterate(GeoIndex pos) { + // CENTER marks the variable "iterGeoPos" to be in an undefined state. I.e., + // there is no iteration that is actually running. + if (iterGeoPos == CENTER) { iterGeoPos = pos; switch (iterGeoPos) { @@ -221,6 +220,7 @@ namespace AMDiS { } + /// Returns the data of the current iterator position. map<int, ElementObjectData>& getIterateData() { switch (iterGeoPos) { @@ -242,6 +242,7 @@ namespace AMDiS { } + /// Returns the rank owner of the current iterator position. int getIterateOwner() { switch (iterGeoPos) { @@ -263,121 +264,220 @@ namespace AMDiS { } + /// Returns the rank owner of a vertex DOF. int getOwner(DegreeOfFreedom vertex) { return vertexOwner[vertex]; } + /// Returns the rank owner of an edge. int getOwner(DofEdge edge) { return edgeOwner[edge]; } + /// Returns the rank owner of an face. int getOwner(DofFace face) { return faceOwner[face]; } + /// Checks if a given vertex DOF is in a given rank. int isInRank(DegreeOfFreedom vertex, int rank) { return (vertexInRank[vertex].count(rank)); } + /// Checks if a given edge is in a given rank. int isInRank(DofEdge edge, int rank) { return (edgeInRank[edge].count(rank)); } + /// Checks if a given face is in a given rank. int isInRank(DofFace face, int rank) { return (faceInRank[face].count(rank)); } + /// Returns a vector with all macro elements that have a given vertex DOF in common. vector<ElementObjectData>& getElements(DegreeOfFreedom vertex) { return vertexElements[vertex]; } + /// Returns a vector with all macro elements that have a given edge in common. vector<ElementObjectData>& getElements(DofEdge edge) { return edgeElements[edge]; } + /// Returns a vector with all macro elements that have a given face in common. vector<ElementObjectData>& getElements(DofFace face) { return faceElements[face]; } - + + /// Returns a map that maps to each rank all macro elements in this rank that + /// have a given vertex DOF in common. map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex) { return vertexInRank[vertex]; } + /// Returns a map that maps to each rank all macro elements in this rank that + /// have a given edge in common. map<int, ElementObjectData>& getElementsInRank(DofEdge edge) { return edgeInRank[edge]; } + /// Returns a map that maps to each rank all macro elements in this rank that + /// have a given face in common. map<int, ElementObjectData>& getElementsInRank(DofFace face) { return faceInRank[face]; } + /// Returns to an element object data the appropriate vertex DOF. DegreeOfFreedom getVertexLocalMap(ElementObjectData &data) { return vertexLocalMap[data]; } + /// Returns to an element object data the appropriate edge. DofEdge getEdgeLocalMap(ElementObjectData &data) { return edgeLocalMap[data]; } + /// Returns to an element object data the appropriate face. DofFace getFaceLocalMap(ElementObjectData &data) { return faceLocalMap[data]; } + /// Write the element database to disk. void serialize(ostream &out); - + + /// Read the element database from disk. void deserialize(istream &in); - private: + protected: + /// Adds the i-th DOF vertex of an element to the object database. + void addVertex(Element *el, int ith) + { + DegreeOfFreedom vertex = el->getDof(ith, 0); + int elIndex = el->getIndex(); + ElementObjectData elObj(elIndex, ith); + + vertexElements[vertex].push_back(elObj); + vertexLocalMap[elObj] = vertex; + } + + /// Adds the i-th edge of an element to the object database. + void addEdge(Element *el, int ith) + { + DofEdge edge = el->getEdge(ith); + int elIndex = el->getIndex(); + ElementObjectData elObj(elIndex, ith); + + edgeElements[edge].push_back(elObj); + edgeLocalMap[elObj] = edge; + } + + /// Adds the i-th face of an element to the object database. + void addFace(Element *el, int ith) + { + DofFace face = el->getFace(ith); + int elIndex = el->getIndex(); + ElementObjectData elObj(elIndex, ith); + + faceElements[face].push_back(elObj); + faceLocalMap[elObj] = face; + } + + + /// Some auxiliary function to write the element object database to disk. void serialize(ostream &out, vector<ElementObjectData>& elVec); + /// Some auxiliary function to read the element object database from disk. void deserialize(istream &in, vector<ElementObjectData>& elVec); + /// Some auxiliary function to write the element object database to disk. void serialize(ostream &out, map<int, ElementObjectData>& data); + /// Some auxiliary function to read the element object database from disk. void deserialize(istream &in, map<int, ElementObjectData>& data); private: + /// The used FE space. + FiniteElemSpace *feSpace; + + /// The mesh that is used to store all its element information in the database. + Mesh *mesh; + + + /// Maps to each vertex DOF all element objects that represent this vertex. map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements; + + /// Maps to each edge all element objects that represent this edge. map<DofEdge, vector<ElementObjectData> > edgeElements; - map<DofFace, vector<ElementObjectData> > faceElements; + /// Maps to each face all element objects that represent this edge. + map<DofFace, vector<ElementObjectData> > faceElements; + + /// Maps to an element object the corresponding vertex DOF. map<ElementObjectData, DegreeOfFreedom> vertexLocalMap; + + /// Maps to an element object the corresponding edge. map<ElementObjectData, DofEdge> edgeLocalMap; + + /// Maps to an element object the corresponding face. map<ElementObjectData, DofFace> faceLocalMap; + /// Defines for all vertex DOFs the rank that ownes this vertex DOF. map<DegreeOfFreedom, int> vertexOwner; + + /// Defines for all edges the rank that ownes this edge. map<DofEdge, int> edgeOwner; + + /// Defines for all faces the rank that ownes this face. map<DofFace, int> faceOwner; + /// Defines to each vertex DOF a map that maps to each rank number the element + /// objects that have this vertex DOF in common. map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank; + + /// Defines to each edge a map that maps to each rank number the element objects + /// that have this edge in common. map<DofEdge, map<int, ElementObjectData> > edgeInRank; + + /// Defines to each face a map that maps to each rank number the element objects + /// that have this face in common. map<DofFace, map<int, ElementObjectData> > faceInRank; + + /// Vertex iterator to iterate over \ref vertexInRank map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter; + + /// Edge iterator to iterate over \ref edgeInRank map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter; + + /// Face iterator to iterate over \ref faceInRank map<DofFace, map<int, ElementObjectData> >::iterator faceIter; + + /// Defines the geometrical iteration index of the iterators. I.e., the value + /// is either VERTEX, EDGE or FACE and the corresponding element objects are + /// traversed. The value CENTER is used to define a not defined states of the + /// iterators, i.e., if no iteration is running. GeoIndex iterGeoPos; public: @@ -385,6 +485,12 @@ namespace AMDiS { PerBoundMap<DegreeOfFreedom>::type periodicVertices; PerBoundMap<DofEdge>::type periodicEdges; PerBoundMap<DofFace>::type periodicFaces; + + // Stores to each vertex all its periodic associations. + std::map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc; + + // Stores to each edge all its periodic associations. + std::map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc; }; } diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index 4e234d5a415b3f7caaececf3f5c586bbb02d080b..f3490093ee59a52c675f73183e182a09cf70a4dc 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -103,6 +103,8 @@ namespace AMDiS { TEST_EXIT(feSpace)("No FE space has been defined for the mesh distributor!\n"); TEST_EXIT(mesh)("No mesh has been defined for the mesh distributor!\n"); + elObjects.setFeSpace(feSpace); + // If the problem has been already read from a file, we need only to set // isRankDofs to all matrices and rhs vector and to remove periodic // boundary conditions (if there are some). @@ -1265,9 +1267,7 @@ namespace AMDiS { FUNCNAME("MeshDistributor::createInteriorBoundaryInfo()"); createMeshElementData(); - createBoundaryData(); - } @@ -1276,7 +1276,6 @@ namespace AMDiS { FUNCNAME("MeshDistributor::updateInteriorBoundaryInfo()"); elObjects.createRankData(partitionVec); - createBoundaryData(); } @@ -1285,12 +1284,6 @@ namespace AMDiS { { FUNCNAME("MeshDistributor::createMeshElementData()"); - // Stores to each vertex all its periodic associations. - std::map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc; - - // Stores to each edge all its periodic associations. - std::map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc; - // === Fills macro element data structures. === @@ -1304,274 +1297,19 @@ namespace AMDiS { Element *el = elInfo->getElement(); macroElIndexMap[el->getIndex()] = el; macroElIndexTypeMap[el->getIndex()] = elInfo->getType(); - - + // === Add all sub object of the element to the variable elObjects. === + elObjects.addElement(elInfo); - elObjects.addElement(el); - - - // === Get periodic boundary information. === - - switch (mesh->getDim()) { - case 2: - for (int i = 0; i < el->getGeo(EDGE); i++) { - if (mesh->isPeriodicAssociation(elInfo->getBoundary(EDGE, i))) { - Element *neigh = elInfo->getNeighbour(i); - - DofEdge edge1 = el->getEdge(i); - DofEdge edge2 = neigh->getEdge(elInfo->getOppVertex(i)); - BoundaryType boundaryType = elInfo->getBoundary(EDGE, i); - - elObjects.addPeriodicEdge(std::make_pair(edge1, edge2), boundaryType); - periodicEdgeAssoc[edge1].insert(edge2); - - elObjects.addPeriodicVertex(std::make_pair(edge1.first, edge2.first), boundaryType); - elObjects.addPeriodicVertex(std::make_pair(edge1.second, edge2.second), boundaryType); - periodicDofAssoc[edge1.first].insert(boundaryType); - periodicDofAssoc[edge1.second].insert(boundaryType); - - TEST_EXIT_DBG(edge1.first == mesh->getPeriodicAssociations(boundaryType)[edge2.first] && - edge1.second == mesh->getPeriodicAssociations(boundaryType)[edge2.second]) - ("Should not happen!\n"); - } - } - break; - case 3: - for (int i = 0; i < el->getGeo(FACE); i++) { - if (mesh->isPeriodicAssociation(elInfo->getBoundary(FACE, i))) { - Element *neigh = elInfo->getNeighbour(i); - - DofFace face1 = el->getFace(i); - DofFace face2 = neigh->getFace(elInfo->getOppVertex(i)); - BoundaryType boundaryType = elInfo->getBoundary(FACE, i); - - elObjects.addPeriodicFace(std::make_pair(face1, face2), elInfo->getBoundary(i)); - - elObjects.addPeriodicVertex(std::make_pair(face1.get<0>(), face2.get<0>()), boundaryType); - elObjects.addPeriodicVertex(std::make_pair(face1.get<1>(), face2.get<1>()), boundaryType); - elObjects.addPeriodicVertex(std::make_pair(face1.get<2>(), face2.get<2>()), boundaryType); - - periodicDofAssoc[face1.get<0>()].insert(boundaryType); - periodicDofAssoc[face1.get<1>()].insert(boundaryType); - periodicDofAssoc[face1.get<2>()].insert(boundaryType); - - TEST_EXIT_DBG(face1.get<0>() == mesh->getPeriodicAssociations(boundaryType)[face2.get<0>()] && - face1.get<1>() == mesh->getPeriodicAssociations(boundaryType)[face2.get<1>()] && - face1.get<2>() == mesh->getPeriodicAssociations(boundaryType)[face2.get<2>()]) - ("Should not happen!\n"); - - - DofEdge elEdge1 = std::make_pair(face1.get<0>(), face1.get<1>()); - DofEdge elEdge2 = std::make_pair(face1.get<0>(), face1.get<2>()); - DofEdge elEdge3 = std::make_pair(face1.get<1>(), face1.get<2>()); - DofEdge neighEdge1 = std::make_pair(face2.get<0>(), face2.get<1>()); - DofEdge neighEdge2 = std::make_pair(face2.get<0>(), face2.get<2>()); - DofEdge neighEdge3 = std::make_pair(face2.get<1>(), face2.get<2>()); - - - elObjects.addPeriodicEdge(std::make_pair(elEdge1, neighEdge1), boundaryType); - elObjects.addPeriodicEdge(std::make_pair(elEdge2, neighEdge2), boundaryType); - elObjects.addPeriodicEdge(std::make_pair(elEdge3, neighEdge3), boundaryType); - - periodicEdgeAssoc[elEdge1].insert(neighEdge1); - periodicEdgeAssoc[elEdge2].insert(neighEdge2); - periodicEdgeAssoc[elEdge3].insert(neighEdge3); - } - } - break; - } - elInfo = stack.traverseNext(elInfo); } + // === Create periodic data, if there are periodic boundary conditions. === + elObjects.createPeriodicData(); - // === Create mesh element data for this rank. === + // === Create mesh element data for this rank. === elObjects.createRankData(partitionVec); - - - // === Search for interectly connected vertices in periodic boundaries. === - - if (elObjects.periodicVertices.size() > 0) { - - - // === Search for an unsed boundary index. === - - BoundaryType newPeriodicBoundaryType = 0; - for (std::map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin(); - it != mesh->getPeriodicAssociations().end(); ++it) - newPeriodicBoundaryType = min(newPeriodicBoundaryType, it->first); - - TEST_EXIT_DBG(newPeriodicBoundaryType < 0)("Should not happen!\n"); - newPeriodicBoundaryType--; - mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = - new VertexVector(feSpace->getAdmin(), ""); - - - // === Get all vertex DOFs that have multiple periodic associations. === - - std::vector<DegreeOfFreedom> multPeriodicDof2, multPeriodicDof3; - for (std::map<DegreeOfFreedom, std::set<BoundaryType> >::iterator it = periodicDofAssoc.begin(); - it != periodicDofAssoc.end(); ++it) { - TEST_EXIT_DBG((mesh->getDim() == 2 && it->second.size() <= 2) || - (mesh->getDim() == 3 && it->second.size() <= 3)) - ("Should not happen!\n"); - - if (it->second.size() == 2) - multPeriodicDof2.push_back(it->first); - if (it->second.size() == 3) - multPeriodicDof3.push_back(it->first); - } - - - if (mesh->getDim() == 2) { - TEST_EXIT_DBG(multPeriodicDof2.size() == 0 || - multPeriodicDof2.size() == 4) - ("Should not happen (%d)!\n", multPeriodicDof2.size()); - TEST_EXIT_DBG(multPeriodicDof3.size() == 0)("Should not happen!\n"); - } - if (mesh->getDim() == 3) { - TEST_EXIT_DBG(multPeriodicDof3.size() == 0 || - multPeriodicDof3.size() == 8) - ("Should not happen (%d)!\n", multPeriodicDof3.size()); - } - - - if (multPeriodicDof2.size() > 0) { - for (unsigned int i = 0; i < multPeriodicDof2.size(); i++) { - DegreeOfFreedom dof0 = multPeriodicDof2[i]; - if (dof0 == -1) - continue; - - DegreeOfFreedom dof1 = -1; - DegreeOfFreedom dof2 = -1; - BoundaryType type0 = *(periodicDofAssoc[dof0].begin()); - BoundaryType type1 = *(++(periodicDofAssoc[dof0].begin())); - - for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.periodicVertices.begin(); - it != elObjects.periodicVertices.end(); ++it) { - if (it->first.first == dof0 && it->second == type0) - dof1 = it->first.second; - if (it->first.first == dof0 && it->second == type1) - dof2 = it->first.second; - - if (dof1 != -1 && dof2 != -1) - break; - } - - TEST_EXIT_DBG(dof1 != -1 && dof2 != -1)("Should not happen!\n"); - - DegreeOfFreedom dof3 = -1; - for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.periodicVertices.begin(); - it != elObjects.periodicVertices.end(); ++it) { - if (it->first.first == dof1 && it->second == type1) { - dof3 = it->first.second; - - TEST_EXIT_DBG(elObjects.periodicVertices[std::make_pair(dof2, dof3)] == type0) - ("Should not happen!\n"); - - break; - } - } - - TEST_EXIT_DBG(dof3 != -1)("Should not happen!\n"); - TEST_EXIT_DBG(elObjects.periodicVertices.count(std::make_pair(dof0, dof3)) == 0) - ("Should not happen!\n"); - TEST_EXIT_DBG(elObjects.periodicVertices.count(std::make_pair(dof3, dof0)) == 0) - ("Should not happen!\n"); - - elObjects.periodicVertices[std::make_pair(dof0, dof3)] = newPeriodicBoundaryType; - elObjects.periodicVertices[std::make_pair(dof3, dof0)] = newPeriodicBoundaryType; - - for (unsigned int j = i + 1; j < multPeriodicDof2.size(); j++) - if (multPeriodicDof2[j] == dof3) - multPeriodicDof2[j] = -1; - } - } - - if (multPeriodicDof3.size() > 0) { - int nMultPeriodicDofs = multPeriodicDof3.size(); - for (int i = 0; i < nMultPeriodicDofs; i++) { - for (int j = i + 1; j < nMultPeriodicDofs; j++) { - std::pair<DegreeOfFreedom, DegreeOfFreedom> perDofs0 = - std::make_pair(multPeriodicDof3[i], multPeriodicDof3[j]); - std::pair<DegreeOfFreedom, DegreeOfFreedom> perDofs1 = - std::make_pair(multPeriodicDof3[j], multPeriodicDof3[i]); - - if (elObjects.periodicVertices.count(perDofs0) == 0) { - TEST_EXIT_DBG(elObjects.periodicVertices.count(perDofs1) == 0) - ("Should not happen!\n"); - - elObjects.periodicVertices[perDofs0] = newPeriodicBoundaryType; - elObjects.periodicVertices[perDofs1] = newPeriodicBoundaryType; - newPeriodicBoundaryType--; - mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = - new VertexVector(feSpace->getAdmin(), ""); - } - } - } - } - - - // === Get all edges that have multiple periodic associations (3D only!). === - - for (std::map<DofEdge, std::set<DofEdge> >::iterator it = periodicEdgeAssoc.begin(); - it != periodicEdgeAssoc.end(); ++it) { - if (it->second.size() > 1) { - TEST_EXIT_DBG(mesh->getDim() == 3)("Should not happen!\n"); - TEST_EXIT_DBG(it->second.size() == 2)("Should not happen!\n"); - - std::pair<DofEdge, DofEdge> perEdge0 = - std::make_pair(*(it->second.begin()), *(++(it->second.begin()))); - std::pair<DofEdge, DofEdge> perEdge1 = - std::make_pair(perEdge0.second, perEdge0.first); - - elObjects.periodicEdges[perEdge0] = newPeriodicBoundaryType; - elObjects.periodicEdges[perEdge1] = newPeriodicBoundaryType; - newPeriodicBoundaryType--; - mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = - new VertexVector(feSpace->getAdmin(), ""); - } - } - - - // === In debug mode we make some tests, if the periodic structures are set === - // === in a symmetric way, i.e., if A -> B for a specific boundary type, === - // === there must be a mapping B -> A with the same boundary type. === - -#if (DEBUG != 0) - for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.periodicVertices.begin(); - it != elObjects.periodicVertices.end(); ++it) { - std::pair<DegreeOfFreedom, DegreeOfFreedom> testVertex = - std::make_pair(it->first.second, it->first.first); - - TEST_EXIT_DBG(elObjects.periodicVertices.count(testVertex) == 1)("Should not happen!\n"); - TEST_EXIT_DBG(elObjects.periodicVertices[testVertex] == it->second)("Should not happen!\n"); - } - - for (PerBoundMap<DofEdge>::iterator it = elObjects.periodicEdges.begin(); - it != elObjects.periodicEdges.end(); ++it) { - std::pair<DofEdge, DofEdge> testEdge = - std::make_pair(it->first.second, it->first.first); - - TEST_EXIT_DBG(elObjects.periodicEdges.count(testEdge) == 1)("Should not happen!\n"); - TEST_EXIT_DBG(elObjects.periodicEdges[testEdge] == it->second)("Should not happen!\n"); - } - - for (PerBoundMap<DofFace>::iterator it = elObjects.periodicFaces.begin(); - it != elObjects.periodicFaces.end(); ++it) { - std::pair<DofFace, DofFace> testFace = - std::make_pair(it->first.second, it->first.first); - - TEST_EXIT_DBG(elObjects.periodicFaces.count(testFace) == 1)("Should not happen!\n"); - TEST_EXIT_DBG(elObjects.periodicFaces[testFace] == it->second)("Should not happen!\n"); - } -#endif - - - } - } @@ -1628,13 +1366,8 @@ namespace AMDiS { bound.neighObj.elType = macroElIndexTypeMap[it2->second.elIndex]; bound.neighObj.subObj = geoIndex; bound.neighObj.ithObj = it2->second.ithObject; - - TEST_EXIT_DBG(rankBoundEl.boundaryType == it2->second.boundaryType) - ("Wrong boundary types: %d %d\n", - rankBoundEl.boundaryType, - it2->second.boundaryType); - - bound.type = rankBoundEl.boundaryType; + + bound.type = INTERIOR; AtomicBoundary& b = myIntBoundary.getNewAtomic(it2->first); b = bound; @@ -1652,12 +1385,8 @@ namespace AMDiS { bound.neighObj.elType = -1; bound.neighObj.subObj = geoIndex; bound.neighObj.ithObj = ownerBoundEl.ithObject; - - TEST_EXIT_DBG(rankBoundEl.boundaryType == ownerBoundEl.boundaryType) - ("Should not happen: %d %d\n", - rankBoundEl.boundaryType, ownerBoundEl.boundaryType); - - bound.type = rankBoundEl.boundaryType; + + bound.type = INTERIOR; AtomicBoundary& b = otherIntBoundary.getNewAtomic(owner); b = bound;