This repository has been archived on 2023-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
foam-extend4.1-coherent-io/applications/utilities/mesh/generation/cfMesh/mergeSurfacePatches/mergeSurfacePatches.C

405 lines
9.9 KiB
C++
Raw Normal View History

2014-11-09 00:10:28 +00:00
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
2014-11-09 00:10:28 +00:00
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
2014-11-09 00:10:28 +00:00
foam-extend is free software: you can redistribute it and/or modify it
2014-11-09 00:10:28 +00:00
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
2014-11-09 00:10:28 +00:00
option) any later version.
foam-extend 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.
2014-11-09 00:10:28 +00:00
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
2014-11-09 00:10:28 +00:00
Description
cfMesh utility to merge the supplied list of patches onto a single
patch.
Author
Ivor Clifford <ivor.clifford@psi.ch>
\*---------------------------------------------------------------------------*/
#include "argList.H"
2015-08-06 22:56:00 +00:00
#include "objectRegistry.H"
#include "foamTime.H"
2015-08-06 22:56:00 +00:00
#include "autoPtr.H"
2014-11-09 00:10:28 +00:00
#include "triSurf.H"
#include "triSurfModifier.H"
#include "demandDrivenData.H"
#include "Pair.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Find the supplied list of patch names and return a list of patch Ids
void getPatchIds
(
const triSurf& origSurf,
const wordList& patchNames,
DynamicList<label>& patchIds
)
{
const geometricSurfacePatchList& origPatches = origSurf.patches();
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Create patch name map
HashSet<word> patchNameHash(patchNames);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Find selected patches
label nFound = 0;
forAll(origPatches, patchI)
{
if (patchNameHash.found(origPatches[patchI].name()))
{
patchIds.append(patchI);
nFound++;
}
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
if (nFound != patchNames.size())
{
WarningIn("getPatchIds")
<< "Not all supplied patch names were found on the surface mesh" << endl;
}
}
// Copy all face subsets from one triSurf to another
void copyFaceSubsets
(
const triSurf& origSurf,
triSurf& newSurf
)
{
DynList<label> subsetIds;
origSurf.facetSubsetIndices(subsetIds);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
forAll(subsetIds, subsetI)
{
label newSubsetId = newSurf.addFacetSubset
(
origSurf.facetSubsetName(subsetI)
);
2015-05-15 13:57:39 +00:00
labelList origFaces;
2014-11-09 00:10:28 +00:00
origSurf.facetsInSubset(subsetI, origFaces);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
forAll(origFaces, faceI)
{
newSurf.addFacetToSubset
(
newSubsetId,
origFaces[faceI]
);
}
}
}
// Copy all edge subsets from one triSurf to another
void copyEdgeSubsets
(
const triSurf& origSurf,
triSurf& newSurf
)
{
DynList<label> subsetIds;
origSurf.edgeSubsetIndices(subsetIds);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
forAll(subsetIds, subsetI)
{
label newSubsetId = newSurf.addEdgeSubset
(
origSurf.edgeSubsetName(subsetI)
);
2015-05-15 13:57:39 +00:00
labelList origEdges;
2014-11-09 00:10:28 +00:00
origSurf.edgesInSubset(subsetI, origEdges);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
forAll(origEdges, faceI)
{
newSurf.addEdgeToSubset
(
newSubsetId,
origEdges[faceI]
);
}
}
}
// Copy all point subsets from one triSurf to another
void copyPointSubsets
(
const triSurf& origSurf,
triSurf& newSurf
)
{
DynList<label> subsetIds;
origSurf.pointSubsetIndices(subsetIds);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
forAll(subsetIds, subsetI)
{
label newSubsetId = newSurf.addPointSubset
(
origSurf.pointSubsetName(subsetI)
);
2015-05-15 13:57:39 +00:00
labelList origPoints;
2014-11-09 00:10:28 +00:00
origSurf.pointsInSubset(subsetI, origPoints);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
forAll(origPoints, faceI)
{
newSurf.addPointToSubset
(
newSubsetId,
origPoints[faceI]
);
}
}
}
// Merge the supplied list of patchIds onto a new patch
autoPtr<triSurf> mergeSurfacePatches
(
const triSurf& origSurf, // Surface
const UList<label>& patchIds, // Ids of patches to merge
const word& newPatchName, // Name of new (merged) patch
bool keepPatches // Keep the original patches - they will be emptied
)
{
const geometricSurfacePatchList& origPatches = origSurf.patches();
const LongList<labelledTri>& origFacets = origSurf.facets();
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
label newPatchId = origPatches.size();
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Determine new patch type
word newPatchType = origPatches[patchIds[0]].geometricType();
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Create patch addressing
List<DynamicList<label> > patchAddr(origPatches.size()+1);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
forAll(origFacets, faceI)
{
patchAddr[origFacets[faceI].region()].append(faceI);
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Move selected patches to new patch
forAll(patchIds, patchI)
{
patchAddr[newPatchId].append(patchAddr[patchIds[patchI]]);
patchAddr[patchIds[patchI]].clear();
}
// Create new facets list
LongList<labelledTri> newFacets(origFacets.size());
labelList newFaceAddr(origFacets.size(), -1);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
label patchCount = 0;
label faceI = 0;
forAll(patchAddr, patchI)
{
const unallocLabelList& addr = patchAddr[patchI];
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
if(addr.size())
{
forAll(addr, i)
{
newFacets[faceI] = origFacets[addr[i]];
newFacets[faceI].region() = patchCount;
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
newFaceAddr[addr[i]] = faceI;
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
faceI++;
}
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
if(addr.size() || keepPatches)
{
patchCount++;
}
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Create new patch list
geometricSurfacePatchList newPatches(patchCount);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
patchCount = 0;
forAll(origPatches, patchI)
{
// Only add patches if they contain faces
if(patchAddr[patchI].size())
{
newPatches[patchCount] = origPatches[patchI];
newPatches[patchCount].index() = patchCount;
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
if(patchAddr[patchI].size() || keepPatches)
{
patchCount++;
}
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Add new patch if it contains faces
if(patchAddr[patchAddr.size()-1].size())
{
newPatches[patchCount] = geometricSurfacePatch
(
newPatchType,
newPatchName,
patchCount
);
}
if(patchAddr[patchAddr.size()-1].size() || keepPatches)
{
patchCount++;
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Create new surface
autoPtr<triSurf> newSurf
(
new triSurf
(
newFacets,
newPatches,
origSurf.featureEdges(),
origSurf.points()
)
);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Transfer face subsets
copyFaceSubsets(origSurf, newSurf());
newSurf->updateFacetsSubsets(newFaceAddr);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Transfer feature edge subsets
copyEdgeSubsets(origSurf, newSurf());
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Transfer point subsets
copyPointSubsets(origSurf, newSurf());
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Done
return newSurf;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::noParallel();
argList::validArgs.clear();
argList::validArgs.append("input surface file");
argList::validArgs.append("new patch");
argList::validOptions.insert("patchNames", "list of names");
argList::validOptions.insert("patchIds", "list of patchIds");
argList::validOptions.insert("patchIdRange", "( start end )");
argList::validOptions.insert("output", "file name (default overwrite)");
argList::validOptions.insert("keep", "");
argList args(argc, argv);
// Process commandline arguments
fileName inFileName(args.args()[1]);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
word newPatchName(args.args()[2]);
fileName outFileName(inFileName);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
if( args.options().found("output") )
{
outFileName = args.options()["output"];
}
bool keepPatches = false;
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
if( args.options().found("keep") )
{
keepPatches = true;
}
// Read original surface
triSurf origSurf(inFileName);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Get patch ids
DynamicList<label> patchIds;
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
if (args.options().found("patchNames"))
{
if (args.options().found("patchIds"))
{
FatalError() << "Cannot specify both patch names and ids"
<< Foam::abort(FatalError);
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
IStringStream is(args.options()["patchNames"]);
wordList patchNames(is);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
getPatchIds
(
origSurf,
patchNames,
patchIds
);
}
if (args.options().found("patchIds"))
{
IStringStream is(args.options()["patchIds"]);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
patchIds = labelList(is);
}
if (args.options().found("patchIds"))
{
IStringStream is(args.options()["patchIds"]);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
patchIds.append(labelList(is));
}
if (args.options().found("patchIdRange"))
{
IStringStream is(args.options()["patchIdRange"]);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
Pair<label> idRange(is);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
for(label id = idRange.first(); id <= idRange.second(); id++)
{
patchIds.append(id);
}
2015-05-15 13:57:39 +00:00
}
2014-11-09 00:10:28 +00:00
if (!patchIds.size())
{
FatalError() << "No patches specified"
<< Foam::abort(FatalError);
}
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Merge patches
autoPtr<triSurf> newSurf = mergeSurfacePatches
(
origSurf,
patchIds,
newPatchName,
keepPatches
);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
// Write new surface mesh
newSurf->writeSurface(outFileName);
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
Info << "Original surface patches: " << origSurf.patches().size() << endl;
Info << "Final surface patches: " << newSurf->patches().size() << endl;
Info << "Surface written to " << outFileName << endl;
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
Info << "End\n" << endl;
2015-05-15 13:57:39 +00:00
2014-11-09 00:10:28 +00:00
return 0;
}
// ************************************************************************* //