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 "demandDrivenData.H"
29 #include "partTriMesh.H"
30 #include "meshSurfacePartitioner.H"
31 #include "VRWGraphList.H"
32 #include "triSurfModifier.H"
33 #include "helperFunctions.H"
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 partTriMesh::partTriMesh(const meshSurfacePartitioner& mPart)
54 pointLabelInMeshSurface_(),
55 meshSurfacePointLabelInTriMesh_(),
57 globalPointLabelPtr_(NULL),
59 globalToLocalPointAddressingPtr_(NULL),
61 pAtParallelBoundariesPtr_(NULL),
62 pAtBufferLayersPtr_(NULL)
64 const meshSurfaceEngine& meshSurface = mPart.surfaceEngine();
65 List<direction> useFace(meshSurface.boundaryFaces().size(), direction(1));
67 createPointsAndTrias(useFace);
70 partTriMesh::partTriMesh
72 const meshSurfacePartitioner& mPart,
73 const labelHashSet& invertedPoints,
74 const label additionalLayers
79 pointLabelInMeshSurface_(),
80 meshSurfacePointLabelInTriMesh_(),
82 globalPointLabelPtr_(NULL),
84 globalToLocalPointAddressingPtr_(NULL),
86 pAtParallelBoundariesPtr_(NULL),
87 pAtBufferLayersPtr_(NULL)
89 const meshSurfaceEngine& meshSurface = mPart.surfaceEngine();
90 const VRWGraph& pointFaces = meshSurface.pointFaces();
91 const faceList::subList& bFaces = meshSurface.boundaryFaces();
92 const labelList& bPoints = meshSurface.boundaryPoints();
93 const labelList& bp = meshSurface.bp();
95 List<direction> useFace(bFaces.size(), direction(0));
97 //- select cells containing at least one vertex of the bad faces
98 forAll(pointFaces, bpI)
99 if( invertedPoints.found(bPoints[bpI]) )
101 forAllRow(pointFaces, bpI, pfI)
102 useFace[pointFaces(bpI, pfI)] = 1;
105 //- add additional layer of cells
106 for(direction layerI=1;layerI<(additionalLayers+direction(1));++layerI)
109 if( useFace[bfI] == layerI )
111 const face& bf = bFaces[bfI];
115 const label bpI = bp[bf[pI]];
117 forAllRow(pointFaces, bpI, pfI)
119 const label fLabel = pointFaces(bpI, pfI);
121 if( !useFace[fLabel] )
122 useFace[fLabel] = layerI + 1;
127 if( Pstream::parRun() )
129 const labelList& globalPointLabel =
130 meshSurface.globalBoundaryPointLabel();
131 const VRWGraph& pProcs = meshSurface.bpAtProcs();
132 const Map<label>& globalToLocal =
133 meshSurface.globalToLocalBndPointAddressing();
135 std::map<label, labelLongList> eData;
136 forAllConstIter(Map<label>, globalToLocal, iter)
138 const label bpI = iter();
140 forAllRow(pProcs, bpI, procI)
142 const label neiProc = pProcs(bpI, procI);
143 if( neiProc == Pstream::myProcNo() )
146 if( eData.find(neiProc) == eData.end() )
150 std::make_pair(neiProc, labelLongList())
154 forAllRow(pointFaces, bpI, pfI)
155 if( useFace[pointFaces(bpI, pfI)] == layerI )
157 eData[neiProc].append(globalPointLabel[bpI]);
163 //- exchange data with other processors
164 labelLongList receivedData;
165 help::exchangeMap(eData, receivedData);
167 forAll(receivedData, i)
169 const label bpI = globalToLocal[receivedData[i]];
171 forAllRow(pointFaces, bpI, pfI)
173 const label fLabel = pointFaces(bpI, pfI);
174 if( !useFace[fLabel] )
175 useFace[fLabel] = layerI + 1;
181 createPointsAndTrias(useFace);
184 partTriMesh::~partTriMesh()
186 deleteDemandDrivenData(globalPointLabelPtr_);
187 deleteDemandDrivenData(pAtProcsPtr_);
188 deleteDemandDrivenData(globalToLocalPointAddressingPtr_);
189 deleteDemandDrivenData(neiProcsPtr_);
190 deleteDemandDrivenData(pAtParallelBoundariesPtr_);
191 deleteDemandDrivenData(pAtBufferLayersPtr_);
194 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
196 void partTriMesh::updateVertex(const label pI, const point& newP)
198 triSurfModifier sMod(surf_);
199 pointField& pts = sMod.pointsAccess();
200 const VRWGraph& pointFacets = surf_.pointFacets();
204 if( pointType_[pI] & FACECENTRE )
206 Warning << "Smoothing auxiliary vertex."
207 << " This has no effect on the original mesh" << endl;
211 //- find face centres attached
212 DynList<label> helper;
213 forAllRow(pointFacets, pI, ptI)
215 const label centreI = surf_[pointFacets(pI, ptI)][2];
216 if( pointType_[centreI] & FACECENTRE )
217 helper.appendIfNotIn(centreI);
220 //- update coordinates of FACECENTRE vertices
223 const label centreI = helper[i];
225 point centre(vector::zero);
226 scalar faceArea(0.0);
227 forAllRow(pointFacets, centreI, ptI)
229 const labelledTri& tri = surf_[pointFacets(centreI, ptI)];
230 point c(vector::zero);
231 for(label i=0;i<3;++i)
234 const scalar area = tri.mag(pts) + VSMALL;
240 pts[centreI] = centre / faceArea;
244 void partTriMesh::updateVerticesSMP(const List<LongList<labelledPoint> >& np)
246 triSurfModifier sMod(surf_);
247 pointField& pts = sMod.pointsAccess();
248 const VRWGraph& pointFacets = surf_.pointFacets();
250 List<direction> updateType(pts.size(), direction(0));
253 # pragma omp parallel num_threads(np.size())
257 const LongList<labelledPoint>& newPoints = np[omp_get_thread_num()];
259 const LongList<labelledPoint>& newPoints = np[0];
264 const labelledPoint& lp = newPoints[i];
265 const label pointI = lp.pointLabel();
267 pts[pointI] = lp.coordinates();
268 updateType[pointI] |= SMOOTH;
270 forAllRow(pointFacets, pointI, ptI)
272 const labelledTri& tri = surf_[pointFacets(pointI, ptI)];
274 if( pointType_[tri[2]] & FACECENTRE )
275 updateType[tri[2]] |= FACECENTRE;
280 //- update coordinates of buffer layer points
281 if( Pstream::parRun() )
283 const labelLongList& bufferLayerPoints = this->bufferLayerPoints();
284 const VRWGraph& pProcs = this->pointAtProcs();
285 const labelLongList& globalPointLabel = this->globalPointLabel();
286 const Map<label>& globalToLocal = this->globalToLocalPointAddressing();
287 const DynList<label>& neiProcs = this->neiProcs();
290 std::map<label, LongList<labelledPoint> > exchangeData;
294 std::make_pair(neiProcs[i], LongList<labelledPoint>())
297 //- add points into the map
298 forAll(bufferLayerPoints, pI)
300 const label pointI = bufferLayerPoints[pI];
302 if( !(updateType[pointI] & SMOOTH) )
305 forAllRow(pProcs, pointI, i)
307 const label neiProc = pProcs(pointI, i);
309 if( neiProc == Pstream::myProcNo() )
312 exchangeData[neiProc].append
314 labelledPoint(globalPointLabel[pointI], pts[pointI])
319 LongList<labelledPoint> receivedData;
320 help::exchangeMap(exchangeData, receivedData);
322 forAll(receivedData, i)
324 const labelledPoint& lp = receivedData[i];
326 const label triPointI = globalToLocal[lp.pointLabel()];
327 pts[triPointI] = lp.coordinates();
329 forAllRow(pointFacets, triPointI, ptI)
331 const labelledTri& tri = surf_[pointFacets(triPointI, ptI)];
333 if( pointType_[tri[2]] & FACECENTRE )
334 updateType[tri[2]] |= FACECENTRE;
339 //- update coordinates of FACECENTRE vertices
341 # pragma omp parallel for schedule(dynamic, 20)
343 forAll(updateType, pI)
345 if( updateType[pI] & FACECENTRE )
347 point centre(vector::zero);
348 scalar faceArea(0.0);
349 forAllRow(pointFacets, pI, ptI)
351 const labelledTri& tri = surf_[pointFacets(pI, ptI)];
352 point c(vector::zero);
353 for(label i=0;i<3;++i)
356 const scalar area = tri.mag(pts) + VSMALL;
362 pts[pI] = centre / faceArea;
366 if( Pstream::parRun() )
367 updateBufferLayers();
370 void partTriMesh::updateVertices()
372 const meshSurfaceEngine& mse = mPart_.surfaceEngine();
373 const labelList& bPoints = mse.boundaryPoints();
374 labelLongList movedPoints(bPoints.size());
375 forAll(movedPoints, i)
378 updateVertices(movedPoints);
381 void partTriMesh::updateVertices(const labelLongList& movedPoints)
383 const meshSurfaceEngine& mse = mPart_.surfaceEngine();
384 const pointFieldPMG& points = mse.points();
385 const labelList& bPoints = mse.boundaryPoints();
387 triSurfModifier sMod(surf_);
388 pointField& pts = sMod.pointsAccess();
389 const VRWGraph& pointFacets = surf_.pointFacets();
391 List<direction> updateType(pts.size(), direction(0));
393 //- update coordinates of vertices which exist in the surface
394 //- of the volume mesh
396 # pragma omp parallel for schedule(dynamic, 50)
398 forAll(movedPoints, i)
400 const label bpI = movedPoints[i];
401 const label pointI = bPoints[bpI];
402 const label triPointI = meshSurfacePointLabelInTriMesh_[bpI];
407 pts[triPointI] = points[pointI];
408 updateType[triPointI] |= SMOOTH;
410 forAllRow(pointFacets, triPointI, ptI)
412 const labelledTri& tri = surf_[pointFacets(triPointI, ptI)];
414 if( pointType_[tri[2]] & FACECENTRE )
415 updateType[tri[2]] |= FACECENTRE;
419 //- update coordinates of buffer layer points
420 if( Pstream::parRun() )
422 const labelLongList& bufferLayerPoints = this->bufferLayerPoints();
423 const VRWGraph& pProcs = this->pointAtProcs();
424 const labelLongList& globalPointLabel = this->globalPointLabel();
425 const Map<label>& globalToLocal = this->globalToLocalPointAddressing();
426 const DynList<label>& neiProcs = this->neiProcs();
429 std::map<label, LongList<labelledPoint> > exchangeData;
433 std::make_pair(neiProcs[i], LongList<labelledPoint>())
436 //- add points into the map
437 forAll(bufferLayerPoints, pI)
439 const label pointI = bufferLayerPoints[pI];
441 if( !(updateType[pointI] & SMOOTH) )
444 forAllRow(pProcs, pointI, i)
446 const label neiProc = pProcs(pointI, i);
448 if( neiProc == Pstream::myProcNo() )
451 exchangeData[neiProc].append
453 labelledPoint(globalPointLabel[pointI], pts[pointI])
458 LongList<labelledPoint> receivedData;
459 help::exchangeMap(exchangeData, receivedData);
461 forAll(receivedData, i)
463 const labelledPoint& lp = receivedData[i];
465 const label triPointI = globalToLocal[lp.pointLabel()];
466 pts[triPointI] = lp.coordinates();
468 forAllRow(pointFacets, triPointI, ptI)
470 const labelledTri& tri = surf_[pointFacets(triPointI, ptI)];
472 if( pointType_[tri[2]] & FACECENTRE )
473 updateType[tri[2]] |= FACECENTRE;
478 //- update coordinates of FACECENTRE vertices
480 # pragma omp parallel for schedule(dynamic, 20)
482 forAll(updateType, pI)
484 if( updateType[pI] & FACECENTRE )
486 point centre(vector::zero);
487 scalar faceArea(0.0);
488 forAllRow(pointFacets, pI, ptI)
490 const labelledTri& tri = surf_[pointFacets(pI, ptI)];
491 point c(vector::zero);
492 for(label i=0;i<3;++i)
495 const scalar area = tri.mag(pts) + VSMALL;
501 pts[pI] = centre / faceArea;
505 if( Pstream::parRun() )
506 updateBufferLayers();
509 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
511 } // End namespace Foam
513 // ************************************************************************* //