/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- 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 setSet Group grpMeshManipulationUtilities Description Manipulate a cell/face/point/ set or zone interactively. \*---------------------------------------------------------------------------*/ #include "argList.H" #include "Time.H" #include "polyMesh.H" #include "globalMeshData.H" #include "StringStream.H" #include "cellSet.H" #include "faceSet.H" #include "pointSet.H" #include "topoSetSource.H" #include "Fstream.H" #include "demandDrivenData.H" #include "foamVtkWriteCellSetFaces.H" #include "foamVtkWriteFaceSet.H" #include "foamVtkWritePointSet.H" #include "IOobjectList.H" #include "cellZoneSet.H" #include "faceZoneSet.H" #include "pointZoneSet.H" #include "timeSelector.H" #include "collatedFileOperation.H" #include #ifdef HAVE_LIBREADLINE #include #include static const char* historyFile = ".setSet"; #endif using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Write set to VTK readable files void writeVTK ( const polyMesh& mesh, const topoSet& currentSet, const fileName& vtkBaseName ) { if (isA(currentSet)) { // Faces of set with OpenFOAM faceID as value vtk::writeFaceSet ( mesh, dynamicCast(currentSet), mesh.time().path()/vtkBaseName, vtk::formatType::LEGACY_BINARY ); } else if (isA(currentSet)) { // External faces of cellset with OpenFOAM cellID as value vtk::writeCellSetFaces ( mesh, dynamicCast(currentSet), mesh.time().path()/vtkBaseName, vtk::formatType::LEGACY_BINARY ); } else if (isA(currentSet)) { vtk::writePointSet ( mesh, dynamicCast(currentSet), mesh.time().path()/vtkBaseName, vtk::formatType::LEGACY_BINARY ); } else { WarningInFunction << "Don't know how to handle set of type " << currentSet.type() << endl; } } void printHelp(Ostream& os) { os << "Please type 'help', 'list', 'quit', 'time ddd'" << " or a set command after prompt." << nl << "'list' will show all current cell/face/point sets." << nl << "'time ddd' will change the current time." << nl << nl << "A set command should be of the following form" << nl << nl << " cellSet|faceSet|pointSet " << nl << nl << "The is one of" << nl << " list - prints the contents of the set" << nl << " clear - clears the set" << nl << " invert - inverts the set" << nl << " remove - remove the set" << nl << " new - sets to set to the source set" << nl << " add - adds all elements from the source set" << nl << " delete - deletes ,," << nl << " subset - combines current set with the source set" << nl << nl << "The sources come in various forms. Type a wrong source" << " to see all the types available." << nl << nl << "Example: pick up all cells connected by point or face to patch" << " movingWall" << nl << nl << "Pick up all faces of patch:" << nl << " faceSet f0 new patchToFace movingWall" << nl << "Add faces 0,1,2:" << nl << " faceSet f0 add labelToFace (0 1 2)" << nl << "Pick up all points used by faces in faceSet f0:" << nl << " pointSet p0 new faceToPoint f0 all" << nl << "Pick up cell which has any face in f0:" << nl << " cellSet c0 new faceToCell f0 any" << nl << "Add cells which have any point in p0:" << nl << " cellSet c0 add pointToCell p0 any" << nl << "List set:" << nl << " cellSet c0 list" << nl << nl << "Zones can be set using zoneSets from corresponding sets:" << nl << " cellZoneSet c0Zone new setToCellZone c0" << nl << " faceZoneSet f0Zone new setToFaceZone f0" << nl << nl << "or if orientation is important:" << nl << " faceZoneSet f0Zone new setsToFaceZone f0 c0" << nl << nl << "ZoneSets can be manipulated using the general actions:" << nl << " list - prints the contents of the set" << nl << " clear - clears the set" << nl << " invert - inverts the set (undefined orientation)" << nl << " remove - remove the set" << nl << endl; } void printAllSets(const polyMesh& mesh, Ostream& os) { IOobjectList objects ( mesh, mesh.time().findInstance ( polyMesh::meshSubDir/"sets", word::null, IOobject::READ_IF_PRESENT, mesh.facesInstance() ), polyMesh::meshSubDir/"sets" ); IOobjectList cellSets(objects.lookupClass(cellSet::typeName)); if (cellSets.size()) { os << "cellSets:" << endl; forAllConstIter(IOobjectList, cellSets, iter) { cellSet set(*iter()); os << '\t' << set.name() << "\tsize:" << set.size() << endl; } } IOobjectList faceSets(objects.lookupClass(faceSet::typeName)); if (faceSets.size()) { os << "faceSets:" << endl; forAllConstIter(IOobjectList, faceSets, iter) { faceSet set(*iter()); os << '\t' << set.name() << "\tsize:" << set.size() << endl; } } IOobjectList pointSets(objects.lookupClass(pointSet::typeName)); if (pointSets.size()) { os << "pointSets:" << endl; forAllConstIter(IOobjectList, pointSets, iter) { pointSet set(*iter()); os << '\t' << set.name() << "\tsize:" << set.size() << endl; } } const cellZoneMesh& cellZones = mesh.cellZones(); if (cellZones.size()) { os << "cellZones:" << endl; forAll(cellZones, i) { const cellZone& zone = cellZones[i]; os << '\t' << zone.name() << "\tsize:" << zone.size() << endl; } } const faceZoneMesh& faceZones = mesh.faceZones(); if (faceZones.size()) { os << "faceZones:" << endl; forAll(faceZones, i) { const faceZone& zone = faceZones[i]; os << '\t' << zone.name() << "\tsize:" << zone.size() << endl; } } const pointZoneMesh& pointZones = mesh.pointZones(); if (pointZones.size()) { os << "pointZones:" << endl; forAll(pointZones, i) { const pointZone& zone = pointZones[i]; os << '\t' << zone.name() << "\tsize:" << zone.size() << endl; } } os << endl; } template void removeZone ( ZoneMesh& zones, const word& setName ) { label zoneID = zones.findZoneID(setName); if (zoneID != -1) { Info<< "Removing zone " << setName << " at index " << zoneID << endl; // Shuffle to last position labelList oldToNew(zones.size()); label newI = 0; forAll(oldToNew, i) { if (i != zoneID) { oldToNew[i] = newI++; } } oldToNew[zoneID] = newI; zones.reorder(oldToNew); // Remove last element zones.setSize(zones.size()-1); zones.clearAddressing(); zones.write(); } } // Physically remove a set void removeSet ( const polyMesh& mesh, const word& setType, const word& setName ) { // Remove the file IOobjectList objects ( mesh, mesh.time().findInstance ( polyMesh::meshSubDir/"sets", word::null, IOobject::READ_IF_PRESENT, mesh.facesInstance() ), polyMesh::meshSubDir/"sets" ); if (objects.found(setName)) { // Remove file fileName object = objects[setName]->objectPath(); Info<< "Removing file " << object << endl; rm(object); } // See if zone if (setType == cellZoneSet::typeName) { removeZone ( const_cast(mesh.cellZones()), setName ); } else if (setType == faceZoneSet::typeName) { removeZone ( const_cast(mesh.faceZones()), setName ); } else if (setType == pointZoneSet::typeName) { removeZone ( const_cast(mesh.pointZones()), setName ); } } // Read command and execute. Return true if ok, false otherwise. bool doCommand ( const polyMesh& mesh, const word& setType, const word& setName, const word& actionName, const bool writeVTKFile, const bool writeCurrentTime, const bool noSync, Istream& is ) { // Get some size estimate for set. const globalMeshData& parData = mesh.globalData(); label typSize = max ( parData.nTotalCells(), max ( parData.nTotalFaces(), parData.nTotalPoints() ) ) / (10*Pstream::nProcs()); bool ok = true; // Set to work on autoPtr currentSetPtr; word sourceType; try { topoSetSource::setAction action = topoSetSource::toAction(actionName); IOobject::readOption r; if (action == topoSetSource::REMOVE) { removeSet(mesh, setType, setName); } else if ( (action == topoSetSource::NEW) || (action == topoSetSource::CLEAR) ) { r = IOobject::NO_READ; currentSetPtr = topoSet::New(setType, mesh, setName, typSize); } else { r = IOobject::MUST_READ; currentSetPtr = topoSet::New(setType, mesh, setName, r); topoSet& currentSet = currentSetPtr(); // Presize it according to current mesh data. currentSet.resize(max(currentSet.size(), typSize)); } if (currentSetPtr.valid()) { topoSet& currentSet = currentSetPtr(); Info<< " Set:" << currentSet.name() << " Size:" << returnReduce(currentSet.size(), sumOp