hexRef8.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
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.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Class
25  Foam::hexRef8
26 
27 Description
28  Refinement of (split) hexes using polyTopoChange.
29 
30 SourceFiles
31  hexRef8.C
32 
33 \*---------------------------------------------------------------------------*/
34 
35 #ifndef hexRef8_H
36 #define hexRef8_H
37 
38 #include "labelIOList.H"
39 #include "face.H"
40 #include "HashSet.H"
41 #include "DynamicList.H"
42 #include "primitivePatch.H"
43 #include "removeFaces.H"
44 #include "refinementHistory.H"
45 #include "PackedBoolList.H"
47 #include "cellShapeList.H"
48 
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 
51 namespace Foam
52 {
53 
54 // Forward declaration of classes
55 class polyMesh;
56 class polyPatch;
57 class polyTopoChange;
58 class polyTopoChangeMap;
59 class polyDistributionMap;
60 
61 /*---------------------------------------------------------------------------*\
62  Class hexRef8 Declaration
63 \*---------------------------------------------------------------------------*/
64 
65 class hexRef8
66 {
67  // Private Data
68 
69  //- Reference to underlying mesh.
70  const polyMesh& mesh_;
71 
72  //- Per cell the refinement level
73  labelIOList cellLevel_;
74 
75  //- Per point the refinement level
76  labelIOList pointLevel_;
77 
78  //- Typical edge length between unrefined points
80 
81  //- Refinement history
82  refinementHistory history_;
83 
84  //- Face remover engine
85  removeFaces faceRemover_;
86 
87  //- Level of saved points
88  Map<label> savedPointLevel_;
89 
90  //- Level of saved cells
91  Map<label> savedCellLevel_;
92 
93  //- Cell shapes when seen as split hexes
94  mutable autoPtr<cellShapeList> cellShapesPtr_;
95 
96 
97  // Private Member Functions
98 
99  //- Reorder according to map.
100  static void reorder
101  (
102  const labelList& map,
103  const label len,
104  const label null,
105  labelList& elems
106  );
107 
108  //- Get patch and zone info
109  void getFaceInfo
110  (
111  const label facei,
112  label& patchID,
113  label& zoneID,
114  label& zoneFlip
115  ) const;
116 
117  //- Adds a face on top of existing facei. Reverses if necessary.
118  label addFace
119  (
120  polyTopoChange& meshMod,
121  const label facei,
122  const face& newFace,
123  const label own,
124  const label nei
125  ) const;
126 
127  //- Adds internal face from point. No checks on reversal.
128  // Adds an internal face from an edge. Assumes orientation correct.
129  // Problem is that the face is between four new vertices. So what do
130  // we provide as master? The only existing mesh item we have is the
131  // edge we have split. Have to be careful in only using it if it has
132  // internal faces since otherwise polyMeshMorph will complain (because
133  // it cannot generate a sensible mapping for the face)
134  label addInternalFace
135  (
136  polyTopoChange& meshMod,
137  const label meshFacei,
138  const label meshPointi,
139  const face& newFace,
140  const label own,
141  const label nei
142  ) const;
143 
144  //- Modifies existing facei for either new owner/neighbour or new face
145  // points. Reverses if necessary.
146  void modFace
147  (
148  polyTopoChange& meshMod,
149  const label facei,
150  const face& newFace,
151  const label own,
152  const label nei
153  ) const;
154 
155  //- Bit complex way to determine the unrefined edge length.
156  scalar getLevel0EdgeLength() const;
157 
158  //- Get cell added to point of celli (if any)
159  // Check whether pointi is an anchor on celli. If it is not check
160  // whether any other point on the face is an anchor cell.
161  label getAnchorCell
162  (
163  const labelListList& cellAnchorPoints,
164  const labelListList& cellAddedCells,
165  const label celli,
166  const label facei,
167  const label pointi
168  ) const;
169 
170  //- Get new owner and neighbour (in unspecified order) of pointi
171  // on facei.
172  void getFaceNeighbours
173  (
174  const labelListList& cellAnchorPoints,
175  const labelListList& cellAddedCells,
176  const label facei,
177  const label pointi,
178 
179  label& own,
180  label& nei
181  ) const;
182 
183 
184  //- Get index of minimum pointlevel.
185  label findMinLevel(const labelList& f) const;
186 
187  //- Get maximum pointlevel.
188  label findMaxLevel(const labelList& f) const;
189 
190  //- Count number of vertices <= anchorLevel
191  label countAnchors(const labelList&, const label) const;
192 
193  //- Debugging: dump cell as .obj file
194  void dumpCell(const label celli) const;
195 
196  //- Find index of point with wantedLevel, starting from fp.
197  label findLevel
198  (
199  const label facei,
200  const face& f,
201  const label startFp,
202  const bool searchForward,
203  const label wantedLevel
204  ) const;
205 
206  //- debug:check orientation of added internal face
207  static void checkInternalOrientation
208  (
209  polyTopoChange& meshMod,
210  const label celli,
211  const label facei,
212  const point& ownPt,
213  const point& neiPt,
214  const face& newFace
215  );
216 
217  //- debug:check orientation of new boundary face
218  static void checkBoundaryOrientation
219  (
220  polyTopoChange& meshMod,
221  const label celli,
222  const label facei,
223  const point& ownPt,
224  const point& boundaryPt,
225  const face& newFace
226  );
227 
228  //- If p0 and p1 are existing vertices check if edge is split and insert
229  // splitPoint.
230  void insertEdgeSplit
231  (
232  const labelList& edgeMidPoint,
233  const label p0,
234  const label p1,
235  DynamicList<label>& verts
236  ) const;
237 
238  //- Store in maps correspondence from midpoint to anchors and faces.
239  // Internal faces are one per edge between anchor points. So one per
240  // midPoint between the anchor points. Here we store the information on
241  // the midPoint and if we have enough information:
242  // - two anchors
243  // - two face mid points
244  // we add the face. Note that this routine can get called anywhere from
245  // two times (two unrefined faces) to four times (two refined faces) so
246  // the first call that adds the information creates the face.
247  label storeMidPointInfo
248  (
249  const labelListList& cellAnchorPoints,
250  const labelListList& cellAddedCells,
251  const labelList& cellMidPoint,
252  const labelList& edgeMidPoint,
253  const label celli,
254  const label facei,
255  const bool faceOrder,
256  const label midPointi,
257  const label anchorPointi,
258  const label faceMidPointi,
259 
260  Map<edge>& midPointToAnchors,
261  Map<edge>& midPointToFaceMids,
262  polyTopoChange& meshMod
263  ) const;
264 
265  //- Create all internal faces from an unsplit face.
266  void createInternalFromSplitFace
267  (
268  const labelListList& cellAnchorPoints,
269  const labelListList& cellAddedCells,
270  const labelList& cellMidPoint,
271  const labelList& faceMidPoint,
272  const labelList& edgeMidPoint,
273  const label celli,
274  const label facei,
275 
276  Map<edge>& midPointToAnchors,
277  Map<edge>& midPointToFaceMids,
278  polyTopoChange& meshMod,
279  label& nFacesAdded
280  ) const;
281 
282  //- Create all internal faces to split celli into 8.
283  void createInternalFaces
284  (
285  const labelListList& cellAnchorPoints,
286  const labelListList& cellAddedCells,
287  const labelList& cellMidPoint,
288  const labelList& faceMidPoint,
289  const labelList& faceAnchorLevel,
290  const labelList& edgeMidPoint,
291  const label celli,
292  polyTopoChange& meshMod
293  ) const;
294 
295  //- Store vertices from startFp up to face split point.
296  // Used when splitting face into 4.
297  void walkFaceToMid
298  (
299  const labelList& edgeMidPoint,
300  const label cLevel,
301  const label facei,
302  const label startFp,
303  DynamicList<label>& faceVerts
304  ) const;
305 
306  //- Same as walkFaceToMid but now walk back.
307  void walkFaceFromMid
308  (
309  const labelList& edgeMidPoint,
310  const label cLevel,
311  const label facei,
312  const label startFp,
313  DynamicList<label>& faceVerts
314  ) const;
315 
316  //- Updates refineCell so consistent 2:1 refinement. Returns local
317  // number of cells changed.
318  label faceConsistentRefinement
319  (
320  const bool maxSet,
322  ) const;
323 
324  //- Check wanted refinement for 2:1 consistency
325  void checkWantedRefinementLevels(const labelList&) const;
326 
327 
328  // Cellshape recognition
329 
330  //- Collect all points on face of certain level
331  void collectLevelPoints
332  (
333  const labelList& f,
334  const label level,
336  ) const;
337 
338  //- Collect all points on face (in local numbering) of certain level
339  void collectLevelPoints
340  (
341  const labelList& meshPoints,
342  const labelList& f,
343  const label level,
345  ) const;
346 
347  //- Collect all faces with four corner points and return true if
348  // hex was matched (6 faces of each four corner points)
349  bool matchHexShape
350  (
351  const label celli,
352  const label cellLevel,
353  DynamicList<face>& quads
354  ) const;
355 
356 
357 public:
358 
359  //- Runtime type information
360  ClassName("hexRef8");
361 
362 
363  // Constructors
364 
365  //- Construct from mesh, read_if_present refinement data
366  // (from write below). If readHistory is true does read_if_present
367  // of refinement history. If false clears all history
368  hexRef8(const polyMesh& mesh, const bool readHistory = true);
369 
370  //- Construct from mesh and un/refinement data and optional size of
371  // starting cells
372  hexRef8
373  (
374  const polyMesh& mesh,
375  const labelList& cellLevel,
376  const labelList& pointLevel,
377  const refinementHistory& history,
378  const scalar level0Edge = -great
379  );
380 
381  //- Construct from mesh and refinement data and optional size of
382  // starting cells
383  hexRef8
384  (
385  const polyMesh& mesh,
386  const labelList& cellLevel,
387  const labelList& pointLevel,
388  const scalar level0Edge = -great
389  );
390 
391  //- Disallow default bitwise copy construction
392  hexRef8(const hexRef8&) = delete;
393 
394 
395  // Member Functions
396 
397  // Access
398 
399  const polyMesh& mesh() const
400  {
401  return mesh_;
402  }
403 
404  const labelIOList& cellLevel() const
405  {
406  return cellLevel_;
407  }
408 
409  const labelIOList& pointLevel() const
410  {
411  return pointLevel_;
412  }
413 
414  const refinementHistory& history() const
415  {
416  return history_;
417  }
418 
419  //- Typical edge length between unrefined points
420  scalar level0EdgeLength() const
421  {
422  return level0Edge_.value();
423  }
424 
425  // Refinement
426 
427  //- Gets level such that the face has four points <= level.
428  label faceLevel(const label facei) const;
429 
430  //- Given valid mesh and current cell level and proposed
431  // cells to refine calculate any clashes (due to 2:1) and return
432  // ok list of cells to refine.
433  // Either adds cells to refine to set (maxSet = true) or
434  // removes cells to refine (maxSet = false)
436  (
437  const labelList& cellsToRefine,
438  const bool maxSet
439  ) const;
440 
441  //- Like consistentRefinement but slower:
442  //
443  // - specify number of cells between consecutive refinement levels
444  // (consistentRefinement equivalent to 1)
445  // - specify max level difference between point-connected cells.
446  // (-1 to disable) Note that with normal 2:1 limitation
447  // (maxFaceDiff=1) there can be 8:1 size difference across point
448  // connected cells so maxPointDiff allows you to make that less.
449  // cellsToRefine : cells we're thinking about refining. It will
450  // extend this set. All refinement levels will be
451  // at least maxFaceDiff layers thick.
452  // facesToCheck : additional faces where to implement the
453  // maxFaceDiff thickness (usually only boundary
454  // faces)
456  (
457  const label maxFaceDiff,
458  const labelList& cellsToRefine,
459  const labelList& facesToCheck,
460  const label maxPointDiff,
461  const labelList& pointsToCheck
462  ) const;
463 
464  //- Like consistentSlowRefinement but uses different meshWave
465  // (proper distance instead of toplogical count). No point checks
466  // yet.
468  (
469  const label maxFaceDiff,
470  const labelList& cellsToRefine,
471  const labelList& facesToCheck
472  ) const;
473 
474  //- Insert refinement. All selected cells will be split into 8.
475  // Returns per element in cells the 8 cells they were split into.
476  // Guarantees that the 0th element is the original cell label.
477  // Mapping:
478  // -split cells: 7 new ones get added from original
479  // -split faces: original gets modified; 3 new ones get added
480  // from original
481  // -added internal faces: added from original cell face(if
482  // that was internal) or created out-of-nothing (so will not
483  // get mapped!). Note: could make this inflate from point but
484  // that will allocate interpolation.
485  // -points added to split edge: added from edge start()
486  // -midpoints added: added from cellPoints[0].
488  (
489  const labelList& cells,
491  );
492 
493  //- Update local numbering for changed mesh.
494  // Called after the mesh change. setRefinement will already have
495  // made sure the pointLevel_ and cellLevel_ are the size of the new
496  // mesh so we only need to account for reordering.
497  void topoChange(const polyTopoChangeMap&);
498 
499 
500  // Restoring : is where other processes delete and reinsert data.
501  // These callbacks allow this to restore the cellLevel
502  // and pointLevel for reintroduced points.
503  // Is not related to undoing my refinement
504 
505  //- Signal points/face/cells for which to store data
506  void storeData
507  (
508  const labelList& pointsToStore,
509  const labelList& facesToStore,
510  const labelList& cellsToStore
511  );
512 
513  //- Update local numbering + undo
514  // Data to restore given as new pointlabel + stored pointlabel
515  // (i.e. what was in pointsToStore)
516  void topoChange
517  (
518  const polyTopoChangeMap&,
519  const Map<label>& pointsToRestore,
520  const Map<label>& facesToRestore,
521  const Map<label>& cellsToRestore
522  );
523 
524 
525  //- Update local numbering for subsetted mesh.
526  // Gets new-to-old maps. Not compatible with unrefinement.
527  void subset
528  (
529  const labelList& pointMap,
530  const labelList& faceMap,
531  const labelList& cellMap
532  );
533 
534  //- Update local numbering for mesh redistribution
535  void distribute(const polyDistributionMap&);
536 
537  //- Debug: Check coupled mesh for correctness
538  void checkMesh() const;
539 
540  //- Debug: Check 2:1 consistency across faces.
541  // maxPointDiff==-1 : only check 2:1 across faces
542  // maxPointDiff!=-1 : check point-connected cells.
544  (
545  const label maxPointDiff,
546  const labelList& pointsToCheck
547  ) const;
548 
549  //- Utility: get hexes as cell shapes
550  const cellShapeList& cellShapes() const;
551 
552 
553  // Unrefinement (undoing refinement, not arbitrary coarsening)
554 
555  //- Return the points at the centre of top-level split cells
556  // that can be unsplit.
557  labelList getSplitPoints() const;
558 
559  //- Given proposed
560  // splitPoints to unrefine according to calculate any clashes
561  // (due to 2:1) and return ok list of points to unrefine.
562  // Either adds points to refine to set (maxSet = true) or
563  // removes points to refine (maxSet = false)
565  (
566  const labelList& pointsToUnrefine,
567  const bool maxSet
568  ) const;
569 
570  //- Remove some refinement. Needs to be supplied output of
571  // consistentUnrefinement. Only call if undoable set.
572  // All 8 pointCells of a split point will be combined into
573  // the lowest numbered cell of those 8.
574  void setUnrefinement
575  (
576  const labelList& splitPointLabels,
578  );
579 
580  // Write
581 
582  // Set instance for mesh files
583  void setInstance(const fileName& inst);
584 
585  //- Force writing refinement+history to polyMesh directory.
586  bool write(const bool write = true) const;
587 
588 
589  // Member Operators
590 
591  //- Disallow default bitwise assignment
592  void operator=(const hexRef8&) = delete;
593 };
594 
595 
596 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
597 
598 } // End namespace Foam
599 
600 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
601 
602 #endif
603 
604 // ************************************************************************* //
A bit-packed bool list.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
const Type & value() const
Return const reference to value.
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:76
A class for handling file names.
Definition: fileName.H:82
Refinement of (split) hexes using polyTopoChange.
Definition: hexRef8.H:65
void checkRefinementLevels(const label maxPointDiff, const labelList &pointsToCheck) const
Debug: Check 2:1 consistency across faces.
Definition: hexRef8.C:4756
labelList consistentSlowRefinement(const label maxFaceDiff, const labelList &cellsToRefine, const labelList &facesToCheck, const label maxPointDiff, const labelList &pointsToCheck) const
Like consistentRefinement but slower:
Definition: hexRef8.C:2289
hexRef8(const polyMesh &mesh, const bool readHistory=true)
Construct from mesh, read_if_present refinement data.
Definition: hexRef8.C:1894
void checkMesh() const
Debug: Check coupled mesh for correctness.
Definition: hexRef8.C:4546
scalar level0EdgeLength() const
Typical edge length between unrefined points.
Definition: hexRef8.H:419
labelListList setRefinement(const labelList &cells, polyTopoChange &)
Insert refinement. All selected cells will be split into 8.
Definition: hexRef8.C:3195
void topoChange(const polyTopoChangeMap &)
Update local numbering for changed mesh.
Definition: hexRef8.C:4237
void distribute(const polyDistributionMap &)
Update local numbering for mesh redistribution.
Definition: hexRef8.C:4517
void operator=(const hexRef8 &)=delete
Disallow default bitwise assignment.
const cellShapeList & cellShapes() const
Utility: get hexes as cell shapes.
Definition: hexRef8.C:5008
bool write(const bool write=true) const
Force writing refinement+history to polyMesh directory.
Definition: hexRef8.C:5632
void setUnrefinement(const labelList &splitPointLabels, polyTopoChange &)
Remove some refinement. Needs to be supplied output of.
Definition: hexRef8.C:5444
const refinementHistory & history() const
Definition: hexRef8.H:413
const labelIOList & cellLevel() const
Definition: hexRef8.H:403
const labelIOList & pointLevel() const
Definition: hexRef8.H:408
labelList consistentUnrefinement(const labelList &pointsToUnrefine, const bool maxSet) const
Given proposed.
Definition: hexRef8.C:5210
labelList getSplitPoints() const
Return the points at the centre of top-level split cells.
Definition: hexRef8.C:5068
label faceLevel(const label facei) const
Gets level such that the face has four points <= level.
Definition: hexRef8.C:780
void storeData(const labelList &pointsToStore, const labelList &facesToStore, const labelList &cellsToStore)
Signal points/face/cells for which to store data.
Definition: hexRef8.C:4215
labelList consistentRefinement(const labelList &cellsToRefine, const bool maxSet) const
Given valid mesh and current cell level and proposed.
Definition: hexRef8.C:2220
const polyMesh & mesh() const
Definition: hexRef8.H:398
ClassName("hexRef8")
Runtime type information.
labelList consistentSlowRefinement2(const label maxFaceDiff, const labelList &cellsToRefine, const labelList &facesToCheck) const
Like consistentSlowRefinement but uses different meshWave.
Definition: hexRef8.C:2773
void subset(const labelList &pointMap, const labelList &faceMap, const labelList &cellMap)
Update local numbering for subsetted mesh.
Definition: hexRef8.C:4435
void setInstance(const fileName &inst)
Definition: hexRef8.C:1700
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Direct mesh changes based on v1.3 polyTopoChange syntax.
Container with cells to refine. Refinement given as single direction.
Definition: refineCell.H:57
All refinement history. Used in unrefinement.
Given list of faces to remove insert all the topology changes. Contains helper function to get consis...
Definition: removeFaces.H:63
const pointField & points
const cellShapeList & cells
Namespace for OpenFOAM.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
labelList f(nPoints)