Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "cellQuality.H"
00030 #include <OpenFOAM/mathematicalConstants.H>
00031
00032
00033
00034
00035 Foam::cellQuality::cellQuality(const polyMesh& mesh)
00036 :
00037 mesh_(mesh)
00038 {}
00039
00040
00041
00042
00043 Foam::tmp<Foam::scalarField> Foam::cellQuality::nonOrthogonality() const
00044 {
00045 tmp<scalarField> tresult
00046 (
00047 new scalarField
00048 (
00049 mesh_.nCells(), 0.0
00050 )
00051 );
00052
00053 scalarField& result = tresult();
00054
00055 scalarField sumArea(mesh_.nCells(), 0.0);
00056
00057 const vectorField& centres = mesh_.cellCentres();
00058 const vectorField& areas = mesh_.faceAreas();
00059
00060 const labelList& own = mesh_.faceOwner();
00061 const labelList& nei = mesh_.faceNeighbour();
00062
00063 forAll (nei, faceI)
00064 {
00065 vector d = centres[nei[faceI]] - centres[own[faceI]];
00066 vector s = areas[faceI];
00067 scalar magS = mag(s);
00068
00069 scalar cosDDotS =
00070 Foam::acos(min(1.0, (d & s)/(mag(d)*magS + VSMALL)))
00071 *180.0/mathematicalConstant::pi;
00072
00073 result[own[faceI]] = max(cosDDotS, result[own[faceI]]);
00074
00075 result[nei[faceI]] = max(cosDDotS, result[nei[faceI]]);
00076 }
00077
00078 forAll (mesh_.boundaryMesh(), patchI)
00079 {
00080 const unallocLabelList& faceCells =
00081 mesh_.boundaryMesh()[patchI].faceCells();
00082
00083 const vectorField::subField faceCentres =
00084 mesh_.boundaryMesh()[patchI].faceCentres();
00085
00086 const vectorField::subField faceAreas =
00087 mesh_.boundaryMesh()[patchI].faceAreas();
00088
00089 forAll(faceCentres, faceI)
00090 {
00091 vector d = faceCentres[faceI] - centres[faceCells[faceI]];
00092 vector s = faceAreas[faceI];
00093 scalar magS = mag(s);
00094
00095 scalar cosDDotS =
00096 Foam::acos(min(1.0, (d & s)/(mag(d)*magS + VSMALL)))
00097 *180.0/mathematicalConstant::pi;
00098
00099 result[faceCells[faceI]] = max(cosDDotS, result[faceCells[faceI]]);
00100 }
00101 }
00102
00103 return tresult;
00104 }
00105
00106
00107 Foam::tmp<Foam::scalarField> Foam::cellQuality::skewness() const
00108 {
00109 tmp<scalarField> tresult
00110 (
00111 new scalarField
00112 (
00113 mesh_.nCells(), 0.0
00114 )
00115 );
00116 scalarField& result = tresult();
00117
00118 scalarField sumArea(mesh_.nCells(), 0.0);
00119
00120 const vectorField& cellCtrs = mesh_.cellCentres();
00121 const vectorField& faceCtrs = mesh_.faceCentres();
00122 const vectorField& areas = mesh_.faceAreas();
00123
00124 const labelList& own = mesh_.faceOwner();
00125 const labelList& nei = mesh_.faceNeighbour();
00126
00127 forAll (nei, faceI)
00128 {
00129 scalar dOwn = mag
00130 (
00131 (faceCtrs[faceI] - cellCtrs[own[faceI]]) & areas[faceI]
00132 )/mag(areas[faceI]);
00133
00134 scalar dNei = mag
00135 (
00136 (cellCtrs[nei[faceI]] - faceCtrs[faceI]) & areas[faceI]
00137 )/mag(areas[faceI]);
00138
00139 point faceIntersection =
00140 cellCtrs[own[faceI]]
00141 + (dOwn/(dOwn+dNei))*(cellCtrs[nei[faceI]] - cellCtrs[own[faceI]]);
00142
00143 scalar skewness =
00144 mag(faceCtrs[faceI] - faceIntersection)
00145 /(mag(cellCtrs[nei[faceI]] - cellCtrs[own[faceI]]) + VSMALL);
00146
00147 result[own[faceI]] = max(skewness, result[own[faceI]]);
00148
00149 result[nei[faceI]] = max(skewness, result[nei[faceI]]);
00150 }
00151
00152 forAll (mesh_.boundaryMesh(), patchI)
00153 {
00154 const unallocLabelList& faceCells =
00155 mesh_.boundaryMesh()[patchI].faceCells();
00156
00157 const vectorField::subField faceCentres =
00158 mesh_.boundaryMesh()[patchI].faceCentres();
00159
00160 const vectorField::subField faceAreas =
00161 mesh_.boundaryMesh()[patchI].faceAreas();
00162
00163 forAll(faceCentres, faceI)
00164 {
00165 vector n = faceAreas[faceI]/mag(faceAreas[faceI]);
00166
00167 point faceIntersection =
00168 cellCtrs[faceCells[faceI]]
00169 + ((faceCentres[faceI] - cellCtrs[faceCells[faceI]])&n)*n;
00170
00171 scalar skewness =
00172 mag(faceCentres[faceI] - faceIntersection)
00173 /(
00174 mag(faceCentres[faceI] - cellCtrs[faceCells[faceI]])
00175 + VSMALL
00176 );
00177
00178 result[faceCells[faceI]] = max(skewness, result[faceCells[faceI]]);
00179 }
00180 }
00181
00182 return tresult;
00183 }
00184
00185
00186 Foam::tmp<Foam::scalarField> Foam::cellQuality::faceNonOrthogonality() const
00187 {
00188 tmp<scalarField> tresult
00189 (
00190 new scalarField
00191 (
00192 mesh_.nFaces(), 0.0
00193 )
00194 );
00195 scalarField& result = tresult();
00196
00197
00198 const vectorField& centres = mesh_.cellCentres();
00199 const vectorField& areas = mesh_.faceAreas();
00200
00201 const labelList& own = mesh_.faceOwner();
00202 const labelList& nei = mesh_.faceNeighbour();
00203
00204 forAll (nei, faceI)
00205 {
00206 vector d = centres[nei[faceI]] - centres[own[faceI]];
00207 vector s = areas[faceI];
00208 scalar magS = mag(s);
00209
00210 scalar cosDDotS =
00211 Foam::acos(min(1.0, (d & s)/(mag(d)*magS + VSMALL)))
00212 *180.0/mathematicalConstant::pi;
00213
00214 result[faceI] = cosDDotS;
00215 }
00216
00217 label globalFaceI = mesh_.nInternalFaces();
00218
00219 forAll (mesh_.boundaryMesh(), patchI)
00220 {
00221 const unallocLabelList& faceCells =
00222 mesh_.boundaryMesh()[patchI].faceCells();
00223
00224 const vectorField::subField faceCentres =
00225 mesh_.boundaryMesh()[patchI].faceCentres();
00226
00227 const vectorField::subField faceAreas =
00228 mesh_.boundaryMesh()[patchI].faceAreas();
00229
00230 forAll(faceCentres, faceI)
00231 {
00232 vector d = faceCentres[faceI] - centres[faceCells[faceI]];
00233 vector s = faceAreas[faceI];
00234 scalar magS = mag(s);
00235
00236 scalar cosDDotS =
00237 Foam::acos(min(1.0, (d & s)/(mag(d)*magS + VSMALL)))
00238 *180.0/mathematicalConstant::pi;
00239
00240 result[globalFaceI++] = cosDDotS;
00241 }
00242 }
00243
00244 return tresult;
00245 }
00246
00247
00248 Foam::tmp<Foam::scalarField> Foam::cellQuality::faceSkewness() const
00249 {
00250 tmp<scalarField> tresult
00251 (
00252 new scalarField
00253 (
00254 mesh_.nFaces(), 0.0
00255 )
00256 );
00257 scalarField& result = tresult();
00258
00259
00260 const vectorField& cellCtrs = mesh_.cellCentres();
00261 const vectorField& faceCtrs = mesh_.faceCentres();
00262 const vectorField& areas = mesh_.faceAreas();
00263
00264 const labelList& own = mesh_.faceOwner();
00265 const labelList& nei = mesh_.faceNeighbour();
00266
00267 forAll (nei, faceI)
00268 {
00269 scalar dOwn = mag
00270 (
00271 (faceCtrs[faceI] - cellCtrs[own[faceI]]) & areas[faceI]
00272 )/mag(areas[faceI]);
00273
00274 scalar dNei = mag
00275 (
00276 (cellCtrs[nei[faceI]] - faceCtrs[faceI]) & areas[faceI]
00277 )/mag(areas[faceI]);
00278
00279 point faceIntersection =
00280 cellCtrs[own[faceI]]
00281 + (dOwn/(dOwn+dNei))*(cellCtrs[nei[faceI]] - cellCtrs[own[faceI]]);
00282
00283 result[faceI] =
00284 mag(faceCtrs[faceI] - faceIntersection)
00285 /(mag(cellCtrs[nei[faceI]] - cellCtrs[own[faceI]]) + VSMALL);
00286 }
00287
00288
00289 label globalFaceI = mesh_.nInternalFaces();
00290
00291 forAll (mesh_.boundaryMesh(), patchI)
00292 {
00293 const unallocLabelList& faceCells =
00294 mesh_.boundaryMesh()[patchI].faceCells();
00295
00296 const vectorField::subField faceCentres =
00297 mesh_.boundaryMesh()[patchI].faceCentres();
00298
00299 const vectorField::subField faceAreas =
00300 mesh_.boundaryMesh()[patchI].faceAreas();
00301
00302 forAll(faceCentres, faceI)
00303 {
00304 vector n = faceAreas[faceI]/mag(faceAreas[faceI]);
00305
00306 point faceIntersection =
00307 cellCtrs[faceCells[faceI]]
00308 + ((faceCentres[faceI] - cellCtrs[faceCells[faceI]])&n)*n;
00309
00310 result[globalFaceI++] =
00311 mag(faceCentres[faceI] - faceIntersection)
00312 /(
00313 mag(faceCentres[faceI] - cellCtrs[faceCells[faceI]])
00314 + VSMALL
00315 );
00316 }
00317 }
00318
00319 return tresult;
00320 }
00321
00322
00323