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 "polyMeshZipUpCells.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <OpenFOAM/Time.H>
00029
00030
00031
00032
00033
00034
00035
00036 bool Foam::polyMeshZipUpCells(polyMesh& mesh)
00037 {
00038 if (polyMesh::debug)
00039 {
00040 Info<< "bool polyMeshZipUpCells(polyMesh& mesh) const: "
00041 << "zipping up topologically open cells" << endl;
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 label nChangedFacesInMesh = 0;
00063 label nCycles = 0;
00064
00065 labelHashSet problemCells;
00066
00067 do
00068 {
00069 nChangedFacesInMesh = 0;
00070
00071 const cellList& Cells = mesh.cells();
00072 const pointField& Points = mesh.points();
00073
00074 faceList newFaces = mesh.faces();
00075
00076 const faceList& oldFaces = mesh.faces();
00077 const labelListList& pFaces = mesh.pointFaces();
00078
00079 forAll (Cells, cellI)
00080 {
00081 const labelList& curFaces = Cells[cellI];
00082 const edgeList cellEdges = Cells[cellI].edges(oldFaces);
00083 const labelList cellPoints = Cells[cellI].labels(oldFaces);
00084
00085
00086
00087 labelList edgeUsage(cellEdges.size(), 0);
00088
00089 forAll (curFaces, faceI)
00090 {
00091 edgeList curFaceEdges = oldFaces[curFaces[faceI]].edges();
00092
00093 forAll (curFaceEdges, faceEdgeI)
00094 {
00095 const edge& curEdge = curFaceEdges[faceEdgeI];
00096
00097 forAll (cellEdges, cellEdgeI)
00098 {
00099 if (cellEdges[cellEdgeI] == curEdge)
00100 {
00101 edgeUsage[cellEdgeI]++;
00102 break;
00103 }
00104 }
00105 }
00106 }
00107
00108 edgeList singleEdges(cellEdges.size());
00109 label nSingleEdges = 0;
00110
00111 forAll (edgeUsage, edgeI)
00112 {
00113 if (edgeUsage[edgeI] == 1)
00114 {
00115 singleEdges[nSingleEdges] = cellEdges[edgeI];
00116 nSingleEdges++;
00117 }
00118 else if (edgeUsage[edgeI] != 2)
00119 {
00120 WarningIn("void polyMeshZipUpCells(polyMesh& mesh)")
00121 << "edge " << cellEdges[edgeI] << " in cell " << cellI
00122 << " used " << edgeUsage[edgeI] << " times. " << nl
00123 << "Should be 1 or 2 - serious error "
00124 << "in mesh structure. " << endl;
00125
00126 # ifdef DEBUG_ZIPUP
00127 forAll (curFaces, faceI)
00128 {
00129 Info<< "face: " << oldFaces[curFaces[faceI]]
00130 << endl;
00131 }
00132
00133 Info<< "Cell edges: " << cellEdges << nl
00134 << "Edge usage: " << edgeUsage << nl
00135 << "Cell points: " << cellPoints << endl;
00136
00137 forAll (cellPoints, cpI)
00138 {
00139 Info<< "vertex create \"" << cellPoints[cpI]
00140 << "\" coordinates "
00141 << Points[cellPoints[cpI]] << endl;
00142 }
00143 # endif
00144
00145
00146 problemCells.insert(cellI);
00147 }
00148 }
00149
00150
00151 if (nSingleEdges == 0) continue;
00152
00153 singleEdges.setSize(nSingleEdges);
00154
00155 # ifdef DEBUG_ZIPUP
00156 Info << "Cell " << cellI << endl;
00157
00158 forAll (curFaces, faceI)
00159 {
00160 Info<< "face: " << oldFaces[curFaces[faceI]] << endl;
00161 }
00162
00163 Info<< "Cell edges: " << cellEdges << nl
00164 << "Edge usage: " << edgeUsage << nl
00165 << "Single edges: " << singleEdges << nl
00166 << "Cell points: " << cellPoints << endl;
00167
00168 forAll (cellPoints, cpI)
00169 {
00170 Info<< "vertex create \"" << cellPoints[cpI]
00171 << "\" coordinates "
00172 << points()[cellPoints[cpI]] << endl;
00173 }
00174 # endif
00175
00176
00177
00178
00179
00180 labelList pointUsage(cellPoints.size(), 0);
00181
00182 forAll (singleEdges, edgeI)
00183 {
00184 const edge& curEdge = singleEdges[edgeI];
00185
00186 forAll (cellPoints, pointI)
00187 {
00188 if
00189 (
00190 cellPoints[pointI] == curEdge.start()
00191 || cellPoints[pointI] == curEdge.end()
00192 )
00193 {
00194 pointUsage[pointI]++;
00195 }
00196 }
00197 }
00198
00199 boolList singleEdgeUsage(singleEdges.size(), false);
00200
00201
00202
00203 forAll (singleEdges, edgeI)
00204 {
00205 bool blockedHead = false;
00206 bool blockedTail = false;
00207
00208 label newEdgeStart = singleEdges[edgeI].start();
00209 label newEdgeEnd = singleEdges[edgeI].end();
00210
00211
00212 forAll (cellPoints, pointI)
00213 {
00214 if (cellPoints[pointI] == newEdgeStart)
00215 {
00216 if (pointUsage[pointI] > 2)
00217 {
00218 blockedHead = true;
00219 }
00220 }
00221 else if (cellPoints[pointI] == newEdgeEnd)
00222 {
00223 if (pointUsage[pointI] > 2)
00224 {
00225 blockedTail = true;
00226 }
00227 }
00228 }
00229
00230 if (blockedHead && blockedTail)
00231 {
00232
00233 singleEdgeUsage[edgeI] = true;
00234 }
00235 }
00236
00237
00238
00239
00240
00241 labelListList edgesToInsert(singleEdges.size());
00242 label nEdgesToInsert = 0;
00243
00244
00245 forAll (singleEdges, edgeI)
00246 {
00247 SLList<label> pointChain;
00248
00249 bool blockHead = false;
00250 bool blockTail = false;
00251
00252 if (!singleEdgeUsage[edgeI])
00253 {
00254
00255 singleEdgeUsage[edgeI] = true;
00256
00257 label newEdgeStart = singleEdges[edgeI].start();
00258 label newEdgeEnd = singleEdges[edgeI].end();
00259
00260 pointChain.insert(newEdgeStart);
00261 pointChain.append(newEdgeEnd);
00262
00263 # ifdef DEBUG_CHAIN
00264 Info<< "found edge to start with: "
00265 << singleEdges[edgeI] << endl;
00266 # endif
00267
00268
00269 forAll (cellPoints, pointI)
00270 {
00271 if (cellPoints[pointI] == newEdgeStart)
00272 {
00273 if (pointUsage[pointI] > 2)
00274 {
00275 # ifdef DEBUG_CHAIN
00276 Info << "start head blocked" << endl;
00277 # endif
00278
00279 blockHead = true;
00280 }
00281 }
00282 else if(cellPoints[pointI] == newEdgeEnd)
00283 {
00284 if (pointUsage[pointI] > 2)
00285 {
00286 # ifdef DEBUG_CHAIN
00287 Info << "start tail blocked" << endl;
00288 # endif
00289
00290 blockTail = true;
00291 }
00292 }
00293 }
00294
00295 bool stopSearching = false;
00296
00297
00298 do
00299 {
00300 stopSearching = false;
00301
00302 forAll (singleEdges, addEdgeI)
00303 {
00304 if (!singleEdgeUsage[addEdgeI])
00305 {
00306
00307 label addStart =
00308 singleEdges[addEdgeI].start();
00309
00310 label addEnd =
00311 singleEdges[addEdgeI].end();
00312
00313 # ifdef DEBUG_CHAIN
00314 Info<< "Trying candidate "
00315 << singleEdges[addEdgeI] << endl;
00316 # endif
00317
00318
00319 if (!blockHead)
00320 {
00321 if (pointChain.first() == addStart)
00322 {
00323
00324 pointChain.insert(addEnd);
00325
00326 singleEdgeUsage[addEdgeI] = true;
00327 }
00328 else if (pointChain.first() == addEnd)
00329 {
00330 pointChain.insert(addStart);
00331
00332 singleEdgeUsage[addEdgeI] = true;
00333 }
00334 }
00335
00336
00337
00338 if (!blockTail && !singleEdgeUsage[addEdgeI])
00339 {
00340 if (pointChain.last() == addStart)
00341 {
00342
00343 pointChain.append(addEnd);
00344
00345 singleEdgeUsage[addEdgeI] = true;
00346 }
00347 else if (pointChain.last() == addEnd)
00348 {
00349 pointChain.append(addStart);
00350
00351 singleEdgeUsage[addEdgeI] = true;
00352 }
00353 }
00354
00355
00356 label curEdgeStart = pointChain.first();
00357 label curEdgeEnd = pointChain.last();
00358
00359 # ifdef DEBUG_CHAIN
00360 Info<< "curEdgeStart: " << curEdgeStart
00361 << " curEdgeEnd: " << curEdgeEnd << endl;
00362 # endif
00363
00364 forAll (cellPoints, pointI)
00365 {
00366 if (cellPoints[pointI] == curEdgeStart)
00367 {
00368 if (pointUsage[pointI] > 2)
00369 {
00370 # ifdef DEBUG_CHAIN
00371 Info << "head blocked" << endl;
00372 # endif
00373
00374 blockHead = true;
00375 }
00376 }
00377 else if(cellPoints[pointI] == curEdgeEnd)
00378 {
00379 if (pointUsage[pointI] > 2)
00380 {
00381 # ifdef DEBUG_CHAIN
00382 Info << "tail blocked" << endl;
00383 # endif
00384
00385 blockTail = true;
00386 }
00387 }
00388 }
00389
00390
00391 if (curEdgeStart == curEdgeEnd)
00392 {
00393 # ifdef DEBUG_CHAIN
00394 Info << "closed loop" << endl;
00395 # endif
00396
00397 pointChain.removeHead();
00398
00399 blockHead = true;
00400 blockTail = true;
00401
00402 stopSearching = true;
00403 }
00404
00405 # ifdef DEBUG_CHAIN
00406 Info<< "current pointChain: " << pointChain
00407 << endl;
00408 # endif
00409
00410 if (stopSearching) break;
00411 }
00412 }
00413 } while (stopSearching);
00414 }
00415
00416 # ifdef DEBUG_CHAIN
00417 Info << "completed patch chain: " << pointChain << endl;
00418 # endif
00419
00420 if (pointChain.size() > 2)
00421 {
00422 edgesToInsert[nEdgesToInsert] = pointChain;
00423 nEdgesToInsert++;
00424 }
00425 }
00426
00427 edgesToInsert.setSize(nEdgesToInsert);
00428
00429 # ifdef DEBUG_ZIPUP
00430 Info << "edgesToInsert: " << edgesToInsert << endl;
00431 # endif
00432
00433
00434 forAll (edgesToInsert, edgeToInsertI)
00435 {
00436
00437
00438
00439
00440
00441
00442 const labelList& unorderedEdge = edgesToInsert[edgeToInsertI];
00443
00444 scalarField dist(unorderedEdge.size());
00445
00446
00447 point startPoint = Points[unorderedEdge[0]];
00448 dist[0] = 0;
00449
00450 vector dir =
00451 Points[unorderedEdge[unorderedEdge.size() - 1]]
00452 - startPoint;
00453
00454 for (label i = 1; i < dist.size(); i++)
00455 {
00456 dist[i] = (Points[unorderedEdge[i]] - startPoint) & dir;
00457 }
00458
00459
00460 labelList orderedEdge(unorderedEdge.size(), -1);
00461 boolList used(unorderedEdge.size(), false);
00462
00463 forAll (orderedEdge, epI)
00464 {
00465 label nextPoint = -1;
00466 scalar minDist = GREAT;
00467
00468 forAll (dist, i)
00469 {
00470 if (!used[i] && dist[i] < minDist)
00471 {
00472 minDist = dist[i];
00473 nextPoint = i;
00474 }
00475 }
00476
00477
00478 orderedEdge[epI] = unorderedEdge[nextPoint];
00479 used[nextPoint] = true;
00480 }
00481
00482 # ifdef DEBUG_ORDER
00483 Info<< "unorderedEdge: " << unorderedEdge << nl
00484 << "orderedEdge: " << orderedEdge << endl;
00485 # endif
00486
00487
00488 forAll (orderedEdge, checkI)
00489 {
00490 for
00491 (
00492 label checkJ = checkI + 1;
00493 checkJ < orderedEdge.size();
00494 checkJ++
00495 )
00496 {
00497 if (orderedEdge[checkI] == orderedEdge[checkJ])
00498 {
00499 WarningIn("void polyMeshZipUpCells(polyMesh& mesh)")
00500 << "Duplicate point found in edge to insert. "
00501 << nl << "Point: " << orderedEdge[checkI]
00502 << " edge: " << orderedEdge << endl;
00503
00504 problemCells.insert(cellI);
00505 }
00506 }
00507 }
00508
00509 edge testEdge
00510 (
00511 orderedEdge[0],
00512 orderedEdge[orderedEdge.size() - 1]
00513 );
00514
00515
00516
00517 const labelList& startPF = pFaces[testEdge.start()];
00518 const labelList& endPF = pFaces[testEdge.start()];
00519
00520 labelList facesSharingEdge(startPF.size() + endPF.size());
00521 label nfse = 0;
00522
00523 forAll (startPF, pfI)
00524 {
00525 facesSharingEdge[nfse++] = startPF[pfI];
00526 }
00527 forAll (endPF, pfI)
00528 {
00529 facesSharingEdge[nfse++] = endPF[pfI];
00530 }
00531
00532 forAll (facesSharingEdge, faceI)
00533 {
00534 bool faceChanges = false;
00535
00536
00537 const label currentFaceIndex = facesSharingEdge[faceI];
00538
00539 const edgeList curFaceEdges =
00540 oldFaces[currentFaceIndex].edges();
00541
00542 forAll (curFaceEdges, cfeI)
00543 {
00544 if (curFaceEdges[cfeI] == testEdge)
00545 {
00546 faceChanges = true;
00547 break;
00548 }
00549 }
00550
00551 if (faceChanges)
00552 {
00553 nChangedFacesInMesh++;
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 face& newFace = newFaces[currentFaceIndex];
00567
00568 bool allPointsPresent = true;
00569
00570 forAll (orderedEdge, oeI)
00571 {
00572 bool curPointFound = false;
00573
00574 forAll (newFace, nfI)
00575 {
00576 if (newFace[nfI] == orderedEdge[oeI])
00577 {
00578 curPointFound = true;
00579 break;
00580 }
00581 }
00582
00583 allPointsPresent =
00584 allPointsPresent && curPointFound;
00585 }
00586
00587 # ifdef DEBUG_ZIPUP
00588 if (allPointsPresent)
00589 {
00590 Info << "All points present" << endl;
00591 }
00592 # endif
00593
00594 if (!allPointsPresent)
00595 {
00596
00597
00598
00599
00600
00601
00602
00603
00604 edgeList newFaceEdges = newFace.edges();
00605
00606 # ifdef DEBUG_ZIPUP
00607 Info << "Not all points present." << endl;
00608 # endif
00609
00610 label nNewFacePoints = 0;
00611
00612 bool edgeAdded = false;
00613
00614 forAll (newFaceEdges, curFacEdgI)
00615 {
00616
00617 if (newFaceEdges[curFacEdgI] == testEdge)
00618 {
00619
00620 edgeAdded = true;
00621
00622
00623
00624 newFace.setSize
00625 (
00626 newFace.size()
00627 + orderedEdge.size() - 2
00628 );
00629
00630 if
00631 (
00632 newFaceEdges[curFacEdgI].start()
00633 == testEdge.start()
00634 )
00635 {
00636
00637 for
00638 (
00639 label i = 0;
00640 i < orderedEdge.size() - 1;
00641 i++
00642 )
00643 {
00644 newFace[nNewFacePoints] =
00645 orderedEdge[i];
00646 nNewFacePoints++;
00647 }
00648 }
00649 else
00650 {
00651
00652 for
00653 (
00654 label i = orderedEdge.size() - 1;
00655 i > 0;
00656 i--
00657 )
00658 {
00659 newFace[nNewFacePoints] =
00660 orderedEdge[i];
00661 nNewFacePoints++;
00662 }
00663 }
00664 }
00665 else
00666 {
00667
00668
00669 newFace[nNewFacePoints] =
00670 newFaceEdges[curFacEdgI].start();
00671 nNewFacePoints++;
00672 }
00673 }
00674
00675 # ifdef DEBUG_ZIPUP
00676 Info<< "oldFace: "
00677 << oldFaces[currentFaceIndex] << nl
00678 << "newFace: " << newFace << endl;
00679 # endif
00680
00681
00682 forAll (newFace, checkI)
00683 {
00684 for
00685 (
00686 label checkJ = checkI + 1;
00687 checkJ < newFace.size();
00688 checkJ++
00689 )
00690 {
00691 if (newFace[checkI] == newFace[checkJ])
00692 {
00693 WarningIn("void polyMeshZipUpCells(polyMesh& mesh)")
00694 << "Duplicate point found "
00695 << "in the new face. " << nl
00696 << "Point: "
00697 << orderedEdge[checkI]
00698 << " face: "
00699 << newFace << endl;
00700
00701 problemCells.insert(cellI);
00702 }
00703 }
00704 }
00705
00706
00707
00708
00709
00710 if (!edgeAdded)
00711 {
00712 Info<< "This edge modifies an already modified "
00713 << "edge. Point insertions skipped."
00714 << endl;
00715 }
00716 }
00717 }
00718 }
00719 }
00720 }
00721
00722 if (problemCells.size())
00723 {
00724
00725 labelList toc(problemCells.toc());
00726 sort(toc);
00727
00728 FatalErrorIn("void polyMeshZipUpCells(polyMesh& mesh)")
00729 << "Found " << problemCells.size() << " problem cells." << nl
00730 << "Cells: " << toc
00731 << abort(FatalError);
00732 }
00733
00734 Info<< "Cycle " << ++nCycles
00735 << " changed " << nChangedFacesInMesh << " faces." << endl;
00736
00737
00738 const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
00739
00740
00741
00742
00743
00744
00745 labelList patchSizes(bMesh.size(), 0);
00746 labelList patchStarts(bMesh.size(), 0);
00747
00748 forAll (bMesh, patchI)
00749 {
00750 patchSizes[patchI] = bMesh[patchI].size();
00751 patchStarts[patchI] = bMesh[patchI].start();
00752 }
00753
00754
00755
00756 mesh.resetPrimitives
00757 (
00758 Xfer<pointField>::null(),
00759 xferMove(newFaces),
00760 Xfer<labelList>::null(),
00761 Xfer<labelList>::null(),
00762 patchSizes,
00763 patchStarts,
00764 true
00765 );
00766
00767
00768 mesh.faceZones().clearAddressing();
00769
00770
00771 mesh.clearOut();
00772
00773 } while (nChangedFacesInMesh > 0 || nCycles > 100);
00774
00775
00776 mesh.setInstance(mesh.time().timeName());
00777
00778 if (nChangedFacesInMesh > 0)
00779 {
00780 FatalErrorIn("void polyMeshZipUpCells(polyMesh& mesh)")
00781 << "cell zip-up failed after 100 cycles. Probable problem "
00782 << "with the original mesh"
00783 << abort(FatalError);
00784 }
00785
00786 return nCycles != 1;
00787 }
00788
00789
00790