1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
5 \\ / A nd | 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/>.
26 \*---------------------------------------------------------------------------*/
28 #include "regionSide.H"
29 #include "meshTools.H"
30 #include "primitiveMesh.H"
31 #include "IndirectList.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 defineTypeNameAndDebug(regionSide, 0);
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45 // Step across edge onto other face on cell
46 Foam::label Foam::regionSide::otherFace
48 const primitiveMesh& mesh,
56 meshTools::getEdgeFaces(mesh, cellI, edgeI, f0I, f1I);
69 // Step across point to other edge on face
70 Foam::label Foam::regionSide::otherEdge
72 const primitiveMesh& mesh,
78 const edge& e = mesh.edges()[edgeI];
80 // Get other point on edge.
81 label freePointI = e.otherVertex(pointI);
83 const labelList& fEdges = mesh.faceEdges()[faceI];
85 forAll(fEdges, fEdgeI)
87 label otherEdgeI = fEdges[fEdgeI];
89 const edge& otherE = mesh.edges()[otherEdgeI];
94 otherE.start() == pointI
95 && otherE.end() != freePointI
98 otherE.end() == pointI
99 && otherE.start() != freePointI
103 // otherE shares one (but not two) points with e.
110 "regionSide::otherEdge(const primitiveMesh&, const label, const label"
112 ) << "Cannot find other edge on face " << faceI << " that uses point "
113 << pointI << " but not point " << freePointI << endl
114 << "Edges on face:" << fEdges
115 << " verts:" << IndirectList<edge>(mesh.edges(), fEdges)()
116 << " Vertices on face:"
117 << mesh.faces()[faceI]
118 << " Vertices on original edge:" << e << abort(FatalError);
124 // Step from faceI (on side cellI) to connected face & cell without crossing
126 void Foam::regionSide::visitConnectedFaces
128 const primitiveMesh& mesh,
129 const labelHashSet& region,
130 const labelHashSet& fenceEdges,
133 labelHashSet& visitedFace
136 if (!visitedFace.found(faceI))
140 Info<< "visitConnectedFaces : cellI:" << cellI << " faceI:"
141 << faceI << " isOwner:" << (cellI == mesh.faceOwner()[faceI])
146 visitedFace.insert(faceI);
148 // Mark which side of face was visited.
149 if (cellI == mesh.faceOwner()[faceI])
151 sideOwner_.insert(faceI);
155 // Visit all neighbouring faces on faceSet. Stay on this 'side' of
156 // face by doing edge-face-cell walk.
157 const labelList& fEdges = mesh.faceEdges()[faceI];
159 forAll(fEdges, fEdgeI)
161 label edgeI = fEdges[fEdgeI];
163 if (!fenceEdges.found(edgeI))
165 // Step along faces on edge from cell to cell until
166 // we hit face on faceSet.
168 // Find face reachable from edge
169 label otherFaceI = otherFace(mesh, cellI, faceI, edgeI);
171 if (mesh.isInternalFace(otherFaceI))
173 label otherCellI = cellI;
175 // Keep on crossing faces/cells until back on face on
177 while (!region.found(otherFaceI))
179 visitedFace.insert(otherFaceI);
183 Info<< "visitConnectedFaces : cellI:" << cellI
184 << " found insideEdgeFace:" << otherFaceI
189 // Cross otherFaceI into neighbouring cell
224 // From edge on face connected to point on region (regionPointI) cross
225 // to all other edges using this point by walking across faces
226 // Does not cross regionEdges so stays on one side
228 void Foam::regionSide::walkPointConnectedFaces
230 const primitiveMesh& mesh,
231 const labelHashSet& regionEdges,
232 const label regionPointI,
233 const label startFaceI,
234 const label startEdgeI,
235 labelHashSet& visitedEdges
239 insidePointFaces_.insert(startFaceI);
243 Info<< "walkPointConnectedFaces : regionPointI:" << regionPointI
244 << " faceI:" << startFaceI
245 << " edgeI:" << startEdgeI << " verts:"
246 << mesh.edges()[startEdgeI]
250 // Cross faceI i.e. get edge not startEdgeI which uses regionPointI
251 label edgeI = otherEdge(mesh, startFaceI, startEdgeI, regionPointI);
253 if (!regionEdges.found(edgeI))
255 if (!visitedEdges.found(edgeI))
257 visitedEdges.insert(edgeI);
261 Info<< "Crossed face from "
262 << " edgeI:" << startEdgeI << " verts:"
263 << mesh.edges()[startEdgeI]
264 << " to edge:" << edgeI << " verts:"
265 << mesh.edges()[edgeI]
269 // Cross edge to all faces connected to it.
271 const labelList& eFaces = mesh.edgeFaces()[edgeI];
273 forAll(eFaces, eFaceI)
275 label faceI = eFaces[eFaceI];
277 walkPointConnectedFaces
292 // Find all faces reachable from all non-fence points and staying on
294 void Foam::regionSide::walkAllPointConnectedFaces
296 const primitiveMesh& mesh,
297 const labelHashSet& regionFaces,
298 const labelHashSet& fencePoints
302 // Get all (internal and external) edges on region.
304 labelHashSet regionEdges(4*regionFaces.size());
308 labelHashSet::const_iterator iter = regionFaces.begin();
309 iter != regionFaces.end();
313 label faceI = iter.key();
315 const labelList& fEdges = mesh.faceEdges()[faceI];
317 forAll(fEdges, fEdgeI)
319 regionEdges.insert(fEdges[fEdgeI]);
325 // Visit all internal points on surface.
328 // Storage for visited points
329 labelHashSet visitedPoint(4*regionFaces.size());
331 // Insert fence points so we don't visit them
334 labelHashSet::const_iterator iter = fencePoints.begin();
335 iter != fencePoints.end();
339 visitedPoint.insert(iter.key());
342 labelHashSet visitedEdges(2*fencePoints.size());
347 Info<< "Excluding visit of points:" << visitedPoint << endl;
352 labelHashSet::const_iterator iter = regionFaces.begin();
353 iter != regionFaces.end();
357 label faceI = iter.key();
362 if (sideOwner_.found(faceI))
364 cellI = mesh.faceOwner()[faceI];
368 cellI = mesh.faceNeighbour()[faceI];
371 // Find starting point and edge on face.
372 const labelList& fEdges = mesh.faceEdges()[faceI];
374 forAll(fEdges, fEdgeI)
376 label edgeI = fEdges[fEdgeI];
378 // Get the face 'perpendicular' to faceI on region.
379 label otherFaceI = otherFace(mesh, cellI, faceI, edgeI);
382 const edge& e = mesh.edges()[edgeI];
384 if (!visitedPoint.found(e.start()))
386 Info<< "Determining visibility from point " << e.start()
389 visitedPoint.insert(e.start());
391 //edgeI = otherEdge(mesh, otherFaceI, edgeI, e.start());
393 walkPointConnectedFaces
403 if (!visitedPoint.found(e.end()))
405 Info<< "Determining visibility from point " << e.end()
408 visitedPoint.insert(e.end());
410 //edgeI = otherEdge(mesh, otherFaceI, edgeI, e.end());
412 walkPointConnectedFaces
427 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
429 // Construct from components
430 Foam::regionSide::regionSide
432 const primitiveMesh& mesh,
433 const labelHashSet& region, // faces of region
434 const labelHashSet& fenceEdges, // outside edges
435 const label startCellI,
436 const label startFaceI
439 sideOwner_(region.size()),
440 insidePointFaces_(region.size())
442 // Storage for visited faces
443 labelHashSet visitedFace(region.size());
445 // Visit all faces on this side of region.
446 // Mark for each face whether owner (or neighbour) has been visited.
459 // Visit all internal points on region and mark faces visitable from these.
460 // Sets insidePointFaces_.
463 labelHashSet fencePoints(fenceEdges.size());
467 labelHashSet::const_iterator iter = fenceEdges.begin();
468 iter != fenceEdges.end();
472 const edge& e = mesh.edges()[iter.key()];
474 fencePoints.insert(e.start());
475 fencePoints.insert(e.end());
478 walkAllPointConnectedFaces(mesh, region, fencePoints);
482 // ************************************************************************* //