diff --git a/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C b/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C index 6ab578d722..78df05d192 100644 --- a/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C +++ b/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C @@ -45,7 +45,6 @@ Description #include "volFields.H" #include "topoDistanceData.H" #include "FaceCellWave.H" -#include "BitOps.H" #include "cellSet.H" #include "faceSet.H" #include "pointSet.H" @@ -56,16 +55,33 @@ using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Get the exposed patchId or define the exposedPatchName in fvMeshSubset +label getExposedPatchId(const polyMesh& mesh, const word& patchName) +{ + const label patchId = mesh.boundaryMesh().findPatchID(patchName); + + if (patchId == -1) + { + fvMeshSubset::exposedPatchName = patchName; + } + + Info<< "Adding exposed internal faces to " + << (patchId == -1 ? "new" : "existing") + << " patch \"" << patchName << "\"" << nl << endl; + + return patchId; +} + + labelList nearestPatch(const polyMesh& mesh, const labelList& patchIDs) { const polyBoundaryMesh& pbm = mesh.boundaryMesh(); // Count number of faces in exposedPatchIDs label nFaces = 0; - forAll(patchIDs, i) + for (const label patchi : patchIDs) { - const polyPatch& pp = pbm[patchIDs[i]]; - nFaces += pp.size(); + nFaces += pbm[patchi].size(); } // Field on cells and faces. @@ -76,16 +92,15 @@ labelList nearestPatch(const polyMesh& mesh, const labelList& patchIDs) labelList patchFaces(nFaces); List patchData(nFaces); nFaces = 0; - forAll(patchIDs, i) + for (const label patchi : patchIDs) { - label patchI = patchIDs[i]; - const polyPatch& pp = pbm[patchI]; + const polyPatch& pp = pbm[patchi]; forAll(pp, i) { patchFaces[nFaces] = pp.start()+i; - patchData[nFaces] = topoDistanceData(patchI, 0); - nFaces++; + patchData[nFaces] = topoDistanceData(patchi, 0); + ++nFaces; } } @@ -150,15 +165,17 @@ void subsetFields const fvMesh& baseMesh = subsetter.baseMesh(); - if (fieldNames.empty()) + label nFields = 0; + for (const word& fieldName : fieldNames) { - return; - } - Info<< "Subsetting " << fieldType << " ("; - forAll(fieldNames, i) - { - const word& fieldName = fieldNames[i]; - if (i) Info<< ' '; + if (!nFields) + { + Info<< "Subsetting " << fieldType << " ("; + } + else + { + Info<< ' '; + } Info<< fieldName; FieldType fld @@ -174,12 +191,18 @@ void subsetFields baseMesh ); - subFields.set(i, subsetter.interpolate(fld)); + subFields.set(nFields, subsetter.interpolate(fld)); // Subsetting adds 'subset' prefix - rename to match original. - subFields[i].rename(fieldName); + subFields[nFields].rename(fieldName); + + ++nFields; + } + + if (nFields) + { + Info<< ')' << nl; } - Info<< ")" << nl; } @@ -200,15 +223,17 @@ void subsetPointFields const fvMesh& baseMesh = subsetter.baseMesh(); - if (fieldNames.empty()) + label nFields = 0; + for (const word& fieldName : fieldNames) { - return; - } - Info<< "Subsetting " << fieldType << " ("; - forAll(fieldNames, i) - { - const word& fieldName = fieldNames[i]; - if (i) Info<< ' '; + if (!nFields) + { + Info<< "Subsetting " << fieldType << " ("; + } + else + { + Info<< ' '; + } Info<< fieldName; FieldType fld @@ -224,12 +249,18 @@ void subsetPointFields pMesh ); - subFields.set(i, subsetter.interpolate(fld)); + subFields.set(nFields, subsetter.interpolate(fld)); // Subsetting adds 'subset' prefix - rename to match original. - subFields[i].rename(fieldName); + subFields[nFields].rename(fieldName); + + ++nFields; + } + + if (nFields) + { + Info<< ')' << nl; } - Info<< ")" << nl; } @@ -249,15 +280,17 @@ void subsetDimensionedFields const fvMesh& baseMesh = subsetter.baseMesh(); - if (fieldNames.empty()) + label nFields = 0; + for (const word& fieldName : fieldNames) { - return; - } - Info<< "Subsetting " << fieldType << " ("; - forAll(fieldNames, i) - { - const word& fieldName = fieldNames[i]; - if (i) Info<< ' '; + if (!nFields) + { + Info<< "Subsetting " << fieldType << " ("; + } + else + { + Info<< ' '; + } Info<< fieldName; FieldType fld @@ -273,12 +306,18 @@ void subsetDimensionedFields baseMesh ); - subFields.set(i, subsetter.interpolate(fld)); + subFields.set(nFields, subsetter.interpolate(fld)); // Subsetting adds 'subset' prefix - rename to match original. - subFields[i].rename(fieldName); + subFields[nFields].rename(fieldName); + + ++nFields; + } + + if (nFields) + { + Info<< ')' << nl; } - Info<< ")" << nl; } @@ -297,40 +336,33 @@ void subsetTopoSets ReadFields(objects, sets); subSets.setSize(sets.size()); - forAll(sets, i) + forAll(sets, seti) { - TopoSet& set = sets[i]; + const TopoSet& set = sets[seti]; Info<< "Subsetting " << set.type() << " " << set.name() << endl; - // Map the data - bitSet isSet(set.maxSize(mesh)); - forAllConstIters(set, iter) + labelHashSet subset(2*min(set.size(), map.size())); + + for (const label id : map) { - isSet.set(iter.key()); - } - label nSet = 0; - forAll(map, i) - { - if (isSet.test(map[i])) + if (set.found(id)) { - ++nSet; + subset.insert(id); } } subSets.set ( - i, - new TopoSet(subMesh, set.name(), nSet, IOobject::AUTO_WRITE) + seti, + new TopoSet + ( + subMesh, + set.name(), + std::move(subset), + IOobject::AUTO_WRITE + ) ); - TopoSet& subSet = subSets[i]; - forAll(map, i) - { - if (isSet.test(map[i])) - { - subSet.insert(i); - } - } } } @@ -340,25 +372,32 @@ int main(int argc, char *argv[]) { argList::addNote ( - "Select a mesh subset based on a cellSet" + "Select a mesh subset based on a cellSet or on cellZone(s) specified " + "as the first command argument." ); #include "addOverwriteOption.H" #include "addRegionOption.H" - argList::addArgument("cellSet"); + argList::addArgument("setOrZoneName"); argList::addOption ( "patch", "name", - "Add exposed internal faces to specified patch instead of to " - "'oldInternalFaces'" + "Add exposed internal faces to specified patch " + "instead of \"oldInternalFaces\"" ); argList::addOption ( "patches", - "names", - "Add exposed internal faces to nearest of specified patches" - " instead of to 'oldInternalFaces'" + "wordRes", + "Add exposed internal faces to closest of specified patches " + "instead of \"oldInternalFaces\"" + ); + argList::addBoolOption + ( + "zone", + "Subset with cellZone(s) instead of cellSet. " + "The command argument may be a list of words or regexs" ); argList::addOption ( @@ -374,11 +413,13 @@ int main(int argc, char *argv[]) #include "createNamedMesh.H" - const word selectionName = args[1]; + // arg[1] = word (cellSet) or wordRes (cellZone) + // const word selectionName = args[1]; word meshInstance = mesh.pointsInstance(); word fieldsInstance = runTime.timeName(); + const bool useCellZone = args.found("zone"); const bool overwrite = args.found("overwrite"); const bool specifiedInstance = args.readIfPresent ( @@ -391,8 +432,6 @@ int main(int argc, char *argv[]) meshInstance = fieldsInstance; } - Info<< "Reading cell set from " << selectionName << nl << endl; - // Default exposed patch id labelList exposedPatchIDs(one(), -1); @@ -401,51 +440,81 @@ int main(int argc, char *argv[]) { const wordRes patchNames(args.getList("patches")); - exposedPatchIDs = mesh.boundaryMesh().patchSet(patchNames).sortedToc(); - - Info<< "Adding exposed internal faces to nearest of patches " - << flatOutput(patchNames) << nl << endl; - - if (exposedPatchIDs.empty()) + if (patchNames.size() == 1 && !patchNames.first().isPattern()) { - FatalErrorInFunction - << nl << "No patches matched. Patches: " - << mesh.boundaryMesh().names() - << exit(FatalError); + exposedPatchIDs.first() = + getExposedPatchId(mesh, patchNames.first()); + } + else + { + exposedPatchIDs = + mesh.boundaryMesh().patchSet(patchNames).sortedToc(); + + Info<< "Adding exposed internal faces to nearest of patches " + << flatOutput(patchNames) << nl << endl; + + if (exposedPatchIDs.empty()) + { + FatalErrorInFunction + << nl << "No patches matched. Patches: " + << mesh.boundaryMesh().names() << nl + << exit(FatalError); + } } } else if (args.found("patch")) { - const word patchName = args["patch"]; + exposedPatchIDs.first() = + getExposedPatchId(mesh, args["patch"]); + } + else + { + Info<< "Adding exposed internal faces to patch \"" + << fvMeshSubset::exposedPatchName + << "\" (created if necessary)" << nl + << nl; + } - exposedPatchIDs.first() = mesh.boundaryMesh().findPatchID(patchName); - Info<< "Adding exposed internal faces to patch " << patchName - << nl << endl; + autoPtr cellSetPtr; - if (exposedPatchIDs.first() == -1) + // arg[1] can be a word (for cellSet) or wordRes (for cellZone) + + wordRes zoneNames; + if (useCellZone) + { + List selectionNames = args.getList(1); + zoneNames.transfer(selectionNames); + + Info<< "Using cellZone " << flatOutput(zoneNames) << nl << endl; + + if (mesh.cellZones().findIndex(zoneNames) == -1) { FatalErrorInFunction - << nl << "No such patch. Patches: " - << mesh.boundaryMesh().names() + << "No cellZones found: " << flatOutput(zoneNames) << nl << nl << exit(FatalError); } } else { - Info<< "Adding exposed internal faces to a patch called" - << " \"oldInternalFaces\" (created if necessary)" << endl - << endl; + const word selectionName = args[1]; + + Info<< "Using cellSet " << selectionName << nl << endl; + + cellSetPtr = autoPtr::New(mesh, selectionName); } // Mesh subsetting engine fvMeshSubset subsetter(mesh); - cellSet currentSet(mesh, selectionName); - { - bitSet selectedCells = BitSetOps::create(mesh.nCells(), currentSet); + bitSet selectedCells = + ( + cellSetPtr + ? BitSetOps::create(mesh.nCells(), *cellSetPtr) + : mesh.cellZones().selection(zoneNames) + ); if (exposedPatchIDs.size() == 1) { @@ -475,6 +544,12 @@ int main(int argc, char *argv[]) true ); } + + Info<< "Subset " + << returnReduce(subsetter.subMesh().nCells(), sumOp