meshSurfaceCheckEdgeTypes.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | cfMesh: A library for mesh generation
4  \\ / O peration |
5  \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6  \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of cfMesh.
10 
11  cfMesh is free software; you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by the
13  Free Software Foundation; either version 3 of the License, or (at your
14  option) any later version.
15 
16  cfMesh 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 cfMesh. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
30 #include "meshSurfaceEngine.H"
31 #include "meshSurfacePartitioner.H"
32 #include "boolList.H"
33 #include "demandDrivenData.H"
34 #include "helperFunctionsPar.H"
35 #include "triangle.H"
36 #include "tetrahedron.H"
37 #include "labelledPoint.H"
38 
39 #include <map>
40 # ifdef USE_OMP
41 #include <omp.h>
42 # endif
43 
44 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 
46 namespace Foam
47 {
48 
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 
52 {
54  const labelList& bp = surfaceEngine_.bp();
55  const VRWGraph& pointFaces = surfaceEngine_.pointFaces();
56  const edgeList& edges = surfaceEngine_.edges();
57  const VRWGraph& edgeFaces = surfaceEngine_.edgeFaces();
58  const labelList& facePatch = surfaceEngine_.boundaryFacePatches();
59  const vectorField& fCentres = surfaceEngine_.faceCentres();
60 
61  //- check if there exist tangled parts of mesh surface where
62  //- classification is not reliable
63  boolList problematicPoint(pointFaces.size(), false);
64 
66  meshSurfaceCheckInvertedVertices checkInverted(mPart);
67  const labelHashSet& invertedPoints = checkInverted.invertedVertices();
68  forAllConstIter(labelHashSet, invertedPoints, it)
69  problematicPoint[bp[it.key()]] = true;
70 
71  //- classify edges
72  edgeType_.setSize(edges.size());
73 
74  # ifdef USE_OMP
75  label nThreads = 3 * omp_get_num_procs();
76  if( edges.size() < 1000 )
77  nThreads = 1;
78  # endif
79 
80  # ifdef USE_OMP
81  # pragma omp parallel num_threads(nThreads)
82  # endif
83  {
84  // TODO: this is not valid for non-manifold meshes
85  //- start checking feature edges
86  # ifdef USE_OMP
87  # pragma omp for schedule(static, 1)
88  # endif
89  forAll(edgeFaces, edgeI)
90  {
91  edgeType_[edgeI] = NONE;
92 
93  if( edgeFaces.sizeOfRow(edgeI) == 2 )
94  {
95  const label f0 = edgeFaces(edgeI, 0);
96  const label f1 = edgeFaces(edgeI, 1);
97 
98  if( facePatch[f0] == facePatch[f1] )
99  {
100  edgeType_[edgeI] |= PATCHEDGE;
101  }
102  else
103  {
104  edgeType_[edgeI] |= FEATUREEDGE;
105  }
106 
107  const edge e = edges[edgeI];
108 
109  //- check if the surface is tangled there
110  if( problematicPoint[bp[e.start()]] )
111  {
112  edgeType_[edgeI] |= UNDETERMINED;
113  continue;
114  }
115 
116  if( problematicPoint[bp[e.end()]] )
117  {
118  edgeType_[edgeI] |= UNDETERMINED;
119  continue;
120  }
121 
122  //- check the volumes pof tets which can be formed at the edge
123  const tetrahedron<point, point> tet0
124  (
125  points[e.start()],
126  points[e.end()],
127  fCentres[f0],
128  fCentres[f1]
129  );
130 
131  if( tet0.mag() > -VSMALL )
132  {
133  edgeType_[edgeI] |= CONCAVEEDGE;
134  continue;
135  }
136 
137  const tetrahedron<point, point> tet1
138  (
139  points[e.end()],
140  points[e.start()],
141  fCentres[f1],
142  fCentres[f0]
143  );
144 
145  if( tet1.mag() > -VSMALL )
146  {
147  edgeType_[edgeI] |= CONCAVEEDGE;
148  continue;
149  }
150 
151  edgeType_[edgeI] |= CONVEXEDGE;
152  }
153  }
154  }
155 
156  if( Pstream::parRun() )
157  {
158  //- check if the edge at processor boundaries are concave or convex
159  const labelList& globalEdgeLabel =
161  const Map<label>& otherProc = surfaceEngine_.otherEdgeFaceAtProc();
162  const Map<label>& otherPatch = surfaceEngine_.otherEdgeFacePatch();
163  const Map<label>& globalToLocalEdge =
165 
166  std::map<label, LongList<labelledPoint> > exchangeFaceCentres;
168  {
169  const label neiProc = surfaceEngine_.beNeiProcs()[i];
170 
171  exchangeFaceCentres.insert
172  (
173  std::make_pair(neiProc, LongList<labelledPoint>())
174  );
175  }
176 
177  forAllConstIter(Map<label>, otherPatch, eIter)
178  {
179  if( eIter() == facePatch[edgeFaces(eIter.key(), 0)] )
180  {
181  edgeType_[eIter()] |= PATCHEDGE;
182  }
183  else
184  {
185  edgeType_[eIter()] |= FEATUREEDGE;
186  }
187 
188  const edge& e = edges[eIter.key()];
189  if
190  (
191  problematicPoint[bp[e.start()]] ||
192  problematicPoint[bp[e.end()]]
193  )
194  {
195  edgeType_[eIter.key()] |= UNDETERMINED;
196  continue;
197  }
198 
199  const label neiProcs = otherProc[eIter.key()];
200  exchangeFaceCentres[neiProcs].append
201  (
203  (
204  globalEdgeLabel[eIter.key()],
205  fCentres[edgeFaces(eIter.key(), 0)]
206  )
207  );
208  }
209 
210  LongList<labelledPoint> receiveCentres;
211  help::exchangeMap(exchangeFaceCentres, receiveCentres);
212 
213  # ifdef USE_OMP
214  # pragma omp parallel for schedule(dynamic, 20)
215  # endif
216  forAll(receiveCentres, i)
217  {
218  const labelledPoint& lp = receiveCentres[i];
219  const label edgeI = globalToLocalEdge[lp.pointLabel()];
220 
221  // TODO: this is valid for manifold meshes, only
222  if( edgeFaces.sizeOfRow(edgeI) != 1 )
223  continue;
224 
225  const vector fCentre = lp.coordinates();
226 
227  const edge& e = edges[edgeI];
228  const label f0 = edgeFaces(edgeI, 0);
229 
230  //- check the volumes pof tets
231  //- which can be formed at the edge
233  (
234  points[e.start()],
235  points[e.end()],
236  fCentres[f0],
237  fCentre
238  );
239 
240  if ( tet0.mag() > -VSMALL )
241  {
242  edgeType_[edgeI] |= CONCAVEEDGE;
243  continue;
244  }
245 
247  (
248  points[e.end()],
249  points[e.start()],
250  fCentre,
251  fCentres[f0]
252  );
253 
254  if ( tet1.mag() > -VSMALL )
255  {
256  edgeType_[edgeI] |= CONCAVEEDGE;
257  continue;
258  }
259 
260  edgeType_[edgeI] |= CONVEXEDGE;
261  }
262  }
263 
264  # ifdef DEBUGClassifyEdges
265  polyMeshGen& mesh_ = const_cast<polyMeshGen&>(surfaceEngine_.mesh());
266  const label badVertices = mesh_.addPointSubset("invertedVertices");
267  forAll(problematicPoint, bpI)
268  if( problematicPoint[bpI] )
269  mesh_.addPointToSubset
270  (
271  badVertices,
273  );
274 
275  const label convexId = mesh_.addPointSubset("convexFeatures");
276  const label concaveId = mesh_.addPointSubset("concaveFeatures");
277  const label undeterminedId = mesh_.addPointSubset("undetermnedFeatures");
278  const label patchId = mesh_.addPointSubset("patchPoints");
279 
280  forAll(edgeType_, edgeI)
281  {
282  if( edgeType_[edgeI] & CONVEXEDGE )
283  {
284  Info <<"Edge " << edgeI << " is convex" << endl;
285  mesh_.addPointToSubset(convexId, edges[edgeI].start());
286  mesh_.addPointToSubset(convexId, edges[edgeI].end());
287  }
288  if( edgeType_[edgeI] & CONCAVEEDGE )
289  {
290  Info << "Edge " << edgeI << " is concave" << endl;
291  mesh_.addPointToSubset(concaveId, edges[edgeI].start());
292  mesh_.addPointToSubset(concaveId, edges[edgeI].end());
293  }
294  if( edgeType_[edgeI] & UNDETERMINED )
295  {
296  Info << "Edge " << edgeI << " is not determined" << endl;
297  mesh_.addPointToSubset(undeterminedId, edges[edgeI].start());
298  mesh_.addPointToSubset(undeterminedId, edges[edgeI].end());
299  }
300  if( edgeType_[edgeI] & PATCHEDGE )
301  {
302  Info << "Edge " << edgeI << " is a patch edge" << endl;
303  mesh_.addPointToSubset(patchId, edges[edgeI].start());
304  mesh_.addPointToSubset(patchId, edges[edgeI].end());
305  }
306  }
307  # endif
308 }
309 
310 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
311 
313 (
314  const meshSurfaceEngine& mse
315 )
316 :
317  surfaceEngine_(mse),
318  edgeType_()
319 {
320  classifyEdges();
321 }
322 
323 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
324 
326 {}
327 
328 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
329 
331 {
332  convexEdges.clear();
333 
334  forAll(edgeType_, eI)
335  {
336  if( edgeType_[eI] & CONVEXEDGE )
337  convexEdges.append(eI);
338  }
339 }
340 
342 {
343  concaveEdges.clear();
344 
345  forAll(edgeType_, eI)
346  {
347  if( edgeType_[eI] & CONCAVEEDGE )
348  concaveEdges.append(eI);
349  }
350 }
351 
352 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
353 
354 } // End namespace Foam
355 
356 // ************************************************************************* //
Foam::meshSurfaceEngine::faceCentres
const vectorField & faceCentres() const
Definition: meshSurfaceEngineI.H:277
Foam::meshSurfaceEngine::bp
const labelList & bp() const
Definition: meshSurfaceEngineI.H:64
Foam::meshSurfaceCheckInvertedVertices
Definition: meshSurfaceCheckInvertedVertices.H:54
Foam::labelledPoint::coordinates
const point & coordinates() const
return point coordinates
Definition: labelledPoint.H:93
boolList.H
Foam::meshSurfaceCheckEdgeTypes::surfaceEngine_
const meshSurfaceEngine & surfaceEngine_
mesh surface
Definition: meshSurfaceCheckEdgeTypes.H:57
Foam::meshSurfaceCheckEdgeTypes::CONCAVEEDGE
@ CONCAVEEDGE
Definition: meshSurfaceCheckEdgeTypes.H:85
Foam::meshSurfaceEngine::globalToLocalBndEdgeAddressing
const Map< label > & globalToLocalBndEdgeAddressing() const
global boundary edge label to local label. Only for processor edges
Definition: meshSurfaceEngineI.H:510
Foam::meshSurfaceEngine::globalBoundaryEdgeLabel
const labelList & globalBoundaryEdgeLabel() const
global boundary edge label
Definition: meshSurfaceEngineI.H:489
helperFunctionsPar.H
meshSurfaceCheckEdgeTypes.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
triangle.H
Foam::meshSurfaceCheckEdgeTypes::CONVEXEDGE
@ CONVEXEDGE
Definition: meshSurfaceCheckEdgeTypes.H:84
Foam::meshSurfaceCheckInvertedVertices::invertedVertices
const labelHashSet & invertedVertices() const
return the labels of inverted vertices
Definition: meshSurfaceCheckInvertedVertices.H:102
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::meshSurfaceCheckEdgeTypes::meshSurfaceCheckEdgeTypes
meshSurfaceCheckEdgeTypes(const meshSurfaceCheckEdgeTypes &)
Disallow default bitwise copy construct.
meshSurfaceCheckInvertedVertices.H
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::meshSurfaceCheckEdgeTypes::edgeType_
List< direction > edgeType_
a list which classifies each edge
Definition: meshSurfaceCheckEdgeTypes.H:60
Foam::meshSurfaceEngine::pointFaces
const VRWGraph & pointFaces() const
Definition: meshSurfaceEngineI.H:162
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
Foam::meshSurfaceEngine::boundaryFacePatches
const labelList & boundaryFacePatches() const
patch label for each boundary face
Definition: meshSurfaceEngineI.H:123
Foam::Map< label >
Foam::polyMeshGen
Definition: polyMeshGen.H:46
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::HashSet< label, Hash< label > >
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
Foam::meshSurfaceCheckEdgeTypes::UNDETERMINED
@ UNDETERMINED
Definition: meshSurfaceCheckEdgeTypes.H:86
Foam::LongList
Definition: LongList.H:55
Foam::meshSurfaceCheckEdgeTypes::convexEdges
void convexEdges(labelLongList &convexEdges) const
return indices of convex edges
Definition: meshSurfaceCheckEdgeTypes.C:330
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
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::Info
messageStream Info
Foam::meshSurfaceCheckEdgeTypes::PATCHEDGE
@ PATCHEDGE
Definition: meshSurfaceCheckEdgeTypes.H:82
Foam::meshSurfaceEngine::otherEdgeFaceAtProc
const Map< label > & otherEdgeFaceAtProc() const
Definition: meshSurfaceEngineI.H:568
Foam::meshSurfaceEngine::beNeiProcs
const DynList< label > & beNeiProcs() const
communication matrix for sending edge data
Definition: meshSurfaceEngineI.H:549
Foam::meshSurfaceCheckEdgeTypes::classifyEdges
void classifyEdges()
check feature edges and classify them
Definition: meshSurfaceCheckEdgeTypes.C:51
Foam::VRWGraph::size
label size() const
Returns the number of rows.
Definition: VRWGraphI.H:122
f1
scalar f1
Definition: createFields.H:28
Foam::meshSurfaceEngine::points
const pointFieldPMG & points() const
Definition: meshSurfaceEngineI.H:49
Foam::VRWGraph::sizeOfRow
label sizeOfRow(const label rowI) const
Returns the number of elements in the given row.
Definition: VRWGraphI.H:127
labelledPoint.H
Foam::polyMeshGenPoints::addPointToSubset
void addPointToSubset(const label, const label)
Definition: polyMeshGenPointsI.H:60
Foam::meshSurfaceEngine::edgeFaces
const VRWGraph & edgeFaces() const
Definition: meshSurfaceEngineI.H:334
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
meshSurfaceEngine.H
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::meshSurfacePartitioner
Definition: meshSurfacePartitioner.H:52
Foam::meshSurfaceEngine::edges
const edgeList & edges() const
Definition: meshSurfaceEngineI.H:296
Foam::meshSurfaceCheckEdgeTypes::~meshSurfaceCheckEdgeTypes
~meshSurfaceCheckEdgeTypes()
Definition: meshSurfaceCheckEdgeTypes.C:325
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::labelledPoint
Definition: labelledPoint.H:50
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::meshSurfaceCheckEdgeTypes::concaveEdges
void concaveEdges(labelLongList &concaveEdges) const
return indices of concave edges
Definition: meshSurfaceCheckEdgeTypes.C:341
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::help::exchangeMap
void exchangeMap(const std::map< label, ListType > &m, LongList< T > &data, const Pstream::commsTypes commsType)
Definition: helperFunctionsPar.C:129
Foam::meshSurfaceEngine::boundaryPoints
const labelList & boundaryPoints() const
Definition: meshSurfaceEngineI.H:84
patchId
label patchId(-1)
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::meshSurfaceEngine::otherEdgeFacePatch
const Map< label > & otherEdgeFacePatch() const
Definition: meshSurfaceEngineI.H:588
Foam::pointFieldPMG
Definition: pointFieldPMG.H:50
Foam::VRWGraph
Definition: VRWGraph.H:101
Foam::tetrahedron::mag
scalar mag() const
Return volume.
Definition: tetrahedronI.H:171
Foam::polyMeshGenPoints::addPointSubset
label addPointSubset(const word &)
point subsets
Definition: polyMeshGenPoints.C:88
Foam::meshSurfaceEngine::mesh
const polyMeshGen & mesh() const
Definition: meshSurfaceEngineI.H:44
Foam::meshSurfaceCheckEdgeTypes::NONE
@ NONE
Definition: meshSurfaceCheckEdgeTypes.H:81
Foam::meshSurfaceEngine
Definition: meshSurfaceEngine.H:54
meshSurfacePartitioner.H
tetrahedron.H
Foam::labelledPoint::pointLabel
label pointLabel() const
return point label
Definition: labelledPoint.H:82
Foam::tetrahedron
A tetrahedron primitive.
Definition: tetrahedron.H:62
Foam::meshSurfaceCheckEdgeTypes::FEATUREEDGE
@ FEATUREEDGE
Definition: meshSurfaceCheckEdgeTypes.H:83