cellCuts.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Class
27  Foam::cellCuts
28 
29 Description
30  Description of cuts across cells.
31 
32  Description of cut is given as list of vertices and
33  list of edges to be cut (and position on edge).
34 
35  Does some checking of correctness/non-overlapping of cuts. 2x2x2
36  refinement has to be done in three passes since cuts can not overlap
37  (would make addressing too complicated)
38 
39  Introduces concept of 'cut' which is either an existing vertex
40  or a edge.
41 
42  Input can either be
43  -# list of cut vertices and list of cut edges. Constructs cell
44  circumference walks ('cellLoops').
45 
46  -# list of cell circumference walks. Will filter them so they
47  don't overlap.
48 
49  -# cellWalker and list of cells to refine (refineCell). Constructs
50  cellLoops and does B. cellWalker is class which can cut a single
51  cell using a plane through the cell centre and in a certain normal
52  direction
53 
54  CellCuts constructed from cellLoops (B, C) can have multiple cut-edges
55  and/or cut-point as long as there is per face only one (or none) cut across
56  a face, i.e. a face can only be split into two faces.
57 
58  The information available after construction:
59  - pointIsCut, edgeIsCut.
60  - faceSplitCut : the cross-cut of a face.
61  - cellLoops : the loop which cuts across a cell
62  - cellAnchorPoints : per cell the vertices on one side which are
63  considered the anchor points.
64 
65  AnchorPoints: connected loops have to be oriented in the same way to
66  be able to grow new internal faces out of the same bottom faces.
67  (limitation of the mapping procedure). The loop is cellLoop is oriented
68  such that the normal of it points towards the anchorPoints.
69  This is the only routine which uses geometric information.
70 
71 
72  Limitations:
73  - cut description is very precise. Hard to get right.
74  - do anchor points need to be unique per cell? Very inefficient.
75  - is orientation guaranteed to be correct? Uses geometric info so can go
76  wrong on highly distorted meshes.
77  - is memory inefficient. Probably need to use Maps instead of
78  labelLists.
79 
80 SourceFiles
81  cellCuts.C
82 
83 \*---------------------------------------------------------------------------*/
84 
85 #ifndef cellCuts_H
86 #define cellCuts_H
87 
88 #include "edgeVertex.H"
89 #include "labelList.H"
90 #include "boolList.H"
91 #include "scalarField.H"
92 #include "pointField.H"
93 #include "DynamicList.H"
94 #include "typeInfo.H"
95 
96 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
97 
98 namespace Foam
99 {
100 
101 // Forward Declarations
102 class polyMesh;
103 class cellLooper;
104 class refineCell;
105 class plane;
106 
107 /*---------------------------------------------------------------------------*\
108  Class cellCuts Declaration
109 \*---------------------------------------------------------------------------*/
110 
111 class cellCuts
112 :
113  public edgeVertex
114 {
115  // Private Data
116 
117  //- Warn for illegal cuts
118  const bool verbose_;
119 
120 
121  // Per point/edge status
122 
123  //- Is mesh point cut
124  boolList pointIsCut_;
125 
126  //- Is edge cut
127  boolList edgeIsCut_;
128 
129  //- If edge is cut gives weight (0->start() to 1->end())
130  scalarField edgeWeight_;
131 
132 
133  // Cut addressing
134 
135  //- Cuts per existing face (includes those along edge of face)
136  // Cuts in no particular order.
137  mutable unique_ptr<labelListList> faceCutsPtr_;
138 
139  //- Per face : cut across edge (so not along existing edge)
140  // (can only be one per face)
141  Map<edge> faceSplitCut_;
142 
143 
144  // Cell-cut addressing
145 
146  //- Loop across cell circumference
147  labelListList cellLoops_;
148 
149  //- Number of valid loops in cellLoops_
150  label nLoops_;
151 
152  //- For each cut cell the points on the 'anchor' side of the cell.
153  labelListList cellAnchorPoints_;
154 
155 
156  // Private Static Functions
157 
158  //- Find value in first n elements of list.
159  static label findPartIndex
160  (
161  const labelList&,
162  const label n,
163  const label val
164  );
165 
166  //- Create boolList with all labels specified set to true
167  // (and rest to false)
168  static boolList expand(const label size, const labelList& labels);
169 
170  //- Create scalarField with all specified labels set to corresponding
171  // value in scalarField.
172  static scalarField expand
173  (
174  const label,
175  const labelList&,
176  const scalarField&
177  );
178 
179  //- Returns -1 or index of first element of lst that cannot be found
180  // in map.
181  static label firstUnique
182  (
183  const labelList& lst,
184  const Map<label>&
185  );
186 
187 
188  // Private Member Functions
189 
190  //- Debugging: write cell's edges and any cut vertices and edges
191  // (so no cell loop determined yet)
192  void writeUncutOBJ(const fileName&, const label celli) const;
193 
194  //- Debugging: write cell's edges, loop and anchors to directory.
195  void writeOBJ
196  (
197  const fileName& dir,
198  const label celli,
199  const pointField& loopPoints,
200  const labelList& anchors
201  ) const;
202 
203  //- Find face on cell using the two edges.
204  label edgeEdgeToFace
205  (
206  const label celli,
207  const label edgeA,
208  const label edgeB
209  ) const;
210 
211 
212  //- Find face on cell using an edge and a vertex.
213  label edgeVertexToFace
214  (
215  const label celli,
216  const label edgeI,
217  const label vertI
218  ) const;
219 
220  //- Find face using two vertices (guaranteed not to be along edge)
221  label vertexVertexToFace
222  (
223  const label celli,
224  const label vertA,
225  const label vertB
226  ) const;
227 
228 
229  // Cut addressing
230 
231  //- Calculate faceCuts in face vertex order.
232  void calcFaceCuts() const;
233 
234 
235  // Loop (cuts on cell circumference) calculation
236 
237  //- Find edge (or -1) on facei using vertices v0,v1
238  label findEdge
239  (
240  const label facei,
241  const label v0,
242  const label v1
243  ) const;
244 
245  //- Find face on which all cuts are (very rare) or -1.
246  label loopFace(const label celli, const labelList& loop) const;
247 
248  //- Cross otherCut into next faces (not exclude0, exclude1)
249  bool walkPoint
250  (
251  const label celli,
252  const label startCut,
253 
254  const label exclude0,
255  const label exclude1,
256 
257  const label otherCut,
258 
259  label& nVisited,
260  labelList& visited
261  ) const;
262 
263  //- Cross cut (which is edge on facei) onto next face
264  bool crossEdge
265  (
266  const label celli,
267  const label startCut,
268  const label facei,
269  const label otherCut,
270 
271  label& nVisited,
272  labelList& visited
273  ) const;
274 
275  // wrapper around visited[nVisited++] = cut. Checks for duplicate
276  // cuts.
277  bool addCut
278  (
279  const label celli,
280  const label cut,
281  label& nVisited,
282  labelList& visited
283  ) const;
284 
285  //- Walk across facei following cuts, starting at cut. Stores cuts
286  // visited
287  // Returns true if valid walk.
288  bool walkFace
289  (
290  const label celli,
291  const label startCut,
292  const label facei,
293  const label cut,
294 
295  label& lastCut,
296  label& beforeLastCut,
297  label& nVisited,
298  labelList& visited
299  ) const;
300 
301  //- Walk across cuts (cut edges or cut vertices) of cell. Stops when
302  // hit cut already visited. Returns true when loop of 3 or more
303  // vertices found.
304  bool walkCell
305  (
306  const label celli,
307  const label startCut, // overall starting cut
308  const label facei,
309  const label prevCut, // current cut
310  label& nVisited,
311  labelList& visited
312  ) const;
313 
314  //- Determine for every cut cell the face it is cut by.
315  void calcCellLoops(const labelList& cutCells);
316 
317 
318  // Cell anchoring
319 
320  //- Are there enough faces on anchor side of celli?
321  bool checkFaces
322  (
323  const label celli,
324  const labelList& anchorPoints
325  ) const;
326 
327  //- Walk unset edges of single cell from starting point and
328  // marks visited edges and vertices with status.
329  void walkEdges
330  (
331  const label celli,
332  const label pointi,
333  const label status,
334 
335  Map<label>& edgeStatus,
336  Map<label>& pointStatus
337  ) const;
338 
339  //- Check anchor points on 'outside' of loop
340  bool loopAnchorConsistent
341  (
342  const label celli,
343  const pointField& loopPts,
344  const labelList& anchorPoints
345  ) const;
346 
347  //- Determines set of anchor points given a loop. The loop should
348  // split the cell into two. Returns true if a valid set of anchor
349  // points determined, false otherwise.
350  bool calcAnchors
351  (
352  const label celli,
353  const labelList& loop,
354  const pointField& loopPts,
355 
356  labelList& anchorPoints
357  ) const;
358 
359  //- Returns coordinates of points on loop with explicitly provided
360  // weights.
361  pointField loopPoints
362  (
363  const labelList& loop,
364  const scalarField& loopWeights
365  ) const;
366 
367  //- Returns weights of loop. Inverse of loopPoints.
368  scalarField loopWeights(const labelList& loop) const;
369 
370  //- Check if cut edges in loop are compatible with ones in
371  // edgeIsCut_
372  bool validEdgeLoop
373  (
374  const labelList& loop,
375  const scalarField& loopWeights
376  ) const;
377 
378  //- Counts number of cuts on face.
379  label countFaceCuts
380  (
381  const label facei,
382  const labelList& loop
383  ) const;
384 
385  //- Determine compatibility of loop with existing cut pattern.
386  // Does not use cut-addressing (faceCuts_, cutCuts_)
387  bool conservativeValidLoop
388  (
389  const label celli,
390  const labelList& loop
391  ) const;
392 
393  //- Check if loop is compatible with existing cut pattern in
394  // pointIsCut, edgeIsCut, faceSplitCut.
395  // Calculates and returns for current cell the cut faces and the
396  // points on one side of the loop.
397  bool validLoop
398  (
399  const label celli,
400  const labelList& loop,
401  const scalarField& loopWeights,
402  Map<edge>& newFaceSplitCut,
403  labelList& anchorPoints
404  ) const;
405 
406  //- Update basic cut information from cellLoops.
407  // Assumes cellLoops_ and edgeWeight_ already set and consistent.
408  // Does not use any other information.
409  void setFromCellLoops();
410 
411  //- Update basic cut information for single cell from cellLoop.
412  bool setFromCellLoop
413  (
414  const label celli,
415  const labelList& loop,
416  const scalarField& loopWeights
417  );
418 
419  //- Update basic cut information from cellLoops. Checks for
420  // consistency with existing cut pattern.
421  void setFromCellLoops
422  (
423  const labelList& cellLabels,
424  const labelListList& cellLoops,
425  const List<scalarField>& cellLoopWeights
426  );
427 
428  //- Update basic cut information to be consistent across
429  // coupled boundaries.
430  void syncProc();
431 
432  //- Cut cells and update basic cut information from cellLoops.
433  // Checks each loop for consistency with existing cut pattern.
434  void setFromCellCutter
435  (
436  const cellLooper&,
437  const List<refineCell>& refCells
438  );
439 
440  //- Same as above but now cut with prescribed plane (instead of
441  // just normal).
442  void setFromCellCutter
443  (
444  const cellLooper&,
445  const labelList& cellLabels,
446  const List<plane>&
447  );
448 
449  //- Set orientation of loops
450  void orientPlanesAndLoops();
451 
452  //- Top level driver: addressing calculation and loop detection
453  // (loops splitting cells).
454  void calcLoopsAndAddressing(const labelList& cutCells);
455 
456  //- Check various consistencies.
457  void check() const;
458 
459 
460  //- No copy construct
461  cellCuts(const cellCuts&) = delete;
462 
463  //- No copy assignment
464  void operator=(const cellCuts&) = delete;
465 
466 
467 public:
468 
469  //- Runtime type information
470  ClassName("cellCuts");
471 
472 
473  // Constructors
474 
475  //- Construct from cells to cut and pattern of cuts
476  cellCuts
477  (
478  const polyMesh& mesh,
479  const labelList& cutCells,
480  const labelList& meshVerts,
481  const labelList& meshEdges,
482  const scalarField& meshEdgeWeights,
483  const bool verbose = true
484  );
485 
486  //- Construct from pattern of cuts. Detect cells to cut.
487  cellCuts
488  (
489  const polyMesh& mesh,
490  const labelList& meshVerts,
491  const labelList& meshEdges,
492  const scalarField& meshEdgeWeights,
493  const bool verbose = true
494  );
495 
496  //- Construct from complete cellLoops through specified cells.
497  // Checks for consistency.
498  // Constructs cut-cut addressing and cellAnchorPoints.
499  cellCuts
500  (
501  const polyMesh& mesh,
502  const labelList& cellLabels,
503  const labelListList& cellLoops,
504  const List<scalarField>& cellEdgeWeights,
505  const bool verbose = true
506  );
507 
508  //- Construct from list of cells to cut and direction to cut in
509  // (always through cell centre) and celllooper.
510  cellCuts
511  (
512  const polyMesh& mesh,
513  const cellLooper& cellCutter,
514  const List<refineCell>& refCells,
515  const bool verbose = true
516  );
517 
518  //- Construct from list of cells to cut and plane to cut with and
519  // celllooper. (constructor above always cuts through cell centre)
520  cellCuts
521  (
522  const polyMesh& mesh,
523  const cellLooper& cellCutter,
524  const labelList& cellLabels,
525  const List<plane>& cutPlanes,
526  const bool verbose = true
527  );
528 
529  //- Construct from components
530  cellCuts
531  (
532  const polyMesh& mesh,
533  const boolList& pointIsCut,
534  const boolList& edgeIsCut,
535  const scalarField& edgeWeight,
536  const Map<edge>& faceSplitCut,
537  const labelListList& cellLoops,
538  const label nLoops,
540  const bool verbose = true
541  );
542 
543 
544  //- Destructor
545  ~cellCuts() = default;
546 
547  //- Clear out demand-driven storage
548  void clearOut();
549 
550 
551  // Member Functions
552 
553  // Access
554 
555  //- Is mesh point cut
556  const boolList& pointIsCut() const
557  {
558  return pointIsCut_;
559  }
560 
561  //- Is edge cut
562  const boolList& edgeIsCut() const
563  {
564  return edgeIsCut_;
565  }
566 
567  //- If edge is cut gives weight (ratio between start() and end())
568  const scalarField& edgeWeight() const
569  {
570  return edgeWeight_;
571  }
572 
573  //- Cuts per existing face (includes those along edge of face)
574  // Cuts in no particular order
575  const labelListList& faceCuts() const
576  {
577  if (!faceCutsPtr_)
578  {
579  calcFaceCuts();
580  }
581  return *faceCutsPtr_;
582  }
583 
584  //- Gives for split face the two cuts that split the face into two.
585  const Map<edge>& faceSplitCut() const
586  {
587  return faceSplitCut_;
588  }
589 
590  //- For each cut cell the cut along the circumference.
591  const labelListList& cellLoops() const
592  {
593  return cellLoops_;
594  }
595 
596  //- Number of valid cell loops
597  label nLoops() const
598  {
599  return nLoops_;
600  }
601 
602  //- For each cut cell the points on the 'anchor' side of the cell.
603  const labelListList& cellAnchorPoints() const
604  {
605  return cellAnchorPoints_;
606  }
607 
608 
609  // Other
610 
611  //- Returns coordinates of points on loop for given cell.
612  // Uses cellLoops_ and edgeWeight_
613  pointField loopPoints(const label celli) const;
614 
615  //- Invert anchor point selection.
617  (
618  const labelList& cellPoints,
619  const labelList& anchorPoints,
620  const labelList& loop
621  ) const;
622 
623  //- Flip loop for celli. Updates anchor points as well.
624  void flip(const label celli);
625 
626  //- Flip loop for celli. Does not update anchors. Use with care
627  // (only if you're sure loop orientation is wrong)
628  void flipLoopOnly(const label celli);
629 
630 
631  // Write
632 
633  //- debugging:Write list of cuts to stream in OBJ format
634  void writeOBJ
635  (
636  Ostream& os,
637  const pointField& loopPoints,
638  label& vertI
639  ) const;
640 
641  //- debugging:Write all of cuts to stream in OBJ format
642  void writeOBJ(Ostream& os) const;
643 
644  //- debugging:Write edges of cell and loop
645  void writeCellOBJ(const fileName& dir, const label celli) const;
646 };
647 
648 
649 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
650 
651 } // End namespace Foam
652 
653 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
654 
655 #endif
656 
657 // ************************************************************************* //
Foam::cellCuts::nLoops
label nLoops() const
Number of valid cell loops.
Definition: cellCuts.H:596
Foam::cellCuts::pointIsCut
const boolList & pointIsCut() const
Is mesh point cut.
Definition: cellCuts.H:555
boolList.H
Foam::cellCuts::faceSplitCut
const Map< edge > & faceSplitCut() const
Gives for split face the two cuts that split the face into two.
Definition: cellCuts.H:584
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
typeInfo.H
scalarField.H
Foam::cellCuts::~cellCuts
~cellCuts()=default
Destructor.
Foam::edgeVertex
Combines edge or vertex in single label. Used to specify cuts across cell circumference.
Definition: edgeVertex.H:55
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: lumpedPointController.H:69
Foam::cellCuts::cellAnchorPoints
const labelListList & cellAnchorPoints() const
For each cut cell the points on the 'anchor' side of the cell.
Definition: cellCuts.H:602
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::cellCuts::edgeWeight
const scalarField & edgeWeight() const
If edge is cut gives weight (ratio between start() and end())
Definition: cellCuts.H:567
n
label n
Definition: TABSMDCalcMethod2.H:31
labelList.H
Foam::Field< scalar >
Foam::cellCuts::faceCuts
const labelListList & faceCuts() const
Cuts per existing face (includes those along edge of face)
Definition: cellCuts.H:574
Foam::cellCuts::cellLoops
const labelListList & cellLoops() const
For each cut cell the cut along the circumference.
Definition: cellCuts.H:590
Foam::cellLooper
Abstract base class. Concrete implementations know how to cut a cell (i.e. determine a loop around th...
Definition: cellLooper.H:72
cut
Patchify triangles based on orientation w.r.t other (triangulated or triangulatable) surfaces.
Foam::cellCuts::writeCellOBJ
void writeCellOBJ(const fileName &dir, const label celli) const
debugging:Write edges of cell and loop
Definition: cellCuts.C:3240
os
OBJstream os(runTime.globalPath()/outputName)
Foam::cellCuts::nonAnchorPoints
labelList nonAnchorPoints(const labelList &cellPoints, const labelList &anchorPoints, const labelList &loop) const
Invert anchor point selection.
Definition: cellCuts.C:1330
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
pointField.H
Foam::cellCuts::flipLoopOnly
void flipLoopOnly(const label celli)
Flip loop for celli. Does not update anchors. Use with care.
Definition: cellCuts.C:3191
Foam::List< bool >
Foam::cellCuts::edgeIsCut
const boolList & edgeIsCut() const
Is edge cut.
Definition: cellCuts.H:561
Foam::cellCuts::ClassName
ClassName("cellCuts")
Runtime type information.
DynamicList.H
Foam::cellCuts::clearOut
void clearOut()
Clear out demand-driven storage.
Definition: cellCuts.C:3143
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::cellCuts::flip
void flip(const label celli)
Flip loop for celli. Updates anchor points as well.
Definition: cellCuts.C:3174
edgeVertex.H
Foam::cellCuts
Description of cuts across cells.
Definition: cellCuts.H:110
Foam::edgeVertex::mesh
const polyMesh & mesh() const
Definition: edgeVertex.H:101