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-------------------------------------------------------------------------------
10License
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
26Class
27 Foam::cellCuts
28
29Description
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
80SourceFiles
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
98namespace Foam
99{
100
101// Forward Declarations
102class polyMesh;
103class cellLooper;
104class refineCell;
105class plane;
106
107/*---------------------------------------------------------------------------*\
108 Class cellCuts Declaration
109\*---------------------------------------------------------------------------*/
111class 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,
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
467public:
468
469 //- Runtime type information
470 ClassName("cellCuts");
471
472
473 // Constructors
474
475 //- Construct from cells to cut and pattern of cuts
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.
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.
500 (
501 const polyMesh& mesh,
502 const labelList& cellLabels,
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.
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)
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
531 (
532 const polyMesh& mesh,
533 const boolList& pointIsCut,
534 const boolList& edgeIsCut,
535 const scalarField& edgeWeight,
536 const Map<edge>& faceSplitCut,
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// ************************************************************************* //
label n
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
Description of cuts across cells.
Definition: cellCuts.H:113
const labelListList & cellLoops() const
For each cut cell the cut along the circumference.
Definition: cellCuts.H:590
const boolList & pointIsCut() const
Is mesh point cut.
Definition: cellCuts.H:555
void writeCellOBJ(const fileName &dir, const label celli) const
debugging:Write edges of cell and loop
Definition: cellCuts.C:3240
const boolList & edgeIsCut() const
Is edge cut.
Definition: cellCuts.H:561
void flipLoopOnly(const label celli)
Flip loop for celli. Does not update anchors. Use with care.
Definition: cellCuts.C:3191
void flip(const label celli)
Flip loop for celli. Updates anchor points as well.
Definition: cellCuts.C:3174
~cellCuts()=default
Destructor.
labelList nonAnchorPoints(const labelList &cellPoints, const labelList &anchorPoints, const labelList &loop) const
Invert anchor point selection.
Definition: cellCuts.C:1330
const labelListList & cellAnchorPoints() const
For each cut cell the points on the 'anchor' side of the cell.
Definition: cellCuts.H:602
label nLoops() const
Number of valid cell loops.
Definition: cellCuts.H:596
const scalarField & edgeWeight() const
If edge is cut gives weight (ratio between start() and end())
Definition: cellCuts.H:567
const Map< edge > & faceSplitCut() const
Gives for split face the two cuts that split the face into two.
Definition: cellCuts.H:584
void clearOut()
Clear out demand-driven storage.
Definition: cellCuts.C:3143
const labelListList & faceCuts() const
Cuts per existing face (includes those along edge of face)
Definition: cellCuts.H:574
ClassName("cellCuts")
Runtime type information.
Abstract base class. Concrete implementations know how to cut a cell (i.e. determine a loop around th...
Definition: cellLooper.H:75
Combines edge or vertex in single label. Used to specify cuts across cell circumference.
Definition: edgeVertex.H:56
const polyMesh & mesh() const
Definition: edgeVertex.H:101
A class for handling file names.
Definition: fileName.H:76
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
Patchify triangles based on orientation w.r.t other (triangulated or triangulatable) surfaces.
#define ClassName(TypeNameString)
Add typeName information from argument TypeNameString to a class.
Definition: className.H:67
OBJstream os(runTime.globalPath()/outputName)
Namespace for OpenFOAM.