99 PRECICE_DEBUG(
"Handle partition data structures for serial participant");
106 PRECICE_CHECK(!
_bb.empty(),
"You are running this participant in serial mode and the bounding box on mesh \"{}\", is empty. Did you call setMeshAccessRegion with valid data?",
_mesh->getName());
110 unsigned int nFilteredVertices =
_mesh->nVertices() - nVerticesInBox;
113 "{} vertices on mesh \"{}\" have been filtered out due to the defined bounding box in \"setMeshAccessRegion\" "
114 "in serial mode. For direct-mesh access via \"getMeshVertexCoordinatesAndIDs()\", these vertices are not accessible. "
115 "Their data values will internally be filled with zero values in order to provide valid data for other participants when reading data.",
116 nFilteredVertices,
_mesh->getName());
120 int vertexCounter = 0;
123 vertexDistribution[0].push_back(vertexCounter);
127 _mesh->setVertexDistribution(std::move(vertexDistribution));
129 _mesh->setVertexOffsets({vertexCounter});
136 "The received mesh {} needs a mapping (either from it, to it, or both) or API access enabled (api-access=\"true\"). Maybe you don't want to receive this mesh at all?",
164 PRECICE_DEBUG(
"Mapping filter, filtered from {} to {} vertices, {} to {} edges, and {} to {} triangles.",
166 _mesh->edges().size(), filteredMesh.
edges().size(),
170 _mesh->addMesh(filteredMesh);
174 if (
m2n().usesTwoLevelInitialization()) {
185 for (
size_t vertexIndex = 0; vertexIndex <
_mesh->nVertices(); ++vertexIndex) {
186 for (
size_t rankIndex = 0; rankIndex <
_mesh->getConnectedRanks().size(); ++rankIndex) {
187 int globalVertexIndex =
_mesh->vertex(vertexIndex).getGlobalIndex();
189 int remoteRank =
_mesh->getConnectedRanks()[rankIndex];
191 _mesh->getCommunicationMap()[remoteRank].push_back(vertexIndex);
204 int numberOfVertices =
_mesh->nVertices();
205 std::vector<VertexID> vertexIDs(numberOfVertices, -1);
206 for (
int i = 0; i < numberOfVertices; i++) {
207 vertexIDs[i] =
_mesh->vertex(i).getGlobalIndex();
213 int numberOfVertices =
_mesh->nVertices();
214 std::vector<VertexID> vertexIDs(numberOfVertices, -1);
215 for (
int i = 0; i < numberOfVertices; i++) {
216 vertexIDs[i] =
_mesh->vertex(i).getGlobalIndex();
218 vertexDistribution[0] = std::move(vertexIDs);
221 PRECICE_DEBUG(
"Receive partition feedback from the secondary rank {}", secondaryRank);
225 _mesh->setVertexDistribution(std::move(vertexDistribution));
235 int numberOfVertices =
_mesh->nVertices();
243 _mesh->setVertexOffsets(std::move(vertexOffsets));
248 vertexOffsets[0] =
_mesh->nVertices();
252 int numberOfSecondaryRankVertices = -1;
255 vertexOffsets[secondaryRank] = numberOfSecondaryRankVertices + vertexOffsets[secondaryRank - 1];
262 _mesh->setVertexOffsets(std::move(vertexOffsets));
387 _mesh->clearPartitioning();
395 if (not
m2n().usesTwoLevelInitialization())
399 int numberOfRemoteRanks = -1;
412 for (
int remoteRank = 0; remoteRank < numberOfRemoteRanks; remoteRank++) {
413 remoteBBMap.emplace(remoteRank, initialBB);
430 std::vector<Rank> connectedRanksList;
433 std::vector<Rank> connectedRanks;
434 for (
auto &remoteBB : remoteBBMap) {
435 if (
_bb.overlapping(remoteBB.second)) {
436 connectedRanks.push_back(remoteBB.first);
440 _mesh->setConnectedRanks(connectedRanks);
441 if (not connectedRanks.empty()) {
442 connectionMap.emplace(0, std::move(connectedRanks));
443 connectedRanksList.push_back(0);
449 if (!secondaryConnectedRanks.empty()) {
450 connectedRanksList.push_back(rank);
451 connectionMap.emplace(rank, std::move(secondaryConnectedRanks));
458 "The mesh \"{}\" of this participant seems to have no partitions at the coupling interface. "
459 "Check that both mapped meshes are describing the same geometry. "
460 "If you deal with very different mesh resolutions, consider increasing the safety-factor in the <receive-mesh /> tag.",
466 std::vector<Rank> connectedRanks;
467 for (
const auto &remoteBB : remoteBBMap) {
468 if (
_bb.overlapping(remoteBB.second)) {
469 connectedRanks.push_back(remoteBB.first);
473 _mesh->setConnectedRanks(connectedRanks);
553 if (
m2n().usesTwoLevelInitialization()) {
585 std::vector<VertexID> sharedVerticesGlobalIDs;
587 std::vector<VertexID> sharedVerticesLocalIDs;
598 localBBMap.at(0) =
_bb;
618 for (
const auto &localBB : localBBMap) {
619 if (
_bb.overlapping(localBB.second)) {
620 localConnectedBBMap.emplace(localBB.first, localBB.second);
629 for (
auto &neighborRank : localConnectedBBMap)
630 sharedVerticesSendMap[neighborRank.first] = std::vector<VertexID>();
633 const int numberOfVertices =
_mesh->nVertices();
634 PRECICE_DEBUG(
"Tag vertices, number of vertices {}", numberOfVertices);
635 std::vector<int> tags(numberOfVertices, 1);
636 std::vector<VertexID> globalIDs(numberOfVertices, -1);
637 int ownedVerticesCount = 0;
638 for (
int i = 0; i < numberOfVertices; i++) {
639 globalIDs[i] =
_mesh->vertex(i).getGlobalIndex();
640 if (
_mesh->vertex(i).isTagged()) {
641 bool vertexIsShared =
false;
642 for (
const auto &neighborRank : localConnectedBBMap) {
643 if (neighborRank.second.contains(
_mesh->vertex(i))) {
644 vertexIsShared =
true;
645 sharedVerticesSendMap[neighborRank.first].push_back(globalIDs[i]);
649 if (not vertexIsShared) {
651 ownedVerticesCount++;
653 sharedVerticesGlobalIDs.push_back(globalIDs[i]);
654 sharedVerticesLocalIDs.push_back(i);
664 std::vector<com::PtrRequest> vertexNumberRequests;
667 std::map<int, int> neighborRanksVertexCount;
668 for (
auto &neighborRank : localConnectedBBMap) {
669 neighborRanksVertexCount.emplace(neighborRank.first, 0);
673 for (
auto &neighborRank : localConnectedBBMap) {
675 vertexNumberRequests.push_back(request);
679 for (
auto &neighborRank : localConnectedBBMap) {
684 for (
auto &rqst : vertexNumberRequests) {
690 std::vector<com::PtrRequest> vertexListRequests;
691 vertexListRequests.reserve(2 * sharedVerticesSendMap.size());
693 std::vector<int> vertexListSizeSendBuffers;
694 vertexListSizeSendBuffers.reserve(sharedVerticesSendMap.size());
696 for (
auto &receivingRank : sharedVerticesSendMap) {
697 vertexListSizeSendBuffers.push_back(
static_cast<int>(receivingRank.second.size()));
699 vertexListRequests.push_back(request);
700 if (vertexListSizeSendBuffers.back() != 0) {
702 vertexListRequests.push_back(request);
706 for (
auto &neighborRank : sharedVerticesSendMap) {
709 if (receiveSize != 0) {
710 std::vector<int> receivedSharedVertices(receiveSize, -1);
712 sharedVerticesReceiveMap.insert(std::make_pair(neighborRank.first, receivedSharedVertices));
717 for (
auto &rqst : vertexListRequests) {
727 for (
auto &sharingRank : sharedVerticesReceiveMap) {
731 if ((ownedVerticesCount > neighborRanksVertexCount[sharingRank.first]) ||
732 (ownedVerticesCount == neighborRanksVertexCount[sharingRank.first] &&
utils::IntraComm::getRank() > sharingRank.first)) {
738 std::vector<int> res;
740 sharingRank.second.begin(), sharingRank.second.end(), std::back_inserter(res));
742 tags[sharedVerticesLocalIDs[r]] =
static_cast<int>(
false);
747 PRECICE_DEBUG(
"{} of {} vertices of mesh {} have been filtered out on rank {} since they have no influence on the mapping.",
752 int numberOfVertices =
_mesh->nVertices();
755 if (numberOfVertices != 0) {
756 PRECICE_DEBUG(
"Tag vertices, number of vertices {}", numberOfVertices);
757 std::vector<int> tags(numberOfVertices, -1);
758 std::vector<VertexID> globalIDs(numberOfVertices, -1);
759 bool atInterface =
false;
760 for (
int i = 0; i < numberOfVertices; i++) {
761 globalIDs[i] =
_mesh->vertex(i).getGlobalIndex();
762 if (
_mesh->vertex(i).isTagged()) {
779 PRECICE_ASSERT(ownerVec.size() ==
static_cast<std::size_t
>(numberOfVertices));
786 std::vector<VertexID> globalOwnerVec(
_mesh->getGlobalNumberOfVertices(), 0);
796 bool primaryRankAtInterface =
false;
797 secondaryOwnerVecs[0].resize(
_mesh->nVertices());
798 secondaryGlobalIDs[0].resize(
_mesh->nVertices());
799 secondaryTags[0].resize(
_mesh->nVertices());
800 for (
size_t i = 0; i <
_mesh->nVertices(); i++) {
801 secondaryGlobalIDs[0][i] =
_mesh->vertex(i).getGlobalIndex();
802 if (
_mesh->vertex(i).isTagged()) {
803 primaryRankAtInterface =
true;
804 secondaryTags[0][i] = 1;
806 secondaryTags[0][i] = 0;
812 Rank ranksAtInterface = 0;
813 if (primaryRankAtInterface)
817 int localNumberOfVertices = -1;
819 PRECICE_DEBUG(
"Rank {} has {} vertices.", rank, localNumberOfVertices);
820 secondaryOwnerVecs[rank].resize(localNumberOfVertices, 0);
822 if (localNumberOfVertices != 0) {
826 PRECICE_DEBUG(
"Rank {} has tags {}", rank, secondaryTags[rank]);
827 PRECICE_DEBUG(
"Rank {} has global IDs {}", rank, secondaryGlobalIDs[rank]);
828 bool atInterface =
false;
836 PRECICE_DEBUG(
"Decide owners, first round by rough load balancing");
839 "After repartitioning of mesh \"{}\" all ranks are empty. "
840 "Please check the dimensions of the provided bounding box "
841 "(in \"setMeshAccessRegion\") and verify that it covers vertices "
842 "in the mesh or check the definition of the provided meshes.",
845 int localGuess =
_mesh->getGlobalNumberOfVertices() / ranksAtInterface;
849 for (
size_t i = 0; i < secondaryOwnerVecs[rank].size(); i++) {
851 if (globalOwnerVec[secondaryGlobalIDs[rank][i]] == 0 && secondaryTags[rank][i] == 1) {
852 secondaryOwnerVecs[rank][i] = 1;
853 globalOwnerVec[secondaryGlobalIDs[rank][i]] = 1;
855 if (counter == localGuess)
864 for (
size_t i = 0; i < secondaryOwnerVecs[rank].size(); i++) {
865 if (globalOwnerVec[secondaryGlobalIDs[rank][i]] == 0 && secondaryTags[rank][i] == 1) {
866 secondaryOwnerVecs[rank][i] = 1;
867 globalOwnerVec[secondaryGlobalIDs[rank][i]] = rank + 1;
874 if (not secondaryTags[rank].empty()) {
875 PRECICE_DEBUG(
"Send owner information to secondary rank {}", rank);
880 PRECICE_DEBUG(
"My owner information: {}", secondaryOwnerVecs[0]);
884 for (
size_t i = 0; i < globalOwnerVec.size(); i++) {
886 "The Vertex with global index {} of mesh: {} was completely filtered out, since it has no influence on any mapping.",
887 i,
_mesh->getName());
890 auto filteredVertices = std::count(globalOwnerVec.begin(), globalOwnerVec.end(), 0);
892 "{} of {} vertices of mesh {} have been filtered out since they have no influence on the mapping.{}",
893 filteredVertices,
_mesh->getGlobalNumberOfVertices(),
_mesh->getName(),
894 _allowDirectAccess ?
" Associated data values of the filtered vertices will be filled with zero values in order to "
895 "provide valid data for other participants when reading data."