pyrMatcher.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 "pyrMatcher.H"
30 #include "cellMatcher.H"
31 #include "primitiveMesh.H"
32 #include "cellModel.H"
33 #include "ListOps.H"
34 
35 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 
40 // Check (4 tri, 1 quad)
41 static inline bool checkFaceSizeMatch(const UList<face>& faces)
42 {
43  if (faces.size() != 5) // facePerCell
44  {
45  return false;
46  }
47 
48  int nTris = 0;
49  int nQuads = 0;
50 
51  for (const face& f : faces)
52  {
53  const label size = f.size();
54 
55  if (size == 3)
56  {
57  ++nTris;
58  }
59  else if (size == 4)
60  {
61  ++nQuads;
62  }
63  else
64  {
65  return false;
66  }
67  }
68 
69  return (nTris == 4 && nQuads == 1);
70 }
71 
72 
73 // Check (4 tri, 1 quad)
74 static inline bool checkFaceSizeMatch
75 (
76  const UList<face>& meshFaces,
77  const labelUList& cellFaces
78 )
79 {
80  if (cellFaces.size() != 5) // facePerCell
81  {
82  return false;
83  }
84 
85  int nTris = 0;
86  int nQuads = 0;
87 
88  for (const label facei : cellFaces)
89  {
90  const label size = meshFaces[facei].size();
91 
92  if (size == 3)
93  {
94  ++nTris;
95  }
96  else if (size == 4)
97  {
98  ++nQuads;
99  }
100  else
101  {
102  return false;
103  }
104  }
105 
106  return (nTris == 4 && nQuads == 1);
107 }
108 
109 } // End namespace Foam
110 
111 
112 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
113 
115 {
116  return checkFaceSizeMatch(faces);
117 }
118 
119 bool Foam::pyrMatcher::test(const primitiveMesh& mesh, const label celli)
120 {
121  return checkFaceSizeMatch(mesh.faces(), mesh.cells()[celli]);
122 }
123 
124 
125 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
126 
128 :
130  (
131  vertPerCell,
132  facePerCell,
133  maxVertPerFace,
134  "pyr" // == cellModel::modelNames[cellModel::PYR]
135  )
136 {}
137 
138 
139 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
140 
142 (
143  const bool checkOnly,
144  const faceList& faces,
145  const labelList& owner,
146  const label celli,
147  const labelList& myFaces
148 )
149 {
150  if (!faceSizeMatch(faces, myFaces))
151  {
152  return false;
153  }
154 
155  // Is pyr for sure since no other shape with 1 quad, 4 triangles
156  if (checkOnly)
157  {
158  return true;
159  }
160 
161  // Calculate localFaces_ and mapping pointMap_, faceMap_
162  label numVert = calcLocalFaces(faces, myFaces);
163 
164  if (numVert != vertPerCell)
165  {
166  return false;
167  }
168 
169  // Set up 'edge' to face mapping.
170  calcEdgeAddressing(numVert);
171 
172  // Set up point on face to index-in-face mapping
173  calcPointFaceIndex();
174 
175  // Storage for maps -vertex to mesh and -face to mesh
176  vertLabels_.setSize(vertPerCell);
177  faceLabels_.setSize(facePerCell);
178 
179  //
180  // Start from quad face (face0)
181  //
182 
183  label face0I = -1;
184  forAll(faceSize_, facei)
185  {
186  if (faceSize_[facei] == 4)
187  {
188  face0I = facei;
189  break;
190  }
191  }
192  const face& face0 = localFaces_[face0I];
193  label face0vert0 = 0;
194 
195 
196  //
197  // Try to follow prespecified path on faces of cell,
198  // starting at face0vert0
199  //
200 
201  vertLabels_[0] = pointMap_[face0[face0vert0]];
202  faceLabels_[0] = faceMap_[face0I];
203 
204  // Walk face 0 from vertex 0 to 1
205  label face0vert1 =
206  nextVert
207  (
208  face0vert0,
209  faceSize_[face0I],
210  !(owner[faceMap_[face0I]] == celli)
211  );
212  vertLabels_[1] = pointMap_[face0[face0vert1]];
213 
214  // Walk face 0 from vertex 1 to 2
215  label face0vert2 =
216  nextVert
217  (
218  face0vert1,
219  faceSize_[face0I],
220  !(owner[faceMap_[face0I]] == celli)
221  );
222  vertLabels_[2] = pointMap_[face0[face0vert2]];
223 
224  // Walk face 0 from vertex 2 to 3
225  label face0vert3 =
226  nextVert
227  (
228  face0vert2,
229  faceSize_[face0I],
230  !(owner[faceMap_[face0I]] == celli)
231  );
232  vertLabels_[3] = pointMap_[face0[face0vert3]];
233 
234  // Jump edge from face0 to face1
235  label face1I =
236  otherFace
237  (
238  numVert,
239  face0[face0vert3],
240  face0[face0vert0],
241  face0I
242  );
243  faceLabels_[1] = faceMap_[face1I];
244 
245  // Jump edge from face0 to face2
246  label face2I =
247  otherFace
248  (
249  numVert,
250  face0[face0vert2],
251  face0[face0vert3],
252  face0I
253  );
254  faceLabels_[2] = faceMap_[face2I];
255 
256  // Jump edge from face0 to face3
257  label face3I =
258  otherFace
259  (
260  numVert,
261  face0[face0vert1],
262  face0[face0vert2],
263  face0I
264  );
265  faceLabels_[3] = faceMap_[face3I];
266 
267  // Jump edge from face0 to face4
268  label face4I =
269  otherFace
270  (
271  numVert,
272  face0[face0vert0],
273  face0[face0vert1],
274  face0I
275  );
276  faceLabels_[4] = faceMap_[face4I];
277 
278  const face& face4 = localFaces_[face4I];
279 
280  // Get index of vert0 in face 4
281  label face4vert0 = pointFaceIndex_[face0[face0vert0]][face4I];
282 
283  // Walk face 4 from vertex 0 to 4
284  label face4vert4 =
285  nextVert
286  (
287  face4vert0,
288  faceSize_[face4I],
289  !(owner[faceMap_[face4I]] == celli)
290  );
291  vertLabels_[4] = pointMap_[face4[face4vert4]];
292 
293  return true;
294 }
295 
296 
298 {
299  return 4*3+4;
300 }
301 
302 
304 (
305  const faceList& meshFaces,
306  const labelList& cellFaces
307 ) const
308 {
309  return checkFaceSizeMatch(meshFaces, cellFaces);
310 }
311 
312 
314 (
315  const primitiveMesh& mesh,
316  const label celli,
317  cellShape& shape
318 )
319 {
320  if
321  (
322  matchShape
323  (
324  false,
325  mesh.faces(),
326  mesh.faceOwner(),
327  celli,
328  mesh.cells()[celli]
329  )
330  )
331  {
332  shape.reset(model(), vertLabels());
333  return true;
334  }
335 
336  return false;
337 }
338 
339 
340 // ************************************************************************* //
Foam::pyrMatcher::faceHashValue
virtual label faceHashValue() const
Hash value of all face sizes of this shape. Can be used for.
Definition: pyrMatcher.C:297
Foam::pyrMatcher::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: pyrMatcher.C:142
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
Foam::primitiveMesh::cells
const cellList & cells() const
Definition: primitiveMeshCells.C:138
primitiveMesh.H
Foam::cellMatcher
Base class for cellshape matchers (hexMatch, prismMatch, etc.). These are classes which given a mesh ...
Definition: cellMatcher.H:99
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::pyrMatcher::matches
virtual bool matches(const primitiveMesh &mesh, const label celli, cellShape &shape)
Like isA but also constructs a cellShape (if shape matches)
Definition: pyrMatcher.C:314
cellModel.H
Foam::pyrMatcher::faceSizeMatch
virtual bool faceSizeMatch(const faceList &, const labelList &) const
Check whether number of face sizes match the shape.
Definition: pyrMatcher.C:304
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1107
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::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
f
labelList f(nPoints)
Foam::List< face >
cellMatcher.H
Foam::UList< face >
Foam::pyrMatcher::pyrMatcher
pyrMatcher()
Default construct.
Definition: pyrMatcher.C:127
Foam::pyrMatcher::test
static bool test(const UList< face > &faces)
Definition: pyrMatcher.C:114
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
pyrMatcher.H
Foam::primitiveMesh
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:78