1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
28 Smoothing mesh using Laplacian smoothing
30 \*---------------------------------------------------------------------------*/
33 #include "timeSelector.H"
34 #include "objectRegistry.H"
38 #include "emptyPolyPatch.H"
39 #include "twoDPointCorrector.H"
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 int main(int argc, char *argv[])
47 timeSelector::addOptions();
49 Foam::argList::validOptions.insert("smoothPatches", "");
51 # include "setRootCase.H"
52 # include "createTime.H"
53 instantList timeDirs = timeSelector::select0(runTime, args);
54 # include "createMesh.H"
56 // bool smoothPatches = args.optionFound("smoothPatches");
58 // Info << "Smoothing patches" << nl << endl;
60 // Smooth internal points
62 const vectorField& oldPoints = mesh.points();
64 vectorField newPoints = oldPoints;
66 if (mesh.nGeometricD() == 3)
68 Info << "3-D mesh" << endl;
70 const labelListList& pointEdges = mesh.pointEdges();
71 const edgeList& edges = mesh.edges();
73 boolList fixedPoints(newPoints.size(), false);
75 forAll(mesh.boundaryMesh(), patchI)
77 const labelList& meshPoints =
78 mesh.boundaryMesh()[patchI].meshPoints();
80 forAll(meshPoints, pointI)
82 fixedPoints[meshPoints[pointI]] = true;
86 scalarField residual(newPoints.size(), 0);
92 forAll(newPoints, pointI)
94 if (!fixedPoints[pointI])
96 vector curNewPoint = vector::zero;
100 forAll(pointEdges[pointI], eI)
102 label curEdgeIndex = pointEdges[pointI][eI];
104 const edge& curEdge = edges[curEdgeIndex];
107 newPoints[curEdge.otherVertex(pointI)]
119 curNewPoint += newPoints[pointI];
121 residual[pointI] = mag(curNewPoint - newPoints[pointI]);
123 newPoints[pointI] = curNewPoint;
127 // smoothed patch points independently
128 // but we do not smooth points on the boundary of the patch
129 // we reset these points
130 // problem: we need to smooth feature edges separately
133 // forAll(mesh.boundaryMesh(), patchI)
135 // const labelList& meshPoints =
136 // mesh.boundaryMesh()[patchI].meshPoints();
138 // forAll(meshPoints, pointI)
140 // label pointID = meshPoints[pointI];
141 // vector curNewPoint = vector::zero;
144 // forAll(pointEdges[pointID], eI)
146 // label curEdgeIndex = pointEdges[pointID][eI];
147 // const edge& curEdge = edges[curEdgeIndex];
149 // // use only boundary points
150 // label otherPointID = curEdge.otherVertex(pointID);
151 // if(fixedPoints[otherPointID])
154 // newPoints[otherPointID]
155 // - newPoints[pointID];
158 // curNewPoint += w*d;
163 // curNewPoint /= sumW;
164 // curNewPoint += newPoints[pointID];
165 // residual[pointID] = mag(curNewPoint - newPoints[pointID]);
166 // newPoints[pointID] = curNewPoint;
169 // // reset boundary points
170 // const labelList& boundaryPoints =
171 // mesh.boundaryMesh()[patchI].boundaryPoints();
172 // forAll(boundaryPoints, bpi)
174 // label boundaryPointID = meshPoints[boundaryPoints[bpi]];
175 // newPoints[boundaryPointID] = oldPoints[boundaryPointID];
176 // residual[boundaryPointID] = 0.0;
181 residual /= max(mag(newPoints - oldPoints) + SMALL);
183 while(max(residual) > 1e-3);
185 Info << "Internal points, max residual: " << max(residual)
186 << ", num of iterations: " << counter << endl;
188 twoDPointCorrector twoDCorrector(mesh);
189 twoDCorrector.correctPoints(newPoints);
193 Info << "2-D mesh" << endl;
195 forAll(mesh.boundaryMesh(), patchI)
199 mesh.boundaryMesh()[patchI].type()
200 == emptyPolyPatch::typeName
203 const labelList& bPoints =
204 mesh.boundaryMesh()[patchI].boundaryPoints();
206 const vectorField& oldPatchPoints =
207 mesh.boundaryMesh()[patchI].localPoints();
209 vectorField newPatchPoints = oldPatchPoints;
211 const labelListList& patchPointEdges =
212 mesh.boundaryMesh()[patchI].pointEdges();
214 const edgeList& patchEdges =
215 mesh.boundaryMesh()[patchI].edges();
217 boolList fixedPoints(newPatchPoints.size(), false);
219 forAll(bPoints, pointI)
221 fixedPoints[bPoints[pointI]] = true;
224 scalarField residual(newPatchPoints.size(), 0);
230 forAll(newPatchPoints, pointI)
232 if (!fixedPoints[pointI])
234 vector curNewPatchPoint = vector::zero;
238 forAll(patchPointEdges[pointI], eI)
241 patchPointEdges[pointI][eI];
243 const edge& curEdge = patchEdges[curEdgeIndex];
246 newPatchPoints[curEdge.otherVertex(pointI)]
247 - newPatchPoints[pointI];
251 curNewPatchPoint += w*d;
256 curNewPatchPoint /= sumW;
258 curNewPatchPoint += newPatchPoints[pointI];
261 mag(curNewPatchPoint - newPatchPoints[pointI]);
263 newPatchPoints[pointI] = curNewPatchPoint;
268 max(mag(newPatchPoints - oldPatchPoints) + SMALL);
270 while(max(residual) > 1e-6);
272 Info << "Empty points, max residual: " << max(residual)
273 << ", num of iterations: " << counter << endl;
275 const labelList& meshPoints =
276 mesh.boundaryMesh()[patchI].meshPoints();
278 forAll(meshPoints, pointI)
280 newPoints[meshPoints[pointI]] = newPatchPoints[pointI];
287 twoDPointCorrector twoDCorrector(mesh);
288 twoDCorrector.correctPoints(newPoints);
290 mesh.movePoints(newPoints);
296 Info<< "End\n" << endl;
302 // ************************************************************************* //