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 / meshOptimizer.C
blobfb873ac296fddb0d87170eb62e8f474a3746d22a
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 "meshSurfaceEngine.H"
31 #include "meshSurfacePartitioner.H"
32 #include "polyMeshGenAddressing.H"
33 #include "polyMeshGenChecks.H"
34 #include "labelLongList.H"
36 // #define DEBUGSmoothing
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 namespace Foam
43 // * * * * * * * * Private member functions * * * * * * * * * * * * * * * * * //
45 const meshSurfaceEngine& meshOptimizer::meshSurface() const
47     if( !msePtr_ )
48         msePtr_ = new meshSurfaceEngine(mesh_);
50     return *msePtr_;
53 void meshOptimizer::clearSurface()
55     deleteDemandDrivenData(msePtr_);
58 label meshOptimizer::findBadFaces
60     labelHashSet& badFaces,
61     const boolList& changedFace
62 ) const
64     badFaces.clear();
66     polyMeshGenChecks::checkFacePyramids
67     (
68         mesh_,
69         false,
70         VSMALL,
71         &badFaces,
72         &changedFace
73     );
75     polyMeshGenChecks::checkFaceFlatness
76     (
77         mesh_,
78         false,
79         0.8,
80         &badFaces,
81         &changedFace
82     );
84     polyMeshGenChecks::checkCellPartTetrahedra
85     (
86         mesh_,
87         false,
88         VSMALL,
89         &badFaces,
90         &changedFace
91     );
93     polyMeshGenChecks::checkFaceAreas
94     (
95         mesh_,
96         false,
97         VSMALL,
98         &badFaces,
99         &changedFace
100     );
102     const label nBadFaces = returnReduce(badFaces.size(), sumOp<label>());
104     return nBadFaces;
107 label meshOptimizer::findLowQualityFaces
109     labelHashSet& badFaces,
110     const boolList& changedFace
111 ) const
113     badFaces.clear();
115     polyMeshGenChecks::checkFaceDotProduct
116     (
117         mesh_,
118         false,
119         70.0,
120         &badFaces
121     );
123     polyMeshGenChecks::checkFaceSkewness
124     (
125         mesh_,
126         false,
127         2.0,
128         &badFaces
129     );
131     const label nBadFaces = returnReduce(badFaces.size(), sumOp<label>());
133     return nBadFaces;
136 void meshOptimizer::calculatePointLocations()
138     vertexLocation_.setSize(mesh_.points().size());
139     vertexLocation_ = INSIDE;
141     const meshSurfaceEngine& mse = meshSurface();
142     const labelList& bPoints = mse.boundaryPoints();
144     //- mark boundary vertices
145     forAll(bPoints, bpI)
146         vertexLocation_[bPoints[bpI]] = BOUNDARY;
148     //- mark edge vertices
149     meshSurfacePartitioner mPart(mse);
150     forAllConstIter(labelHashSet, mPart.edgePoints(), it)
151         vertexLocation_[bPoints[it.key()]] = EDGE;
153     //- mark corner vertices
154     forAllConstIter(labelHashSet, mPart.corners(), it)
155         vertexLocation_[bPoints[it.key()]] = CORNER;
157     if( Pstream::parRun() )
158     {
159         const polyMeshGenAddressing& addresing = mesh_.addressingData();
160         const VRWGraph& pointAtProcs = addresing.pointAtProcs();
162         forAll(pointAtProcs, pointI)
163             if( pointAtProcs.sizeOfRow(pointI) != 0 )
164                 vertexLocation_[pointI] |= PARALLELBOUNDARY;
165     }
168 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
170 // Construct from mesh
171 meshOptimizer::meshOptimizer(polyMeshGen& mesh)
173     mesh_(mesh),
174     vertexLocation_(),
175     lockedFaces_(),
176     msePtr_(NULL),
177     enforceConstraints_(false),
178     badPointsSubsetName_()
180     calculatePointLocations();
183 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
185 meshOptimizer::~meshOptimizer()
187     clearSurface();
190 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
192 void meshOptimizer::enforceConstraints(const word subsetName)
194     enforceConstraints_ = true;
196     badPointsSubsetName_ = subsetName;
199 void meshOptimizer::lockCellsInSubset(const word& subsetName)
201     //- lock the points in the cell subset with the given name
202     label subsetI = mesh_.cellSubsetIndex(subsetName);
203     if( subsetI >= 0 )
204     {
205         labelLongList lc;
206         mesh_.cellsInSubset(subsetI, lc);
208         lockCells(lc);
209     }
210     else
211     {
212         Warning << "Subset " << subsetName << " is not a cell subset!"
213             << " Cannot lock cells!" << endl;
214     }
217 void meshOptimizer::lockFacesInSubset(const word& subsetName)
219     //- lock the points in the face subset with the given name
220     label subsetI = mesh_.faceSubsetIndex(subsetName);
221     if( subsetI >= 0 )
222     {
223         labelLongList lf;
224         mesh_.facesInSubset(subsetI, lf);
226         lockFaces(lf);
227     }
228     else
229     {
230         Warning << "Subset " << subsetName << " is not a face subset!"
231             << " Cannot lock faces!" << endl;
232     }
235 void meshOptimizer::lockPointsInSubset(const word& subsetName)
237     //- lock the points in the point subset with the given name
238     label subsetI = mesh_.pointSubsetIndex(subsetName);
239     if( subsetI >= 0 )
240     {
241         labelLongList lp;
242         mesh_.pointsInSubset(subsetI, lp);
244         lockCells(lp);
245     }
246     else
247     {
248         Warning << "Subset " << subsetName << " is not a point subset!"
249             << " Cannot lock points!" << endl;
250     }
253 void meshOptimizer::removeUserConstraints()
255     lockedFaces_.setSize(0);
257     //- unlock points
258     # ifdef USE_OMP
259     # pragma omp parallel for schedule(dynamic, 50)
260     # endif
261     forAll(vertexLocation_, i)
262     {
263         if( vertexLocation_[i] & LOCKED )
264             vertexLocation_[i] ^= LOCKED;
265     }
268 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
270 } // End namespace Foam
272 // ************************************************************************* //