diff --git a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H index 57e528a29a1283b14d7fd51a9d08a44f70c25ef0..d82b67199fc511cdaaad765964fc86c27c5852cf 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H @@ -172,6 +172,12 @@ public: return index_; } + //- Return the index of this zone in zone list + label& index() + { + return index_; + } + //- Return a reference to the look-up map const Map<label>& lookupMap() const; diff --git a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C index 9745cb61db1cdc4f9a121f52407dd359afdf3de4..24c4a537c14c7f7cc8e6c2b791b058f34518e651 100644 --- a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C +++ b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C @@ -201,14 +201,24 @@ Foam::wordList Foam::fvMeshDistribute::mergeWordList(const wordList& procNames) List<wordList> allNames(Pstream::nProcs()); allNames[Pstream::myProcNo()] = procNames; Pstream::gatherList(allNames); - Pstream::scatterList(allNames); - wordHashSet mergedNames; - forAll(allNames, proci) + // Assume there are few zone names to merge. Use HashSet otherwise (but + // maintain ordering) + DynamicList<word> mergedNames; + if (Pstream::master()) { - mergedNames.insert(allNames[proci]); + mergedNames = procNames; + for (const wordList& names : allNames) + { + for (const word& name : names) + { + mergedNames.appendUniq(name); + } + } } - return mergedNames.sortedToc(); + Pstream::scatter(mergedNames); + + return mergedNames; } @@ -1932,11 +1942,17 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute } - // Collect any zone names + // Collect any zone names over all processors and shuffle zones accordingly + // Note that this is not necessary for redistributePar since that already + // checks for it. However other use (e.g. mesh generators) might not. const wordList pointZoneNames(mergeWordList(mesh_.pointZones().names())); + reorderZones<pointZone>(pointZoneNames, mesh_.pointZones()); + const wordList faceZoneNames(mergeWordList(mesh_.faceZones().names())); - const wordList cellZoneNames(mergeWordList(mesh_.cellZones().names())); + reorderZones<faceZone>(faceZoneNames, mesh_.faceZones()); + const wordList cellZoneNames(mergeWordList(mesh_.cellZones().names())); + reorderZones<cellZone>(cellZoneNames, mesh_.cellZones()); // Local environment of all boundary faces diff --git a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.H b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.H index 1c4c7d518a1863c390c99efdebafb4d5331eb6e5..e14565ccde4231ca33327703d513fb2366a9ba6c 100644 --- a/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.H +++ b/src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.H @@ -97,6 +97,14 @@ class fvMeshDistribute //- Merge wordlists over all processors static wordList mergeWordList(const wordList&); + //- Reorder zones according to names + template<class ZoneType, class ZoneMesh> + void reorderZones + ( + const wordList& zoneNames, + ZoneMesh& zones + ); + // Patch handling diff --git a/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C b/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C index ab7395d6651ad8f8ca625956a154a22e2424f0b9..bda893b7e6dd3d89af831301913bad107dd36342 100644 --- a/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C +++ b/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C @@ -30,6 +30,53 @@ License // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +template<class ZoneType, class ZoneMesh> +void Foam::fvMeshDistribute::reorderZones +( + const wordList& zoneNames, + ZoneMesh& zones +) +{ + zones.clearAddressing(); + + // Shift old ones to new position + UPtrList<ZoneType> newZonePtrs(zoneNames.size()); + forAll(zones, zonei) + { + auto* zonePtr = zones.get(zonei); + if (!zonePtr) + { + FatalErrorInFunction << "Problem with zones " << zones.names() + << exit(FatalError); + } + const label newIndex = zoneNames.find(zonePtr->name()); + zonePtr->index() = newIndex; + newZonePtrs.set(newIndex, zonePtr); + } + + // Add empty zones for unknown ones + forAll(newZonePtrs, i) + { + if (!newZonePtrs.get(i)) + { + newZonePtrs.set + ( + i, + new ZoneType + ( + zoneNames[i], + i, + zones + ) + ); + } + } + + // Transfer + zones.swap(newZonePtrs); +} + + template<class GeoField> void Foam::fvMeshDistribute::printIntFieldInfo(const fvMesh& mesh) {