diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index 82895be047874dad587ec48d901755c0117d78c2..c540d1b6a9cf03107ac88e96b994fb363a7d006a 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -1854,7 +1854,7 @@ namespace AMDiS { StdMpi<vector<int> > stdMpi(mpiComm, false); - // === Each rank traverse its periodic boundaries and sends the dof indices === + // === Each rank traverse its periodic boundaries and sends the DOF indices === // === to the rank "on the other side" of the periodic boundary. === RankToDofContainer rankPeriodicDofs; @@ -1863,8 +1863,6 @@ 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"); @@ -1876,10 +1874,6 @@ 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; @@ -1891,8 +1885,6 @@ 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); } } } @@ -1904,22 +1896,11 @@ 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++) { -// WorldVector<double> c; -// mesh->getDofIndexCoords(*(dofs[nDofs + i]), feSpace, c); -// MSG(" SEND i = %d DOF = %d (%f %f %f)\n", nDofs + i, mapLocalGlobalDofs[*(dofs[nDofs + i])], c[0], c[1], c[2]); + for (unsigned int i = 0; i < (dofs.size() - nDofs); i++) rankToDofType[it->first].push_back(boundIt->type); - } } // Send the global indices to the rank on the other side. @@ -1944,9 +1925,6 @@ 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]; vector<int>& types = rankToDofType[it->first]; @@ -1958,25 +1936,68 @@ namespace AMDiS { int mapGlobalDofIndex = stdMpi.getRecvData(it->first)[i]; BoundaryType type = types[i]; -// WorldVector<double> c; -// mesh->getDofIndexCoords(*(dofs[i]), feSpace, c); -// MSG(" RECV i = %d DOF = %d (%f %f %f)\n", i, *(dofs[i]), c[0], c[1], c[2]); - - // 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); } } } + + StdMpi<PeriodicDofMap> stdMpi2(mpiComm); + + + + for (RankToBoundMap::iterator it = periodicBoundary.boundary.begin(); + it != periodicBoundary.boundary.end(); ++it) { + if (it->first == mpiRank) + continue; + + PeriodicDofMap perObjMap; + + for (vector<AtomicBoundary>::iterator boundIt = it->second.begin(); + boundIt != it->second.end(); ++boundIt) { + if (boundIt->type >= -3) + continue; + + DofContainer dofs; + boundIt->rankObj.el->getVertexDofs(feSpace, boundIt->rankObj, dofs); + boundIt->rankObj.el->getNonVertexDofs(feSpace, boundIt->rankObj, dofs); + + for (unsigned int i = 0; i < dofs.size(); i++) { + DegreeOfFreedom globalDof = mapLocalGlobalDofs[*dofs[i]]; + + for (std::set<BoundaryType>::iterator perAscIt = periodicDofAssociations[globalDof].begin(); + perAscIt != periodicDofAssociations[globalDof].end(); ++perAscIt) + if (*perAscIt >= -3) { + TEST_EXIT_DBG(periodicDof[*perAscIt].count(globalDof) == 1) + ("Should not happen!\n"); + perObjMap[*perAscIt][globalDof] = periodicDof[*perAscIt][globalDof]; + } + } + } + + stdMpi2.send(it->first, perObjMap); + stdMpi2.recv(it->first); + } + + stdMpi2.startCommunication<int>(MPI_INT); + + for (std::map<int, PeriodicDofMap>::iterator it = stdMpi2.getRecvData().begin(); + it != stdMpi2.getRecvData().end(); ++it) + for (PeriodicDofMap::iterator perIt = it->second.begin(); + perIt != it->second.end(); ++perIt) + for (DofMapping::iterator dofIt = perIt->second.begin(); + dofIt != perIt->second.end(); ++dofIt) { + TEST_EXIT_DBG(periodicDof[perIt->first].count(dofIt->second) == 0 || + periodicDof[perIt->first][dofIt->second] == dofIt->first) + ("Should not happen!\n"); + + periodicDof[perIt->first][dofIt->second] = dofIt->first; + } + #if (DEBUG != 0) ParallelDebug::testPeriodicBoundary(*this); #endif diff --git a/AMDiS/src/parallel/PetscSolver.cc b/AMDiS/src/parallel/PetscSolver.cc index ead30d480e9307c379f421626942a57988fddc30..6a2a23d1a02f9697651c37ffa54897a8821fb9df 100644 --- a/AMDiS/src/parallel/PetscSolver.cc +++ b/AMDiS/src/parallel/PetscSolver.cc @@ -56,52 +56,6 @@ namespace AMDiS { TEST_EXIT(mat)("No DOFMatrix!\n"); - typedef map<DegreeOfFreedom, DegreeOfFreedom> DofMapping; - typedef map<BoundaryType, DofMapping> PeriodicDofMap; - - StdMpi<PeriodicDofMap> stdMpi(meshDistributor->getMpiComm()); - if (meshDistributor->getMpiRank() == 0) { - for (int i = 1; i < meshDistributor->getMpiSize(); i++) - stdMpi.recv(i); - } else { - stdMpi.send(0, meshDistributor->getPeriodicMapping()); - } - stdMpi.startCommunication<int>(MPI_INT); - - - - StdMpi<PeriodicDofMap> stdMpi2(meshDistributor->getMpiComm()); - PeriodicDofMap overallDofMap; - - if (meshDistributor->getMpiRank() == 0) { - overallDofMap = meshDistributor->getPeriodicMapping(); - for (int i = 1; i < meshDistributor->getMpiSize(); i++) { - PeriodicDofMap &rankDofMap = stdMpi.getRecvData(i); - for (PeriodicDofMap::iterator it = rankDofMap.begin(); it != rankDofMap.end(); ++it) { - for (DofMapping::iterator dofIt = it->second.begin(); dofIt != it->second.end(); ++dofIt) { - if (overallDofMap[it->first].count(dofIt->first) == 1) { - TEST_EXIT_DBG(overallDofMap[it->first][dofIt->first] == dofIt->second) - ("Should not happen!\n"); - } else { - overallDofMap[it->first][dofIt->first] = dofIt->second; - } - } - } - } - - for (int i = 1; i < meshDistributor->getMpiSize(); i++) - stdMpi2.send(i, overallDofMap); - } else { - stdMpi2.recv(0); - } - - - stdMpi2.startCommunication<int>(MPI_INT); - - if (meshDistributor->getMpiRank() > 0) - overallDofMap = stdMpi2.getRecvData(0); - - using mtl::tag::row; using mtl::tag::nz; using mtl::begin; using mtl::end; namespace traits= mtl::traits; typedef DOFMatrix::base_matrix_type Matrix; @@ -134,6 +88,9 @@ namespace AMDiS { // Calculate petsc row index. int rowIndex = globalRowDof * dispMult + dispAddRow; + cols.clear(); + values.clear(); + for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); icursor != icend; ++icursor) { @@ -144,8 +101,8 @@ namespace AMDiS { if (!periodicCol) { // Calculate the exact position of the column index in the petsc matrix. - int colIndex = globalColDof * dispMult + dispAddCol; - MatSetValue(petscMatrix, rowIndex, colIndex, value(*icursor), ADD_VALUES); + cols.push_back(globalColDof * dispMult + dispAddCol); + values.push_back(value(*icursor)); } else { std::set<int>& perColAsc = meshDistributor->getPerDofAssociations(globalColDof); std::set<int> perAsc; @@ -160,18 +117,21 @@ namespace AMDiS { for (std::set<int>::iterator it = perAsc.begin(); it != perAsc.end(); ++it) { int nCols = static_cast<int>(newCols.size()); for (int i = 0; i < nCols; i++) { - TEST_EXIT(overallDofMap[*it].count(newCols[i]) > 0)("Should not happen: %d %d\n", *it, newCols[i]); - - newCols.push_back(overallDofMap[*it][newCols[i]]); + TEST_EXIT(meshDistributor->isPeriodicDof(*it, newCols[i])) + ("Should not happen: %d %d\n", *it, newCols[i]); + newCols.push_back(meshDistributor->getPeriodicMapping(*it, newCols[i])); } } for (int i = 0; i < newCols.size(); i++) { - int colIndex = newCols[i] * dispMult + dispAddCol; - MatSetValue(petscMatrix, rowIndex, colIndex, scaledValue, ADD_VALUES); + cols.push_back(newCols[i] * dispMult + dispAddCol); + values.push_back(scaledValue); } } } + + MatSetValues(petscMatrix, 1, &rowIndex, cols.size(), + &(cols[0]), &(values[0]), ADD_VALUES); } else { for (icursor_type icursor = begin<nz>(cursor), icend = end<nz>(cursor); icursor != icend; ++icursor) { @@ -198,16 +158,17 @@ namespace AMDiS { int nEntry = static_cast<int>(entry.size()); for (int i = 0; i < nEntry; i++) { int perRowDof = 0; - if (overallDofMap[*it].count(entry[i].first) > 0) - perRowDof = overallDofMap[*it][entry[i].first]; + if (meshDistributor->getPeriodicMapping()[*it].count(entry[i].first)) + perRowDof = meshDistributor->getPeriodicMapping(*it, entry[i].first); else perRowDof = entry[i].first; int perColDof; - if (overallDofMap[*it].count(entry[i].second) > 0) - perColDof = overallDofMap[*it][entry[i].second]; + if (meshDistributor->getPeriodicMapping()[*it].count(entry[i].second)) + perColDof = meshDistributor->getPeriodicMapping(*it, entry[i].second); else perColDof = entry[i].second; + entry.push_back(std::make_pair(perRowDof, perColDof)); }