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
00027
00028
00029
00030 #include "enrichedPatch.H"
00031 #include <OpenFOAM/boolList.H>
00032 #include <OpenFOAM/DynamicList.H>
00033 #include <OpenFOAM/labelPair.H>
00034 #include <OpenFOAM/primitiveMesh.H>
00035 #include <OpenFOAM/HashSet.H>
00036
00037
00038
00039
00040 const Foam::label Foam::enrichedPatch::maxFaceSizeDebug_ = 100;
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 void Foam::enrichedPatch::calcCutFaces() const
00051 {
00052 if (cutFacesPtr_ || cutFaceMasterPtr_ || cutFaceSlavePtr_)
00053 {
00054 FatalErrorIn("void enrichedPatch::calcCutFaces() const")
00055 << "Cut faces addressing already calculated."
00056 << abort(FatalError);
00057 }
00058
00059 const faceList& enFaces = enrichedFaces();
00060 const labelList& mp = meshPoints();
00061 const faceList& lf = localFaces();
00062 const pointField& lp = localPoints();
00063 const labelListList& pp = pointPoints();
00064
00065
00066
00067
00068 const Map<labelList>& masterPointFaceAddr = masterPointFaces();
00069
00070
00071 DynamicList<face> cf(2*lf.size());
00072 DynamicList<label> cfMaster(2*lf.size());
00073 DynamicList<label> cfSlave(2*lf.size());
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 HashSet<edge, Hash<edge> > edgesUsedOnce(pp.size());
00098 HashSet<edge, Hash<edge> > edgesUsedTwice
00099 (pp.size()*primitiveMesh::edgesPerPoint_);
00100
00101
00102 forAll (lf, faceI)
00103 {
00104 const face& curLocalFace = lf[faceI];
00105 const face& curGlobalFace = enFaces[faceI];
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 boolList usedFaceEdges(curLocalFace.size(), false);
00139
00140 SLList<edge> edgeSeeds;
00141
00142
00143 edgeList cfe = curLocalFace.edges();
00144 forAll (curLocalFace, edgeI)
00145 {
00146 edgeSeeds.append(cfe[edgeI]);
00147 }
00148
00149
00150 vector normal = curLocalFace.normal(lp);
00151 normal /= mag(normal);
00152
00153 while (edgeSeeds.size())
00154 {
00155
00156 const edge curEdge = edgeSeeds.removeHead();
00157
00158
00159 const label curEdgeWhich = curLocalFace.which(curEdge.start());
00160
00161
00162
00163 if
00164 (
00165 curEdgeWhich > -1
00166 && curLocalFace.nextLabel(curEdgeWhich) == curEdge.end()
00167 )
00168 {
00169
00170
00171 if (usedFaceEdges[curEdgeWhich]) continue;
00172
00173 usedFaceEdges[curEdgeWhich] = true;
00174 }
00175
00176
00177 if (edgesUsedTwice.found(curEdge)) continue;
00178
00179
00180
00181 DynamicList<label> cutFaceGlobalPoints(2*curLocalFace.size());
00182 DynamicList<label> cutFaceLocalPoints(2*curLocalFace.size());
00183
00184
00185 label prevPointLabel = curEdge.start();
00186 cutFaceGlobalPoints.append(mp[prevPointLabel]);
00187 cutFaceLocalPoints.append(prevPointLabel);
00188
00189
00190 label curPointLabel = curEdge.end();
00191 point curPoint = lp[curPointLabel];
00192 cutFaceGlobalPoints.append(mp[curPointLabel]);
00193 cutFaceLocalPoints.append(curPointLabel);
00194
00195 bool completedCutFace = false;
00196
00197 label faceSizeDebug = maxFaceSizeDebug_;
00198
00199 do
00200 {
00201
00202
00203 const labelList& nextPoints = pp[curPointLabel];
00204
00205
00206 vector ahead = curPoint - lp[prevPointLabel];
00207 ahead -= normal*(normal & ahead);
00208 ahead /= mag(ahead);
00209
00210 vector right = normal ^ ahead;
00211 right /= mag(right);
00212
00213
00214 scalar atanTurn = -GREAT;
00215 label bestAtanPoint = -1;
00216
00217 forAll (nextPoints, nextI)
00218 {
00219
00220
00221 if (nextPoints[nextI] != prevPointLabel)
00222 {
00223
00224 vector newDir = lp[nextPoints[nextI]] - curPoint;
00225
00226 newDir -= normal*(normal & newDir);
00227 scalar magNewDir = mag(newDir);
00228
00229
00230 if (magNewDir < SMALL)
00231 {
00232 FatalErrorIn
00233 (
00234 "void enrichedPatch::"
00235 "calcCutFaces() const"
00236 ) << "Zero length edge detected. Probable "
00237 << "projection error: slave patch probably "
00238 << "does not project onto master. "
00239 << "Please switch on "
00240 << "enriched patch debug for more info"
00241 << abort(FatalError);
00242 }
00243
00244 newDir /= magNewDir;
00245
00246 scalar curAtanTurn =
00247 atan2(newDir & right, newDir & ahead);
00248
00249
00250
00251 if (curAtanTurn > atanTurn)
00252 {
00253 bestAtanPoint = nextPoints[nextI];
00254 atanTurn = curAtanTurn;
00255 }
00256 }
00257 }
00258
00259
00260
00261
00262
00263
00264
00265 const label whichNextPoint = curLocalFace.which(curPointLabel);
00266
00267 if
00268 (
00269 whichNextPoint > -1
00270 && curLocalFace.nextLabel(whichNextPoint) == bestAtanPoint
00271 && usedFaceEdges[whichNextPoint]
00272 )
00273 {
00274
00275
00276
00277 completedCutFace = true;
00278 }
00279
00280
00281 if (edgesUsedTwice.found(edge(curPointLabel, bestAtanPoint)))
00282 {
00283
00284
00285 completedCutFace = true;
00286
00287 }
00288
00289 if (completedCutFace) continue;
00290
00291
00292 if (mp[bestAtanPoint] == cutFaceGlobalPoints[0])
00293 {
00294
00295
00296 completedCutFace = true;
00297
00298 if (debug)
00299 {
00300 Pout<< " local: " << cutFaceLocalPoints
00301 << " one side: " << faceI;
00302 }
00303
00304
00305 face cutFaceGlobal;
00306 cutFaceGlobal.transfer(cutFaceGlobalPoints);
00307
00308 cf.append(cutFaceGlobal);
00309
00310 face cutFaceLocal;
00311 cutFaceLocal.transfer(cutFaceLocalPoints);
00312
00313
00314
00315
00316
00317 forAll (cutFaceLocal, cutI)
00318 {
00319 const edge curCutFaceEdge
00320 (
00321 cutFaceLocal[cutI],
00322 cutFaceLocal.nextLabel(cutI)
00323 );
00324
00325
00326 HashSet<edge, Hash<edge> >::iterator euoIter =
00327 edgesUsedOnce.find(curCutFaceEdge);
00328
00329 if (euoIter == edgesUsedOnce.end())
00330 {
00331
00332 edgesUsedOnce.insert(curCutFaceEdge);
00333 }
00334 else
00335 {
00336
00337 edgesUsedOnce.erase(euoIter);
00338 edgesUsedTwice.insert(curCutFaceEdge);
00339 }
00340
00341 const label curCutFaceEdgeWhich = curLocalFace.which(curCutFaceEdge.start());
00342
00343 if
00344 (
00345 curCutFaceEdgeWhich > -1
00346 && curLocalFace.nextLabel(curCutFaceEdgeWhich) == curCutFaceEdge.end()
00347 )
00348 {
00349
00350
00351 usedFaceEdges[curCutFaceEdgeWhich] = true;
00352 }
00353 else
00354 {
00355
00356
00357 edgeSeeds.append(curCutFaceEdge.reverseEdge());
00358 }
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 if (faceI < slavePatch_.size())
00382 {
00383 Map<labelList>::const_iterator mpfAddrIter =
00384 masterPointFaceAddr.find(cutFaceGlobal[0]);
00385
00386 bool otherSideFound = false;
00387
00388 if (mpfAddrIter != masterPointFaceAddr.end())
00389 {
00390 bool miss = false;
00391
00392
00393 const labelList& masterFacesOfPZero = mpfAddrIter();
00394
00395 labelList hits(masterFacesOfPZero.size(), 1);
00396
00397 for
00398 (
00399 label pointI = 1;
00400 pointI < cutFaceGlobal.size();
00401 pointI++
00402 )
00403 {
00404 Map<labelList>::const_iterator
00405 mpfAddrPointIter =
00406 masterPointFaceAddr.find
00407 (
00408 cutFaceGlobal[pointI]
00409 );
00410
00411 if
00412 (
00413 mpfAddrPointIter
00414 == masterPointFaceAddr.end()
00415 )
00416 {
00417
00418 miss = true;
00419 break;
00420 }
00421
00422 const labelList& curMasterFaces =
00423 mpfAddrPointIter();
00424
00425
00426
00427 forAll (curMasterFaces, i)
00428 {
00429 forAll (masterFacesOfPZero, j)
00430 {
00431 if
00432 (
00433 curMasterFaces[i]
00434 == masterFacesOfPZero[j]
00435 )
00436 {
00437 hits[j]++;
00438 break;
00439 }
00440 }
00441 }
00442 }
00443
00444
00445 if (!miss)
00446 {
00447 forAll (hits, pointI)
00448 {
00449 if (hits[pointI] == cutFaceGlobal.size())
00450 {
00451
00452 otherSideFound = true;
00453
00454 cfMaster.append
00455 (
00456 masterFacesOfPZero[pointI]
00457 );
00458
00459 cfSlave.append(faceI);
00460
00461
00462
00463 cf[cf.size() - 1] =
00464 cf[cf.size() - 1].reverseFace();
00465
00466 if (debug)
00467 {
00468 Pout<< " other side: "
00469 << masterFacesOfPZero[pointI]
00470 << endl;
00471 }
00472 }
00473 }
00474
00475 }
00476
00477 if (!otherSideFound || miss)
00478 {
00479 if (debug)
00480 {
00481 Pout << " solo slave A" << endl;
00482 }
00483
00484 cfMaster.append(-1);
00485 cfSlave.append(faceI);
00486 }
00487 }
00488 else
00489 {
00490
00491 if (debug)
00492 {
00493 Pout << " solo slave B" << endl;
00494 }
00495
00496 cfMaster.append(-1);
00497 cfSlave.append(faceI);
00498 }
00499 }
00500 else
00501 {
00502 if (debug)
00503 {
00504 Pout << " master side" << endl;
00505 }
00506
00507 cfMaster.append(faceI - slavePatch_.size());
00508 cfSlave.append(-1);
00509 }
00510 }
00511 else
00512 {
00513
00514 prevPointLabel = curPointLabel;
00515 curPointLabel = bestAtanPoint;
00516 curPoint = lp[curPointLabel];
00517 cutFaceGlobalPoints.append(mp[curPointLabel]);
00518 cutFaceLocalPoints.append(curPointLabel);
00519
00520 if (debug || cutFaceGlobalPoints.size() > faceSizeDebug)
00521 {
00522 faceSizeDebug *= 2;
00523
00524
00525 forAll (cutFaceGlobalPoints, checkI)
00526 {
00527 for
00528 (
00529 label checkJ = checkI + 1;
00530 checkJ < cutFaceGlobalPoints.size();
00531 checkJ++
00532 )
00533 {
00534 if
00535 (
00536 cutFaceGlobalPoints[checkI]
00537 == cutFaceGlobalPoints[checkJ]
00538 )
00539 {
00540
00541 cutFaceLocalPoints.shrink();
00542
00543 face origFace;
00544 face origFaceLocal;
00545 if (faceI < slavePatch_.size())
00546 {
00547 origFace = slavePatch_[faceI];
00548 origFaceLocal =
00549 slavePatch_.localFaces()[faceI];
00550 }
00551 else
00552 {
00553 origFace =
00554 masterPatch_
00555 [faceI - slavePatch_.size()];
00556
00557 origFaceLocal =
00558 masterPatch_.localFaces()
00559 [faceI - slavePatch_.size()];
00560 }
00561
00562 FatalErrorIn
00563 (
00564 "void enrichedPatch::"
00565 "calcCutFaces() const"
00566 ) << "Duplicate point found in cut face. "
00567 << "Error in the face cutting "
00568 << "algorithm for global face "
00569 << origFace << " local face "
00570 << origFaceLocal << nl
00571 << "Slave size: " << slavePatch_.size()
00572 << " Master size: "
00573 << masterPatch_.size()
00574 << " index: " << faceI << ".\n"
00575 << "Face: " << curGlobalFace << nl
00576 << "Cut face: " << cutFaceGlobalPoints
00577 << " local: " << cutFaceLocalPoints
00578 << nl << "Points: "
00579 << face(cutFaceLocalPoints).points(lp)
00580 << abort(FatalError);
00581 }
00582 }
00583 }
00584 }
00585 }
00586 } while (!completedCutFace);
00587 }
00588
00589 if (debug)
00590 {
00591 Pout << " Finished face " << faceI << endl;
00592 }
00593
00594 }
00595
00596
00597 cutFacesPtr_ = new faceList();
00598 cutFacesPtr_->transfer(cf);
00599
00600 cutFaceMasterPtr_ = new labelList();
00601 cutFaceMasterPtr_->transfer(cfMaster);
00602
00603 cutFaceSlavePtr_ = new labelList();
00604 cutFaceSlavePtr_->transfer(cfSlave);
00605 }
00606
00607
00608 void Foam::enrichedPatch::clearCutFaces()
00609 {
00610 deleteDemandDrivenData(cutFacesPtr_);
00611 deleteDemandDrivenData(cutFaceMasterPtr_);
00612 deleteDemandDrivenData(cutFaceSlavePtr_);
00613 }
00614
00615
00616
00617
00618 const Foam::faceList& Foam::enrichedPatch::cutFaces() const
00619 {
00620 if (!cutFacesPtr_)
00621 {
00622 calcCutFaces();
00623 }
00624
00625 return *cutFacesPtr_;
00626 }
00627
00628
00629 const Foam::labelList& Foam::enrichedPatch::cutFaceMaster() const
00630 {
00631 if (!cutFaceMasterPtr_)
00632 {
00633 calcCutFaces();
00634 }
00635
00636 return *cutFaceMasterPtr_;
00637 }
00638
00639
00640 const Foam::labelList& Foam::enrichedPatch::cutFaceSlave() const
00641 {
00642 if (!cutFaceSlavePtr_)
00643 {
00644 calcCutFaces();
00645 }
00646
00647 return *cutFaceSlavePtr_;
00648 }
00649
00650
00651