From dfeb9e9ebf98db2406bf288ff986f509bbfbd159 Mon Sep 17 00:00:00 2001 From: Thomas Witkowski <thomas.witkowski@gmx.de> Date: Thu, 6 Jan 2011 13:35:23 +0000 Subject: [PATCH] Work on parallel periodic boundary condition in 3D. --- AMDiS/src/parallel/MeshDistributor.cc | 198 +++++++++++++++++--------- AMDiS/src/parallel/MeshDistributor.h | 2 +- AMDiS/src/parallel/ParallelDebug.cc | 86 ++++++++++- AMDiS/src/parallel/ParallelDebug.h | 7 + AMDiS/src/parallel/StdMpi.cc | 58 ++++++++ AMDiS/src/parallel/StdMpi.h | 5 + 6 files changed, 289 insertions(+), 67 deletions(-) diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index a1762416..e21545ae 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -221,6 +221,9 @@ namespace AMDiS { createPeriodicMap(); +#if (DEBUG != 0) + ParallelDebug::testPeriodicBoundary(*this); +#endif // === Global refinements. === @@ -547,7 +550,7 @@ namespace AMDiS { for (InteriorBoundary::iterator it(periodicBoundary); !it.end(); ++it) { if (it.getRank() == mpiRank) { - // ERROR_EXIT("Na, du weisst schon!\n"); + WARNING("Na, du weisst schon!\n"); } else { if ((mesh->getDim() == 2 && it->rankObj.subObj == EDGE) || (mesh->getDim() == 3 && it->rankObj.subObj == FACE)) @@ -1261,8 +1264,6 @@ namespace AMDiS { { FUNCNAME("MeshDistributor::createInteriorBoundaryInfo()"); - MSG("CREATE BOUNDARY INFO!\n"); - createMeshElementData(); createBoundaryData(); @@ -1274,8 +1275,6 @@ namespace AMDiS { { FUNCNAME("MeshDistributor::updateInteriorBoundaryInfo()"); - MSG("UPDATE BOUNDARY INFO!\n"); - elObjects.createRankData(partitionVec); createBoundaryData(); @@ -1328,8 +1327,8 @@ namespace AMDiS { periodicEdgeAssoc[edge1].insert(edge2); - periodicDofs[std::make_pair(edge1.first, edge2.first)] = boundaryType; - periodicDofs[std::make_pair(edge1.second, edge2.second)] = boundaryType; + periodicVertices[std::make_pair(edge1.first, edge2.first)] = boundaryType; + periodicVertices[std::make_pair(edge1.second, edge2.second)] = boundaryType; periodicDofAssoc[edge1.first].insert(boundaryType); periodicDofAssoc[edge1.second].insert(boundaryType); @@ -1351,9 +1350,9 @@ namespace AMDiS { periodicFaces[std::make_pair(face1, face2)] = elInfo->getBoundary(i); - periodicDofs[std::make_pair(face1.get<0>(), face2.get<0>())] = boundaryType; - periodicDofs[std::make_pair(face1.get<1>(), face2.get<1>())] = boundaryType; - periodicDofs[std::make_pair(face1.get<2>(), face2.get<2>())] = boundaryType; + periodicVertices[std::make_pair(face1.get<0>(), face2.get<0>())] = boundaryType; + periodicVertices[std::make_pair(face1.get<1>(), face2.get<1>())] = boundaryType; + periodicVertices[std::make_pair(face1.get<2>(), face2.get<2>())] = boundaryType; periodicDofAssoc[face1.get<0>()].insert(boundaryType); periodicDofAssoc[face1.get<1>()].insert(boundaryType); @@ -1395,7 +1394,7 @@ namespace AMDiS { // === Search for interectly connected vertices in periodic boundaries. === - if (periodicDofs.size() > 0) { + if (periodicVertices.size() > 0) { // === Search for an unsed boundary index. === @@ -1413,52 +1412,51 @@ namespace AMDiS { // === Get all vertex DOFs that have multiple periodic associations. === - std::vector<DegreeOfFreedom> multiplePeriodicDof; + std::map<int, std::vector<DegreeOfFreedom> > multiplePeriodicDof; for (std::map<DegreeOfFreedom, std::set<BoundaryType> >::iterator it = periodicDofAssoc.begin(); it != periodicDofAssoc.end(); ++it) { - if (mesh->getDim() == 2) { - TEST_EXIT_DBG(it->second.size() <= 2)("Should not happen!\n"); - } - if (mesh->getDim() == 3) { - TEST_EXIT_DBG(it->second.size() <= 3)("Should not happen!\n"); - } - - - if ((mesh->getDim() == 2 && it->second.size() == 2) || - (mesh->getDim() == 3 && it->second.size() == 3)) - multiplePeriodicDof.push_back(it->first); - } - - - if (mesh->getDim() == 2) { - TEST_EXIT_DBG(multiplePeriodicDof.size() == 0 || - multiplePeriodicDof.size() == 4) - ("Should not happen (%d)!\n", multiplePeriodicDof.size()); - } - - if (mesh->getDim() == 3) { - TEST_EXIT_DBG(multiplePeriodicDof.size() == 0 || - multiplePeriodicDof.size() == 8) - ("Should not happen (%d)!\n", multiplePeriodicDof.size()); + TEST_EXIT_DBG((mesh->getDim() == 2 && it->second.size() <= 2) || + (mesh->getDim() == 3 && it->second.size() <= 3)) + ("Should not happen!\n"); + + multiplePeriodicDof[it->second.size()].push_back(it->first); } - int nMultiplePeriodicDofs = multiplePeriodicDof.size(); - for (int i = 0; i < nMultiplePeriodicDofs; i++) { - for (int j = 0; j < nMultiplePeriodicDofs; j++) { - if (i == j) - continue; - - std::pair<DegreeOfFreedom, DegreeOfFreedom> perDofs = - std::make_pair(multiplePeriodicDof[i], multiplePeriodicDof[j]); - - if (periodicDofs.count(perDofs) == 0) - periodicDofs[perDofs] = newPeriodicBoundaryType; + if (mesh->getDim() == 2) + TEST_EXIT_DBG(multiplePeriodicDof[2].size() == 0 || + multiplePeriodicDof[2].size() == 4) + ("Should not happen (%d)!\n", multiplePeriodicDof[2].size()); + if (mesh->getDim() == 3) + TEST_EXIT_DBG(multiplePeriodicDof[3].size() == 0 || + multiplePeriodicDof[3].size() == 8) + ("Should not happen (%d)!\n", multiplePeriodicDof[3].size()); + + + for (int k = 2; k <= 3; k++) { + int nMultiplePeriodicDofs = multiplePeriodicDof[k].size(); + for (int i = 0; i < nMultiplePeriodicDofs; i++) { + for (int j = i + 1; j < nMultiplePeriodicDofs; j++) { + std::pair<DegreeOfFreedom, DegreeOfFreedom> perDofs0 = + std::make_pair(multiplePeriodicDof[k][i], multiplePeriodicDof[k][j]); + std::pair<DegreeOfFreedom, DegreeOfFreedom> perDofs1 = + std::make_pair(multiplePeriodicDof[k][j], multiplePeriodicDof[k][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 (std::map<DofEdge, std::set<DofEdge> >::iterator it = periodicEdgeAssoc.begin(); @@ -1474,10 +1472,47 @@ namespace AMDiS { 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 (std::map<std::pair<DegreeOfFreedom, DegreeOfFreedom>, BoundaryType>::iterator it = periodicVertices.begin(); + it != periodicVertices.end(); ++it) { + std::pair<DegreeOfFreedom, DegreeOfFreedom> testVertex = + std::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 (std::map<std::pair<DofEdge, DofEdge>, BoundaryType>::iterator it = periodicEdges.begin(); + it != periodicEdges.end(); ++it) { + std::pair<DofEdge, DofEdge> testEdge = + std::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 (std::map<std::pair<DofFace, DofFace>, BoundaryType>::iterator it = periodicFaces.begin(); + it != periodicFaces.end(); ++it) { + std::pair<DofFace, DofFace> testFace = + std::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 + + } } @@ -1488,7 +1523,7 @@ namespace AMDiS { FUNCNAME("MeshDistributor::createBoundaryData()"); - // === Clear all relevant data structures, === + // === Clear all relevant data structures. === myIntBoundary.clear(); otherIntBoundary.clear(); @@ -1578,12 +1613,19 @@ namespace AMDiS { // === Create periodic boundary data structure. === - for (std::map<std::pair<DegreeOfFreedom, DegreeOfFreedom>, BoundaryType>::iterator it = periodicDofs.begin(); - it != periodicDofs.end(); ++it) { + for (std::map<std::pair<DegreeOfFreedom, DegreeOfFreedom>, BoundaryType>::iterator it = periodicVertices.begin(); + it != periodicVertices.end(); ++it) { if (elObjects.isInRank(it->first.first, mpiRank) == false) continue; + WorldVector<double> c0, c1; + mesh->getDofIndexCoords(it->first.first, feSpace, c0); + mesh->getDofIndexCoords(it->first.second, feSpace, c1); + + MSG("CREATE BOUNDARY FOR DOF MAP: %d (%.3f %.3f %.3f)<-> %d (%.3f %.3f %.3f)\n", it->first.first, + c0[0], c0[1], c0[2], it->first.second, c1[0], c1[1], c1[2]); ElementObjectData& perDofEl0 = elObjects.getElementsInRank(it->first.first)[mpiRank]; + MSG("DATA: %d %d %d\n", perDofEl0.elIndex, VERTEX, perDofEl0.ithObject); for (std::map<int, ElementObjectData>::iterator elIt = elObjects.getElementsInRank(it->first.second).begin(); elIt != elObjects.getElementsInRank(it->first.second).end(); ++elIt) { @@ -2033,6 +2075,8 @@ namespace AMDiS { for (RankToBoundMap::iterator it = periodicBoundary.boundary.begin(); it != periodicBoundary.boundary.end(); ++it) { + MSG("------------- WITH RANK %d ------------------\n", it->first); + if (it->first == mpiRank) { TEST_EXIT_DBG(it->second.size() % 2 == 0)("Should not happen!\n"); @@ -2044,6 +2088,10 @@ namespace AMDiS { bound.neighObj.el->getVertexDofs(feSpace, bound.neighObj, dofs1); bound.neighObj.el->getNonVertexDofs(feSpace, bound.neighObj, dofs1); + MSG("BOUND-I %d-%d-%d WITH %d-%d-%d\n", + bound.rankObj.elIndex, bound.rankObj.subObj, bound.rankObj.ithObj, + bound.neighObj.elIndex, bound.neighObj.subObj, bound.neighObj.ithObj); + TEST_EXIT_DBG(dofs0.size() == dofs1.size())("Should not happen!\n"); BoundaryType type = bound.type; @@ -2055,6 +2103,8 @@ namespace AMDiS { if (periodicDofAssociations[globalDof0].count(type) == 0) { periodicDof[type][globalDof0] = globalDof1; periodicDofAssociations[globalDof0].insert(type); + + MSG("SET(A TYPE %d) DOF %d -> %d\n", type, globalDof0, globalDof1); } } } @@ -2066,12 +2116,20 @@ namespace AMDiS { boundIt != it->second.end(); ++boundIt) { int nDofs = dofs.size(); + + MSG("BOUND-R (T = %d) %d-%d-%d WITH %d-%d-%d\n", + boundIt->type, + boundIt->rankObj.elIndex, boundIt->rankObj.subObj, boundIt->rankObj.ithObj, + boundIt->neighObj.elIndex, boundIt->neighObj.subObj, boundIt->neighObj.ithObj); + boundIt->rankObj.el->getVertexDofs(feSpace, boundIt->rankObj, dofs); boundIt->rankObj.el->getNonVertexDofs(feSpace, boundIt->rankObj, dofs); - for (unsigned int i = 0; i < (dofs.size() - nDofs); i++) + for (unsigned int i = 0; i < (dofs.size() - nDofs); i++) { + MSG(" i = %d DOF = %d\n", nDofs + i, mapLocalGlobalDofs[*(dofs[nDofs + i])]); rankToDofType[it->first].push_back(boundIt->type); + } } // Send the global indices to the rank on the other side. @@ -2088,6 +2146,8 @@ namespace AMDiS { stdMpi.startCommunication<int>(MPI_INT); + MSG("===============================\n"); + // === The rank has received the dofs from the rank on the other side of === // === the boundary. Now it can use them to create the mapping between === // === the periodic dofs in this rank and the corresponding periodic === @@ -2096,6 +2156,9 @@ namespace AMDiS { for (RankToBoundMap::iterator it = periodicBoundary.boundary.begin(); it != periodicBoundary.boundary.end(); ++it) { + + MSG("------------- WITH RANK %d ------------------\n", it->first); + DofContainer& dofs = rankPeriodicDofs[it->first]; std::vector<int>& types = rankToDofType[it->first]; @@ -2110,24 +2173,29 @@ namespace AMDiS { // Check if this global dof with the corresponding boundary type was // not added before by another periodic boundary from other rank. if (periodicDofAssociations[globalDofIndex].count(type) == 0) { + + MSG("SET(B-%d TYPE %d) DOF %d -> %d\n", i, type, globalDofIndex, mapGlobalDofIndex); + + periodicDof[type][globalDofIndex] = mapGlobalDofIndex; periodicDofAssociations[globalDofIndex].insert(type); + } else { + MSG("ASSOC ALREADY SET FOR %d TYPE %d\n", i, type); } } } - #if (DEBUG != 0) - // In 2D, a periodic DOF can have either 1 or 3 associations. Check this! - if (mesh->getDim() == 2) { - for (std::map<int, std::set<BoundaryType> >::iterator it = periodicDofAssociations.begin(); - it != periodicDofAssociations.end(); ++it) { - int nAssoc = it->second.size(); - TEST_EXIT_DBG(nAssoc == 1 || nAssoc == 3) - ("Should not happen! DOF %d has %d periodic associations!\n", - it->first, nAssoc); - } - } + for (std::map<int, std::set<BoundaryType> >::iterator it = periodicDofAssociations.begin(); + it != periodicDofAssociations.end(); ++it) { + WorldVector<double> c; + mesh->getDofIndexCoords(it->first, feSpace, c); + int nAssoc = it->second.size(); + TEST_EXIT_DBG(nAssoc == 1 || nAssoc == 3 || + (mesh->getDim() == 3 && (nAssoc == 7 || nAssoc == 11))) + ("Should not happen! DOF %d (%e %e %e) has %d periodic associations!\n", + it->first, c[0], c[1], (mesh->getDim() == 2 ? 0.0 : c[2]), nAssoc); + } #endif } @@ -2179,7 +2247,7 @@ namespace AMDiS { elObjects.serialize(out); - SerUtil::serialize(out, periodicDofs); + SerUtil::serialize(out, periodicVertices); SerUtil::serialize(out, periodicEdges); SerUtil::serialize(out, periodicFaces); @@ -2243,7 +2311,7 @@ namespace AMDiS { elObjects.deserialize(in); - SerUtil::deserialize(in, periodicDofs); + SerUtil::deserialize(in, periodicVertices); SerUtil::deserialize(in, periodicEdges); SerUtil::deserialize(in, periodicFaces); diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h index 7ad15f37..7a05fd16 100644 --- a/AMDiS/src/parallel/MeshDistributor.h +++ b/AMDiS/src/parallel/MeshDistributor.h @@ -479,7 +479,7 @@ namespace AMDiS { std::map<int, int> macroElIndexTypeMap; // The following three data structures store periodic DOFs, edges and faces. - std::map<std::pair<DegreeOfFreedom, DegreeOfFreedom>, BoundaryType> periodicDofs; + std::map<std::pair<DegreeOfFreedom, DegreeOfFreedom>, BoundaryType> periodicVertices; std::map<std::pair<DofEdge, DofEdge>, BoundaryType> periodicEdges; std::map<std::pair<DofFace, DofFace>, BoundaryType> periodicFaces; diff --git a/AMDiS/src/parallel/ParallelDebug.cc b/AMDiS/src/parallel/ParallelDebug.cc index 8fbf82ab..f8cf20b6 100644 --- a/AMDiS/src/parallel/ParallelDebug.cc +++ b/AMDiS/src/parallel/ParallelDebug.cc @@ -139,6 +139,89 @@ namespace AMDiS { } + void ParallelDebug::testPeriodicBoundary(MeshDistributor &pdb) + { + FUNCNAME("ParallelDebug::testPeriodicBoundary()"); + + typedef MeshDistributor::PeriodicDofMap PeriodicDofMap; + + StdMpi<PeriodicDofMap> stdMpi(pdb.mpiComm, true); + + if (pdb.mpiRank == 0) { + for (int i = 1; i < pdb.mpiSize; i++) + stdMpi.recv(i); + } else { + stdMpi.send(0, pdb.periodicDof); + } + + stdMpi.startCommunication<int>(MPI_INT); + + int foundError = 0; + + // === The boundary DOFs are checked only on the zero rank. === + + if (pdb.mpiRank == 0) { + std::map<int, PeriodicDofMap> rankToMaps; + PeriodicDofMap dofMap = pdb.periodicDof; + rankToMaps[0] = dofMap; + + for (int i = 1; i < pdb.mpiSize; i++) { + PeriodicDofMap &otherMap = stdMpi.getRecvData(i); + rankToMaps[i] = otherMap; + + for (PeriodicDofMap::iterator it = otherMap.begin(); + it != otherMap.end(); ++it) { + for (MeshDistributor::DofMapping::iterator dofIt = it->second.begin(); + dofIt != it->second.end(); ++dofIt) { + if (dofMap.count(it->first) == 1 && + dofMap[it->first].count(dofIt->first) == 1) { + TEST_EXIT_DBG(dofMap[it->first][dofIt->first] == dofIt->second) + ("Should not happen!\n"); + } else { + dofMap[it->first][dofIt->first] = dofIt->second; + } + } + } + } + + + // === Now we test if global DOF A is mapped to B, then B must be mapped === + // === to A for the same boundary type. === + + for (PeriodicDofMap::iterator it = dofMap.begin(); + it != dofMap.end(); ++it) { + for (MeshDistributor::DofMapping::iterator dofIt = it->second.begin(); + dofIt != it->second.end(); ++dofIt) { + if (it->second[dofIt->second] != dofIt->first) { + MSG("[DBG] For boundary type %d: DOF %d -> %d, but %d -> %d!\n", + it ->first, + dofIt->first, dofIt->second, + dofIt->second, it->second[dofIt->second]); + + for (int i = 0; i < pdb.mpiSize; i++) { + if (rankToMaps[i][it->first].count(dofIt->first) == 1) { + MSG("[DBG] %d -> %d in rank %d\n", + dofIt->first, rankToMaps[i][it->first][dofIt->first], i); + } + + if (rankToMaps[i][it->first].count(dofIt->second) == 1) { + MSG("[DBG] %d -> %d in rank %d\n", + dofIt->second, rankToMaps[i][it->first][dofIt->second], i); + } + } + + ERROR("Wrong periodic DOFs!\n"); + foundError = 1; + } + } + } + } + + mpi::globalAdd(foundError); + TEST_EXIT(foundError == 0)("Error found on at least on rank!\n"); + } + + void ParallelDebug::testCommonDofs(MeshDistributor &pdb, bool printCoords) { FUNCNAME("ParallelDebug::testCommonDofs()"); @@ -573,7 +656,8 @@ namespace AMDiS { } for (InteriorBoundary::iterator it(pdb.periodicBoundary); !it.end(); ++it) { - MSG("Periodic boundary with rank %d: \n", it.getRank()); + MSG("Periodic boundary (ID %d) with rank %d: \n", + it->type, it.getRank()); MSG(" ranks obj-ind: %d sub-obj: %d ith-obj: %d\n", it->rankObj.elIndex, it->rankObj.subObj, it->rankObj.ithObj); MSG(" neigh obj-ind: %d sub-obj: %d ith-obj: %d\n", diff --git a/AMDiS/src/parallel/ParallelDebug.h b/AMDiS/src/parallel/ParallelDebug.h index 36921199..101d2f21 100644 --- a/AMDiS/src/parallel/ParallelDebug.h +++ b/AMDiS/src/parallel/ParallelDebug.h @@ -41,6 +41,13 @@ namespace AMDiS { */ static void testInteriorBoundary(MeshDistributor &pdb); + /** \brief + * Test if all periodic boundaries are set in a consistent way on all ranks. + * + * \param[in] pdb Parallel problem definition used for debugging. + */ + static void testPeriodicBoundary(MeshDistributor &pdb); + /** \brief * This function is used for debugging only. It traverses all interior boundaries * and compares the DOF indices on them with the dof indices of the boundarys diff --git a/AMDiS/src/parallel/StdMpi.cc b/AMDiS/src/parallel/StdMpi.cc index aab70545..33019f54 100644 --- a/AMDiS/src/parallel/StdMpi.cc +++ b/AMDiS/src/parallel/StdMpi.cc @@ -83,6 +83,20 @@ namespace AMDiS { return size; } + int intSizeOf(std::map<BoundaryType, std::map<DegreeOfFreedom, DegreeOfFreedom> > &data) + { + int size = 1; + + for (std::map<BoundaryType, std::map<DegreeOfFreedom, DegreeOfFreedom> >::iterator it = data.begin(); + it != data.end(); ++it) { + size += 2 + it->second.size() * 2; + } + + MSG("RET SIZE = %d\n", size); + + return size; + } + void makeBuf(int &data, int *buf) { buf[0] = data; @@ -322,4 +336,48 @@ namespace AMDiS { } } + void makeBuf(std::map<BoundaryType, std::map<DegreeOfFreedom, DegreeOfFreedom> > &data, int *buf) + { + buf[0] = data.size(); + int counter = 1; + + for (std::map<BoundaryType, std::map<DegreeOfFreedom, DegreeOfFreedom> >::iterator it = data.begin(); + it != data.end(); ++it) { + buf[counter++] = it->first; + buf[counter++] = it->second.size(); + + for (std::map<DegreeOfFreedom, DegreeOfFreedom>::iterator it2 = it->second.begin(); + it2 != it->second.end(); ++it2) { + buf[counter++] = it2->first; + buf[counter++] = it2->second; + } + } + } + + void makeFromBuf(std::map<BoundaryType, std::map<DegreeOfFreedom, DegreeOfFreedom> > &data, int *buf, int bufSize) + { + data.clear(); + + if (bufSize == 0) + return; + + int counter = 1; + + for (int i = 0; i < buf[0]; i++) { + BoundaryType bound = buf[counter++]; + std::map<DegreeOfFreedom, DegreeOfFreedom> dofs; + + int nDofs = buf[counter++]; + for (int j = 0; j < nDofs; j++) { + DegreeOfFreedom dof0, dof1; + dof0 = buf[counter++]; + dof1 = buf[counter++]; + dofs[dof0] = dof1; + } + + data[bound] = dofs; + } + + TEST_EXIT(bufSize == counter)("Should not happen!\n"); + } } diff --git a/AMDiS/src/parallel/StdMpi.h b/AMDiS/src/parallel/StdMpi.h index 213145d6..40b5c03b 100644 --- a/AMDiS/src/parallel/StdMpi.h +++ b/AMDiS/src/parallel/StdMpi.h @@ -55,6 +55,8 @@ namespace AMDiS { int intSizeOf(std::vector<std::vector<double> > &data); + int intSizeOf(std::map<BoundaryType, std::map<DegreeOfFreedom, DegreeOfFreedom> > &data); + void makeBuf(int &data, int *buf); void makeFromBuf(int &data, int *buf, int bufSize); @@ -98,7 +100,10 @@ namespace AMDiS { void makeBuf(std::vector<std::vector<double> > &data, double *buf); void makeFromBuf(std::vector<std::vector<double> > &data, double *buf, int bufSize); + + void makeBuf(std::map<BoundaryType, std::map<DegreeOfFreedom, DegreeOfFreedom> > &data, int *buf); + void makeFromBuf(std::map<BoundaryType, std::map<DegreeOfFreedom, DegreeOfFreedom> > &data, int *buf, int bufSize); template<typename SendT, typename RecvT=SendT> -- GitLab