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

removeCellLayer.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 Description
00025     Remove a layer of cells and prepare addressing data
00026 
00027 \*---------------------------------------------------------------------------*/
00028 
00029 #include "layerAdditionRemoval.H"
00030 #include <OpenFOAM/polyMesh.H>
00031 #include <OpenFOAM/primitiveMesh.H>
00032 #include <dynamicMesh/polyTopoChange.H>
00033 #include <OpenFOAM/oppositeFace.H>
00034 #include <dynamicMesh/polyTopoChanger.H>
00035 #include <dynamicMesh/polyRemoveCell.H>
00036 #include <dynamicMesh/polyRemoveFace.H>
00037 #include <dynamicMesh/polyRemovePoint.H>
00038 #include <dynamicMesh/polyModifyFace.H>
00039 
00040 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00041 
00042 bool Foam::layerAdditionRemoval::validCollapse() const
00043 {
00044     // Check for valid layer collapse
00045     // - no boundary-to-boundary collapse
00046 
00047     if (debug)
00048     {
00049         Pout << "Checking layer collapse for object " << name() << endl;
00050     }
00051 
00052     // Grab the face collapse mapping
00053     const polyMesh& mesh = topoChanger().mesh();
00054 
00055     const labelList& ftc = facesPairing();
00056     const labelList& mf = mesh.faceZones()[faceZoneID_.index()];
00057 
00058     label nBoundaryHits = 0;
00059 
00060     forAll (mf, faceI)
00061     {
00062         if
00063         (
00064             !mesh.isInternalFace(mf[faceI])
00065          && !mesh.isInternalFace(ftc[faceI])
00066         )
00067         {
00068             nBoundaryHits++;
00069         }
00070     }
00071 
00072 
00073     if (debug)
00074     {
00075         Pout<< "Finished checking layer collapse for object "
00076             << name() <<".  Number of boundary-on-boundary hits: "
00077             << nBoundaryHits << endl;
00078     }
00079 
00080     if (returnReduce(nBoundaryHits, sumOp<label>()) > 0)
00081     {
00082         return false;
00083     }
00084     else
00085     {
00086         return true;
00087     }
00088 }
00089 
00090 void Foam::layerAdditionRemoval::removeCellLayer
00091 (
00092     polyTopoChange& ref
00093 ) const
00094 {
00095     // Algorithm for layer removal.  Second phase: topological change
00096     // 2)  Go through all the faces of the master cell layer and remove
00097     //     the ones that are not in the master face zone.
00098     //
00099     // 3)  Grab all the faces coming out of points that are collapsed
00100     //     and select the ones that are not marked for removal.  Go
00101     //     through the remaining faces and replace the point to remove by
00102     //     the equivalent point in the master face zone.
00103     if (debug)
00104     {
00105         Pout << "Removing the cell layer for object " << name() << endl;
00106     }
00107 
00108     const polyMesh& mesh = topoChanger().mesh();
00109 
00110     const labelList& ptc = pointsPairing();
00111     const labelList& ftc = facesPairing();
00112 
00113     // Remove all the cells from the master layer
00114     const labelList& mc =
00115         topoChanger().mesh().faceZones()[faceZoneID_.index()].masterCells();
00116 
00117     forAll (mc, cellI)
00118     {
00119         ref.setAction(polyRemoveCell(mc[cellI]));
00120     }
00121 
00122     // Remove all the faces from the master layer cells which are not in
00123     // the master face layer
00124     labelHashSet facesToRemoveMap(mc.size()*primitiveMesh::facesPerCell_);
00125 
00126     const cellList& cells = mesh.cells();
00127 
00128     forAll (mc, cellI)
00129     {
00130         const cell& curCell = cells[mc[cellI]];
00131 
00132         forAll (curCell, faceI)
00133         {
00134             // Check if the face is in the master zone.  If not, remove it
00135             if
00136             (
00137                 mesh.faceZones().whichZone(curCell[faceI])
00138              != faceZoneID_.index()
00139             )
00140             {
00141                 facesToRemoveMap.insert(curCell[faceI]);
00142             }
00143         }
00144     }
00145 
00146     forAllConstIter(labelHashSet, facesToRemoveMap, iter)
00147     {
00148         ref.setAction(polyRemoveFace(iter.key()));
00149     }
00150 
00151     // Remove all points that will be collapsed
00152     forAll (ptc, pointI)
00153     {
00154         ref.setAction(polyRemovePoint(ptc[pointI]));
00155     }
00156 
00157     // Grab all faces coming off points to be deleted.  If the face
00158     // has not been deleted, replace the removed point with the
00159     // equivalent from the master layer.
00160 
00161     // Make a map of all point to be removed, giving the master point label
00162     // for each of them
00163 
00164     Map<label> removedPointMap(2*ptc.size());
00165 
00166     const labelList& meshPoints =
00167         mesh.faceZones()[faceZoneID_.index()]().meshPoints();
00168 
00169     forAll (ptc, pointI)
00170     {
00171         removedPointMap.insert(ptc[pointI], meshPoints[pointI]);
00172     }
00173 
00174     const labelListList& pf = mesh.pointFaces();
00175 
00176     const faceList& faces = mesh.faces();
00177     const labelList& own = mesh.faceOwner();
00178     const labelList& nei = mesh.faceNeighbour();
00179 
00180     // Make a list of faces to be modified using the map to avoid duplicates
00181     labelHashSet facesToModify(ptc.size()*primitiveMesh::facesPerPoint_);
00182 
00183     forAll (ptc, pointI)
00184     {
00185         const labelList& curFaces = pf[ptc[pointI]];
00186 
00187         forAll (curFaces, faceI)
00188         {
00189             if (!facesToRemoveMap.found(curFaces[faceI]))
00190             {
00191                 facesToModify.insert(curFaces[faceI]);
00192             }
00193         }
00194     }
00195 
00196     labelList ftm = facesToModify.toc();
00197 
00198 //Pout << "faces to modify: " << ftm << endl;
00199 
00200     forAll (ftm, faceI)
00201     {
00202         // For every face to modify, copy the face and re-map the vertices.
00203         // It is known all the faces will be changed since they hang off
00204         // re-mapped vertices
00205         label curFaceID = ftm[faceI];
00206 
00207         face newFace(faces[curFaceID]);
00208 
00209         forAll (newFace, pointI)
00210         {
00211             Map<label>::iterator rpmIter =
00212                 removedPointMap.find(newFace[pointI]);
00213 
00214             if (rpmIter != removedPointMap.end())
00215             {
00216                 // Point mapped. Replace it
00217                 newFace[pointI] = rpmIter();
00218             }
00219         }
00220 
00221 //Pout<< "face label: " << curFaceID
00222 //    << " old face: " << faces[curFaceID]
00223 //    << " new face: " << newFace << endl;
00224 
00225         // Get face zone and its flip
00226         label modifiedFaceZone = mesh.faceZones().whichZone(curFaceID);
00227         bool modifiedFaceZoneFlip = false;
00228 
00229         if (modifiedFaceZone >= 0)
00230         {
00231             modifiedFaceZoneFlip =
00232                 mesh.faceZones()[modifiedFaceZone].flipMap()
00233                 [
00234                     mesh.faceZones()[modifiedFaceZone].whichFace(curFaceID)
00235                 ];
00236         }
00237         
00238         label newNei;
00239         
00240         if (curFaceID < mesh.nInternalFaces())
00241         {
00242             newNei = nei[curFaceID];
00243         }
00244         else
00245         {
00246             newNei = -1;
00247         }
00248 
00249         // Modify the face
00250         ref.setAction
00251         (
00252             polyModifyFace
00253             (
00254                 newFace,                // modified face
00255                 curFaceID,              // label of face being modified
00256                 own[curFaceID],         // owner
00257                 newNei,                 // neighbour
00258                 false,                  // face flip
00259                 mesh.boundaryMesh().whichPatch(curFaceID),// patch for face
00260                 false,                  // remove from zone
00261                 modifiedFaceZone,       // zone for face
00262                 modifiedFaceZoneFlip    // face flip in zone
00263             )
00264         );
00265     }
00266 
00267     // Modify the faces in the master layer to point past the removed cells
00268 
00269     const labelList& mf = mesh.faceZones()[faceZoneID_.index()];
00270     const boolList& mfFlip = mesh.faceZones()[faceZoneID_.index()].flipMap();
00271 
00272     forAll (mf, faceI)
00273     {
00274         // Grab the owner and neighbour of the faces to be collapsed and get rid
00275         // of the cell to be removed
00276         label masterSideCell = own[mf[faceI]];
00277 
00278         if (masterSideCell == mc[faceI])
00279         {
00280             // Owner cell of the face is being removed.
00281             // Grab the neighbour instead
00282             masterSideCell = nei[mf[faceI]];
00283         }
00284 
00285         label slaveSideCell = own[ftc[faceI]];
00286 
00287         if (slaveSideCell == mc[faceI])
00288         {
00289             // Owner cell of the face is being removed.
00290             // Grab the neighbour instead
00291             slaveSideCell = nei[ftc[faceI]];
00292         }
00293 
00294         // Find out if the face needs to be flipped
00295         label newOwner = -1;
00296         label newNeighbour = -1;
00297         bool flipFace = false;
00298         label newPatchID = -1;
00299         label newZoneID = -1;
00300 
00301         // Is any of the faces a boundary face?  If so, grab the patch
00302         // A boundary-to-boundary collapse is checked for in validCollapse()
00303         // and cannot happen here.  
00304 
00305         if (!mesh.isInternalFace(mf[faceI]))
00306         {
00307             // Master is the boundary face: it gets a new owner but no flip
00308             newOwner = slaveSideCell;
00309             newNeighbour = -1;
00310             flipFace = false;
00311             newPatchID = mesh.boundaryMesh().whichPatch(mf[faceI]);
00312             newZoneID = mesh.faceZones().whichZone(mf[faceI]);
00313         }
00314         else if (!mesh.isInternalFace(ftc[faceI]))
00315         {
00316             // Slave is the boundary face: grab its patch
00317             newOwner = slaveSideCell;
00318             newNeighbour = -1;
00319 
00320             // Find out if the face flip is necessary
00321             if (own[mf[faceI]] == slaveSideCell)
00322             {
00323                 flipFace = false;
00324             }
00325             else
00326             {
00327                 flipFace = true;
00328             }
00329 
00330             newPatchID = mesh.boundaryMesh().whichPatch(ftc[faceI]);
00331 
00332             // The zone of the master face is preserved
00333             newZoneID = mesh.faceZones().whichZone(mf[faceI]);
00334         }
00335         else
00336         {
00337             // Both faces are internal: flip is decided based on which of the
00338             // new cells around it has a lower label
00339             newOwner = min(masterSideCell, slaveSideCell);
00340             newNeighbour = max(masterSideCell, slaveSideCell);
00341 
00342             if (newOwner == own[mf[faceI]] || newNeighbour == nei[mf[faceI]])
00343             {
00344                 flipFace = false;
00345             }
00346             else
00347             {
00348                 flipFace = true;
00349             }
00350 
00351             newPatchID = -1;
00352 
00353             // The zone of the master face is preserved
00354             newZoneID = mesh.faceZones().whichZone(mf[faceI]);
00355         }
00356 
00357         // Modify the face and flip if necessary
00358         face newFace = faces[mf[faceI]];
00359         bool zoneFlip = mfFlip[faceI];
00360 
00361         if (flipFace)
00362         {
00363             newFace = newFace.reverseFace();
00364             zoneFlip = !zoneFlip;
00365         }
00366 
00367 // Pout<< "Modifying face " << mf[faceI]
00368 //     << " newFace: " << newFace << nl
00369 //     << " newOwner: " << newOwner
00370 //     << " newNeighbour: " << newNeighbour
00371 //     << " flipFace: " << flipFace
00372 //     << " newPatchID: " << newPatchID
00373 //     << " newZoneID: " << newZoneID << nl
00374 //     << " oldOwn: " << own[mf[faceI]]
00375 //     << " oldNei: " << nei[mf[faceI]] << endl;
00376 
00377         ref.setAction
00378         (
00379             polyModifyFace
00380             (
00381                 newFace,       // modified face
00382                 mf[faceI],     // label of face being modified
00383                 newOwner,      // owner
00384                 newNeighbour,  // neighbour
00385                 flipFace,      // flip
00386                 newPatchID,    // patch for face
00387                 false,         // remove from zone
00388                 newZoneID,     // new zone
00389                 zoneFlip       // face flip in zone
00390             )
00391         );
00392     }
00393 }
00394 
00395 
00396 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines