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] & LOCKED )
66 if( vertexLocation_[pointI] & PARALLELBOUNDARY )
68 procPoints.append(pointI);
73 vector newP(vector::zero);
75 const label nPointPoints = pPoints.sizeOfRow(pointI);
77 if( nPointPoints == 0 )
80 for(label pI=0;pI<nPointPoints;++pI)
81 newP += points[pPoints(pointI, pI)];
83 newP /= pPoints.sizeOfRow(pointI);
84 points[pointI] = newP;
87 laplacianParallel(procPoints, false);
90 updateMeshGeometry(smoothPoints);
93 void meshOptimizer::laplaceSmoother::laplacianSurface
95 const labelLongList& smoothPoints,
96 const label nIterations
99 const VRWGraph& pPoints = mesh_.addressingData().pointPoints();
100 pointFieldPMG& points = mesh_.points();
102 for(label iterationI=0;iterationI<nIterations;++iterationI)
104 labelLongList procPoints;
106 forAll(smoothPoints, i)
108 const label pointI = smoothPoints[i];
110 if( vertexLocation_[pointI] & LOCKED )
113 if( vertexLocation_[pointI] & PARALLELBOUNDARY )
115 procPoints.append(pointI);
120 vector newP(vector::zero);
123 forAllRow(pPoints, pointI, pI)
125 const label pLabel = pPoints(pointI, pI);
126 if( vertexLocation_[pLabel] & INSIDE )
129 newP += points[pLabel];
136 points[pointI] = newP;
140 laplacianParallel(smoothPoints, true);
143 updateMeshGeometry(smoothPoints);
146 void meshOptimizer::laplaceSmoother::laplacianPC
148 const labelLongList& smoothPoints,
149 const label nIterations
152 const VRWGraph& pointCells = mesh_.addressingData().pointCells();
153 const vectorField& centres = mesh_.addressingData().cellCentres();
154 pointFieldPMG& points = mesh_.points();
156 for(label iterationI=0;iterationI<nIterations;++iterationI)
158 labelLongList procPoints;
161 # pragma omp parallel for schedule(dynamic, 20)
163 forAll(smoothPoints, i)
165 const label pointI = smoothPoints[i];
167 if( vertexLocation_[pointI] & LOCKED )
170 if( pointCells.sizeOfRow(pointI) == 0 )
173 if( vertexLocation_[pointI] & PARALLELBOUNDARY )
176 # pragma omp critical
178 procPoints.append(pointI);
183 point newP(vector::zero);
184 forAllRow(pointCells, pointI, pcI)
185 newP += centres[pointCells(pointI, pcI)];
187 newP /= pointCells.sizeOfRow(pointI);
189 points[pointI] = newP;
192 laplacianPCParallel(procPoints);
194 updateMeshGeometry(smoothPoints);
198 void meshOptimizer::laplaceSmoother::laplacianWPC
200 const labelLongList& smoothPoints,
201 const label nIterations
204 const VRWGraph& pointCells = mesh_.addressingData().pointCells();
205 const vectorField& centres = mesh_.addressingData().cellCentres();
206 const scalarField& volumes = mesh_.addressingData().cellVolumes();
208 pointFieldPMG& points = mesh_.points();
210 for(label iterationI=0;iterationI<nIterations;++iterationI)
212 labelLongList procPoints;
215 # pragma omp parallel for schedule(dynamic, 20)
217 forAll(smoothPoints, i)
219 const label pointI = smoothPoints[i];
221 if( vertexLocation_[pointI] & LOCKED )
224 if( pointCells.sizeOfRow(pointI) == 0 )
227 if( vertexLocation_[pointI] & PARALLELBOUNDARY )
230 # pragma omp critical
232 procPoints.append(pointI);
237 point newP(vector::zero);
238 scalar sumWeights(0.0);
239 forAllRow(pointCells, pointI, pcI)
241 const label cellI = pointCells(pointI, pcI);
242 const scalar w = Foam::max(volumes[cellI], VSMALL);
243 newP += w * centres[cellI];
248 points[pointI] = newP;
251 laplacianWPCParallel(procPoints);
253 updateMeshGeometry(smoothPoints);
257 void meshOptimizer::laplaceSmoother::updateMeshGeometry
259 const labelLongList& smoothPoints
262 const cellListPMG& cells = mesh_.cells();
263 const VRWGraph& pointCells = mesh_.addressingData().pointCells();
265 boolList chF(mesh_.faces().size(), false);
268 # pragma omp parallel for if( smoothPoints.size() > 100 ) \
269 schedule(dynamic, 20)
271 forAll(smoothPoints, i)
273 const label pointI = smoothPoints[i];
275 if( vertexLocation_[pointI] & LOCKED )
278 forAllRow(pointCells, pointI, pcI)
280 const cell& c = cells[pointCells(pointI, pcI)];
287 //- make sure that neighbouring processors get the same information
288 const PtrList<processorBoundaryPatch>& pBnd = mesh_.procBoundaries();
291 const label start = pBnd[patchI].patchStart();
292 const label size = pBnd[patchI].patchSize();
294 labelLongList sendData;
295 for(label faceI=0;faceI<size;++faceI)
297 if( chF[start+faceI] )
298 sendData.append(faceI);
304 pBnd[patchI].neiProcNo(),
308 toOtherProc << sendData;
313 labelList receivedData;
315 IPstream fromOtherProc
318 pBnd[patchI].neiProcNo()
321 fromOtherProc >> receivedData;
323 const label start = pBnd[patchI].patchStart();
324 forAll(receivedData, i)
325 chF[start+receivedData[i]] = true;
328 //- update geometry information
329 const_cast<polyMeshGenAddressing&>
331 mesh_.addressingData()
332 ).updateGeometry(chF);
335 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
336 // Constructor of laplaceSmoother
338 meshOptimizer::laplaceSmoother::laplaceSmoother
341 const List<direction>& vertexLocation
345 vertexLocation_(vertexLocation)
348 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
350 meshOptimizer::laplaceSmoother::~laplaceSmoother()
353 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
356 void meshOptimizer::laplaceSmoother::optimizeLaplacian(const label nIterations)
358 labelLongList smoothPoints;
360 forAll(vertexLocation_, pointI)
362 if( vertexLocation_[pointI] & INSIDE )
363 smoothPoints.append(pointI);
366 laplacian(smoothPoints, nIterations);
369 void meshOptimizer::laplaceSmoother::optimizeLaplacian
371 const labelHashSet& badFaces,
372 const label nIterations
375 FatalError << "Not implemented " << exit(FatalError);
378 void meshOptimizer::laplaceSmoother::optimizeSurfaceLaplacian
380 const labelHashSet& badFaces,
381 const label nIterations
384 FatalError << "Not implemented " << exit(FatalError);
387 void meshOptimizer::laplaceSmoother::optimizeLaplacianPC
389 const label nIterations
392 labelLongList smoothPoints;
394 forAll(vertexLocation_, pointI)
396 if( vertexLocation_[pointI] & INSIDE )
397 smoothPoints.append(pointI);
400 laplacianPC(smoothPoints, nIterations);
403 void meshOptimizer::laplaceSmoother::optimizeLaplacianPC
405 const labelHashSet& badFaces,
406 const label nIterations
409 FatalError << "Not implemented " << exit(FatalError);
412 void meshOptimizer::laplaceSmoother::optimizeLaplacianWPC
414 const label nIterations
417 labelLongList smoothPoints;
419 forAll(vertexLocation_, pointI)
421 if( vertexLocation_[pointI] & INSIDE )
422 smoothPoints.append(pointI);
425 laplacianWPC(smoothPoints, nIterations);
428 void meshOptimizer::laplaceSmoother::optimizeLaplacianWPC
430 const labelHashSet& badFaces,
431 const label nIterations
434 FatalError << "Not implemented " << exit(FatalError);
437 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
439 } // End namespace Foam
441 // ************************************************************************* //