// // Software License for AMDiS // // Copyright (c) 2010 Dresden University of Technology // All rights reserved. // Authors: Simon Vey, Thomas Witkowski et al. // // This file is part of AMDiS // // See also license.opensource.txt in the distribution. #include "VertexVector.h" #include "parallel/ElementObjectDatabase.h" namespace AMDiS { void ElementObjectDatabase::create(map& rankMap, MeshLevelData& ld) { FUNCNAME("ElementObjectDatabase::create()"); macroElementRankMap = &rankMap; levelData = &ld; // === Fills macro element data structures. === TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_NEIGH | Mesh::FILL_BOUND); while (elInfo) { TEST_EXIT_DBG(elInfo->getLevel() == 0)("Should not happen!\n"); Element *el = elInfo->getElement(); macroElIndexMap.insert(make_pair(el->getIndex(), el)); macroElIndexTypeMap.insert(make_pair(el->getIndex(), elInfo->getType())); // Add all sub object of the element to the variable elObjDb. addElement(elInfo); elInfo = stack.traverseNext(elInfo); } // Create periodic data, if there are periodic boundary conditions. createPeriodicData(); // Create data about the reverse modes of neighbouring elements. createReverseModeData(); } void ElementObjectDatabase::createMacroElementInfo(vector &mel) { macroElIndexMap.clear(); macroElIndexTypeMap.clear(); for (vector::iterator it = mel.begin(); it != mel.end(); ++it) { macroElIndexMap.insert(make_pair((*it)->getIndex(), (*it)->getElement())); macroElIndexTypeMap.insert(make_pair((*it)->getIndex(), (*it)->getElType())); } } void ElementObjectDatabase::addElement(ElInfo *elInfo) { FUNCNAME("ElementObjectDatabase::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); TEST_EXIT_DBG(neigh)("Should not happen!\n"); 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); TEST_EXIT_DBG(neigh)("Should not happen!\n"); 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 ElementObjectDatabase::createPeriodicData() { FUNCNAME("ElementObjectDatabase::createPeriodicData()"); TEST_EXIT_DBG(mesh)("Mesh not set!\n"); // === Return, if there are no periodic vertices, i.e., there are no === // === periodic boundaries in the mesh. === if (periodicVertices.size() == 0) return; // === Calculate smallest periodic boundary ID in mesh. === smallestPeriodicBcType = 0; for (map::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. === // 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 multPeriodicDof2, multPeriodicDof3; for (map >::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::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::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)] = provideConnectedPeriodicBoundary(type0, type1); periodicVertices[make_pair(dof3, dof0)] = provideConnectedPeriodicBoundary(type0, type1); 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 perDofs0 = make_pair(multPeriodicDof3[i], multPeriodicDof3[j]); pair perDofs1 = make_pair(multPeriodicDof3[j], multPeriodicDof3[i]); if (periodicVertices.count(perDofs0) == 0) { BoundaryType b = getNewBoundaryType(); periodicVertices[perDofs0] = b; periodicVertices[perDofs1] = b; } } } } // === Get all edges that have multiple periodic associations (3D only!). === for (map >::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"); DofEdge edge0 = it->first; DofEdge edge1 = *(it->second.begin()); DofEdge edge2 = *(++(it->second.begin())); pair perEdge0 = make_pair(edge1, edge2); pair perEdge1 = make_pair(edge2, edge1); TEST_EXIT_DBG(periodicEdges.count(make_pair(edge0, edge1)) == 1) ("Should not happen!\n"); TEST_EXIT_DBG(periodicEdges.count(make_pair(edge1, edge0)) == 1) ("Should not happen!\n"); BoundaryType type0 = periodicEdges[make_pair(edge0, edge1)]; BoundaryType type1 = periodicEdges[make_pair(edge0, edge2)]; BoundaryType type2 = provideConnectedPeriodicBoundary(type0, type1); periodicEdges[perEdge0] = type2; periodicEdges[perEdge1] = type2; } } // === 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::iterator it = periodicVertices.begin(); it != periodicVertices.end(); ++it) { pair 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::iterator it = periodicEdges.begin(); it != periodicEdges.end(); ++it) { pair 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::iterator it = periodicFaces.begin(); it != periodicFaces.end(); ++it) { pair 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 } BoundaryType ElementObjectDatabase::getNewBoundaryType() { FUNCNAME("ElementObjectDatabase::getNewBoundaryType()"); BoundaryType newPeriodicBoundaryType = 0; for (map::iterator it = mesh->getPeriodicAssociations().begin(); it != mesh->getPeriodicAssociations().end(); ++it) newPeriodicBoundaryType = std::min(newPeriodicBoundaryType, it->first); TEST_EXIT_DBG(newPeriodicBoundaryType < 0)("Should not happen!\n"); newPeriodicBoundaryType--; mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = new VertexVector(feSpace->getAdmin(), ""); return newPeriodicBoundaryType; } BoundaryType ElementObjectDatabase::provideConnectedPeriodicBoundary(BoundaryType b0, BoundaryType b1) { FUNCNAME("ElementObjectDatabase::provideConnectedPeriodicBoundary()"); std::pair bConn = (b0 <= b1 ? make_pair(b0, b1) : make_pair(b1, b0)); if (bConnMap.count(bConn) == 0) { BoundaryType newPeriodicBoundaryType = getNewBoundaryType(); VertexVector &vecB0 = mesh->getPeriodicAssociations(b0); VertexVector &vecB1 = mesh->getPeriodicAssociations(b1); VertexVector &vecC = mesh->getPeriodicAssociations(newPeriodicBoundaryType); DOFIteratorBase it(const_cast(feSpace->getAdmin()), USED_DOFS); for (it.reset(); !it.end(); ++it) { if (!it.isDofFree()) { TEST_EXIT_DBG(vecB1[vecB0[it.getDOFIndex()]] == vecB0[vecB1[it.getDOFIndex()]]) ("Should not happen!\n"); vecC[it.getDOFIndex()] = vecB1[vecB0[it.getDOFIndex()]]; } } bConnMap[bConn] = newPeriodicBoundaryType; } return bConnMap[bConn]; } void ElementObjectDatabase::updateRankData() { FUNCNAME("ElementObjectDatabase::updateRankData()"); vertexInRank.clear(); for (map >::iterator it = vertexElements.begin(); it != vertexElements.end(); ++it) { for (vector::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; } } edgeInRank.clear(); for (map >::iterator it = edgeElements.begin(); it != edgeElements.end(); ++it) { for (vector::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; } } faceInRank.clear(); for (map >::iterator it = faceElements.begin(); it != faceElements.end(); ++it) { for (vector::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; } } } void ElementObjectDatabase::createReverseModeData() { FUNCNAME("ElementObjectDatabase::createReverseModeData()"); // === In 2D, all reverse modes are always true! === if (mesh->getDim() == 2) return; // === First, create reverse modes for all "directly" neighbouring elements. === for (map >::iterator edgeIt = edgeElements.begin(); edgeIt != edgeElements.end(); ++edgeIt) { vector& els = edgeIt->second; for (unsigned int i = 0; i < els.size(); i++) { BoundaryObject obj0(macroElIndexMap[els[i].elIndex], macroElIndexTypeMap[els[i].elIndex], EDGE, els[i].ithObject); for (unsigned int j = i + 1; j < els.size(); j++) { BoundaryObject obj1(macroElIndexMap[els[j].elIndex], macroElIndexTypeMap[els[j].elIndex], EDGE, els[j].ithObject); bool reverseMode = BoundaryObject::computeReverseMode(obj0, obj1, feSpace, INTERIOR); edgeReverseMode[make_pair(els[i], els[j])] = reverseMode; edgeReverseMode[make_pair(els[j], els[i])] = reverseMode; } } } for (map >::iterator faceIt = faceElements.begin(); faceIt != faceElements.end(); ++faceIt) { vector& els = faceIt->second; for (unsigned int i = 0; i < els.size(); i++) { BoundaryObject obj0(macroElIndexMap[els[i].elIndex], macroElIndexTypeMap[els[i].elIndex], FACE, els[i].ithObject); for (unsigned int j = i + 1; j < els.size(); j++) { BoundaryObject obj1(macroElIndexMap[els[j].elIndex], macroElIndexTypeMap[els[j].elIndex], FACE, els[j].ithObject); bool reverseMode = BoundaryObject::computeReverseMode(obj0, obj1, feSpace, INTERIOR); faceReverseMode[make_pair(els[i], els[j])] = reverseMode; faceReverseMode[make_pair(els[j], els[i])] = reverseMode; } } } // === And create reverse modes for periodic neighbouring elements. === for (PerBoundMap::iterator edgeIt = periodicEdges.begin(); edgeIt != periodicEdges.end(); ++edgeIt) { vector &edges0 = edgeElements[edgeIt->first.first]; vector &edges1 = edgeElements[edgeIt->first.second]; for (unsigned int i = 0; i < edges0.size(); i++) { BoundaryObject obj0(macroElIndexMap[edges0[i].elIndex], macroElIndexTypeMap[edges0[i].elIndex], EDGE, edges0[i].ithObject); for (unsigned int j = 0; j < edges1.size(); j++) { BoundaryObject obj1(macroElIndexMap[edges1[j].elIndex], macroElIndexTypeMap[edges1[j].elIndex], EDGE, edges1[j].ithObject); bool reverseMode = BoundaryObject::computeReverseMode(obj0, obj1, feSpace, edgeIt->second); edgeReverseMode[make_pair(edges0[i], edges1[j])] = reverseMode; edgeReverseMode[make_pair(edges1[j], edges0[i])] = reverseMode; } } } for (PerBoundMap::iterator faceIt = periodicFaces.begin(); faceIt != periodicFaces.end(); ++faceIt) { vector &faces0 = faceElements[faceIt->first.first]; vector &faces1 = faceElements[faceIt->first.second]; TEST_EXIT_DBG(faces0.size() == faces1.size() == 1)("Should not happen!\n"); BoundaryObject obj0(macroElIndexMap[faces0[0].elIndex], macroElIndexTypeMap[faces0[0].elIndex], FACE, faces0[0].ithObject); BoundaryObject obj1(macroElIndexMap[faces1[0].elIndex], macroElIndexTypeMap[faces1[0].elIndex], FACE, faces1[0].ithObject); bool reverseMode = BoundaryObject::computeReverseMode(obj0, obj1, feSpace, faceIt->second); faceReverseMode[make_pair(faces0[0], faces1[0])] = reverseMode; faceReverseMode[make_pair(faces1[0], faces0[0])] = reverseMode; } } int ElementObjectDatabase::getIterateOwner(int level) { FUNCNAME("ElementObjectDatabase::getIterateOwner()"); TEST_EXIT_DBG(macroElementRankMap)("Should not happen!\n"); int owner = -1; vector *objData; switch (iterGeoPos) { case VERTEX: objData = &(vertexElements[vertexIter->first]); break; case EDGE: objData = &(edgeElements[edgeIter->first]); break; case FACE: objData = &(faceElements[faceIter->first]); break; } std::set &levelRanks = levelData->getLevelRanks(level); bool allRanks = (levelRanks.size() == 1 && *(levelRanks.begin()) == -1); for (vector::iterator it = objData->begin(); it != objData->end(); ++it) { int elRank = (*macroElementRankMap)[it->elIndex]; if (allRanks || levelData->getLevelRanks(level).count(elRank)) owner = std::max(owner, elRank); } return owner; } int ElementObjectDatabase::getIterateMaxLevel() { FUNCNAME("ElementObjectDatabase::getIterateMaxLevel()"); int nLevel = levelData->getLevelNumber(); TEST_EXIT_DBG(nLevel > 0)("Should not happen!\n"); vector > ranksInLevel; ranksInLevel.resize(nLevel); switch (iterGeoPos) { case VERTEX: { vector& vertexData = vertexElements[vertexIter->first]; for (vector::iterator it = vertexData.begin(); it != vertexData.end(); ++it) ranksInLevel[0].insert((*macroElementRankMap)[it->elIndex]); } break; case EDGE: { vector& edgeData = edgeElements[edgeIter->first]; for (vector::iterator it = edgeData.begin(); it != edgeData.end(); ++it) ranksInLevel[0].insert((*macroElementRankMap)[it->elIndex]); } break; case FACE: { vector& faceData = faceElements[faceIter->first]; for (vector::iterator it = faceData.begin(); it != faceData.end(); ++it) ranksInLevel[0].insert((*macroElementRankMap)[it->elIndex]); } break; default: ERROR_EXIT("Should not happen!\n"); } for (std::set::iterator it = ranksInLevel[0].begin(); it != ranksInLevel[0].end(); ++it) for (int level = 1; level < nLevel; level++) ranksInLevel[level].insert(levelData->getLevelId(level, *it)); int maxLevel = 0; for (int level = 1; level < nLevel; level++) if (ranksInLevel[level].size() > 1) maxLevel = level; return maxLevel; } void ElementObjectDatabase::serialize(ostream &out) { FUNCNAME("ElementObjectDatabase::serialize()"); int nSize = vertexElements.size(); SerUtil::serialize(out, nSize); for (map >::iterator it = vertexElements.begin(); it != vertexElements.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); } nSize = edgeElements.size(); SerUtil::serialize(out, nSize); for (map >::iterator it = edgeElements.begin(); it != edgeElements.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); } nSize = faceElements.size(); SerUtil::serialize(out, nSize); for (map >::iterator it = faceElements.begin(); it != faceElements.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); } nSize = vertexLocalMap.size(); SerUtil::serialize(out, nSize); for (map::iterator it = vertexLocalMap.begin(); it != vertexLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); } nSize = edgeLocalMap.size(); SerUtil::serialize(out, nSize); for (map::iterator it = edgeLocalMap.begin(); it != edgeLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); } nSize = faceLocalMap.size(); SerUtil::serialize(out, nSize); for (map::iterator it = faceLocalMap.begin(); it != faceLocalMap.end(); ++it) { it->first.serialize(out); SerUtil::serialize(out, it->second); } ERROR_EXIT("REWRITE SERIALIZATION!\n"); nSize = vertexInRank.size(); SerUtil::serialize(out, nSize); for (map >::iterator it = vertexInRank.begin(); it != vertexInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); } nSize = edgeInRank.size(); SerUtil::serialize(out, nSize); for (map >::iterator it = edgeInRank.begin(); it != edgeInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); } nSize = faceInRank.size(); SerUtil::serialize(out, nSize); for (map >::iterator it = faceInRank.begin(); it != faceInRank.end(); ++it) { SerUtil::serialize(out, it->first); serialize(out, it->second); } SerUtil::serialize(out, periodicVertices); SerUtil::serialize(out, periodicEdges); SerUtil::serialize(out, periodicFaces); nSize = periodicDofAssoc.size(); SerUtil::serialize(out, nSize); for (map >::iterator it = periodicDofAssoc.begin(); it != periodicDofAssoc.end(); ++it) { SerUtil::serialize(out, it->first); SerUtil::serialize(out, it->second); } nSize = periodicEdgeAssoc.size(); SerUtil::serialize(out, nSize); for (map >::iterator it = periodicEdgeAssoc.begin(); it != periodicEdgeAssoc.end(); ++it) { SerUtil::serialize(out, it->first); SerUtil::serialize(out, it->second); } nSize = edgeReverseMode.size(); SerUtil::serialize(out, nSize); for (map, bool>::iterator it = edgeReverseMode.begin(); it != edgeReverseMode.end(); ++it) { it->first.first.serialize(out); it->first.second.serialize(out); SerUtil::serialize(out, it->second); } nSize = faceReverseMode.size(); SerUtil::serialize(out, nSize); for (map, bool>::iterator it = faceReverseMode.begin(); it != faceReverseMode.end(); ++it) { it->first.first.serialize(out); it->first.second.serialize(out); SerUtil::serialize(out, it->second); } } void ElementObjectDatabase::deserialize(istream &in) { FUNCNAME("ElementObjectDatabase::deserialize()"); int nSize; SerUtil::deserialize(in, nSize); vertexElements.clear(); for (int i = 0; i < nSize; i++) { DegreeOfFreedom dof; vector data; SerUtil::deserialize(in, dof); deserialize(in, data); vertexElements[dof] = data; } SerUtil::deserialize(in, nSize); edgeElements.clear(); for (int i = 0; i < nSize; i++) { DofEdge edge; vector data; SerUtil::deserialize(in, edge); deserialize(in, data); edgeElements[edge] = data; } SerUtil::deserialize(in, nSize); faceElements.clear(); for (int i = 0; i < nSize; i++) { DofFace face; vector data; SerUtil::deserialize(in, face); deserialize(in, data); faceElements[face] = data; } SerUtil::deserialize(in, nSize); vertexLocalMap.clear(); for (int i = 0; i < nSize; i++) { ElementObjectData data; DegreeOfFreedom dof; data.deserialize(in); SerUtil::deserialize(in, dof); vertexLocalMap[data] = dof; } SerUtil::deserialize(in, nSize); edgeLocalMap.clear(); for (int i = 0; i < nSize; i++) { ElementObjectData data; DofEdge edge; data.deserialize(in); SerUtil::deserialize(in, edge); edgeLocalMap[data] = edge; } SerUtil::deserialize(in, nSize); faceLocalMap.clear(); for (int i = 0; i < nSize; i++) { ElementObjectData data; DofFace face; data.deserialize(in); SerUtil::deserialize(in, face); faceLocalMap[data] = face; } ERROR_EXIT("REWRITE DESERIALIZATION!\n"); SerUtil::deserialize(in, nSize); vertexInRank.clear(); for (int i = 0; i < nSize; i++) { DegreeOfFreedom dof; map data; SerUtil::deserialize(in, dof); deserialize(in, data); vertexInRank[dof] = data; } SerUtil::deserialize(in, nSize); edgeInRank.clear(); for (int i = 0; i < nSize; i++) { DofEdge edge; map data; SerUtil::deserialize(in, edge); deserialize(in, data); edgeInRank[edge] = data; } SerUtil::deserialize(in, nSize); faceInRank.clear(); for (int i = 0; i < nSize; i++) { DofFace face; map data; SerUtil::deserialize(in, face); deserialize(in, data); faceInRank[face] = data; } SerUtil::deserialize(in, periodicVertices); SerUtil::deserialize(in, periodicEdges); SerUtil::deserialize(in, periodicFaces); SerUtil::deserialize(in, nSize); periodicDofAssoc.clear(); for (int i = 0; i < nSize; i++) { DegreeOfFreedom dof; std::set dofs; SerUtil::deserialize(in, dof); SerUtil::deserialize(in, dofs); periodicDofAssoc[dof] = dofs; } SerUtil::deserialize(in, nSize); periodicEdgeAssoc.clear(); for (int i = 0; i < nSize; i++) { DofEdge edge; std::set edges; SerUtil::deserialize(in, edge); SerUtil::deserialize(in, edges); periodicEdgeAssoc[edge] = edges; } SerUtil::deserialize(in, nSize); edgeReverseMode.clear(); for (int i = 0; i < nSize; i++) { ElementObjectData obj0, obj1; bool reverseMode; obj0.deserialize(in); obj1.deserialize(in); SerUtil::deserialize(in, reverseMode); edgeReverseMode[make_pair(obj0, obj1)] = reverseMode; } SerUtil::deserialize(in, nSize); faceReverseMode.clear(); for (int i = 0; i < nSize; i++) { ElementObjectData obj0, obj1; bool reverseMode; obj0.deserialize(in); obj1.deserialize(in); SerUtil::deserialize(in, reverseMode); faceReverseMode[make_pair(obj0, obj1)] = reverseMode; } } void ElementObjectDatabase::serialize(ostream &out, vector& elVec) { int nSize = elVec.size(); SerUtil::serialize(out, nSize); for (int i = 0; i < nSize; i++) elVec[i].serialize(out); } void ElementObjectDatabase::deserialize(istream &in, vector& elVec) { int nSize; SerUtil::deserialize(in, nSize); elVec.resize(nSize); for (int i = 0; i < nSize; i++) elVec[i].deserialize(in); } void ElementObjectDatabase::serialize(ostream &out, map& data) { int nSize = data.size(); SerUtil::serialize(out, nSize); for (map::iterator it = data.begin(); it != data.end(); ++it) { SerUtil::serialize(out, it->first); it->second.serialize(out); } } void ElementObjectDatabase::deserialize(istream &in, map& data) { int nSize; SerUtil::deserialize(in, nSize); for (int i = 0; i < nSize; i++) { int index; ElementObjectData elObj; SerUtil::deserialize(in, index); elObj.deserialize(in); data[index] = elObj; } } }