PrimitivePatchCheck.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 | Copyright (C) 2011-2015 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 Description
25  Checks topology of the patch.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "PrimitivePatch.H"
30 #include "Map.H"
31 #include "ListOps.H"
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 template
36 <
37  class Face,
38  template<class> class FaceList,
39  class PointField,
40  class PointType
41 >
42 void
45 (
46  const label pointI,
47  const labelList& pFaces,
48  const label startFaceI,
49  const label startEdgeI,
50  boolList& pFacesHad
51 ) const
52 {
53  label index = findIndex(pFaces, startFaceI);
54 
55  if (!pFacesHad[index])
56  {
57  // Mark face as been visited.
58  pFacesHad[index] = true;
59 
60  // Step to next edge on face which is still using pointI
61  const labelList& fEdges = faceEdges()[startFaceI];
62 
63  label nextEdgeI = -1;
64 
65  forAll(fEdges, i)
66  {
67  label edgeI = fEdges[i];
68 
69  const edge& e = edges()[edgeI];
70 
71  if (edgeI != startEdgeI && (e[0] == pointI || e[1] == pointI))
72  {
73  nextEdgeI = edgeI;
74 
75  break;
76  }
77  }
78 
79  if (nextEdgeI == -1)
80  {
82  << "Problem: cannot find edge out of " << fEdges
83  << "on face " << startFaceI << " that uses point " << pointI
84  << " and is not edge " << startEdgeI << abort(FatalError);
85  }
86 
87  // Walk to next face(s) across edge.
88  const labelList& eFaces = edgeFaces()[nextEdgeI];
89 
90  forAll(eFaces, i)
91  {
92  if (eFaces[i] != startFaceI)
93  {
94  visitPointRegion
95  (
96  pointI,
97  pFaces,
98  eFaces[i],
99  nextEdgeI,
100  pFacesHad
101  );
102  }
103  }
104  }
105 }
106 
107 
108 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
109 
110 template
111 <
112  class Face,
113  template<class> class FaceList,
114  class PointField,
115  class PointType
116 >
117 typename
120 surfaceType() const
121 {
122  if (debug)
123  {
124  Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
125  "surfaceType() : "
126  "calculating patch topology"
127  << endl;
128  }
129 
130  const labelListList& edgeFcs = edgeFaces();
131 
132  surfaceTopo pType = MANIFOLD;
133 
134  forAll(edgeFcs, edgeI)
135  {
136  label nNbrs = edgeFcs[edgeI].size();
137 
138  if (nNbrs < 1 || nNbrs > 2)
139  {
140  pType = ILLEGAL;
141 
142  // Can exit now. Surface is illegal.
143  return pType;
144  }
145  else if (nNbrs == 1)
146  {
147  // Surface might be open or illegal so keep looping.
148  pType = OPEN;
149  }
150  }
151 
152  if (debug)
153  {
154  Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
155  "surfaceType() : "
156  "finished calculating patch topology"
157  << endl;
158  }
159 
160  return pType;
161 }
162 
163 
164 template
165 <
166  class Face,
167  template<class> class FaceList,
168  class PointField,
169  class PointType
170 >
171 bool
174 (
175  const bool report,
176  labelHashSet* setPtr
177 ) const
178 {
179  if (debug)
180  {
181  Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
182  "checkTopology(const bool, labelHashSet&) : "
183  "checking patch topology"
184  << endl;
185  }
186 
187  // Check edgeFaces
188 
189  const labelListList& edgeFcs = edgeFaces();
190 
191  bool illegalTopo = false;
192 
193  forAll(edgeFcs, edgeI)
194  {
195  label nNbrs = edgeFcs[edgeI].size();
196 
197  if (nNbrs < 1 || nNbrs > 2)
198  {
199  illegalTopo = true;
200 
201  if (report)
202  {
203  Info<< "Edge " << edgeI << " with vertices:" << edges()[edgeI]
204  << " has " << nNbrs << " face neighbours"
205  << endl;
206  }
207 
208  if (setPtr)
209  {
210  const edge& e = edges()[edgeI];
211 
212  setPtr->insert(meshPoints()[e.start()]);
213  setPtr->insert(meshPoints()[e.end()]);
214  }
215  }
216  }
217 
218  if (debug)
219  {
220  Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
221  "checkTopology(const bool, labelHashSet&) : "
222  "finished checking patch topology"
223  << endl;
224  }
225 
226  return illegalTopo;
227 }
228 
229 
230 template
231 <
232  class Face,
233  template<class> class FaceList,
234  class PointField,
235  class PointType
236 >
237 bool
240 (
241  const bool report,
242  labelHashSet* setPtr
243 ) const
244 {
245  const labelListList& pf = pointFaces();
246  const labelListList& pe = pointEdges();
247  const labelListList& ef = edgeFaces();
248  const labelList& mp = meshPoints();
249 
250  bool foundError = false;
251 
252  forAll(pf, pointI)
253  {
254  const labelList& pFaces = pf[pointI];
255 
256  // Visited faces (as indices into pFaces)
257  boolList pFacesHad(pFaces.size(), false);
258 
259  // Starting edge
260  const labelList& pEdges = pe[pointI];
261  label startEdgeI = pEdges[0];
262 
263  const labelList& eFaces = ef[startEdgeI];
264 
265  forAll(eFaces, i)
266  {
267  // Visit all faces using pointI, starting from eFaces[i] and
268  // startEdgeI. Mark off all faces visited in pFacesHad.
269  this->visitPointRegion
270  (
271  pointI,
272  pFaces,
273  eFaces[i], // starting face for walk
274  startEdgeI, // starting edge for walk
275  pFacesHad
276  );
277  }
278 
279  // After this all faces using pointI should have been visited and
280  // marked off in pFacesHad.
281 
282  label unset = findIndex(pFacesHad, false);
283 
284  if (unset != -1)
285  {
286  foundError = true;
287 
288  label meshPointI = mp[pointI];
289 
290  if (setPtr)
291  {
292  setPtr->insert(meshPointI);
293  }
294 
295  if (report)
296  {
297  Info<< "Point " << meshPointI
298  << " uses faces which are not connected through an edge"
299  << nl
300  << "This means that the surface formed by this patched"
301  << " is multiply connected at this point" << nl
302  << "Connected (patch) faces:" << nl;
303 
304  forAll(pFacesHad, i)
305  {
306  if (pFacesHad[i])
307  {
308  Info<< " " << pFaces[i] << endl;
309  }
310  }
311 
312  Info<< nl << "Unconnected (patch) faces:" << nl;
313  forAll(pFacesHad, i)
314  {
315  if (!pFacesHad[i])
316  {
317  Info<< " " << pFaces[i] << endl;
318  }
319  }
320  }
321  }
322  }
323 
324  return foundError;
325 }
326 
327 
328 // ************************************************************************* //
Foam::constant::atomic::mp
const dimensionedScalar mp
Proton mass.
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::findIndex
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::PrimitivePatch::surfaceType
surfaceTopo surfaceType() const
Calculate surface type formed by patch.
Definition: PrimitivePatchCheck.C:123
pFaces
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=*(cellModeller::lookup("hex"));labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells]=cellShape(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
Definition: readKivaGrid.H:235
Map.H
Foam::label
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
PrimitivePatch.H
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
Foam::PrimitivePatch::checkTopology
bool checkTopology(const bool report=false, labelHashSet *setPtr=NULL) const
Check surface formed by patch for manifoldness (see above).
Definition: PrimitivePatchCheck.C:177
Foam::FatalError
error FatalError
Foam::PrimitivePatch::visitPointRegion
void visitPointRegion(const label pointI, const labelList &pFaces, const label startFaceI, const label startEdgeI, boolList &pFacesHad) const
Face-edge-face walk while remaining on a patch point.
Definition: PrimitivePatchCheck.C:46
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::boolList
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
Foam::PrimitivePatch::surfaceTopo
surfaceTopo
Enumeration defining the surface type. Used in check routines.
Definition: PrimitivePatchTemplate.H:106
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: doubleFloat.H:94
ListOps.H
Various functions to operate on Lists.
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
Definition: HashSet.H:210
Foam::PrimitivePatch::checkPointManifold
bool checkPointManifold(const bool report=false, labelHashSet *setPtr=NULL) const
Checks primitivePatch for faces sharing point but not edge.
Definition: PrimitivePatchCheck.C:247