initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / dynamicMesh / meshCut / cellCuts / cellCuts.H
blob50c9b0d0230266b9ae9c9efbc629ad757406239a
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software; you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Class
26     Foam::cellCuts
28 Description
29     Description of cuts across cells.
31     Description of cut is given as list of vertices and
32     list of edges to be cut (and position on edge).
34     Does some checking of correctness/non-overlapping of cuts. 2x2x2
35     refinement has to be done in three passes since cuts can not overlap
36     (would make addressing too complicated)
38     Introduces concept of 'cut' which is either an existing vertex
39     or a edge.
41     Input can either be
42     -# list of cut vertices and list of cut edges. Constructs cell
43        circumference walks ('cellLoops').
45     -# list of cell circumference walks. Will filter them so they
46        don't overlap.
48     -# cellWalker and list of cells to refine (refineCell). Constructs
49        cellLoops and does B. cellWalker is class which can cut a single
50        cell using a plane through the cell centre and in a certain normal
51        direction
53     CellCuts constructed from cellLoops (B, C) can have multiple cut-edges
54     and/or cut-point as long as there is per face only one (or none) cut across
55     a face, i.e. a face can only be split into two faces.
57     The information available after construction:
58       - pointIsCut, edgeIsCut.
59       - faceSplitCut : the cross-cut of a face.
60       - cellLoops : the loop which cuts across a cell
61       - cellAnchorPoints : per cell the vertices on one side which are
62         considered the anchor points.
64     AnchorPoints: connected loops have to be oriented in the same way to 
65     be able to grow new internal faces out of the same bottom faces.
66     (limitation of the mapping procedure). The loop is cellLoop is oriented
67     such that the normal of it points towards the anchorPoints.
68     This is the only routine which uses geometric information.
71     Limitations:
72     - cut description is very precise. Hard to get right.
73     - do anchor points need to be unique per cell? Very inefficient.
74     - is orientation guaranteed to be correct? Uses geometric info so can go
75       wrong on highly distorted meshes.
76     - is memory inefficient. Probably need to use Maps instead of
77       labelLists.
79 SourceFiles
80     cellCuts.C
82 \*---------------------------------------------------------------------------*/
84 #ifndef cellCuts_H
85 #define cellCuts_H
87 #include "edgeVertex.H"
88 #include "labelList.H"
89 #include "boolList.H"
90 #include "scalarField.H"
91 #include "pointField.H"
92 #include "DynamicList.H"
93 #include "typeInfo.H"
95 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
97 namespace Foam
100 // Forward declaration of classes
101 class polyMesh;
102 class cellLooper;
103 class refineCell;
104 class plane;
106 /*---------------------------------------------------------------------------*\
107                            Class cellCuts Declaration
108 \*---------------------------------------------------------------------------*/
110 class cellCuts
112     public edgeVertex
114     // Private data
116         // Per point/edge status
118             //- Is mesh point cut
119             boolList pointIsCut_;
121             //- Is edge cut
122             boolList edgeIsCut_;
124             //- If edge is cut gives weight (0->start() to 1->end())
125             scalarField edgeWeight_;
128         // Cut addressing
130             //- Cuts per existing face (includes those along edge of face)
131             //  Cuts in no particular order.
132             mutable labelListList* faceCutsPtr_;
134             //- Per face : cut across edge (so not along existing edge)
135             //  (can only be one per face)
136             Map<edge> faceSplitCut_;
139         // Cell-cut addressing
141             //- Loop across cell circumference
142             labelListList cellLoops_;
144             //- Number of valid loops in cellLoops_
145             label nLoops_;
147             //- For each cut cell the points on the 'anchor' side of the cell.
148             labelListList cellAnchorPoints_;
151     // Private Static Functions
153         //- Find value in first n elements of list.
154         static label findPartIndex
155         (
156             const labelList&,
157             const label n,
158             const label val
159         );
161         //- Create boolList with all labels specified set to true
162         //  (and rest to false)
163         static boolList expand(const label size, const labelList& labels);
165         //- Create scalarField with all specified labels set to corresponding
166         //  value in scalarField.
167         static scalarField expand
168         (
169             const label,
170             const labelList&,
171             const scalarField&
172         );
174         //- Returns -1 or index of first element of lst that cannot be found
175         //  in map.
176         static label firstUnique
177         (
178             const labelList& lst,
179             const Map<label>&
180         );
182     // Private Member Functions
184         //- Debugging: write cell's edges and any cut vertices and edges
185         //  (so no cell loop determined yet)
186         void writeUncutOBJ(const fileName&, const label cellI) const;
188         //- Debugging: write cell's edges, loop and anchors to directory.
189         void writeOBJ
190         (
191             const fileName& dir,
192             const label cellI,
193             const pointField& loopPoints,
194             const labelList& anchors
195         ) const;
197         //- Find face on cell using the two edges.
198         label edgeEdgeToFace
199         (
200             const label cellI,
201             const label edgeA,
202             const label edgeB
203         ) const;
206         //- Find face on cell using an edge and a vertex.
207         label edgeVertexToFace
208         (
209             const label cellI,
210             const label edgeI,
211             const label vertI
212         ) const;
214         //- Find face using two vertices (guaranteed not to be along edge)
215         label vertexVertexToFace
216         (
217             const label cellI,
218             const label vertA,
219             const label vertB
220         ) const;
223         // Cut addressing
225             //- Calculate faceCuts in face vertex order.
226             void calcFaceCuts() const;
229         // Loop (cuts on cell circumference) calculation
231             //- Find edge (or -1) on faceI using vertices v0,v1
232             label findEdge
233             (
234                 const label faceI,
235                 const label v0,
236                 const label v1
237             ) const;
239             //- Find face on which all cuts are (very rare) or -1.
240             label loopFace(const label cellI, const labelList& loop) const;
242             //- Cross otherCut into next faces (not exclude0, exclude1)
243             bool walkPoint
244             (
245                 const label cellI,
246                 const label startCut,
248                 const label exclude0,
249                 const label exclude1,
251                 const label otherCut,
253                 label& nVisited,
254                 labelList& visited
255             ) const;
257             //- Cross cut (which is edge on faceI) onto next face
258             bool crossEdge
259             (
260                 const label cellI,
261                 const label startCut,
262                 const label faceI,
263                 const label otherCut,
265                 label& nVisited,
266                 labelList& visited
267             ) const;
269             // wrapper around visited[nVisited++] = cut. Checks for duplicate
270             // cuts.
271             bool addCut
272             (
273                 const label cellI,
274                 const label cut,
275                 label& nVisited,
276                 labelList& visited
277             ) const;
279             //- Walk across faceI following cuts, starting at cut. Stores cuts
280             //  visited
281             bool walkFace
282             (
283                 const label cellI,
284                 const label startCut,
285                 const label faceI,
286                 const label cut,
288                 label& lastCut,
289                 label& beforeLastCut,
290                 label& nVisited,
291                 labelList& visited
292             ) const;
294             //- Walk across cuts (cut edges or cut vertices) of cell. Stops when
295             //  hit cut  already visited. Returns true when loop of 3 or more
296             //  vertices found.
297             bool walkCell
298             (
299                 const label cellI,
300                 const label startCut,   // overall starting cut
301                 const label faceI,
302                 const label prevCut,    // current cut
303                 label& nVisited,
304                 labelList& visited
305             ) const;
307             //- Determine for every cut cell the face it is cut by.
308             void calcCellLoops(const labelList& cutCells);
311         // Cell anchoring
313             //- Are there enough faces on anchor side of cellI?
314             bool checkFaces
315             (
316                 const label cellI,
317                 const labelList& anchorPoints
318             ) const;
320             //- Walk unset edges of single cell from starting point and
321             //  marks visited edges and vertices with status.
322             void walkEdges
323             (
324                 const label cellI,
325                 const label pointI,
326                 const label status,
328                 Map<label>& edgeStatus,
329                 Map<label>& pointStatus
330             ) const;
332             //- Check anchor points on 'outside' of loop
333             bool loopAnchorConsistent
334             (
335                 const label cellI,
336                 const pointField& loopPts,
337                 const labelList& anchorPoints
338             ) const;
340             //- Determines set of anchor points given a loop. The loop should
341             //  split the cell into two. Returns true if a valid set of anchor
342             //  points determined, false otherwise.
343             bool calcAnchors
344             (
345                 const label cellI,
346                 const labelList& loop,
347                 const pointField& loopPts,
349                 labelList& anchorPoints
350             ) const;
352             //- Returns coordinates of points on loop with explicitly provided
353             //  weights.
354             pointField loopPoints
355             (
356                 const labelList& loop,
357                 const scalarField& loopWeights
358             ) const;
360             //- Returns weights of loop. Inverse of loopPoints.
361             scalarField loopWeights(const labelList& loop) const;
363             //- Check if cut edges in loop are compatible with ones in
364             //  edgeIsCut_
365             bool validEdgeLoop
366             (
367                 const labelList& loop,
368                 const scalarField& loopWeights
369             ) const;
371             //- Counts number of cuts on face.
372             label countFaceCuts
373             (
374                 const label faceI,
375                 const labelList& loop
376             ) const;
378             //- Determines if loop through cellI consistent with existing
379             //  pattern.
380             bool conservativeValidLoop
381             (
382                 const label cellI,
383                 const labelList& loop
384             ) const;
386             //- Check if loop is compatible with existing cut pattern in
387             //  pointIsCut, edgeIsCut, faceSplitCut.
388             //  Calculates and returns for current cell the cut faces and the
389             //  points on one side of the loop.
390             bool validLoop
391             (
392                 const label cellI,
393                 const labelList& loop,
394                 const scalarField& loopWeights,
395                 Map<edge>& newFaceSplitCut,
396                 labelList& anchorPoints
397             ) const;
399             //- Update basic cut information from cellLoops. Assumes cellLoops_
400             //  already set and consistent.
401             void setFromCellLoops();
403             //- Update basic cut information for single cell from cellLoop.
404             bool setFromCellLoop
405             (
406                 const label cellI,
407                 const labelList& loop,
408                 const scalarField& loopWeights
409             );
411             //- Update basic cut information from cellLoops. Checks for
412             //  consistency with existing cut pattern.
413             void setFromCellLoops
414             (
415                 const labelList& cellLabels,
416                 const labelListList& cellLoops,
417                 const List<scalarField>& cellLoopWeights
418             );
420             //- Cut cells and update basic cut information from cellLoops.
421             //  Checks each loop for consistency with existing cut pattern.
422             void setFromCellCutter
423             (
424                 const cellLooper&,
425                 const List<refineCell>& refCells
426             );
428             //- Same as above but now cut with prescribed plane.
429             void setFromCellCutter
430             (
431                 const cellLooper&,
432                 const labelList& cellLabels,
433                 const List<plane>&
434             );
436             //- Set orientation of loops
437             void orientPlanesAndLoops();
438             
439             //- top level driver: adressing calculation and loop detection
440             void calcLoopsAndAddressing(const labelList& cutCells);
442             //- Check various consistencies.
443             void check() const;
446         //- Disallow default bitwise copy construct
447         cellCuts(const cellCuts&);
449         //- Disallow default bitwise assignment
450         void operator=(const cellCuts&);
453 public:
455     //- Runtime type information
456     ClassName("cellCuts");
459     // Constructors
461         //- Construct from cells to cut and pattern of cuts
462         cellCuts
463         (
464             const polyMesh& mesh,
465             const labelList& cutCells,
466             const labelList& meshVerts,
467             const labelList& meshEdges,
468             const scalarField& meshEdgeWeights
469         );
471         //- Construct from pattern of cuts. Detect cells to cut.
472         cellCuts
473         (
474             const polyMesh& mesh,
475             const labelList& meshVerts,
476             const labelList& meshEdges,
477             const scalarField& meshEdgeWeights
478         );
480         //- Construct from complete cellLoops through specified cells.
481         //  Checks for consistency.
482         //  Constructs cut-cut addressing and cellAnchorPoints.
483         cellCuts
484         (
485             const polyMesh& mesh,
486             const labelList& cellLabels,
487             const labelListList& cellLoops,
488             const List<scalarField>& cellEdgeWeights
489         );
491         //- Construct from list of cells to cut and direction to cut in
492         //  (always through cell centre) and celllooper.
493         cellCuts
494         (
495             const polyMesh& mesh,
496             const cellLooper& cellCutter,
497             const List<refineCell>& refCells
498         );
500         //- Construct from list of cells to cut and plane to cut with and
501         //  celllooper. (constructor above always cuts through cell centre)
502         cellCuts
503         (
504             const polyMesh& mesh,
505             const cellLooper& cellCutter,
506             const labelList& cellLabels,
507             const List<plane>& cutPlanes
508         );
510         //- Construct from components
511         cellCuts
512         (
513             const polyMesh& mesh,
514             const boolList& pointIsCut,
515             const boolList& edgeIsCut,
516             const scalarField& edgeWeight,
517             const Map<edge>& faceSplitCut,
518             const labelListList& cellLoops,
519             const label nLoops,
520             const labelListList& cellAnchorPoints
521         );
524     // Destructor
526         ~cellCuts();
528         //- Clear out demand driven storage
529         void clearOut();
532     // Member Functions
534         // Access
536             //- Is mesh point cut
537             const boolList& pointIsCut() const
538             {
539                 return pointIsCut_;
540             }
542             //- Is edge cut
543             const boolList& edgeIsCut() const
544             {
545                 return edgeIsCut_;
546             }
548             //- If edge is cut gives weight (ratio between start() and end())
549             const scalarField& edgeWeight() const
550             {
551                 return edgeWeight_;
552             }
554             //- Cuts per existing face (includes those along edge of face)
555             //  Cuts in no particular order
556             const labelListList& faceCuts() const
557             {
558                 if (!faceCutsPtr_)
559                 {
560                     calcFaceCuts();
561                 }
562                 return *faceCutsPtr_;
563             }
565             //- Gives for split face the two cuts that split the face into two.
566             const Map<edge>& faceSplitCut() const
567             {
568                 return faceSplitCut_;
569             }
571             //- For each cut cell the cut along the circumference.
572             const labelListList& cellLoops() const
573             {
574                 return cellLoops_;
575             }
577             //- Number of valid cell loops
578             label nLoops() const
579             {
580                 return nLoops_;
581             }
583             //- For each cut cell the points on the 'anchor' side of the cell.
584             const labelListList& cellAnchorPoints() const
585             {
586                 return cellAnchorPoints_;
587             }
590         // Other
592             //- Returns coordinates of points on loop for given cell.
593             //  Uses cellLoops_ and edgeWeight_
594             pointField loopPoints(const label cellI) const;
595   
596             //- Invert anchor point selection.
597             labelList nonAnchorPoints
598             (
599                 const labelList& cellPoints,
600                 const labelList& anchorPoints,
601                 const labelList& loop
602             ) const;
604             //- Flip loop for cellI. Updates anchor points as well.
605             void flip(const label cellI);
607             //- Flip loop for cellI. Does not update anchors. Use with care
608             //  (only if you're sure loop orientation is wrong)
609             void flipLoopOnly(const label cellI);
612         // Write
614             //- debugging:Write list of cuts to stream in OBJ format
615             void writeOBJ
616             (
617                 Ostream& os,
618                 const pointField& loopPoints,
619                 label& vertI
620             ) const;
622             //- debugging:Write all of cuts to stream in OBJ format
623             void writeOBJ(Ostream& os) const;
625             //- debugging:Write edges of cell and loop
626             void writeCellOBJ(const fileName& dir, const label cellI) const;
631 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
633 } // End namespace Foam
635 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
637 #endif
639 // ************************************************************************* //