46template<
class PatchType>
49 const bool allGeometry,
60 if (!Pstream::parRun())
62 typedef typename PatchType::surfaceTopo TopoType;
63 TopoType pTyp = pp.surfaceType();
69 else if (pTyp == TopoType::MANIFOLD)
71 if (pp.checkPointManifold(
true, &
points))
74 <<
"multiply connected (shared point)";
78 Info<<
setw(34) <<
"ok (closed singly connected)";
82 pp.checkTopology(
false, &
points);
86 pp.checkTopology(
false, &
points);
88 if (pTyp == TopoType::OPEN)
91 <<
"ok (non-closed singly connected)";
96 <<
"multiply connected (shared edge)";
107 boundBox bb(pp.points(), mp,
true);
116 const polyMesh&
mesh,
117 const bool allTopology,
118 const bool allGeometry,
119 autoPtr<surfaceWriter>& surfWriter,
120 autoPtr<coordSetWriter>& setWriter
123 label noFailedChecks = 0;
125 Info<<
"Checking topology..." <<
endl;
128 mesh.boundaryMesh().checkDefinition(
true);
135 if (isA<emptyPolyPatch>(
mesh.boundaryMesh()[patchi]))
137 nEmpty +=
mesh.boundaryMesh()[patchi].size();
140 reduce(nEmpty, sumOp<label>());
144 if (nTotCells && (nEmpty % nTotCells))
146 Info<<
" ***Total number of faces on empty patches"
147 <<
" is not divisible by the number of cells in the mesh."
148 <<
" Hence this mesh is not 1D or 2D."
154 mesh.boundaryMesh().checkParallelSync(
true);
157 mesh.cellZones().checkDefinition(
true);
158 if (
mesh.cellZones().checkParallelSync(
true))
162 mesh.faceZones().checkDefinition(
true);
163 if (
mesh.faceZones().checkParallelSync(
true))
167 mesh.pointZones().checkDefinition(
true);
168 if (
mesh.pointZones().checkParallelSync(
true))
179 const cell& cFaces =
mesh.cells()[celli];
181 if (cFaces.size() <= 3)
185 for (
const label facei : cFaces)
187 if (facei < 0 || facei >=
mesh.nFaces())
198 Info<<
" Illegal cells (less than 4 faces or out of range faces)"
199 <<
" found, number of cells: " << nCells <<
endl;
202 Info<<
" <<Writing " << nCells
203 <<
" illegal cells to set " <<
cells.name() <<
endl;
204 cells.instance() =
mesh.pointsInstance();
206 if (surfWriter && surfWriter->enabled())
213 Info<<
" Cell to face addressing OK." <<
endl;
227 <<
" unused points to set " <<
points.name() <<
endl;
230 if (setWriter && setWriter->enabled())
238 faceSet faces(
mesh,
"upperTriangularFace",
mesh.nFaces()/100);
239 if (
mesh.checkUpperTriangular(
true, &faces))
249 <<
" unordered faces to set " << faces.name() <<
endl;
250 faces.instance() =
mesh.pointsInstance();
252 if (surfWriter && surfWriter->enabled())
260 faceSet faces(
mesh,
"outOfRangeFaces",
mesh.nFaces()/100);
261 if (
mesh.checkFaceVertices(
true, &faces))
268 <<
" faces with out-of-range or duplicate vertices to set "
269 << faces.name() <<
endl;
270 faces.instance() =
mesh.pointsInstance();
272 if (surfWriter && surfWriter->enabled())
288 Info<<
" <<Writing " << nCells
289 <<
" cells with over used edges to set " <<
cells.name()
291 cells.instance() =
mesh.pointsInstance();
293 if (surfWriter && surfWriter->enabled())
302 faceSet faces(
mesh,
"edgeFaces",
mesh.nFaces()/100);
303 if (
mesh.checkFaceFaces(
true, &faces))
312 <<
" faces with non-standard edge connectivity to set "
313 << faces.name() <<
endl;
314 faces.instance() =
mesh.pointsInstance();
316 if (surfWriter && surfWriter->enabled())
327 for (label facei = 0; facei <
mesh.nInternalFaces(); facei++)
329 nInternalFaces[
mesh.faceOwner()[facei]]++;
330 nInternalFaces[
mesh.faceNeighbour()[facei]]++;
332 const polyBoundaryMesh&
patches =
mesh.boundaryMesh();
339 for (
const label facei : owners)
341 nInternalFaces[facei]++;
346 cellSet oneCells(
mesh,
"oneInternalFaceCells",
mesh.nCells()/100);
347 cellSet twoCells(
mesh,
"twoInternalFacesCells",
mesh.nCells()/100);
349 forAll(nInternalFaces, celli)
351 if (nInternalFaces[celli] <= 1)
353 oneCells.insert(celli);
355 else if (nInternalFaces[celli] == 2)
357 twoCells.insert(celli);
361 label nOneCells =
returnReduce(oneCells.size(), sumOp<label>());
365 Info<<
" <<Writing " << nOneCells
366 <<
" cells with zero or one non-boundary face to set "
369 oneCells.instance() =
mesh.pointsInstance();
371 if (surfWriter && surfWriter->enabled())
377 label nTwoCells =
returnReduce(twoCells.size(), sumOp<label>());
381 Info<<
" <<Writing " << nTwoCells
382 <<
" cells with two non-boundary faces to set "
385 twoCells.instance() =
mesh.pointsInstance();
387 if (surfWriter && surfWriter->enabled())
395 regionSplit rs(
mesh);
397 if (rs.nRegions() <= 1)
399 Info<<
" Number of regions: " << rs.nRegions() <<
" (OK)."
405 Info<<
" *Number of regions: " << rs.nRegions() <<
endl;
407 Info<<
" The mesh has multiple regions which are not connected "
408 "by any face." <<
endl
409 <<
" <<Writing region information to "
410 <<
mesh.time().timeName()/
"cellToRegion"
418 mesh.time().timeName(),
437 boolList regionDisconnected(rs.nRegions(),
true);
447 label facei =
mesh.nInternalFaces();
448 facei <
mesh.nFaces();
452 const label regioni = rs[
mesh.faceOwner()[facei]];
453 const face&
f =
mesh.faces()[facei];
454 for (
const label verti :
f)
456 label& pRegion = pointToRegion[verti];
461 else if (pRegion == -2)
464 regionDisconnected[regioni] =
false;
466 else if (pRegion != regioni)
469 regionDisconnected[regioni] =
false;
470 regionDisconnected[pRegion] =
false;
477 Pstream::listCombineAllGather
487 PtrList<cellSet> cellRegions(rs.nRegions());
488 for (label i = 0; i < rs.nRegions(); i++)
504 cellRegions[rs[i]].insert(i);
507 for (label i = 0; i < rs.nRegions(); i++)
509 Info<<
" <<Writing region " << i;
512 if (regionDisconnected[i])
514 Info<<
" (fully disconnected)";
518 Info<<
" (point connected)";
523 <<
" cells to cellSet " << cellRegions[i].name() <<
endl;
525 cellRegions[i].
write();
532 <<
" points that are in multiple regions to set "
535 if (setWriter && setWriter->enabled())
552 if (!Pstream::parRun())
554 Info<<
"\nChecking patch topology for multiply connected"
555 <<
" surfaces..." <<
endl;
559 Info<<
"\nChecking basic patch addressing..." <<
endl;
562 const polyBoundaryMesh&
patches =
mesh.boundaryMesh();
567 <<
setw(20) <<
"Patch"
568 <<
setw(9) <<
"Faces"
569 <<
setw(9) <<
"Points";
570 if (!Pstream::parRun())
572 Info<<
setw(34) <<
"Surface topology";
576 Info<<
" Bounding box";
582 const polyPatch& pp =
patches[patchi];
584 if (!isA<processorPolyPatch>(pp))
595 if (!Pstream::parRun())
597 Info<<
"\nChecking faceZone topology for multiply connected"
598 <<
" surfaces..." <<
endl;
602 Info<<
"\nChecking basic faceZone addressing..." <<
endl;
609 if (faceZones.size())
612 <<
setw(20) <<
"FaceZone"
613 <<
setw(9) <<
"Faces"
614 <<
setw(9) <<
"Points";
616 if (!Pstream::parRun())
618 Info<<
setw(34) <<
"Surface topology";
622 Info<<
" Bounding box";
626 for (
const faceZone& fz : faceZones)
634 Info<<
" No faceZones found."<<
endl;
643 <<
" conflicting points to set " <<
points.name() <<
endl;
646 if (setWriter && setWriter->enabled())
653 Info<<
"\nChecking basic cellZone addressing..." <<
endl;
659 if (cellZones.size())
662 <<
setw(20) <<
"CellZone"
663 <<
setw(13) <<
"Cells"
664 <<
setw(13) <<
"Points"
665 <<
setw(13) <<
"Volume"
666 <<
"BoundingBox" <<
endl;
672 bitSet isZonePoint(
mesh.nPoints());
674 for (
const cellZone& cZone : cellZones)
680 for (
const label celli : cZone)
682 v += cellVolumes[celli];
683 for (
const label facei :
cells[celli])
685 const face&
f = faces[facei];
686 for (
const label verti :
f)
688 if (isZonePoint.set(verti))
690 bb.add(
mesh.points()[verti]);
699 <<
setw(19) << cZone.name()
706 <<
' ' << bb <<
endl;
711 Info<<
" No cellZones found."<<
endl;
724 mesh.faceNeighbour();
735 return noFailedChecks;
Istream and Ostream manipulators taking arguments.
reduce(hasMovingMesh, orOp< bool >())
ios_base::fmtflags setf(const ios_base::fmtflags f)
Set flags of stream.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
const polyBoundaryMesh & patches
bool coupled(solutionDict.getOrDefault("coupledEnergyField", false))
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
const dimensionedScalar mp
Proton mass.
List< label > labelList
A List of labels.
ZoneMesh< cellZone, polyMesh > cellZoneMesh
A ZoneMesh with the type cellZone.
List< cell > cellList
A List of cells.
void checkPatch(const bool allGeometry, const word &name, const PatchType &pp, pointSet &points)
label checkTopology(const polyMesh &mesh, const bool allTopology, const bool allGeometry, autoPtr< surfaceWriter > &surfWriter, autoPtr< coordSetWriter > &setWriter)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Omanip< int > setw(const int i)
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
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.
IOList< label > labelIOList
Label container classes.
List< bool > boolList
A List of bools.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
List< face > faceList
A List of faces.
UList< label > labelUList
A UList of labels.
#define forAll(list, i)
Loop across all elements in list.