BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / meshTools / edgeFaceCirculator / edgeFaceCirculatorI.H
blob6eac8946f645d3056af2cbb6c6851f2509a85a66
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "primitiveMesh.H"
28 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
30 void Foam::edgeFaceCirculator::setEnd()
32     faceLabel_ = -1;
33     index_ = -1;
37 void Foam::edgeFaceCirculator::setFace
39     const label faceI,
40     const label cellI
43     faceLabel_ = faceI;
45     if (!isBoundaryEdge_ && !mesh_.isInternalFace(faceI))
46     {
47         FatalErrorIn
48         (
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
52             << abort(FatalError);
53     }
57 void Foam::edgeFaceCirculator::otherFace(const label cellI)
59     const face& f = mesh_.faces()[faceLabel_];
60     label v0 = f[index_];
61     label v1 = f.nextLabel(index_);
63     const cell& cFaces = mesh_.cells()[cellI];
65     forAll(cFaces, i)
66     {
67         label faceB = cFaces[i];
69         if (faceB != faceLabel_)
70         {
71             label fp = getMinIndex(mesh_.faces()[faceB], v0, v1);
73             if (fp >= 0)
74             {
75                 index_ = fp;
76                 setFace(faceB, cellI);
77                 return;
78             }
79         }
80     }
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]
87         << abort(FatalError);
91 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
93 //- Construct from components
94 Foam::edgeFaceCirculator::edgeFaceCirculator
96     const primitiveMesh& mesh,
97     const label faceLabel,
98     const bool ownerSide,
99     const label index,
100     const bool isBoundaryEdge
103     mesh_(mesh),
104     faceLabel_(faceLabel),
105     ownerSide_(ownerSide),
106     index_(index),
107     isBoundaryEdge_(isBoundaryEdge),
108     startFaceLabel_(faceLabel_)
112 //- Construct copy
113 Foam::edgeFaceCirculator::edgeFaceCirculator(const edgeFaceCirculator& circ)
115     mesh_(circ.mesh_),
116     faceLabel_(circ.faceLabel_),
117     ownerSide_(circ.ownerSide_),
118     index_(circ.index_),
119     isBoundaryEdge_(circ.isBoundaryEdge_),
120     startFaceLabel_(circ.startFaceLabel_)
124 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
126 Foam::label Foam::edgeFaceCirculator::getMinIndex
128     const face& f,
129     const label v0,
130     const label v1
133     label fp = findIndex(f, v0);
135     if (fp != -1)
136     {
137         label fpMin1 = f.rcIndex(fp);
139         if (f[fpMin1] == v1)
140         {
141             fp = fpMin1;
142         }
143         else
144         {
145             label fpPlus1 = f.fcIndex(fp);
147             if (f[fpPlus1] != v1)
148             {
149                 fp = -1;
150             }
151         }
152     }
153     return fp;
157 Foam::label Foam::edgeFaceCirculator::faceLabel() const
159     return faceLabel_;
163 bool Foam::edgeFaceCirculator::ownerSide() const
165     return ownerSide_;
169 Foam::label Foam::edgeFaceCirculator::index() const
171     return index_;
175 Foam::label Foam::edgeFaceCirculator::cellLabel() const
177     if (ownerSide_)
178     {
179         return mesh_.faceOwner()[faceLabel_];
180     }
181     else if (mesh_.isInternalFace(faceLabel_))
182     {
183         return mesh_.faceNeighbour()[faceLabel_];
184     }
185     else
186     {
187         return -1;
188     }
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);
198     if (fp != index_)
199     {
200         FatalErrorIn
201         (
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);
206     }
208     // If we are neighbour the face would point into us so the min index would
209     // be v0.
210     return ownerSide_ != (f[index_] == v0);
214 void Foam::edgeFaceCirculator::setCanonical()
216     if (isBoundaryEdge_)
217     {
218         // Boundary edge. Step until we're on boundary face and ownerSide
219         label i = 0;
221         while (true)
222         {
223             if (mesh_.isInternalFace(faceLabel_))
224             {
225                 if (ownerSide_)
226                 {
227                     label cellI = mesh_.faceNeighbour()[faceLabel_];
228                     otherFace(cellI);
229                     // Maintain reverse direction of walking
230                     ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
231                 }
232                 else
233                 {
234                     label cellI = mesh_.faceOwner()[faceLabel_];
235                     otherFace(cellI);
236                     // Maintain reverse direction of walking
237                     ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
238                 }
239             }
240             else if (ownerSide_)
241             {
242                 break;
243             }
244             else
245             {
246                 label cellI = mesh_.faceOwner()[faceLabel_];
247                 otherFace(cellI);
248                 // Maintain reverse direction of walking
249                 ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
250             }
252             i++;
254             if (i >= 1000)
255             {
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);
265             }
266         }
268         // Set up for correct walking
269         ownerSide_ = true;
270         startFaceLabel_ = faceLabel_;
271     }
272     else
273     {
274         // Internal edge. Walk until we hit minimum face label.
275         label minFaceI = faceLabel_;
276         bool minOwnerSide = ownerSide_;
277         label minIndex = index_;
279         while (true)
280         {
281             operator++();
283             if (operator==(end()))
284             {
285                 break;
286             }
288             if (!mesh_.isInternalFace(faceLabel_))
289             {
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_)]
297                     << "." << endl
298                     << "Are you sure this is an internal edge?"
299                     << abort(FatalError);
300             }
302             if (faceLabel_ < minFaceI)
303             {
304                 minFaceI = faceLabel_;
305                 minOwnerSide = ownerSide_;
306                 minIndex = index_;
307             }
308         }
310         faceLabel_ = minFaceI;
311         ownerSide_ = minOwnerSide;
312         index_ = minIndex;
313         startFaceLabel_ = faceLabel_;
314     }
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)
335     //{
336     //    // both endConstIter
337     //    return true;
338     //}
339     //
340     //return
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&
356 Foam::edgeFaceCirculator::operator++()
358     if (faceLabel_ == -1)
359     {
360         FatalErrorIn("edgeFaceCirculator::operator++()")
361             << "Already reached end(). Cannot walk any further."
362             << abort(FatalError);
363     }
364     else if (ownerSide_)
365     {
366         // Step to owner
367         label cellI = mesh_.faceOwner()[faceLabel_];
368         otherFace(cellI);
369         // Maintain direction of walking
370         ownerSide_ = (mesh_.faceOwner()[faceLabel_] != cellI);
372         // Check for internal edge : ends on starting face.
373         if (!isBoundaryEdge_ && faceLabel_ == startFaceLabel_)
374         {
375             setEnd();
376         }
377     }
378     else if (mesh_.isInternalFace(faceLabel_))
379     {
380         // Step to neighbour
381         label cellI = mesh_.faceNeighbour()[faceLabel_];
382         otherFace(cellI);
383         // Maintain direction of walking
384         ownerSide_ = (mesh_.faceOwner()[faceLabel_] != cellI);
386         // Check for internal edge : ends on starting face.
387         if (!isBoundaryEdge_ && faceLabel_ == startFaceLabel_)
388         {
389             setEnd();
390         }
391     }
392     else
393     {
394         // neighbour side of boundary face reached. Mark as endConstIter.
395         setEnd();
396     }
398     return *this;
402 Foam::edgeFaceCirculator Foam::edgeFaceCirculator::begin() const
404     edgeFaceCirculator iter
405     (
406         mesh_,
407         faceLabel_,
408         ownerSide_,
409         index_,
410         isBoundaryEdge_
411     );
413     if (isBoundaryEdge_)
414     {
415         iter.setCanonical();
416     }
417     return iter;
421 Foam::edgeFaceCirculator Foam::edgeFaceCirculator::cbegin() const
423     edgeFaceCirculator iter
424     (
425         mesh_,
426         faceLabel_,
427         ownerSide_,
428         index_,
429         isBoundaryEdge_
430     );
432     if (isBoundaryEdge_)
433     {
434         iter.setCanonical();
435     }
436     return iter;
440 const Foam::edgeFaceCirculator& Foam::edgeFaceCirculator::end() const
442     return endConstIter;
445 const Foam::edgeFaceCirculator& Foam::edgeFaceCirculator::cend() const
447     return endConstIter;
451 // ************************************************************************* //