45 const scalar severeNonorthogonalityThreshold,
55 const scalar dDotS = (d &
s)/(
mag(d)*
mag(
s) + vSmall);
57 if (dDotS < severeNonorthogonalityThreshold)
71 Pout<<
"Severe non-orthogonality for face " << facei
72 <<
" between cells " << mesh.
faceOwner()[facei]
87 <<
"Severe non-orthogonality detected for face "
89 <<
" between cells " << mesh.
faceOwner()[facei]
113 const scalar minTetQuality,
134 if (tetQual < minTetQuality)
138 Pout<<
"bool meshCheck::checkFaceTets("
139 <<
"const bool, const scalar, const pointField&"
140 <<
", const pointField&"
141 <<
", const labelList&, labelHashSet*) : "
143 <<
" has a triangle that points the wrong way."
145 <<
"Tet quality: " << tetQual
176 const label facei = changedFaces[i];
178 affectedCells.
insert(own[facei]);
182 affectedCells.
insert(nei[facei]);
186 return affectedCells.
toc();
200 const scalar orthWarn,
217 const scalar severeNonorthogonalityThreshold =
::cos(orthWarn);
227 syncTools::swapBoundaryFacePositions(mesh, neiCc);
229 scalar minDDotS = great;
234 label severeNonOrth = 0;
236 label errorNonOrth = 0;
240 const label facei = checkFaces[i];
242 const point& ownCc = cellCentres[own[facei]];
250 severeNonorthogonalityThreshold,
253 cellCentres[nei[facei]] - ownCc,
260 if (dDotS < minDDotS)
278 severeNonorthogonalityThreshold,
288 if (dDotS < minDDotS)
302 const label face1 = baffles[i].second();
304 const point& ownCc = cellCentres[own[face0]];
310 severeNonorthogonalityThreshold,
313 cellCentres[own[face1]] - ownCc,
320 if (dDotS < minDDotS)
338 if (report && minDDotS < severeNonorthogonalityThreshold)
340 Info<<
"Number of non-orthogonality errors: " << errorNonOrth
341 <<
". Number of severely non-orthogonal faces: "
342 << severeNonOrth <<
"." <<
endl;
350 Info<<
"Mesh non-orthogonality Max: "
357 if (errorNonOrth > 0)
362 <<
"Error in non-orthogonality detected" <<
endl;
371 Info<<
"Non-orthogonality check OK.\n" <<
endl;
382 const scalar minPyrVol,
397 label nErrorPyrs = 0;
401 const label facei = checkFaces[i];
407 cellCentres[own[facei]]
410 if (pyrVol > -minPyrVol)
414 Pout<<
"bool meshCheck::checkFacePyramids("
415 <<
"const bool, const scalar, const pointField&"
416 <<
", const labelList&, labelHashSet*): "
417 <<
"face " << facei <<
" points the wrong way. " <<
endl
418 <<
"Pyramid volume: " << -pyrVol
419 <<
" Face " <<
f[facei] <<
" area: " <<
f[facei].mag(
p)
420 <<
" Owner cell: " << own[facei] <<
endl
421 <<
"Owner cell vertex labels: "
422 << mesh.
cells()[own[facei]].labels(
f)
438 const scalar pyrVol =
441 if (pyrVol < minPyrVol)
445 Pout<<
"bool meshCheck::checkFacePyramids("
446 <<
"const bool, const scalar, const pointField&"
447 <<
", const labelList&, labelHashSet*): "
448 <<
"face " << facei <<
" points the wrong way. " <<
endl
449 <<
"Pyramid volume: " << -pyrVol
450 <<
" Face " <<
f[facei] <<
" area: " <<
f[facei].mag(
p)
451 <<
" Neighbour cell: " << nei[facei] <<
endl
452 <<
"Neighbour cell vertex labels: "
453 << mesh.
cells()[nei[facei]].labels(
f)
470 const label face1 = baffles[i].second();
472 const point& ownCc = cellCentres[own[face0]];
481 if (pyrVolOwn > -minPyrVol)
485 Pout<<
"bool meshCheck::checkFacePyramids("
486 <<
"const bool, const scalar, const pointField&"
487 <<
", const labelList&, labelHashSet*): "
488 <<
"face " << face0 <<
" points the wrong way. " <<
endl
489 <<
"Pyramid volume: " << -pyrVolOwn
490 <<
" Face " <<
f[face0] <<
" area: " <<
f[face0].mag(
p)
491 <<
" Owner cell: " << own[face0] <<
endl
492 <<
"Owner cell vertex labels: "
493 << mesh.
cells()[own[face0]].labels(
f)
507 const scalar pyrVolNbr =
510 if (pyrVolNbr < minPyrVol)
514 Pout<<
"bool meshCheck::checkFacePyramids("
515 <<
"const bool, const scalar, const pointField&"
516 <<
", const labelList&, labelHashSet*): "
517 <<
"face " << face0 <<
" points the wrong way. " <<
endl
518 <<
"Pyramid volume: " << -pyrVolNbr
519 <<
" Face " <<
f[face0] <<
" area: " <<
f[face0].mag(
p)
520 <<
" Neighbour cell: " << own[face1] <<
endl
521 <<
"Neighbour cell vertex labels: "
522 << mesh.
cells()[own[face1]].labels(
f)
542 <<
"Error in face pyramids: faces pointing the wrong way."
552 Info<<
"Face pyramids OK.\n" <<
endl;
563 const scalar minTetQuality,
587 syncTools::swapBoundaryFacePositions(mesh, neiCc);
589 label nErrorTets = 0;
593 const label facei = checkFaces[i];
604 cellCentres[own[facei]],
625 cellCentres[nei[facei]],
636 polyMeshTetDecomposition::findSharedBasePoint
661 polyMeshTetDecomposition::findSharedBasePoint
683 polyMeshTetDecomposition::findBasePoint
706 const label face1 = baffles[i].second();
715 cellCentres[own[face0]],
734 cellCentres[own[face1]],
745 polyMeshTetDecomposition::findSharedBasePoint
749 cellCentres[own[face1]],
771 <<
"Error in face decomposition: negative tets."
792 const scalar internalSkew,
793 const scalar boundarySkew,
813 syncTools::swapBoundaryCellPositions(mesh, cellCentres, neiCc);
821 const label facei = checkFaces[i];
833 cellCentres[own[facei]],
834 cellCentres[nei[facei]]
840 if (skewness > internalSkew)
844 Pout<<
"Severe skewness for face " << facei
845 <<
" skewness = " << skewness <<
endl;
856 maxSkew =
max(maxSkew, skewness);
868 cellCentres[own[facei]],
875 if (skewness > internalSkew)
879 Pout<<
"Severe skewness for coupled face " << facei
880 <<
" skewness = " << skewness <<
endl;
891 maxSkew =
max(maxSkew, skewness);
903 cellCentres[own[facei]]
910 if (skewness > boundarySkew)
914 Pout<<
"Severe skewness for boundary face " << facei
915 <<
" skewness = " << skewness <<
endl;
926 maxSkew =
max(maxSkew, skewness);
933 const label face1 = baffles[i].second();
935 const point& ownCc = cellCentres[own[face0]];
936 const point& neiCc = cellCentres[own[face1]];
953 if (skewness > internalSkew)
957 Pout<<
"Severe skewness for face " << face0
958 <<
" skewness = " << skewness <<
endl;
969 maxSkew =
max(maxSkew, skewness);
982 <<
" percent.\nThis may impair the quality of the result." <<
nl
983 << nWarnSkew <<
" highly skew faces detected."
993 Info<<
"Max skewness = " << 100*maxSkew
994 <<
" percent. Face skewness OK.\n" <<
endl;
1005 const scalar warnWeight,
1028 syncTools::swapBoundaryFacePositions(mesh, neiCc);
1031 scalar minWeight = great;
1033 label nWarnWeight = 0;
1037 const label facei = checkFaces[i];
1039 const point& fc = faceCentres[facei];
1040 const vector& fa = faceAreas[facei];
1042 const scalar dOwn =
mag(fa & (fc-cellCentres[own[facei]]));
1046 const scalar dNei =
mag(fa & (cellCentres[nei[facei]]-fc));
1047 const scalar weight =
min(dNei, dOwn)/(dNei + dOwn + vSmall);
1049 if (weight < warnWeight)
1053 Pout<<
"Small weighting factor for face " << facei
1054 <<
" weight = " << weight <<
endl;
1065 minWeight =
min(minWeight, weight);
1075 const scalar weight =
min(dNei, dOwn)/(dNei + dOwn + vSmall);
1077 if (weight < warnWeight)
1081 Pout<<
"Small weighting factor for face " << facei
1082 <<
" weight = " << weight <<
endl;
1093 minWeight =
min(minWeight, weight);
1101 const label face1 = baffles[i].second();
1103 const point& ownCc = cellCentres[own[face0]];
1104 const point& fc = faceCentres[face0];
1105 const vector& fa = faceAreas[face0];
1107 const scalar dOwn =
mag(fa & (fc-ownCc));
1108 const scalar dNei =
mag(fa & (cellCentres[own[face1]]-fc));
1109 const scalar weight =
min(dNei, dOwn)/(dNei + dOwn + vSmall);
1111 if (weight < warnWeight)
1115 Pout<<
"Small weighting factor for face " << face0
1116 <<
" weight = " << weight <<
endl;
1127 minWeight =
min(minWeight, weight);
1133 if (minWeight < warnWeight)
1138 << minWeight <<
'.' <<
nl
1139 << nWarnWeight <<
" faces with small weights detected."
1149 Info<<
"Min weight = " << minWeight
1150 <<
". Weights OK.\n" <<
endl;
1161 const scalar warnRatio,
1182 syncTools::swapBoundaryFaceList(mesh, neiVols);
1185 scalar minRatio = great;
1187 label nWarnRatio = 0;
1191 const label facei = checkFaces[i];
1193 const scalar ownVol =
mag(cellVolumes[own[facei]]);
1195 scalar neiVol = -great;
1199 neiVol =
mag(cellVolumes[nei[facei]]);
1213 const scalar ratio =
1214 min(ownVol, neiVol)/(
max(ownVol, neiVol) + vSmall);
1216 if (ratio < warnRatio)
1220 Pout<<
"Small ratio for face " << facei
1221 <<
" ratio = " << ratio <<
endl;
1232 minRatio =
min(minRatio, ratio);
1239 const label face1 = baffles[i].second();
1241 const scalar ownVol =
mag(cellVolumes[own[face0]]);
1243 const scalar neiVol =
mag(cellVolumes[own[face1]]);
1247 const scalar ratio =
1248 min(ownVol, neiVol)/(
max(ownVol, neiVol) + vSmall);
1250 if (ratio < warnRatio)
1254 Pout<<
"Small ratio for face " << face0
1255 <<
" ratio = " << ratio <<
endl;
1266 minRatio =
min(minRatio, ratio);
1273 if (minRatio < warnRatio)
1278 << minRatio <<
'.' <<
nl
1279 << nWarnRatio <<
" faces with small ratios detected."
1289 Info<<
"Min ratio = " << minRatio
1290 <<
". Ratios OK.\n" <<
endl;
1301 const scalar maxConcave,
1309 if (maxConcave < -small || maxConcave >
degToRad(180)+small)
1312 <<
"maxConcave should be [0..180] degrees but is "
1316 const scalar maxSin =
Foam::sin(maxConcave);
1320 scalar maxEdgeSin = 0.0;
1324 label errorFacei = -1;
1328 const label facei = checkFaces[i];
1330 const face&
f = fcs[facei];
1332 vector faceNormal = faceAreas[facei];
1333 faceNormal /=
mag(faceNormal) + vSmall;
1337 scalar magEPrev =
mag(ePrev);
1338 ePrev /= magEPrev + vSmall;
1343 const label fp1 =
f.fcIndex(fp0);
1347 const scalar magE10 =
mag(e10);
1348 e10 /= magE10 + vSmall;
1350 if (magEPrev > small && magE10 > small)
1352 vector edgeNormal = ePrev ^ e10;
1353 const scalar magEdgeNormal =
mag(edgeNormal);
1355 if (magEdgeNormal < maxSin)
1362 edgeNormal /= magEdgeNormal;
1364 if ((edgeNormal & faceNormal) < small)
1366 if (facei != errorFacei)
1378 maxEdgeSin =
max(maxEdgeSin, magEdgeNormal);
1393 if (maxEdgeSin > small)
1395 const scalar maxConcaveDegr =
1398 Info<<
"There are " << nConcave
1399 <<
" faces with concave angles between consecutive"
1400 <<
" edges. Max concave angle = " << maxConcaveDegr
1401 <<
" degrees.\n" <<
endl;
1405 Info<<
"All angles in faces are convex or less than "
1406 <<
radToDeg(maxConcave) <<
" degrees concave.\n" <<
endl;
1415 << nConcave <<
" face points with severe concave angle (> "
1416 <<
radToDeg(maxConcave) <<
" deg) found.\n"
1432 const scalar minTwist,
1442 if (minTwist < -1-small || minTwist > 1+small)
1445 <<
"minTwist should be [-1..1] but is now " << minTwist
1465 syncTools::swapBoundaryFacePositions(mesh, neiCc);
1469 const label facei = checkFaces[i];
1471 const face&
f = fcs[facei];
1479 nf = cellCentres[nei[facei]] - cellCentres[own[facei]];
1480 nf /=
mag(nf) + vSmall;
1486 - cellCentres[own[facei]];
1487 nf /=
mag(nf) + vSmall;
1491 nf = faceCentres[facei] - cellCentres[own[facei]];
1492 nf /=
mag(nf) + vSmall;
1495 if (nf != vector::zero)
1497 const point& fc = faceCentres[facei];
1506 p[
f.nextLabel(fpI)],
1511 const scalar magTri =
mag(triArea);
1513 if (magTri > vSmall && ((nf & triArea/magTri) < minTwist))
1535 Info<<
"There are " << nWarped
1536 <<
" faces with cosine of the angle"
1537 <<
" between triangle normal and face normal less than "
1538 << minTwist <<
nl <<
endl;
1542 Info<<
"All faces are flat in that the cosine of the angle"
1543 <<
" between triangle normal and face normal less than "
1544 << minTwist <<
nl <<
endl;
1553 << nWarped <<
" faces with severe warpage "
1554 <<
"(cosine of the angle between triangle normal and "
1555 <<
"face normal < " << minTwist <<
") found.\n"
1571 const scalar minTwist,
1580 if (minTwist < -1-small || minTwist > 1+small)
1583 <<
"minTwist should be [-1..1] but is now " << minTwist
1593 const label facei = checkFaces[i];
1595 const face&
f = fcs[facei];
1599 const point& fc = faceCentres[facei];
1614 const scalar magTri =
mag(prevN);
1616 if (magTri > vSmall)
1641 const scalar magTri =
mag(triN);
1643 if (magTri > vSmall)
1647 if ((prevN & triN) < minTwist)
1661 else if (minTwist > 0)
1673 while (fp != startFp);
1685 Info<<
"There are " << nWarped
1686 <<
" faces with cosine of the angle"
1687 <<
" between consecutive triangle normals less than "
1688 << minTwist <<
nl <<
endl;
1692 Info<<
"All faces are flat in that the cosine of the angle"
1693 <<
" between consecutive triangle normals is less than "
1694 << minTwist <<
nl <<
endl;
1703 << nWarped <<
" faces with severe warpage "
1704 <<
"(cosine of the angle between consecutive triangle normals"
1705 <<
" < " << minTwist <<
") found.\n"
1721 const scalar minFlatness,
1730 if (minFlatness < -small || minFlatness > 1+small)
1733 <<
"minFlatness should be [0..1] but is now " << minFlatness
1743 const label facei = checkFaces[i];
1745 const face&
f = fcs[facei];
1749 const point& fc = faceCentres[facei];
1752 scalar sumArea = 0.0;
1764 if (sumArea/
mag(faceAreas[facei]) < minFlatness)
1782 Info<<
"There are " << nWarped
1783 <<
" faces with area of individual triangles"
1784 <<
" compared to overall area less than "
1785 << minFlatness <<
nl <<
endl;
1789 Info<<
"All faces are flat in that the area of individual triangles"
1790 <<
" compared to overall area is less than "
1791 << minFlatness <<
nl <<
endl;
1800 << nWarped <<
" non-flat faces "
1801 <<
"(area of individual triangles"
1802 <<
" compared to overall area"
1803 <<
" < " << minFlatness <<
") found.\n"
1819 const scalar minArea,
1826 label nZeroArea = 0;
1830 const label facei = checkFaces[i];
1832 if (
mag(faceAreas[facei]) < minArea)
1849 Info<<
"There are " << nZeroArea
1850 <<
" faces with area < " << minArea <<
'.' <<
nl <<
endl;
1854 Info<<
"All faces have area > " << minArea <<
'.' <<
nl <<
endl;
1863 << nZeroArea <<
" faces with area < " << minArea
1880 const scalar warnDet,
1889 scalar minDet = great;
1890 scalar sumDet = 0.0;
1898 const cell& cFaces =
cells[affectedCells[i]];
1901 scalar magAreaSum = 0;
1905 const label facei = cFaces[cFacei];
1907 const scalar magArea =
mag(faceAreas[facei]);
1909 magAreaSum += magArea;
1910 areaSum += faceAreas[facei]*(faceAreas[facei]/(magArea + vSmall));
1914 const scalar scaledDet = 27*
det(areaSum/(magAreaSum + vSmall));
1916 minDet =
min(minDet, scaledDet);
1917 sumDet += scaledDet;
1920 if (scaledDet < warnDet)
1927 const label facei = cFaces[cFacei];
1944 Info<<
"Cell determinant (1 = uniform cube) : average = "
1945 << sumDet / nSumDet <<
" min = " << minDet <<
endl;
1950 Info<<
"There are " << nWarnDet
1951 <<
" cells with determinant < " << warnDet <<
'.' <<
nl
1956 Info<<
"All faces have determinant > " << warnDet <<
'.' <<
nl
1966 << nWarnDet <<
" cells with determinant < " << warnDet
#define forAll(list, i)
Loop across all elements in list.
bool insert(const Key &key)
Insert a new entry.
List< Key > toc() const
Return the table of contents.
void size(const label)
Override size to be inconsistent with allocated storage.
T & first()
Return the first element of the list.
A cell is defined as a list of faces with extra functionality.
A face is a list of labels corresponding to mesh vertices.
Mesh consisting of general polyhedral cells.
virtual const faceList & faces() const
Return raw faces.
virtual const labelList & faceOwner() const
Return face owner.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
virtual const labelList & faceNeighbour() const
Return face neighbour.
Cell-face mesh analysis engine.
virtual const faceList & faces() const =0
Return faces.
virtual const labelList & faceOwner() const =0
Face face-owner addressing.
label nInternalFaces() const
virtual const labelList & faceNeighbour() const =0
Face face-neighbour addressing.
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
const cellList & cells() const
A triangle primitive used to calculate face areas and swept volumes.
vector area() const
Return vector area.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
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.name(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const fvPatchList & patches
#define WarningInFunction
Report a warning using Foam::Warning.
#define SeriousErrorInFunction
Report an error message using Foam::SeriousError.
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.
tmp< scalarField > faceSkewness(const polyMesh &mesh, const pointField &points, const vectorField &fCtrs, const vectorField &fAreas, const vectorField &cellCtrs)
Generate skewness field.
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.
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)
Check the difference between normals of individual face-triangles (from.
labelList getAffectedCells(const primitiveMesh &mesh, const labelList &changedFaces)
bool checkFaceArea(const bool report, const scalar minArea, const polyMesh &, const vectorField &faceAreas, const labelList &checkFaces, labelHashSet *setPtr)
Check for small faces.
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)
bool checkCellDeterminant(const polyMesh &mesh, const bool report, labelHashSet *setPtr)
bool checkFaceAngles(const bool report, const scalar maxConcave, 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.
bool checkVolRatio(const polyMesh &mesh, const bool report, const scalar minRatio=0.01, labelHashSet *setPtr=nullptr)
Check for neighbouring cell volumes.
scalar boundaryFaceSkewness(const primitiveMesh &mesh, const pointField &p, const vectorField &fCtrs, const vectorField &fAreas, const label facei, const point &ownCc)
Skewness of single boundary face.
scalar checkNonOrtho(const primitiveMesh &mesh, const bool report, const scalar severeNonorthogonalityThreshold, const label facei, const vector &s, const vector &d, label &severeNonOrth, label &errorNonOrth, labelHashSet *setPtr)
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.
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.
bool checkFaceOrthogonality(const polyMesh &mesh, const scalar nonOrthThreshold, const bool report=false, labelHashSet *setPtr=nullptr)
Check face orthogonality.
bool checkFaceSkewness(const polyMesh &mesh, const scalar skewThreshold, const bool report=false, labelHashSet *setPtr=nullptr)
Check face skewness.
bool checkFaceTet(const primitiveMesh &mesh, const bool report, const scalar minTetQuality, const pointField &p, const label facei, const point &fc, const point &cc, labelHashSet *setPtr)
pyramid< point, const point &, const face & > pyramidPointFaceRef
dimensionedScalar det(const dimensionedSphericalTensor &dt)
dimensionedScalar asin(const dimensionedScalar &ds)
scalar radToDeg(const scalar rad)
Convert radians to degrees.
scalar degToRad(const scalar deg)
Convert degrees to radians.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Ostream & endl(Ostream &os)
Add newline and flush stream.
errorManip< error > abort(error &err)
dimensionedScalar sin(const dimensionedScalar &ds)
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
dimensioned< scalar > mag(const dimensioned< Type > &)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
triangle< point, const point & > triPointRef
prefixOSstream Pout(cout, "Pout")
dimensionedScalar cos(const dimensionedScalar &ds)
dimensionedScalar acos(const dimensionedScalar &ds)
tetrahedron< point, const point & > tetPointRef