diff --git a/applications/utilities/mesh/manipulation/topoSet/topoSetDict b/applications/utilities/mesh/manipulation/topoSet/topoSetDict index 4c2180f21d489ff5b916f8bce73628f23443558c..1f58d59ddee437f838f92bd7905cd044ec58232c 100644 --- a/applications/utilities/mesh/manipulation/topoSet/topoSetDict +++ b/applications/utilities/mesh/manipulation/topoSet/topoSetDict @@ -238,6 +238,14 @@ FoamFile // cos 0.01; // Tolerance (max cos of angle) // } // +// // Walk on faces in faceSet, starting from face nearest given position +// source regionToFace; +// sourceInfo +// { +// set f0; +// nearPoint (0.1 0.1 0.005); +// } +// // // // pointSet diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files index 3329c2b28d1115a290a7cc0b4b11537fadc7cd11..392fa459985a2410f403700c3bb4e6cccea53187 100644 --- a/src/meshTools/Make/files +++ b/src/meshTools/Make/files @@ -110,6 +110,7 @@ $(faceSources)/patchToFace/patchToFace.C $(faceSources)/boundaryToFace/boundaryToFace.C $(faceSources)/zoneToFace/zoneToFace.C $(faceSources)/boxToFace/boxToFace.C +$(faceSources)/regionToFace/regionToFace.C pointSources = sets/pointSources $(pointSources)/labelToPoint/labelToPoint.C diff --git a/src/meshTools/sets/faceSources/regionToFace/regionToFace.C b/src/meshTools/sets/faceSources/regionToFace/regionToFace.C new file mode 100644 index 0000000000000000000000000000000000000000..20182eb7f5c2120ea6ffa6ae33c1704c96a7dec5 --- /dev/null +++ b/src/meshTools/sets/faceSources/regionToFace/regionToFace.C @@ -0,0 +1,401 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "regionToFace.H" +#include "polyMesh.H" +#include "faceSet.H" +#include "mappedPatchBase.H" +#include "indirectPrimitivePatch.H" +#include "PatchTools.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + +defineTypeNameAndDebug(regionToFace, 0); + +addToRunTimeSelectionTable(topoSetSource, regionToFace, word); + +addToRunTimeSelectionTable(topoSetSource, regionToFace, istream); + +} + + +Foam::topoSetSource::addToUsageTable Foam::regionToFace::usage_ +( + regionToFace::typeName, + "\n Usage: regionToFace <faceSet> (x y z)\n\n" + " Select all faces in the connected region of the faceSet" + " starting from the point.\n" +); + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Synchronise edges +void Foam::regionToFace::syncEdges +( + const labelList& patchEdges, + const labelList& coupledEdges, + const bool syncNonCollocated, + + PackedBoolList& isChangedEdge, + DynamicList<label>& changedEdges, + labelList& allEdgeData +) const +{ + const globalMeshData& globalData = mesh_.globalData(); + const mapDistribute& map = globalData.globalEdgeSlavesMap(); + + // Convert patch-edge data into cpp-edge data + labelList cppEdgeData(map.constructSize(), labelMax); + + forAll(patchEdges, i) + { + label patchEdgeI = patchEdges[i]; + label coupledEdgeI = coupledEdges[i]; + + if (isChangedEdge[patchEdgeI]) + { + cppEdgeData[coupledEdgeI] = allEdgeData[patchEdgeI]; + } + } + + // Synchronise + globalData.syncData + ( + cppEdgeData, + globalData.globalEdgeSlaves(), + ( + syncNonCollocated + ? globalData.globalEdgeTransformedSlaves() // transformed elems + : labelListList(globalData.globalEdgeSlaves().size()) //no transformed + ), + map, + minEqOp<label>() + ); + + // Back from cpp-edge to patch-edge data + forAll(patchEdges, i) + { + label patchEdgeI = patchEdges[i]; + label coupledEdgeI = coupledEdges[i]; + + if (cppEdgeData[coupledEdgeI] != labelMax) + { + allEdgeData[patchEdgeI] = cppEdgeData[coupledEdgeI]; + + if (!isChangedEdge[patchEdgeI]) + { + changedEdges.append(patchEdgeI); + isChangedEdge[patchEdgeI] = true; + } + } + } +} + + +void Foam::regionToFace::markZone +( + const indirectPrimitivePatch& patch, + const label procI, + const label faceI, + const label zoneI, + labelList& faceZone +) const +{ + // Calculate correspondence between patch and globalData.coupledPatch. + labelList patchEdges; + labelList coupledEdges; + PackedBoolList sameEdgeOrientation; + PatchTools::matchEdges + ( + mesh_.globalData().coupledPatch(), + patch, + + coupledEdges, + patchEdges, + sameEdgeOrientation + ); + + + DynamicList<label> changedEdges(patch.nEdges()); + labelList allEdgeData(patch.nEdges(), -1); + PackedBoolList isChangedEdge(patch.nEdges()); + + + // Fill initial seed + // ~~~~~~~~~~~~~~~~~ + + if (Pstream::myProcNo() == procI) + { + const labelList& fEdges = patch.faceEdges()[faceI]; + forAll(fEdges, i) + { + label edgeI = fEdges[i]; + if (!isChangedEdge[edgeI]) + { + allEdgeData[edgeI] = zoneI; + changedEdges.append(edgeI); + isChangedEdge[edgeI] = true; + } + } + } + + syncEdges + ( + patchEdges, + coupledEdges, + true, //syncNonCollocated, + + isChangedEdge, + changedEdges, + allEdgeData + ); + + + // Edge-Face-Edge walk across patch + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + while (true) + { + // From edge to face + // ~~~~~~~~~~~~~~~~~ + + DynamicList<label> changedFaces(patch.size()); + + forAll(changedEdges, changedI) + { + label edgeI = changedEdges[changedI]; + const labelList& eFaces = patch.edgeFaces()[edgeI]; + + forAll(eFaces, i) + { + label faceI = eFaces[i]; + + if (faceZone[faceI] == -1) + { + faceZone[faceI] = zoneI; + changedFaces.append(faceI); + } + } + } + + + label nChangedFaces = returnReduce(changedFaces.size(), sumOp<label>()); + if (nChangedFaces == 0) + { + break; + } + + + // From face to edge + // ~~~~~~~~~~~~~~~~~ + + isChangedEdge = false; + changedEdges.clear(); + + forAll(changedFaces, i) + { + label faceI = changedFaces[i]; + const labelList& fEdges = patch.faceEdges()[faceI]; + + forAll(fEdges, fp) + { + label edgeI = fEdges[fp]; + + if (!isChangedEdge[edgeI]) + { + allEdgeData[edgeI] = zoneI; + changedEdges.append(edgeI); + isChangedEdge[edgeI] = true; + } + } + } + + syncEdges + ( + patchEdges, + coupledEdges, + true, //syncNonCollocated, + + isChangedEdge, + changedEdges, + allEdgeData + ); + + label nChangedEdges = returnReduce(changedEdges.size(), sumOp<label>()); + if (nChangedEdges == 0) + { + break; + } + } +} + + +void Foam::regionToFace::combine(topoSet& set, const bool add) const +{ + Info<< " Loading subset " << setName_ << " to delimit search region." + << endl; + faceSet subSet(mesh_, setName_); + + indirectPrimitivePatch patch + ( + IndirectList<face>(mesh_.faces(), subSet.toc()), + mesh_.points() + ); + + mappedPatchBase::nearInfo ni + ( + pointIndexHit(false, vector::zero, -1), + Tuple2<scalar, label> + ( + sqr(GREAT), + Pstream::myProcNo() + ) + ); + + forAll(patch, i) + { + const point& fc = patch.faceCentres()[i]; + scalar d2 = magSqr(fc-nearPoint_); + + if (!ni.first().hit() || d2 < ni.second().first()) + { + ni.second().first() = d2; + ni.first().setHit(); + ni.first().setPoint(fc); + ni.first().setIndex(i); + } + } + + // Globally reduce + combineReduce(ni, mappedPatchBase::nearestEqOp()); + + Info<< " Found nearest face at " << ni.first().rawPoint() + << " on processor " << ni.second().second() + << " face " << ni.first().index() + << " distance " << Foam::sqrt(ni.second().first()) << endl; + + labelList faceRegion(patch.size(), -1); + markZone + ( + patch, + ni.second().second(), // procI + ni.first().index(), // start face + 0, // currentZone + faceRegion + ); + + forAll(faceRegion, faceI) + { + if (faceRegion[faceI] == 0) + { + addOrDelete(set, patch.addressing()[faceI], add); + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +// Construct from components +Foam::regionToFace::regionToFace +( + const polyMesh& mesh, + const word& setName, + const point& nearPoint +) +: + topoSetSource(mesh), + setName_(setName), + nearPoint_(nearPoint) +{} + + +// Construct from dictionary +Foam::regionToFace::regionToFace +( + const polyMesh& mesh, + const dictionary& dict +) +: + topoSetSource(mesh), + setName_(dict.lookup("set")), + nearPoint_(dict.lookup("nearPoint")) +{} + + +// Construct from Istream +Foam::regionToFace::regionToFace +( + const polyMesh& mesh, + Istream& is +) +: + topoSetSource(mesh), + setName_(checkIs(is)), + nearPoint_(checkIs(is)) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::regionToFace::~regionToFace() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::regionToFace::applyToSet +( + const topoSetSource::setAction action, + topoSet& set +) const +{ + if ((action == topoSetSource::NEW) || (action == topoSetSource::ADD)) + { + Info<< " Adding all faces of connected region of set " + << setName_ + << " starting from point " + << nearPoint_ << " ..." << endl; + + combine(set, true); + } + else if (action == topoSetSource::DELETE) + { + Info<< " Removing all cells of connected region of set " + << setName_ + << " starting from point " + << nearPoint_ << " ..." << endl; + + combine(set, false); + } +} + + +// ************************************************************************* // diff --git a/src/meshTools/sets/faceSources/regionToFace/regionToFace.H b/src/meshTools/sets/faceSources/regionToFace/regionToFace.H new file mode 100644 index 0000000000000000000000000000000000000000..e4352792bb8e0849a15f12cc07398c15952e2fb4 --- /dev/null +++ b/src/meshTools/sets/faceSources/regionToFace/regionToFace.H @@ -0,0 +1,151 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 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 <http://www.gnu.org/licenses/>. + +Class + Foam::regionToFace + +Description + A topoSetSource to select faces belonging to topological connected region + (that contains given point) + +SourceFiles + regionToFace.C + +\*---------------------------------------------------------------------------*/ + +#ifndef regionToFace_H +#define regionToFace_H + +#include "topoSetSource.H" +#include "PackedBoolList.H" +#include "indirectPrimitivePatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class regionToFace Declaration +\*---------------------------------------------------------------------------*/ + +class regionToFace +: + public topoSetSource +{ + // Private data + + //- Add usage string + static addToUsageTable usage_; + + //- Name of set to use + word setName_; + + //- Coordinate that is nearest/on connected region + point nearPoint_; + + // Private Member Functions + + //- Sync patch edges + void syncEdges + ( + const labelList& patchEdges, + const labelList& coupledEdges, + const bool syncNonCollocated, + + PackedBoolList& isChangedEdge, + DynamicList<label>& changedEdges, + labelList& allEdgeData + ) const; + + //- Walk edge-face-edge + void markZone + ( + const indirectPrimitivePatch& patch, + const label procI, + const label faceI, + const label zoneI, + labelList& faceZone + ) const; + + void combine(topoSet& set, const bool add) const; + +public: + + //- Runtime type information + TypeName("regionToFace"); + + // Constructors + + //- Construct from components + regionToFace + ( + const polyMesh& mesh, + const word& setName, + const point& nearPoint + ); + + //- Construct from dictionary + regionToFace + ( + const polyMesh& mesh, + const dictionary& dict + ); + + //- Construct from Istream + regionToFace + ( + const polyMesh& mesh, + Istream& + ); + + + //- Destructor + virtual ~regionToFace(); + + + // Member Functions + + virtual sourceType setType() const + { + return FACESETSOURCE; + } + + virtual void applyToSet + ( + const topoSetSource::setAction action, + topoSet& + ) const; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //