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

cellCuts.H

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 Class
00025     Foam::cellCuts
00026 
00027 Description
00028     Description of cuts across cells.
00029 
00030     Description of cut is given as list of vertices and
00031     list of edges to be cut (and position on edge).
00032 
00033     Does some checking of correctness/non-overlapping of cuts. 2x2x2
00034     refinement has to be done in three passes since cuts can not overlap
00035     (would make addressing too complicated)
00036 
00037     Introduces concept of 'cut' which is either an existing vertex
00038     or a edge.
00039 
00040     Input can either be
00041     -# list of cut vertices and list of cut edges. Constructs cell
00042        circumference walks ('cellLoops').
00043 
00044     -# list of cell circumference walks. Will filter them so they
00045        don't overlap.
00046 
00047     -# cellWalker and list of cells to refine (refineCell). Constructs
00048        cellLoops and does B. cellWalker is class which can cut a single
00049        cell using a plane through the cell centre and in a certain normal
00050        direction
00051 
00052     CellCuts constructed from cellLoops (B, C) can have multiple cut-edges
00053     and/or cut-point as long as there is per face only one (or none) cut across
00054     a face, i.e. a face can only be split into two faces.
00055 
00056     The information available after construction:
00057       - pointIsCut, edgeIsCut.
00058       - faceSplitCut : the cross-cut of a face.
00059       - cellLoops : the loop which cuts across a cell
00060       - cellAnchorPoints : per cell the vertices on one side which are
00061         considered the anchor points.
00062 
00063     AnchorPoints: connected loops have to be oriented in the same way to 
00064     be able to grow new internal faces out of the same bottom faces.
00065     (limitation of the mapping procedure). The loop is cellLoop is oriented
00066     such that the normal of it points towards the anchorPoints.
00067     This is the only routine which uses geometric information.
00068 
00069 
00070     Limitations:
00071     - cut description is very precise. Hard to get right.
00072     - do anchor points need to be unique per cell? Very inefficient.
00073     - is orientation guaranteed to be correct? Uses geometric info so can go
00074       wrong on highly distorted meshes.
00075     - is memory inefficient. Probably need to use Maps instead of
00076       labelLists.
00077 
00078 SourceFiles
00079     cellCuts.C
00080 
00081 \*---------------------------------------------------------------------------*/
00082 
00083 #ifndef cellCuts_H
00084 #define cellCuts_H
00085 
00086 #include <dynamicMesh/edgeVertex.H>
00087 #include <OpenFOAM/labelList.H>
00088 #include <OpenFOAM/boolList.H>
00089 #include <OpenFOAM/scalarField.H>
00090 #include <OpenFOAM/pointField.H>
00091 #include <OpenFOAM/DynamicList.H>
00092 #include <OpenFOAM/typeInfo.H>
00093 
00094 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00095 
00096 namespace Foam
00097 {
00098 
00099 // Forward declaration of classes
00100 class polyMesh;
00101 class cellLooper;
00102 class refineCell;
00103 class plane;
00104 
00105 /*---------------------------------------------------------------------------*\
00106                            Class cellCuts Declaration
00107 \*---------------------------------------------------------------------------*/
00108 
00109 class cellCuts
00110 :
00111     public edgeVertex
00112 {
00113     // Private data
00114 
00115         // Per point/edge status
00116 
00117             //- Is mesh point cut
00118             boolList pointIsCut_;
00119 
00120             //- Is edge cut
00121             boolList edgeIsCut_;
00122 
00123             //- If edge is cut gives weight (0->start() to 1->end())
00124             scalarField edgeWeight_;
00125 
00126 
00127         // Cut addressing
00128 
00129             //- Cuts per existing face (includes those along edge of face)
00130             //  Cuts in no particular order.
00131             mutable labelListList* faceCutsPtr_;
00132 
00133             //- Per face : cut across edge (so not along existing edge)
00134             //  (can only be one per face)
00135             Map<edge> faceSplitCut_;
00136 
00137 
00138         // Cell-cut addressing
00139 
00140             //- Loop across cell circumference
00141             labelListList cellLoops_;
00142 
00143             //- Number of valid loops in cellLoops_
00144             label nLoops_;
00145 
00146             //- For each cut cell the points on the 'anchor' side of the cell.
00147             labelListList cellAnchorPoints_;
00148 
00149 
00150     // Private Static Functions
00151 
00152         //- Find value in first n elements of list.
00153         static label findPartIndex
00154         (
00155             const labelList&,
00156             const label n,
00157             const label val
00158         );
00159 
00160         //- Create boolList with all labels specified set to true
00161         //  (and rest to false)
00162         static boolList expand(const label size, const labelList& labels);
00163 
00164         //- Create scalarField with all specified labels set to corresponding
00165         //  value in scalarField.
00166         static scalarField expand
00167         (
00168             const label,
00169             const labelList&,
00170             const scalarField&
00171         );
00172 
00173         //- Returns -1 or index of first element of lst that cannot be found
00174         //  in map.
00175         static label firstUnique
00176         (
00177             const labelList& lst,
00178             const Map<label>&
00179         );
00180 
00181     // Private Member Functions
00182 
00183         //- Debugging: write cell's edges and any cut vertices and edges
00184         //  (so no cell loop determined yet)
00185         void writeUncutOBJ(const fileName&, const label cellI) const;
00186 
00187         //- Debugging: write cell's edges, loop and anchors to directory.
00188         void writeOBJ
00189         (
00190             const fileName& dir,
00191             const label cellI,
00192             const pointField& loopPoints,
00193             const labelList& anchors
00194         ) const;
00195 
00196         //- Find face on cell using the two edges.
00197         label edgeEdgeToFace
00198         (
00199             const label cellI,
00200             const label edgeA,
00201             const label edgeB
00202         ) const;
00203 
00204 
00205         //- Find face on cell using an edge and a vertex.
00206         label edgeVertexToFace
00207         (
00208             const label cellI,
00209             const label edgeI,
00210             const label vertI
00211         ) const;
00212 
00213         //- Find face using two vertices (guaranteed not to be along edge)
00214         label vertexVertexToFace
00215         (
00216             const label cellI,
00217             const label vertA,
00218             const label vertB
00219         ) const;
00220 
00221 
00222         // Cut addressing
00223 
00224             //- Calculate faceCuts in face vertex order.
00225             void calcFaceCuts() const;
00226 
00227 
00228         // Loop (cuts on cell circumference) calculation
00229 
00230             //- Find edge (or -1) on faceI using vertices v0,v1
00231             label findEdge
00232             (
00233                 const label faceI,
00234                 const label v0,
00235                 const label v1
00236             ) const;
00237 
00238             //- Find face on which all cuts are (very rare) or -1.
00239             label loopFace(const label cellI, const labelList& loop) const;
00240 
00241             //- Cross otherCut into next faces (not exclude0, exclude1)
00242             bool walkPoint
00243             (
00244                 const label cellI,
00245                 const label startCut,
00246 
00247                 const label exclude0,
00248                 const label exclude1,
00249 
00250                 const label otherCut,
00251 
00252                 label& nVisited,
00253                 labelList& visited
00254             ) const;
00255 
00256             //- Cross cut (which is edge on faceI) onto next face
00257             bool crossEdge
00258             (
00259                 const label cellI,
00260                 const label startCut,
00261                 const label faceI,
00262                 const label otherCut,
00263 
00264                 label& nVisited,
00265                 labelList& visited
00266             ) const;
00267 
00268             // wrapper around visited[nVisited++] = cut. Checks for duplicate
00269             // cuts.
00270             bool addCut
00271             (
00272                 const label cellI,
00273                 const label cut,
00274                 label& nVisited,
00275                 labelList& visited
00276             ) const;
00277 
00278             //- Walk across faceI following cuts, starting at cut. Stores cuts
00279             //  visited
00280             bool walkFace
00281             (
00282                 const label cellI,
00283                 const label startCut,
00284                 const label faceI,
00285                 const label cut,
00286 
00287                 label& lastCut,
00288                 label& beforeLastCut,
00289                 label& nVisited,
00290                 labelList& visited
00291             ) const;
00292 
00293             //- Walk across cuts (cut edges or cut vertices) of cell. Stops when
00294             //  hit cut  already visited. Returns true when loop of 3 or more
00295             //  vertices found.
00296             bool walkCell
00297             (
00298                 const label cellI,
00299                 const label startCut,   // overall starting cut
00300                 const label faceI,
00301                 const label prevCut,    // current cut
00302                 label& nVisited,
00303                 labelList& visited
00304             ) const;
00305 
00306             //- Determine for every cut cell the face it is cut by.
00307             void calcCellLoops(const labelList& cutCells);
00308 
00309 
00310         // Cell anchoring
00311 
00312             //- Are there enough faces on anchor side of cellI?
00313             bool checkFaces
00314             (
00315                 const label cellI,
00316                 const labelList& anchorPoints
00317             ) const;
00318 
00319             //- Walk unset edges of single cell from starting point and
00320             //  marks visited edges and vertices with status.
00321             void walkEdges
00322             (
00323                 const label cellI,
00324                 const label pointI,
00325                 const label status,
00326 
00327                 Map<label>& edgeStatus,
00328                 Map<label>& pointStatus
00329             ) const;
00330 
00331             //- Check anchor points on 'outside' of loop
00332             bool loopAnchorConsistent
00333             (
00334                 const label cellI,
00335                 const pointField& loopPts,
00336                 const labelList& anchorPoints
00337             ) const;
00338 
00339             //- Determines set of anchor points given a loop. The loop should
00340             //  split the cell into two. Returns true if a valid set of anchor
00341             //  points determined, false otherwise.
00342             bool calcAnchors
00343             (
00344                 const label cellI,
00345                 const labelList& loop,
00346                 const pointField& loopPts,
00347 
00348                 labelList& anchorPoints
00349             ) const;
00350 
00351             //- Returns coordinates of points on loop with explicitly provided
00352             //  weights.
00353             pointField loopPoints
00354             (
00355                 const labelList& loop,
00356                 const scalarField& loopWeights
00357             ) const;
00358 
00359             //- Returns weights of loop. Inverse of loopPoints.
00360             scalarField loopWeights(const labelList& loop) const;
00361 
00362             //- Check if cut edges in loop are compatible with ones in
00363             //  edgeIsCut_
00364             bool validEdgeLoop
00365             (
00366                 const labelList& loop,
00367                 const scalarField& loopWeights
00368             ) const;
00369 
00370             //- Counts number of cuts on face.
00371             label countFaceCuts
00372             (
00373                 const label faceI,
00374                 const labelList& loop
00375             ) const;
00376 
00377             //- Determines if loop through cellI consistent with existing
00378             //  pattern.
00379             bool conservativeValidLoop
00380             (
00381                 const label cellI,
00382                 const labelList& loop
00383             ) const;
00384 
00385             //- Check if loop is compatible with existing cut pattern in
00386             //  pointIsCut, edgeIsCut, faceSplitCut.
00387             //  Calculates and returns for current cell the cut faces and the
00388             //  points on one side of the loop.
00389             bool validLoop
00390             (
00391                 const label cellI,
00392                 const labelList& loop,
00393                 const scalarField& loopWeights,
00394                 Map<edge>& newFaceSplitCut,
00395                 labelList& anchorPoints
00396             ) const;
00397 
00398             //- Update basic cut information from cellLoops. Assumes cellLoops_
00399             //  already set and consistent.
00400             void setFromCellLoops();
00401 
00402             //- Update basic cut information for single cell from cellLoop.
00403             bool setFromCellLoop
00404             (
00405                 const label cellI,
00406                 const labelList& loop,
00407                 const scalarField& loopWeights
00408             );
00409 
00410             //- Update basic cut information from cellLoops. Checks for
00411             //  consistency with existing cut pattern.
00412             void setFromCellLoops
00413             (
00414                 const labelList& cellLabels,
00415                 const labelListList& cellLoops,
00416                 const List<scalarField>& cellLoopWeights
00417             );
00418 
00419             //- Cut cells and update basic cut information from cellLoops.
00420             //  Checks each loop for consistency with existing cut pattern.
00421             void setFromCellCutter
00422             (
00423                 const cellLooper&,
00424                 const List<refineCell>& refCells
00425             );
00426 
00427             //- Same as above but now cut with prescribed plane.
00428             void setFromCellCutter
00429             (
00430                 const cellLooper&,
00431                 const labelList& cellLabels,
00432                 const List<plane>&
00433             );
00434 
00435             //- Set orientation of loops
00436             void orientPlanesAndLoops();
00437             
00438             //- top level driver: adressing calculation and loop detection
00439             void calcLoopsAndAddressing(const labelList& cutCells);
00440 
00441             //- Check various consistencies.
00442             void check() const;
00443 
00444 
00445         //- Disallow default bitwise copy construct
00446         cellCuts(const cellCuts&);
00447 
00448         //- Disallow default bitwise assignment
00449         void operator=(const cellCuts&);
00450 
00451 
00452 public:
00453 
00454     //- Runtime type information
00455     ClassName("cellCuts");
00456 
00457 
00458     // Constructors
00459 
00460         //- Construct from cells to cut and pattern of cuts
00461         cellCuts
00462         (
00463             const polyMesh& mesh,
00464             const labelList& cutCells,
00465             const labelList& meshVerts,
00466             const labelList& meshEdges,
00467             const scalarField& meshEdgeWeights
00468         );
00469 
00470         //- Construct from pattern of cuts. Detect cells to cut.
00471         cellCuts
00472         (
00473             const polyMesh& mesh,
00474             const labelList& meshVerts,
00475             const labelList& meshEdges,
00476             const scalarField& meshEdgeWeights
00477         );
00478 
00479         //- Construct from complete cellLoops through specified cells.
00480         //  Checks for consistency.
00481         //  Constructs cut-cut addressing and cellAnchorPoints.
00482         cellCuts
00483         (
00484             const polyMesh& mesh,
00485             const labelList& cellLabels,
00486             const labelListList& cellLoops,
00487             const List<scalarField>& cellEdgeWeights
00488         );
00489 
00490         //- Construct from list of cells to cut and direction to cut in
00491         //  (always through cell centre) and celllooper.
00492         cellCuts
00493         (
00494             const polyMesh& mesh,
00495             const cellLooper& cellCutter,
00496             const List<refineCell>& refCells
00497         );
00498 
00499         //- Construct from list of cells to cut and plane to cut with and
00500         //  celllooper. (constructor above always cuts through cell centre)
00501         cellCuts
00502         (
00503             const polyMesh& mesh,
00504             const cellLooper& cellCutter,
00505             const labelList& cellLabels,
00506             const List<plane>& cutPlanes
00507         );
00508 
00509         //- Construct from components
00510         cellCuts
00511         (
00512             const polyMesh& mesh,
00513             const boolList& pointIsCut,
00514             const boolList& edgeIsCut,
00515             const scalarField& edgeWeight,
00516             const Map<edge>& faceSplitCut,
00517             const labelListList& cellLoops,
00518             const label nLoops,
00519             const labelListList& cellAnchorPoints
00520         );
00521 
00522 
00523     // Destructor
00524 
00525         ~cellCuts();
00526 
00527         //- Clear out demand driven storage
00528         void clearOut();
00529 
00530 
00531     // Member Functions
00532 
00533         // Access
00534 
00535             //- Is mesh point cut
00536             const boolList& pointIsCut() const
00537             {
00538                 return pointIsCut_;
00539             }
00540 
00541             //- Is edge cut
00542             const boolList& edgeIsCut() const
00543             {
00544                 return edgeIsCut_;
00545             }
00546 
00547             //- If edge is cut gives weight (ratio between start() and end())
00548             const scalarField& edgeWeight() const
00549             {
00550                 return edgeWeight_;
00551             }
00552 
00553             //- Cuts per existing face (includes those along edge of face)
00554             //  Cuts in no particular order
00555             const labelListList& faceCuts() const
00556             {
00557                 if (!faceCutsPtr_)
00558                 {
00559                     calcFaceCuts();
00560                 }
00561                 return *faceCutsPtr_;
00562             }
00563 
00564             //- Gives for split face the two cuts that split the face into two.
00565             const Map<edge>& faceSplitCut() const
00566             {
00567                 return faceSplitCut_;
00568             }
00569 
00570             //- For each cut cell the cut along the circumference.
00571             const labelListList& cellLoops() const
00572             {
00573                 return cellLoops_;
00574             }
00575 
00576             //- Number of valid cell loops
00577             label nLoops() const
00578             {
00579                 return nLoops_;
00580             }
00581 
00582             //- For each cut cell the points on the 'anchor' side of the cell.
00583             const labelListList& cellAnchorPoints() const
00584             {
00585                 return cellAnchorPoints_;
00586             }
00587 
00588 
00589         // Other
00590 
00591             //- Returns coordinates of points on loop for given cell.
00592             //  Uses cellLoops_ and edgeWeight_
00593             pointField loopPoints(const label cellI) const;
00594   
00595             //- Invert anchor point selection.
00596             labelList nonAnchorPoints
00597             (
00598                 const labelList& cellPoints,
00599                 const labelList& anchorPoints,
00600                 const labelList& loop
00601             ) const;
00602 
00603             //- Flip loop for cellI. Updates anchor points as well.
00604             void flip(const label cellI);
00605 
00606             //- Flip loop for cellI. Does not update anchors. Use with care
00607             //  (only if you're sure loop orientation is wrong)
00608             void flipLoopOnly(const label cellI);
00609 
00610 
00611         // Write
00612 
00613             //- debugging:Write list of cuts to stream in OBJ format
00614             void writeOBJ
00615             (
00616                 Ostream& os,
00617                 const pointField& loopPoints,
00618                 label& vertI
00619             ) const;
00620 
00621             //- debugging:Write all of cuts to stream in OBJ format
00622             void writeOBJ(Ostream& os) const;
00623 
00624             //- debugging:Write edges of cell and loop
00625             void writeCellOBJ(const fileName& dir, const label cellI) const;
00626 
00627 };
00628 
00629 
00630 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00631 
00632 } // End namespace Foam
00633 
00634 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00635 
00636 #endif
00637 
00638 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines