wedgeMatcher.C
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-2018 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 \*---------------------------------------------------------------------------*/
25 
26 #include "wedgeMatcher.H"
27 #include "primitiveMesh.H"
28 #include "ListOps.H"
29 
30 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
31 
32 const Foam::label Foam::wedgeMatcher::vertPerCell = 7;
33 const Foam::label Foam::wedgeMatcher::facePerCell = 6;
34 const Foam::label Foam::wedgeMatcher::maxVertPerFace = 4;
35 
36 
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 
40 :
42  (
43  vertPerCell,
44  facePerCell,
45  maxVertPerFace,
46  "wedge"
47  )
48 {}
49 
50 
51 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
52 
54 {}
55 
56 
57 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
58 
60 (
61  const bool checkOnly,
62  const faceList& faces,
63  const labelList& owner,
64  const label celli,
65  const labelList& myFaces
66 )
67 {
68  if (!faceSizeMatch(faces, myFaces))
69  {
70  return false;
71  }
72 
73  // Calculate localFaces_ and mapping pointMap_, faceMap_
74  label numVert = calcLocalFaces(faces, myFaces);
75 
76  if (numVert != vertPerCell)
77  {
78  return false;
79  }
80 
81  // Set up 'edge' to face mapping.
82  calcEdgeAddressing(numVert);
83 
84  // Set up point on face to index-in-face mapping
86 
87  // Storage for maps -vertex to mesh and -face to mesh
88  vertLabels_.setSize(vertPerCell);
89  faceLabels_.setSize(facePerCell);
90 
91  //
92  // Try first triangular face. Rotate in all directions.
93  // Walk path to other triangular face.
94  //
95 
96  label face0I = -1;
97  forAll(faceSize_, facei)
98  {
99  if (faceSize_[facei] == 3)
100  {
101  face0I = facei;
102  break;
103  }
104  }
105 
106  const face& face0 = localFaces_[face0I];
107 
108  // Try all rotations of this face
109  for (label face0vert0 = 0; face0vert0 < faceSize_[face0I]; face0vert0++)
110  {
111  //
112  // Try to follow prespecified path on faces of cell,
113  // starting at face0vert0
114  //
115 
116  vertLabels_[0] = pointMap_[face0[face0vert0]];
117  faceLabels_[0] = faceMap_[face0I];
118  // Info<< endl << "Wedge vertex 0: vertex " << face0[face0vert0]
119  // << " at position " << face0vert0 << " in face " << face0
120  // << endl;
121 
122  // Walk face 0 from vertex 0 to 1
123  label face0vert1 =
124  nextVert
125  (
126  face0vert0,
127  faceSize_[face0I],
128  !(owner[faceMap_[face0I]] == celli)
129  );
130  vertLabels_[1] = pointMap_[face0[face0vert1]];
131  // Info<< "Wedge vertex 1: vertex " << face0[face0vert1]
132  // << " at position " << face0vert1 << " in face " << face0
133  // << endl;
134 
135  // Jump edge from face0 to face4
136  label face4I =
137  otherFace
138  (
139  numVert,
140  face0[face0vert0],
141  face0[face0vert1],
142  face0I
143  );
144  const face& face4 = localFaces_[face4I];
145  // Info<< "Stepped to wedge face 4 " << face4
146  // << " across edge " << face0[face0vert0] << " "
147  // << face0[face0vert1]
148  // << endl;
149 
150  if (faceSize_[face4I] != 4)
151  {
152  // Info<< "Cannot be Wedge Face 4 since size="
153  // << faceSize_[face4I] << endl;
154  continue;
155  }
156 
157  // Is wedge for sure now
158  if (checkOnly)
159  {
160  return true;
161  }
162 
163  faceLabels_[4] = faceMap_[face4I];
164 
165  // Get index of vertex 0 in face4
166  label face4vert0 = pointFaceIndex_[face0[face0vert0]][face4I];
167 
168  // Info<< "Wedge vertex 0 also: vertex " << face4[face4vert0]
169  // << " at position " << face4vert0 << " in face " << face4
170  // << endl;
171 
172  // Walk face 4 from vertex 4 to 3
173  label face4vert3 =
174  nextVert
175  (
176  face4vert0,
177  faceSize_[face4I],
178  !(owner[faceMap_[face4I]] == celli)
179  );
180  vertLabels_[3] = pointMap_[face4[face4vert3]];
181  // Info<< "Wedge vertex 3: vertex " << face4[face4vert3]
182  // << " at position " << face4vert3 << " in face " << face4
183  // << endl;
184 
185 
186  // Jump edge from face4 to face2
187  label face2I =
188  otherFace
189  (
190  numVert,
191  face4[face4vert0],
192  face4[face4vert3],
193  face4I
194  );
195  const face& face2 = localFaces_[face2I];
196  // Info<< "Stepped to wedge face 2 " << face2
197  // << " across edge " << face4[face4vert0] << " "
198  // << face4[face4vert3]
199  // << endl;
200 
201  if (faceSize_[face2I] != 3)
202  {
203  // Info<< "Cannot be Wedge Face 2 since size="
204  // << faceSize_[face2I] << endl;
205  continue;
206  }
207  faceLabels_[2] = faceMap_[face2I];
208 
209  // Is wedge for sure now
210  // Info<< "** WEDGE **" << endl;
211 
212 
213  //
214  // Walk to other faces and vertices and assign mapping.
215  //
216 
217  // Vertex 6
218  label face2vert3 = pointFaceIndex_[face4[face4vert3]][face2I];
219 
220  // Walk face 2 from vertex 3 to 6
221  label face2vert6 =
222  nextVert
223  (
224  face2vert3,
225  faceSize_[face2I],
226  (owner[faceMap_[face2I]] == celli)
227  );
228  vertLabels_[6] = pointMap_[face2[face2vert6]];
229 
230  // Jump edge from face2 to face1
231  label face1I =
232  otherFace
233  (
234  numVert,
235  face2[face2vert3],
236  face2[face2vert6],
237  face2I
238  );
239  faceLabels_[1] = faceMap_[face1I];
240  const face& face1 = localFaces_[face1I];
241  // Info<< "Stepped to wedge face 1 " << face1
242  // << " across edge " << face2[face2vert3] << " "
243  // << face2[face2vert6]
244  // << endl;
245 
246  label face1vert6 = pointFaceIndex_[face2[face2vert6]][face1I];
247 
248  // Walk face 1 from vertex 6 to 5
249  label face1vert5 =
250  nextVert
251  (
252  face1vert6,
253  faceSize_[face1I],
254  !(owner[faceMap_[face1I]] == celli)
255  );
256  vertLabels_[5] = pointMap_[face1[face1vert5]];
257 
258  // Walk face 1 from vertex 5 to 4
259  label face1vert4 =
260  nextVert
261  (
262  face1vert5,
263  faceSize_[face1I],
264  !(owner[faceMap_[face1I]] == celli)
265  );
266  vertLabels_[4] = pointMap_[face1[face1vert4]];
267 
268  // Walk face 0 from vertex 1 to 2
269  label face0vert2 =
270  nextVert
271  (
272  face0vert1,
273  faceSize_[face0I],
274  !(owner[faceMap_[face0I]] == celli)
275  );
276  vertLabels_[2] = pointMap_[face0[face0vert2]];
277  // Info<< "Wedge vertex 2: vertex " << face0[face0vert2]
278  // << " at position " << face0vert2 << " in face " << face0
279  // << endl;
280 
281  // Jump edge from face0 to face3
282  label face3I =
283  otherFace
284  (
285  numVert,
286  face0[face0vert1],
287  face0[face0vert2],
288  face0I
289  );
290  faceLabels_[3] = faceMap_[face3I];
291  // const face& face3 = localFaces_[face3I];
292  // Info<< "Stepped to wedge face 3 " << face3
293  // << " across edge " << face0[face0vert1] << " "
294  // << face0[face0vert2]
295  // << endl;
296 
297 
298  // Jump edge from face0 to face5
299  label face5I =
300  otherFace
301  (
302  numVert,
303  face0[face0vert2],
304  face0[face0vert0],
305  face0I
306  );
307  faceLabels_[5] = faceMap_[face5I];
308  // const face& face5 = localFaces_[face5I];
309  // Info<< "Stepped to wedge face 5 " << face5
310  // << " across edge " << face0[face0vert2] << " "
311  // << face0[face0vert0]
312  // << endl;
313 
314  return true;
315  }
316 
317  // Tried all triangular faces, in all rotations but no match found
318  return false;
319 }
320 
321 
323 {
324  return 2*3 + 4*4;
325 }
326 
327 
329 (
330  const faceList& faces,
331  const labelList& myFaces
332 ) const
333 {
334  if (myFaces.size() != 6)
335  {
336  return false;
337  }
338 
339  label nTris = 0;
340  label nQuads = 0;
341 
342  forAll(myFaces, myFacei)
343  {
344  label size = faces[myFaces[myFacei]].size();
345 
346  if (size == 3)
347  {
348  nTris++;
349  }
350  else if (size == 4)
351  {
352  nQuads++;
353  }
354  else
355  {
356  return false;
357  }
358  }
359  if ((nTris == 2) && (nQuads == 4))
360  {
361  return true;
362  }
363  else
364  {
365  return false;
366  }
367 }
368 
369 
370 bool Foam::wedgeMatcher::isA(const primitiveMesh& mesh, const label celli)
371 {
372  return matchShape
373  (
374  true,
375  mesh.faces(),
376  mesh.faceOwner(),
377  celli,
378  mesh.cells()[celli]
379  );
380 }
381 
382 
384 {
385  // Do as if mesh with one cell only
386  return matchShape
387  (
388  true,
389  faces, // all faces in mesh
390  labelList(faces.size(), 0), // cell 0 is owner of all faces
391  0, // cell label
392  identity(faces.size()) // faces of cell 0
393  );
394 }
395 
396 
398 (
399  const primitiveMesh& mesh,
400  const label celli,
401  cellShape& shape
402 )
403 {
404  if
405  (
406  matchShape
407  (
408  false,
409  mesh.faces(),
410  mesh.faceOwner(),
411  celli,
412  mesh.cells()[celli]
413  )
414  )
415  {
416  shape = cellShape(model(), vertLabels());
417 
418  return true;
419  }
420  else
421  {
422  return false;
423  }
424 }
425 
426 
427 // ************************************************************************* //
const labelList & vertLabels() const
Definition: cellMatcherI.H:74
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Base class for cellshape matchers (hexMatch, prismMatch, etc.). These are classes which given a mesh ...
Definition: cellMatcher.H:99
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:74
labelList faceMap_
Map from local to mesh face numbering.
Definition: cellMatcher.H:132
An analytical geometric cellShape.
Definition: cellShape.H:69
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
const cellList & cells() const
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: wedgeMatcher.C:60
void calcEdgeAddressing(const label numVert)
Fill edge (start, end) to face number.
Definition: cellMatcher.C:138
labelList vertLabels_
After matching: holds mesh vertices in cellmodel order.
Definition: cellMatcher.H:142
labelListList pointFaceIndex_
pointFaceIndex[localVertI][localFacei] is index in localFace
Definition: cellMatcher.H:139
wedgeMatcher()
Construct null.
Definition: wedgeMatcher.C:39
Various functions to operate on Lists.
void calcPointFaceIndex()
Fill vertex/face to index in face data structure.
Definition: cellMatcher.C:187
~wedgeMatcher()
Destructor.
Definition: wedgeMatcher.C:53
label calcLocalFaces(const faceList &faces, const labelList &myFaces)
Calculates localFaces. Returns number of local vertices (or -1.
Definition: cellMatcher.C:74
labelList faceSize_
Number of vertices per face in localFaces_.
Definition: cellMatcher.H:126
List< label > labelList
A List of labels.
Definition: labelList.H:56
virtual label faceHashValue() const
Hash value of all face sizes of this shape. Can be used for.
Definition: wedgeMatcher.C:322
labelList faceLabels_
After matching: holds mesh faces in cellmodel order.
Definition: cellMatcher.H:145
const cellModel & model() const
Definition: cellMatcherI.H:86
faceList localFaces_
Faces using local vertex numbering.
Definition: cellMatcher.H:123
labelList pointMap_
Map from local to mesh vertex numbering.
Definition: cellMatcher.H:129
label otherFace(const label numVert, const label v0, const label v1, const label localFacei) const
Given start,end of edge lookup both faces sharing it and return.
Definition: cellMatcher.C:216
void setSize(const label)
Reset size of List.
Definition: List.C:281
virtual bool isA(const primitiveMesh &mesh, const label celli)
Exact match. Uses faceSizeMatch.
Definition: wedgeMatcher.C:370
virtual const faceList & faces() const =0
Return faces.
virtual const labelList & faceOwner() const =0
Face face-owner addressing.
static label nextVert(const label, const label, const bool)
Step along face either in righthand or lefthand direction.
Definition: cellMatcherI.H:112
virtual bool matches(const primitiveMesh &mesh, const label celli, cellShape &shape)
Like isA but also constructs a cellShape (if shape matches)
Definition: wedgeMatcher.C:398
virtual bool faceSizeMatch(const faceList &, const labelList &) const
Check whether number of face sizes match the shape.
Definition: wedgeMatcher.C:329