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 "primitiveMesh.H"
28 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30 void Foam::edgeFaceCirculator::setEnd()
37 void Foam::edgeFaceCirculator::setFace
45 if (!isBoundaryEdge_ && !mesh_.isInternalFace(faceI))
49 "edgeFaceCirculator::setFace(const label, const label)"
50 ) << "Edge is not defined as boundary edge but still walked to"
51 << " boundary face:" << faceI << " on cell:" << cellI
57 void Foam::edgeFaceCirculator::otherFace(const label cellI)
59 const face& f = mesh_.faces()[faceLabel_];
61 label v1 = f.nextLabel(index_);
63 const cell& cFaces = mesh_.cells()[cellI];
67 label faceB = cFaces[i];
69 if (faceB != faceLabel_)
71 label fp = getMinIndex(mesh_.faces()[faceB], v0, v1);
76 setFace(faceB, cellI);
82 FatalErrorIn("edgeFaceCirculator::otherFace(const label)")
83 << "Could not find next face stepping"
84 << " through cell along edge." << endl
85 << "face:" << faceLabel_ << " index in face:" << index_
86 << " edge:" << mesh_.points()[v0] << mesh_.points()[v1]
91 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
93 //- Construct from components
94 Foam::edgeFaceCirculator::edgeFaceCirculator
96 const primitiveMesh& mesh,
97 const label faceLabel,
100 const bool isBoundaryEdge
104 faceLabel_(faceLabel),
105 ownerSide_(ownerSide),
107 isBoundaryEdge_(isBoundaryEdge),
108 startFaceLabel_(faceLabel_)
113 Foam::edgeFaceCirculator::edgeFaceCirculator(const edgeFaceCirculator& circ)
116 faceLabel_(circ.faceLabel_),
117 ownerSide_(circ.ownerSide_),
119 isBoundaryEdge_(circ.isBoundaryEdge_),
120 startFaceLabel_(circ.startFaceLabel_)
124 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
126 Foam::label Foam::edgeFaceCirculator::getMinIndex
133 label fp = findIndex(f, v0);
137 label fpMin1 = f.rcIndex(fp);
145 label fpPlus1 = f.fcIndex(fp);
147 if (f[fpPlus1] != v1)
157 Foam::label Foam::edgeFaceCirculator::faceLabel() const
163 bool Foam::edgeFaceCirculator::ownerSide() const
169 Foam::label Foam::edgeFaceCirculator::index() const
175 Foam::label Foam::edgeFaceCirculator::cellLabel() const
179 return mesh_.faceOwner()[faceLabel_];
181 else if (mesh_.isInternalFace(faceLabel_))
183 return mesh_.faceNeighbour()[faceLabel_];
192 bool Foam::edgeFaceCirculator::sameOrder(const label v0, const label v1) const
194 const face& f = mesh_.faces()[faceLabel_];
196 label fp = getMinIndex(f, v0, v1);
202 "edgeFaceCirculator::sameOrder(const label, const label) const"
203 ) << "v0:" << v1 << " and v1:" << v1
204 << " not on position:" << index_ << " on face:" << faceLabel_
205 << " verts:" << f << " or not consecutive." << abort(FatalError);
208 // If we are neighbour the face would point into us so the min index would
210 return ownerSide_ != (f[index_] == v0);
214 void Foam::edgeFaceCirculator::setCanonical()
218 // Boundary edge. Step until we're on boundary face and ownerSide
223 if (mesh_.isInternalFace(faceLabel_))
227 label cellI = mesh_.faceNeighbour()[faceLabel_];
229 // Maintain reverse direction of walking
230 ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
234 label cellI = mesh_.faceOwner()[faceLabel_];
236 // Maintain reverse direction of walking
237 ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
246 label cellI = mesh_.faceOwner()[faceLabel_];
248 // Maintain reverse direction of walking
249 ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
256 const face& f = mesh_.faces()[faceLabel_];
258 FatalErrorIn("Foam::edgeFaceCirculator::setCanonical()")
259 << "Walked " << i << " cells around edge "
260 << mesh_.points()[f[index_]]
261 << mesh_.points()[f.nextLabel(index_)]
262 << " without reaching a boundary face."
263 << " Are you sure this is a boundary edge?"
264 << abort(FatalError);
268 // Set up for correct walking
270 startFaceLabel_ = faceLabel_;
274 // Internal edge. Walk until we hit minimum face label.
275 label minFaceI = faceLabel_;
276 bool minOwnerSide = ownerSide_;
277 label minIndex = index_;
283 if (operator==(end()))
288 if (!mesh_.isInternalFace(faceLabel_))
290 const face& f = mesh_.faces()[faceLabel_];
292 FatalErrorIn("Foam::edgeFaceCirculator::setCanonical()")
293 << "Reached boundary face " << faceLabel_
294 << " when walking around internal edge "
295 << mesh_.points()[f[index_]]
296 << mesh_.points()[f.nextLabel(index_)]
298 << "Are you sure this is an internal edge?"
299 << abort(FatalError);
302 if (faceLabel_ < minFaceI)
304 minFaceI = faceLabel_;
305 minOwnerSide = ownerSide_;
310 faceLabel_ = minFaceI;
311 ownerSide_ = minOwnerSide;
313 startFaceLabel_ = faceLabel_;
318 void Foam::edgeFaceCirculator::operator=(const edgeFaceCirculator& circ)
320 faceLabel_ = circ.faceLabel_;
321 ownerSide_ = circ.ownerSide_;
322 index_ = circ.index_;
323 isBoundaryEdge_ = circ.isBoundaryEdge_;
324 startFaceLabel_ = circ.startFaceLabel_;
328 bool Foam::edgeFaceCirculator::operator==(const edgeFaceCirculator& circ) const
330 return faceLabel_ == circ.faceLabel_ && index_ == circ.index_;
332 ////- Note: do I need full comparison? If not we now have that circulators
333 //// around same edge but in different direction are considered not equal
334 //if (faceLabel_ == -1 && circ.faceLabel_ == -1)
336 // // both endConstIter
341 // faceLabel_ == circ.faceLabel_
342 // && ownerSide_ == circ.ownerSide_
343 // && index_ == circ.index_;
344 // && startFaceLabel_ == circ.startFaceLabel_;
348 bool Foam::edgeFaceCirculator::operator!=(const edgeFaceCirculator& circ) const
350 return !(*this == circ);
354 //- Step to next face.
355 Foam::edgeFaceCirculator& Foam::edgeFaceCirculator::operator++()
357 if (faceLabel_ == -1)
359 FatalErrorIn("edgeFaceCirculator::operator++()")
360 << "Already reached end(). Cannot walk any further."
361 << abort(FatalError);
366 label cellI = mesh_.faceOwner()[faceLabel_];
368 // Maintain direction of walking
369 ownerSide_ = (mesh_.faceOwner()[faceLabel_] != cellI);
371 // Check for internal edge : ends on starting face.
372 if (!isBoundaryEdge_ && faceLabel_ == startFaceLabel_)
377 else if (mesh_.isInternalFace(faceLabel_))
380 label cellI = mesh_.faceNeighbour()[faceLabel_];
382 // Maintain direction of walking
383 ownerSide_ = (mesh_.faceOwner()[faceLabel_] != cellI);
385 // Check for internal edge : ends on starting face.
386 if (!isBoundaryEdge_ && faceLabel_ == startFaceLabel_)
393 // neighbour side of boundary face reached. Mark as endConstIter.
401 Foam::edgeFaceCirculator Foam::edgeFaceCirculator::begin() const
403 edgeFaceCirculator iter
420 Foam::edgeFaceCirculator Foam::edgeFaceCirculator::cbegin() const
422 edgeFaceCirculator iter
439 const Foam::edgeFaceCirculator& Foam::edgeFaceCirculator::end() const
444 const Foam::edgeFaceCirculator& Foam::edgeFaceCirculator::cend() const
450 // ************************************************************************* //