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
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -25,104 +25,163 @@ Application
mergeMeshes
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 "Time.H"
#include "timeSelector.H"
#include "mergePolyMesh.H"
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[])
{
argList::addNote
(
"merge two meshes"
);
argList::addNote("Merge meshes without stitching");
argList::noParallel();
#include "addOverwriteOption.H"
#include "addRegionOption.H"
argList::validArgs.append("masterCase");
argList::addOption
(
"masterRegion",
"name",
"specify alternative mesh region for the master mesh"
"addRegions",
"'(region1 region2 ... regionN)'"
"list of regions to merge"
);
argList::validArgs.append("addCase");
argList::addOption
(
"addRegion",
"name",
"specify alternative mesh region for the additional mesh"
"addCases",
"'(\"casePath1\" \"casePath2\" ... \"casePathN\")'",
"list of cases to merge"
);
argList args(argc, argv);
if (!args.check())
argList::addOption
(
"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 word oldInstance = mesh.pointsInstance();
fileName masterCase = args[1];
word masterRegion = polyMesh::defaultRegion;
args.optionReadIfPresent("masterRegion", masterRegion);
if (!overwrite)
{
runTime++;
}
fileName addCase = args[2];
word addRegion = polyMesh::defaultRegion;
args.optionReadIfPresent("addRegion", addRegion);
// Construct the mergePolyMesh class for the current mesh
mergePolyMesh mergeMeshes(mesh);
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
// Add all the specified region meshes
forAll(regions, i)
{
Info<< "Create polyMesh for region " << regions[i] << endl;
polyMesh meshToAdd
(
IOobject
(
masterRegion,
runTimeMaster.name(),
runTimeMaster
regions[i],
runTime.name(),
runTime
)
);
const word oldInstance = masterMesh.pointsInstance();
Info<< "Adding mesh " << meshToAdd.objectPath() << endl;
mergeMeshes.addMesh(meshToAdd);
}
Info<< "Reading mesh to add for time = " << runTimeToAdd.name() << nl;
// Add all the specified case meshes
forAll(caseRegions, i)
{
const fileName& addCase = caseRegions[i].first();
const word& addRegion = caseRegions[i].second();
Info<< "Create mesh\n" << endl;
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
@ -133,22 +192,20 @@ int main(int argc, char *argv[])
)
);
if (!overwrite)
{
runTimeMaster++;
Info<< "Adding mesh " << meshToAdd.objectPath() << endl;
mergeMeshes.addMesh(meshToAdd);
}
Info<< "Writing combined mesh to " << runTimeMaster.name() << endl;
masterMesh.addMesh(meshToAdd);
masterMesh.merge();
Info << nl << "Merging all meshes" << endl;
mergeMeshes.merge();
if (overwrite)
{
masterMesh.setInstance(oldInstance);
mesh.setInstance(oldInstance);
}
masterMesh.write();
Info<< "Writing mesh to " << mesh.facesInstance() << endl;
mesh.write();
Info<< "End\n" << endl;

View File

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

View File

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

View File

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