24 const wedgePolyPatch& wpp
27 const polyBoundaryMesh& patches = mesh.boundaryMesh();
29 scalar wppCosAngle = wpp.cosAngle();
37 && isA<wedgePolyPatch>(patches[
patchi])
40 const wedgePolyPatch& pp =
41 refCast<const wedgePolyPatch>(patches[
patchi]);
44 scalar ppCosAngle = wpp.centreNormal() & pp.n();
48 pp.size() == wpp.size()
49 &&
mag(pp.axis() & wpp.axis()) >= (1-1
e-3)
50 &&
mag(ppCosAngle - wppCosAngle) >= 1
e-3
65 const Vector<label>& directions,
70 EdgeMap<label> edgesInError;
76 const polyBoundaryMesh& patches = mesh.boundaryMesh();
79 if (patches[patchi].size() && isA<wedgePolyPatch>(patches[patchi]))
81 const wedgePolyPatch& pp =
82 refCast<const wedgePolyPatch>(patches[
patchi]);
84 scalar wedgeAngle =
acos(pp.cosAngle());
88 Info<<
" Wedge " << pp.name() <<
" with angle " 89 <<
radToDeg(wedgeAngle) <<
" degrees" 96 if (oppositePatchi == -1)
100 Info<<
" ***Cannot find opposite wedge for wedge " 101 << pp.name() <<
endl;
106 const wedgePolyPatch& opp =
107 refCast<const wedgePolyPatch>(patches[oppositePatchi]);
110 if (
mag(opp.axis() & pp.axis()) < (1-1
e-3))
114 Info<<
" ***Wedges do not have the same axis." 115 <<
" Encountered " << pp.axis()
116 <<
" on patch " << pp.name()
117 <<
" which differs from " << opp.axis()
118 <<
" on opposite wedge patch" << opp.axis()
129 const face& f = pp[i];
133 label p1 = f.nextLabel(fp);
134 edgesInError.insert(edge(p0, p1), -1);
140 const point& p0 = p[pp.meshPoints()[0]];
141 forAll(pp.meshPoints(), i)
143 const point& pt = p[pp.meshPoints()[i]];
144 scalar d =
mag((pt - p0) & pp.n());
150 Info<<
" ***Wedge patch " << pp.name() <<
" not planar." 151 <<
" Point " << pt <<
" is not in patch plane by " 164 label nEdgesInError = 0;
168 const face& f = fcs[facei];
173 label p1 = f.nextLabel(fp);
177 scalar magD =
mag(d);
179 if (magD > rootVSmall)
184 label nEmptyDirs = 0;
185 label nNonEmptyDirs = 0;
186 for (
direction cmpt=0; cmpt<vector::nComponents; cmpt++)
188 if (
mag(d[cmpt]) > 1
e-6)
190 if (directions[cmpt] == 0)
205 else if (nEmptyDirs == 1)
208 if (nNonEmptyDirs > 0)
210 if (edgesInError.insert(edge(p0, p1), facei))
216 else if (nEmptyDirs > 1)
219 if (edgesInError.insert(edge(p0, p1), facei))
235 Info<<
" ***Number of edges not aligned with or perpendicular to " 236 <<
"non-empty directions: " << nErrorEdges <<
endl;
241 setPtr->resize(2*nEdgesInError);
246 setPtr->insert(iter.key()[0]);
247 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.transform().transformPosition(ptsAtIndex, ptsAtIndex);
319 if (facePts.size() > index)
321 facePts[index] = ptsAtIndex[facei];
336 const polyMesh& mesh,
343 const polyBoundaryMesh& patches = mesh.boundaryMesh();
347 List<pointField> nbrPoints(fcs.size() - mesh.nInternalFaces());
352 if (patches[patchi].coupled())
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());
366 const point& p0 = p[f[fp]];
367 nbrPoints[bFacei][fp] = p0;
377 transformPositionList()
381 label nErrorFaces = 0;
382 scalar avgMismatch = 0;
383 label nCoupledPoints = 0;
387 if (patches[patchi].coupled())
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()
422 const point& p0 = p[f[fp]];
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 <<
"." 473 Info<<
" Coupled point location match (average " 474 << avgMismatch <<
") OK." <<
endl;
484 const polyMesh& mesh,
493 autoPtr<globalIndex> globalPoints;
494 autoPtr<globalIndex> globalFaces;
502 patch.meshPointMap(),
505 uniqueMeshPointLabels,
528 mesh.time().writeFormat(),
529 mesh.time().writeCompression()
533 "weightsSum_" + file.name(),
546 const polyBoundaryMesh& pbm = mesh.boundaryMesh();
548 const word tmName(mesh.time().timeName());
552 if (isA<cyclicAMIPolyPatch>(pbm[patchi]))
554 const cyclicAMIPolyPatch& cpp =
555 refCast<const cyclicAMIPolyPatch>(pbm[
patchi]);
559 Info<<
"Calculating AMI weights between owner patch: " 560 << cpp.name() <<
" and neighbour patch: " 561 << cpp.nbrPatch().name() <<
endl;
568 fileName(
"postProcessing") /
"src_" + tmName
575 fileName(
"postProcessing") /
"tgt_" + tmName
585 const polyMesh& mesh,
586 const bool allGeometry,
587 const autoPtr<surfaceWriter>& surfWriter,
588 const autoPtr<Foam::setWriter>& setWriter
591 label noFailedChecks = 0;
593 Info<<
"\nChecking geometry..." <<
endl;
596 const boundBox& globalBb = mesh.bounds();
598 Info<<
" Overall domain bounding box " 599 << globalBb.min() <<
" " << globalBb.max() <<
endl;
603 scalar minDistSqr =
magSqr(1
e-6 * globalBb.span());
607 Info<<
" Mesh has " << mesh.nGeometricD()
608 <<
" geometric (non-empty/wedge) directions " << validDirs <<
endl;
612 Info<<
" Mesh has " << mesh.nSolutionD()
613 <<
" solution (non-empty) directions " << solDirs <<
endl;
615 if (mesh.nGeometricD() < 3)
617 pointSet nonAlignedPoints(mesh,
"nonAlignedEdges", mesh.nPoints()/100);
623 &&
checkWedges(mesh,
true, validDirs, &nonAlignedPoints)
627 && mesh.checkEdgeAlignment(
true, validDirs, &nonAlignedPoints)
634 nonAlignedPoints.size(),
640 Info<<
" <<Writing " << nNonAligned
641 <<
" points on non-aligned edges to set " 642 << nonAlignedPoints.name() <<
endl;
643 nonAlignedPoints.instance() = mesh.pointsInstance();
644 nonAlignedPoints.
write();
645 if (setWriter.valid())
653 if (mesh.checkClosedBoundary(
true)) noFailedChecks++;
656 cellSet
cells(mesh,
"nonClosedCells", mesh.nCells()/100+1);
657 cellSet aspectCells(mesh,
"highAspectRatioCells", mesh.nCells()/100+1);
660 mesh.checkClosedCells
675 Info<<
" <<Writing " << nNonClosed
676 <<
" non closed cells to set " <<
cells.name() <<
endl;
677 cells.instance() = mesh.pointsInstance();
679 if (surfWriter.valid())
690 Info<<
" <<Writing " << nHighAspect
691 <<
" cells with high aspect ratio to set " 692 << aspectCells.name() <<
endl;
693 aspectCells.instance() = mesh.pointsInstance();
695 if (surfWriter.valid())
703 faceSet faces(mesh,
"zeroAreaFaces", mesh.nFaces()/100+1);
704 if (mesh.checkFaceAreas(
true, &faces))
712 Info<<
" <<Writing " << nFaces
713 <<
" zero area faces to set " << faces.name() <<
endl;
714 faces.instance() = mesh.pointsInstance();
716 if (surfWriter.valid())
725 cellSet
cells(mesh,
"zeroVolumeCells", mesh.nCells()/100+1);
726 if (mesh.checkCellVolumes(
true, &
cells))
734 Info<<
" <<Writing " << nCells
735 <<
" zero volume cells to set " <<
cells.name() <<
endl;
736 cells.instance() = mesh.pointsInstance();
738 if (surfWriter.valid())
747 faceSet faces(mesh,
"nonOrthoFaces", mesh.nFaces()/100+1);
748 if (mesh.checkFaceOrthogonality(
true, &faces))
757 Info<<
" <<Writing " << nFaces
758 <<
" non-orthogonal faces to set " << faces.name() <<
endl;
759 faces.instance() = mesh.pointsInstance();
761 if (surfWriter.valid())
769 faceSet faces(mesh,
"wrongOrientedFaces", mesh.nFaces()/100 + 1);
770 if (mesh.checkFacePyramids(
true, -small, &faces))
778 Info<<
" <<Writing " << nFaces
779 <<
" faces with incorrect orientation to set " 780 << faces.name() <<
endl;
781 faces.instance() = mesh.pointsInstance();
783 if (surfWriter.valid())
792 faceSet faces(mesh,
"skewFaces", mesh.nFaces()/100+1);
793 if (mesh.checkFaceSkewness(
true, &faces))
801 Info<<
" <<Writing " << nFaces
802 <<
" skew faces to set " << faces.name() <<
endl;
803 faces.instance() = mesh.pointsInstance();
805 if (surfWriter.valid())
814 faceSet faces(mesh,
"coupledFaces", mesh.nFaces()/100 + 1);
823 Info<<
" <<Writing " << nFaces
824 <<
" faces with incorrectly matched 0th (or consecutive)" 826 << faces.name() <<
endl;
827 faces.instance() = mesh.pointsInstance();
829 if (surfWriter.valid())
839 faceSet faces(mesh,
"lowQualityTetFaces", mesh.nFaces()/100+1);
857 Info<<
" <<Writing " << nFaces
858 <<
" faces with low quality or negative volume " 859 <<
"decomposition tets to set " << faces.name() <<
endl;
860 faces.instance() = mesh.pointsInstance();
862 if (surfWriter.valid())
873 pointSet
points(mesh,
"shortEdges", mesh.nPoints()/1000 + 1);
874 if (mesh.checkEdgeLength(
true, minDistSqr, &
points))
882 Info<<
" <<Writing " << nPoints
883 <<
" points on short edges to set " <<
points.name()
885 points.instance() = mesh.pointsInstance();
887 if (setWriter.valid())
896 if (mesh.checkPointNearness(
false, minDistSqr, &
points))
902 if (nPoints > nEdgeClose)
904 pointSet nearPoints(mesh,
"nearPoints",
points);
905 Info<<
" <<Writing " << nPoints
906 <<
" near (closer than " <<
Foam::sqrt(minDistSqr)
907 <<
" apart) points to set " << nearPoints.
name() <<
endl;
908 nearPoints.instance() = mesh.pointsInstance();
910 if (setWriter.valid())
920 faceSet faces(mesh,
"concaveFaces", mesh.nFaces()/100 + 1);
921 if (mesh.checkFaceAngles(
true, 10, &faces))
929 Info<<
" <<Writing " << nFaces
930 <<
" faces with concave angles to set " << faces.name()
932 faces.instance() = mesh.pointsInstance();
934 if (surfWriter.valid())
944 faceSet faces(mesh,
"warpedFaces", mesh.nFaces()/100 + 1);
945 if (mesh.checkFaceFlatness(
true, 0.8, &faces))
953 Info<<
" <<Writing " << nFaces
954 <<
" warped faces to set " << faces.name() <<
endl;
955 faces.instance() = mesh.pointsInstance();
957 if (surfWriter.valid())
967 cellSet
cells(mesh,
"underdeterminedCells", mesh.nCells()/100);
968 if (mesh.checkCellDeterminant(
true, &
cells))
974 Info<<
" <<Writing " << nCells
975 <<
" under-determined cells to set " <<
cells.name() <<
endl;
976 cells.instance() = mesh.pointsInstance();
978 if (surfWriter.valid())
987 cellSet
cells(mesh,
"concaveCells", mesh.nCells()/100);
988 if (mesh.checkConcaveCells(
true, &
cells))
994 Info<<
" <<Writing " << nCells
995 <<
" concave cells to set " <<
cells.name() <<
endl;
996 cells.instance() = mesh.pointsInstance();
998 if (surfWriter.valid())
1007 faceSet faces(mesh,
"lowWeightFaces", mesh.nFaces()/100);
1008 if (mesh.checkFaceWeight(
true, 0.05, &faces))
1014 Info<<
" <<Writing " << nFaces
1015 <<
" faces with low interpolation weights to set " 1016 << faces.name() <<
endl;
1017 faces.instance() = mesh.pointsInstance();
1019 if (surfWriter.valid())
1028 faceSet faces(mesh,
"lowVolRatioFaces", mesh.nFaces()/100);
1029 if (mesh.checkVolRatio(
true, 0.01, &faces))
1035 Info<<
" <<Writing " << nFaces
1036 <<
" faces with low volume ratio cells to set " 1037 << faces.name() <<
endl;
1038 faces.instance() = mesh.pointsInstance();
1040 if (surfWriter.valid())
1052 return noFailedChecks;
dimensionedScalar acos(const dimensionedScalar &ds)
#define forAll(list, i)
Loop across all elements in list.
virtual Ostream & write(const char)=0
Write character.
FvWallInfoData< WallInfo, label > 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.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Unit conversion functions.
void mergeAndWrite(const polyMesh &mesh, const surfaceWriter &setWriter, const word &name, const indirectPrimitivePatch setPatch, const fileName &outputDir)
Generate merged surface on master and write. Needs input patch.
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool master(const label communicator=0)
Am I the master process.
Holds information (coordinate and normal) regarding nearest wall point.
Vector< scalar > vector
A scalar version of the templated Vector.
static label worldComm
Default communicator (all processors)
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
static bool checkFaceTets(const polyMesh &mesh, scalar tol=minTetQuality, const bool report=false, labelHashSet *setPtr=nullptr)
Check face-decomposition tet volume.
vectorField pointField
pointField is a vectorField.
label checkGeometry(const polyMesh &mesh, const bool allGeometry, const autoPtr< surfaceWriter > &, const autoPtr< setWriter > &)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
bool checkWedges(const polyMesh &, const bool report, const Vector< label > &, labelHashSet *)
Check wedge orientation.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
List< label > labelList
A List of labels.
errorManip< error > abort(error &err)
label findOppositeWedge(const polyMesh &, const wedgePolyPatch &)
dimensioned< scalar > magSqr(const dimensioned< Type > &)
bool checkCoupledPoints(const polyMesh &, const bool report, labelHashSet *)
Check 0th vertex on coupled faces.
const word & name() const
Return const reference to name.
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
Addressing for a faceList slice.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
vector point
Point is a vector.
void writeAMIWeightsSums(const polyMesh &)
Write out the weights-sums on all the AMI patches.
static const Vector< Cmpt > one
dimensioned< scalar > mag(const dimensioned< Type > &)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
const doubleScalar e
Elementary charge.
void writeAMIWeightsSum(const polyMesh &, const primitivePatch &, const scalarField &, const fileName &)
Write out the weights-sum on the given AMI patch.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
static const scalar minTetQuality
Minimum tetrahedron quality.
const dimensionedScalar e
Elementary charge.
static List< int > & procID(label communicator)
Process ID of given process index.