/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it 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 option) any later version. OpenFOAM 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. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . Application subsetMesh Description Selects a section of mesh based on a cellSet. The utility sub-sets the mesh to choose only a part of interest. Check the setSet/cellSet/topoSet utilities to see how to select cells based on various shapes. The mesh will subset all points, faces and cells needed to make a sub-mesh but will not preserve attached boundary types. \*---------------------------------------------------------------------------*/ #include "fvMeshSubset.H" #include "argList.H" #include "cellSet.H" #include "IOobjectList.H" #include "volFields.H" #include "topoDistanceData.H" #include "FaceCellWave.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 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) { const polyPatch& pp = pbm[patchIDs[i]]; nFaces += pp.size(); } // Field on cells and faces. List cellData(mesh.nCells()); List faceData(mesh.nFaces()); // Start of changes labelList patchFaces(nFaces); List patchData(nFaces); nFaces = 0; forAll(patchIDs, i) { label patchI = patchIDs[i]; const polyPatch& pp = pbm[patchI]; forAll(pp, i) { patchFaces[nFaces] = pp.start()+i; patchData[nFaces] = topoDistanceData(patchI, 0); nFaces++; } } // Propagate information inwards FaceCellWave deltaCalc ( mesh, patchFaces, patchData, faceData, cellData, mesh.globalData().nTotalCells()+1 ); // And extract labelList nearest(mesh.nFaces()); bool haveWarned = false; forAll(faceData, faceI) { if (!faceData[faceI].valid(deltaCalc.data())) { if (!haveWarned) { WarningIn("meshRefinement::nearestPatch(..)") << "Did not visit some faces, e.g. face " << faceI << " at " << mesh.faceCentres()[faceI] << endl << "Using patch " << patchIDs[0] << " as nearest" << endl; haveWarned = true; } nearest[faceI] = patchIDs[0]; } else { nearest[faceI] = faceData[faceI].data(); } } return nearest; } template void subsetVolFields ( const fvMeshSubset& subsetter, const wordList& fieldNames, PtrList >& subFields ) { const fvMesh& baseMesh = subsetter.baseMesh(); forAll(fieldNames, i) { const word& fieldName = fieldNames[i]; Info<< "Subsetting field " << fieldName << endl; GeometricField fld ( IOobject ( fieldName, baseMesh.time().timeName(), baseMesh, IOobject::MUST_READ, IOobject::NO_WRITE ), baseMesh ); subFields.set(i, subsetter.interpolate(fld)); } } template void subsetSurfaceFields ( const fvMeshSubset& subsetter, const wordList& fieldNames, PtrList >& subFields ) { const fvMesh& baseMesh = subsetter.baseMesh(); forAll(fieldNames, i) { const word& fieldName = fieldNames[i]; Info<< "Subsetting field " << fieldName << endl; GeometricField fld ( IOobject ( fieldName, baseMesh.time().timeName(), baseMesh, IOobject::MUST_READ, IOobject::NO_WRITE ), baseMesh ); subFields.set(i, subsetter.interpolate(fld)); } } template void subsetPointFields ( const fvMeshSubset& subsetter, const pointMesh& pMesh, const wordList& fieldNames, PtrList >& subFields ) { const fvMesh& baseMesh = subsetter.baseMesh(); forAll(fieldNames, i) { const word& fieldName = fieldNames[i]; Info<< "Subsetting field " << fieldName << endl; GeometricField fld ( IOobject ( fieldName, baseMesh.time().timeName(), baseMesh, IOobject::MUST_READ, IOobject::NO_WRITE ), pMesh ); subFields.set(i, subsetter.interpolate(fld)); } } template void subsetDimensionedFields ( const fvMeshSubset& subsetter, const wordList& fieldNames, PtrList >& subFields ) { const fvMesh& baseMesh = subsetter.baseMesh(); forAll(fieldNames, i) { const word& fieldName = fieldNames[i]; Info<< "Subsetting field " << fieldName << endl; DimensionedField fld ( IOobject ( fieldName, baseMesh.time().timeName(), baseMesh, IOobject::MUST_READ, IOobject::NO_WRITE ), baseMesh ); subFields.set(i, subsetter.interpolate(fld)); } } int main(int argc, char *argv[]) { argList::addNote ( "select a mesh subset based on a cellSet" ); #include "addOverwriteOption.H" #include "addRegionOption.H" argList::validArgs.append("cellSet"); argList::addOption ( "patch", "name", "add exposed internal faces to specified patch instead of to " "'oldInternalFaces'" ); argList::addOption ( "patches", "names", "add exposed internal faces to nearest of specified patches" " instead of to 'oldInternalFaces'" ); argList::addOption ( "resultTime", "time", "specify a time for the resulting mesh" ); #include "setRootCase.H" #include "createTime.H" runTime.functionObjects().off(); Foam::word meshRegionName = polyMesh::defaultRegion; args.optionReadIfPresent("region", meshRegionName); #include "createNamedMesh.H" const word setName = args[1]; word meshInstance = mesh.pointsInstance(); word fieldsInstance = runTime.timeName(); const bool overwrite = args.optionFound("overwrite"); const bool specifiedInstance = args.optionReadIfPresent ( "resultTime", fieldsInstance ); if (specifiedInstance) { // Set both mesh and field to this time meshInstance = fieldsInstance; } Info<< "Reading cell set from " << setName << endl << endl; // Create mesh subsetting engine fvMeshSubset subsetter(mesh); labelList exposedPatchIDs; if (args.optionFound("patch")) { const word patchName = args["patch"]; exposedPatchIDs = labelList ( 1, mesh.boundaryMesh().findPatchID(patchName) ); if (exposedPatchIDs[0] == -1) { FatalErrorInFunction << nl << "Valid patches are " << mesh.boundaryMesh().names() << exit(FatalError); } Info<< "Adding exposed internal faces to patch " << patchName << endl << endl; } else if (args.optionFound("patches")) { const wordReList patchNames(args.optionRead("patches")); exposedPatchIDs = mesh.boundaryMesh().patchSet(patchNames).sortedToc(); Info<< "Adding exposed internal faces to nearest of patches " << patchNames << endl << endl; } else { Info<< "Adding exposed internal faces to a patch called" << " \"oldInternalFaces\" (created if necessary)" << endl << endl; exposedPatchIDs = labelList(1, label(-1)); } cellSet currentSet(mesh, setName); if (exposedPatchIDs.size() == 1) { subsetter.setLargeCellSubset(currentSet, exposedPatchIDs[0], true); } else { // Find per face the nearest patch labelList nearestExposedPatch(nearestPatch(mesh, exposedPatchIDs)); labelList region(mesh.nCells(), 0); forAllConstIter(cellSet, currentSet, iter) { region[iter.key()] = 1; } labelList exposedFaces(subsetter.getExposedFaces(region, 1, true)); subsetter.setLargeCellSubset ( region, 1, exposedFaces, UIndirectList