FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

polyMeshZipUpCells.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "polyMeshZipUpCells.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <OpenFOAM/Time.H>
00029 
00030 // #define DEBUG_ZIPUP 1
00031 // #define DEBUG_CHAIN 1
00032 // #define DEBUG_ORDER 1
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     // Algorithm:
00045     // Take the original mesh and visit all cells.  For every cell
00046     // calculate the edges of all faces on the cells.  A cell is
00047     // correctly topologically closed when all the edges are referenced
00048     // by exactly two faces.  If the edges are referenced only by a
00049     // single face, additional vertices need to be inserted into some
00050     // of the faces (topological closedness).  If an edge is
00051     // referenced by more that two faces, there is an error in
00052     // topological closedness.
00053     // Point insertion into the faces is done by attempting to create
00054     // closed loops and inserting the intermediate points into the
00055     // defining edge
00056     // Note:
00057     // The algorithm is recursive and changes the mesh faces in each
00058     // pass.  It is therefore essential to discard the addressing
00059     // after every pass.  The algorithm is completed when the mesh
00060     // stops changing.
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             // Find the edges used only once in the cell
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                     // Gather the problem cell
00146                     problemCells.insert(cellI);
00147                 }
00148             }
00149 
00150             // Check if the cell is already zipped up
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             // Loop through all single edges and mark the points they use
00177             // points marked twice are internal to edge; those marked more than
00178             // twice are corners
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             // loop through all edges and eliminate the ones that are
00202             // blocked out
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                 // check that the edge has not got all ends blocked
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                     // Eliminating edge singleEdges[edgeI] as blocked
00233                     singleEdgeUsage[edgeI] = true;
00234                 }
00235             }
00236 
00237             // Go through the points and start from the point used twice
00238             // check all the edges to find the edges starting from this point
00239             // add the
00240 
00241             labelListList edgesToInsert(singleEdges.size());
00242             label nEdgesToInsert = 0;
00243 
00244             // Find a good edge
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                     // found a new edge
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                     // Check if head or tail are blocked
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                     // Go through the unused edges and try to chain them up
00298                     do
00299                     {
00300                         stopSearching = false;
00301 
00302                         forAll (singleEdges, addEdgeI)
00303                         {
00304                             if (!singleEdgeUsage[addEdgeI])
00305                             {
00306                                 // Grab start and end of the candidate
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                                 // Try to add the edge onto the head
00319                                 if (!blockHead)
00320                                 {
00321                                     if (pointChain.first() == addStart)
00322                                     {
00323                                         // Added at start mark as used
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                                 // Try the other end only if the first end
00337                                 // did not add it
00338                                 if (!blockTail && !singleEdgeUsage[addEdgeI])
00339                                 {
00340                                     if (pointChain.last() == addStart)
00341                                     {
00342                                         // Added at start mark as used
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                                 // check if the new head or tail are blocked
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                                 // Check if the loop is closed
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             // Insert the edges into a list of faces
00434             forAll (edgesToInsert, edgeToInsertI)
00435             {
00436                 // Order the points of the edge
00437                 // Warning: the ordering must be parametric, because in
00438                 // the case of multiple point insertion onto the same edge
00439                 // it is possible to get non-cyclic loops
00440                 //
00441 
00442                 const labelList& unorderedEdge = edgesToInsert[edgeToInsertI];
00443 
00444                 scalarField dist(unorderedEdge.size());
00445 
00446                 // Calculate distance
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                 // Sort points
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                     // Insert the next point
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                 // check for duplicate points in the ordered edge
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                 // In order to avoid edge-to-edge comparison, get faces using
00516                 // point-face addressing in two goes.
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                     // Label of the face being analysed
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                         // In order to avoid loosing point from multiple
00555                         // insertions into the same face, the new face
00556                         // will be change incrementally.
00557                         // 1) Check if all the internal points of the edge
00558                         // to add already exist in the face. If so, the
00559                         // edge has already been included 2) Check if the
00560                         // point insertion occurs on an edge which is
00561                         // still untouched. If so, simply insert
00562                         // additional points into the face.  3) If not,
00563                         // the edge insertion occurs on an already
00564                         // modified edge. ???
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                             // Not all points are already present.  The
00597                             // new edge will need to be inserted into the
00598                             // face.
00599 
00600                             // Check to see if a new edge fits onto an
00601                             // untouched edge of the face.  Make sure the
00602                             // edges are grabbed before the face is
00603                             // resized.
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                                 // Does the current edge change?
00617                                 if (newFaceEdges[curFacEdgI] == testEdge)
00618                                 {
00619                                     // Found an edge match
00620                                     edgeAdded = true;
00621 
00622                                     // Resize the face to accept additional
00623                                     // points
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                                         // insertion in ascending order
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                                         // insertion in reverse order
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                                     // Does not fit onto this edge.
00668                                     // Copy the next point into the face
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                             // Check for duplicate points in the new face
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                             // Check if the edge is added.
00707                             // If not, then it comes on top of an already
00708                             // modified edge and they need to be
00709                             // merged in together.
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             // This cycle has failed.  Print out the problem cells
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         // Reset the polyMesh. Number of points/faces/cells/patches stays the
00741         // same, only the faces themselves have changed so clear all derived
00742         // (edge, point) addressing.
00743 
00744         // Collect the patch sizes
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         // Reset the mesh. Number of active faces is one beyond the last patch
00755         // (patches guaranteed to be in increasing order)
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                // boundary forms valid boundary mesh.
00765         );
00766 
00767         // Reset any addressing on face zones.
00768         mesh.faceZones().clearAddressing();
00769 
00770         // Clear the addressing
00771         mesh.clearOut();
00772 
00773     } while (nChangedFacesInMesh > 0 || nCycles > 100);
00774 
00775     // Flags the mesh files as being changed
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 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines