/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2012 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 . 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 utilities to see how to select cells based on various. 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 "cellSelection.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 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)); } } // Main program: int main(int argc, char *argv[]) { argList::addNote ( "select a mesh subset based on a provided cellSet and/or" " selection criteria" ); #include "addDictOption.H" argList::addOption ( "cellSet", "name", "operates on specified cellSet name" ); argList::addOption ( "patch", "name", "add exposed internal faces to specified patch instead of to " "'oldInternalFaces'" ); #include "addOverwriteOption.H" #include "addRegionOption.H" #include "setRootCase.H" #include "createTime.H" runTime.functionObjects().off(); word setName; const bool useCellSet = args.optionReadIfPresent("cellSet", setName); const bool useDict = args.optionFound("dict"); const bool overwrite = args.optionFound("overwrite"); if (!useCellSet && !useDict) { FatalErrorIn(args.executable()) << "No cells to operate on selected. Please supply at least one of " << "'-cellSet', '-dict'" << exit(FatalError); } #include "createNamedMesh.H" const word oldInstance = mesh.pointsInstance(); autoPtr currentSet; if (useCellSet) { // Load the cellSet Info<< "Operating on cell set " << setName << nl << endl; currentSet.reset(new cellSet(mesh, setName)); } PtrList selectors; if (useDict) { const word dictName("subsetMeshDict"); #include "setSystemMeshDictionaryIO.H" Info<< "Reading selection criteria from " << dictName << nl << endl; IOdictionary dict(dictIO); const dictionary& selectionsDict = dict.subDict("selections"); label n = 0; forAllConstIter(dictionary, selectionsDict, iter) { if (iter().isDict()) { n++; } } selectors.setSize(n); n = 0; forAllConstIter(dictionary, selectionsDict, iter) { if (iter().isDict()) { selectors.set ( n++, cellSelection::New(iter().keyword(), mesh, iter().dict()) ); } } } // Create mesh subsetting engine fvMeshSubset subsetter(mesh); label patchI = -1; if (args.optionFound("patch")) { const word patchName = args["patch"]; patchI = mesh.boundaryMesh().findPatchID(patchName); if (patchI == -1) { FatalErrorIn(args.executable()) << "Illegal patch " << patchName << nl << "Valid patches are " << mesh.boundaryMesh().names() << exit(FatalError); } Info<< "Adding exposed internal faces to patch " << patchName << endl << endl; } else { Info<< "Adding exposed internal faces to a patch called" << " \"oldInternalFaces\" (created if necessary)" << endl << endl; } // Select cells to operate on // ~~~~~~~~~~~~~~~~~~~~~~~~~~ boolList selectedCell(mesh.nCells(), false); if (currentSet.valid()) { const cellSet& set = currentSet(); forAllConstIter(cellSet, set, iter) { selectedCell[iter.key()] = true; } } else { selectedCell = true; } // Manipulate selectedCell according to dictionary // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ forAll(selectors, i) { Info<< "Applying cellSelector " << selectors[i].name() << endl; selectors[i].select(selectedCell); Info<< "After applying cellSelector " << selectors[i].name() << " have " << cellSelection::count(selectedCell) << " cells" << nl << endl; } // Back from selectedCells to region { Info<< "Final selection : " << cellSelection::count(selectedCell) << " cells" << nl << endl; labelList cellRegion(mesh.nCells(), -1); forAll(selectedCell, cellI) { if (selectedCell[cellI]) { cellRegion[cellI] = 0; } } subsetter.setLargeCellSubset(cellRegion, 0, patchI, true); } IOobjectList objects(mesh, runTime.timeName()); // Read vol fields and subset // ~~~~~~~~~~~~~~~~~~~~~~~~~~ wordList scalarNames(objects.names(volScalarField::typeName)); PtrList scalarFlds(scalarNames.size()); subsetVolFields(subsetter, scalarNames, scalarFlds); wordList vectorNames(objects.names(volVectorField::typeName)); PtrList vectorFlds(vectorNames.size()); subsetVolFields(subsetter, vectorNames, vectorFlds); wordList sphericalTensorNames ( objects.names(volSphericalTensorField::typeName) ); PtrList sphericalTensorFlds ( sphericalTensorNames.size() ); subsetVolFields(subsetter, sphericalTensorNames, sphericalTensorFlds); wordList symmTensorNames(objects.names(volSymmTensorField::typeName)); PtrList symmTensorFlds(symmTensorNames.size()); subsetVolFields(subsetter, symmTensorNames, symmTensorFlds); wordList tensorNames(objects.names(volTensorField::typeName)); PtrList tensorFlds(tensorNames.size()); subsetVolFields(subsetter, tensorNames, tensorFlds); // Read surface fields and subset // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ wordList surfScalarNames(objects.names(surfaceScalarField::typeName)); PtrList surfScalarFlds(surfScalarNames.size()); subsetSurfaceFields(subsetter, surfScalarNames, surfScalarFlds); wordList surfVectorNames(objects.names(surfaceVectorField::typeName)); PtrList surfVectorFlds(surfVectorNames.size()); subsetSurfaceFields(subsetter, surfVectorNames, surfVectorFlds); wordList surfSphericalTensorNames ( objects.names(surfaceSphericalTensorField::typeName) ); PtrList surfSphericalTensorFlds ( surfSphericalTensorNames.size() ); subsetSurfaceFields ( subsetter, surfSphericalTensorNames, surfSphericalTensorFlds ); wordList surfSymmTensorNames ( objects.names(surfaceSymmTensorField::typeName) ); PtrList surfSymmTensorFlds ( surfSymmTensorNames.size() ); subsetSurfaceFields(subsetter, surfSymmTensorNames, surfSymmTensorFlds); wordList surfTensorNames(objects.names(surfaceTensorField::typeName)); PtrList surfTensorFlds(surfTensorNames.size()); subsetSurfaceFields(subsetter, surfTensorNames, surfTensorFlds); // Read point fields and subset // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const pointMesh& pMesh = pointMesh::New(mesh); wordList pointScalarNames(objects.names(pointScalarField::typeName)); PtrList pointScalarFlds(pointScalarNames.size()); subsetPointFields(subsetter, pMesh, pointScalarNames, pointScalarFlds); wordList pointVectorNames(objects.names(pointVectorField::typeName)); PtrList pointVectorFlds(pointVectorNames.size()); subsetPointFields(subsetter, pMesh, pointVectorNames, pointVectorFlds); wordList pointSphericalTensorNames ( objects.names(pointSphericalTensorField::typeName) ); PtrList pointSphericalTensorFlds ( pointSphericalTensorNames.size() ); subsetPointFields ( subsetter, pMesh, pointSphericalTensorNames, pointSphericalTensorFlds ); wordList pointSymmTensorNames ( objects.names(pointSymmTensorField::typeName) ); PtrList pointSymmTensorFlds ( pointSymmTensorNames.size() ); subsetPointFields ( subsetter, pMesh, pointSymmTensorNames, pointSymmTensorFlds ); wordList pointTensorNames(objects.names(pointTensorField::typeName)); PtrList pointTensorFlds(pointTensorNames.size()); subsetPointFields(subsetter, pMesh, pointTensorNames, pointTensorFlds); // Write mesh and fields to new time // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (!overwrite) { runTime++; } else { subsetter.subMesh().setInstance(oldInstance); } Info<< "Writing subsetted mesh and fields to time " << runTime.timeName() << endl; subsetter.subMesh().write(); // Subsetting adds 'subset' prefix. Rename field to be like original. forAll(scalarFlds, i) { scalarFlds[i].rename(scalarNames[i]); scalarFlds[i].write(); } forAll(vectorFlds, i) { vectorFlds[i].rename(vectorNames[i]); vectorFlds[i].write(); } forAll(sphericalTensorFlds, i) { sphericalTensorFlds[i].rename(sphericalTensorNames[i]); sphericalTensorFlds[i].write(); } forAll(symmTensorFlds, i) { symmTensorFlds[i].rename(symmTensorNames[i]); symmTensorFlds[i].write(); } forAll(tensorFlds, i) { tensorFlds[i].rename(tensorNames[i]); tensorFlds[i].write(); } // Surface ones. forAll(surfScalarFlds, i) { surfScalarFlds[i].rename(surfScalarNames[i]); surfScalarFlds[i].write(); } forAll(surfVectorFlds, i) { surfVectorFlds[i].rename(surfVectorNames[i]); surfVectorFlds[i].write(); } forAll(surfSphericalTensorFlds, i) { surfSphericalTensorFlds[i].rename(surfSphericalTensorNames[i]); surfSphericalTensorFlds[i].write(); } forAll(surfSymmTensorFlds, i) { surfSymmTensorFlds[i].rename(surfSymmTensorNames[i]); surfSymmTensorFlds[i].write(); } forAll(surfTensorNames, i) { surfTensorFlds[i].rename(surfTensorNames[i]); surfTensorFlds[i].write(); } // Point ones forAll(pointScalarFlds, i) { pointScalarFlds[i].rename(pointScalarNames[i]); pointScalarFlds[i].write(); } forAll(pointVectorFlds, i) { pointVectorFlds[i].rename(pointVectorNames[i]); pointVectorFlds[i].write(); } forAll(pointSphericalTensorFlds, i) { pointSphericalTensorFlds[i].rename(pointSphericalTensorNames[i]); pointSphericalTensorFlds[i].write(); } forAll(pointSymmTensorFlds, i) { pointSymmTensorFlds[i].rename(pointSymmTensorNames[i]); pointSymmTensorFlds[i].write(); } forAll(pointTensorNames, i) { pointTensorFlds[i].rename(pointTensorNames[i]); pointTensorFlds[i].write(); } Info<< "\nEnd\n" << endl; return 0; } // ************************************************************************* //