FreeFOAM The Cross-Platform CFD Toolkit
edgeFaceCirculatorI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include <OpenFOAM/primitiveMesh.H>
27 
28 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
29 
30 void Foam::edgeFaceCirculator::setEnd()
31 {
32  faceLabel_ = -1;
33  index_ = -1;
34 }
35 
36 
37 void Foam::edgeFaceCirculator::setFace
38 (
39  const label faceI,
40  const label cellI
41 )
42 {
43  faceLabel_ = faceI;
44 
45  if (!isBoundaryEdge_ && !mesh_.isInternalFace(faceI))
46  {
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  }
54 }
55 
56 
57 void Foam::edgeFaceCirculator::otherFace(const label cellI)
58 {
59  const face& f = mesh_.faces()[faceLabel_];
60  label v0 = f[index_];
61  label v1 = f.nextLabel(index_);
62 
63  const cell& cFaces = mesh_.cells()[cellI];
64 
65  forAll(cFaces, i)
66  {
67  label faceB = cFaces[i];
68 
69  if (faceB != faceLabel_)
70  {
71  label fp = getMinIndex(mesh_.faces()[faceB], v0, v1);
72 
73  if (fp >= 0)
74  {
75  index_ = fp;
76  setFace(faceB, cellI);
77  return;
78  }
79  }
80  }
81 
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);
88 }
89 
90 
91 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
92 
93 //- Construct from components
95 (
96  const primitiveMesh& mesh,
97  const label faceLabel,
98  const bool ownerSide,
99  const label index,
100  const bool isBoundaryEdge
101 )
102 :
103  mesh_(mesh),
104  faceLabel_(faceLabel),
105  ownerSide_(ownerSide),
106  index_(index),
107  isBoundaryEdge_(isBoundaryEdge),
108  startFaceLabel_(faceLabel_)
109 {}
110 
111 
112 //- Construct copy
114 :
115  mesh_(circ.mesh_),
116  faceLabel_(circ.faceLabel_),
117  ownerSide_(circ.ownerSide_),
118  index_(circ.index_),
119  isBoundaryEdge_(circ.isBoundaryEdge_),
120  startFaceLabel_(circ.startFaceLabel_)
121 {}
122 
123 
124 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
125 
127 (
128  const face& f,
129  const label v0,
130  const label v1
131 )
132 {
133  label fp = findIndex(f, v0);
134 
135  if (fp != -1)
136  {
137  label fpMin1 = f.rcIndex(fp);
138 
139  if (f[fpMin1] == v1)
140  {
141  fp = fpMin1;
142  }
143  else
144  {
145  label fpPlus1 = f.fcIndex(fp);
146 
147  if (f[fpPlus1] != v1)
148  {
149  fp = -1;
150  }
151  }
152  }
153  return fp;
154 }
155 
156 
158 {
159  return faceLabel_;
160 }
161 
162 
164 {
165  return ownerSide_;
166 }
167 
168 
170 {
171  return index_;
172 }
173 
174 
176 {
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  }
189 }
190 
191 
192 bool Foam::edgeFaceCirculator::sameOrder(const label v0, const label v1) const
193 {
194  const face& f = mesh_.faces()[faceLabel_];
195 
196  label fp = getMinIndex(f, v0, v1);
197 
198  if (fp != index_)
199  {
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  }
207 
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);
211 }
212 
213 
215 {
216  if (isBoundaryEdge_)
217  {
218  // Boundary edge. Step until we're on boundary face and ownerSide
219  label i = 0;
220 
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  }
251 
252  i++;
253 
254  if (i >= 1000)
255  {
256  const face& f = mesh_.faces()[faceLabel_];
257 
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  }
267 
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_;
278 
279  while (true)
280  {
281  operator++();
282 
283  if (operator==(end()))
284  {
285  break;
286  }
287 
288  if (!mesh_.isInternalFace(faceLabel_))
289  {
290  const face& f = mesh_.faces()[faceLabel_];
291 
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  }
301 
302  if (faceLabel_ < minFaceI)
303  {
304  minFaceI = faceLabel_;
305  minOwnerSide = ownerSide_;
306  minIndex = index_;
307  }
308  }
309 
310  faceLabel_ = minFaceI;
311  ownerSide_ = minOwnerSide;
312  index_ = minIndex;
313  startFaceLabel_ = faceLabel_;
314  }
315 }
316 
317 
319 {
320  faceLabel_ = circ.faceLabel_;
321  ownerSide_ = circ.ownerSide_;
322  index_ = circ.index_;
323  isBoundaryEdge_ = circ.isBoundaryEdge_;
324  startFaceLabel_ = circ.startFaceLabel_;
325 }
326 
327 
329 {
330  return faceLabel_ == circ.faceLabel_ && index_ == circ.index_;
331 
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_;
345 }
346 
347 
349 {
350  return !(*this == circ);
351 }
352 
353 
354 //- Step to next face.
356 {
357  if (faceLabel_ == -1)
358  {
359  FatalErrorIn("edgeFaceCirculator::operator++()")
360  << "Already reached end(). Cannot walk any further."
361  << abort(FatalError);
362  }
363  else if (ownerSide_)
364  {
365  // Step to owner
366  label cellI = mesh_.faceOwner()[faceLabel_];
367  otherFace(cellI);
368  // Maintain direction of walking
369  ownerSide_ = (mesh_.faceOwner()[faceLabel_] != cellI);
370 
371  // Check for internal edge : ends on starting face.
372  if (!isBoundaryEdge_ && faceLabel_ == startFaceLabel_)
373  {
374  setEnd();
375  }
376  }
377  else if (mesh_.isInternalFace(faceLabel_))
378  {
379  // Step to neighbour
380  label cellI = mesh_.faceNeighbour()[faceLabel_];
381  otherFace(cellI);
382  // Maintain direction of walking
383  ownerSide_ = (mesh_.faceOwner()[faceLabel_] != cellI);
384 
385  // Check for internal edge : ends on starting face.
386  if (!isBoundaryEdge_ && faceLabel_ == startFaceLabel_)
387  {
388  setEnd();
389  }
390  }
391  else
392  {
393  // neighbour side of boundary face reached. Mark as endConstIter.
394  setEnd();
395  }
396 
397  return *this;
398 }
399 
400 
402 {
403  edgeFaceCirculator iter
404  (
405  mesh_,
406  faceLabel_,
407  ownerSide_,
408  index_,
409  isBoundaryEdge_
410  );
411 
412  if (isBoundaryEdge_)
413  {
414  iter.setCanonical();
415  }
416  return iter;
417 }
418 
419 
421 {
422  edgeFaceCirculator iter
423  (
424  mesh_,
425  faceLabel_,
426  ownerSide_,
427  index_,
428  isBoundaryEdge_
429  );
430 
431  if (isBoundaryEdge_)
432  {
433  iter.setCanonical();
434  }
435  return iter;
436 }
437 
438 
440 {
441  return endConstIter;
442 }
443 
445 {
446  return endConstIter;
447 }
448 
449 
450 // ************************ vim: set sw=4 sts=4 et: ************************ //