1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM 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 OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 \*---------------------------------------------------------------------------*/
27 #include "cellQuality.H"
28 #include "unitConversion.H"
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 Foam::cellQuality::cellQuality(const polyMesh& mesh)
39 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
41 Foam::tmp<Foam::scalarField> Foam::cellQuality::nonOrthogonality() const
43 tmp<scalarField> tresult
51 scalarField& result = tresult();
53 scalarField sumArea(mesh_.nCells(), 0.0);
55 const vectorField& centres = mesh_.cellCentres();
56 const vectorField& areas = mesh_.faceAreas();
58 const labelList& own = mesh_.faceOwner();
59 const labelList& nei = mesh_.faceNeighbour();
63 vector d = centres[nei[faceI]] - centres[own[faceI]];
64 vector s = areas[faceI];
68 radToDeg(Foam::acos(min(1.0, (d & s)/(mag(d)*magS + VSMALL))));
70 result[own[faceI]] = max(cosDDotS, result[own[faceI]]);
72 result[nei[faceI]] = max(cosDDotS, result[nei[faceI]]);
75 forAll(mesh_.boundaryMesh(), patchI)
77 const labelUList& faceCells =
78 mesh_.boundaryMesh()[patchI].faceCells();
80 const vectorField::subField faceCentres =
81 mesh_.boundaryMesh()[patchI].faceCentres();
83 const vectorField::subField faceAreas =
84 mesh_.boundaryMesh()[patchI].faceAreas();
86 forAll(faceCentres, faceI)
88 vector d = faceCentres[faceI] - centres[faceCells[faceI]];
89 vector s = faceAreas[faceI];
93 radToDeg(Foam::acos(min(1.0, (d & s)/(mag(d)*magS + VSMALL))));
95 result[faceCells[faceI]] = max(cosDDotS, result[faceCells[faceI]]);
103 Foam::tmp<Foam::scalarField> Foam::cellQuality::skewness() const
105 tmp<scalarField> tresult
112 scalarField& result = tresult();
114 scalarField sumArea(mesh_.nCells(), 0.0);
116 const vectorField& cellCtrs = mesh_.cellCentres();
117 const vectorField& faceCtrs = mesh_.faceCentres();
118 const vectorField& areas = mesh_.faceAreas();
120 const labelList& own = mesh_.faceOwner();
121 const labelList& nei = mesh_.faceNeighbour();
127 (faceCtrs[faceI] - cellCtrs[own[faceI]]) & areas[faceI]
132 (cellCtrs[nei[faceI]] - faceCtrs[faceI]) & areas[faceI]
135 point faceIntersection =
137 + (dOwn/(dOwn+dNei))*(cellCtrs[nei[faceI]] - cellCtrs[own[faceI]]);
140 mag(faceCtrs[faceI] - faceIntersection)
141 /(mag(cellCtrs[nei[faceI]] - cellCtrs[own[faceI]]) + VSMALL);
143 result[own[faceI]] = max(skewness, result[own[faceI]]);
145 result[nei[faceI]] = max(skewness, result[nei[faceI]]);
148 forAll(mesh_.boundaryMesh(), patchI)
150 const labelUList& faceCells =
151 mesh_.boundaryMesh()[patchI].faceCells();
153 const vectorField::subField faceCentres =
154 mesh_.boundaryMesh()[patchI].faceCentres();
156 const vectorField::subField faceAreas =
157 mesh_.boundaryMesh()[patchI].faceAreas();
159 forAll(faceCentres, faceI)
161 vector n = faceAreas[faceI]/mag(faceAreas[faceI]);
163 point faceIntersection =
164 cellCtrs[faceCells[faceI]]
165 + ((faceCentres[faceI] - cellCtrs[faceCells[faceI]])&n)*n;
168 mag(faceCentres[faceI] - faceIntersection)
170 mag(faceCentres[faceI] - cellCtrs[faceCells[faceI]])
174 result[faceCells[faceI]] = max(skewness, result[faceCells[faceI]]);
182 Foam::tmp<Foam::scalarField> Foam::cellQuality::faceNonOrthogonality() const
184 tmp<scalarField> tresult
191 scalarField& result = tresult();
194 const vectorField& centres = mesh_.cellCentres();
195 const vectorField& areas = mesh_.faceAreas();
197 const labelList& own = mesh_.faceOwner();
198 const labelList& nei = mesh_.faceNeighbour();
202 vector d = centres[nei[faceI]] - centres[own[faceI]];
203 vector s = areas[faceI];
204 scalar magS = mag(s);
207 radToDeg(Foam::acos(min(1.0, (d & s)/(mag(d)*magS + VSMALL))));
209 result[faceI] = cosDDotS;
212 label globalFaceI = mesh_.nInternalFaces();
214 forAll(mesh_.boundaryMesh(), patchI)
216 const labelUList& faceCells =
217 mesh_.boundaryMesh()[patchI].faceCells();
219 const vectorField::subField faceCentres =
220 mesh_.boundaryMesh()[patchI].faceCentres();
222 const vectorField::subField faceAreas =
223 mesh_.boundaryMesh()[patchI].faceAreas();
225 forAll(faceCentres, faceI)
227 vector d = faceCentres[faceI] - centres[faceCells[faceI]];
228 vector s = faceAreas[faceI];
229 scalar magS = mag(s);
232 radToDeg(Foam::acos(min(1.0, (d & s)/(mag(d)*magS + VSMALL))));
234 result[globalFaceI++] = cosDDotS;
242 Foam::tmp<Foam::scalarField> Foam::cellQuality::faceSkewness() const
244 tmp<scalarField> tresult
251 scalarField& result = tresult();
254 const vectorField& cellCtrs = mesh_.cellCentres();
255 const vectorField& faceCtrs = mesh_.faceCentres();
256 const vectorField& areas = mesh_.faceAreas();
258 const labelList& own = mesh_.faceOwner();
259 const labelList& nei = mesh_.faceNeighbour();
265 (faceCtrs[faceI] - cellCtrs[own[faceI]]) & areas[faceI]
270 (cellCtrs[nei[faceI]] - faceCtrs[faceI]) & areas[faceI]
273 point faceIntersection =
275 + (dOwn/(dOwn+dNei))*(cellCtrs[nei[faceI]] - cellCtrs[own[faceI]]);
278 mag(faceCtrs[faceI] - faceIntersection)
279 /(mag(cellCtrs[nei[faceI]] - cellCtrs[own[faceI]]) + VSMALL);
283 label globalFaceI = mesh_.nInternalFaces();
285 forAll(mesh_.boundaryMesh(), patchI)
287 const labelUList& faceCells =
288 mesh_.boundaryMesh()[patchI].faceCells();
290 const vectorField::subField faceCentres =
291 mesh_.boundaryMesh()[patchI].faceCentres();
293 const vectorField::subField faceAreas =
294 mesh_.boundaryMesh()[patchI].faceAreas();
296 forAll(faceCentres, faceI)
298 vector n = faceAreas[faceI]/mag(faceAreas[faceI]);
300 point faceIntersection =
301 cellCtrs[faceCells[faceI]]
302 + ((faceCentres[faceI] - cellCtrs[faceCells[faceI]])&n)*n;
304 result[globalFaceI++] =
305 mag(faceCentres[faceI] - faceIntersection)
307 mag(faceCentres[faceI] - cellCtrs[faceCells[faceI]])
317 // ************************************************************************* //