hexMatcher.C
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-2016 OpenFOAM Foundation
9  Copyright (C) 2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "hexMatcher.H"
30 #include "primitiveMesh.H"
31 #include "ListOps.H"
32 
33 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37 
38 // Check (6 quad)
39 static inline bool checkFaceSizeMatch(const UList<face>& faces)
40 {
41  if (faces.size() != 6) // facePerCell
42  {
43  return false;
44  }
45 
46  for (const face& f : faces)
47  {
48  if (f.size() != 4) // quad
49  {
50  return false;
51  }
52  }
53 
54  return true;
55 }
56 
57 
58 // Check (6 quad)
59 static inline bool checkFaceSizeMatch
60 (
61  const UList<face>& meshFaces,
62  const labelUList& cellFaces
63 )
64 {
65  if (cellFaces.size() != 6) // facePerCell
66  {
67  return false;
68  }
69 
70  for (const label facei : cellFaces)
71  {
72  if (meshFaces[facei].size() != 4) // quad
73  {
74  return false;
75  }
76  }
77 
78  return true;
79 }
80 
81 
82 } // End namespace Foam
83 
84 
85 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
86 
88 {
89  return checkFaceSizeMatch(faces);
90 }
91 
92 bool Foam::hexMatcher::test(const primitiveMesh& mesh, const label celli)
93 {
94  return checkFaceSizeMatch(mesh.faces(), mesh.cells()[celli]);
95 }
96 
97 
98 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
99 
101 :
103  (
104  vertPerCell,
105  facePerCell,
106  maxVertPerFace,
107  "hex" // == cellModel::modelNames[cellModel::HEX]
108  )
109 {}
110 
111 
112 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
113 
115 (
116  const bool checkOnly,
117  const faceList& faces,
118  const labelList& owner,
119  const label celli,
120  const labelList& myFaces
121 )
122 {
123  if (!faceSizeMatch(faces, myFaces))
124  {
125  return false;
126  }
127 
128  // Is hex for sure since all faces are quads
129 
130  if (checkOnly)
131  {
132  return true;
133  }
134 
135  // Calculate localFaces_ and mapping pointMap_, faceMap_
136  label numVert = calcLocalFaces(faces, myFaces);
137 
138  if (numVert != vertPerCell)
139  {
140  return false;
141  }
142 
143  // Set up 'edge' to face mapping.
144  calcEdgeAddressing(numVert);
145 
146  // Set up point on face to index-in-face mapping
147  calcPointFaceIndex();
148 
149  // Storage for maps -vertex to mesh and -face to mesh
150  vertLabels_.setSize(vertPerCell);
151  faceLabels_.setSize(facePerCell);
152 
153  //
154  // Try bottom face (face 4).
155  // Only need to try one orientation of this face since hex is
156  // rotation symmetric
157  //
158 
159  label face4I = 0;
160 
161  const face& face4 = localFaces_[face4I];
162  label face4vert0 = 0;
163 
164  vertLabels_[0] = pointMap_[face4[face4vert0]];
165  faceLabels_[4] = faceMap_[face4I];
166 
167  // Walk face 4 from vertex 0 to 1
168  label face4vert1 =
169  nextVert
170  (
171  face4vert0,
172  faceSize_[face4I],
173  !(owner[faceMap_[face4I]] == celli)
174  );
175  vertLabels_[1] = pointMap_[face4[face4vert1]];
176 
177  // Walk face 4 from vertex 1 to 2
178  label face4vert2 =
179  nextVert
180  (
181  face4vert1,
182  faceSize_[face4I],
183  !(owner[faceMap_[face4I]] == celli)
184  );
185  vertLabels_[2] = pointMap_[face4[face4vert2]];
186 
187  // Walk face 4 from vertex 2 to 3
188  label face4vert3 =
189  nextVert
190  (
191  face4vert2,
192  faceSize_[face4I],
193  !(owner[faceMap_[face4I]] == celli)
194  );
195  vertLabels_[3] = pointMap_[face4[face4vert3]];
196 
197  // Jump edge from face4 to face0
198  label face0I =
199  otherFace
200  (
201  numVert,
202  face4[face4vert3],
203  face4[face4vert0],
204  face4I
205  );
206  faceLabels_[0] = faceMap_[face0I];
207  const face& face0 = localFaces_[face0I];
208 
209  label face0vert0 = pointFaceIndex_[face4[face4vert0]][face0I];
210 
211  // Walk face 0 from vertex 0 to 4
212  label face0vert4 =
213  nextVert
214  (
215  face0vert0,
216  faceSize_[face0I],
217  (owner[faceMap_[face0I]] == celli)
218  );
219  vertLabels_[4] = pointMap_[face0[face0vert4]];
220 
221  // Walk face 0 from vertex 4 to 7
222  label face0vert7 =
223  nextVert
224  (
225  face0vert4,
226  faceSize_[face0I],
227  (owner[faceMap_[face0I]] == celli)
228  );
229  vertLabels_[7] = pointMap_[face0[face0vert7]];
230 
231  // Jump edge from face0 to face5
232  label face5I =
233  otherFace
234  (
235  numVert,
236  face0[face0vert4],
237  face0[face0vert7],
238  face0I
239  );
240  const face& face5 = localFaces_[face5I];
241  faceLabels_[5] = faceMap_[face5I];
242 
243  label face5vert4 = pointFaceIndex_[face0[face0vert4]][face5I];
244 
245  // Walk face 5 from vertex 4 to 5
246  label face5vert5 =
247  nextVert
248  (
249  face5vert4,
250  faceSize_[face5I],
251  (owner[faceMap_[face5I]] == celli)
252  );
253  vertLabels_[5] = pointMap_[face5[face5vert5]];
254 
255  // Walk face 5 from vertex 5 to 6
256  label face5vert6 =
257  nextVert
258  (
259  face5vert5,
260  faceSize_[face5I],
261  (owner[faceMap_[face5I]] == celli)
262  );
263  vertLabels_[6] = pointMap_[face5[face5vert6]];
264 
265  // Jump edge from face4 to face2
266  label face2I =
267  otherFace
268  (
269  numVert,
270  face4[face4vert0],
271  face4[face4vert1],
272  face4I
273  );
274  faceLabels_[2] = faceMap_[face2I];
275 
276  // Jump edge from face4 to face1
277  label face1I =
278  otherFace
279  (
280  numVert,
281  face4[face4vert1],
282  face4[face4vert2],
283  face4I
284  );
285  faceLabels_[1] = faceMap_[face1I];
286 
287  // Jump edge from face4 to face3
288  label face3I =
289  otherFace
290  (
291  numVert,
292  face4[face4vert2],
293  face4[face4vert3],
294  face4I
295  );
296  faceLabels_[3] = faceMap_[face3I];
297 
298  return true;
299 }
300 
301 
303 {
304  return facePerCell*vertPerCell;
305 }
306 
307 
309 (
310  const faceList& meshFaces,
311  const labelList& cellFaces
312 ) const
313 {
314  return checkFaceSizeMatch(meshFaces, cellFaces);
315 }
316 
317 
319 (
320  const primitiveMesh& mesh,
321  const label celli,
322  cellShape& shape
323 )
324 {
325  if
326  (
327  matchShape
328  (
329  false,
330  mesh.faces(),
331  mesh.faceOwner(),
332  celli,
333  mesh.cells()[celli]
334  )
335  )
336  {
337  shape.reset(model(), vertLabels());
338  return true;
339  }
340 
341  return false;
342 }
343 
344 
345 // ************************************************************************* //
Foam::hexMatcher::faceSizeMatch
virtual bool faceSizeMatch(const faceList &, const labelList &) const
Check whether number of face sizes match the shape.
Definition: hexMatcher.C:309
Foam::meshTools::otherFace
label otherFace(const primitiveMesh &mesh, const label celli, const label facei, const label edgeI)
Return face on cell using edgeI but not facei. Throws error.
Definition: meshTools.C:555
Foam::checkFaceSizeMatch
static bool checkFaceSizeMatch(const UList< face > &faces)
Definition: hexMatcher.C:39
hexMatcher.H
Foam::primitiveMesh::cells
const cellList & cells() const
Definition: primitiveMeshCells.C:138
Foam::hexMatcher::test
static bool test(const UList< face > &faces)
Definition: hexMatcher.C:87
primitiveMesh.H
Foam::hexMatcher::matchShape
virtual bool matchShape(const bool checkOnly, const faceList &faces, const labelList &faceOwner, const label celli, const labelList &myFaces)
Low level shape recognition. Return true if matches.
Definition: hexMatcher.C:115
Foam::cellMatcher
Base class for cellshape matchers (hexMatch, prismMatch, etc.). These are classes which given a mesh ...
Definition: cellMatcher.H:99
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1107
Foam::hexMatcher::matches
virtual bool matches(const primitiveMesh &mesh, const label celli, cellShape &shape)
Like isA but also constructs a cellShape (if shape matches)
Definition: hexMatcher.C:319
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::cellShape
An analytical geometric cellShape.
Definition: cellShape.H:69
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::cellShape::reset
void reset(const cellModel &model, const labelUList &labels, const bool doCollapse=false)
Reset from components.
Definition: cellShapeI.H:300
Foam::hexMatcher::faceHashValue
virtual label faceHashValue() const
Hash value of all face sizes of this shape. Can be used for.
Definition: hexMatcher.C:302
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
f
labelList f(nPoints)
Foam::List< face >
Foam::UList< face >
Foam::hexMatcher::hexMatcher
hexMatcher()
Default construct.
Definition: hexMatcher.C:100
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:72
ListOps.H
Various functions to operate on Lists.
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::primitiveMesh
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:78