mergeMeshes: Extended to merge lists of meshes

Description
    Merges meshes without stitching.

Usage
    \b mergeMeshes [OPTION]

    Options:
      - \par -doc
        Display the documentation in browser

      - \par -srcDoc
        Display the source documentation in browser

      - \par -help
        Print the usage

      - \par -case \<dir\>
        Select a case directory instead of the current working directory

      - \par -region \<name\>
        Specify an alternative mesh region.

      - \par -addRegions "'(region1 region2 ... regionN)'"
        Specify list of region meshes to merge.

      - \par -addCases "'(\"casePath1\" \"casePath2\" ... \"casePathN\")'"
        Specify list of case meshes to merge.

      - \par -addCaseRegions "'((\"casePath1\" region1) (\"casePath2\" region2)"
        Specify list of case region meshes to merge.
This commit is contained in:
Henry Weller
2024-01-17 19:03:05 +00:00
parent a671b738c9
commit f47e1b0bab
5 changed files with 216 additions and 165 deletions

View File

@ -1,23 +0,0 @@
Info<< nl << "Create Times" << endl;
const fileName masterCasePath = masterCase.path();
const fileName masterCaseName = masterCase.name();
Time runTimeMaster
(
Time::controlDictName,
masterCasePath,
masterCaseName,
false
);
const fileName addCasePath = addCase.path();
const fileName addCaseName = addCase.name();
Time runTimeToAdd
(
Time::controlDictName,
addCasePath,
addCaseName,
false
);

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -25,130 +25,187 @@ Application
mergeMeshes mergeMeshes
Description Description
Merges two meshes. Merges meshes without stitching.
Usage
\b mergeMeshes [OPTION]
Options:
- \par -doc
Display the documentation in browser
- \par -srcDoc
Display the source documentation in browser
- \par -help
Print the usage
- \par -case \<dir\>
Select a case directory instead of the current working directory
- \par -region \<name\>
Specify an alternative mesh region.
- \par -addRegions "'(region1 region2 ... regionN)'"
Specify list of region meshes to merge.
- \par -addCases "'(\"casePath1\" \"casePath2\" ... \"casePathN\")'"
Specify list of case meshes to merge.
- \par -addCaseRegions "'((\"casePath1\" region1) (\"casePath2\" region2)"
Specify list of case region meshes to merge.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "argList.H" #include "argList.H"
#include "Time.H" #include "Time.H"
#include "timeSelector.H"
#include "mergePolyMesh.H" #include "mergePolyMesh.H"
using namespace Foam; using namespace Foam;
void getRootCase(fileName& casePath)
{
casePath.clean();
if (casePath.empty() || casePath == ".")
{
// handle degenerate form and '.'
casePath = cwd();
}
else if (casePath[0] != '/' && casePath.name() == "..")
{
// avoid relative cases ending in '..' - makes for very ugly names
casePath = cwd()/casePath;
casePath.clean();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
argList::addNote argList::addNote("Merge meshes without stitching");
(
"merge two meshes"
);
argList::noParallel(); argList::noParallel();
#include "addOverwriteOption.H" #include "addOverwriteOption.H"
#include "addRegionOption.H"
argList::validArgs.append("masterCase");
argList::addOption argList::addOption
( (
"masterRegion", "addRegions",
"name", "'(region1 region2 ... regionN)'"
"specify alternative mesh region for the master mesh" "list of regions to merge"
); );
argList::validArgs.append("addCase");
argList::addOption argList::addOption
( (
"addRegion", "addCases",
"name", "'(\"casePath1\" \"casePath2\" ... \"casePathN\")'",
"specify alternative mesh region for the additional mesh" "list of cases to merge"
); );
argList args(argc, argv); argList::addOption
if (!args.check()) (
"addCaseRegions",
"'((\"casePath1\" region1) (\"casePath2\" region2)"
"... (\"casePathN\" regionN))'",
"list of case regions to merge"
);
#include "setRootCase.H"
const wordList regions
(
args.optionLookupOrDefault<wordList>("addRegions", wordList::null())
);
const fileNameList cases
(
args.optionLookupOrDefault<fileNameList>
(
"addCases",
fileNameList::null()
)
);
List<Tuple2<fileName, word>> caseRegions
(
args.optionLookupOrDefault<List<Tuple2<fileName, word>>>
(
"addCaseRegions",
List<Tuple2<fileName, word>>::null()
)
);
forAll(cases, i)
{ {
FatalError.exit(); caseRegions.append({cases[i], polyMesh::defaultRegion});
} }
#include "createTimeNoFunctionObjects.H"
// Select time if specified
timeSelector::selectIfPresent(runTime, args);
#include "createNamedPolyMesh.H"
const bool overwrite = args.optionFound("overwrite"); const bool overwrite = args.optionFound("overwrite");
const word oldInstance = mesh.pointsInstance();
fileName masterCase = args[1];
word masterRegion = polyMesh::defaultRegion;
args.optionReadIfPresent("masterRegion", masterRegion);
fileName addCase = args[2];
word addRegion = polyMesh::defaultRegion;
args.optionReadIfPresent("addRegion", addRegion);
getRootCase(masterCase);
getRootCase(addCase);
Info<< "Master: " << masterCase << " region " << masterRegion << nl
<< "mesh to add: " << addCase << " region " << addRegion << endl;
#include "createTimes.H"
Info<< "Reading master mesh for time = " << runTimeMaster.name() << nl;
Info<< "Create mesh\n" << endl;
mergePolyMesh masterMesh
(
IOobject
(
masterRegion,
runTimeMaster.name(),
runTimeMaster
)
);
const word oldInstance = masterMesh.pointsInstance();
Info<< "Reading mesh to add for time = " << runTimeToAdd.name() << nl;
Info<< "Create mesh\n" << endl;
polyMesh meshToAdd
(
IOobject
(
addRegion,
runTimeToAdd.name(),
runTimeToAdd
)
);
if (!overwrite) if (!overwrite)
{ {
runTimeMaster++; runTime++;
} }
Info<< "Writing combined mesh to " << runTimeMaster.name() << endl; // Construct the mergePolyMesh class for the current mesh
mergePolyMesh mergeMeshes(mesh);
masterMesh.addMesh(meshToAdd);
masterMesh.merge(); // Add all the specified region meshes
forAll(regions, i)
{
Info<< "Create polyMesh for region " << regions[i] << endl;
polyMesh meshToAdd
(
IOobject
(
regions[i],
runTime.name(),
runTime
)
);
Info<< "Adding mesh " << meshToAdd.objectPath() << endl;
mergeMeshes.addMesh(meshToAdd);
}
// Add all the specified case meshes
forAll(caseRegions, i)
{
const fileName& addCase = caseRegions[i].first();
const word& addRegion = caseRegions[i].second();
const fileName addCasePath(addCase.path());
const fileName addCaseName(addCase.name());
// Construct the time for the new case without reading the controlDict
Time runTimeToAdd
(
// Time::controlDictName,
addCasePath,
addCaseName,
false
);
Info<< "Create polyMesh for case " << runTimeToAdd.path() << endl;
polyMesh meshToAdd
(
IOobject
(
addRegion,
runTimeToAdd.name(),
runTimeToAdd
)
);
Info<< "Adding mesh " << meshToAdd.objectPath() << endl;
mergeMeshes.addMesh(meshToAdd);
}
Info << nl << "Merging all meshes" << endl;
mergeMeshes.merge();
if (overwrite) if (overwrite)
{ {
masterMesh.setInstance(oldInstance); mesh.setInstance(oldInstance);
} }
masterMesh.write(); Info<< "Writing mesh to " << mesh.facesInstance() << endl;
mesh.write();
Info<< "End\n" << endl; Info<< "End\n" << endl;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -31,7 +31,7 @@ License
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(mergePolyMesh, 1); defineTypeNameAndDebug(mergePolyMesh, 0);
} }
@ -117,32 +117,32 @@ Foam::label Foam::mergePolyMesh::zoneIndex
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mergePolyMesh::mergePolyMesh(const IOobject& io) Foam::mergePolyMesh::mergePolyMesh(polyMesh& mesh)
: :
polyMesh(io), mesh_(mesh),
meshMod_(*this), meshMod_(mesh_),
patchNames_(2*boundaryMesh().size()), patchNames_(2*mesh_.boundaryMesh().size()),
patchDicts_(2*boundaryMesh().size()), patchDicts_(2*mesh_.boundaryMesh().size()),
pointZoneNames_(), pointZoneNames_(),
faceZoneNames_(), faceZoneNames_(),
cellZoneNames_() cellZoneNames_()
{ {
// Insert the original patches into the list // Insert the original patches into the list
wordList curPatchNames = boundaryMesh().names(); wordList curPatchNames = mesh_.boundaryMesh().names();
forAll(boundaryMesh(), patchi) forAll(mesh_.boundaryMesh(), patchi)
{ {
patchNames_.append(boundaryMesh()[patchi].name()); patchNames_.append(mesh_.boundaryMesh()[patchi].name());
OStringStream os; OStringStream os;
boundaryMesh()[patchi].write(os); mesh_.boundaryMesh()[patchi].write(os);
patchDicts_.append(dictionary(IStringStream(os.str())())); patchDicts_.append(dictionary(IStringStream(os.str())()));
} }
// Insert point, face and cell zones into the list // Insert point, face and cell zones into the list
// Point zones // Point zones
wordList curPointZoneNames = pointZones().names(); wordList curPointZoneNames = mesh_.pointZones().names();
if (curPointZoneNames.size()) if (curPointZoneNames.size())
{ {
pointZoneNames_.setCapacity(2*curPointZoneNames.size()); pointZoneNames_.setCapacity(2*curPointZoneNames.size());
@ -154,7 +154,7 @@ Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
} }
// Face zones // Face zones
wordList curFaceZoneNames = faceZones().names(); wordList curFaceZoneNames = mesh_.faceZones().names();
if (curFaceZoneNames.size()) if (curFaceZoneNames.size())
{ {
@ -166,7 +166,7 @@ Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
} }
// Cell zones // Cell zones
wordList curCellZoneNames = cellZones().names(); wordList curCellZoneNames = mesh_.cellZones().names();
if (curCellZoneNames.size()) if (curCellZoneNames.size())
{ {
@ -367,20 +367,26 @@ void Foam::mergePolyMesh::addMesh(const polyMesh& m)
void Foam::mergePolyMesh::merge() void Foam::mergePolyMesh::merge()
{ {
Info<< "patch names: " << patchNames_ << nl if (debug)
<< "patch dicts: " << patchDicts_ << nl {
<< "point zone names: " << pointZoneNames_ << nl Info<< "patch names: " << patchNames_ << nl
<< "face zone names: " << faceZoneNames_ << nl << "patch dicts: " << patchDicts_ << nl
<< "cell zone names: " << cellZoneNames_ << endl; << "point zone names: " << pointZoneNames_ << nl
<< "face zone names: " << faceZoneNames_ << nl
<< "cell zone names: " << cellZoneNames_ << endl;
}
// Add the patches if necessary // Add the patches if necessary
if (patchNames_.size() != boundaryMesh().size()) if (patchNames_.size() != mesh_.boundaryMesh().size())
{ {
Info<< "Copying old patches" << endl; if (debug)
{
Info<< "Copying old patches" << endl;
}
List<polyPatch*> newPatches(patchNames_.size()); List<polyPatch*> newPatches(patchNames_.size());
const polyBoundaryMesh& oldPatches = boundaryMesh(); const polyBoundaryMesh& oldPatches = mesh_.boundaryMesh();
// Note. Re-using counter in two for loops // Note. Re-using counter in two for loops
label patchi = 0; label patchi = 0;
@ -390,7 +396,10 @@ void Foam::mergePolyMesh::merge()
newPatches[patchi] = oldPatches[patchi].clone(oldPatches).ptr(); newPatches[patchi] = oldPatches[patchi].clone(oldPatches).ptr();
} }
Info<< "Adding new patches. " << endl; if (debug)
{
Info<< "Adding new patches. " << endl;
}
label endOfLastPatch = label endOfLastPatch =
patchi == 0 patchi == 0
@ -416,21 +425,25 @@ void Foam::mergePolyMesh::merge()
); );
} }
removeBoundary(); mesh_.removeBoundary();
addPatches(newPatches); mesh_.addPatches(newPatches);
} }
// Add the zones if necessary // Add the zones if necessary
if (pointZoneNames_.size() > pointZones().size()) if (pointZoneNames_.size() > mesh_.pointZones().size())
{ {
Info<< "Adding new pointZones. " << endl; if (debug)
label nZones = pointZones().size(); {
Info<< "Adding new pointZones. " << endl;
}
pointZones().setSize(pointZoneNames_.size()); label nZones = mesh_.pointZones().size();
mesh_.pointZones().setSize(pointZoneNames_.size());
for (label zoneI = nZones; zoneI < pointZoneNames_.size(); zoneI++) for (label zoneI = nZones; zoneI < pointZoneNames_.size(); zoneI++)
{ {
pointZones().set mesh_.pointZones().set
( (
zoneI, zoneI,
new pointZone new pointZone
@ -438,22 +451,26 @@ void Foam::mergePolyMesh::merge()
pointZoneNames_[zoneI], pointZoneNames_[zoneI],
labelList(), labelList(),
zoneI, zoneI,
pointZones() mesh_.pointZones()
) )
); );
} }
} }
if (cellZoneNames_.size() > cellZones().size())
if (cellZoneNames_.size() > mesh_.cellZones().size())
{ {
Info<< "Adding new cellZones. " << endl; if (debug)
{
Info<< "Adding new cellZones. " << endl;
}
label nZones = cellZones().size(); label nZones = mesh_.cellZones().size();
cellZones().setSize(cellZoneNames_.size()); mesh_.cellZones().setSize(cellZoneNames_.size());
for (label zoneI = nZones; zoneI < cellZoneNames_.size(); zoneI++) for (label zoneI = nZones; zoneI < cellZoneNames_.size(); zoneI++)
{ {
cellZones().set mesh_.cellZones().set
( (
zoneI, zoneI,
new cellZone new cellZone
@ -461,22 +478,26 @@ void Foam::mergePolyMesh::merge()
cellZoneNames_[zoneI], cellZoneNames_[zoneI],
labelList(), labelList(),
zoneI, zoneI,
cellZones() mesh_.cellZones()
) )
); );
} }
} }
if (faceZoneNames_.size() > faceZones().size())
if (faceZoneNames_.size() > mesh_.faceZones().size())
{ {
Info<< "Adding new faceZones. " << endl; if (debug)
{
Info<< "Adding new faceZones. " << endl;
}
label nZones = faceZones().size(); label nZones = mesh_.faceZones().size();
faceZones().setSize(faceZoneNames_.size()); mesh_.faceZones().setSize(faceZoneNames_.size());
for (label zoneI = nZones; zoneI < faceZoneNames_.size(); zoneI++) for (label zoneI = nZones; zoneI < faceZoneNames_.size(); zoneI++)
{ {
faceZones().set mesh_.faceZones().set
( (
zoneI, zoneI,
new faceZone new faceZone
@ -485,14 +506,14 @@ void Foam::mergePolyMesh::merge()
labelList(), labelList(),
boolList(), boolList(),
zoneI, zoneI,
faceZones() mesh_.faceZones()
) )
); );
} }
} }
// Change mesh. No inflation // Change mesh. No inflation
meshMod_.changeMesh(*this, false); meshMod_.changeMesh(mesh_, false);
// Clear topo change for the next operation // Clear topo change for the next operation
meshMod_.clear(); meshMod_.clear();

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -25,7 +25,7 @@ Class
Foam::mergePolyMesh Foam::mergePolyMesh
Description Description
Add a given mesh to the original mesh to create a single new mesh Merge meshes into a single mesh without stitching.
SourceFiles SourceFiles
mergePolyMesh.C mergePolyMesh.C
@ -48,11 +48,12 @@ namespace Foam
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class mergePolyMesh class mergePolyMesh
:
public polyMesh
{ {
// Private Data // Private Data
//- The master mesh the other meshes are merged into
polyMesh& mesh_;
//- Topological change to accumulated all mesh changes //- Topological change to accumulated all mesh changes
polyTopoChange meshMod_; polyTopoChange meshMod_;
@ -89,11 +90,8 @@ public:
// Constructors // Constructors
//- Construct from IOobject //- Construct from polyMesh
mergePolyMesh(const IOobject& io); mergePolyMesh(polyMesh& mesh);
//- Disallow default bitwise copy construction
mergePolyMesh(const mergePolyMesh&) = delete;
//- Destructor //- Destructor

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2023 OpenFOAM Foundation \\ / A nd | Copyright (C) 2023-2024 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -124,17 +124,15 @@ int main(int argc, char *argv[])
runTime++; runTime++;
} }
// Stitch the patch-pairs // Stitch all the patch-pairs
mergePatchPairs(mesh, patchPairNames, snapTol); mergePatchPairs(mesh, patchPairNames, snapTol);
// Write mesh
if (overwrite) if (overwrite)
{ {
mesh.setInstance(oldInstance); mesh.setInstance(oldInstance);
} }
Info<< "Writing mesh to " << mesh.facesInstance() << endl; Info<< "Writing mesh to " << mesh.facesInstance() << endl;
mesh.write(); mesh.write();
Info<< "End\n" << endl; Info<< "End\n" << endl;