1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "regionSide.H"
27 #include "meshTools.H"
28 #include "primitiveMesh.H"
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 defineTypeNameAndDebug(regionSide, 0);
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42 // Step across edge onto other face on cell
43 Foam::label Foam::regionSide::otherFace
45 const primitiveMesh& mesh,
53 meshTools::getEdgeFaces(mesh, cellI, edgeI, f0I, f1I);
66 // Step across point to other edge on face
67 Foam::label Foam::regionSide::otherEdge
69 const primitiveMesh& mesh,
75 const edge& e = mesh.edges()[edgeI];
77 // Get other point on edge.
78 label freePointI = e.otherVertex(pointI);
80 const labelList& fEdges = mesh.faceEdges()[faceI];
82 forAll(fEdges, fEdgeI)
84 label otherEdgeI = fEdges[fEdgeI];
86 const edge& otherE = mesh.edges()[otherEdgeI];
91 otherE.start() == pointI
92 && otherE.end() != freePointI
95 otherE.end() == pointI
96 && otherE.start() != freePointI
100 // otherE shares one (but not two) points with e.
107 "regionSide::otherEdge(const primitiveMesh&, const label, const label"
109 ) << "Cannot find other edge on face " << faceI << " that uses point "
110 << pointI << " but not point " << freePointI << endl
111 << "Edges on face:" << fEdges
112 << " verts:" << UIndirectList<edge>(mesh.edges(), fEdges)()
113 << " Vertices on face:"
114 << mesh.faces()[faceI]
115 << " Vertices on original edge:" << e << abort(FatalError);
121 // Step from faceI (on side cellI) to connected face & cell without crossing
123 void Foam::regionSide::visitConnectedFaces
125 const primitiveMesh& mesh,
126 const labelHashSet& region,
127 const labelHashSet& fenceEdges,
130 labelHashSet& visitedFace
133 if (!visitedFace.found(faceI))
137 Info<< "visitConnectedFaces : cellI:" << cellI << " faceI:"
138 << faceI << " isOwner:" << (cellI == mesh.faceOwner()[faceI])
143 visitedFace.insert(faceI);
145 // Mark which side of face was visited.
146 if (cellI == mesh.faceOwner()[faceI])
148 sideOwner_.insert(faceI);
152 // Visit all neighbouring faces on faceSet. Stay on this 'side' of
153 // face by doing edge-face-cell walk.
154 const labelList& fEdges = mesh.faceEdges()[faceI];
156 forAll(fEdges, fEdgeI)
158 label edgeI = fEdges[fEdgeI];
160 if (!fenceEdges.found(edgeI))
162 // Step along faces on edge from cell to cell until
163 // we hit face on faceSet.
165 // Find face reachable from edge
166 label otherFaceI = otherFace(mesh, cellI, faceI, edgeI);
168 if (mesh.isInternalFace(otherFaceI))
170 label otherCellI = cellI;
172 // Keep on crossing faces/cells until back on face on
174 while (!region.found(otherFaceI))
176 visitedFace.insert(otherFaceI);
180 Info<< "visitConnectedFaces : cellI:" << cellI
181 << " found insideEdgeFace:" << otherFaceI
186 // Cross otherFaceI into neighbouring cell
221 // From edge on face connected to point on region (regionPointI) cross
222 // to all other edges using this point by walking across faces
223 // Does not cross regionEdges so stays on one side
225 void Foam::regionSide::walkPointConnectedFaces
227 const primitiveMesh& mesh,
228 const labelHashSet& regionEdges,
229 const label regionPointI,
230 const label startFaceI,
231 const label startEdgeI,
232 labelHashSet& visitedEdges
236 insidePointFaces_.insert(startFaceI);
240 Info<< "walkPointConnectedFaces : regionPointI:" << regionPointI
241 << " faceI:" << startFaceI
242 << " edgeI:" << startEdgeI << " verts:"
243 << mesh.edges()[startEdgeI]
247 // Cross faceI i.e. get edge not startEdgeI which uses regionPointI
248 label edgeI = otherEdge(mesh, startFaceI, startEdgeI, regionPointI);
250 if (!regionEdges.found(edgeI))
252 if (!visitedEdges.found(edgeI))
254 visitedEdges.insert(edgeI);
258 Info<< "Crossed face from "
259 << " edgeI:" << startEdgeI << " verts:"
260 << mesh.edges()[startEdgeI]
261 << " to edge:" << edgeI << " verts:"
262 << mesh.edges()[edgeI]
266 // Cross edge to all faces connected to it.
268 const labelList& eFaces = mesh.edgeFaces()[edgeI];
270 forAll(eFaces, eFaceI)
272 label faceI = eFaces[eFaceI];
274 walkPointConnectedFaces
289 // Find all faces reachable from all non-fence points and staying on
291 void Foam::regionSide::walkAllPointConnectedFaces
293 const primitiveMesh& mesh,
294 const labelHashSet& regionFaces,
295 const labelHashSet& fencePoints
299 // Get all (internal and external) edges on region.
301 labelHashSet regionEdges(4*regionFaces.size());
305 labelHashSet::const_iterator iter = regionFaces.begin();
306 iter != regionFaces.end();
310 label faceI = iter.key();
312 const labelList& fEdges = mesh.faceEdges()[faceI];
314 forAll(fEdges, fEdgeI)
316 regionEdges.insert(fEdges[fEdgeI]);
322 // Visit all internal points on surface.
325 // Storage for visited points
326 labelHashSet visitedPoint(4*regionFaces.size());
328 // Insert fence points so we don't visit them
331 labelHashSet::const_iterator iter = fencePoints.begin();
332 iter != fencePoints.end();
336 visitedPoint.insert(iter.key());
339 labelHashSet visitedEdges(2*fencePoints.size());
344 Info<< "Excluding visit of points:" << visitedPoint << endl;
349 labelHashSet::const_iterator iter = regionFaces.begin();
350 iter != regionFaces.end();
354 label faceI = iter.key();
359 if (sideOwner_.found(faceI))
361 cellI = mesh.faceOwner()[faceI];
365 cellI = mesh.faceNeighbour()[faceI];
368 // Find starting point and edge on face.
369 const labelList& fEdges = mesh.faceEdges()[faceI];
371 forAll(fEdges, fEdgeI)
373 label edgeI = fEdges[fEdgeI];
375 // Get the face 'perpendicular' to faceI on region.
376 label otherFaceI = otherFace(mesh, cellI, faceI, edgeI);
379 const edge& e = mesh.edges()[edgeI];
381 if (!visitedPoint.found(e.start()))
383 Info<< "Determining visibility from point " << e.start()
386 visitedPoint.insert(e.start());
388 //edgeI = otherEdge(mesh, otherFaceI, edgeI, e.start());
390 walkPointConnectedFaces
400 if (!visitedPoint.found(e.end()))
402 Info<< "Determining visibility from point " << e.end()
405 visitedPoint.insert(e.end());
407 //edgeI = otherEdge(mesh, otherFaceI, edgeI, e.end());
409 walkPointConnectedFaces
424 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
426 // Construct from components
427 Foam::regionSide::regionSide
429 const primitiveMesh& mesh,
430 const labelHashSet& region, // faces of region
431 const labelHashSet& fenceEdges, // outside edges
432 const label startCellI,
433 const label startFaceI
436 sideOwner_(region.size()),
437 insidePointFaces_(region.size())
439 // Storage for visited faces
440 labelHashSet visitedFace(region.size());
442 // Visit all faces on this side of region.
443 // Mark for each face whether owner (or neighbour) has been visited.
456 // Visit all internal points on region and mark faces visitable from these.
457 // Sets insidePointFaces_.
460 labelHashSet fencePoints(fenceEdges.size());
464 labelHashSet::const_iterator iter = fenceEdges.begin();
465 iter != fenceEdges.end();
469 const edge& e = mesh.edges()[iter.key()];
471 fencePoints.insert(e.start());
472 fencePoints.insert(e.end());
475 walkAllPointConnectedFaces(mesh, region, fencePoints);
479 // ************************************************************************* //