38 namespace polyMeshCheck
47 const scalar severeNonorthogonalityThreshold,
57 scalar dDotS = (d &
s)/(
mag(d)*
mag(s) + vSmall);
59 if (dDotS < severeNonorthogonalityThreshold)
73 Pout<<
"Severe non-orthogonality for face " << facei
74 <<
" between cells " << mesh.
faceOwner()[facei]
89 <<
"Severe non-orthogonality detected for face " 91 <<
" between cells " << mesh.
faceOwner()[facei]
114 const scalar minTetQuality,
135 if (tetQual < minTetQuality)
139 Pout<<
"bool polyMeshCheck::checkFaceTets(" 140 <<
"const bool, const scalar, const pointField&" 141 <<
", const pointField&" 142 <<
", const labelList&, labelHashSet*) : " 144 <<
" has a triangle that points the wrong way." 146 <<
"Tet quality: " << tetQual
175 label facei = changedFaces[i];
177 affectedCells.insert(own[facei]);
181 affectedCells.insert(nei[facei]);
184 return affectedCells.toc();
197 const scalar orthWarn,
214 const scalar severeNonorthogonalityThreshold =
::cos(
degToRad(orthWarn));
226 scalar minDDotS = great;
231 label severeNonOrth = 0;
233 label errorNonOrth = 0;
237 label facei = checkFaces[i];
239 const point& ownCc = cellCentres[own[facei]];
247 severeNonorthogonalityThreshold,
250 cellCentres[nei[facei]] - ownCc,
257 if (dDotS < minDDotS)
269 if (patches[patchi].coupled())
275 severeNonorthogonalityThreshold,
285 if (dDotS < minDDotS)
299 label face1 = baffles[i].second();
301 const point& ownCc = cellCentres[own[face0]];
307 severeNonorthogonalityThreshold,
310 cellCentres[own[face1]] - ownCc,
317 if (dDotS < minDDotS)
335 if (report && minDDotS < severeNonorthogonalityThreshold)
337 Info<<
"Number of non-orthogonality errors: " << errorNonOrth
338 <<
". Number of severely non-orthogonal faces: " 339 << severeNonOrth <<
"." <<
endl;
347 Info<<
"Mesh non-orthogonality Max: " 354 if (errorNonOrth > 0)
359 <<
"Error in non-orthogonality detected" <<
endl;
368 Info<<
"Non-orthogonality check OK.\n" <<
endl;
379 const scalar minPyrVol,
394 label nErrorPyrs = 0;
398 label facei = checkFaces[i];
404 cellCentres[own[facei]]
407 if (pyrVol > -minPyrVol)
411 Pout<<
"bool polyMeshCheck::checkFacePyramids(" 412 <<
"const bool, const scalar, const pointField&" 413 <<
", const labelList&, labelHashSet*): " 414 <<
"face " << facei <<
" points the wrong way. " <<
endl 415 <<
"Pyramid volume: " << -pyrVol
416 <<
" Face " << f[facei] <<
" area: " << f[facei].mag(p)
417 <<
" Owner cell: " << own[facei] <<
endl 418 <<
"Owner cell vertex labels: " 419 << mesh.
cells()[own[facei]].labels(f)
438 if (pyrVol < minPyrVol)
442 Pout<<
"bool polyMeshCheck::checkFacePyramids(" 443 <<
"const bool, const scalar, const pointField&" 444 <<
", const labelList&, labelHashSet*): " 445 <<
"face " << facei <<
" points the wrong way. " <<
endl 446 <<
"Pyramid volume: " << -pyrVol
447 <<
" Face " << f[facei] <<
" area: " << f[facei].mag(p)
448 <<
" Neighbour cell: " << nei[facei] <<
endl 449 <<
"Neighbour cell vertex labels: " 450 << mesh.
cells()[nei[facei]].labels(f)
467 label face1 = baffles[i].second();
469 const point& ownCc = cellCentres[own[face0]];
478 if (pyrVolOwn > -minPyrVol)
482 Pout<<
"bool polyMeshCheck::checkFacePyramids(" 483 <<
"const bool, const scalar, const pointField&" 484 <<
", const labelList&, labelHashSet*): " 485 <<
"face " << face0 <<
" points the wrong way. " <<
endl 486 <<
"Pyramid volume: " << -pyrVolOwn
487 <<
" Face " << f[face0] <<
" area: " << f[face0].mag(p)
488 <<
" Owner cell: " << own[face0] <<
endl 489 <<
"Owner cell vertex labels: " 490 << mesh.
cells()[own[face0]].labels(f)
507 if (pyrVolNbr < minPyrVol)
511 Pout<<
"bool polyMeshCheck::checkFacePyramids(" 512 <<
"const bool, const scalar, const pointField&" 513 <<
", const labelList&, labelHashSet*): " 514 <<
"face " << face0 <<
" points the wrong way. " <<
endl 515 <<
"Pyramid volume: " << -pyrVolNbr
516 <<
" Face " << f[face0] <<
" area: " << f[face0].mag(p)
517 <<
" Neighbour cell: " << own[face1] <<
endl 518 <<
"Neighbour cell vertex labels: " 519 << mesh.
cells()[own[face1]].labels(f)
539 <<
"Error in face pyramids: faces pointing the wrong way." 549 Info<<
"Face pyramids OK.\n" <<
endl;
560 const scalar minTetQuality,
586 label nErrorTets = 0;
590 label facei = checkFaces[i];
601 cellCentres[own[facei]],
622 cellCentres[nei[facei]],
654 if (patches[patchi].coupled())
703 label face1 = baffles[i].second();
712 cellCentres[own[face0]],
731 cellCentres[own[face1]],
746 cellCentres[own[face1]],
768 <<
"Error in face decomposition: negative tets." 789 const scalar internalSkew,
790 const scalar boundarySkew,
818 label facei = checkFaces[i];
830 cellCentres[own[facei]],
831 cellCentres[nei[facei]]
837 if (skewness > internalSkew)
841 Pout<<
"Severe skewness for face " << facei
842 <<
" skewness = " << skewness <<
endl;
853 maxSkew =
max(maxSkew, skewness);
855 else if (patches[patches.
whichPatch(facei)].coupled())
865 cellCentres[own[facei]],
872 if (skewness > internalSkew)
876 Pout<<
"Severe skewness for coupled face " << facei
877 <<
" skewness = " << skewness <<
endl;
888 maxSkew =
max(maxSkew, skewness);
900 cellCentres[own[facei]]
907 if (skewness > boundarySkew)
911 Pout<<
"Severe skewness for boundary face " << facei
912 <<
" skewness = " << skewness <<
endl;
923 maxSkew =
max(maxSkew, skewness);
930 label face1 = baffles[i].second();
932 const point& ownCc = cellCentres[own[face0]];
933 const point& neiCc = cellCentres[own[face1]];
950 if (skewness > internalSkew)
954 Pout<<
"Severe skewness for face " << face0
955 <<
" skewness = " << skewness <<
endl;
966 maxSkew =
max(maxSkew, skewness);
979 <<
" percent.\nThis may impair the quality of the result." <<
nl 980 << nWarnSkew <<
" highly skew faces detected." 990 Info<<
"Max skewness = " << 100*maxSkew
991 <<
" percent. Face skewness OK.\n" <<
endl;
1002 const scalar warnWeight,
1028 scalar minWeight = great;
1030 label nWarnWeight = 0;
1034 label facei = checkFaces[i];
1036 const point& fc = faceCentres[facei];
1037 const vector& fa = faceAreas[facei];
1039 scalar dOwn =
mag(fa & (fc-cellCentres[own[facei]]));
1043 scalar dNei =
mag(fa & (cellCentres[nei[facei]]-fc));
1044 scalar weight =
min(dNei,dOwn)/(dNei+dOwn+vSmall);
1046 if (weight < warnWeight)
1050 Pout<<
"Small weighting factor for face " << facei
1051 <<
" weight = " << weight <<
endl;
1062 minWeight =
min(minWeight, weight);
1068 if (patches[patchi].coupled())
1071 scalar weight =
min(dNei,dOwn)/(dNei+dOwn+vSmall);
1073 if (weight < warnWeight)
1077 Pout<<
"Small weighting factor for face " << facei
1078 <<
" weight = " << weight <<
endl;
1089 minWeight =
min(minWeight, weight);
1097 label face1 = baffles[i].second();
1099 const point& ownCc = cellCentres[own[face0]];
1100 const point& fc = faceCentres[face0];
1101 const vector& fa = faceAreas[face0];
1103 scalar dOwn =
mag(fa & (fc-ownCc));
1104 scalar dNei =
mag(fa & (cellCentres[own[face1]]-fc));
1105 scalar weight =
min(dNei,dOwn)/(dNei+dOwn+vSmall);
1107 if (weight < warnWeight)
1111 Pout<<
"Small weighting factor for face " << face0
1112 <<
" weight = " << weight <<
endl;
1123 minWeight =
min(minWeight, weight);
1129 if (minWeight < warnWeight)
1134 << minWeight <<
'.' <<
nl 1135 << nWarnWeight <<
" faces with small weights detected." 1145 Info<<
"Min weight = " << minWeight
1146 <<
". Weights OK.\n" <<
endl;
1157 const scalar warnRatio,
1181 scalar minRatio = great;
1183 label nWarnRatio = 0;
1187 label facei = checkFaces[i];
1189 scalar ownVol =
mag(cellVolumes[own[facei]]);
1191 scalar neiVol = -great;
1195 neiVol =
mag(cellVolumes[nei[facei]]);
1201 if (patches[patchi].coupled())
1209 scalar ratio =
min(ownVol, neiVol) / (
max(ownVol, neiVol) + vSmall);
1211 if (ratio < warnRatio)
1215 Pout<<
"Small ratio for face " << facei
1216 <<
" ratio = " << ratio <<
endl;
1227 minRatio =
min(minRatio, ratio);
1234 label face1 = baffles[i].second();
1236 scalar ownVol =
mag(cellVolumes[own[face0]]);
1238 scalar neiVol =
mag(cellVolumes[own[face1]]);
1242 scalar ratio =
min(ownVol, neiVol) / (
max(ownVol, neiVol) + vSmall);
1244 if (ratio < warnRatio)
1248 Pout<<
"Small ratio for face " << face0
1249 <<
" ratio = " << ratio <<
endl;
1260 minRatio =
min(minRatio, ratio);
1267 if (minRatio < warnRatio)
1272 << minRatio <<
'.' <<
nl 1273 << nWarnRatio <<
" faces with small ratios detected." 1283 Info<<
"Min ratio = " << minRatio
1284 <<
". Ratios OK.\n" <<
endl;
1295 const scalar maxDeg,
1303 if (maxDeg < -small || maxDeg > 180+small)
1306 <<
"maxDeg should be [0..180] but is now " << maxDeg
1314 scalar maxEdgeSin = 0.0;
1318 label errorFacei = -1;
1322 label facei = checkFaces[i];
1324 const face&
f = fcs[facei];
1326 vector faceNormal = faceAreas[facei];
1327 faceNormal /=
mag(faceNormal) + vSmall;
1331 scalar magEPrev =
mag(ePrev);
1332 ePrev /= magEPrev + vSmall;
1340 vector e10(p[f[fp1]] - p[f[fp0]]);
1341 scalar magE10 =
mag(e10);
1342 e10 /= magE10 + vSmall;
1344 if (magEPrev > small && magE10 > small)
1346 vector edgeNormal = ePrev ^ e10;
1347 scalar magEdgeNormal =
mag(edgeNormal);
1349 if (magEdgeNormal < maxSin)
1356 edgeNormal /= magEdgeNormal;
1358 if ((edgeNormal & faceNormal) < small)
1360 if (facei != errorFacei)
1372 maxEdgeSin =
max(maxEdgeSin, magEdgeNormal);
1387 if (maxEdgeSin > small)
1389 scalar maxConcaveDegr =
1392 Info<<
"There are " << nConcave
1393 <<
" faces with concave angles between consecutive" 1394 <<
" edges. Max concave angle = " << maxConcaveDegr
1395 <<
" degrees.\n" <<
endl;
1399 Info<<
"All angles in faces are convex or less than " << maxDeg
1400 <<
" degrees concave.\n" <<
endl;
1409 << nConcave <<
" face points with severe concave angle (> " 1410 << maxDeg <<
" deg) found.\n" 1426 const scalar minTwist,
1436 if (minTwist < -1-small || minTwist > 1+small)
1439 <<
"minTwist should be [-1..1] but is now " << minTwist
1508 label facei = checkFaces[i];
1510 const face&
f = fcs[facei];
1518 nf = cellCentres[nei[facei]] - cellCentres[own[facei]];
1519 nf /=
mag(nf) + vSmall;
1521 else if (patches[patches.
whichPatch(facei)].coupled())
1525 - cellCentres[own[facei]];
1526 nf /=
mag(nf) + vSmall;
1530 nf = faceCentres[facei] - cellCentres[own[facei]];
1531 nf /=
mag(nf) + vSmall;
1536 const point& fc = faceCentres[facei];
1550 scalar magTri =
mag(triArea);
1552 if (magTri > vSmall && ((nf & triArea/magTri) < minTwist))
1574 Info<<
"There are " << nWarped
1575 <<
" faces with cosine of the angle" 1576 <<
" between triangle normal and face normal less than " 1577 << minTwist <<
nl <<
endl;
1581 Info<<
"All faces are flat in that the cosine of the angle" 1582 <<
" between triangle normal and face normal less than " 1583 << minTwist <<
nl <<
endl;
1592 << nWarped <<
" faces with severe warpage " 1593 <<
"(cosine of the angle between triangle normal and " 1594 <<
"face normal < " << minTwist <<
") found.\n" 1610 const scalar minTwist,
1619 if (minTwist < -1-small || minTwist > 1+small)
1622 <<
"minTwist should be [-1..1] but is now " << minTwist
1632 label facei = checkFaces[i];
1634 const face&
f = fcs[facei];
1638 const point& fc = faceCentres[facei];
1653 scalar magTri =
mag(prevN);
1655 if (magTri > vSmall)
1680 scalar magTri =
mag(triN);
1682 if (magTri > vSmall)
1686 if ((prevN & triN) < minTwist)
1700 else if (minTwist > 0)
1712 while (fp != startFp);
1724 Info<<
"There are " << nWarped
1725 <<
" faces with cosine of the angle" 1726 <<
" between consecutive triangle normals less than " 1727 << minTwist <<
nl <<
endl;
1731 Info<<
"All faces are flat in that the cosine of the angle" 1732 <<
" between consecutive triangle normals is less than " 1733 << minTwist <<
nl <<
endl;
1742 << nWarped <<
" faces with severe warpage " 1743 <<
"(cosine of the angle between consecutive triangle normals" 1744 <<
" < " << minTwist <<
") found.\n" 1760 const scalar minFlatness,
1769 if (minFlatness < -small || minFlatness > 1+small)
1772 <<
"minFlatness should be [0..1] but is now " << minFlatness
1782 label facei = checkFaces[i];
1784 const face&
f = fcs[facei];
1788 const point& fc = faceCentres[facei];
1791 scalar sumArea = 0.0;
1803 if (sumArea/
mag(faceAreas[facei]) < minFlatness)
1821 Info<<
"There are " << nWarped
1822 <<
" faces with area of individual triangles" 1823 <<
" compared to overall area less than " 1824 << minFlatness <<
nl <<
endl;
1828 Info<<
"All faces are flat in that the area of individual triangles" 1829 <<
" compared to overall area is less than " 1830 << minFlatness <<
nl <<
endl;
1839 << nWarped <<
" non-flat faces " 1840 <<
"(area of individual triangles" 1841 <<
" compared to overall area" 1842 <<
" < " << minFlatness <<
") found.\n" 1858 const scalar minArea,
1865 label nZeroArea = 0;
1869 label facei = checkFaces[i];
1871 if (
mag(faceAreas[facei]) < minArea)
1888 Info<<
"There are " << nZeroArea
1889 <<
" faces with area < " << minArea <<
'.' <<
nl <<
endl;
1893 Info<<
"All faces have area > " << minArea <<
'.' <<
nl <<
endl;
1902 << nZeroArea <<
" faces with area < " << minArea
1919 const scalar warnDet,
1928 scalar minDet = great;
1929 scalar sumDet = 0.0;
1937 const cell& cFaces = cells[affectedCells[i]];
1940 scalar magAreaSum = 0;
1944 label facei = cFaces[cFacei];
1946 scalar magArea =
mag(faceAreas[facei]);
1948 magAreaSum += magArea;
1949 areaSum += faceAreas[facei]*(faceAreas[facei]/(magArea+vSmall));
1952 scalar scaledDet =
det(areaSum/(magAreaSum+vSmall))/0.037037037037037;
1954 minDet =
min(minDet, scaledDet);
1955 sumDet += scaledDet;
1958 if (scaledDet < warnDet)
1965 label facei = cFaces[cFacei];
1982 Info<<
"Cell determinant (1 = uniform cube) : average = " 1983 << sumDet / nSumDet <<
" min = " << minDet <<
endl;
1988 Info<<
"There are " << nWarnDet
1989 <<
" cells with determinant < " << warnDet <<
'.' <<
nl 1994 Info<<
"All faces have determinant > " << warnDet <<
'.' <<
nl 2004 << nWarnDet <<
" cells with determinant < " << warnDet
bool checkTriangleTwist(const bool report, const scalar minTwist, const polyMesh &, const vectorField &faceAreas, const vectorField &faceCentres, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
Check consecutive face-triangle (from face-centre decomposition) normals.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
dimensionedScalar acos(const dimensionedScalar &ds)
tetrahedron< point, const point & > tetPointRef
#define forAll(list, i)
Loop across all elements in list.
A triangle primitive used to calculate face areas and swept volumes.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
scalar radToDeg(const scalar rad)
Conversion from radians to degrees.
bool checkFaceArea(const bool report, const scalar minArea, const polyMesh &, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
Check for small faces.
A face is a list of labels corresponding to mesh vertices.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
scalar checkNonOrtho(const polyMesh &mesh, const bool report, const scalar severeNonorthogonalityThreshold, const label facei, const vector &s, const vector &d, label &severeNonOrth, label &errorNonOrth, labelHashSet *setPtr)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
label nInternalFaces() const
virtual const labelList & faceNeighbour() const
Return face neighbour.
bool checkFaceTet(const polyMesh &mesh, const bool report, const scalar minTetQuality, const pointField &p, const label facei, const point &fc, const point &cc, labelHashSet *setPtr)
Unit conversion functions.
void size(const label)
Override size to be inconsistent with allocated storage.
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Ostream & endl(Ostream &os)
Add newline and flush stream.
label nextLabel(const label i) const
Next vertex on face.
const cellList & cells() const
dimensionedScalar det(const dimensionedSphericalTensor &dt)
bool checkFaceDotProduct(const bool report, const scalar orthWarn, const polyMesh &, const vectorField &cellCentres, const vectorField &faceAreas, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *setPtr)
Check face non-orthogonality.
bool insert(const Key &key)
Insert a new entry.
T & first()
Return the first element of the list.
bool checkFaceSkewness(const bool report, const scalar internalSkew, const scalar boundarySkew, const polyMesh &mesh, const pointField &points, const vectorField &cellCentres, const vectorField &faceCentres, const vectorField &faceAreas, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *setPtr)
Check face skewness.
dimensionedScalar asin(const dimensionedScalar &ds)
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
static label findBasePoint(const polyMesh &mesh, label fI, scalar tol, bool report=false)
Find the base point to use for a minimum triangle.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
bool checkFaceTets(const bool report, const scalar minPyrVol, const polyMesh &, const vectorField &cellCentres, const vectorField &faceCentres, const pointField &p, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *)
Check face tetrahedra volumes.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
dimensionedScalar cos(const dimensionedScalar &ds)
PolyMesh checking routines. Checks various criteria for a mesh and supplied geometry, with the mesh only used for topology. Coupled patch aware (i.e., coupled faces are treated as internal).
static label findSharedBasePoint(const polyMesh &mesh, label fI, const point &nCc, scalar tol, bool report=false)
Find the first suitable base point to use for a minimum.
labelList getAffectedCells(const polyMesh &mesh, const labelList &changedFaces)
virtual const labelList & faceOwner() const
Return face owner.
bool checkFaceTwist(const bool report, const scalar minTwist, const polyMesh &, const vectorField &cellCentres, const vectorField &faceAreas, const vectorField &faceCentres, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
virtual const faceList & faces() const
Return raw faces.
pyramid< point, const point &, const face & > pyramidPointFaceRef
errorManip< error > abort(error &err)
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
bool checkFaceFlatness(const bool report, const scalar minFlatness, const polyMesh &, const vectorField &faceAreas, const vectorField &faceCentres, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
Check for face areas v.s. sum of face-triangle (from face-centre.
dimensionedScalar sin(const dimensionedScalar &ds)
bool checkFaceAngles(const bool report, const scalar maxDeg, const polyMesh &mesh, const vectorField &faceAreas, const pointField &p, const labelList &checkFaces, labelHashSet *setPtr)
Check convexity of angles in a face. See primitiveMesh for explanation.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
bool checkCellDeterminant(const bool report, const scalar minDet, const polyMesh &, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
Check the area of internal faces v.s. boundary faces.
bool checkFacePyramids(const bool report, const scalar minPyrVol, const polyMesh &, const vectorField &cellCentres, const pointField &p, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *)
Check face pyramid volumes.
#define WarningInFunction
Report a warning using Foam::Warning.
A cell is defined as a list of faces with extra functionality.
prefixOSstream Pout(cout, "Pout")
triangle< point, const point & > triPointRef
dimensioned< scalar > mag(const dimensioned< Type > &)
bool checkFaceWeights(const bool report, const scalar warnWeight, const polyMesh &mesh, const vectorField &cellCentres, const vectorField &faceCentres, const vectorField &faceAreas, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *setPtr)
Check interpolation weights (0.5 for regular mesh)
Mesh consisting of general polyhedral cells.
T & last()
Return the last element of the list.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
bool checkVolRatio(const bool report, const scalar warnRatio, const polyMesh &mesh, const scalarField &cellVolumes, const labelList &checkFaces, const List< labelPair > &baffles, labelHashSet *setPtr)
Cell volume ratio of neighbouring cells (1 for regular mesh)
static const Vector< scalar > zero