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 "meshOptimizer.H"
30 #include "polyMeshGenAddressing.H"
31 #include "meshSurfaceEngine.H"
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 void meshOptimizer::laplaceSmoother::laplacian
48 const labelLongList& smoothPoints,
49 const label nIterations
52 const VRWGraph& pPoints = mesh_.addressingData().pointPoints();
53 pointFieldPMG& points = mesh_.points();
55 for(label iterationI=0;iterationI<nIterations;++iterationI)
57 labelLongList procPoints;
59 forAll(smoothPoints, i)
61 const label pointI = smoothPoints[i];
63 if( vertexLocation_[pointI] & PARALLELBOUNDARY )
65 procPoints.append(pointI);
70 vector newP(vector::zero);
72 const label nPointPoints = pPoints.sizeOfRow(pointI);
74 if( nPointPoints == 0 )
77 for(label pI=0;pI<nPointPoints;++pI)
78 newP += points[pPoints(pointI, pI)];
80 newP /= pPoints.sizeOfRow(pointI);
81 points[pointI] = newP;
84 laplacianParallel(procPoints, false);
87 updateMeshGeometry(smoothPoints);
90 void meshOptimizer::laplaceSmoother::laplacianSurface
92 const labelLongList& smoothPoints,
93 const label nIterations
96 const VRWGraph& pPoints = mesh_.addressingData().pointPoints();
97 pointFieldPMG& points = mesh_.points();
99 for(label iterationI=0;iterationI<nIterations;++iterationI)
101 labelLongList procPoints;
103 forAll(smoothPoints, i)
105 const label pointI = smoothPoints[i];
107 if( vertexLocation_[pointI] & PARALLELBOUNDARY )
109 procPoints.append(pointI);
114 vector newP(vector::zero);
117 forAllRow(pPoints, pointI, pI)
119 const label pLabel = pPoints(pointI, pI);
120 if( vertexLocation_[pLabel] & INSIDE )
123 newP += points[pLabel];
130 points[pointI] = newP;
134 laplacianParallel(smoothPoints, true);
137 updateMeshGeometry(smoothPoints);
140 void meshOptimizer::laplaceSmoother::laplacianPC
142 const labelLongList& smoothPoints,
143 const label nIterations
146 const VRWGraph& pointCells = mesh_.addressingData().pointCells();
147 const vectorField& centres = mesh_.addressingData().cellCentres();
148 pointFieldPMG& points = mesh_.points();
150 for(label iterationI=0;iterationI<nIterations;++iterationI)
152 labelLongList procPoints;
155 # pragma omp parallel for schedule(dynamic, 20)
157 forAll(smoothPoints, i)
159 const label pointI = smoothPoints[i];
161 if( pointCells.sizeOfRow(pointI) == 0 )
164 if( vertexLocation_[pointI] & PARALLELBOUNDARY )
167 # pragma omp critical
169 procPoints.append(pointI);
174 point newP(vector::zero);
175 forAllRow(pointCells, pointI, pcI)
176 newP += centres[pointCells(pointI, pcI)];
178 newP /= pointCells.sizeOfRow(pointI);
180 points[pointI] = newP;
183 laplacianPCParallel(procPoints);
185 updateMeshGeometry(smoothPoints);
189 void meshOptimizer::laplaceSmoother::laplacianWPC
191 const labelLongList& smoothPoints,
192 const label nIterations
195 const VRWGraph& pointCells = mesh_.addressingData().pointCells();
196 const vectorField& centres = mesh_.addressingData().cellCentres();
197 const scalarField& volumes = mesh_.addressingData().cellVolumes();
199 pointFieldPMG& points = mesh_.points();
201 for(label iterationI=0;iterationI<nIterations;++iterationI)
203 labelLongList procPoints;
206 # pragma omp parallel for schedule(dynamic, 20)
208 forAll(smoothPoints, i)
210 const label pointI = smoothPoints[i];
212 if( pointCells.sizeOfRow(pointI) == 0 )
215 if( vertexLocation_[pointI] & PARALLELBOUNDARY )
218 # pragma omp critical
220 procPoints.append(pointI);
225 point newP(vector::zero);
226 scalar sumWeights(0.0);
227 forAllRow(pointCells, pointI, pcI)
229 const label cellI = pointCells(pointI, pcI);
230 const scalar w = Foam::max(volumes[cellI], VSMALL);
231 newP += w * centres[cellI];
236 points[pointI] = newP;
239 laplacianWPCParallel(procPoints);
241 updateMeshGeometry(smoothPoints);
245 void meshOptimizer::laplaceSmoother::updateMeshGeometry
247 const labelLongList& smoothPoints
250 const cellListPMG& cells = mesh_.cells();
251 const VRWGraph& pointCells = mesh_.addressingData().pointCells();
253 boolList chF(mesh_.faces().size(), false);
256 # pragma omp parallel for if( smoothPoints.size() > 100 ) \
257 schedule(dynamic, 20)
259 forAll(smoothPoints, i)
261 const label pointI = smoothPoints[i];
263 forAllRow(pointCells, pointI, pcI)
265 const cell& c = cells[pointCells(pointI, pcI)];
272 //- make sure that neighbouring processors get the same information
273 const PtrList<processorBoundaryPatch>& pBnd = mesh_.procBoundaries();
276 const label start = pBnd[patchI].patchStart();
277 const label size = pBnd[patchI].patchSize();
279 labelLongList sendData;
280 for(label faceI=0;faceI<size;++faceI)
282 if( chF[start+faceI] )
283 sendData.append(faceI);
289 pBnd[patchI].neiProcNo(),
293 toOtherProc << sendData;
298 labelList receivedData;
300 IPstream fromOtherProc
303 pBnd[patchI].neiProcNo()
306 fromOtherProc >> receivedData;
308 const label start = pBnd[patchI].patchStart();
309 forAll(receivedData, i)
310 chF[start+receivedData[i]] = true;
313 //- update geometry information
314 const_cast<polyMeshGenAddressing&>
316 mesh_.addressingData()
317 ).updateGeometry(chF);
320 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
321 // Constructor of laplaceSmoother
323 meshOptimizer::laplaceSmoother::laplaceSmoother
326 const List<direction>& vertexLocation
330 vertexLocation_(vertexLocation)
333 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
335 meshOptimizer::laplaceSmoother::~laplaceSmoother()
338 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
341 void meshOptimizer::laplaceSmoother::optimizeLaplacian(const label nIterations)
343 labelLongList smoothPoints;
345 forAll(vertexLocation_, pointI)
346 if( vertexLocation_[pointI] & INSIDE )
347 smoothPoints.append(pointI);
349 laplacian(smoothPoints, nIterations);
352 void meshOptimizer::laplaceSmoother::optimizeLaplacian
354 const labelHashSet& badFaces,
355 const label nIterations
358 FatalError << "Not implemented " << exit(FatalError);
361 void meshOptimizer::laplaceSmoother::optimizeSurfaceLaplacian
363 const labelHashSet& badFaces,
364 const label nIterations
367 FatalError << "Not implemented " << exit(FatalError);
370 void meshOptimizer::laplaceSmoother::optimizeLaplacianPC
372 const label nIterations
375 labelLongList smoothPoints;
377 forAll(vertexLocation_, pointI)
378 if( vertexLocation_[pointI] & INSIDE )
379 smoothPoints.append(pointI);
381 laplacianPC(smoothPoints, nIterations);
384 void meshOptimizer::laplaceSmoother::optimizeLaplacianPC
386 const labelHashSet& badFaces,
387 const label nIterations
390 FatalError << "Not implemented " << exit(FatalError);
393 void meshOptimizer::laplaceSmoother::optimizeLaplacianWPC
395 const label nIterations
398 labelLongList smoothPoints;
400 forAll(vertexLocation_, pointI)
401 if( vertexLocation_[pointI] & INSIDE )
402 smoothPoints.append(pointI);
404 laplacianWPC(smoothPoints, nIterations);
407 void meshOptimizer::laplaceSmoother::optimizeLaplacianWPC
409 const labelHashSet& badFaces,
410 const label nIterations
413 FatalError << "Not implemented " << exit(FatalError);
416 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
418 } // End namespace Foam
420 // ************************************************************************* //