1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
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.
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
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/>.
26 \*---------------------------------------------------------------------------*/
28 #include "meshSurfaceCheckInvertedVertices.H"
29 #include "meshSurfacePartitioner.H"
31 #include "demandDrivenData.H"
32 #include "refLabelledPoint.H"
33 #include "helperFunctions.H"
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 void meshSurfaceCheckInvertedVertices::checkVertices()
50 const labelList& facePatch = surfacePartitioner_.boundaryFacePatches();
51 const meshSurfaceEngine& mse = surfacePartitioner_.surfaceEngine();
52 const pointFieldPMG& points = mse.points();
53 const labelList& bp = mse.bp();
54 const VRWGraph& pointFaces = mse.pointFaces();
55 const VRWGraph& pointInFaces = mse.pointInFaces();
56 const faceList::subList& bFaces = mse.boundaryFaces();
57 const vectorField& pNormals = mse.pointNormals();
58 const vectorField& fCentres = mse.faceCentres();
59 const vectorField& fNormals = mse.faceNormals();
61 const labelHashSet& corners = surfacePartitioner_.corners();
62 const labelHashSet& edgePoints = surfacePartitioner_.edgePoints();
64 typedef std::map<label, vector> ltvMap;
65 typedef std::map<label, ltvMap> lltvMap;
66 lltvMap pointPatchNormal;
68 forAllConstIter(labelHashSet, corners, it)
70 const label bpI = it.key();
72 if( activePointsPtr_ && !activePointsPtr_->operator[](bpI))
75 ltvMap& patchNormal = pointPatchNormal[bpI];
77 forAllRow(pointFaces, bpI, pfI)
79 const label bfI = pointFaces(bpI, pfI);
80 const label patchI = facePatch[bfI];
82 if( patchNormal.find(patchI) == patchNormal.end() )
84 patchNormal[patchI] = fNormals[bfI];
88 patchNormal[patchI] += fNormals[bfI];
93 forAllConstIter(labelHashSet, edgePoints, it)
95 const label bpI = it.key();
97 if( activePointsPtr_ && !activePointsPtr_->operator[](bpI))
100 ltvMap& patchNormal = pointPatchNormal[bpI];
102 forAllRow(pointFaces, bpI, pfI)
104 const label bfI = pointFaces(bpI, pfI);
105 const label patchI = facePatch[bfI];
107 if( patchNormal.find(patchI) == patchNormal.end() )
109 patchNormal[patchI] = fNormals[bfI];
113 patchNormal[patchI] += fNormals[bfI];
118 if( Pstream::parRun() )
120 const Map<label>& globalToLocal = mse.globalToLocalBndPointAddressing();
121 const DynList<label>& neiProcs = mse.bpNeiProcs();
122 const VRWGraph& bpAtProcs = mse.bpAtProcs();
124 std::map<label, LongList<refLabelledPoint> > exchangeData;
126 exchangeData[neiProcs[i]].clear();
128 forAllConstIter(Map<label>, globalToLocal, it)
130 const label bpI = it();
132 if( pointPatchNormal.find(bpI) != pointPatchNormal.end() )
134 const ltvMap& patchNormal = pointPatchNormal[bpI];
136 forAllRow(bpAtProcs, bpI, i)
138 const label neiProc = bpAtProcs(bpI, i);
140 if( neiProc == Pstream::myProcNo() )
143 forAllConstIter(ltvMap, patchNormal, pIt)
144 exchangeData[neiProc].append
149 labelledPoint(pIt->first, pIt->second)
156 LongList<refLabelledPoint> receivedData;
157 help::exchangeMap(exchangeData, receivedData);
159 forAll(receivedData, i)
161 const refLabelledPoint& rlp = receivedData[i];
162 const label bpI = globalToLocal[rlp.objectLabel()];
164 ltvMap& patchNormal = pointPatchNormal[bpI];
166 const labelledPoint& lp = rlp.lPoint();
167 patchNormal[lp.pointLabel()] += lp.coordinates();
171 forAllIter(lltvMap, pointPatchNormal, it)
173 ltvMap& patchNormal = pointPatchNormal[it->first];
175 forAllIter(ltvMap, patchNormal, pIt)
177 const scalar magv = mag(pIt->second) + VSMALL;
183 invertedVertices_.clear();
186 # pragma omp parallel for if( pointFaces.size() > 100 ) \
187 schedule(dynamic, 20)
189 forAll(pointFaces, bpI)
191 if( activePointsPtr_ && !activePointsPtr_->operator[](bpI) )
194 forAllRow(pointFaces, bpI, pfI)
196 const label pI = pointInFaces(bpI, pfI);
197 const label bfI = pointFaces(bpI, pfI);
199 vector pNormal = pNormals[bpI];
201 if( pointPatchNormal.find(bpI) != pointPatchNormal.end() )
202 pNormal = pointPatchNormal[bpI][facePatch[bfI]];
204 const face& bf = bFaces[bfI];
206 //- chech the first triangle (with the next node)
207 triangle<point, point> triNext
210 points[bf.nextLabel(pI)],
214 vector nNext = triNext.normal();
215 scalar mNext = mag(nNext);
217 //- face has zero area
221 # pragma omp critical
223 invertedVertices_.insert(bf[pI]);
232 //- collocated points
233 if( magSqr(triNext.a() - triNext.b()) < VSMALL )
236 # pragma omp critical
238 invertedVertices_.insert(bf[pI]);
242 if( magSqr(triNext.c() - triNext.a()) < VSMALL )
245 # pragma omp critical
247 invertedVertices_.insert(bf[pI]);
252 //- normal vector is not visible
253 if( (nNext & pNormal) < 0.0 )
256 # pragma omp critical
258 invertedVertices_.insert(bf[pI]);
263 //- check the second triangle (with previous node)
264 triangle<point, point> triPrev
268 points[bf.prevLabel(pI)]
271 vector nPrev = triPrev.normal();
272 scalar mPrev = mag(nPrev);
274 //- face has zero area
278 # pragma omp critical
280 invertedVertices_.insert(bf[pI]);
289 //- collocated points
290 if( magSqr(triPrev.a() - triPrev.b()) < VSMALL )
293 # pragma omp critical
295 invertedVertices_.insert(bf[pI]);
299 if( magSqr(triPrev.c() - triPrev.a()) < VSMALL )
302 # pragma omp critical
304 invertedVertices_.insert(bf[pI]);
309 //- normal vector is not visible
310 if( (nPrev & pNormal) < 0.0 )
313 # pragma omp critical
315 invertedVertices_.insert(bf[pI]);
320 //- check whether the normals of both triangles
321 //- point in the same direction
322 if( (nNext & nPrev) < 0.0 )
325 # pragma omp critical
327 invertedVertices_.insert(bf[pI]);
334 //- check if there exist concave faces
336 # pragma omp parallel for schedule(dynamic, 50)
340 const face& bf = bFaces[bfI];
342 DynList<bool> OkPoints;
343 if( !help::isFaceConvexAndOk(bf, points, OkPoints) )
347 if( activePointsPtr_ && !(*activePointsPtr_)[bp[bf[pI]]] )
353 # pragma omp critical
356 invertedVertices_.insert(bf[pI]);
363 if( Pstream::parRun() )
365 //- exchange global labels of inverted points
366 const labelList& bPoints = mse.boundaryPoints();
367 const Map<label>& globalToLocal =
368 mse.globalToLocalBndPointAddressing();
369 const VRWGraph& bpAtProcs = mse.bpAtProcs();
370 const DynList<label>& neiProcs = mse.bpNeiProcs();
372 std::map<label, labelLongList> shareData;
374 shareData.insert(std::make_pair(neiProcs[i], labelLongList()));
376 forAllConstIter(Map<label>, globalToLocal, iter)
378 const label bpI = iter();
380 if( !invertedVertices_.found(bPoints[bpI]) )
383 forAllRow(bpAtProcs, bpI, procI)
385 const label neiProc = bpAtProcs(bpI, procI);
387 if( neiProc == Pstream::myProcNo() )
390 shareData[neiProc].append(iter.key());
394 //- exchange data with other processors
395 labelLongList receivedData;
396 help::exchangeMap(shareData, receivedData);
398 forAll(receivedData, i)
400 const label bpI = globalToLocal[receivedData[i]];
401 invertedVertices_.insert(bPoints[bpI]);
406 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
408 meshSurfaceCheckInvertedVertices::meshSurfaceCheckInvertedVertices
410 const meshSurfacePartitioner& mpart
413 surfacePartitioner_(mpart),
414 activePointsPtr_(NULL),
420 meshSurfaceCheckInvertedVertices::meshSurfaceCheckInvertedVertices
422 const meshSurfacePartitioner& mpart,
423 const boolList& activePoints
426 surfacePartitioner_(mpart),
427 activePointsPtr_(&activePoints),
433 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
435 meshSurfaceCheckInvertedVertices::~meshSurfaceCheckInvertedVertices()
438 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
440 } // End namespace Foam
442 // ************************************************************************* //