diff --git a/applications/utilities/surface/surfaceSplitByPatch/surfaceSplitByPatch.C b/applications/utilities/surface/surfaceSplitByPatch/surfaceSplitByPatch.C index f49d334e5b..bc35115335 100644 --- a/applications/utilities/surface/surfaceSplitByPatch/surfaceSplitByPatch.C +++ b/applications/utilities/surface/surfaceSplitByPatch/surfaceSplitByPatch.C @@ -31,12 +31,33 @@ Group grpSurfaceUtilities Description - Writes regions of triSurface to separate files. + Writes surface regions to separate files. + +Usage + \b surfaceSplitByPatch [OPTION] + + Options: + - \par -patches NAME | LIST + Specify single patch or multiple patches (name or regex) to extract + For example, + \verbatim + -patches top + -patches '( front \".*back\" )' + \endverbatim + + - \par -excludePatches NAME | LIST + Specify single or multiple patches (name or regex) not to extract. + For example, + \verbatim + -excludePatches '( inlet_1 inlet_2 "proc.*")' + \endverbatim \*---------------------------------------------------------------------------*/ #include "argList.H" -#include "triSurface.H" +#include "MeshedSurfaces.H" +#include "stringListOps.H" +#include "geometricSurfacePatch.H" using namespace Foam; @@ -48,65 +69,103 @@ int main(int argc, char *argv[]) ( "Write surface mesh regions to separate files" ); - argList::noParallel(); + argList::addOption + ( + "patches", + "wordRes", + "Specify single patch or multiple patches to write\n" + "Eg, 'top' or '( front \".*back\" )'" + ); + argList::addOption + ( + "excludePatches", + "wordRes", + "Specify single patch or multiple patches to exclude from writing." + " Eg, 'outlet' or '( inlet \".*Wall\" )'" + ); + argList::addArgument("input", "The input surface file"); + argList args(argc, argv); const fileName surfName = args[1]; - Info<< "Reading surf from " << surfName << " ..." << nl << endl; + const fileName surfBase(surfName.lessExt()); - fileName surfBase = surfName.lessExt(); - - word extension = surfName.ext(); - - triSurface surf(surfName); - - Info<< "Writing regions to separate files ..." - << nl << endl; + const word extension(surfName.ext()); - const geometricSurfacePatchList& patches = surf.patches(); + Info<< nl + << "Read surface from " << surfName << " ..." << nl << endl; - forAll(patches, patchi) + meshedSurface surf(surfName); + + const surfZoneList& zones = surf.surfZones(); + + Info<< " " << surf.size() << " faces with " + << zones.size() << " zones" << nl << nl; + + + wordRes includePatches, excludePatches; + + if (args.readListIfPresent("patches", includePatches)) { - const geometricSurfacePatch& pp = patches[patchi]; + Info<< "Including patches " << flatOutput(includePatches) + << nl << endl; + } + if (args.readListIfPresent("excludePatches", excludePatches)) + { + Info<< "Excluding patches " << flatOutput(excludePatches) + << nl << endl; + } - word patchName(pp.name()); + // Identity if both whitelist and blacklist are empty + const labelList zoneIndices + ( + stringListOps::findMatching + ( + zones, + includePatches, + excludePatches, + nameOp() + ) + ); + + + Info<< "Writing regions to " + << zoneIndices.size() << " separate files ..." << nl << endl; + + + // Faces to subset + bitSet includeMap(surf.size()); + + for (const label zonei : zoneIndices) + { + const surfZone& zn = zones[zonei]; + + includeMap.reset(); + includeMap.set(zn.range()); + + word patchName(zn.name()); if (patchName.empty()) { - patchName = geometricSurfacePatch::defaultName(patchi); + // In case people expect the same names as with triSurface + patchName = geometricSurfacePatch::defaultName(zonei); } fileName outFile(surfBase + '_' + patchName + '.' + extension); - Info<< " Writing patch " << patchName << " to file " << outFile - << endl; + Info<< " Zone " << zonei << " (" << zn.size() << " faces) " + << patchName + << " to file " << outFile << nl; - - // Collect faces of region - boolList includeMap(surf.size(), false); - - forAll(surf, facei) - { - const labelledTri& f = surf[facei]; - - if (f.region() == patchi) - { - includeMap[facei] = true; - } - } - - // Subset triSurface - - triSurface subSurf(surf.subsetMesh(includeMap)); - - subSurf.write(outFile); + // Subset and write + surf.subsetMesh(includeMap).write(outFile); } - Info<< "End\n" << endl; + Info<< "\nEnd\n" << endl; return 0; } diff --git a/applications/utilities/surface/surfaceSubset/surfaceSubset.C b/applications/utilities/surface/surfaceSubset/surfaceSubset.C index 3050d05469..04031d3f04 100644 --- a/applications/utilities/surface/surfaceSubset/surfaceSubset.C +++ b/applications/utilities/surface/surfaceSubset/surfaceSubset.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2015-2019 OpenCFD Ltd. + Copyright (C) 2015-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -36,8 +36,8 @@ Description \*---------------------------------------------------------------------------*/ -#include "triSurface.H" #include "triSurfaceSearch.H" +#include "MeshedSurfaces.H" #include "argList.H" #include "Fstream.H" #include "IOdictionary.H" @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) { argList::addNote ( - "A surface analysis tool that subsets the triSurface to choose a" + "A surface analysis tool that subsets the surface to choose a" " region of interest." ); @@ -71,7 +71,8 @@ int main(int argc, char *argv[]) dictionary meshSubsetDict(dictFile); Info<< "Reading surface " << args[2] << " ..." << endl; - triSurface surf1(args[2]); + + meshedSurface surf1(args[2]); const fileName outFileName(args[3]); @@ -101,134 +102,115 @@ int main(int argc, char *argv[]) meshSubsetDict.lookup("zone") ); - if (markedZone.size() && markedZone.size() != 2) + + boundBox zoneBb; + + if (markedZone.size()) { - FatalErrorInFunction - << "zone specification should be two points, min and max of " - << "the boundingbox" << endl - << "zone:" << markedZone - << exit(FatalError); + if (markedZone.size() != 2) + { + FatalErrorInFunction + << "zone specification should be two points, min and max of " + << "the boundingbox" << endl + << "zone:" << markedZone + << exit(FatalError); + } + + zoneBb.min() = markedZone[0]; + zoneBb.max() = markedZone[1]; + + if (!zoneBb.valid()) + { + WarningInFunction + << "Defined zone is invalid: " << zoneBb << nl; + } } + const bool addFaceNeighbours = meshSubsetDict.get("addFaceNeighbours"); const bool invertSelection = - meshSubsetDict.lookupOrDefault("invertSelection", false); + meshSubsetDict.getOrDefault("invertSelection", false); // Mark the cells for the subset // Faces to subset - boolList facesToSubset(surf1.size(), false); + bitSet facesToSubset(surf1.size(), false); // - // pick up faces connected to "localPoints" + // Faces connected to "localPoints" // if (markedPoints.size()) { Info<< "Found " << markedPoints.size() << " marked point(s)." << endl; - // pick up cells sharing the point - - forAll(markedPoints, pointi) + for (const label pointi : markedPoints) { - if - ( - markedPoints[pointi] < 0 - || markedPoints[pointi] >= surf1.nPoints() - ) + if (pointi < 0 || pointi >= surf1.nPoints()) { FatalErrorInFunction - << "localPoint label " << markedPoints[pointi] - << "out of range." - << " The mesh has got " - << surf1.nPoints() << " localPoints." + << "localPoint label " << pointi << "out of range." + << " Surface has " << surf1.nPoints() << " localPoints." << exit(FatalError); } - const labelList& curFaces = - surf1.pointFaces()[markedPoints[pointi]]; + const labelList& curFaces = surf1.pointFaces()[pointi]; - forAll(curFaces, i) - { - facesToSubset[curFaces[i]] = true; - } + facesToSubset.set(curFaces); } } - // - // pick up faces connected to "edges" + // Faces connected to "edges" // if (markedEdges.size()) { Info<< "Found " << markedEdges.size() << " marked edge(s)." << endl; - // pick up cells sharing the edge - - forAll(markedEdges, edgeI) + for (const label edgei : markedEdges) { - if - ( - markedEdges[edgeI] < 0 - || markedEdges[edgeI] >= surf1.nEdges() - ) + if (edgei < 0 || edgei >= surf1.nEdges()) { FatalErrorInFunction - << "edge label " << markedEdges[edgeI] - << "out of range." - << " The mesh has got " - << surf1.nEdges() << " edges." + << "edge label " << edgei << "out of range." + << " Surface has " << surf1.nEdges() << " edges." << exit(FatalError); } - const labelList& curFaces = surf1.edgeFaces()[markedEdges[edgeI]]; + const labelList& curFaces = surf1.edgeFaces()[edgei]; - forAll(curFaces, i) - { - facesToSubset[curFaces[i]] = true; - } + facesToSubset.set(curFaces); } } // - // pick up faces with centre inside "zone" + // Faces with centre inside "zone" // - if (markedZone.size() == 2) + if (zoneBb.valid()) { - const point& min = markedZone[0]; - const point& max = markedZone[1]; - - Info<< "Using zone min:" << min << " max:" << max << endl; + Info<< "Using zone " << zoneBb << endl; forAll(surf1, facei) { const point centre = surf1[facei].centre(surf1.points()); - if - ( - (centre.x() >= min.x()) - && (centre.y() >= min.y()) - && (centre.z() >= min.z()) - && (centre.x() <= max.x()) - && (centre.y() <= max.y()) - && (centre.z() <= max.z()) - ) + if (zoneBb.contains(centre)) { - facesToSubset[facei] = true; + facesToSubset.set(facei); } } } // - // pick up faces on certain side of surface + // Faces on certain side of surface // if (meshSubsetDict.found("surface")) @@ -237,18 +219,16 @@ int main(int argc, char *argv[]) const fileName surfName(surfDict.get("name")); - const bool outside(surfDict.get("outside")); + const volumeType::type volType = + ( + surfDict.getOrDefault("outside", false) + ? volumeType::OUTSIDE + : volumeType::INSIDE + ); - if (outside) - { - Info<< "Selecting all triangles with centre outside surface " - << surfName << endl; - } - else - { - Info<< "Selecting all triangles with centre inside surface " - << surfName << endl; - } + Info<< "Selecting faces with centre located " + << volumeType::names[volType] << " of surface " + << surfName << endl; // Read surface to select on triSurface selectSurf(surfName); @@ -264,22 +244,15 @@ int main(int argc, char *argv[]) searchSelectSurf.tree(); // Check if face (centre) is in outside or inside. - forAll(facesToSubset, facei) + forAll(surf1, facei) { if (!facesToSubset[facei]) { const point fc(surf1[facei].centre(surf1.points())); - volumeType t = selectTree.getVolumeType(fc); - - if - ( - outside - ? (t == volumeType::OUTSIDE) - : (t == volumeType::INSIDE) - ) + if (volType == selectTree.getVolumeType(fc)) { - facesToSubset[facei] = true; + facesToSubset.set(facei); } } } @@ -304,7 +277,7 @@ int main(int argc, char *argv[]) if (pl.distance(fc) < distance && mag(pl.normal() & nf) > cosAngle) { - facesToSubset[facei] = true; + facesToSubset.set(facei); } } } @@ -323,38 +296,29 @@ int main(int argc, char *argv[]) Info<< "Found " << markedFaces.size() << " marked face(s)." << endl; // Check and mark faces to pick up - forAll(markedFaces, facei) + for (const label facei : markedFaces) { - if - ( - markedFaces[facei] < 0 - || markedFaces[facei] >= surf1.size() - ) + if (facei < 0 || facei >= surf1.size()) { FatalErrorInFunction - << "Face label " << markedFaces[facei] << "out of range." - << " The mesh has got " - << surf1.size() << " faces." + << "Face label " << facei << "out of range." + << " Surface has " << surf1.size() << " faces." << exit(FatalError); } // Mark the face - facesToSubset[markedFaces[facei]] = true; + facesToSubset.set(facei); - // mark its neighbours if requested + // Mark its neighbours if requested if (addFaceNeighbours) { - const labelList& curFaces = - surf1.faceFaces()[markedFaces[facei]]; + const labelList& curFaces = surf1.faceFaces()[facei]; - forAll(curFaces, i) + for (const label neiFacei : curFaces) { - label facei = curFaces[i]; - - if (!facesToSubset[facei]) + if (facesToSubset.set(neiFacei)) { - facesToSubset[facei] = true; - nFaceNeighbours++; + ++nFaceNeighbours; } } } @@ -372,15 +336,12 @@ int main(int argc, char *argv[]) { Info<< "Inverting selection." << endl; - forAll(facesToSubset, i) - { - facesToSubset[i] = facesToSubset[i] ? false : true; - } + facesToSubset.flip(); } // Create subsetted surface - triSurface surf2(surf1.subsetMesh(facesToSubset)); + meshedSurface surf2(surf1.subsetMesh(facesToSubset)); Info<< "Subset:" << endl; surf2.writeStats(Info);