47 template<
class PatchType>
50 const bool allGeometry,
59 typedef typename PatchType::surfaceTopo TopoType;
61 const label globalSize =
returnReduce(pp.size(), sumOp<label>());
65 <<
setw(9) << globalSize
72 else if (Pstream::parRun())
87 const globalIndex globalFaces(
mesh.nFaces());
91 label meshEdgei = meshEdges[edgei];
92 const labelList& eFaces = edgeFaces[edgei];
95 labelList& globalEFaces = globalEdgeFaces[meshEdgei];
96 globalEFaces.
setSize(eFaces.size());
99 globalEFaces[i] = globalFaces.toGlobal(meshFaces[eFaces[i]]);
108 syncTools::syncEdgeList
112 ListOps::uniqueEqOp<label>(),
117 label labelTyp = TopoType::MANIFOLD;
120 const label meshEdgei = meshEdges[edgei];
121 const labelList& globalEFaces = globalEdgeFaces[meshEdgei];
122 if (globalEFaces.size() == 1)
125 labelTyp =
max(labelTyp, TopoType::OPEN);
127 else if (globalEFaces.size() == 0 || globalEFaces.size() > 2)
130 labelTyp =
max(labelTyp, TopoType::ILLEGAL);
133 reduce(labelTyp, maxOp<label>());
135 if (labelTyp == TopoType::MANIFOLD)
137 Info<<
setw(34) <<
"ok (closed singly connected)";
139 else if (labelTyp == TopoType::OPEN)
142 <<
"ok (non-closed singly connected)";
147 <<
"multiply connected (shared edge)";
152 TopoType pTyp = pp.surfaceType();
154 if (pTyp == TopoType::MANIFOLD)
156 if (pp.checkPointManifold(
true, &
points))
159 <<
"multiply connected (shared point)";
163 Info<<
setw(34) <<
"ok (closed singly connected)";
167 pp.checkTopology(
false, &
points);
171 pp.checkTopology(
false, &
points);
173 if (pTyp == TopoType::OPEN)
176 <<
"ok (non-closed singly connected)";
181 <<
"multiply connected (shared edge)";
192 boundBox bb(pp.points(),
mp,
true);
202 const polyMesh&
mesh,
203 const ZoneMesh<Zone, polyMesh>& zones,
208 for (
const auto& zone : zones)
210 for (
const label elem : zone)
215 && zoneID[elem] != zone.index()
220 zoneID[elem] = zone.index();
230 const polyMesh&
mesh,
231 const bool allTopology,
232 const bool allGeometry,
233 autoPtr<surfaceWriter>& surfWriter,
234 autoPtr<coordSetWriter>& setWriter
237 label noFailedChecks = 0;
239 Info<<
"Checking topology..." <<
endl;
242 mesh.boundaryMesh().checkDefinition(
true);
249 if (isA<emptyPolyPatch>(
mesh.boundaryMesh()[patchi]))
251 nEmpty +=
mesh.boundaryMesh()[patchi].size();
254 reduce(nEmpty, sumOp<label>());
258 if (nCells && (nEmpty % nCells))
260 Info<<
" ***Total number of faces on empty patches" 261 <<
" is not divisible by the number of cells in the mesh." 262 <<
" Hence this mesh is not 1D or 2D." 268 mesh.boundaryMesh().checkParallelSync(
true);
271 mesh.cellZones().checkDefinition(
true);
272 if (
mesh.cellZones().checkParallelSync(
true))
276 mesh.faceZones().checkDefinition(
true);
277 if (
mesh.faceZones().checkParallelSync(
true))
281 mesh.pointZones().checkDefinition(
true);
282 if (
mesh.pointZones().checkParallelSync(
true))
293 const cell& cFaces =
mesh.cells()[celli];
295 if (cFaces.size() <= 3)
299 for (
const label facei : cFaces)
301 if (facei < 0 || facei >=
mesh.nFaces())
312 Info<<
" Illegal cells (less than 4 faces or out of range faces)" 313 <<
" found, number of cells: " << nCells <<
endl;
316 Info<<
" <<Writing " << nCells
317 <<
" illegal cells to set " <<
cells.name() <<
endl;
318 cells.instance() =
mesh.pointsInstance();
320 if (surfWriter && surfWriter->enabled())
327 Info<<
" Cell to face addressing OK." <<
endl;
341 <<
" unused points to set " <<
points.name() <<
endl;
344 if (setWriter && setWriter->enabled())
352 faceSet faces(
mesh,
"upperTriangularFace",
mesh.nFaces()/100);
353 if (
mesh.checkUpperTriangular(
true, &faces))
358 const label nFaces =
returnReduce(faces.size(), sumOp<label>());
362 Info<<
" <<Writing " << nFaces
363 <<
" unordered faces to set " << faces.name() <<
endl;
364 faces.instance() =
mesh.pointsInstance();
366 if (surfWriter && surfWriter->enabled())
374 faceSet faces(
mesh,
"outOfRangeFaces",
mesh.nFaces()/100);
375 if (
mesh.checkFaceVertices(
true, &faces))
379 const label nFaces =
returnReduce(faces.size(), sumOp<label>());
381 Info<<
" <<Writing " << nFaces
382 <<
" faces with out-of-range or duplicate vertices to set " 383 << faces.name() <<
endl;
384 faces.instance() =
mesh.pointsInstance();
386 if (surfWriter && surfWriter->enabled())
402 Info<<
" <<Writing " << nCells
403 <<
" cells with over used edges to set " <<
cells.name()
405 cells.instance() =
mesh.pointsInstance();
407 if (surfWriter && surfWriter->enabled())
416 faceSet faces(
mesh,
"edgeFaces",
mesh.nFaces()/100);
417 if (
mesh.checkFaceFaces(
true, &faces))
422 const label nFaces =
returnReduce(faces.size(), sumOp<label>());
425 Info<<
" <<Writing " << nFaces
426 <<
" faces with non-standard edge connectivity to set " 427 << faces.name() <<
endl;
428 faces.instance() =
mesh.pointsInstance();
430 if (surfWriter && surfWriter->enabled())
441 for (label facei = 0; facei <
mesh.nInternalFaces(); facei++)
443 nInternalFaces[
mesh.faceOwner()[facei]]++;
444 nInternalFaces[
mesh.faceNeighbour()[facei]]++;
446 const polyBoundaryMesh&
patches =
mesh.boundaryMesh();
453 for (
const label facei : owners)
455 nInternalFaces[facei]++;
460 cellSet oneCells(
mesh,
"oneInternalFaceCells",
mesh.nCells()/100);
461 cellSet twoCells(
mesh,
"twoInternalFacesCells",
mesh.nCells()/100);
463 forAll(nInternalFaces, celli)
465 if (nInternalFaces[celli] <= 1)
467 oneCells.insert(celli);
469 else if (nInternalFaces[celli] == 2)
471 twoCells.insert(celli);
475 const label nOneCells =
returnReduce(oneCells.size(), sumOp<label>());
479 Info<<
" <<Writing " << nOneCells
480 <<
" cells with zero or one non-boundary face to set " 483 oneCells.instance() =
mesh.pointsInstance();
485 if (surfWriter && surfWriter->enabled())
491 const label nTwoCells =
returnReduce(twoCells.size(), sumOp<label>());
495 Info<<
" <<Writing " << nTwoCells
496 <<
" cells with two non-boundary faces to set " 499 twoCells.instance() =
mesh.pointsInstance();
501 if (surfWriter && surfWriter->enabled())
509 regionSplit rs(
mesh);
511 if (rs.nRegions() <= 1)
513 Info<<
" Number of regions: " << rs.nRegions() <<
" (OK)." 519 Info<<
" *Number of regions: " << rs.nRegions() <<
endl;
521 Info<<
" The mesh has multiple regions which are not connected " 522 "by any face." <<
endl 523 <<
" <<Writing region information to " 524 <<
mesh.time().timeName()/
"cellToRegion" 532 mesh.time().timeName(),
551 boolList regionDisconnected(rs.nRegions(),
true);
561 label facei =
mesh.nInternalFaces();
562 facei <
mesh.nFaces();
566 const label regioni = rs[
mesh.faceOwner()[facei]];
567 const face&
f =
mesh.faces()[facei];
568 for (
const label verti :
f)
570 label& pRegion = pointToRegion[verti];
575 else if (pRegion == -2)
578 regionDisconnected[regioni] =
false;
580 else if (pRegion != regioni)
583 regionDisconnected[regioni] =
false;
584 regionDisconnected[pRegion] =
false;
591 Pstream::listCombineReduce(regionDisconnected, andEqOp<bool>());
597 PtrList<cellSet> cellRegions(rs.nRegions());
598 for (label i = 0; i < rs.nRegions(); i++)
614 cellRegions[rs[i]].insert(i);
617 for (label i = 0; i < rs.nRegions(); i++)
619 Info<<
" <<Writing region " << i;
622 if (regionDisconnected[i])
624 Info<<
" (fully disconnected)";
628 Info<<
" (point connected)";
633 <<
" cells to cellSet " << cellRegions[i].name() <<
endl;
635 cellRegions[i].
write();
642 <<
" points that are in multiple regions to set " 645 if (setWriter && setWriter->enabled())
662 Info<<
"\nChecking patch topology for multiply connected" 663 <<
" surfaces..." <<
endl;
665 const polyBoundaryMesh&
patches =
mesh.boundaryMesh();
670 <<
setw(20) <<
"Patch" 671 <<
setw(9) <<
"Faces" 672 <<
setw(9) <<
"Points" 673 <<
"Surface topology";
676 Info<<
" Bounding box";
682 const polyPatch& pp =
patches[patchi];
684 if (!isA<processorPolyPatch>(pp))
704 Info<<
"\nChecking faceZone topology for multiply connected" 705 <<
" surfaces..." <<
endl;
711 if (faceZones.size())
714 <<
setw(20) <<
"FaceZone" 715 <<
setw(9) <<
"Faces" 716 <<
setw(9) <<
"Points" 717 <<
setw(34) <<
"Surface topology";
720 Info<<
" Bounding box";
724 for (
const faceZone& fz : faceZones)
742 faceSet mzFaces(
mesh,
"multiZoneFaces",
mesh.nFaces()/100);
746 Info<<
" <<Writing " << nMulti
747 <<
" faces that are in multiple zones" 748 <<
" to set " << mzFaces.name() <<
endl;
749 mzFaces.instance() =
mesh.pointsInstance();
751 if (surfWriter && surfWriter->enabled())
760 Info<<
" No faceZones found."<<
endl;
769 <<
" conflicting points to set " <<
points.name() <<
endl;
772 if (setWriter && setWriter->enabled())
779 Info<<
"\nChecking basic cellZone addressing..." <<
endl;
785 if (cellZones.size())
788 <<
setw(20) <<
"CellZone" 789 <<
setw(13) <<
"Cells" 790 <<
setw(13) <<
"Points" 791 <<
setw(13) <<
"Volume" 792 <<
"BoundingBox" <<
endl;
798 bitSet isZonePoint(
mesh.nPoints());
800 for (
const cellZone& cZone : cellZones)
806 for (
const label celli : cZone)
808 v += cellVolumes[celli];
809 for (
const label facei :
cells[celli])
811 const face&
f = faces[facei];
812 for (
const label verti :
f)
814 if (isZonePoint.set(verti))
816 bb.add(
mesh.points()[verti]);
825 <<
setw(19) << cZone.name()
832 <<
' ' << bb <<
endl;
839 cellSet mzCells(
mesh,
"multiZoneCells",
mesh.nCells()/100);
843 Info<<
" <<Writing " << nMulti
844 <<
" cells that are in multiple zones" 845 <<
" to set " << mzCells.name() <<
endl;
846 mzCells.instance() =
mesh.pointsInstance();
848 if (surfWriter && surfWriter->enabled())
857 Info<<
" No cellZones found."<<
endl;
863 Info<<
"\nChecking basic pointZone addressing..." <<
endl;
869 if (pointZones.size())
872 <<
setw(20) <<
"PointZone" 873 <<
setw(8) <<
"Points" 874 <<
"BoundingBox" <<
nl;
876 for (
const auto& zone : pointZones)
886 <<
setw(20) << zone.name()
896 pointSet mzPoints(
mesh,
"multiZonePoints",
mesh.nPoints()/100);
900 Info<<
" <<Writing " << nMulti
901 <<
" points that are in multiple zones" 902 <<
" to set " << mzPoints.name() <<
endl;
903 mzPoints.instance() =
mesh.pointsInstance();
905 if (setWriter && setWriter->enabled())
914 Info<<
" No pointZones found."<<
endl;
928 mesh.faceNeighbour();
939 return noFailedChecks;
label checkTopology(const polyMesh &mesh, const bool allTopology, const bool allGeometry, autoPtr< surfaceWriter > &surfWriter, autoPtr< coordSetWriter > &setWriter)
List< labelList > labelListList
A List of labelList.
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
ios_base::fmtflags setf(const ios_base::fmtflags f)
Set flags of stream.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
constexpr char nl
The newline '\n' character (0x0a)
void checkPatch(const bool allGeometry, const word &name, const polyMesh &mesh, const PatchType &pp, const labelList &meshFaces, const labelList &meshEdges, pointSet &points)
List< face > faceList
A List of faces.
bool coupled(solutionDict.getOrDefault("coupledEnergyField", false))
Ostream & endl(Ostream &os)
Add newline and flush stream.
void mergeAndWrite(const polyMesh &mesh, surfaceWriter &writer, const word &name, const indirectPrimitivePatch &setPatch, const fileName &outputDir)
Generate merged surface on master and write. Needs input patch.
label checkZones(const polyMesh &mesh, const ZoneMesh< Zone, polyMesh > &zones, topoSet &set)
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
UList< label > labelUList
A UList of labels.
#define forAll(list, i)
Loop across all elements in list.
void setSize(const label n)
Alias for resize()
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with the type pointZone.
Istream and Ostream manipulators taking arguments.
const polyBoundaryMesh & patches
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Omanip< int > setw(const int i)
List< label > labelList
A List of labels.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
List< bool > boolList
A List of bools.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
List< cell > cellList
A List of cells.
ZoneMesh< cellZone, polyMesh > cellZoneMesh
A ZoneMesh with the type cellZone.
const dimensionedScalar mp
Proton mass.
IOList< label > labelIOList
Label container classes.
static constexpr const zero Zero
Global zero (0)