prismMatcher.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 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "prismMatcher.H"
29 #include "primitiveMesh.H"
30 #include "ListOps.H"
31 
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 
35 :
37  (
38  vertPerCell,
39  facePerCell,
40  maxVertPerFace,
41  "prism" // == cellModel::modelNames[cellModel::PRISM]
42  )
43 {}
44 
45 
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 
49 (
50  const bool checkOnly,
51  const faceList& faces,
52  const labelList& owner,
53  const label celli,
54  const labelList& myFaces
55 )
56 {
57  if (!faceSizeMatch(faces, myFaces))
58  {
59  return false;
60  }
61 
62  // Calculate localFaces_ and mapping pointMap_, faceMap_
63  label numVert = calcLocalFaces(faces, myFaces);
64 
65  if (numVert != vertPerCell)
66  {
67  return false;
68  }
69 
70  // Set up 'edge' to face mapping.
71  calcEdgeAddressing(numVert);
72 
73  // Set up point on face to index-in-face mapping
74  calcPointFaceIndex();
75 
76  // Storage for maps -vertex to mesh and -face to mesh
77  vertLabels_.setSize(vertPerCell);
78  faceLabels_.setSize(facePerCell);
79 
80  //
81  // Try first triangular face.
82  // Only need to try one orientation of this face since prism is
83  // rotation symmetric
84  //
85 
86  label face0I = -1;
87  forAll(faceSize_, facei)
88  {
89  if (faceSize_[facei] == 3)
90  {
91  face0I = facei;
92  break;
93  }
94  }
95 
96  const face& face0 = localFaces_[face0I];
97  label face0vert0 = 0;
98 
99  //
100  // Try to follow prespecified path on faces of cell,
101  // starting at face0vert0
102  //
103 
104  vertLabels_[0] = pointMap_[face0[face0vert0]];
105  faceLabels_[0] = faceMap_[face0I];
106  //Info<< endl << "Prism vertex 0: vertex " << face0[face0vert0]
107  // << " at position " << face0vert0 << " in face " << face0
108  // << endl;
109 
110  // Walk face 0 from vertex 0 to 1
111  label face0vert1 =
112  nextVert
113  (
114  face0vert0,
115  faceSize_[face0I],
116  !(owner[faceMap_[face0I]] == celli)
117  );
118  vertLabels_[1] = pointMap_[face0[face0vert1]];
119  //Info<< "Prism vertex 1: vertex " << face0[face0vert1]
120  // << " at position " << face0vert1 << " in face " << face0
121  // << endl;
122 
123  // Jump edge from face0 to face4
124  label face4I =
125  otherFace
126  (
127  numVert,
128  face0[face0vert0],
129  face0[face0vert1],
130  face0I
131  );
132  const face& face4 = localFaces_[face4I];
133  //Info<< "Stepped to prism face 4 " << face4
134  // << " across edge " << face0[face0vert0] << " "
135  // << face0[face0vert1]
136  // << endl;
137 
138  if (faceSize_[face4I] != 4)
139  {
140  //Info<< "Cannot be Prism Face 4 since size="
141  // << faceSize_[face4I] << endl;
142  return false;
143  }
144  faceLabels_[4] = faceMap_[face4I];
145 
146  label face4vert1 = pointFaceIndex_[face0[face0vert1]][face4I];
147 
148  //Info<< "Prism vertex 1 also: vertex " << face4[face4vert1]
149  // << " at position " << face4vert1 << " in face " << face4
150  // << endl;
151 
152  // Walk face 4 from vertex 1 to 4
153  label face4vert4 =
154  nextVert
155  (
156  face4vert1,
157  faceSize_[face4I],
158  (owner[faceMap_[face4I]] == celli)
159  );
160  vertLabels_[4] = pointMap_[face4[face4vert4]];
161  //Info<< "Prism vertex 4: vertex " << face4[face4vert4]
162  // << " at position " << face4vert4 << " in face " << face4
163  // << endl;
164 
165  // Walk face 4 from vertex 1 to 3
166  label face4vert3 =
167  nextVert
168  (
169  face4vert4,
170  faceSize_[face4I],
171  (owner[faceMap_[face4I]] == celli)
172  );
173  vertLabels_[3] = pointMap_[face4[face4vert3]];
174  //Info<< "Prism vertex 3: vertex " << face4[face4vert3]
175  // << " at position " << face4vert3 << " in face " << face4
176  // << endl;
177 
178  // Jump edge from face4 to face1
179  label face1I =
180  otherFace
181  (
182  numVert,
183  face4[face4vert3],
184  face4[face4vert4],
185  face4I
186  );
187  //const face& face1 = localFaces_[face1I];
188  //Info<< "Stepped to prism face 1 " << face1
189  // << " across edge " << face4[face4vert3] << " "
190  // << face4[face4vert4]
191  // << endl;
192 
193  if (faceSize_[face1I] != 3)
194  {
195  //Info<< "Cannot be Prism Face 1 since size="
196  // << faceSize_[face1I] << endl;
197  return false;
198  }
199 
200  // Is prism for sure now
201  if (checkOnly)
202  {
203  return true;
204  }
205 
206  faceLabels_[1] = faceMap_[face1I];
207 
208 
209  //
210  // Walk to other faces and assign mapping.
211  //
212 
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  //Info<< "Prism vertex 2: vertex " << face0[face0vert2]
224  // << " at position " << face0vert2 << " in face " << face0
225  // << endl;
226 
227  // Jump edge from face0 to face3
228  label face3I =
229  otherFace
230  (
231  numVert,
232  face0[face0vert1],
233  face0[face0vert2],
234  face0I
235  );
236  faceLabels_[3] = faceMap_[face3I];
237  const face& face3 = localFaces_[face3I];
238  //Info<< "Stepped to prism face 3 " << face3
239  // << " across edge " << face0[face0vert1] << " "
240  // << face0[face0vert2]
241  // << endl;
242 
243  label face3vert2 = pointFaceIndex_[face0[face0vert2]][face3I];
244 
245  //Info<< "Prism vertex 2 also: vertex " << face3[face3vert2]
246  // << " at position " << face3vert2 << " in face " << face3
247  // << endl;
248 
249  label face3vert5 =
250  nextVert
251  (
252  face3vert2,
253  faceSize_[face3I],
254  (owner[faceMap_[face3I]] == celli)
255  );
256  vertLabels_[5] = pointMap_[face3[face3vert5]];
257  //Info<< "Prism vertex 5: vertex " << face3[face3vert5]
258  // << " at position " << face3vert5 << " in face " << face3
259  // << endl;
260 
261  // Jump edge from face0 to face2
262  label face2I =
263  otherFace
264  (
265  numVert,
266  face0[face0vert2],
267  face0[face0vert0],
268  face0I
269  );
270  faceLabels_[2] = faceMap_[face2I];
271  //const face& face2 = localFaces_[face2I];
272  //Info<< "Stepped to prism face 2 " << face2
273  // << " across edge " << face0[face0vert2] << " "
274  // << face0[face0vert0]
275  // << endl;
276 
277  //label face2vert2 = pointFaceIndex_[face0[face0vert2]][face2I];
278  //Info<< "Prism vertex 2 also: vertex " << face2[face2vert2]
279  // << " at position " << face2vert2 << " in face " << face2
280  // << endl;
281 
282  return true;
283 }
284 
285 
287 {
288  return 2*3 + 4*4;
289 }
290 
291 
293 (
294  const faceList& faces,
295  const labelList& myFaces
296 ) const
297 {
298  if (myFaces.size() != 5)
299  {
300  return false;
301  }
302 
303  label nTris = 0;
304  label nQuads = 0;
305 
306  for (const label facei : myFaces)
307  {
308  const label size = faces[facei].size();
309 
310  if (size == 3)
311  {
312  ++nTris;
313  }
314  else if (size == 4)
315  {
316  ++nQuads;
317  }
318  else
319  {
320  return false;
321  }
322  }
323 
324  return (nTris == 2 && nQuads == 3);
325 }
326 
327 
328 bool Foam::prismMatcher::isA(const primitiveMesh& mesh, const label celli)
329 {
330  return matchShape
331  (
332  true,
333  mesh.faces(),
334  mesh.faceOwner(),
335  celli,
336  mesh.cells()[celli]
337  );
338 }
339 
340 
342 {
343  // Do as if mesh with one cell only
344  return matchShape
345  (
346  true,
347  faces, // all faces in mesh
348  labelList(faces.size(), Zero), // cell 0 is owner of all faces
349  0, // cell label
350  identity(faces.size()) // faces of cell 0
351  );
352 }
353 
354 
356 (
357  const primitiveMesh& mesh,
358  const label celli,
359  cellShape& shape
360 )
361 {
362  if
363  (
364  matchShape
365  (
366  false,
367  mesh.faces(),
368  mesh.faceOwner(),
369  celli,
370  mesh.cells()[celli]
371  )
372  )
373  {
374  shape.reset(model(), vertLabels());
375  return true;
376  }
377 
378  return false;
379 }
380 
381 
382 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
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::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
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
prismMatcher.H
Foam::prismMatcher::isA
virtual bool isA(const primitiveMesh &mesh, const label celli)
Exact match. Uses faceSizeMatch.
Definition: prismMatcher.C:328
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::cellShape::reset
void reset(const cellModel &model, const labelUList &labels, const bool doCollapse=false)
Reset from components.
Definition: cellShapeI.H:300
Foam::prismMatcher::prismMatcher
prismMatcher()
Default construct.
Definition: prismMatcher.C:34
Foam::polyMesh::faces
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1094
Foam::prismMatcher::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: prismMatcher.C:49
Foam::List< face >
Foam::prismMatcher::matches
virtual bool matches(const primitiveMesh &mesh, const label celli, cellShape &shape)
Like isA but also constructs a cellShape (if shape matches)
Definition: prismMatcher.C:356
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::prismMatcher::faceSizeMatch
virtual bool faceSizeMatch(const faceList &, const labelList &) const
Check whether number of face sizes match the shape.
Definition: prismMatcher.C:293
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::prismMatcher::faceHashValue
virtual label faceHashValue() const
Hash value of all face sizes of this shape. Can be used for.
Definition: prismMatcher.C:286
Foam::primitiveMesh
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:78