diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index f17a4459669b8ba63df0608c3ebe7a728400ae8d..e84bcb6cebf8556784ec57e25ebf11d01e13c06b 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -55,8 +55,9 @@ namespace AMDiS { using namespace boost::filesystem; using namespace std; - const Flag MeshDistributor::BOUNDARY_SUBOBJ_SORTED = 0X01L; - const Flag MeshDistributor::BOUNDARY_EDGE_SCHUR = 0X02L; + const Flag MeshDistributor::BOUNDARY_SUBOBJ_SORTED = 0X01L; + const Flag MeshDistributor::BOUNDARY_FILL_INFO_SEND_DOFS = 0X02L; + const Flag MeshDistributor::BOUNDARY_FILL_INFO_RECV_DOFS = 0X04L; inline bool cmpDofsByValue(const DegreeOfFreedom* dof1, const DegreeOfFreedom* dof2) { @@ -648,6 +649,29 @@ namespace AMDiS { } + void MeshDistributor::getAllBoundaryDofs(DofContainer& dofs) + { + FUNCNAME("MeshDistributor::getAllBoundaryDofs()"); + + DofContainerSet dofSet; + + for (RankToDofContainer::iterator sendIt = sendDofs.begin(); + sendIt != sendDofs.end(); ++sendIt) + for (DofContainer::iterator dofIt = sendIt->second.begin(); + dofIt != sendIt->second.end(); ++dofIt) + dofSet.insert(*dofIt); + + for (RankToDofContainer::iterator recvIt = recvDofs.begin(); + recvIt != recvDofs.end(); ++recvIt) + for (DofContainer::iterator dofIt = recvIt->second.begin(); + dofIt != recvIt->second.end(); ++dofIt) + dofSet.insert(*dofIt); + + dofs.clear(); + dofs.insert(dofs.begin(), dofSet.begin(), dofSet.end()); + } + + void MeshDistributor::setRankDofs(ProblemStatSeq *probStat) { int nComponents = probStat->getNumComponents(); @@ -657,7 +681,8 @@ namespace AMDiS { probStat->getSystemMatrix(i, j)->setRankDofs(isRankDof); TEST_EXIT_DBG(probStat->getRhs()->getDOFVector(i))("No RHS vector!\n"); - TEST_EXIT_DBG(probStat->getSolution()->getDOFVector(i))("No solution vector!\n"); + TEST_EXIT_DBG(probStat->getSolution()->getDOFVector(i)) + ("No solution vector!\n"); probStat->getRhs()->getDOFVector(i)->setRankDofs(isRankDof); probStat->getSolution()->getDOFVector(i)->setRankDofs(isRankDof); @@ -1674,16 +1699,31 @@ namespace AMDiS { DofContainer& tmp = sendDofs[it.getRank()]; tmp.insert(tmp.end(), dofs.begin(), dofs.end()); - dofSet.insert(dofs.begin(), dofs.end()); + + if (createBoundaryDofFlag.isSet(BOUNDARY_FILL_INFO_SEND_DOFS)) + dofSet.insert(dofs.begin(), dofs.end()); } } } - for (int geo = FACE; geo >= VERTEX; geo--) - for (InteriorBoundary::iterator it(otherIntBoundary); !it.end(); ++it) - if (it->rankObj.subObj == geo) - it->rankObj.el->getAllDofs(feSpace, it->rankObj, - recvDofs[it.getRank()]); + for (int geo = FACE; geo >= VERTEX; geo--) { + std::set<const DegreeOfFreedom*> &dofSet = + boundaryDofInfo.geoDofs[static_cast<GeoIndex>(geo)]; + dofSet.clear(); + + for (InteriorBoundary::iterator it(otherIntBoundary); !it.end(); ++it) { + if (it->rankObj.subObj == geo) { + dofs.clear(); + it->rankObj.el->getAllDofs(feSpace, it->rankObj, dofs); + + DofContainer& tmp = recvDofs[it.getRank()]; + tmp.insert(tmp.end(), dofs.begin(), dofs.end()); + + if (createBoundaryDofFlag.isSet(BOUNDARY_FILL_INFO_RECV_DOFS)) + dofSet.insert(dofs.begin(), dofs.end()); + } + } + } } else { for (InteriorBoundary::iterator it(myIntBoundary); !it.end(); ++it) it->rankObj.el->getAllDofs(feSpace, it->rankObj, diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h index a4e4e05daf53ddf387d830a11c0ca24a4c053c75..07360c8929ac66e187e613c99c67f423b080bbb8 100644 --- a/AMDiS/src/parallel/MeshDistributor.h +++ b/AMDiS/src/parallel/MeshDistributor.h @@ -24,11 +24,8 @@ #define AMDIS_MESHDISTRIBUTOR_H -#include <map> -#include <set> -#include <vector> #include <mpi.h> - +#include "parallel/ParallelTypes.h" #include "parallel/MeshPartitioner.h" #include "parallel/InteriorBoundary.h" #include "AMDiS_fwd.h" @@ -54,36 +51,6 @@ namespace AMDiS { class MeshDistributor { - protected: - /// Defines a mapping type from DOFs to rank numbers. - typedef map<const DegreeOfFreedom*, int> DofToRank; - - /// Defines a mapping type from DOFs to a set of rank numbers. - typedef map<const DegreeOfFreedom*, std::set<int> > DofToPartitions; - - /// Defines a mapping type from rank numbers to sets of DOFs. - typedef map<int, DofContainer> RankToDofContainer; - - /// Defines a mapping type from DOF indices to DOF indices. - typedef map<DegreeOfFreedom, DegreeOfFreedom> DofMapping; - - /// Defines a mapping type from DOFs to boolean values. - typedef map<const DegreeOfFreedom*, bool> DofToBool; - - /// Defines a mapping type from DOF indices to boolean values. - typedef map<DegreeOfFreedom, bool> DofIndexToBool; - - /// Forward type (it maps rank numbers to the interior boundary objects). - typedef InteriorBoundary::RankToBoundMap RankToBoundMap; - - typedef map<const DegreeOfFreedom*, DegreeOfFreedom> DofIndexMap; - - /// Mapps a boundar type, i.e., a boundary identifier index, to a periodic - /// DOF mapping. - typedef map<BoundaryType, DofMapping> PeriodicDofMap; - - typedef vector<MeshStructure> MeshCodeVec; - public: MeshDistributor(); @@ -310,6 +277,8 @@ namespace AMDiS { return boundaryDofInfo; } + void getAllBoundaryDofs(DofContainer& dofs); + protected: /** \brief * Determines the interior boundaries, i.e. boundaries between ranks, and stores @@ -622,10 +591,20 @@ namespace AMDiS { BoundaryDofInfo boundaryDofInfo; public: - /// + /// The boundary DOFs are sorted by subobject entities, i.e., first all + /// face DOFs, edge DOFs and to the last vertex DOFs will be set to + /// communication structure vectors, \ref sendDofs and \ref recvDofs. static const Flag BOUNDARY_SUBOBJ_SORTED; - static const Flag BOUNDARY_EDGE_SCHUR; + /// When boundary DOFs are created, \ref boundaryDofInfo is filled for + /// all DOFs that this rank will send to other ranks (thus, rank + /// owned DOFs. + static const Flag BOUNDARY_FILL_INFO_SEND_DOFS; + + /// When boundary DOFs are created, \ref boundaryDofInfo is filled for + /// all DOFs that this rank will receive from other ranks (thus, DOFs + /// that are owned by another rank). + static const Flag BOUNDARY_FILL_INFO_RECV_DOFS; friend class ParallelDebug; }; diff --git a/AMDiS/src/parallel/ParallelDebug.cc b/AMDiS/src/parallel/ParallelDebug.cc index 0ee7fccba18531b269cf0cb35a9a89430cc0d044..071a0657a4949a35e67bb1523f8d0c6ccb754fa8 100644 --- a/AMDiS/src/parallel/ParallelDebug.cc +++ b/AMDiS/src/parallel/ParallelDebug.cc @@ -22,13 +22,14 @@ namespace AMDiS { + using namespace std; + + void ParallelDebug::testInteriorBoundary(MeshDistributor &pdb) { FUNCNAME("ParallelDebug::testInteriorBoundary()"); - typedef MeshDistributor::RankToBoundMap RankToBoundMap; - - std::vector<int*> sendBuffers, recvBuffers; + vector<int*> sendBuffers, recvBuffers; MPI::Request request[pdb.myIntBoundary.boundary.size() + pdb.otherIntBoundary.boundary.size() + @@ -163,8 +164,6 @@ namespace AMDiS { // === 2. check: All periodic DOFs must be symmetric, i.e., if A is mapped === // === to B, then B must be mapped to A. === - typedef MeshDistributor::PeriodicDofMap PeriodicDofMap; - StdMpi<PeriodicDofMap> stdMpi(pdb.mpiComm, true); if (pdb.mpiRank == 0) { @@ -182,7 +181,7 @@ namespace AMDiS { if (pdb.mpiRank == 0) { // Stores to each rank the periodic DOF mappings of this rank. - std::map<int, PeriodicDofMap> rankToMaps; + map<int, PeriodicDofMap> rankToMaps; PeriodicDofMap dofMap = pdb.periodicDof; rankToMaps[0] = dofMap; @@ -192,7 +191,7 @@ namespace AMDiS { for (PeriodicDofMap::iterator it = otherMap.begin(); it != otherMap.end(); ++it) { - for (MeshDistributor::DofMapping::iterator dofIt = it->second.begin(); + for (DofMapping::iterator dofIt = it->second.begin(); dofIt != it->second.end(); ++dofIt) { if (dofMap.count(it->first) == 1 && dofMap[it->first].count(dofIt->first) == 1) { @@ -211,7 +210,7 @@ namespace AMDiS { for (PeriodicDofMap::iterator it = dofMap.begin(); it != dofMap.end(); ++it) { - for (MeshDistributor::DofMapping::iterator dofIt = it->second.begin(); + for (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", @@ -247,7 +246,7 @@ namespace AMDiS { // === periodic boundaries only on rectangulars and boxes. === RankToCoords sendCoords; - std::map<int, std::vector<BoundaryType> > rankToDofType; + map<int, vector<BoundaryType> > rankToDofType; for (InteriorBoundary::RankToBoundMap::iterator it = pdb.periodicBoundary.boundary.begin(); it != pdb.periodicBoundary.boundary.end(); ++it) { @@ -330,7 +329,7 @@ namespace AMDiS { } /// Defines a mapping type from rank numbers to sets of DOFs. - typedef std::map<int, DofContainer> RankToDofContainer; + typedef map<int, DofContainer> RankToDofContainer; // Maps to each neighbour rank an array of WorldVectors. This array contains the // coordinates of all DOFs this rank shares on the interior boundary with the @@ -358,9 +357,9 @@ namespace AMDiS { dofIt != it->second.end(); ++dofIt) recvCoords[it->first].push_back(coords[**dofIt]); - std::vector<int> sendSize(pdb.mpiSize, 0); - std::vector<int> recvSize(pdb.mpiSize, 0); - std::vector<int> recvSizeBuffer(pdb.mpiSize, 0); + vector<int> sendSize(pdb.mpiSize, 0); + vector<int> recvSize(pdb.mpiSize, 0); + vector<int> recvSizeBuffer(pdb.mpiSize, 0); MPI::Request request[(pdb.mpiSize - 1) * 2]; int requestCounter = 0; @@ -426,7 +425,7 @@ namespace AMDiS { // === Print error message if the coordinates are not the same. === if (printCoords) { MSG("[DBG] i = %d\n", i); - std::stringstream oss; + stringstream oss; oss.precision(5); oss << "[DBG] Rank " << pdb.mpiRank << " from rank " << it->first << " expect coords ("; @@ -465,7 +464,7 @@ namespace AMDiS { DOFVector<WorldVector<double> > coords(pdb.feSpace, "tmp"); pdb.mesh->getDofIndexCoords(pdb.feSpace, coords); - typedef std::map<WorldVector<double>, int> CoordsIndexMap; + typedef map<WorldVector<double>, int> CoordsIndexMap; CoordsIndexMap coordsToIndex; DOFIterator<WorldVector<double> > it(&coords, USED_DOFS); @@ -491,7 +490,7 @@ namespace AMDiS { coordsIt != otherCoords.end(); ++coordsIt) { if (coordsToIndex.count(coordsIt->first) == 1 && coordsToIndex[coordsIt->first] != coordsIt->second) { - std::stringstream oss; + stringstream oss; oss.precision(5); oss << "DOF at coords "; for (int i = 0; i < Global::getGeo(WORLD); i++) @@ -517,8 +516,8 @@ namespace AMDiS { FUNCNAME("ParallelDebug::testAllElements()"); std::set<int> macroElements; - int minElementIndex = std::numeric_limits<int>::max(); - int maxElementIndex = std::numeric_limits<int>::min(); + int minElementIndex = numeric_limits<int>::max(); + int maxElementIndex = numeric_limits<int>::min(); TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(pdb.mesh, 0, Mesh::CALL_EL_LEVEL); @@ -559,7 +558,7 @@ namespace AMDiS { { FUNCNAME("ParallelDebug::testDofContainerCommunication()"); - std::map<int, int> sendNumber; + map<int, int> sendNumber; for (RankToDofContainer::iterator it = sendDofs.begin(); it != sendDofs.end(); ++it) sendNumber[it->first] = it->second.size(); @@ -570,7 +569,7 @@ namespace AMDiS { stdMpi.startCommunication(); int foundError = 0; - for (std::map<int, int>::iterator it = stdMpi.getRecvData().begin(); + for (map<int, int>::iterator it = stdMpi.getRecvData().begin(); it != stdMpi.getRecvData().end(); ++it) { if (it->second != static_cast<int>(recvDofs[it->first].size())) { ERROR("Rank expectes %d DOFs to receive from rank %d, but %d DOFs are received!\n", @@ -588,7 +587,7 @@ namespace AMDiS { { FUNCNAME("ParallelDebug::testDoubleDofs()"); - std::map<WorldVector<double>, DegreeOfFreedom> cMap; + map<WorldVector<double>, DegreeOfFreedom> cMap; int foundError = 0; TraverseStack stack; @@ -619,20 +618,17 @@ namespace AMDiS { void ParallelDebug::printMapLocalGlobal(MeshDistributor &pdb, int rank) { if (rank == -1 || pdb.mpiRank == rank) { - std::cout << "====== DOF MAP LOCAL -> GLOBAL ====== " << std::endl; + cout << "====== DOF MAP LOCAL -> GLOBAL ====== " << endl; - typedef std::map<DegreeOfFreedom, DegreeOfFreedom> DofMapping; - typedef std::map<int, DofContainer> RankToDofContainer; - for (DofMapping::iterator it = pdb.mapLocalGlobalDofs.begin(); it != pdb.mapLocalGlobalDofs.end(); it++) { DegreeOfFreedom localdof = -1; if (pdb.mapLocalDofIndex.count(it->first) > 0) localdof = pdb.mapLocalDofIndex[it->first]; - std::cout << "DOF " << it->first << " " + cout << "DOF " << it->first << " " << it->second << " " - << localdof << std::endl; + << localdof << endl; WorldVector<double> coords; pdb.mesh->getDofIndexCoords(it->first, pdb.feSpace, coords); coords.print(); @@ -642,7 +638,7 @@ namespace AMDiS { for (DofContainer::iterator dofit = rankit->second.begin(); dofit != rankit->second.end(); ++dofit) if (**dofit == it->first) - std::cout << "SEND DOF TO " << rankit->first << std::endl; + cout << "SEND DOF TO " << rankit->first << endl; } for (RankToDofContainer::iterator rankit = pdb.recvDofs.begin(); @@ -650,10 +646,10 @@ namespace AMDiS { for (DofContainer::iterator dofit = rankit->second.begin(); dofit != rankit->second.end(); ++dofit) if (**dofit == it->first) - std::cout << "RECV DOF FROM " << rankit->first << std::endl; + cout << "RECV DOF FROM " << rankit->first << endl; } - std::cout << "------" << std::endl; + cout << "------" << endl; } } } @@ -666,19 +662,19 @@ namespace AMDiS { ERROR_EXIT("Function must be rewritten!\n"); #if 0 - typedef std::map<DegreeOfFreedom, DegreeOfFreedom> DofMapping; - typedef std::map<DegreeOfFreedom, std::set<DegreeOfFreedom> > PeriodicDofMap; + typedef map<DegreeOfFreedom, DegreeOfFreedom> DofMapping; + typedef map<DegreeOfFreedom, std::set<DegreeOfFreedom> > PeriodicDofMap; if (rank == -1 || pdb.mpiRank == rank) { - std::cout << "====== DOF MAP PERIODIC ====== " << std::endl; + cout << "====== DOF MAP PERIODIC ====== " << endl; for (PeriodicDofMap::iterator it = pdb.periodicDof.begin(); it != pdb.periodicDof.end(); ++it) { - std::cout << "DOF MAP " << it->first << ": "; + cout << "DOF MAP " << it->first << ": "; for (std::set<DegreeOfFreedom>::iterator dofit = it->second.begin(); dofit != it->second.end(); ++dofit) - std::cout << *dofit << " "; - std::cout << std::endl; + cout << *dofit << " "; + cout << endl; DegreeOfFreedom localdof = -1; for (DofMapping::iterator dofIt = pdb.mapLocalGlobalDofs.begin(); @@ -703,21 +699,21 @@ namespace AMDiS { DofContainer& rankAllDofs) { if (rank == -1 || pdb.mpiRank == rank) { - std::cout << "====== RANK DOF INFORMATION ====== " << std::endl; + cout << "====== RANK DOF INFORMATION ====== " << endl; - std::cout << " RANK OWNED DOFS: " << std::endl; + cout << " RANK OWNED DOFS: " << endl; for (DofContainer::iterator dofit = rankDofs.begin(); dofit != rankDofs.end(); ++dofit) { - std::cout << " " << **dofit << std::endl; + cout << " " << **dofit << endl; WorldVector<double> coords; pdb.mesh->getDofIndexCoords(*dofit, pdb.feSpace, coords); coords.print(); } - std::cout << " RANK ALL DOFS: " << std::endl; + cout << " RANK ALL DOFS: " << endl; for (DofContainer::iterator dofit = rankAllDofs.begin(); dofit != rankAllDofs.end(); ++dofit) { - std::cout << " " << **dofit << std::endl; + cout << " " << **dofit << endl; WorldVector<double> coords; pdb.mesh->getDofIndexCoords(*dofit, pdb.feSpace, coords); coords.print(); @@ -763,21 +759,21 @@ namespace AMDiS { void ParallelDebug::writeDebugFile(MeshDistributor &pdb, - std::string prefix, std::string postfix) + string prefix, string postfix) { FUNCNAME("ParallelDebug::writeCoordsFile()"); - std::stringstream filename; + stringstream filename; filename << prefix << "-" << pdb.mpiRank << "." << postfix; DOFVector<WorldVector<double> > coords(pdb.feSpace, "tmp"); pdb.mesh->getDofIndexCoords(pdb.feSpace, coords); - typedef std::map<int, std::vector<DegreeOfFreedom> > ElDofMap; + typedef map<int, vector<DegreeOfFreedom> > ElDofMap; ElDofMap elDofMap; TraverseStack stack; const BasisFunction *basisFcts = pdb.feSpace->getBasisFcts(); - std::vector<DegreeOfFreedom> localIndices(basisFcts->getNumber()); + vector<DegreeOfFreedom> localIndices(basisFcts->getNumber()); ElInfo *elInfo = stack.traverseFirst(pdb.mesh, -1, Mesh::CALL_LEAF_EL); while (elInfo) { basisFcts->getLocalIndices(elInfo->getElement(), @@ -788,7 +784,7 @@ namespace AMDiS { // === Write informations about all DOFs. === - std::ofstream file; + ofstream file; file.open(filename.str().c_str()); file << "# First line contains number of DOFs, than each line has the format\n"; file << "# Local DOF index Global DOF index Is rank DOF x-coord y-coord z-coord\n"; @@ -839,7 +835,7 @@ namespace AMDiS { ElementFileWriter::writeFile(vec, pdb.mesh, filename); } - void ParallelDebug::writePartitioningFile(std::string filename, + void ParallelDebug::writePartitioningFile(string filename, int counter, FiniteElemSpace *feSpace) { diff --git a/AMDiS/src/parallel/ParallelDebug.h b/AMDiS/src/parallel/ParallelDebug.h index 126cdd091c544f9eca8fcdbf56008e366a39f2f1..9a9cb7ce867a9f3fef6b0f4201ca52d0a0cdc60a 100644 --- a/AMDiS/src/parallel/ParallelDebug.h +++ b/AMDiS/src/parallel/ParallelDebug.h @@ -23,6 +23,7 @@ #ifndef AMDIS_PARALLELDEBUG_H #define AMDIS_PARALLELDEBUG_H +#include "parallel/ParallelTypes.h" #include "parallel/MeshDistributor.h" namespace AMDiS { @@ -30,8 +31,6 @@ namespace AMDiS { class ParallelDebug { protected: - typedef MeshDistributor::RankToDofContainer RankToDofContainer; - typedef std::vector<WorldVector<double> > CoordsVec; /// Defines a mapping type from rank numbers to sets of coordinates. diff --git a/AMDiS/src/parallel/ParallelTypes.h b/AMDiS/src/parallel/ParallelTypes.h new file mode 100644 index 0000000000000000000000000000000000000000..4fd6aa3f4ea515981c66f2f1b288274f0ab966d2 --- /dev/null +++ b/AMDiS/src/parallel/ParallelTypes.h @@ -0,0 +1,66 @@ +// ============================================================================ +// == == +// == AMDiS - Adaptive multidimensional simulations == +// == == +// == http://www.amdis-fem.org == +// == == +// ============================================================================ +// +// 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. + + + +/** \file ParallelTypes.h */ + +#include <vector> +#include <set> +#include <map> +#include "Global.h" +#include "parallel/InteriorBoundary.h" + +#ifndef AMDIS_PARALLEL_TYPES_H +#define AMDIS_PARALLEL_TYPES_H + +namespace AMDiS { + + using namespace std; + + /// Defines a mapping type from DOFs to rank numbers. + typedef map<const DegreeOfFreedom*, int> DofToRank; + + /// Defines a mapping type from DOFs to a set of rank numbers. + typedef map<const DegreeOfFreedom*, std::set<int> > DofToPartitions; + + /// Defines a mapping type from rank numbers to sets of DOFs. + typedef map<int, DofContainer> RankToDofContainer; + + /// Defines a mapping type from DOF indices to DOF indices. + typedef map<DegreeOfFreedom, DegreeOfFreedom> DofMapping; + + /// Defines a mapping type from DOFs to boolean values. + typedef map<const DegreeOfFreedom*, bool> DofToBool; + + /// Defines a mapping type from DOF indices to boolean values. + typedef map<DegreeOfFreedom, bool> DofIndexToBool; + + /// Forward type (it maps rank numbers to the interior boundary objects). + typedef InteriorBoundary::RankToBoundMap RankToBoundMap; + + typedef map<const DegreeOfFreedom*, DegreeOfFreedom> DofIndexMap; + + /// Mapps a boundar type, i.e., a boundary identifier index, to a periodic + /// DOF mapping. + typedef map<BoundaryType, DofMapping> PeriodicDofMap; + + typedef vector<MeshStructure> MeshCodeVec; +} + +#endif diff --git a/AMDiS/src/parallel/PetscSolverFeti.cc b/AMDiS/src/parallel/PetscSolverFeti.cc index f7b9ef62dc3a8081a83633570627b64b4ade01d3..359ce100b06e7e00f49b3e512582cbf96c558de6 100644 --- a/AMDiS/src/parallel/PetscSolverFeti.cc +++ b/AMDiS/src/parallel/PetscSolverFeti.cc @@ -20,6 +20,45 @@ namespace AMDiS { #ifdef HAVE_PETSC_DEV + void PetscSolverFeti::updateDofData(int nComponents) + { + FUNCNAME("PetscSolverFeti::updateDofData()"); + + definePrimals(); + } + + + void PetscSolverFeti::definePrimals() + { + FUNCNAME("PetscSolverFeti::definePrimals()"); + + TEST_EXIT_DBG(meshDistributor->getMesh()->getDim() == 2) + ("Works for 2D problems only!"); + + primals = meshDistributor->getBoundaryDofInfo().geoDofs[VERTEX]; + globalPrimalIndex.clear(); + + int nRankPrimals = 0; + for (DofContainerSet::iterator it = primals.begin(); + it != primals.end(); ++it) + if (meshDistributor->getIsRankDof(**it)) { + globalPrimalIndex[**it] = nRankPrimals; + nRankPrimals++; + } + + int nOverallPrimals = 0, rStartPrimals = 0; + mpi::getDofNumbering(meshDistributor->getMpiComm(), + nRankPrimals, rStartPrimals, nOverallPrimals); + + for (DofMapping::iterator it = globalPrimalIndex.begin(); + it != globalPrimalIndex.end(); ++it) + it->second += rStartPrimals; + + MSG_DBG("nRankPrimals = %d nOverallPrimals = %d\n", + nRankPrimals, nOverallPrimals); + } + + void PetscSolverFeti::fillPetscMatrix(Matrix<DOFMatrix*> *mat, SystemVector *vec) { FUNCNAME("PetscSolverFeti::fillPetscMatrix()"); diff --git a/AMDiS/src/parallel/PetscSolverFeti.h b/AMDiS/src/parallel/PetscSolverFeti.h index 4dfcb4e0f7562daafcdd722a77c72d7c0cc64659..07479356b3c1490cbf15a3c42f710944201f611d 100644 --- a/AMDiS/src/parallel/PetscSolverFeti.h +++ b/AMDiS/src/parallel/PetscSolverFeti.h @@ -21,6 +21,7 @@ /** \file PetscSolverFeti.h */ #include "parallel/PetscSolver.h" +#include "parallel/ParallelTypes.h" #ifndef AMDIS_PETSC_SOLVER_FETI_H #define AMDIS_PETSC_SOLVER_FETI_H @@ -41,6 +42,23 @@ namespace AMDiS { void fillPetscMatrix(Matrix<DOFMatrix*> *mat, SystemVector *vec); void solvePetscMatrix(SystemVector &vec, AdaptInfo *adaptInfo); + + Flag getBoundaryDofRequirement() + { + return + MeshDistributor::BOUNDARY_SUBOBJ_SORTED | + MeshDistributor::BOUNDARY_FILL_INFO_SEND_DOFS | + MeshDistributor::BOUNDARY_FILL_INFO_RECV_DOFS; + } + protected: + void updateDofData(int nComponents); + + void definePrimals(); + + protected: + DofContainerSet primals; + + DofMapping globalPrimalIndex; }; #endif diff --git a/AMDiS/src/parallel/PetscSolverSchur.h b/AMDiS/src/parallel/PetscSolverSchur.h index 2b7f68cb52fb2333f408907b9cc43ea61da1230c..8f9034f3ec6ca4fc78f400bed24acf0c65c9b167 100644 --- a/AMDiS/src/parallel/PetscSolverSchur.h +++ b/AMDiS/src/parallel/PetscSolverSchur.h @@ -44,7 +44,9 @@ namespace AMDiS { Flag getBoundaryDofRequirement() { - return MeshDistributor::BOUNDARY_SUBOBJ_SORTED; + return + MeshDistributor::BOUNDARY_SUBOBJ_SORTED | + MeshDistributor::BOUNDARY_FILL_INFO_SEND_DOFS; } protected: