// // 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 "InteriorBoundary.h" #include "FiniteElemSpace.h" #include "BasisFunction.h" #include "Serializer.h" namespace AMDiS { void BoundaryObject::setReverseMode(BoundaryObject &otherBound, FiniteElemSpace *feSpace) { FUNCNAME("BoundaryObject::setReverseMode()"); bool otherMode = false; switch (feSpace->getMesh()->getDim()) { case 2: otherMode = true; break; case 3: TEST_EXIT_DBG(otherBound.elType == 0) ("Only 3D macro elements with level 0 are supported!\n"); if (subObj == EDGE) { int el0_v0 = el->getVertexOfEdge(ithObj, 0); int el0_v1 = el->getVertexOfEdge(ithObj, 1); int el1_v0 = el->getVertexOfEdge(otherBound.ithObj, 0); int el1_v1 = el->getVertexOfEdge(otherBound.ithObj, 1); const BasisFunction *basFcts = feSpace->getBasisFcts(); int nBasFcts = basFcts->getNumber(); std::vector localDofs0(nBasFcts), localDofs1(nBasFcts); basFcts->getLocalIndices(el, feSpace->getAdmin(), localDofs0); basFcts->getLocalIndices(otherBound.el, feSpace->getAdmin(), localDofs1); TEST_EXIT_DBG(localDofs0[el0_v0] == localDofs1[el1_v0] || localDofs0[el0_v0] == localDofs1[el1_v1]) ("This should not happen!\n"); TEST_EXIT_DBG(localDofs0[el0_v1] == localDofs1[el1_v0] || localDofs0[el0_v1] == localDofs1[el1_v1]) ("This should not happen!\n"); if (localDofs0[el0_v0] != localDofs1[el1_v0]) otherMode = true; } if (subObj == FACE && ithObj != 1) { const BasisFunction *basFcts = feSpace->getBasisFcts(); int nBasFcts = basFcts->getNumber(); std::vector localDofs0(nBasFcts), localDofs1(nBasFcts); basFcts->getLocalIndices(el, feSpace->getAdmin(), localDofs0); basFcts->getLocalIndices(otherBound.el, feSpace->getAdmin(), localDofs1); if (ithObj == 2 || ithObj == 3) otherMode = (localDofs0[0] != localDofs1[0]); if (ithObj == 0) otherMode = (localDofs0[1] != localDofs1[1]); } break; default: ERROR_EXIT("This should not happen!\n"); } otherBound.reverseMode = otherMode; } bool BoundaryObject::operator==(const BoundaryObject& other) const { return (other.elIndex == elIndex && // other.elType == elType && other.subObj == subObj && other.ithObj == ithObj); } bool BoundaryObject::operator!=(const BoundaryObject& other) const { return (other.elIndex != elIndex || // other.elType != elType || other.subObj != subObj || other.ithObj != ithObj); } bool AtomicBoundary::operator==(const AtomicBoundary& other) const { return (rankObj == other.rankObj && neighObj == other.neighObj && type == other.type); } AtomicBoundary& InteriorBoundary::getNewAtomic(int rank) { boundary[rank].resize(boundary[rank].size() + 1); return boundary[rank][boundary[rank].size() - 1]; } bool InteriorBoundary::operator==(const InteriorBoundary& other) const { InteriorBoundary& other2 = const_cast(other); for (RankToBoundMap::const_iterator it = boundary.begin(); it != boundary.end(); ++it) { if (other2.boundary.count(it->first) == 0) return false; if (other2.boundary[it->first].size() != it->second.size()) return false; for (unsigned int i = 0; i < it->second.size(); i++) { std::vector::iterator bIt = find(other2.boundary[it->first].begin(), other2.boundary[it->first].end(), it->second[i]); if (bIt == other2.boundary[it->first].end()) return false; } } return true; } void InteriorBoundary::serialize(std::ostream &out) { FUNCNAME("InteriorBoundary::serialize()"); int mSize = boundary.size(); SerUtil::serialize(out, mSize); for (RankToBoundMap::iterator it = boundary.begin(); it != boundary.end(); ++it) { int rank = it->first; int boundSize = it->second.size(); SerUtil::serialize(out, rank); SerUtil::serialize(out, boundSize); for (int i = 0; i < boundSize; i++) { AtomicBoundary &bound = (it->second)[i]; SerUtil::serialize(out, bound.rankObj.elIndex); SerUtil::serialize(out, bound.rankObj.elType); SerUtil::serialize(out, bound.rankObj.subObj); SerUtil::serialize(out, bound.rankObj.ithObj); SerUtil::serialize(out, bound.rankObj.reverseMode); serializeExcludeList(out, bound.rankObj.excludedSubstructures); SerUtil::serialize(out, bound.neighObj.elIndex); SerUtil::serialize(out, bound.neighObj.elType); SerUtil::serialize(out, bound.neighObj.subObj); SerUtil::serialize(out, bound.neighObj.ithObj); SerUtil::serialize(out, bound.neighObj.reverseMode); serializeExcludeList(out, bound.neighObj.excludedSubstructures); SerUtil::serialize(out, bound.type); } } } void InteriorBoundary::deserialize(std::istream &in, std::map &elIndexMap) { FUNCNAME("InteriorBoundary::deserialize()"); int mSize = 0; SerUtil::deserialize(in, mSize); for (int i = 0; i < mSize; i++) { int rank = 0; int boundSize = 0; SerUtil::deserialize(in, rank); SerUtil::deserialize(in, boundSize); boundary[rank].resize(boundSize); for (int i = 0; i < boundSize; i++) { AtomicBoundary &bound = boundary[rank][i]; SerUtil::deserialize(in, bound.rankObj.elIndex); SerUtil::deserialize(in, bound.rankObj.elType); SerUtil::deserialize(in, bound.rankObj.subObj); SerUtil::deserialize(in, bound.rankObj.ithObj); SerUtil::deserialize(in, bound.rankObj.reverseMode); deserializeExcludeList(in, bound.rankObj.excludedSubstructures); SerUtil::deserialize(in, bound.neighObj.elIndex); SerUtil::deserialize(in, bound.neighObj.elType); SerUtil::deserialize(in, bound.neighObj.subObj); SerUtil::deserialize(in, bound.neighObj.ithObj); SerUtil::deserialize(in, bound.neighObj.reverseMode); deserializeExcludeList(in, bound.neighObj.excludedSubstructures); SerUtil::deserialize(in, bound.type); TEST_EXIT_DBG(elIndexMap.count(bound.rankObj.elIndex) == 1) ("Cannot find element with index %d for deserialization!\n", bound.rankObj.elIndex); TEST_EXIT_DBG(elIndexMap[bound.rankObj.elIndex]->getIndex() == bound.rankObj.elIndex)("Should not happen!\n"); bound.rankObj.el = elIndexMap[bound.rankObj.elIndex]; bound.neighObj.el = NULL; } } } void InteriorBoundary::serializeExcludeList(std::ostream &out, ExcludeList &list) { int size = list.size(); SerUtil::serialize(out, size); for (int i = 0; i < size; i++) { SerUtil::serialize(out, list[i].first); SerUtil::serialize(out, list[i].second); } } void InteriorBoundary::deserializeExcludeList(std::istream &in, ExcludeList &list) { int size = 0; SerUtil::deserialize(in, size); list.resize(0); list.reserve(size); for (int i = 0; i < size; i++) { GeoIndex a; int b; SerUtil::deserialize(in, a); SerUtil::deserialize(in, b); list.push_back(std::make_pair(a, b)); } } }