Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <OpenFOAM/primitiveMesh.H>
00027
00028
00029
00030 void Foam::edgeFaceCirculator::setEnd()
00031 {
00032 faceLabel_ = -1;
00033 index_ = -1;
00034 }
00035
00036
00037 void Foam::edgeFaceCirculator::setFace
00038 (
00039 const label faceI,
00040 const label cellI
00041 )
00042 {
00043 faceLabel_ = faceI;
00044
00045 if (!isBoundaryEdge_ && !mesh_.isInternalFace(faceI))
00046 {
00047 FatalErrorIn
00048 (
00049 "edgeFaceCirculator::setFace(const label, const label)"
00050 ) << "Edge is not defined as boundary edge but still walked to"
00051 << " boundary face:" << faceI << " on cell:" << cellI
00052 << abort(FatalError);
00053 }
00054 }
00055
00056
00057 void Foam::edgeFaceCirculator::otherFace(const label cellI)
00058 {
00059 const face& f = mesh_.faces()[faceLabel_];
00060 label v0 = f[index_];
00061 label v1 = f.nextLabel(index_);
00062
00063 const cell& cFaces = mesh_.cells()[cellI];
00064
00065 forAll(cFaces, i)
00066 {
00067 label faceB = cFaces[i];
00068
00069 if (faceB != faceLabel_)
00070 {
00071 label fp = getMinIndex(mesh_.faces()[faceB], v0, v1);
00072
00073 if (fp >= 0)
00074 {
00075 index_ = fp;
00076 setFace(faceB, cellI);
00077 return;
00078 }
00079 }
00080 }
00081
00082 FatalErrorIn("edgeFaceCirculator::otherFace(const label)")
00083 << "Could not find next face stepping"
00084 << " through cell along edge." << endl
00085 << "face:" << faceLabel_ << " index in face:" << index_
00086 << " edge:" << mesh_.points()[v0] << mesh_.points()[v1]
00087 << abort(FatalError);
00088 }
00089
00090
00091
00092
00093
00094 Foam::edgeFaceCirculator::edgeFaceCirculator
00095 (
00096 const primitiveMesh& mesh,
00097 const label faceLabel,
00098 const bool ownerSide,
00099 const label index,
00100 const bool isBoundaryEdge
00101 )
00102 :
00103 mesh_(mesh),
00104 faceLabel_(faceLabel),
00105 ownerSide_(ownerSide),
00106 index_(index),
00107 isBoundaryEdge_(isBoundaryEdge),
00108 startFaceLabel_(faceLabel_)
00109 {}
00110
00111
00112
00113 Foam::edgeFaceCirculator::edgeFaceCirculator(const edgeFaceCirculator& circ)
00114 :
00115 mesh_(circ.mesh_),
00116 faceLabel_(circ.faceLabel_),
00117 ownerSide_(circ.ownerSide_),
00118 index_(circ.index_),
00119 isBoundaryEdge_(circ.isBoundaryEdge_),
00120 startFaceLabel_(circ.startFaceLabel_)
00121 {}
00122
00123
00124
00125
00126 Foam::label Foam::edgeFaceCirculator::getMinIndex
00127 (
00128 const face& f,
00129 const label v0,
00130 const label v1
00131 )
00132 {
00133 label fp = findIndex(f, v0);
00134
00135 if (fp != -1)
00136 {
00137 label fpMin1 = f.rcIndex(fp);
00138
00139 if (f[fpMin1] == v1)
00140 {
00141 fp = fpMin1;
00142 }
00143 else
00144 {
00145 label fpPlus1 = f.fcIndex(fp);
00146
00147 if (f[fpPlus1] != v1)
00148 {
00149 fp = -1;
00150 }
00151 }
00152 }
00153 return fp;
00154 }
00155
00156
00157 Foam::label Foam::edgeFaceCirculator::faceLabel() const
00158 {
00159 return faceLabel_;
00160 }
00161
00162
00163 bool Foam::edgeFaceCirculator::ownerSide() const
00164 {
00165 return ownerSide_;
00166 }
00167
00168
00169 Foam::label Foam::edgeFaceCirculator::index() const
00170 {
00171 return index_;
00172 }
00173
00174
00175 Foam::label Foam::edgeFaceCirculator::cellLabel() const
00176 {
00177 if (ownerSide_)
00178 {
00179 return mesh_.faceOwner()[faceLabel_];
00180 }
00181 else if (mesh_.isInternalFace(faceLabel_))
00182 {
00183 return mesh_.faceNeighbour()[faceLabel_];
00184 }
00185 else
00186 {
00187 return -1;
00188 }
00189 }
00190
00191
00192 bool Foam::edgeFaceCirculator::sameOrder(const label v0, const label v1) const
00193 {
00194 const face& f = mesh_.faces()[faceLabel_];
00195
00196 label fp = getMinIndex(f, v0, v1);
00197
00198 if (fp != index_)
00199 {
00200 FatalErrorIn
00201 (
00202 "edgeFaceCirculator::sameOrder(const label, const label) const"
00203 ) << "v0:" << v1 << " and v1:" << v1
00204 << " not on position:" << index_ << " on face:" << faceLabel_
00205 << " verts:" << f << " or not consecutive." << abort(FatalError);
00206 }
00207
00208
00209
00210 return ownerSide_ != (f[index_] == v0);
00211 }
00212
00213
00214 void Foam::edgeFaceCirculator::setCanonical()
00215 {
00216 if (isBoundaryEdge_)
00217 {
00218
00219 label i = 0;
00220
00221 while (true)
00222 {
00223 if (mesh_.isInternalFace(faceLabel_))
00224 {
00225 if (ownerSide_)
00226 {
00227 label cellI = mesh_.faceNeighbour()[faceLabel_];
00228 otherFace(cellI);
00229
00230 ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
00231 }
00232 else
00233 {
00234 label cellI = mesh_.faceOwner()[faceLabel_];
00235 otherFace(cellI);
00236
00237 ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
00238 }
00239 }
00240 else if (ownerSide_)
00241 {
00242 break;
00243 }
00244 else
00245 {
00246 label cellI = mesh_.faceOwner()[faceLabel_];
00247 otherFace(cellI);
00248
00249 ownerSide_ = (mesh_.faceOwner()[faceLabel_] == cellI);
00250 }
00251
00252 i++;
00253
00254 if (i >= 1000)
00255 {
00256 const face& f = mesh_.faces()[faceLabel_];
00257
00258 FatalErrorIn("Foam::edgeFaceCirculator::setCanonical()")
00259 << "Walked " << i << " cells around edge "
00260 << mesh_.points()[f[index_]]
00261 << mesh_.points()[f.nextLabel(index_)]
00262 << " without reaching a boundary face."
00263 << " Are you sure this is a boundary edge?"
00264 << abort(FatalError);
00265 }
00266 }
00267
00268
00269 ownerSide_ = true;
00270 startFaceLabel_ = faceLabel_;
00271 }
00272 else
00273 {
00274
00275 label minFaceI = faceLabel_;
00276 bool minOwnerSide = ownerSide_;
00277 label minIndex = index_;
00278
00279 while (true)
00280 {
00281 operator++();
00282
00283 if (operator==(end()))
00284 {
00285 break;
00286 }
00287
00288 if (!mesh_.isInternalFace(faceLabel_))
00289 {
00290 const face& f = mesh_.faces()[faceLabel_];
00291
00292 FatalErrorIn("Foam::edgeFaceCirculator::setCanonical()")
00293 << "Reached boundary face " << faceLabel_
00294 << " when walking around internal edge "
00295 << mesh_.points()[f[index_]]
00296 << mesh_.points()[f.nextLabel(index_)]
00297 << "." << endl
00298 << "Are you sure this is an internal edge?"
00299 << abort(FatalError);
00300 }
00301
00302 if (faceLabel_ < minFaceI)
00303 {
00304 minFaceI = faceLabel_;
00305 minOwnerSide = ownerSide_;
00306 minIndex = index_;
00307 }
00308 }
00309
00310 faceLabel_ = minFaceI;
00311 ownerSide_ = minOwnerSide;
00312 index_ = minIndex;
00313 startFaceLabel_ = faceLabel_;
00314 }
00315 }
00316
00317
00318 void Foam::edgeFaceCirculator::operator=(const edgeFaceCirculator& circ)
00319 {
00320 faceLabel_ = circ.faceLabel_;
00321 ownerSide_ = circ.ownerSide_;
00322 index_ = circ.index_;
00323 isBoundaryEdge_ = circ.isBoundaryEdge_;
00324 startFaceLabel_ = circ.startFaceLabel_;
00325 }
00326
00327
00328 bool Foam::edgeFaceCirculator::operator==(const edgeFaceCirculator& circ) const
00329 {
00330 return faceLabel_ == circ.faceLabel_ && index_ == circ.index_;
00331
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 }
00346
00347
00348 bool Foam::edgeFaceCirculator::operator!=(const edgeFaceCirculator& circ) const
00349 {
00350 return !(*this == circ);
00351 }
00352
00353
00354
00355 Foam::edgeFaceCirculator& Foam::edgeFaceCirculator::operator++()
00356 {
00357 if (faceLabel_ == -1)
00358 {
00359 FatalErrorIn("edgeFaceCirculator::operator++()")
00360 << "Already reached end(). Cannot walk any further."
00361 << abort(FatalError);
00362 }
00363 else if (ownerSide_)
00364 {
00365
00366 label cellI = mesh_.faceOwner()[faceLabel_];
00367 otherFace(cellI);
00368
00369 ownerSide_ = (mesh_.faceOwner()[faceLabel_] != cellI);
00370
00371
00372 if (!isBoundaryEdge_ && faceLabel_ == startFaceLabel_)
00373 {
00374 setEnd();
00375 }
00376 }
00377 else if (mesh_.isInternalFace(faceLabel_))
00378 {
00379
00380 label cellI = mesh_.faceNeighbour()[faceLabel_];
00381 otherFace(cellI);
00382
00383 ownerSide_ = (mesh_.faceOwner()[faceLabel_] != cellI);
00384
00385
00386 if (!isBoundaryEdge_ && faceLabel_ == startFaceLabel_)
00387 {
00388 setEnd();
00389 }
00390 }
00391 else
00392 {
00393
00394 setEnd();
00395 }
00396
00397 return *this;
00398 }
00399
00400
00401 Foam::edgeFaceCirculator Foam::edgeFaceCirculator::begin() const
00402 {
00403 edgeFaceCirculator iter
00404 (
00405 mesh_,
00406 faceLabel_,
00407 ownerSide_,
00408 index_,
00409 isBoundaryEdge_
00410 );
00411
00412 if (isBoundaryEdge_)
00413 {
00414 iter.setCanonical();
00415 }
00416 return iter;
00417 }
00418
00419
00420 Foam::edgeFaceCirculator Foam::edgeFaceCirculator::cbegin() const
00421 {
00422 edgeFaceCirculator iter
00423 (
00424 mesh_,
00425 faceLabel_,
00426 ownerSide_,
00427 index_,
00428 isBoundaryEdge_
00429 );
00430
00431 if (isBoundaryEdge_)
00432 {
00433 iter.setCanonical();
00434 }
00435 return iter;
00436 }
00437
00438
00439 const Foam::edgeFaceCirculator& Foam::edgeFaceCirculator::end() const
00440 {
00441 return endConstIter;
00442 }
00443
00444 const Foam::edgeFaceCirculator& Foam::edgeFaceCirculator::cend() const
00445 {
00446 return endConstIter;
00447 }
00448
00449
00450