Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
10License
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\*---------------------------------------------------------------------------*/
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 =
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 =
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 =
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 =
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
286Foam::label Foam::prismMatcher::faceHashValue() const
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;
322 }
323
324 return (nTris == 2 && nQuads == 3);
325}
326
327
328bool 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
341bool Foam::prismMatcher::isA(const faceList& faces)
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// ************************************************************************* //
Various functions to operate on Lists.
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
const cellModel & model() const
labelListList pointFaceIndex_
pointFaceIndex[localVertI][localFacei] is index in localFace
labelList faceMap_
Map from local to mesh face numbering.
label calcLocalFaces(const faceList &faces, const labelList &myFaces)
Calculates localFaces. Returns number of local vertices (or -1.
Definition cellMatcher.C:67
labelList pointMap_
Map from local to mesh vertex numbering.
labelList faceLabels_
After matching: holds mesh faces in cellmodel order.
static label nextVert(const label, const label, const bool)
Step along face either in righthand or lefthand direction.
labelList vertLabels_
After matching: holds mesh vertices in cellmodel order.
const labelList & vertLabels() const
labelList faceSize_
Number of vertices per face in localFaces_.
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.
void calcEdgeAddressing(const label numVert)
Fill edge (start, end) to face number.
faceList localFaces_
Faces using local vertex numbering.
cellMatcher(const cellMatcher &)=delete
No copy construct.
void calcPointFaceIndex()
Fill vertex/face to index in face data structure.
An analytical geometric cellShape.
Definition cellShape.H:71
void reset(const cellModel &model, const labelUList &labels, const bool doCollapse=false)
Reset from components.
Definition cellShapeI.H:359
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
virtual const faceList & faces() const
Return raw faces.
Definition polyMesh.C:1088
Cell-face mesh analysis engine.
virtual bool faceSizeMatch(const faceList &, const labelList &) const
Check whether number of face sizes match the shape.
prismMatcher()
Default construct.
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.
virtual bool matches(const primitiveMesh &mesh, const label celli, cellShape &shape)
Like isA but also constructs a cellShape (if shape matches).
virtual bool isA(const primitiveMesh &mesh, const label celli)
Exact match. Uses faceSizeMatch.
virtual label faceHashValue() const
Hash value of all face sizes of this shape. Can be used for.
dynamicFvMesh & mesh
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:548
List< label > labelList
A List of labels.
Definition List.H:62
List< face > faceList
List of faces.
Definition faceListFwd.H:41
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299