44 const bool allTopology,
45 const bool allGeometry,
46 const autoPtr<surfaceWriter>& writer
49 label noFailedChecks = 0;
51 Info<<
"Checking topology..." <<
endl;
54 mesh.boundaryMesh().checkDefinition(
true);
61 if (isA<emptyPolyPatch>(mesh.boundaryMesh()[
patchi]))
63 nEmpty += mesh.boundaryMesh()[
patchi].size();
66 reduce(nEmpty, sumOp<label>());
70 if (nTotCells && (nEmpty % nTotCells))
72 Info<<
" ***Total number of faces on empty patches" 73 <<
" is not divisible by the number of cells in the mesh." 74 <<
" Hence this mesh is not 1D or 2D." 80 mesh.boundaryMesh().checkParallelSync(
true);
83 mesh.cellZones().checkDefinition(
true);
84 if (mesh.cellZones().checkParallelSync(
true))
88 mesh.faceZones().checkDefinition(
true);
89 if (mesh.faceZones().checkParallelSync(
true))
93 mesh.pointZones().checkDefinition(
true);
94 if (mesh.pointZones().checkParallelSync(
true))
101 cellSet
cells(mesh,
"illegalCells", mesh.nCells()/100);
103 forAll(mesh.cells(), celli)
105 const cell& cFaces = mesh.cells()[celli];
107 if (cFaces.size() <= 3)
113 if (cFaces[i] < 0 || cFaces[i] >= mesh.nFaces())
124 Info<<
" Illegal cells (less than 4 faces or out of range faces)" 125 <<
" found, number of cells: " << nCells <<
endl;
128 Info<<
" <<Writing " << nCells
129 <<
" illegal cells to set " <<
cells.name() <<
endl;
130 cells.instance() = mesh.pointsInstance();
140 Info<<
" Cell to face addressing OK." <<
endl;
146 pointSet
points(mesh,
"unusedPoints", mesh.nPoints()/100);
147 if (mesh.checkPoints(
true, &
points))
153 Info<<
" <<Writing " << nPoints
154 <<
" unused points to set " <<
points.name() <<
endl;
155 points.instance() = mesh.pointsInstance();
161 faceSet faces(mesh,
"upperTriangularFace", mesh.nFaces()/100);
162 if (mesh.checkUpperTriangular(
true, &faces))
171 Info<<
" <<Writing " << nFaces
172 <<
" unordered faces to set " << faces.name() <<
endl;
173 faces.instance() = mesh.pointsInstance();
183 faceSet faces(mesh,
"outOfRangeFaces", mesh.nFaces()/100);
184 if (mesh.checkFaceVertices(
true, &faces))
190 Info<<
" <<Writing " << nFaces
191 <<
" faces with out-of-range or duplicate vertices to set " 192 << faces.name() <<
endl;
193 faces.instance() = mesh.pointsInstance();
204 cellSet
cells(mesh,
"zipUpCells", mesh.nCells()/100);
205 if (mesh.checkCellsZipUp(
true, &
cells))
211 Info<<
" <<Writing " << nCells
212 <<
" cells with over used edges to set " <<
cells.name()
214 cells.instance() = mesh.pointsInstance();
226 faceSet faces(mesh,
"edgeFaces", mesh.nFaces()/100);
227 if (mesh.checkFaceFaces(
true, &faces))
235 Info<<
" <<Writing " << nFaces
236 <<
" faces with non-standard edge connectivity to set " 237 << faces.name() <<
endl;
238 faces.instance() = mesh.pointsInstance();
249 labelList nInternalFaces(mesh.nCells(), 0);
251 for (
label facei = 0; facei < mesh.nInternalFaces(); facei++)
253 nInternalFaces[mesh.faceOwner()[facei]]++;
254 nInternalFaces[mesh.faceNeighbour()[facei]]++;
256 const polyBoundaryMesh& patches = mesh.boundaryMesh();
259 if (patches[
patchi].coupled())
265 nInternalFaces[owners[i]]++;
270 cellSet oneCells(mesh,
"oneInternalFaceCells", mesh.nCells()/100);
271 cellSet twoCells(mesh,
"twoInternalFacesCells", mesh.nCells()/100);
273 forAll(nInternalFaces, celli)
275 if (nInternalFaces[celli] <= 1)
277 oneCells.insert(celli);
279 else if (nInternalFaces[celli] == 2)
281 twoCells.insert(celli);
289 Info<<
" <<Writing " << nOneCells
290 <<
" cells with zero or one non-boundary face to set " 293 oneCells.instance() = mesh.pointsInstance();
305 Info<<
" <<Writing " << nTwoCells
306 <<
" cells with two non-boundary faces to set " 309 twoCells.instance() = mesh.pointsInstance();
319 regionSplit rs(mesh);
321 if (rs.nRegions() <= 1)
323 Info<<
" Number of regions: " << rs.nRegions() <<
" (OK)." 329 Info<<
" *Number of regions: " << rs.nRegions() <<
endl;
331 Info<<
" The mesh has multiple regions which are not connected " 332 "by any face." << endl
333 <<
" <<Writing region information to " 334 << mesh.time().timeName()/
"cellToRegion" 342 mesh.time().timeName(),
354 boolList regionDisconnected(rs.nRegions(),
true);
360 labelList pointToRegion(mesh.nPoints(), -1);
364 label faceI = mesh.nInternalFaces();
365 faceI < mesh.nFaces();
369 label regionI = rs[mesh.faceOwner()[faceI]];
370 const face& f = mesh.faces()[faceI];
373 label& pRegion = pointToRegion[f[fp]];
378 else if (pRegion == -2)
381 regionDisconnected[regionI] =
false;
383 else if (pRegion != regionI)
386 regionDisconnected[regionI] =
false;
387 regionDisconnected[pRegion] =
false;
393 Pstream::listCombineGather(regionDisconnected, andEqOp<bool>());
394 Pstream::listCombineScatter(regionDisconnected);
400 PtrList<cellSet> cellRegions(rs.nRegions());
401 for (
label i = 0; i < rs.nRegions(); i++)
417 cellRegions[rs[i]].insert(i);
420 for (
label i = 0; i < rs.nRegions(); i++)
422 Info<<
" <<Writing region " << i;
425 if (regionDisconnected[i])
427 Info<<
" (fully disconnected)";
431 Info<<
" (point connected)";
436 <<
" cells to cellSet " << cellRegions[i].name() <<
endl;
438 cellRegions[i].
write();
445 if (!Pstream::parRun())
447 Info<<
"\nChecking patch topology for multiply connected" 448 <<
" surfaces..." <<
endl;
452 Info<<
"\nChecking basic patch addressing..." <<
endl;
456 const polyBoundaryMesh& patches = mesh.boundaryMesh();
469 <<
setw(20) <<
"Patch" 470 <<
setw(9) <<
"Faces" 471 <<
setw(9) <<
"Points";
472 if (!Pstream::parRun())
474 Info<<
setw(34) <<
"Surface topology";
478 Info<<
" Bounding box";
484 const polyPatch& pp = patches[
patchi];
486 if (!isA<processorPolyPatch>(pp))
489 <<
setw(20) << pp.name()
493 if (!Pstream::parRun())
495 primitivePatch::surfaceTopo pTyp = pp.surfaceType();
501 else if (pTyp == primitivePatch::MANIFOLD)
503 if (pp.checkPointManifold(
true, &
points))
506 <<
"multiply connected (shared point)";
510 Info<<
setw(34) <<
"ok (closed singly connected)";
514 pp.checkTopology(
false, &
points);
518 pp.checkTopology(
false, &
points);
520 if (pTyp == primitivePatch::OPEN)
523 <<
"ok (non-closed singly connected)";
528 <<
"multiply connected (shared edge)";
543 bb.min() =
min(bb.min(), pts[mp[i]]);
544 bb.max() =
max(bb.max(), pts[mp[i]]);
546 reduce(bb.min(), minOp<vector>());
547 reduce(bb.max(), maxOp<vector>());
558 <<
" conflicting points to set " 561 points.instance() = mesh.pointsInstance();
577 mesh.faceNeighbour();
588 return noFailedChecks;
label checkTopology(const polyMesh &, const bool, const bool, const autoPtr< surfaceWriter > &)
#define forAll(list, i)
Loop across all elements in list.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
ios_base::fmtflags setf(const ios_base::fmtflags f)
Set flags of stream.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Ostream & endl(Ostream &os)
Add newline and flush stream.
UList< label > labelUList
List< bool > boolList
Bool container classes.
vectorField pointField
pointField is a vectorField.
List< label > labelList
A List of labels.
void mergeAndWrite(const polyMesh &mesh, const surfaceWriter &writer, const word &name, const indirectPrimitivePatch setPatch, const fileName &outputDir)
Generate merged surface on master and write. Needs input patch.
prefixOSstream Pout(cout,"Pout")
Istream and Ostream manipulators taking arguments.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
word name(const complex &)
Return a string representation of a complex.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
virtual Ostream & write(const token &)=0
Write next token to stream.
Omanip< int > setw(const int i)
IOList< label > labelIOList
Label container classes.