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-2024 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 index
109  label getPatchIndex(const label facei) const;
110 
111  //- Adds a face on top of existing facei. Reverses if necessary.
112  label addFace
113  (
114  polyTopoChange& meshMod,
115  const label facei,
116  const face& newFace,
117  const label own,
118  const label nei
119  ) const;
120 
121  //- Adds internal face from point. No checks on reversal.
122  // Adds an internal face from an edge. Assumes orientation correct.
123  // Problem is that the face is between four new vertices. So what do
124  // we provide as master? The only existing mesh item we have is the
125  // edge we have split. Have to be careful in only using it if it has
126  // internal faces since otherwise polyMeshMorph will complain (because
127  // it cannot generate a sensible mapping for the face)
128  label addInternalFace
129  (
130  polyTopoChange& meshMod,
131  const label meshFacei,
132  const label meshPointi,
133  const face& newFace,
134  const label own,
135  const label nei
136  ) const;
137 
138  //- Modifies existing facei for either new owner/neighbour or new face
139  // points. Reverses if necessary.
140  void modifyFace
141  (
142  polyTopoChange& meshMod,
143  const label facei,
144  const face& newFace,
145  const label own,
146  const label nei
147  ) const;
148 
149  //- Bit complex way to determine the unrefined edge length.
150  scalar getLevel0EdgeLength() const;
151 
152  //- Get cell added to point of celli (if any)
153  // Check whether pointi is an anchor on celli. If it is not check
154  // whether any other point on the face is an anchor cell.
155  label getAnchorCell
156  (
157  const labelListList& cellAnchorPoints,
158  const labelListList& cellAddedCells,
159  const label celli,
160  const label facei,
161  const label pointi
162  ) const;
163 
164  //- Get new owner and neighbour (in unspecified order) of pointi
165  // on facei.
166  void getFaceNeighbours
167  (
168  const labelListList& cellAnchorPoints,
169  const labelListList& cellAddedCells,
170  const label facei,
171  const label pointi,
172 
173  label& own,
174  label& nei
175  ) const;
176 
177 
178  //- Get index of minimum pointlevel.
179  label findMinLevel(const labelList& f) const;
180 
181  //- Get maximum pointlevel.
182  label findMaxLevel(const labelList& f) const;
183 
184  //- Count number of vertices <= anchorLevel
185  label countAnchors(const labelList&, const label) const;
186 
187  //- Debugging: dump cell as .obj file
188  void dumpCell(const label celli) const;
189 
190  //- Find index of point with wantedLevel, starting from fp.
191  label findLevel
192  (
193  const label facei,
194  const face& f,
195  const label startFp,
196  const bool searchForward,
197  const label wantedLevel
198  ) const;
199 
200  //- debug:check orientation of added internal face
201  static void checkInternalOrientation
202  (
203  polyTopoChange& meshMod,
204  const label celli,
205  const label facei,
206  const point& ownPt,
207  const point& neiPt,
208  const face& newFace
209  );
210 
211  //- debug:check orientation of new boundary face
212  static void checkBoundaryOrientation
213  (
214  polyTopoChange& meshMod,
215  const label celli,
216  const label facei,
217  const point& ownPt,
218  const point& boundaryPt,
219  const face& newFace
220  );
221 
222  //- If p0 and p1 are existing vertices check if edge is split and insert
223  // splitPoint.
224  void insertEdgeSplit
225  (
226  const labelList& edgeMidPoint,
227  const label p0,
228  const label p1,
229  DynamicList<label>& verts
230  ) const;
231 
232  //- Store in maps correspondence from midpoint to anchors and faces.
233  // Internal faces are one per edge between anchor points. So one per
234  // midPoint between the anchor points. Here we store the information on
235  // the midPoint and if we have enough information:
236  // - two anchors
237  // - two face mid points
238  // we add the face. Note that this routine can get called anywhere from
239  // two times (two unrefined faces) to four times (two refined faces) so
240  // the first call that adds the information creates the face.
241  label storeMidPointInfo
242  (
243  const labelListList& cellAnchorPoints,
244  const labelListList& cellAddedCells,
245  const labelList& cellMidPoint,
246  const labelList& edgeMidPoint,
247  const label celli,
248  const label facei,
249  const bool faceOrder,
250  const label midPointi,
251  const label anchorPointi,
252  const label faceMidPointi,
253 
254  Map<edge>& midPointToAnchors,
255  Map<edge>& midPointToFaceMids,
256  polyTopoChange& meshMod
257  ) const;
258 
259  //- Create all internal faces from an unsplit face.
260  void createInternalFromSplitFace
261  (
262  const labelListList& cellAnchorPoints,
263  const labelListList& cellAddedCells,
264  const labelList& cellMidPoint,
265  const labelList& faceMidPoint,
266  const labelList& edgeMidPoint,
267  const label celli,
268  const label facei,
269 
270  Map<edge>& midPointToAnchors,
271  Map<edge>& midPointToFaceMids,
272  polyTopoChange& meshMod,
273  label& nFacesAdded
274  ) const;
275 
276  //- Create all internal faces to split celli into 8.
277  void createInternalFaces
278  (
279  const labelListList& cellAnchorPoints,
280  const labelListList& cellAddedCells,
281  const labelList& cellMidPoint,
282  const labelList& faceMidPoint,
283  const labelList& faceAnchorLevel,
284  const labelList& edgeMidPoint,
285  const label celli,
286  polyTopoChange& meshMod
287  ) const;
288 
289  //- Store vertices from startFp up to face split point.
290  // Used when splitting face into 4.
291  void walkFaceToMid
292  (
293  const labelList& edgeMidPoint,
294  const label cLevel,
295  const label facei,
296  const label startFp,
297  DynamicList<label>& faceVerts
298  ) const;
299 
300  //- Same as walkFaceToMid but now walk back.
301  void walkFaceFromMid
302  (
303  const labelList& edgeMidPoint,
304  const label cLevel,
305  const label facei,
306  const label startFp,
307  DynamicList<label>& faceVerts
308  ) const;
309 
310  //- Updates refineCell so consistent 2:1 refinement. Returns local
311  // number of cells changed.
312  label faceConsistentRefinement
313  (
314  const bool maxSet,
316  ) const;
317 
318  //- Check wanted refinement for 2:1 consistency
319  void checkWantedRefinementLevels(const labelList&) const;
320 
321 
322  // Cellshape recognition
323 
324  //- Collect all points on face of certain level
325  void collectLevelPoints
326  (
327  const labelList& f,
328  const label level,
330  ) const;
331 
332  //- Collect all points on face (in local numbering) of certain level
333  void collectLevelPoints
334  (
335  const labelList& meshPoints,
336  const labelList& f,
337  const label level,
339  ) const;
340 
341  //- Collect all faces with four corner points and return true if
342  // hex was matched (6 faces of each four corner points)
343  bool matchHexShape
344  (
345  const label celli,
346  const label cellLevel,
347  DynamicList<face>& quads
348  ) const;
349 
350 
351 public:
352 
353  //- Runtime type information
354  ClassName("hexRef8");
355 
356 
357  // Constructors
358 
359  //- Construct from mesh, read_if_present refinement data
360  // (from write below). If readHistory is true does read_if_present
361  // of refinement history. If false clears all history
362  hexRef8(const polyMesh& mesh, const bool readHistory = true);
363 
364  //- Construct from mesh and un/refinement data and optional size of
365  // starting cells
366  hexRef8
367  (
368  const polyMesh& mesh,
369  const labelList& cellLevel,
370  const labelList& pointLevel,
371  const refinementHistory& history,
372  const scalar level0Edge = -great
373  );
374 
375  //- Construct from mesh and refinement data and optional size of
376  // starting cells
377  hexRef8
378  (
379  const polyMesh& mesh,
380  const labelList& cellLevel,
381  const labelList& pointLevel,
382  const scalar level0Edge = -great
383  );
384 
385  //- Disallow default bitwise copy construction
386  hexRef8(const hexRef8&) = delete;
387 
388 
389  // Member Functions
390 
391  // Access
392 
393  const polyMesh& mesh() const
394  {
395  return mesh_;
396  }
397 
398  const labelIOList& cellLevel() const
399  {
400  return cellLevel_;
401  }
402 
403  const labelIOList& pointLevel() const
404  {
405  return pointLevel_;
406  }
407 
408  const refinementHistory& history() const
409  {
410  return history_;
411  }
412 
413  //- Typical edge length between unrefined points
414  scalar level0EdgeLength() const
415  {
416  return level0Edge_.value();
417  }
418 
419  // Refinement
420 
421  //- Gets level such that the face has four points <= level.
422  label faceLevel(const label facei) const;
423 
424  //- Given valid mesh and current cell level and proposed
425  // cells to refine calculate any clashes (due to 2:1) and return
426  // ok list of cells to refine.
427  // Either adds cells to refine to set (maxSet = true) or
428  // removes cells to refine (maxSet = false)
430  (
431  const labelList& cellsToRefine,
432  const bool maxSet
433  ) const;
434 
435  //- Like consistentRefinement but slower:
436  //
437  // - specify number of cells between consecutive refinement levels
438  // (consistentRefinement equivalent to 1)
439  // - specify max level difference between point-connected cells.
440  // (-1 to disable) Note that with normal 2:1 limitation
441  // (maxFaceDiff=1) there can be 8:1 size difference across point
442  // connected cells so maxPointDiff allows you to make that less.
443  // cellsToRefine : cells we're thinking about refining. It will
444  // extend this set. All refinement levels will be
445  // at least maxFaceDiff layers thick.
446  // facesToCheck : additional faces where to implement the
447  // maxFaceDiff thickness (usually only boundary
448  // faces)
450  (
451  const label maxFaceDiff,
452  const labelList& cellsToRefine,
453  const labelList& facesToCheck,
454  const label maxPointDiff,
455  const labelList& pointsToCheck
456  ) const;
457 
458  //- Like consistentSlowRefinement but uses different meshWave
459  // (proper distance instead of toplogical count). No point checks
460  // yet.
462  (
463  const label maxFaceDiff,
464  const labelList& cellsToRefine,
465  const labelList& facesToCheck
466  ) const;
467 
468  //- Insert refinement. All selected cells will be split into 8.
469  // Returns per element in cells the 8 cells they were split into.
470  // Guarantees that the 0th element is the original cell label.
471  // Mapping:
472  // -split cells: 7 new ones get added from original
473  // -split faces: original gets modified; 3 new ones get added
474  // from original
475  // -added internal faces: added from original cell face(if
476  // that was internal) or created out-of-nothing (so will not
477  // get mapped!).
478  // -points added to split edge: added from edge start()
479  // -midpoints added: added from cellPoints[0].
481  (
482  const labelList& cells,
484  );
485 
486  //- Update local numbering for changed mesh.
487  // Called after the mesh change. setRefinement will already have
488  // made sure the pointLevel_ and cellLevel_ are the size of the new
489  // mesh so we only need to account for reordering.
490  void topoChange(const polyTopoChangeMap&);
491 
492 
493  // Restoring : is where other processes delete and reinsert data.
494  // These callbacks allow this to restore the cellLevel
495  // and pointLevel for reintroduced points.
496  // Is not related to undoing my refinement
497 
498  //- Signal points/face/cells for which to store data
499  void storeData
500  (
501  const labelList& pointsToStore,
502  const labelList& facesToStore,
503  const labelList& cellsToStore
504  );
505 
506  //- Update local numbering + undo
507  // Data to restore given as new pointlabel + stored pointlabel
508  // (i.e. what was in pointsToStore)
509  void topoChange
510  (
511  const polyTopoChangeMap&,
512  const Map<label>& pointsToRestore,
513  const Map<label>& facesToRestore,
514  const Map<label>& cellsToRestore
515  );
516 
517 
518  //- Update local numbering for subsetted mesh.
519  // Gets new-to-old maps. Not compatible with unrefinement.
520  void subset
521  (
522  const labelList& pointMap,
523  const labelList& faceMap,
524  const labelList& cellMap
525  );
526 
527  //- Update local numbering for mesh redistribution
528  void distribute(const polyDistributionMap&);
529 
530  //- Debug: Check coupled mesh for correctness
531  void checkMesh() const;
532 
533  //- Debug: Check 2:1 consistency across faces.
534  // maxPointDiff==-1 : only check 2:1 across faces
535  // maxPointDiff!=-1 : check point-connected cells.
537  (
538  const label maxPointDiff,
539  const labelList& pointsToCheck
540  ) const;
541 
542  //- Utility: get hexes as cell shapes
543  const cellShapeList& cellShapes() const;
544 
545 
546  // Unrefinement (undoing refinement, not arbitrary coarsening)
547 
548  //- Return the points at the centre of top-level split cells
549  // that can be unsplit.
550  labelList getSplitPoints() const;
551 
552  //- Given proposed
553  // splitPoints to unrefine according to calculate any clashes
554  // (due to 2:1) and return ok list of points to unrefine.
555  // Either adds points to refine to set (maxSet = true) or
556  // removes points to refine (maxSet = false)
558  (
559  const labelList& pointsToUnrefine,
560  const bool maxSet
561  ) const;
562 
563  //- Remove some refinement. Needs to be supplied output of
564  // consistentUnrefinement. Only call if undoable set.
565  // All 8 pointCells of a split point will be combined into
566  // the lowest numbered cell of those 8.
567  void setUnrefinement
568  (
569  const labelList& splitPointLabels,
571  );
572 
573  // Write
574 
575  // Set instance for mesh files
576  void setInstance(const fileName& inst);
577 
578  //- Force writing refinement+history to polyMesh directory.
579  bool write(const bool write = true) const;
580 
581 
582  // Member Operators
583 
584  //- Disallow default bitwise assignment
585  void operator=(const hexRef8&) = delete;
586 };
587 
588 
589 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
590 
591 } // End namespace Foam
592 
593 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
594 
595 #endif
596 
597 // ************************************************************************* //
A bit-packed bool list.
Type & value()
Return a reference to the value.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
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:4596
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:2184
hexRef8(const polyMesh &mesh, const bool readHistory=true)
Construct from mesh, read_if_present refinement data.
Definition: hexRef8.C:1789
void checkMesh() const
Debug: Check coupled mesh for correctness.
Definition: hexRef8.C:4386
scalar level0EdgeLength() const
Typical edge length between unrefined points.
Definition: hexRef8.H:413
labelListList setRefinement(const labelList &cells, polyTopoChange &)
Insert refinement. All selected cells will be split into 8.
Definition: hexRef8.C:3090
void topoChange(const polyTopoChangeMap &)
Update local numbering for changed mesh.
Definition: hexRef8.C:4108
void distribute(const polyDistributionMap &)
Update local numbering for mesh redistribution.
Definition: hexRef8.C:4357
void operator=(const hexRef8 &)=delete
Disallow default bitwise assignment.
const cellShapeList & cellShapes() const
Utility: get hexes as cell shapes.
Definition: hexRef8.C:4848
bool write(const bool write=true) const
Force writing refinement+history to polyMesh directory.
Definition: hexRef8.C:5472
void setUnrefinement(const labelList &splitPointLabels, polyTopoChange &)
Remove some refinement. Needs to be supplied output of.
Definition: hexRef8.C:5284
const refinementHistory & history() const
Definition: hexRef8.H:407
const labelIOList & cellLevel() const
Definition: hexRef8.H:397
const labelIOList & pointLevel() const
Definition: hexRef8.H:402
labelList consistentUnrefinement(const labelList &pointsToUnrefine, const bool maxSet) const
Given proposed.
Definition: hexRef8.C:5050
labelList getSplitPoints() const
Return the points at the centre of top-level split cells.
Definition: hexRef8.C:4908
label faceLevel(const label facei) const
Gets level such that the face has four points <= level.
Definition: hexRef8.C:675
void storeData(const labelList &pointsToStore, const labelList &facesToStore, const labelList &cellsToStore)
Signal points/face/cells for which to store data.
Definition: hexRef8.C:4086
labelList consistentRefinement(const labelList &cellsToRefine, const bool maxSet) const
Given valid mesh and current cell level and proposed.
Definition: hexRef8.C:2115
const polyMesh & mesh() const
Definition: hexRef8.H:392
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:2668
void subset(const labelList &pointMap, const labelList &faceMap, const labelList &cellMap)
Update local numbering for subsetted mesh.
Definition: hexRef8.C:4275
void setInstance(const fileName &inst)
Definition: hexRef8.C:1595
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)