diff --git a/applications/utilities/mesh/manipulation/reorderPatches/Make/files b/applications/utilities/mesh/manipulation/reorderPatches/Make/files new file mode 100644 index 0000000000..8b50968e11 --- /dev/null +++ b/applications/utilities/mesh/manipulation/reorderPatches/Make/files @@ -0,0 +1,3 @@ +reorderPatches.C + +EXE = $(FOAM_APPBIN)/reorderPatches diff --git a/applications/utilities/mesh/manipulation/reorderPatches/Make/options b/applications/utilities/mesh/manipulation/reorderPatches/Make/options new file mode 100644 index 0000000000..6946273d27 --- /dev/null +++ b/applications/utilities/mesh/manipulation/reorderPatches/Make/options @@ -0,0 +1,10 @@ +EXE_INC = \ + -I$(LIB_SRC)/polyTopoChange/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/finiteVolume/lnInclude + +EXE_LIBS = \ + -lpolyTopoChange \ + -lmeshTools \ + -lfiniteVolume \ + -lgenericFvFields diff --git a/applications/utilities/mesh/manipulation/reorderPatches/reorderPatches.C b/applications/utilities/mesh/manipulation/reorderPatches/reorderPatches.C new file mode 100644 index 0000000000..bfd69a775e --- /dev/null +++ b/applications/utilities/mesh/manipulation/reorderPatches/reorderPatches.C @@ -0,0 +1,256 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | Website: https://openfoam.org + \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + reorderPatches + +Description + Utility to reorder the patches of a case + + The new patch order may be specified directly as a list of patch names + following the -patchOrder option or from the boundary file of a reference + case specified using the -referenceCase option with or without the + -referenceRegion option. + + This utility run either serial or parallel but either way the reference + case boundary file is read from the constant directory. + +Usage + \b reorderPatches + + Options: + - \par -patchOrder \ + Specify the list of patch names in the new order. + + - \par -referenceCase \ + Specify the reference case path + + - \par -referenceRegion \ + Specify an alternative mesh region for the reference case. + If -referenceCase is not specified the current case is used. + + - \par -overwrite \n + Replace the old mesh with the new one, rather than writing the new one + into a separate time directory + + - \par -region \ + Specify an alternative mesh region. + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "fvMesh.H" +#include "polyBoundaryMeshEntries.H" +#include "timeSelector.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + timeSelector::addOptions(true, false); + + argList::addNote + ( + "Stitch the faces on the specified patch pairs\n" + "converting the overlapping patch faces into internal faces.\n" + ); + + #include "addOverwriteOption.H" + #include "addRegionOption.H" + + argList::addOption + ( + "patchOrder", + "wordList", + "specify the list of patch names in the new order" + ); + + argList::addOption + ( + "referenceCase", + "fileName", + "specify the reference case path" + ); + + argList::addOption + ( + "referenceRegion", + "word", + "specify the reference region" + ); + + #include "setRootCase.H" + + wordList referencePatchNames; + + if (args.optionFound("patchOrder")) + { + args.optionLookup("patchOrder")() >> referencePatchNames; + } + else if + ( + args.optionFound("referenceCase") + || args.optionFound("referenceRegion") + ) + { + const fileName referenceCasePath + ( + args.optionLookupOrDefault("referenceCase", args.path()) + ); + const fileName rootDirReference = referenceCasePath.path().toAbsolute(); + const fileName caseDirReference = referenceCasePath.name(); + + const string caseDirOrig = getEnv("FOAM_CASE"); + const string caseNameOrig = getEnv("FOAM_CASENAME"); + setEnv("FOAM_CASE", rootDirReference/caseDirReference, true); + setEnv("FOAM_CASENAME", caseDirReference, true); + Time referenceRunTime + ( + Time::controlDictName, + rootDirReference, + caseDirReference, + false + ); + setEnv("FOAM_CASE", caseDirOrig, true); + setEnv("FOAM_CASENAME", caseNameOrig, true); + + word referenceRegion; + if (args.optionFound("referenceRegion")) + { + referenceRegion = args["referenceRegion"]; + Info<< "Reference region: " << referenceRegion << endl; + } + + const fileName referenceMeshDir(referenceRegion/polyMesh::meshSubDir); + + typeIOobject ioObj + ( + "boundary", + referenceRunTime.findInstance + ( + referenceMeshDir, + "boundary", + IOobject::MUST_READ + ), + referenceMeshDir, + referenceRunTime, + IOobject::MUST_READ, + IOobject::NO_WRITE, + false + ); + + if (ioObj.headerOk()) + { + polyBoundaryMeshEntries patchEntries(ioObj); + + referencePatchNames.setSize(patchEntries.size()); + + forAll(patchEntries, patchi) + { + referencePatchNames[patchi] = patchEntries[patchi].keyword(); + } + } + else + { + FatalErrorInFunction + << "Cannot find or read the boundary file for reference case " + << nl + << " " << referenceCasePath + << exit(FatalError); + } + } + else + { + FatalErrorInFunction + << "Reference patch order not specified" + << exit(FatalError); + } + + #include "createTimeNoFunctionObjects.H" + #include "createRegionMeshNoChangers.H" + + // Select time if specified + timeSelector::selectIfPresent(runTime, args); + + const bool overwrite = args.optionFound("overwrite"); + + const word oldInstance = mesh.pointsInstance(); + + if (!overwrite) + { + runTime++; + } + + if + ( + !Pstream::parRun() + && mesh.boundaryMesh().size() != referencePatchNames.size() + ) + { + FatalErrorInFunction + << "Number of reference patches " << referencePatchNames.size() + << " is not equal to the number of patches in the mesh " + << mesh.boundaryMesh().size() + << exit(FatalError); + } + + // Reorder the patches + labelList newToOldPatches(identityMap(mesh.boundaryMesh().size())); + + forAll(referencePatchNames, patchi) + { + const label oldPatchi = + mesh.boundaryMesh().findIndex(referencePatchNames[patchi]); + + if (oldPatchi != -1) + { + newToOldPatches[patchi] = oldPatchi; + } + else + { + FatalErrorInFunction + << "Cannot find reference patch " << referencePatchNames[patchi] + << " in the mesh which has patches " + << mesh.boundaryMesh().names() + << exit(FatalError); + } + } + mesh.reorderPatches(newToOldPatches, false); + + if (overwrite) + { + mesh.setInstance(oldInstance); + } + + Info<< "Writing mesh to " << mesh.facesInstance() << endl; + mesh.write(); + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* //