25 const wedgePolyPatch& wpp
28 const polyBoundaryMesh&
patches =
mesh.boundaryMesh();
30 scalar wppCosAngle = wpp.cosAngle();
38 && isA<wedgePolyPatch>(
patches[patchi])
41 const wedgePolyPatch& pp =
42 refCast<const wedgePolyPatch>(
patches[patchi]);
45 scalar ppCosAngle = wpp.centreNormal() & pp.n();
49 pp.size() == wpp.size()
50 &&
mag(pp.axis() & wpp.axis()) >= (1-1
e-3)
51 &&
mag(ppCosAngle - wppCosAngle) >= 1
e-3
66 const Vector<label>& directions,
71 EdgeMap<label> edgesInError;
77 const polyBoundaryMesh&
patches =
mesh.boundaryMesh();
80 if (
patches[patchi].size() && isA<wedgePolyPatch>(
patches[patchi]))
82 const wedgePolyPatch& pp =
83 refCast<const wedgePolyPatch>(
patches[patchi]);
85 scalar wedgeAngle =
acos(pp.cosAngle());
89 Info<<
" Wedge " << pp.name() <<
" with angle "
90 <<
radToDeg(wedgeAngle) <<
" degrees"
97 if (oppositePatchi == -1)
101 Info<<
" ***Cannot find opposite wedge for wedge "
102 << pp.name() <<
endl;
107 const wedgePolyPatch& opp =
108 refCast<const wedgePolyPatch>(
patches[oppositePatchi]);
111 if (
mag(opp.axis() & pp.axis()) < (1-1
e-3))
115 Info<<
" ***Wedges do not have the same axis."
116 <<
" Encountered " << pp.axis()
117 <<
" on patch " << pp.name()
118 <<
" which differs from " << opp.axis()
119 <<
" on opposite wedge patch" << opp.axis()
130 const face&
f = pp[i];
134 label p1 =
f.nextLabel(fp);
135 edgesInError.insert(edge(
p0, p1), -1);
141 const point&
p0 =
p[pp.meshPoints()[0]];
142 forAll(pp.meshPoints(), i)
144 const point& pt =
p[pp.meshPoints()[i]];
145 scalar d =
mag((pt -
p0) & pp.n());
151 Info<<
" ***Wedge patch " << pp.name() <<
" not planar."
152 <<
" Point " << pt <<
" is not in patch plane by "
165 label nEdgesInError = 0;
169 const face&
f = fcs[facei];
174 label p1 =
f.nextLabel(fp);
178 scalar magD =
mag(d);
180 if (magD > ROOTVSMALL)
185 label nEmptyDirs = 0;
186 label nNonEmptyDirs = 0;
187 for (
direction cmpt=0; cmpt<vector::nComponents; cmpt++)
189 if (
mag(d[cmpt]) > 1
e-6)
191 if (directions[cmpt] == 0)
206 else if (nEmptyDirs == 1)
209 if (nNonEmptyDirs > 0)
211 if (edgesInError.insert(edge(
p0, p1), facei))
217 else if (nEmptyDirs > 1)
220 if (edgesInError.insert(edge(
p0, p1), facei))
230 label nErrorEdges =
returnReduce(nEdgesInError, sumOp<label>());
236 Info<<
" ***Number of edges not aligned with or perpendicular to "
237 <<
"non-empty directions: " << nErrorEdges <<
endl;
242 setPtr->resize(2*nEdgesInError);
247 setPtr->insert(iter.key()[0]);
248 setPtr->insert(iter.key()[1]);
258 Info<<
" All edges aligned with or perpendicular to "
259 <<
"non-empty directions." <<
endl;
269 class transformPositionList
276 const coupledPolyPatch& cpp,
277 List<pointField>& pts
283 List<pointField> newPts(pts.size());
286 newPts[facei].setSize(pts[facei].size());
299 if (facePts.size() > index)
301 ptsAtIndex[facei] = facePts[index];
313 cpp.transformPosition(ptsAtIndex);
319 if (facePts.size() > index)
321 facePts[index] = ptsAtIndex[facei];
328 pts.transfer(newPts);
336 const polyMesh&
mesh,
343 const polyBoundaryMesh&
patches =
mesh.boundaryMesh();
347 List<pointField> nbrPoints(fcs.size() -
mesh.nInternalFaces());
354 const coupledPolyPatch& cpp = refCast<const coupledPolyPatch>
361 label bFacei = cpp.start() + i -
mesh.nInternalFaces();
362 const face&
f = cpp[i];
363 nbrPoints[bFacei].setSize(
f.size());
367 nbrPoints[bFacei][fp] =
p0;
372 syncTools::syncBoundaryFaceList
377 transformPositionList()
381 label nErrorFaces = 0;
382 scalar avgMismatch = 0;
383 label nCoupledPoints = 0;
389 const coupledPolyPatch& cpp =
390 refCast<const coupledPolyPatch>(
patches[patchi]);
407 label bFacei = cpp.start() + i -
mesh.nInternalFaces();
408 const face&
f = cpp[i];
410 if (
f.size() != nbrPoints[bFacei].size())
413 <<
"Local face size : " <<
f.size()
414 <<
" does not equal neighbour face size : "
415 << nbrPoints[bFacei].size()
423 scalar d =
mag(
p0 - nbrPoints[bFacei][j]);
425 if (d > smallDist[i])
429 setPtr->insert(cpp.start()+i);
446 reduce(nErrorFaces, sumOp<label>());
447 reduce(avgMismatch, maxOp<scalar>());
448 reduce(nCoupledPoints, sumOp<label>());
450 if (nCoupledPoints > 0)
452 avgMismatch /= nCoupledPoints;
459 Info<<
" **Error in coupled point location: "
461 <<
" faces have their 0th or consecutive vertex not opposite"
462 <<
" their coupled equivalent. Average mismatch "
463 << avgMismatch <<
"."
472 Info<<
" Coupled point location match (average "
473 << avgMismatch <<
") OK." <<
endl;
482 const polyMesh&
mesh,
483 const bool allGeometry,
484 autoPtr<surfaceWriter>& surfWriter,
485 const autoPtr<writer<scalar>>& setWriter
488 label noFailedChecks = 0;
490 Info<<
"\nChecking geometry..." <<
endl;
493 const boundBox& globalBb =
mesh.bounds();
495 Info<<
" Overall domain bounding box "
496 << globalBb.min() <<
" " << globalBb.max() <<
endl;
500 scalar minDistSqr =
magSqr(1
e-6 * globalBb.span());
504 Info<<
" Mesh has " <<
mesh.nGeometricD()
505 <<
" geometric (non-empty/wedge) directions " << validDirs <<
endl;
509 Info<<
" Mesh has " <<
mesh.nSolutionD()
510 <<
" solution (non-empty) directions " << solDirs <<
endl;
512 if (
mesh.nGeometricD() < 3)
514 pointSet nonAlignedPoints(
mesh,
"nonAlignedEdges",
mesh.nPoints()/100);
524 &&
mesh.checkEdgeAlignment(
true, validDirs, &nonAlignedPoints)
531 nonAlignedPoints.size(),
537 Info<<
" <<Writing " << nNonAligned
538 <<
" points on non-aligned edges to set "
539 << nonAlignedPoints.name() <<
endl;
540 nonAlignedPoints.instance() =
mesh.pointsInstance();
541 nonAlignedPoints.write();
550 if (
mesh.checkClosedBoundary(
true)) noFailedChecks++;
554 cellSet aspectCells(
mesh,
"highAspectRatioCells",
mesh.nCells()/100+1);
557 mesh.checkClosedCells
572 Info<<
" <<Writing " << nNonClosed
573 <<
" non closed cells to set " <<
cells.name() <<
endl;
574 cells.instance() =
mesh.pointsInstance();
583 label nHighAspect =
returnReduce(aspectCells.size(), sumOp<label>());
587 Info<<
" <<Writing " << nHighAspect
588 <<
" cells with high aspect ratio to set "
589 << aspectCells.name() <<
endl;
590 aspectCells.instance() =
mesh.pointsInstance();
600 faceSet faces(
mesh,
"zeroAreaFaces",
mesh.nFaces()/100+1);
601 if (
mesh.checkFaceAreas(
true, &faces))
605 label nFaces =
returnReduce(faces.size(), sumOp<label>());
609 Info<<
" <<Writing " << nFaces
610 <<
" zero area faces to set " << faces.name() <<
endl;
611 faces.instance() =
mesh.pointsInstance();
631 Info<<
" <<Writing " << nCells
632 <<
" zero volume cells to set " <<
cells.name() <<
endl;
633 cells.instance() =
mesh.pointsInstance();
644 faceSet faces(
mesh,
"nonOrthoFaces",
mesh.nFaces()/100+1);
645 if (
mesh.checkFaceOrthogonality(
true, &faces))
650 label nFaces =
returnReduce(faces.size(), sumOp<label>());
654 Info<<
" <<Writing " << nFaces
655 <<
" non-orthogonal faces to set " << faces.name() <<
endl;
656 faces.instance() =
mesh.pointsInstance();
666 faceSet faces(
mesh,
"wrongOrientedFaces",
mesh.nFaces()/100 + 1);
667 if (
mesh.checkFacePyramids(
true, -SMALL, &faces))
671 label nFaces =
returnReduce(faces.size(), sumOp<label>());
675 Info<<
" <<Writing " << nFaces
676 <<
" faces with incorrect orientation to set "
677 << faces.name() <<
endl;
678 faces.instance() =
mesh.pointsInstance();
689 faceSet faces(
mesh,
"skewFaces",
mesh.nFaces()/100+1);
690 if (
mesh.checkFaceSkewness(
true, &faces))
694 label nFaces =
returnReduce(faces.size(), sumOp<label>());
698 Info<<
" <<Writing " << nFaces
699 <<
" skew faces to set " << faces.name() <<
endl;
700 faces.instance() =
mesh.pointsInstance();
711 faceSet faces(
mesh,
"coupledFaces",
mesh.nFaces()/100 + 1);
716 label nFaces =
returnReduce(faces.size(), sumOp<label>());
720 Info<<
" <<Writing " << nFaces
721 <<
" faces with incorrectly matched 0th (or consecutive)"
723 << faces.name() <<
endl;
724 faces.instance() =
mesh.pointsInstance();
736 faceSet faces(
mesh,
"lowQualityTetFaces",
mesh.nFaces()/100+1);
739 polyMeshTetDecomposition::checkFaceTets
742 polyMeshTetDecomposition::minTetQuality,
750 label nFaces =
returnReduce(faces.size(), sumOp<label>());
754 Info<<
" <<Writing " << nFaces
755 <<
" faces with low quality or negative volume "
756 <<
"decomposition tets to set " << faces.name() <<
endl;
757 faces.instance() =
mesh.pointsInstance();
771 if (
mesh.checkEdgeLength(
true, minDistSqr, &
points))
780 <<
" points on short edges to set " <<
points.name()
793 if (
mesh.checkPointNearness(
false, minDistSqr, &
points))
801 pointSet nearPoints(
mesh,
"nearPoints",
points);
803 <<
" near (closer than " <<
Foam::sqrt(minDistSqr)
804 <<
" apart) points to set " << nearPoints.
name() <<
endl;
805 nearPoints.instance() =
mesh.pointsInstance();
817 faceSet faces(
mesh,
"concaveFaces",
mesh.nFaces()/100 + 1);
818 if (
mesh.checkFaceAngles(
true, 10, &faces))
822 label nFaces =
returnReduce(faces.size(), sumOp<label>());
826 Info<<
" <<Writing " << nFaces
827 <<
" faces with concave angles to set " << faces.name()
829 faces.instance() =
mesh.pointsInstance();
841 faceSet faces(
mesh,
"warpedFaces",
mesh.nFaces()/100 + 1);
842 if (
mesh.checkFaceFlatness(
true, 0.8, &faces))
846 label nFaces =
returnReduce(faces.size(), sumOp<label>());
850 Info<<
" <<Writing " << nFaces
851 <<
" warped faces to set " << faces.name() <<
endl;
852 faces.instance() =
mesh.pointsInstance();
864 cellSet
cells(
mesh,
"underdeterminedCells",
mesh.nCells()/100);
865 if (
mesh.checkCellDeterminant(
true, &
cells))
871 Info<<
" <<Writing " << nCells
872 <<
" under-determined cells to set " <<
cells.name() <<
endl;
873 cells.instance() =
mesh.pointsInstance();
885 if (
mesh.checkConcaveCells(
true, &
cells))
891 Info<<
" <<Writing " << nCells
892 <<
" concave cells to set " <<
cells.name() <<
endl;
893 cells.instance() =
mesh.pointsInstance();
904 faceSet faces(
mesh,
"lowWeightFaces",
mesh.nFaces()/100);
905 if (
mesh.checkFaceWeight(
true, 0.05, &faces))
909 label nFaces =
returnReduce(faces.size(), sumOp<label>());
911 Info<<
" <<Writing " << nFaces
912 <<
" faces with low interpolation weights to set "
913 << faces.name() <<
endl;
914 faces.instance() =
mesh.pointsInstance();
925 faceSet faces(
mesh,
"lowVolRatioFaces",
mesh.nFaces()/100);
926 if (
mesh.checkVolRatio(
true, 0.01, &faces))
930 label nFaces =
returnReduce(faces.size(), sumOp<label>());
932 Info<<
" <<Writing " << nFaces
933 <<
" faces with low volume ratio cells to set "
934 << faces.name() <<
endl;
935 faces.instance() =
mesh.pointsInstance();
946 const polyBoundaryMesh& pbm =
mesh.boundaryMesh();
948 const word tmName(
mesh.time().timeName());
949 const word procAndTime(
Foam::name(Pstream::myProcNo()) +
"_" + tmName);
951 autoPtr<surfaceWriter> patchWriter;
954 patchWriter.reset(
new surfaceWriters::vtkWriter());
957 surfaceWriter& wr = (surfWriter ? *surfWriter : *patchWriter);
961 const fileName outputDir
963 mesh.time().globalPath()/functionObject::outputPrefix/
"checkMesh"
968 if (isA<cyclicAMIPolyPatch>(pbm[patchi]))
970 const cyclicAMIPolyPatch& cpp =
971 refCast<const cyclicAMIPolyPatch>(pbm[patchi]);
975 Info<<
"Calculating AMI weights between owner patch: "
976 << cpp.name() <<
" and neighbour patch: "
977 << cpp.neighbPatch().name() <<
endl;
986 autoPtr<globalIndex> globalPoints;
987 autoPtr<globalIndex> globalFaces;
998 uniqueMeshPointLabels,
1007 globalFaces().gather
1009 ami.srcWeightsSum(),
1013 if (Pstream::master())
1025 (outputDir / fName),
1029 wr.write(
"weightsSum", mergedWeights);
1033 if (isA<cyclicACMIPolyPatch>(pbm[patchi]))
1035 const cyclicACMIPolyPatch& pp =
1036 refCast<const cyclicACMIPolyPatch>(pbm[patchi]);
1039 globalFaces().gather
1045 if (Pstream::master())
1057 (outputDir / fName),
1061 wr.write(
"mask", mergedMask);
1070 autoPtr<globalIndex> globalPoints;
1071 autoPtr<globalIndex> globalFaces;
1077 cpp.neighbPatch().localFaces(),
1078 cpp.neighbPatch().meshPoints(),
1079 cpp.neighbPatch().meshPointMap(),
1082 uniqueMeshPointLabels,
1091 globalFaces().gather
1093 ami.tgtWeightsSum(),
1097 if (Pstream::master())
1109 (outputDir / fName),
1113 wr.write(
"weightsSum", mergedWeights);
1117 if (isA<cyclicACMIPolyPatch>(pbm[patchi]))
1119 const cyclicACMIPolyPatch& pp =
1120 refCast<const cyclicACMIPolyPatch>(pbm[patchi]);
1122 globalFaces().gather
1124 pp.neighbPatch().mask(),
1128 if (Pstream::master())
1140 (outputDir / fName),
1144 wr.write(
"mask", mergedMask);
1154 return noFailedChecks;