Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / mesh / cfMesh / utilities / smoothers / geometry / meshOptimizer / meshOptimizerOptimizePoint.C
blob87cc7e72af1f516a9869f3fa6749fecc9cc56799
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.
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
19     for more details.
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/>.
24 Description
26 \*---------------------------------------------------------------------------*/
28 #include "demandDrivenData.H"
29 #include "meshOptimizer.H"
30 #include "polyMeshGenAddressing.H"
31 #include "meshSurfaceEngine.H"
33 # ifdef USE_OMP
34 #include <omp.h>
35 # endif
37 //#define DEBUGSmooth
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 namespace Foam
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)
56     {
57         labelLongList procPoints;
59         forAll(smoothPoints, i)
60         {
61             const label pointI = smoothPoints[i];
63             if( vertexLocation_[pointI] & LOCKED )
64                 continue;
66             if( vertexLocation_[pointI] & PARALLELBOUNDARY )
67             {
68                 procPoints.append(pointI);
70                 continue;
71             }
73             vector newP(vector::zero);
75             const label nPointPoints = pPoints.sizeOfRow(pointI);
77             if( nPointPoints == 0 )
78                 return;
80             for(label pI=0;pI<nPointPoints;++pI)
81                 newP += points[pPoints(pointI, pI)];
83             newP /= pPoints.sizeOfRow(pointI);
84             points[pointI] = newP;
85         }
87         laplacianParallel(procPoints, false);
88     }
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)
103     {
104         labelLongList procPoints;
106         forAll(smoothPoints, i)
107         {
108             const label pointI = smoothPoints[i];
110             if( vertexLocation_[pointI] & LOCKED )
111                 continue;
113             if( vertexLocation_[pointI] & PARALLELBOUNDARY )
114             {
115                 procPoints.append(pointI);
117                 continue;
118             }
120             vector newP(vector::zero);
122             label counter(0);
123             forAllRow(pPoints, pointI, pI)
124             {
125                 const label pLabel = pPoints(pointI, pI);
126                 if( vertexLocation_[pLabel] & INSIDE )
127                     continue;
129                 newP += points[pLabel];
130                 ++counter;
131             }
133             if( counter != 0 )
134             {
135                 newP /= counter;
136                 points[pointI] = newP;
137             }
138         }
140         laplacianParallel(smoothPoints, true);
141     }
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)
157     {
158         labelLongList procPoints;
160         # ifdef USE_OMP
161         # pragma omp parallel for schedule(dynamic, 20)
162         # endif
163         forAll(smoothPoints, i)
164         {
165             const label pointI = smoothPoints[i];
167             if( vertexLocation_[pointI] & LOCKED )
168                 continue;
170             if( pointCells.sizeOfRow(pointI) == 0 )
171                 continue;
173             if( vertexLocation_[pointI] & PARALLELBOUNDARY )
174             {
175                 # ifdef USE_OMP
176                 # pragma omp critical
177                 # endif
178                 procPoints.append(pointI);
180                 continue;
181             }
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;
190         }
192         laplacianPCParallel(procPoints);
194         updateMeshGeometry(smoothPoints);
195     }
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)
211     {
212         labelLongList procPoints;
214         # ifdef USE_OMP
215         # pragma omp parallel for schedule(dynamic, 20)
216         # endif
217         forAll(smoothPoints, i)
218         {
219             const label pointI = smoothPoints[i];
221             if( vertexLocation_[pointI] & LOCKED )
222                 continue;
224             if( pointCells.sizeOfRow(pointI) == 0 )
225                 continue;
227             if( vertexLocation_[pointI] & PARALLELBOUNDARY )
228             {
229                 # ifdef USE_OMP
230                 # pragma omp critical
231                 # endif
232                 procPoints.append(pointI);
234                 continue;
235             }
237             point newP(vector::zero);
238             scalar sumWeights(0.0);
239             forAllRow(pointCells, pointI, pcI)
240             {
241                 const label cellI = pointCells(pointI, pcI);
242                 const scalar w = Foam::max(volumes[cellI], VSMALL);
243                 newP += w * centres[cellI];
244                 sumWeights += w;
245             }
247             newP /= sumWeights;
248             points[pointI] = newP;
249         }
251         laplacianWPCParallel(procPoints);
253         updateMeshGeometry(smoothPoints);
254     }
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);
267     # ifdef USE_OMP
268     # pragma omp parallel for if( smoothPoints.size() > 100 ) \
269     schedule(dynamic, 20)
270     # endif
271     forAll(smoothPoints, i)
272     {
273         const label pointI = smoothPoints[i];
275         if( vertexLocation_[pointI] & LOCKED )
276             continue;
278         forAllRow(pointCells, pointI, pcI)
279         {
280             const cell& c = cells[pointCells(pointI, pcI)];
282             forAll(c, fI)
283                 chF[c[fI]] = true;
284         }
285     }
287     //- make sure that neighbouring processors get the same information
288     const PtrList<processorBoundaryPatch>& pBnd = mesh_.procBoundaries();
289     forAll(pBnd, patchI)
290     {
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)
296         {
297             if( chF[start+faceI] )
298                 sendData.append(faceI);
299         }
301         OPstream toOtherProc
302         (
303             Pstream::blocking,
304             pBnd[patchI].neiProcNo(),
305             sendData.byteSize()
306         );
308         toOtherProc << sendData;
309     }
311     forAll(pBnd, patchI)
312     {
313         labelList receivedData;
315         IPstream fromOtherProc
316         (
317             Pstream::blocking,
318             pBnd[patchI].neiProcNo()
319         );
321         fromOtherProc >> receivedData;
323         const label start = pBnd[patchI].patchStart();
324         forAll(receivedData, i)
325             chF[start+receivedData[i]] = true;
326     }
328     //- update geometry information
329     const_cast<polyMeshGenAddressing&>
330     (
331         mesh_.addressingData()
332     ).updateGeometry(chF);
335 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
336 // Constructor of laplaceSmoother
338 meshOptimizer::laplaceSmoother::laplaceSmoother
340     polyMeshGen& mesh,
341     const List<direction>& vertexLocation
344     mesh_(mesh),
345     vertexLocation_(vertexLocation)
348 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
350 meshOptimizer::laplaceSmoother::~laplaceSmoother()
353 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
354 // Member Functions
356 void meshOptimizer::laplaceSmoother::optimizeLaplacian(const label nIterations)
358     labelLongList smoothPoints;
360     forAll(vertexLocation_, pointI)
361     {
362         if( vertexLocation_[pointI] & INSIDE )
363             smoothPoints.append(pointI);
364     }
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)
395     {
396         if( vertexLocation_[pointI] & INSIDE )
397             smoothPoints.append(pointI);
398     }
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)
420     {
421         if( vertexLocation_[pointI] & INSIDE )
422             smoothPoints.append(pointI);
423     }
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 // ************************************************************************* //