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

removePoints.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 <OpenFOAM/BiIndirectList.H>
00027 #include "removePoints.H"
00028 #include <OpenFOAM/PstreamReduceOps.H>
00029 #include <OpenFOAM/polyMesh.H>
00030 #include "polyTopoChange.H"
00031 #include <dynamicMesh/polyRemovePoint.H>
00032 #include <dynamicMesh/polyAddPoint.H>
00033 #include <dynamicMesh/polyModifyFace.H>
00034 #include <OpenFOAM/syncTools.H>
00035 #include <meshTools/wallPoint.H>  // only to use 'greatPoint'
00036 #include <meshTools/faceSet.H>
00037 
00038 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00039 
00040 namespace Foam
00041 {
00042 
00043 defineTypeNameAndDebug(removePoints, 0);
00044 
00045 }
00046 
00047 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00048 
00049 // Change the vertices of the face whilst keeping everything else the same.
00050 void Foam::removePoints::modifyFace
00051 (
00052     const label faceI,
00053     const face& newFace,
00054     polyTopoChange& meshMod
00055 ) const
00056 {
00057     // Get other face data.
00058     label patchI = -1;
00059     label owner = mesh_.faceOwner()[faceI];
00060     label neighbour = -1;
00061 
00062     if (mesh_.isInternalFace(faceI))
00063     {
00064         neighbour = mesh_.faceNeighbour()[faceI];
00065     }
00066     else
00067     {
00068         patchI = mesh_.boundaryMesh().whichPatch(faceI);
00069     }
00070 
00071     label zoneID = mesh_.faceZones().whichZone(faceI);
00072 
00073     bool zoneFlip = false;
00074 
00075     if (zoneID >= 0)
00076     {
00077         const faceZone& fZone = mesh_.faceZones()[zoneID];
00078 
00079         zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
00080     }
00081 
00082     meshMod.setAction
00083     (
00084         polyModifyFace
00085         (
00086             newFace,        // modified face
00087             faceI,          // label of face being modified
00088             owner,          // owner
00089             neighbour,      // neighbour
00090             false,          // face flip
00091             patchI,         // patch for face
00092             false,          // remove from zone
00093             zoneID,         // zone for face
00094             zoneFlip        // face flip in zone
00095         )
00096     );
00097 }
00098 
00099 
00100 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00101 
00102 // Construct from mesh
00103 Foam::removePoints::removePoints
00104 (
00105     const polyMesh& mesh,
00106     const bool undoable
00107 )
00108 :
00109     mesh_(mesh),
00110     undoable_(undoable)
00111 {}
00112 
00113 
00114 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00115 
00116 Foam::label Foam::removePoints::countPointUsage
00117 (
00118     const scalar minCos,
00119     boolList& pointCanBeDeleted
00120 ) const
00121 {
00122     // Containers to store two edges per point:
00123     // -1   : not filled
00124     // >= 0 : edge label
00125     // -2   : more than two edges for point
00126     labelList edge0(mesh_.nPoints(), -1);
00127     labelList edge1(mesh_.nPoints(), -1);
00128 
00129     const edgeList& edges = mesh_.edges();
00130 
00131     forAll(edges, edgeI)
00132     {
00133         const edge& e = edges[edgeI];
00134 
00135         forAll(e, eI)
00136         {
00137             label pointI = e[eI];
00138 
00139             if (edge0[pointI] == -2)
00140             {
00141                 // Already too many edges
00142             }
00143             else if (edge0[pointI] == -1)
00144             {
00145                 // Store first edge using point
00146                 edge0[pointI] = edgeI;
00147             }
00148             else
00149             {
00150                 // Already one edge using point. Check second container.
00151 
00152                 if (edge1[pointI] == -1)
00153                 {
00154                     // Store second edge using point
00155                     edge1[pointI] = edgeI;
00156                 }
00157                 else
00158                 {
00159                     // Third edge using point. Mark.
00160                     edge0[pointI] = -2;
00161                     edge1[pointI] = -2;
00162                 }
00163             }
00164         }
00165     }
00166 
00167 
00168     // Check the ones used by only 2 edges that these are sufficiently in line.
00169     const pointField& points = mesh_.points();
00170 
00171     pointCanBeDeleted.setSize(mesh_.nPoints());
00172     pointCanBeDeleted = false;
00173     label nDeleted = 0;
00174 
00175     forAll(edge0, pointI)
00176     {
00177         if (edge0[pointI] >= 0 && edge1[pointI] >= 0)
00178         {
00179             // Point used by two edges exactly
00180 
00181             const edge& e0 = edges[edge0[pointI]];
00182             const edge& e1 = edges[edge1[pointI]];
00183 
00184             label common = e0.commonVertex(e1);
00185             label vLeft = e0.otherVertex(common);
00186             label vRight = e1.otherVertex(common);
00187 
00188             vector e0Vec = points[common] - points[vLeft];
00189             e0Vec /= mag(e0Vec) + VSMALL;
00190 
00191             vector e1Vec = points[vRight] - points[common];
00192             e1Vec /= mag(e1Vec) + VSMALL;
00193 
00194             if ((e0Vec & e1Vec) > minCos)
00195             {
00196                 pointCanBeDeleted[pointI] = true;
00197                 nDeleted++;
00198             }
00199         }
00200         else if (edge0[pointI] == -1)
00201         {
00202             // point not used at all
00203             pointCanBeDeleted[pointI] = true;
00204             nDeleted++;
00205         }
00206     }
00207     edge0.clear();
00208     edge1.clear();
00209 
00210 
00211     // Protect any points on faces that would collapse down to nothing
00212     // No particular intelligence so might protect too many points
00213     forAll(mesh_.faces(), faceI)
00214     {
00215         const face& f = mesh_.faces()[faceI];
00216 
00217         label nCollapse = 0;
00218         forAll(f, fp)
00219         {
00220             if (pointCanBeDeleted[f[fp]])
00221             {
00222                 nCollapse++;
00223             }
00224         }
00225 
00226         if ((f.size() - nCollapse) < 3)
00227         {
00228             // Just unmark enough points
00229             forAll(f, fp)
00230             {
00231                 if (pointCanBeDeleted[f[fp]])
00232                 {
00233                     pointCanBeDeleted[f[fp]] = false;
00234                     --nCollapse;
00235                     if (nCollapse == 0)
00236                     {
00237                         break;
00238                     }
00239                 }
00240             }
00241         }
00242     }
00243 
00244 
00245     // Point can be deleted only if all processors want to delete it
00246     syncTools::syncPointList
00247     (
00248         mesh_,
00249         pointCanBeDeleted,
00250         andEqOp<bool>(),
00251         true,               // null value
00252         false               // no separation
00253     );
00254 
00255     return returnReduce(nDeleted, sumOp<label>());
00256 }
00257 
00258 
00259 void Foam::removePoints::setRefinement
00260 (
00261     const boolList& pointCanBeDeleted,
00262     polyTopoChange& meshMod
00263 )
00264 {
00265     // Count deleted points
00266     label nDeleted = 0;
00267     forAll(pointCanBeDeleted, pointI)
00268     {
00269         if (pointCanBeDeleted[pointI])
00270         {
00271             nDeleted++;
00272         }
00273     }
00274 
00275     // Faces (in mesh face labels) affected by points removed. Will hopefully
00276     // be only a few.
00277     labelHashSet facesAffected(4*nDeleted);
00278 
00279 
00280     // Undo: from global mesh point to index in savedPoint_
00281     Map<label> pointToSaved;
00282 
00283     // Size undo storage
00284     if (undoable_)
00285     {
00286         savedPoints_.setSize(nDeleted);
00287         pointToSaved.resize(2*nDeleted);
00288     }
00289     
00290 
00291     // Remove points
00292     // ~~~~~~~~~~~~~
00293 
00294     nDeleted = 0;
00295 
00296     forAll(pointCanBeDeleted, pointI)
00297     {
00298         if (pointCanBeDeleted[pointI])
00299         {
00300             if (undoable_)
00301             {
00302                 pointToSaved.insert(pointI, nDeleted);
00303                 savedPoints_[nDeleted++] = mesh_.points()[pointI];
00304             }
00305             meshMod.setAction(polyRemovePoint(pointI));
00306 
00307             // Store faces affected
00308             const labelList& pFaces = mesh_.pointFaces()[pointI];
00309 
00310             forAll(pFaces, i)
00311             {
00312                 facesAffected.insert(pFaces[i]);
00313             }
00314         }
00315     }
00316 
00317 
00318 
00319     // Update faces
00320     // ~~~~~~~~~~~~
00321 
00322 
00323     if (undoable_)
00324     {
00325         savedFaceLabels_.setSize(facesAffected.size());
00326         savedFaces_.setSize(facesAffected.size());
00327     }
00328     label nSaved = 0;
00329 
00330     forAllConstIter(labelHashSet, facesAffected, iter)
00331     {
00332         label faceI = iter.key();
00333 
00334         const face& f = mesh_.faces()[faceI];
00335 
00336         face newFace(f.size());
00337 
00338         label newI = 0;
00339 
00340         forAll(f, fp)
00341         {
00342             label pointI = f[fp];
00343 
00344             if (!pointCanBeDeleted[pointI])
00345             {
00346                 newFace[newI++] = pointI;
00347             }
00348         }
00349         newFace.setSize(newI);
00350 
00351         // Actually change the face to the new vertices
00352         modifyFace(faceI, newFace, meshMod);
00353 
00354         // Save the face. Negative indices are into savedPoints_
00355         if (undoable_)
00356         {
00357             savedFaceLabels_[nSaved] = faceI;
00358 
00359             face& savedFace = savedFaces_[nSaved++];
00360             savedFace.setSize(f.size());
00361 
00362             forAll(f, fp)
00363             {
00364                 label pointI = f[fp];
00365 
00366                 if (pointCanBeDeleted[pointI])
00367                 {
00368                     savedFace[fp] = -pointToSaved[pointI]-1;
00369                 }
00370                 else
00371                 {
00372                     savedFace[fp] = pointI;
00373                 }
00374             }
00375         }
00376     }
00377 
00378     if (undoable_)
00379     {
00380         // DEBUG: Compare the stored faces with the current ones.
00381         if (debug)
00382         {
00383             forAll(savedFaceLabels_, saveI)
00384             {
00385                 // Points from the mesh
00386                 List<point> meshPoints
00387                 (
00388                     UIndirectList<point>
00389                     (
00390                         mesh_.points(),
00391                         mesh_.faces()[savedFaceLabels_[saveI]]  // mesh face
00392                     )
00393                 );
00394 
00395                 // Points from the saved face
00396                 List<point> keptPoints
00397                 (
00398                     BiIndirectList<point>
00399                     (
00400                         mesh_.points(),
00401                         savedPoints_,
00402                         savedFaces_[saveI]  // saved face
00403                     )
00404                 );
00405 
00406                 if (meshPoints != keptPoints)
00407                 {
00408                     FatalErrorIn("setRefinement")
00409                         << "faceI:" << savedFaceLabels_[saveI] << nl
00410                         << "meshPoints:" << meshPoints << nl
00411                         << "keptPoints:" << keptPoints << nl
00412                         << abort(FatalError);
00413                 }
00414             }
00415         }
00416     }
00417 }
00418 
00419 
00420 void Foam::removePoints::updateMesh(const mapPolyMesh& map)
00421 {
00422     if (undoable_)
00423     {
00424         forAll(savedFaceLabels_, localI)
00425         {
00426             if (savedFaceLabels_[localI] >= 0)
00427             {
00428                 label newFaceI = map.reverseFaceMap()[savedFaceLabels_[localI]];
00429 
00430                 if (newFaceI == -1)
00431                 {
00432                     FatalErrorIn
00433                     (
00434                         "removePoints::updateMesh(const mapPolyMesh&)"
00435                     )   << "Old face " << savedFaceLabels_[localI]
00436                         << " seems to have dissapeared."
00437                         << abort(FatalError);
00438                 }
00439                 savedFaceLabels_[localI] = newFaceI;
00440             }
00441         }
00442 
00443 
00444         // Renumber mesh vertices (indices >=0). Leave saved vertices
00445         // (<0) intact.
00446         forAll(savedFaces_, i)
00447         {
00448             face& f = savedFaces_[i];
00449 
00450             forAll(f, fp)
00451             {
00452                 label pointI = f[fp];
00453 
00454                 if (pointI >= 0)
00455                 {
00456                     f[fp] = map.reversePointMap()[pointI];
00457 
00458                     if (f[fp] == -1)
00459                     {
00460                         FatalErrorIn
00461                         (
00462                             "removePoints::updateMesh(const mapPolyMesh&)"
00463                         )   << "Old point " << pointI
00464                             << " seems to have dissapeared."
00465                             << abort(FatalError);
00466                     }
00467                 }
00468             }
00469         }
00470 
00471 
00472         // DEBUG: Compare the stored faces with the current ones.
00473         if (debug)
00474         {
00475             forAll(savedFaceLabels_, saveI)
00476             {
00477                 if (savedFaceLabels_[saveI] >= 0)
00478                 {
00479                     const face& f = mesh_.faces()[savedFaceLabels_[saveI]];
00480 
00481                     // Get kept points of saved faces.
00482                     const face& savedFace = savedFaces_[saveI];
00483 
00484                     face keptFace(savedFace.size());
00485                     label keptFp = 0;
00486 
00487                     forAll(savedFace, fp)
00488                     {
00489                         label pointI = savedFace[fp];
00490 
00491                         if (pointI >= 0)
00492                         {
00493                             keptFace[keptFp++] = pointI;
00494                         }
00495                     }
00496                     keptFace.setSize(keptFp);
00497 
00498                     // Compare as faces (since f might have rotated and
00499                     // face::operator== takes care of this)
00500                     if (keptFace != f)
00501                     {
00502                         FatalErrorIn("setRefinement")
00503                             << "faceI:" << savedFaceLabels_[saveI] << nl
00504                             << "face:" << f << nl
00505                             << "keptFace:" << keptFace << nl
00506                             << "saved points:"
00507                             <<  BiIndirectList<point>
00508                                 (
00509                                     mesh_.points(),
00510                                     savedPoints_,
00511                                     savedFace
00512                                 )() << nl
00513                             << abort(FatalError);
00514                     }
00515                 }
00516             }
00517         }
00518     }
00519 }
00520 
00521 
00522 // Given list of faces to undo picks up the local indices of the faces
00523 // to restore. Additionally it also picks up all the faces that use
00524 // any of the deleted points.
00525 void Foam::removePoints::getUnrefimentSet
00526 (
00527     const labelList& undoFaces,
00528     labelList& localFaces,
00529     labelList& localPoints
00530 ) const
00531 {
00532     if (!undoable_)
00533     {
00534         FatalErrorIn
00535         (
00536             "removePoints::getUnrefimentSet(const labelList&"
00537             ", labelList&, labelList&) const"
00538         )   << "removePoints not constructed with"
00539             << " unrefinement capability."
00540             << abort(FatalError);
00541     }
00542 
00543     if (debug)
00544     {
00545         // Check if synced.
00546         faceSet undoFacesSet(mesh_, "undoFacesSet", undoFaces);
00547         label sz = undoFacesSet.size();
00548 
00549         undoFacesSet.sync(mesh_);
00550         if (sz != undoFacesSet.size())
00551         {
00552             FatalErrorIn
00553             (
00554                 "removePoints::getUnrefimentSet(const labelList&"
00555                 ", labelList&, labelList&) const"
00556             )   << "undoFaces not synchronised across coupled faces." << endl
00557                 << "Size before sync:" << sz
00558                 << "  after sync:" << undoFacesSet.size()
00559                 << abort(FatalError);
00560         }
00561     }
00562 
00563 
00564     // Problem: input undoFaces are synced. But e.g.
00565     // two faces, A (uncoupled) and B(coupled) share a deleted point. A gets
00566     // passed in to be restored. Now picking up the deleted point and the
00567     // original faces using it picks up face B. But not its coupled neighbour!
00568     // Problem is that we cannot easily synchronise the deleted points
00569     // (e.g. syncPointList) since they're not in the mesh anymore - only the
00570     // faces are. So we have to collect the points-to-restore as indices
00571     // in the faces (which is information we can synchronise)
00572 
00573 
00574 
00575     // Mark points-to-restore
00576     labelHashSet localPointsSet(undoFaces.size());
00577 
00578     {
00579         // Create set of faces to be restored
00580         labelHashSet undoFacesSet(undoFaces);
00581 
00582         forAll(savedFaceLabels_, saveI)
00583         {
00584             if (savedFaceLabels_[saveI] < 0)
00585             {
00586                 FatalErrorIn
00587                 (
00588                     "removePoints::getUnrefimentSet(const labelList&"
00589                     ", labelList&, labelList&) const"
00590                 )   << "Illegal face label " << savedFaceLabels_[saveI]
00591                     << " at index " << saveI
00592                     << abort(FatalError);
00593             }
00594 
00595             if (undoFacesSet.found(savedFaceLabels_[saveI]))
00596             {
00597                 const face& savedFace = savedFaces_[saveI];
00598 
00599                 forAll(savedFace, fp)
00600                 {
00601                     if (savedFace[fp] < 0)
00602                     {
00603                         label savedPointI = -savedFace[fp]-1;
00604 
00605                         if (savedPoints_[savedPointI] == wallPoint::greatPoint)
00606                         {
00607                             FatalErrorIn
00608                             (
00609                                 "removePoints::getUnrefimentSet"
00610                                 "(const labelList&, labelList&, labelList&)"
00611                                 " const"
00612                             )   << "Trying to restore point " << savedPointI
00613                                 << " from mesh face " << savedFaceLabels_[saveI]
00614                                 << " saved face:" << savedFace
00615                                 << " which has already been undone."
00616                                 << abort(FatalError);
00617                         }
00618 
00619                         localPointsSet.insert(savedPointI);
00620                     }
00621                 }
00622             }
00623         }
00624 
00625 
00626         // Per boundary face, per index in face whether the point needs
00627         // restoring. Note that this is over all saved faces, not just over
00628         // the ones in undoFaces.
00629 
00630         boolListList faceVertexRestore(mesh_.nFaces()-mesh_.nInternalFaces());
00631 
00632         // Populate with my local points-to-restore.
00633         forAll(savedFaces_, saveI)
00634         {
00635             label bFaceI = savedFaceLabels_[saveI] - mesh_.nInternalFaces();
00636 
00637             if (bFaceI >= 0)
00638             {
00639                 const face& savedFace = savedFaces_[saveI];
00640 
00641                 boolList& fRestore = faceVertexRestore[bFaceI];
00642 
00643                 fRestore.setSize(savedFace.size());
00644                 fRestore = false;
00645 
00646                 forAll(savedFace, fp)
00647                 {
00648                     if (savedFace[fp] < 0)
00649                     {
00650                         label savedPointI = -savedFace[fp]-1;
00651 
00652                         if (localPointsSet.found(savedPointI))
00653                         {
00654                             fRestore[fp] = true;
00655                         }
00656                     }
00657                 }
00658             }
00659         }
00660 
00661         syncTools::syncBoundaryFaceList
00662         (
00663             mesh_,
00664             faceVertexRestore,
00665             faceEqOp<bool, orEqOp>(),   // special operator to handle faces
00666             false                       // no separation
00667         );
00668 
00669         // So now if any of the points-to-restore is used by any coupled face
00670         // anywhere the corresponding index in faceVertexRestore will be set.
00671 
00672         // Now combine the localPointSet and the (sychronised)
00673         // boundary-points-to-restore.
00674 
00675         forAll(savedFaces_, saveI)
00676         {
00677             label bFaceI = savedFaceLabels_[saveI] - mesh_.nInternalFaces();
00678 
00679             if (bFaceI >= 0)
00680             {
00681                 const boolList& fRestore = faceVertexRestore[bFaceI];
00682 
00683                 const face& savedFace = savedFaces_[saveI];
00684 
00685                 forAll(fRestore, fp)
00686                 {
00687                     // Does neighbour require point restored?
00688                     if (fRestore[fp])
00689                     {
00690                         if (savedFace[fp] >= 0)
00691                         {
00692                             FatalErrorIn
00693                             (
00694                                 "removePoints::getUnrefimentSet"
00695                                 "(const labelList&, labelList&, labelList&)"
00696                                 " const"
00697                             )   << "Problem: on coupled face:"
00698                                 << savedFaceLabels_[saveI]
00699                                 << " fc:"
00700                                 << mesh_.faceCentres()[savedFaceLabels_[saveI]]
00701                                 << endl
00702                                 << " my neighbour tries to restore the vertex"
00703                                 << " at index " << fp
00704                                 << " whereas my saved face:" << savedFace
00705                                 << " does not indicate a deleted vertex"
00706                                 << " at that position."
00707                                 << abort(FatalError);
00708                         }
00709 
00710                         label savedPointI = -savedFace[fp]-1;
00711 
00712                         localPointsSet.insert(savedPointI);
00713                     }
00714                 }
00715             }
00716         }
00717     }
00718 
00719     localPoints = localPointsSet.toc();
00720 
00721 
00722     // Collect all saved faces using any localPointsSet 
00723     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00724 
00725     labelHashSet localFacesSet(2*undoFaces.size());
00726 
00727     forAll(savedFaces_, saveI)
00728     {
00729         const face& savedFace = savedFaces_[saveI];
00730 
00731         forAll(savedFace, fp)
00732         {
00733             if (savedFace[fp] < 0)
00734             {
00735                 label savedPointI = -savedFace[fp]-1;
00736 
00737                 if (localPointsSet.found(savedPointI))
00738                 {
00739                     localFacesSet.insert(saveI);
00740                 }
00741             }
00742         }
00743     }
00744     localFaces = localFacesSet.toc();
00745 
00746 
00747     // Note that at this point the localFaces to restore can contain points
00748     // that are not going to be restored! The localFaces though will
00749     // be guaranteed to be all the ones affected by the restoration of the
00750     // localPoints.
00751 }
00752 
00753 
00754 void Foam::removePoints::setUnrefinement
00755 (
00756     const labelList& localFaces,
00757     const labelList& localPoints,
00758     polyTopoChange& meshMod
00759 )
00760 {
00761     if (!undoable_)
00762     {
00763         FatalErrorIn
00764         (
00765             "removePoints::setUnrefinement(const labelList&"
00766             ", labelList&, polyTopoChange&)"
00767         )   << "removePoints not constructed with"
00768             << " unrefinement capability."
00769             << abort(FatalError);
00770     }
00771 
00772 
00773     // Per savedPoint -1 or the restored point label
00774     labelList addedPoints(savedPoints_.size(), -1);
00775 
00776     forAll(localPoints, i)
00777     {
00778         label localI = localPoints[i];
00779 
00780         if (savedPoints_[localI] == wallPoint::greatPoint)
00781         {
00782             FatalErrorIn
00783             (
00784                 "removePoints::setUnrefinement(const labelList&"
00785                 ", labelList&, polyTopoChange&)"
00786             )   << "Saved point " << localI << " already restored!"
00787                 << abort(FatalError);
00788         }
00789 
00790         addedPoints[localI] = meshMod.setAction
00791         (
00792             polyAddPoint
00793             (
00794                 savedPoints_[localI],   // point
00795                 -1,                     // master point
00796                 -1,                     // zone for point
00797                 true                    // supports a cell
00798             )
00799         );
00800 
00801         // Mark the restored points so they are not restored again.
00802         savedPoints_[localI] = wallPoint::greatPoint;
00803     }
00804 
00805     forAll(localFaces, i)
00806     {
00807         label saveI = localFaces[i];
00808 
00809         // Modify indices into saved points (so < 0) to point to the
00810         // added points.
00811         face& savedFace = savedFaces_[saveI];
00812 
00813         face newFace(savedFace.size());
00814         label newFp = 0;
00815 
00816         bool hasSavedPoints = false;
00817 
00818         forAll(savedFace, fp)
00819         {
00820             if (savedFace[fp] < 0)
00821             {
00822                 label addedPointI = addedPoints[-savedFace[fp]-1];
00823 
00824                 if (addedPointI != -1)
00825                 {
00826                     savedFace[fp] = addedPointI;
00827                     newFace[newFp++] = addedPointI;
00828                 }
00829                 else
00830                 {
00831                     hasSavedPoints = true;
00832                 }
00833             }
00834             else
00835             {
00836                 newFace[newFp++] = savedFace[fp];
00837             }
00838         }
00839         newFace.setSize(newFp);
00840 
00841         modifyFace(savedFaceLabels_[saveI], newFace, meshMod);
00842 
00843         if (!hasSavedPoints)
00844         {
00845             // Face fully restored. Mark for compaction later on
00846             savedFaceLabels_[saveI] = -1;
00847             savedFaces_[saveI].clear();
00848         }
00849     }
00850 
00851 
00852     // Compact face labels
00853     label newSaveI = 0;
00854 
00855     forAll(savedFaceLabels_, saveI)
00856     {
00857         if (savedFaceLabels_[saveI] != -1)
00858         {
00859             if (newSaveI != saveI)
00860             {
00861                 savedFaceLabels_[newSaveI] = savedFaceLabels_[saveI];
00862                 savedFaces_[newSaveI].transfer(savedFaces_[saveI]);
00863             }
00864             newSaveI++;
00865         }
00866     }
00867 
00868     savedFaceLabels_.setSize(newSaveI);
00869     savedFaces_.setSize(newSaveI);
00870 
00871 
00872     // Check that all faces have been restored that use any restored points
00873     if (debug)
00874     {
00875         forAll(savedFaceLabels_, saveI)
00876         {
00877             const face& savedFace = savedFaces_[saveI];
00878 
00879             forAll(savedFace, fp)
00880             {
00881                 if (savedFace[fp] < 0)
00882                 {
00883                     label addedPointI = addedPoints[-savedFace[fp]-1];
00884 
00885                     if (addedPointI != -1)
00886                     {
00887                         FatalErrorIn("setUnrefinement")
00888                             << "Face:" << savedFaceLabels_[saveI]
00889                             << " savedVerts:" << savedFace
00890                             << " uses restored point:" << -savedFace[fp]-1
00891                             << " with new pointlabel:" << addedPointI
00892                             << abort(FatalError);
00893                     }
00894                 }
00895             }
00896         }
00897     }
00898 }
00899 
00900 
00901 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines