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-2016 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  InfoInFunction << "Calculating patch topology" << endl;
125  }
126 
127  const labelListList& edgeFcs = edgeFaces();
128 
129  surfaceTopo pType = MANIFOLD;
130 
131  forAll(edgeFcs, edgeI)
132  {
133  label nNbrs = edgeFcs[edgeI].size();
134 
135  if (nNbrs < 1 || nNbrs > 2)
136  {
137  pType = ILLEGAL;
138 
139  // Can exit now. Surface is illegal.
140  return pType;
141  }
142  else if (nNbrs == 1)
143  {
144  // Surface might be open or illegal so keep looping.
145  pType = OPEN;
146  }
147  }
148 
149  if (debug)
150  {
151  Info<< " Finished." << endl;
152  }
153 
154  return pType;
155 }
156 
157 
158 template
159 <
160  class Face,
161  template<class> class FaceList,
162  class PointField,
163  class PointType
164 >
165 bool
168 (
169  const bool report,
170  labelHashSet* setPtr
171 ) const
172 {
173  if (debug)
174  {
175  InfoInFunction << "Checking patch topology" << endl;
176  }
177 
178  // Check edgeFaces
179 
180  const labelListList& edgeFcs = edgeFaces();
181 
182  bool illegalTopo = false;
183 
184  forAll(edgeFcs, edgeI)
185  {
186  label nNbrs = edgeFcs[edgeI].size();
187 
188  if (nNbrs < 1 || nNbrs > 2)
189  {
190  illegalTopo = true;
191 
192  if (report)
193  {
194  Info<< "Edge " << edgeI << " with vertices:" << edges()[edgeI]
195  << " has " << nNbrs << " face neighbours"
196  << endl;
197  }
198 
199  if (setPtr)
200  {
201  const edge& e = edges()[edgeI];
202 
203  setPtr->insert(meshPoints()[e.start()]);
204  setPtr->insert(meshPoints()[e.end()]);
205  }
206  }
207  }
208 
209  if (debug)
210  {
211  Info<< " Finished." << endl;
212  }
213 
214  return illegalTopo;
215 }
216 
217 
218 template
219 <
220  class Face,
221  template<class> class FaceList,
222  class PointField,
223  class PointType
224 >
225 bool
228 (
229  const bool report,
230  labelHashSet* setPtr
231 ) const
232 {
233  const labelListList& pf = pointFaces();
234  const labelListList& pe = pointEdges();
235  const labelListList& ef = edgeFaces();
236  const labelList& mp = meshPoints();
237 
238  bool foundError = false;
239 
240  forAll(pf, pointi)
241  {
242  const labelList& pFaces = pf[pointi];
243 
244  // Visited faces (as indices into pFaces)
245  boolList pFacesHad(pFaces.size(), false);
246 
247  // Starting edge
248  const labelList& pEdges = pe[pointi];
249  label startEdgeI = pEdges[0];
250 
251  const labelList& eFaces = ef[startEdgeI];
252 
253  forAll(eFaces, i)
254  {
255  // Visit all faces using pointi, starting from eFaces[i] and
256  // startEdgeI. Mark off all faces visited in pFacesHad.
257  this->visitPointRegion
258  (
259  pointi,
260  pFaces,
261  eFaces[i], // starting face for walk
262  startEdgeI, // starting edge for walk
263  pFacesHad
264  );
265  }
266 
267  // After this all faces using pointi should have been visited and
268  // marked off in pFacesHad.
269 
270  label unset = findIndex(pFacesHad, false);
271 
272  if (unset != -1)
273  {
274  foundError = true;
275 
276  label meshPointi = mp[pointi];
277 
278  if (setPtr)
279  {
280  setPtr->insert(meshPointi);
281  }
282 
283  if (report)
284  {
285  Info<< "Point " << meshPointi
286  << " uses faces which are not connected through an edge"
287  << nl
288  << "This means that the surface formed by this patched"
289  << " is multiply connected at this point" << nl
290  << "Connected (patch) faces:" << nl;
291 
292  forAll(pFacesHad, i)
293  {
294  if (pFacesHad[i])
295  {
296  Info<< " " << pFaces[i] << endl;
297  }
298  }
299 
300  Info<< nl << "Unconnected (patch) faces:" << nl;
301  forAll(pFacesHad, i)
302  {
303  if (!pFacesHad[i])
304  {
305  Info<< " " << pFaces[i] << endl;
306  }
307  }
308  }
309  }
310  }
311 
312  return foundError;
313 }
314 
315 
316 // ************************************************************************* //
label end() const
Return end vertex label.
Definition: edgeI.H:92
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
surfaceTopo
Enumeration defining the surface type. Used in check routines.
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
bool checkTopology(const bool report=false, labelHashSet *setPtr=NULL) const
Check surface formed by patch for manifoldness (see above).
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
surfaceTopo surfaceType() const
Calculate surface type formed by patch.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
Various functions to operate on Lists.
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
A list of faces which address into the list of points.
bool checkPointManifold(const bool report=false, labelHashSet *setPtr=NULL) const
Checks primitivePatch for faces sharing point but not edge.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
List< label > labelList
A List of labels.
Definition: labelList.H:56
errorManip< error > abort(error &err)
Definition: errorManip.H:131
label start() const
Return start vertex label.
Definition: edgeI.H:81
static const char nl
Definition: Ostream.H:262
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
messageStream Info
const dimensionedScalar mp
Proton mass.
#define InfoInFunction
Report an information message using Foam::Info.