diff --git a/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H b/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H index 8d8021b08f..94c6c6c779 100644 --- a/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H +++ b/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H @@ -1,30 +1,56 @@ -// Handle merging of patch pairs +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2009 OpenFOAM Foundation + Copyright (C) 2017-2022 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM, distributed under GPL-3.0-or-later. + +Description + Handle merging of patch pairs + +\*---------------------------------------------------------------------------*/ + { wordPairList mergePatchPairs; - // Read in a list of dictionaries for the merge patch pairs + // Read in a list of merge patch pairs if ( meshDict.readIfPresent("mergePatchPairs", mergePatchPairs) && mergePatchPairs.size() ) { - Info<< "Creating merge patch pairs" << nl << endl; + Info<< "Merging " << mergePatchPairs.size() << " patch pairs" << nl; - Info<< "Adding point and face zones" << endl; + // Cleanup + wordHashSet cleanupPatches(4*mergePatchPairs.size()); + wordHashSet cleanupPointZones(2*mergePatchPairs.size()); + wordHashSet cleanupFaceZones(2*mergePatchPairs.size()); + + Info<< " Adding point and face zones" << endl; { - auto& pzs = mesh.pointZones(); - pzs.clearAddressing(); - auto& fzs = mesh.faceZones(); - fzs.clearAddressing(); + const auto& pbm = mesh.boundaryMesh(); + + auto& pzs = mesh.pointZones(); pzs.clearAddressing(); + auto& fzs = mesh.faceZones(); fzs.clearAddressing(); forAll(mergePatchPairs, pairi) { + // Patch pairs + const polyPatch& patch0 = pbm[mergePatchPairs[pairi].first()]; + const polyPatch& patch1 = pbm[mergePatchPairs[pairi].second()]; + const word mergeName ( mergePatchPairs[pairi].first() + mergePatchPairs[pairi].second() - + name(pairi) + + Foam::name(pairi) ); // An empty zone for cut points @@ -37,40 +63,35 @@ pzs ) ); + cleanupPointZones.insert(pzs.last().name()); - // Master patch - const word masterPatchName(mergePatchPairs[pairi].first()); - const polyPatch& masterPatch = - mesh.boundaryMesh()[masterPatchName]; - + // Coupling side 0 (master) fzs.append ( new faceZone ( - mergeName + "MasterZone", - identity(masterPatch.range()), + mergeName + "Side0Zone", + identity(patch0.range()), false, // none are flipped fzs.size(), fzs ) ); + cleanupFaceZones.insert(fzs.last().name()); - // Slave patch - const word slavePatchName(mergePatchPairs[pairi].second()); - const polyPatch& slavePatch = - mesh.boundaryMesh()[slavePatchName]; - + // Coupling side 1 (slave) fzs.append ( new faceZone ( - mergeName + "SlaveZone", - identity(slavePatch.range()), + mergeName + "Side1Zone", + identity(patch1.range()), false, // none are flipped fzs.size(), fzs ) ); + cleanupFaceZones.insert(fzs.last().name()); // An empty zone for cut faces fzs.append @@ -82,35 +103,38 @@ fzs ) ); - } // end of all merge pairs + cleanupFaceZones.insert(fzs.last().name()); + } } - - Info<< "Creating attachPolyTopoChanger" << endl; + Info<< " Merging with attachPolyTopoChanger" << endl; attachPolyTopoChanger polyMeshAttacher(mesh); - polyMeshAttacher.setSize(mergePatchPairs.size()); + polyMeshAttacher.resize(1); forAll(mergePatchPairs, pairi) { + cleanupPatches.insert(mergePatchPairs[pairi].first()); + cleanupPatches.insert(mergePatchPairs[pairi].second()); + const word mergeName ( mergePatchPairs[pairi].first() + mergePatchPairs[pairi].second() - + name(pairi) + + Foam::name(pairi) ); // Add the sliding interface mesh modifier polyMeshAttacher.set ( - pairi, + 0, new slidingInterface ( - "couple" + name(pairi), + "couple" + Foam::name(pairi), pairi, polyMeshAttacher, - mergeName + "MasterZone", - mergeName + "SlaveZone", + mergeName + "Side0Zone", + mergeName + "Side1Zone", mergeName + "CutPointZone", mergeName + "CutFaceZone", mergePatchPairs[pairi].first(), @@ -120,12 +144,135 @@ intersection::VISIBLE ) ); + + polyMeshAttacher.attach(false); // Do not yet remove empty patches } - polyMeshAttacher.attach(true); + // Re-do the boundary patches, removing empty merge patches + // but keeping any other empty patches + { + const polyBoundaryMesh& oldPatches = mesh.boundaryMesh(); + + polyPatchList newPatches(oldPatches.size()); + label nNewPatches = 0; + + wordHashSet removedPatches(cleanupPatches.capacity()); + + forAll(oldPatches, patchi) + { + const word& patchName = oldPatches[patchi].name(); + + if + ( + !cleanupPatches.found(patchName) + || returnReduceOr(oldPatches[patchi].size()) + ) + { + newPatches.set + ( + nNewPatches, + oldPatches[patchi].clone + ( + mesh.boundaryMesh(), + nNewPatches, + oldPatches[patchi].size(), + oldPatches[patchi].start() + ) + ); + + ++nNewPatches; + } + else + { + removedPatches.insert(patchName); + } + } + + newPatches.resize(nNewPatches); + + mesh.removeBoundary(); + mesh.addPatches(newPatches); + + Info<< "Removed " << removedPatches.size() + << " empty merged patches:" << nl + << " " << flatOutput(removedPatches.sortedToc()) << endl; + } + + // Cleanup empty merged point zones + { + PtrList& zones = mesh.pointZones(); + mesh.pointZones().clearAddressing(); + + wordHashSet removedZones(2*zones.size()); + + label nZones = 0; + forAll(zones, zonei) + { + if + ( + !cleanupPointZones.found(zones[zonei].name()) + || returnReduceOr(zones[zonei].size()) + ) + { + zones.set(nZones, zones.release(zonei)); + zones[nZones].index() = nZones; // re-index + ++nZones; + } + else + { + removedZones.insert(zones[zonei].name()); + } + } + zones.resize(nZones); + + if (removedZones.size()) + { + Info<< "Removed " << removedZones.size() + << " empty point zones:" << nl + << " " << flatOutput(removedZones.sortedToc()) << endl; + } + } + + // Cleanup empty merged face zones + { + PtrList& zones = mesh.faceZones(); + mesh.faceZones().clearAddressing(); + + wordHashSet removedZones(2*zones.size()); + + label nZones = 0; + forAll(zones, zonei) + { + if + ( + !cleanupFaceZones.found(zones[zonei].name()) + || returnReduceOr(zones[zonei].size()) + ) + { + zones.set(nZones, zones.release(zonei)); + zones[nZones].index() = nZones; // re-index + ++nZones; + } + else + { + removedZones.insert(zones[zonei].name()); + } + } + zones.resize(nZones); + + if (removedZones.size()) + { + Info<< "Removed " << removedZones.size() + << " empty merged face zones:" << nl + << " " << flatOutput(removedZones.sortedToc()) << endl; + } + } } else { - Info<< nl << "There are no merge patch pairs" << endl; + Info<< "No patch pairs to merge" << endl; } } + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C b/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C index 2cfe9fe00a..57812d4ec0 100644 --- a/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C +++ b/applications/utilities/mesh/manipulation/stitchMesh/stitchMesh.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2017-2020 OpenCFD Ltd. + Copyright (C) 2017-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -564,7 +564,7 @@ int main(int argc, char *argv[]) mesh.faceZones() ( - mergePatchName + "MasterZone", + mergePatchName + "Side0Zone", true // verbose ).resetAddressing(std::move(faceIds), false); @@ -574,7 +574,7 @@ int main(int argc, char *argv[]) mesh.faceZones() ( - mergePatchName + "SlaveZone", + mergePatchName + "Side1Zone", true // verbose ).resetAddressing(std::move(faceIds), false); @@ -595,8 +595,8 @@ int main(int argc, char *argv[]) "couple" + Foam::name(actioni), 0, stitcher, - mergePatchName + "MasterZone", - mergePatchName + "SlaveZone", + mergePatchName + "Side0Zone", + mergePatchName + "Side1Zone", mergePatchName + "CutPointZone", cutZoneName, masterPatchName, diff --git a/tutorials/mesh/blockMesh/mergePairs/Allclean b/tutorials/mesh/blockMesh/mergePairs/Allclean new file mode 100755 index 0000000000..d4f5975bc8 --- /dev/null +++ b/tutorials/mesh/blockMesh/mergePairs/Allclean @@ -0,0 +1,10 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions +#------------------------------------------------------------------------------ + +cleanCase0 + +rm -rf constant + +#------------------------------------------------------------------------------ diff --git a/tutorials/mesh/blockMesh/mergePairs/Allrun b/tutorials/mesh/blockMesh/mergePairs/Allrun new file mode 100755 index 0000000000..c0ee92beed --- /dev/null +++ b/tutorials/mesh/blockMesh/mergePairs/Allrun @@ -0,0 +1,8 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +runApplication blockMesh + +#------------------------------------------------------------------------------ diff --git a/tutorials/mesh/blockMesh/mergePairs/system/blockMeshDict b/tutorials/mesh/blockMesh/mergePairs/system/blockMeshDict new file mode 100644 index 0000000000..aaa0d5c705 --- /dev/null +++ b/tutorials/mesh/blockMesh/mergePairs/system/blockMeshDict @@ -0,0 +1,119 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2212 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 0.001; + +vertices +( + // Block d + ( 50 -17 -12.5) + (100 -17 -12.5) + (100 -2 -12.5) + ( 50 -2 -12.5) + ( 50 -17 12.5) + (100 -17 12.5) + (100 -2 12.5) + ( 50 -2 12.5) + + // Block e + ( 0 -17 -12.5) + ( 50 -17 -12.5) + ( 50 -2 -12.5) + ( 0 -2 -12.5) + ( 0 -17 12.5) + ( 50 -17 12.5) + ( 50 -2 12.5) + ( 0 -2 12.5) + + // Block f + ( 0 -19 -12.5) + ( 50 -19 -12.5) + ( 50 -17 -12.5) + ( 0 -17 -12.5) + ( 0 -19 12.5) + ( 50 -19 12.5) + ( 50 -17 12.5) + ( 0 -17 12.5) +); + +blocks +( + // Block d + hex (0 1 2 3 4 5 6 7) block-d (4 5 4) grading (1 1 1) + + // Block e + hex (8 9 10 11 12 13 14 15) block-e (4 4 4) grading (1 1 1) + + // Block f + hex (16 17 18 19 20 21 22 23) block-f (5 4 4) grading (1 1 1) +); + + +edges +( +); + + +boundary +( + mid6 + { + type patch; + faces + ( + (0 0) // Block d + ); + } + mid7 + { + type patch; + faces + ( + (1 1) // Block e + ); + } + mid8 + { + type patch; + faces + ( + (1 2) // Block e + ); + } + mid9 + { + type patch; + faces + ( + (2 3) // Block e + ); + } + + other + { + type patch; + faces (); + } +); + + +mergePatchPairs +( + (mid6 mid7) + (mid8 mid9) +); + +// ************************************************************************* // diff --git a/tutorials/mesh/blockMesh/mergePairs/system/controlDict b/tutorials/mesh/blockMesh/mergePairs/system/controlDict new file mode 100644 index 0000000000..c2e46fdfc9 --- /dev/null +++ b/tutorials/mesh/blockMesh/mergePairs/system/controlDict @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2206 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application blockMesh; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 0; + +deltaT 0; + +writeControl timeStep; + +writeInterval 1; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 6; + +writeCompression off; + +timeFormat general; + +timePrecision 6; + +runTimeModifiable true; + + +// ************************************************************************* //