25#include "voloctree_mapper.hpp"
69 :
VolumeMapper(referencePatch, mappedPatch, communicator)
83 m_partitionIR.clear();
89void VolOctreeMapper::clearPartitionMappingLists()
91 m_partitionIR.clearLists();
119 m_partitionIR.map_rank_previousMapping.clear();
122 if (info.type == adaption::Type::TYPE_PARTITION_SEND ||
123 info.type == adaption::Type::TYPE_PARTITION_RECV ||
124 info.type == adaption::Type::TYPE_PARTITION_NOTICE) {
125 throw std::runtime_error (
"Mapper: type of adation not supported : " + std::to_string(info.type));
127 if (info.type != adaption::Type::TYPE_DELETION && info.type != adaption::Type::TYPE_CREATION) {
128 for (
long id : info.previous) {
154 _mappingAdaptionReferenceUpdate(adaptionInfo, inverseFilled);
156 _mappingAdaptionMappedUpdate(adaptionInfo);
178void VolOctreeMapper::_mappingAdaptionReferenceUpdate(
const std::vector<adaption::Info> &adaptionInfo,
bool inverseFilled)
186 bool changedPartition =
false;
188 bool checkPart =
true;
191 changedPartition = _recoverPartition();
195 if (!changedPartition) {
196 for (
const adaption::Info &info : adaptionInfo) {
197 if (info.type == adaption::Type::TYPE_PARTITION_SEND ||
198 info.type == adaption::Type::TYPE_PARTITION_RECV ||
199 info.type == adaption::Type::TYPE_PARTITION_NOTICE) {
200 throw std::runtime_error (
"Mapper: type of adation not supported : " + std::to_string(info.type));
201 }
else if (
info.type == adaption::Type::TYPE_DELETION ||
202 info.type == adaption::Type::TYPE_CREATION) {
207 for (
long idprevious :
info.previous) {
210 std::size_t imapped = 0;
211 for (
long idp : mappedIds) {
215 std::vector<long>::iterator it = std::find((*mappingMapped)[idp].ids.begin(), (*mappingMapped)[idp].ids.end(), idprevious);
216 if (it != (*mappingMapped)[idp].ids.end()) {
217 (*mappingMapped)[idp].ids.erase(it);
219 int dist =
static_cast<int>(std::distance((*mappingMapped)[idp].ids.begin(), it));
220 (*mappingMapped)[idp].ranks.erase((*mappingMapped)[idp].ranks.begin()+dist);
225 mapping::Info &inverseMappingInfo = m_partitionIR.map_rank_inverseMapping[
m_previousMapping[idprevious].ranks[imapped]][idp];
226 std::vector<long>::iterator it = std::find(inverseMappingInfo.ids.begin(), inverseMappingInfo.ids.end(), idprevious);
227 if (it != inverseMappingInfo.ids.end()) {
228 int dist =
static_cast<int>(std::distance(inverseMappingInfo.ids.begin(), it));
229 inverseMappingInfo.ids.erase(it);
230 inverseMappingInfo.ranks.erase(inverseMappingInfo.ranks.begin() + dist);
242 case adaption::Type::TYPE_RENUMBERING:
244 long id =
info.current[0];
245 mapping::Info &mappingInfo = (*mappingAdapted)[id];
247 mappingInfo.ids.clear();
249 mappingInfo.entity = mapping::Entity::ENTITY_CELL;
256 const std::vector<long> &mappedIds = mappingInfo.ids;
258 std::size_t imapped = 0;
259 for (
long idp : mappedIds) {
261 if (checkPart || mappingInfo.ranks[imapped] ==
m_rank) {
263 (*mappingMapped)[idp].ids.push_back(
id);
265 (*mappingMapped)[idp].ranks.push_back(
info.rank);
267 mapping::Info &inverseMappingInfo = m_partitionIR.map_rank_inverseMapping[mappingInfo.ranks[imapped]][idp];
268 inverseMappingInfo.ids.push_back(
id);
269 inverseMappingInfo.ranks.push_back(
info.rank);
279 case adaption::Type::TYPE_REFINEMENT:
280 case adaption::Type::TYPE_COARSENING:
283 for (
long id :
info.current) {
284 mapping::Info &mappingInfo = (*mappingAdapted)[id];
286 mappingInfo.ids.clear();
288 mappingInfo.ranks.clear();
291 mappingInfo.entity = mapping::Entity::ENTITY_CELL;
294 for (
long idprevious :
info.previous) {
300 std::size_t imapped = 0;
301 for (
long mappedId : mappedIds) {
302 VolOctree::OctantInfo oinfoprev;
303 uint64_t mortonmapped;
304 uint64_t mortonlastdescmapped;
308 if (checkPart || mappedRanks[imapped] ==
m_rank) {
316 mappedRank = mappedRanks[imapped];
318 OctantIR *poct = m_partitionIR.map_rank_rec_octantIR[mappedRanks[imapped]][mappedId];
322 mappedRank = mappedRanks[imapped];
326 for (
long id :
info.current) {
329 uint64_t morton, mortonlastdesc;
331 VolOctree::OctantInfo octantIfo = adaptedPatch->
getCellOctant(
id);
336 bool checkmorton =
false;
338 checkmorton |= (morton >= mortonmapped && mortonlastdesc <= mortonlastdescmapped);
339 checkmorton |= (morton <= mortonmapped && mortonlastdesc >= mortonlastdescmapped);
342 if (level == levelmapped) {
343 mapping::Info &mappingInfo = (*mappingAdapted)[id];
344 if (mappingInfo.ids.size() == 0) {
345 mappingInfo.type = mapping::Type::TYPE_RENUMBERING;
346 mappingInfo.ids.push_back(mappedId);
348 mappingInfo.ranks.push_back(mappedRank);
353 if (checkPart || mappedRank ==
m_rank) {
355 (*mappingMapped)[mappedId].type = mapping::Type::TYPE_RENUMBERING;
356 (*mappingMapped)[mappedId].ids.clear();
357 (*mappingMapped)[mappedId].ids.push_back(
id);
359 (*mappingMapped)[mappedId].ranks.push_back(
info.rank);
361 mapping::Info &inverseMappingInfo = m_partitionIR.map_rank_inverseMapping[mappedRank][mappedId];
362 inverseMappingInfo.type = mapping::Type::TYPE_RENUMBERING;
363 inverseMappingInfo.ids.push_back(
id);
364 inverseMappingInfo.ranks.push_back(
info.rank);
369 else if (level > levelmapped) {
370 mapping::Info &mappingInfo = (*mappingAdapted)[id];
371 if (mappingInfo.ids.size() == 0) {
372 mappingInfo.type = mapping::Type::TYPE_REFINEMENT;
373 mappingInfo.ids.push_back(mappedId);
375 mappingInfo.ranks.push_back(mappedRank);
380 if (checkPart || mappedRank ==
m_rank) {
382 if (std::find((*mappingMapped)[mappedId].ids.begin(), (*mappingMapped)[mappedId].ids.end(), id) == (*mappingMapped)[mappedId].ids.end()) {
383 (*mappingMapped)[mappedId].ids.push_back(
id);
384 (*mappingMapped)[mappedId].type = mapping::Type::TYPE_COARSENING;
386 (*mappingMapped)[mappedId].ranks.push_back(
info.rank);
391 mapping::Info &inverseMappingInfo = m_partitionIR.map_rank_inverseMapping[mappedRank][mappedId];
392 inverseMappingInfo.type = mapping::Type::TYPE_COARSENING;
393 inverseMappingInfo.ids.push_back(
id);
394 inverseMappingInfo.ranks.push_back(
info.rank);
398 }
else if (level < levelmapped) {
399 mapping::Info &mappingInfo = (*mappingAdapted)[id];
400 if (std::find(mappingInfo.ids.begin(), mappingInfo.ids.end(), mappedId) == mappingInfo.ids.end()) {
401 mappingInfo.type = mapping::Type::TYPE_COARSENING;
402 mappingInfo.ids.push_back(mappedId);
404 mappingInfo.ranks.push_back(mappedRank);
409 if (checkPart || mappedRank ==
m_rank ) {
411 if ((*mappingMapped)[mappedId].ids.size() == 0) {
412 (*mappingMapped)[mappedId].type = mapping::Type::TYPE_REFINEMENT;
413 (*mappingMapped)[mappedId].ids.push_back(
id);
415 (*mappingMapped)[mappedId].ranks.push_back(
info.rank);
420 mapping::Info &inverseMappingInfo = m_partitionIR.map_rank_inverseMapping[mappedRank][mappedId];
421 if (inverseMappingInfo.ids.size() == 0) {
422 inverseMappingInfo.type = mapping::Type::TYPE_REFINEMENT;
423 inverseMappingInfo.ids.push_back(
id);
424 inverseMappingInfo.ranks.push_back(
info.rank);
448 _communicateInverseMapperBack();
462void VolOctreeMapper::_mappingAdaptionMappedUpdate(
const std::vector<adaption::Info> &adaptionInfo)
464 const VolOctree *adaptedPatch =
static_cast<const VolOctree*
>(
m_mappedPatch);
465 const VolOctree *referencePatch =
static_cast<const VolOctree*
>(
m_referencePatch);
468 PiercedStorage<mapping::Info> *mappingReference = &
m_mapping;
470 bool changedPartition =
false;
472 bool checkPart =
true;
475 changedPartition = _recoverPartition();
480 throw std::runtime_error(
"Updating mapping with adaption of mapped mesh possible only if inverse mapper is filled");
483 if (!changedPartition) {
484 std::vector<adaption::Info> adaptionInfoRef;
487 _communicateMappedAdaptionInfo(adaptionInfo, &adaptionInfoRef);
489 adaptionInfoRef = adaptionInfo;
492 adaptionInfoRef = adaptionInfo;
495 for (
const adaption::Info &info : adaptionInfoRef) {
496 if (
info.type == adaption::Type::TYPE_PARTITION_SEND ||
497 info.type == adaption::Type::TYPE_PARTITION_RECV ||
498 info.type == adaption::Type::TYPE_PARTITION_NOTICE) {
499 throw std::runtime_error (
"Mapper: type of adation not supported : " + std::to_string(
info.type));
500 }
else if (
info.type == adaption::Type::TYPE_DELETION ||
501 info.type == adaption::Type::TYPE_CREATION) {
505 for (
long idprevious :
info.previous) {
506 std::vector<long> *mappedIds;
513 mappedIds = &(m_partitionIR.map_rank_previousMapping[
info.rank][idprevious].ids);
516 for (
long idp : *mappedIds) {
517 std::vector<long>::iterator it = std::find((*mappingReference)[idp].ids.begin(), (*mappingReference)[idp].ids.end(), idprevious);
518 if (it != (*mappingReference)[idp].ids.end()) {
519 (*mappingReference)[idp].ids.erase(it);
521 int dist =
static_cast<int>(std::distance((*mappingReference)[idp].ids.begin(), it));
522 (*mappingReference)[idp].ranks.erase((*mappingReference)[idp].ranks.begin()+dist);
529 if (
info.type == adaption::Type::TYPE_RENUMBERING) {
530 long id =
info.current[0];
531 mapping::Info &mappingInfo = (*mappingAdapted)[id];
533 std::vector<long> *mappedIds;
537 mappingInfo.ids.clear();
539 mappingInfo.entity = mapping::Entity::ENTITY_CELL;
541 mappedIds = &(mappingInfo.ids);
545 for (
long _idp :
info.previous) {
546 if (m_partitionIR.map_rank_inverseMapping[
info.rank].count(_idp)) {
547 m_partitionIR.map_rank_inverseMapping[
info.rank].erase(_idp);
551 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ids.clear();
552 m_partitionIR.map_rank_inverseMapping[
info.rank][id].type = m_partitionIR.map_rank_previousMapping[
info.rank][
info.previous[0]].type;
553 m_partitionIR.map_rank_inverseMapping[
info.rank][id].entity = mapping::Entity::ENTITY_CELL;
554 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ids = m_partitionIR.map_rank_previousMapping[
info.rank][
info.previous[0]].ids;
555 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ranks = m_partitionIR.map_rank_previousMapping[
info.rank][
info.previous[0]].ranks;
556 mappedIds = &(m_partitionIR.map_rank_inverseMapping[
info.rank][id].ids);
559 for (
long idp : *mappedIds) {
560 (*mappingReference)[idp].ids.push_back(
id);
562 (*mappingReference)[idp].ranks.push_back(
info.rank);
568 if (
info.type == adaption::Type::TYPE_REFINEMENT ||
info.type == adaption::Type::TYPE_COARSENING) {
570 for (
long id :
info.current) {
574 mapping::Info &mappingInfo = (*mappingAdapted)[id];
575 mappingInfo.ids.clear();
576 mappingInfo.entity = mapping::Entity::ENTITY_CELL;
578 mappingInfo.ranks.clear();
580 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ids.clear();
581 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ranks.clear();
582 m_partitionIR.map_rank_inverseMapping[
info.rank][id].entity = mapping::Entity::ENTITY_CELL;
587 for (
long idprevious :
info.previous) {
588 std::vector<long> *mappedIds;
590 std::vector<int> *mappedRanks;
597 mappedIds = &(m_partitionIR.map_rank_previousMapping[
info.rank][idprevious].ids);
598 mappedRanks = &(m_partitionIR.map_rank_previousMapping[
info.rank][idprevious].ranks);
601 std::size_t icount = 0;
602 for (
long mappedId : *mappedIds) {
603 VolOctree::OctantInfo oinfoprev = referencePatch->getCellOctant(mappedId);
604 const Octant *octant = referencePatch->getOctantPointer(oinfoprev);
605 uint64_t mortonreference = referencePatch->getTree().getMorton(octant);
606 uint64_t mortonlastdescreference = referencePatch->getTree().getLastDescMorton(octant);
607 uint8_t levelreference = referencePatch->getCellLevel(mappedId);
610 int mappedRank = (*mappedRanks)[icount];
612 for (
long id :
info.current) {
615 uint64_t morton, mortonlastdesc;
619 level = adaptedPatch->getCellLevel(
id);
620 VolOctree::OctantInfo octantIfo = adaptedPatch->getCellOctant(
id);
621 const Octant *octant = adaptedPatch->getOctantPointer(octantIfo);
622 morton = adaptedPatch->getTree().getMorton(octant);
623 mortonlastdesc = adaptedPatch->getTree().getLastDescMorton(octant);
626 OctantIR *octantIR = m_partitionIR.map_rank_rec_octantIR[
info.rank][id];
627 level = octantIR->octant.getLevel();
628 morton = adaptedPatch->getTree().getMorton(&octantIR->octant);
629 mortonlastdesc = adaptedPatch->getTree().getLastDescMorton(&octantIR->octant);
633 bool checkmorton =
false;
635 checkmorton |= (morton >= mortonreference && mortonlastdesc <= mortonlastdescreference);
636 checkmorton |= (morton <= mortonreference && mortonlastdesc >= mortonlastdescreference);
640 if (level == levelreference) {
644 mapping::Info &mappingInfo = (*mappingAdapted)[id];
645 if (mappingInfo.ids.size() == 0) {
646 mappingInfo.type = mapping::Type::TYPE_RENUMBERING;
647 mappingInfo.ids.push_back(mappedId);
649 mappingInfo.ranks.push_back(
info.rank);
654 if (m_partitionIR.map_rank_inverseMapping[
info.rank][
id].ids.size() == 0) {
655 m_partitionIR.map_rank_inverseMapping[
info.rank][id].type = mapping::Type::TYPE_RENUMBERING;
656 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ids.push_back(mappedId);
657 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ranks.push_back(mappedRank);
661 (*mappingReference)[mappedId].type = mapping::Type::TYPE_RENUMBERING;
662 (*mappingReference)[mappedId].ids.clear();
663 (*mappingReference)[mappedId].ids.push_back(
id);
665 (*mappingReference)[mappedId].ranks.push_back(
info.rank);
667 }
else if (level > levelreference) {
671 mapping::Info &mappingInfo = (*mappingAdapted)[id];
672 if (mappingInfo.ids.size() == 0) {
673 mappingInfo.type = mapping::Type::TYPE_REFINEMENT;
674 mappingInfo.ids.push_back(mappedId);
676 mappingInfo.ranks.push_back(mappedRank);
681 if (m_partitionIR.map_rank_inverseMapping[
info.rank][
id].ids.size() == 0) {
682 m_partitionIR.map_rank_inverseMapping[
info.rank][id].type = mapping::Type::TYPE_REFINEMENT;
683 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ids.push_back(mappedId);
684 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ranks.push_back(mappedRank);
688 if (std::find((*mappingReference)[mappedId].ids.begin(), (*mappingReference)[mappedId].ids.end(), id) == (*mappingReference)[mappedId].ids.end()) {
689 (*mappingReference)[mappedId].ids.push_back(
id);
690 (*mappingReference)[mappedId].type = mapping::Type::TYPE_COARSENING;
692 (*mappingReference)[mappedId].ranks.push_back(
info.rank);
695 }
else if (level < levelreference) {
699 mapping::Info &mappingInfo = (*mappingAdapted)[id];
700 if (std::find(mappingInfo.ids.begin(), mappingInfo.ids.end(), mappedId) == mappingInfo.ids.end()) {
701 mappingInfo.type = mapping::Type::TYPE_COARSENING;
702 mappingInfo.ids.push_back(mappedId);
704 mappingInfo.ranks.push_back(mappedRank);
709 if (std::find(m_partitionIR.map_rank_inverseMapping[
info.rank][
id].ids.begin(), m_partitionIR.map_rank_inverseMapping[
info.rank][id].ids.end(), mappedId) == m_partitionIR.map_rank_inverseMapping[
info.rank][
id].ids.end()) {
710 m_partitionIR.map_rank_inverseMapping[
info.rank][id].type = mapping::Type::TYPE_COARSENING;
711 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ids.push_back(mappedId);
712 m_partitionIR.map_rank_inverseMapping[
info.rank][id].ranks.push_back(mappedRank);
716 if ((*mappingReference)[mappedId].ids.size() == 0) {
717 (*mappingReference)[mappedId].type = mapping::Type::TYPE_REFINEMENT;
718 (*mappingReference)[mappedId].ids.push_back(
id);
720 (*mappingReference)[mappedId].ranks.push_back(
info.rank);
735 _communicateInverseMapperBack();
754 std::unordered_map<int, std::vector<long>> received;
756 for (OctantIR octir : m_partitionIR.list_rec_octantIR_before) {
757 received[octir.rank].push_back(octir.id);
760 for (OctantIR octir : m_partitionIR.list_rec_octantIR_after) {
761 received[octir.rank].push_back(octir.id);
777 std::unordered_map<int, std::vector<long>> sent;
780 std::unordered_map<int, std::set<long>> rankIdSend;
783 long id = cell.getId();
785 for (
int rank : info.ranks) {
787 rankIdSend[rank].insert(
id);
792 for (
const auto & rankId : rankIdSend) {
793 sent[rankId.first].assign(rankId.second.begin(), rankId.second.end());
809 std::unordered_map<int, std::vector<long>> received;
816 std::unordered_map<int, std::set<long>> rankIdRecv;
819 long id = cell.getId();
821 std::size_t idsSize = info.ids.size();
822 for (std::size_t i = 0; i < idsSize; ++i) {
824 rankIdRecv[info.ranks[i]].insert(info.ids[i]);
829 for (
const auto & rankId : rankIdRecv) {
830 received[rankId.first].assign(rankId.second.begin(), rankId.second.end());
846 std::unordered_map<int, std::vector<long>> sent;
848 for (OctantIR octir : m_partitionIR.list_sent_octantIR) {
849 sent[octir.rank].push_back(octir.id);
866void VolOctreeMapper::_mapMeshes(
bool fillInverse)
875 throw std::runtime_error (
"mesh mapper: different domain of VolOctree meshes not allowed.");
893 _mapMeshesSamePartition(
nullptr,
nullptr, fillInverse, &indRef);
900 _mapMeshesSamePartition(
nullptr,
nullptr, fillInverse, &indRef);
902 _mapMeshPartitioned(fillInverse);
925void VolOctreeMapper::_mapMeshesSamePartition(
const std::vector<OctantIR> *octantsIRReference,
const std::vector<OctantIR> *octantsIRMapped,
926 bool fillInverse,
long *indRef)
933 bool localMapped =
false;
936 std::vector<OctantIR> tempOctantsIRReference;
937 if (!octantsIRReference) {
939 tempOctantsIRReference.reserve(n);
940 for (
long i = 0; i < n; i++) {
941 VolOctree::OctantInfo octantIfoRef(i,
true);
943 long idRef = referencePatch->
getOctantId(octantIfoRef);
945 tempOctantsIRReference.emplace_back(*octRef, idRef, idRef,
m_rank);
947 tempOctantsIRReference.emplace_back(*octRef, idRef, idRef);
950 octantsIRReference = &tempOctantsIRReference;
953 std::vector<OctantIR> tempOctantsIRMapped;
954 if (!octantsIRMapped) {
956 tempOctantsIRMapped.reserve(n);
957 for (
long i = 0; i < n; i++) {
958 VolOctree::OctantInfo octantIfoMap(i,
true);
960 long idMap = mappedPatch->
getOctantId(octantIfoMap);
962 tempOctantsIRMapped.emplace_back(*octMap, idMap, idMap,
m_rank);
964 tempOctantsIRMapped.emplace_back(*octMap, idMap, idMap);
967 octantsIRMapped = &tempOctantsIRMapped;
979 long nRef = octantsIRReference->size();
980 long nMap = octantsIRMapped->size();
983 if (*indRef < nRef && nMap > 0) {
986 uint64_t morton = referencePatch->
getTree().
getMorton(&octantsIRReference->at(*indRef).octant);
988 for (indMap = 0; indMap < nMap; ++indMap) {
990 if (mortonMapLastdesc >= morton) {
996 std::unordered_map<long, mapping::Info> inverseGlobalMapping;
997 while (*indRef < nRef && indMap < nMap) {
998 long idRef = octantsIRReference->at(*indRef).id;
999 long idMap = octantsIRMapped->at(indMap).id;
1000 long gidMap = octantsIRMapped->at(indMap).globalId;
1001#if BITPIT_ENABLE_MPI
1002 int rank = octantsIRMapped->at(indMap).rank;
1005 m_mapping[idRef].entity = mapping::Entity::ENTITY_CELL;
1007 inverseGlobalMapping[gidMap].entity = mapping::Entity::ENTITY_CELL;
1010 if (octantsIRMapped->at(indMap).octant.getLevel() == octantsIRReference->at(*indRef).octant.getLevel()) {
1012 m_mapping[idRef].type = mapping::Type::TYPE_RENUMBERING;
1013#if BITPIT_ENABLE_MPI
1017 inverseGlobalMapping[gidMap].ids.push_back(idRef);
1018 inverseGlobalMapping[gidMap].type = mapping::Type::TYPE_RENUMBERING;
1019#if BITPIT_ENABLE_MPI
1020 inverseGlobalMapping[gidMap].ranks.push_back(
m_rank);
1026 else if (octantsIRMapped->at(indMap).octant.getLevel() > octantsIRReference->at(*indRef).octant.getLevel()) {
1027 m_mapping[idRef].type = mapping::Type::TYPE_COARSENING;
1030 uint64_t mortonMap = mappedPatch->
getTree().
getMorton(&octantsIRMapped->at(indMap).octant);
1032 while(mortonMap <= mortonlastdesc) {
1034#if BITPIT_ENABLE_MPI
1038 inverseGlobalMapping[gidMap].type = mapping::Type::TYPE_REFINEMENT;
1039 inverseGlobalMapping[gidMap].ids.push_back(idRef);
1040#if BITPIT_ENABLE_MPI
1041 inverseGlobalMapping[gidMap].ranks.push_back(
m_rank);
1045 if (indMap == nMap) {
1048 idMap = octantsIRMapped->at(indMap).id;
1049 gidMap = octantsIRMapped->at(indMap).globalId;
1050#if BITPIT_ENABLE_MPI
1051 rank = octantsIRMapped->at(indMap).rank;
1053 mortonMap = mappedPatch->
getTree().
getMorton(&octantsIRMapped->at(indMap).octant);
1056 if (mortonMapLastDesc >= mortonlastdesc) {
1060 else if (octantsIRMapped->at(indMap).octant.getLevel() < octantsIRReference->at(*indRef).octant.getLevel()) {
1062 uint64_t morton = referencePatch->
getTree().
getMorton(&octantsIRReference->at(*indRef).octant);
1066 inverseGlobalMapping[gidMap].type = mapping::Type::TYPE_COARSENING;
1069 while (morton <= mortonlastdescmesh) {
1070 m_mapping[idRef].type = mapping::Type::TYPE_REFINEMENT;
1072#if BITPIT_ENABLE_MPI
1076 inverseGlobalMapping[gidMap].ids.push_back(idRef);
1077#if BITPIT_ENABLE_MPI
1078 inverseGlobalMapping[gidMap].ranks.push_back(
m_rank);
1082 if (*indRef == nRef) {
1085 morton = referencePatch->
getTree().
getMorton(&octantsIRReference->at(*indRef).octant);
1086 idRef = octantsIRReference->at(*indRef).id;
1094 std::unordered_map<long, mapping::Info> inverseLocalMapping;
1095#if BITPIT_ENABLE_MPI
1097 _communicateInverseMapper(octantsIRMapped, inverseGlobalMapping, &inverseLocalMapping);
1099 inverseGlobalMapping.swap(inverseLocalMapping);
1102 inverseGlobalMapping.swap(inverseLocalMapping);
1105 for (
const auto &mappingEntry : inverseLocalMapping) {
1107 for (
long inverseMappedId : mappingEntry.second.ids){
1110#if BITPIT_ENABLE_MPI
1111 for (
int inverseMappedRank : mappingEntry.second.ranks){
1119#if BITPIT_ENABLE_MPI
1129 std::vector<uint64_t> partitionMapped =
static_cast<const VolOctree*
>(
m_mappedPatch)->getTree().getPartitionLastDesc();
1130 std::vector<uint64_t> partitionReference =
static_cast<const VolOctree*
>(
m_referencePatch)->getTree().getPartitionLastDesc();
1131 for (
int rank = 0; rank <
m_nProcs; ++rank) {
1132 if (partitionReference[rank] != partitionMapped[rank]) {
1146void VolOctreeMapper::_mapMeshPartitioned(
bool fillInverse)
1148 _recoverPartition();
1154 std::vector<OctantIR> octantsIRReference;
1155 octantsIRReference.reserve(n);
1156 for (
long i = 0; i < n; i++) {
1160 octantsIRReference.emplace_back(*octRef, idRef, idRef,
m_rank);
1164 _mapMeshesSamePartition(&octantsIRReference, &m_partitionIR.list_rec_octantIR_before, fillInverse, &indRef);
1165 _mapMeshesSamePartition(&octantsIRReference,
nullptr, fillInverse, &indRef);
1166 _mapMeshesSamePartition(&octantsIRReference, &m_partitionIR.list_rec_octantIR_after, fillInverse, &indRef);
1175bool VolOctreeMapper::_recoverPartition()
1181 const VolOctree* referencePatch =
static_cast<const VolOctree*
>(
m_referencePatch);
1182 const VolOctree* mappedPatch =
static_cast<const VolOctree*
>(
m_mappedPatch);
1184 std::vector<uint64_t> partitionLDMapped = mappedPatch->getTree().getPartitionLastDesc();
1185 std::vector<uint64_t> partitionFDReference = referencePatch->getTree().getPartitionFirstDesc();
1186 std::vector<uint64_t> partitionFDMapped = mappedPatch->getTree().getPartitionFirstDesc();
1188 if (m_partitionIR.partitionFDReference.size() != 0) {
1189 if (m_partitionIR.partitionFDMapped != partitionFDMapped ||
1190 m_partitionIR.partitionLDMapped != partitionLDMapped ||
1191 m_partitionIR.partitionFDReference != partitionFDReference ||
1192 m_partitionIR.partitionLDReference != partitionLDReference) {
1193 m_partitionIR.partitionFDReference.clear();
1194 m_partitionIR.partitionLDReference.clear();
1195 m_partitionIR.partitionFDMapped.clear();
1196 m_partitionIR.partitionLDMapped.clear();
1201 std::map<int, std::vector<int>> frommapped_rank;
1202 std::map<int,std::vector<int>> toreference_rank;
1203 for (
int ref_rank = 0; ref_rank <
m_nProcs; ref_rank++) {
1204 uint64_t local_first_morton = partitionFDReference[ref_rank];
1205 uint64_t local_last_morton = partitionLDReference[ref_rank];
1207 for (
int irank = 0; irank <
m_nProcs; irank++) {
1208 if (irank != ref_rank) {
1209 if (partitionFDMapped[irank] <= local_first_morton && partitionLDMapped[irank] >= local_first_morton) {
1210 frommapped_rank[ref_rank].push_back(irank);
1211 toreference_rank[irank].push_back(ref_rank);
1213 else if (partitionFDMapped[irank] <= local_last_morton && partitionLDMapped[irank] >= local_last_morton) {
1214 frommapped_rank[ref_rank].push_back(irank);
1215 toreference_rank[irank].push_back(ref_rank);
1217 else if (partitionFDMapped[irank] <= local_first_morton && partitionLDMapped[irank] >= local_last_morton) {
1218 frommapped_rank[ref_rank].push_back(irank);
1219 toreference_rank[irank].push_back(ref_rank);
1221 else if (partitionFDMapped[irank] >= local_first_morton && partitionLDMapped[irank] <= local_last_morton) {
1222 frommapped_rank[ref_rank].push_back(irank);
1223 toreference_rank[irank].push_back(ref_rank);
1229 clearPartitionMappingLists();
1232 std::map<int, std::vector<const Octant*>> list_octant;
1233 std::map<int, std::vector<long>> list_id;
1234 std::map<int, std::vector<long>> list_globalId;
1238 std::vector<int>::iterator overlap_ref_rank_begin_it = toreference_rank[
m_rank].begin();
1239 std::vector<int>::iterator overlap_ref_rank_end_it = toreference_rank[
m_rank].end();
1240 if (overlap_ref_rank_begin_it != overlap_ref_rank_end_it) {
1241 uint32_t first_overlap_map_idx = 0;
1242 int first_overlap_ref_rank = *overlap_ref_rank_begin_it;
1243 uint64_t reference_first_morton = partitionFDReference[first_overlap_ref_rank];
1244 uint64_t first_overlap_map_morton = mappedPatch->getTree().getLastDescMorton(first_overlap_map_idx);
1245 while (first_overlap_map_morton < reference_first_morton) {
1246 first_overlap_map_idx++;
1247 if (first_overlap_map_idx == mappedPatch->getTree().getNumOctants()) {
1250 first_overlap_map_morton = mappedPatch->getTree().getLastDescMorton(first_overlap_map_idx);
1255 if (first_overlap_map_idx < mappedPatch->getTree().getNumOctants() ) {
1256 uint32_t idx = first_overlap_map_idx;
1257 for (std::vector<int>::iterator ref_rank_it = overlap_ref_rank_begin_it; ref_rank_it != overlap_ref_rank_end_it; ++ref_rank_it) {
1258 int reference_rank = *ref_rank_it;
1259 uint64_t reference_last_morton = partitionLDReference[reference_rank];
1260 uint64_t morton = mappedPatch->getTree().getMorton(idx);
1261 while (morton < reference_last_morton) {
1262 const Octant *oct = mappedPatch->getTree().getOctant(idx);
1263 list_octant[reference_rank].push_back(oct);
1264 VolOctree::OctantInfo octantIfo(idx,
true);
1265 long id = mappedPatch->getOctantId(octantIfo);
1266 list_id[reference_rank].push_back(
id);
1267 long globalId = mappedPatch->getTree().getGlobalIdx(idx);
1268 list_globalId[reference_rank].push_back(globalId);
1269 m_partitionIR.list_sent_octantIR.emplace_back(*oct,
id, globalId, reference_rank);
1271 if (idx == mappedPatch->getTree().getNumOctants()) {
1274 morton = mappedPatch->getTree().getMorton(idx);
1276 if (idx <= mappedPatch->getTree().getNumOctants() && idx > 0) {
1297 for (
int reference_rank : toreference_rank[
m_rank]) {
1298 const std::vector<const Octant*> &rankOctants = list_octant[reference_rank];
1299 std::size_t nRankOctants = rankOctants.size();
1302 std::size_t buffSize =
sizeof(std::size_t) + nRankOctants * octantBinarySize;
1303 octCommunicator.setSend(reference_rank,buffSize);
1306 SendBuffer &sendBuffer = octCommunicator.getSendBuffer(reference_rank);
1307 sendBuffer << nRankOctants;
1308 for (std::size_t n = 0; n < nRankOctants; ++n) {
1309 const Octant &octant = *rankOctants[n];
1310 sendBuffer << octant;
1312 long id = list_id[reference_rank][n];
1315 long globalId = list_globalId[reference_rank][n];
1316 sendBuffer << globalId;
1320 octCommunicator.discoverRecvs();
1321 octCommunicator.startAllRecvs();
1322 octCommunicator.startAllSends();
1324 std::vector<int> recvRanks = octCommunicator.getRecvRanks();
1325 std::sort(recvRanks.begin(),recvRanks.end());
1327 std::vector<OctantIR> &list_rec_octantIR_before = m_partitionIR.list_rec_octantIR_before;
1328 std::vector<OctantIR> &list_rec_octantIR_after = m_partitionIR.list_rec_octantIR_after;
1329 std::vector<OctantIR> *_list_rec_octantIR;
1331 list_rec_octantIR_before.clear();
1332 list_rec_octantIR_after.clear();
1334 for (
int rank : recvRanks) {
1335 octCommunicator.waitRecv(rank);
1338 _list_rec_octantIR = &list_rec_octantIR_before;
1339 }
else if (rank >
m_rank) {
1340 _list_rec_octantIR = &list_rec_octantIR_after;
1345 RecvBuffer &recvBuffer = octCommunicator.getRecvBuffer(rank);
1347 std::size_t nRecvOctants;
1348 recvBuffer >> nRecvOctants;
1349 for (std::size_t n = 0; n < nRecvOctants; ++n) {
1351 recvBuffer >> octant;
1357 recvBuffer >> globalId;
1359 _list_rec_octantIR->emplace_back(octant,
id, globalId, rank);
1362 for (OctantIR &octantIR : *_list_rec_octantIR) {
1363 long id = octantIR.id;
1364 m_partitionIR.map_rank_rec_octantIR[rank][id] = &octantIR;
1368 octCommunicator.waitAllSends();
1370 m_partitionIR.partitionLDReference = partitionLDReference;
1371 m_partitionIR.partitionLDMapped = partitionLDMapped;
1372 m_partitionIR.partitionFDReference = partitionFDReference;
1373 m_partitionIR.partitionFDMapped = partitionFDMapped;
1385void VolOctreeMapper::_communicateInverseMapper(
const std::vector<OctantIR> *octantsIRMapped,
1386 const std::unordered_map<long, mapping::Info> &inverseGlobalMapping,
1387 std::unordered_map<long, mapping::Info> *inverseLocalMapping)
1390 std::set<int> toRanks;
1391 std::map<int, std::vector<long>> toRankGlobalId;
1392 std::map<long, long > globalIdToId;
1393 for (
const OctantIR &octantIR : *octantsIRMapped) {
1394 if (!inverseGlobalMapping.count(octantIR.globalId)){
1397 toRankGlobalId[octantIR.rank].push_back(octantIR.globalId);
1398 globalIdToId[octantIR.globalId] = octantIR.id;
1399 toRanks.insert(octantIR.rank);
1406 for (
int rank : toRanks) {
1408 std::size_t buffSize = 0;
1409 for (
long globalId : toRankGlobalId[rank]) {
1410 const mapping::Info &
info = inverseGlobalMapping.at(globalId);
1411 int mappedSize =
info.ids.size();
1412 std::size_t infoBytes = std::size_t(
sizeof(
long) +
sizeof(
int) +
sizeof(
int) +
sizeof(
int) + (
sizeof(
long))*mappedSize);
1413 buffSize += infoBytes;
1415 buffSize += std::size_t(
sizeof(
int));
1416 mapCommunicator.setSend(rank, buffSize);
1419 SendBuffer &sendBuffer = mapCommunicator.getSendBuffer(rank);
1420 sendBuffer << int(toRankGlobalId[rank].size());
1421 for (
long globalId : toRankGlobalId[rank]) {
1422 const mapping::Info &
info = inverseGlobalMapping.at(globalId);
1423 sendBuffer << globalId;
1424 sendBuffer << int(
info.type);
1425 sendBuffer << int(
info.entity);
1426 int mappedSize =
info.ids.size();
1427 sendBuffer << mappedSize;
1428 for (
long refId :
info.ids) {
1429 sendBuffer << refId;
1432 m_partitionIR.map_rank_inverseMapping[rank][globalIdToId[globalId]] =
info;
1437 mapCommunicator.discoverRecvs();
1438 mapCommunicator.startAllRecvs();
1439 mapCommunicator.startAllSends();
1441 int nCompletedRecvs = 0;
1442 while (nCompletedRecvs < mapCommunicator.getRecvCount()) {
1443 int rank = mapCommunicator.waitAnyRecv();
1444 RecvBuffer &recvBuffer = mapCommunicator.getRecvBuffer(rank);
1448 for (
int i = 0; i < nof; i++) {
1450 recvBuffer >> globalId;
1452 uint32_t idx =
static_cast<const VolOctree*
>(
m_mappedPatch)->getTree().getLocalIdx(globalId);
1453 VolOctree::OctantInfo octantIfo(idx,
true);
1459 recvBuffer >> entity;
1461 long id =
static_cast<const VolOctree*
>(
m_mappedPatch)->getOctantId(octantIfo);
1462 mapping::Info &
info = (*inverseLocalMapping)[id];
1467 for (
int j=0; j<nmap; j++) {
1469 recvBuffer >> idref;
1470 info.ids.push_back(idref);
1471 info.ranks.push_back(rank);
1478 mapCommunicator.waitAllSends();
1485void VolOctreeMapper::_communicateInverseMapperBack()
1488 std::set<int> toRanks;
1489 std::map<int, std::vector<long>> toRankId;
1490 for (
const auto &mappingEntry : m_partitionIR.map_rank_inverseMapping) {
1491 toRanks.insert(mappingEntry.first);
1493 const std::unordered_map<long, mapping::Info> &inverseMappingInfo = m_partitionIR.map_rank_inverseMapping[mappingEntry.first];
1494 for (
const auto &submappingEntry : inverseMappingInfo) {
1495 toRankId[mappingEntry.first].push_back(submappingEntry.first);
1503 for (
int rank : toRanks) {
1504 const std::unordered_map<long, mapping::Info> &inverseMappingInfo = m_partitionIR.map_rank_inverseMapping[rank];
1507 std::size_t buffSize = 0;
1508 for (
long id : toRankId[rank]) {
1509 const mapping::Info &
info = inverseMappingInfo.at(
id);
1510 int mappedSize =
info.ids.size();
1511 std::size_t infoBytes = std::size_t(
sizeof(
long) +
sizeof(
int) +
sizeof(
int) +
sizeof(
int) + (
sizeof(
long))*mappedSize);
1512 buffSize += infoBytes;
1514 buffSize += std::size_t(
sizeof(
int));
1515 mapCommunicator.setSend(rank,buffSize);
1518 SendBuffer &sendBuffer = mapCommunicator.getSendBuffer(rank);
1519 sendBuffer << int(toRankId[rank].size());
1520 for (
long id : toRankId[rank]) {
1521 const mapping::Info &
info = inverseMappingInfo.at(
id);
1523 sendBuffer << int(
info.type);
1524 sendBuffer << int(
info.entity);
1525 int mappedSize =
info.ids.size();
1526 sendBuffer << mappedSize;
1527 for (
long refId :
info.ids) {
1528 sendBuffer << refId;
1533 mapCommunicator.discoverRecvs();
1534 mapCommunicator.startAllRecvs();
1535 mapCommunicator.startAllSends();
1537 int nCompletedRecvs = 0;
1538 while (nCompletedRecvs < mapCommunicator.getRecvCount()) {
1539 int rank = mapCommunicator.waitAnyRecv();
1540 RecvBuffer &recvBuffer = mapCommunicator.getRecvBuffer(rank);
1544 for (
int i = 0; i < nof; i++) {
1552 recvBuffer >> entity;
1564 auto idsIter =
info.ids.begin();
1565 auto ranksIter =
info.ranks.begin();
1566 while (idsIter !=
info.ids.end()) {
1567 int rank = *ranksIter;
1569 idsIter =
info.ids.erase(idsIter);
1570 ranksIter =
info.ranks.erase(ranksIter);
1580 for (
int j=0; j<nmap; j++) {
1582 recvBuffer >> idref;
1583 info.ids.push_back(idref);
1584 info.ranks.push_back(rank);
1591 mapCommunicator.waitAllSends();
1604void VolOctreeMapper::_communicateMappedAdaptionInfo(
const std::vector<adaption::Info> &adaptionInfoMap, std::vector<adaption::Info> *adaptionInfoRef)
1607 std::set<int> toRanks;
1608 std::map<int, std::set<long>> toRankInd;
1609 std::map<int, std::vector<long>> toRankId;
1612 for (
auto &info : adaptionInfoMap) {
1613 for (
long id :
info.previous) {
1618 for (
int rank : itPreviousMapping->second.ranks) {
1619 toRanks.insert(rank);
1620 toRankInd[rank].insert(n);
1621 toRankId[rank].push_back(
id);
1631 for (
int rank : toRanks) {
1632 std::size_t buffSize = 0;
1633 for (
long id : toRankId[rank]) {
1635 int mappedSize =
info.ids.size();
1636 std::size_t infoBytes = std::size_t(
sizeof(
long) + 3*
sizeof(
int) + (
sizeof(
long))*mappedSize);
1637 buffSize += infoBytes;
1639 buffSize += std::size_t(
sizeof(
int));
1641 for (
long ind : toRankInd[rank]) {
1642 const adaption::Info &
info = adaptionInfoMap[ind];
1643 int currentSize =
info.current.size();
1644 int previousSize =
info.previous.size();
1645 std::size_t infoBytes = std::size_t(5*
sizeof(
int) + (
sizeof(
long))*(currentSize+previousSize));
1646 buffSize += infoBytes;
1648 buffSize += std::size_t(
sizeof(
int));
1650 mapCommunicator.setSend(rank,buffSize);
1653 SendBuffer &sendBuffer = mapCommunicator.getSendBuffer(rank);
1654 sendBuffer << int(toRankId[rank].size());
1655 for (
long id : toRankId[rank]) {
1660 const mapping::Info &
info = itPreviousMapping->second;
1662 sendBuffer << int(
info.type);
1663 sendBuffer << int(
info.entity);
1664 int mappedSize =
info.ids.size();
1665 sendBuffer << mappedSize;
1666 for (
long refId :
info.ids) {
1667 sendBuffer << refId;
1671 sendBuffer << int(toRankInd[rank].size());
1672 for (
long ind : toRankInd[rank]) {
1673 const adaption::Info &
info = adaptionInfoMap[ind];
1674 sendBuffer << int(
info.type);
1675 sendBuffer << int(
info.entity);
1676 int currentSize =
info.current.size();
1677 int previousSize =
info.previous.size();
1678 sendBuffer << currentSize;
1679 for (
long Id :
info.current) {
1682 sendBuffer << previousSize;
1683 for (
long Id :
info.previous) {
1695 mapCommunicator.discoverRecvs();
1696 mapCommunicator.startAllRecvs();
1697 mapCommunicator.startAllSends();
1700 int nCompletedRecvs = 0;
1701 while (nCompletedRecvs < mapCommunicator.getRecvCount()) {
1702 int rank = mapCommunicator.waitAnyRecv();
1704 RecvBuffer &recvBuffer = mapCommunicator.getRecvBuffer(rank);
1706 recvBuffer >> nofMapper;
1707 for (
int i = 0; i < nofMapper; i++) {
1712 recvBuffer >> mtype;
1715 recvBuffer >> mentity;
1722 for (
int j=0; j<nmap; j++) {
1724 recvBuffer >> idref;
1725 info.ids.push_back(idref);
1728 m_partitionIR.map_rank_previousMapping[rank][id] =
info;
1729 m_partitionIR.map_rank_inverseMapping[rank].erase(
id);
1733 recvBuffer >> nofInfo;
1734 for (
int i = 0; i < nofInfo; i++) {
1739 recvBuffer >> entity;
1741 adaption::Info
info;
1742 info.type = adaption::Type(type);
1743 info.entity = adaption::Entity(entity);
1745 recvBuffer >> ncurrent;
1746 for (
int j=0; j<ncurrent; j++) {
1749 info.current.push_back(
id);
1752 recvBuffer >> nprevious;
1753 for (
int j=0; j<nprevious; j++) {
1756 info.previous.push_back(
id);
1759 recvBuffer >> arank;
1761 adaptionInfoRef->push_back(info);
1767 mapCommunicator.waitAllSends();
The Cell class defines the cells.
static unsigned int getBinarySize()
uint64_t getMorton(uint32_t idx) const
const std::vector< uint64_t > & getPartitionLastDesc() const
uint64_t getLastDescMorton(const Octant *oct) const
uint8_t getLevel(uint32_t idx) const
PiercedVector< Cell > & getCells()
bool isPartitioned() const
long getInternalCellCount() const
Metafunction for generating a pierced storage.
The VolOctreeMapper is the class to map two meshes of class VolOctree.
std::unordered_map< int, std::vector< long > > getReceivedReferenceIds() const override
std::unordered_map< int, std::vector< long > > getReceivedMappedIds() const override
std::unordered_map< int, std::vector< long > > getSentReferenceIds() const override
void adaptionPrepare(const std::vector< adaption::Info > &adaptionInfo, bool reference=true) override
void adaptionCleanup() override
void adaptionAlter(const std::vector< adaption::Info > &adaptionInfo, bool reference=true, bool inverseFilled=false) override
VolOctreeMapper(const VolOctree *referencePatch, const VolOctree *mappedPatch, MPI_Comm communicator)
bool checkPartition() override
std::unordered_map< int, std::vector< long > > getSentMappedIds() const override
void clearPartitionMapping()
The VolOctree defines a Octree patch.
int getCellLevel(long id) const
OctantInfo getCellOctant(long id) const
Octant * getOctantPointer(const OctantInfo &octantInfo)
PabloUniform & getTree()
Gets a reference to the octree associated with the patch.
long getOctantId(const OctantInfo &octantInfo) const
The VolumeMapper is the class to map two meshes.
const VolumeKernel * m_mappedPatch
std::unordered_map< long, mapping::Info > m_previousMapping
void initialize(bool fillInv=false)
PiercedStorage< mapping::Info > m_inverseMapping
PiercedStorage< mapping::Info > m_mapping
void clearInverseMapping()
const VolumeKernel * m_referencePatch
Logger & info(log::Visibility defaultVisibility)
The Info struct defines the information associated to an adaption.