44 const bool allTopology,
45 const bool allGeometry,
46 const autoPtr<surfaceWriter>& surfWriter,
47 const autoPtr<Foam::setWriter>& setWriter
50 label noFailedChecks = 0;
52 Info<<
"Checking topology..." <<
endl;
55 mesh.boundaryMesh().checkDefinition(
true);
62 if (isA<emptyPolyPatch>(mesh.boundaryMesh()[
patchi]))
64 nEmpty += mesh.boundaryMesh()[
patchi].size();
67 reduce(nEmpty, sumOp<label>());
71 if (nTotCells && (nEmpty % nTotCells))
73 Info<<
" ***Total number of faces on empty patches" 74 <<
" is not divisible by the number of cells in the mesh." 75 <<
" Hence this mesh is not 1D or 2D." 81 mesh.boundaryMesh().checkParallelSync(
true);
84 mesh.cellZones().checkDefinition(
true);
85 if (mesh.cellZones().checkParallelSync(
true))
89 mesh.faceZones().checkDefinition(
true);
90 if (mesh.faceZones().checkParallelSync(
true))
94 mesh.pointZones().checkDefinition(
true);
95 if (mesh.pointZones().checkParallelSync(
true))
102 cellSet
cells(mesh,
"illegalCells", mesh.nCells()/100);
104 forAll(mesh.cells(), celli)
106 const cell& cFaces = mesh.cells()[celli];
108 if (cFaces.size() <= 3)
114 if (cFaces[i] < 0 || cFaces[i] >= mesh.nFaces())
125 Info<<
" Illegal cells (less than 4 faces or out of range faces)" 126 <<
" found, number of cells: " << nCells <<
endl;
129 Info<<
" <<Writing " << nCells
130 <<
" illegal cells to set " <<
cells.name() <<
endl;
131 cells.instance() = mesh.pointsInstance();
133 if (surfWriter.valid())
141 Info<<
" Cell to face addressing OK." <<
endl;
147 pointSet
points(mesh,
"unusedPoints", mesh.nPoints()/100);
148 if (mesh.checkPoints(
true, &
points))
154 Info<<
" <<Writing " << nPoints
155 <<
" unused points to set " <<
points.name() <<
endl;
156 points.instance() = mesh.pointsInstance();
158 if (setWriter.valid())
166 faceSet faces(mesh,
"upperTriangularFace", mesh.nFaces()/100);
167 if (mesh.checkUpperTriangular(
true, &faces))
176 Info<<
" <<Writing " << nFaces
177 <<
" unordered faces to set " << faces.name() <<
endl;
178 faces.instance() = mesh.pointsInstance();
180 if (surfWriter.valid())
188 faceSet faces(mesh,
"outOfRangeFaces", mesh.nFaces()/100);
189 if (mesh.checkFaceVertices(
true, &faces))
195 Info<<
" <<Writing " << nFaces
196 <<
" faces with out-of-range or duplicate vertices to set " 197 << faces.name() <<
endl;
198 faces.instance() = mesh.pointsInstance();
200 if (surfWriter.valid())
209 cellSet
cells(mesh,
"zipUpCells", mesh.nCells()/100);
210 if (mesh.checkCellsZipUp(
true, &
cells))
216 Info<<
" <<Writing " << nCells
217 <<
" cells with over used edges to set " <<
cells.name()
219 cells.instance() = mesh.pointsInstance();
221 if (surfWriter.valid())
231 faceSet faces(mesh,
"edgeFaces", mesh.nFaces()/100);
232 if (mesh.checkFaceFaces(
true, &faces))
240 Info<<
" <<Writing " << nFaces
241 <<
" faces with non-standard edge connectivity to set " 242 << faces.name() <<
endl;
243 faces.instance() = mesh.pointsInstance();
245 if (surfWriter.valid())
254 labelList nInternalFaces(mesh.nCells(), 0);
256 for (
label facei = 0; facei < mesh.nInternalFaces(); facei++)
258 nInternalFaces[mesh.faceOwner()[facei]]++;
259 nInternalFaces[mesh.faceNeighbour()[facei]]++;
261 const polyBoundaryMesh& patches = mesh.boundaryMesh();
264 if (patches[
patchi].coupled())
270 nInternalFaces[owners[i]]++;
275 cellSet oneCells(mesh,
"oneInternalFaceCells", mesh.nCells()/100);
276 cellSet twoCells(mesh,
"twoInternalFacesCells", mesh.nCells()/100);
278 forAll(nInternalFaces, celli)
280 if (nInternalFaces[celli] <= 1)
282 oneCells.insert(celli);
284 else if (nInternalFaces[celli] == 2)
286 twoCells.insert(celli);
294 Info<<
" <<Writing " << nOneCells
295 <<
" cells with zero or one non-boundary face to set " 298 oneCells.instance() = mesh.pointsInstance();
300 if (surfWriter.valid())
310 Info<<
" <<Writing " << nTwoCells
311 <<
" cells with two non-boundary faces to set " 314 twoCells.instance() = mesh.pointsInstance();
316 if (surfWriter.valid())
324 regionSplit rs(mesh);
326 if (rs.nRegions() <= 1)
328 Info<<
" Number of regions: " << rs.nRegions() <<
" (OK)." 334 Info<<
" *Number of regions: " << rs.nRegions() <<
endl;
336 Info<<
" The mesh has multiple regions which are not connected " 337 "by any face." << endl
338 <<
" <<Writing region information to " 339 << mesh.time().timeName()/
"cellToRegion" 347 mesh.time().timeName(),
366 boolList regionDisconnected(rs.nRegions(),
true);
372 labelList pointToRegion(mesh.nPoints(), -1);
376 label faceI = mesh.nInternalFaces();
377 faceI < mesh.nFaces();
381 label regionI = rs[mesh.faceOwner()[faceI]];
382 const face& f = mesh.faces()[faceI];
385 label& pRegion = pointToRegion[f[fp]];
390 else if (pRegion == -2)
393 regionDisconnected[regionI] =
false;
395 else if (pRegion != regionI)
398 regionDisconnected[regionI] =
false;
399 regionDisconnected[pRegion] =
false;
406 Pstream::listCombineGather(regionDisconnected, andEqOp<bool>());
407 Pstream::listCombineScatter(regionDisconnected);
413 PtrList<cellSet> cellRegions(rs.nRegions());
414 for (
label i = 0; i < rs.nRegions(); i++)
430 cellRegions[rs[i]].insert(i);
433 for (
label i = 0; i < rs.nRegions(); i++)
435 Info<<
" <<Writing region " << i;
438 if (regionDisconnected[i])
440 Info<<
" (fully disconnected)";
444 Info<<
" (point connected)";
449 <<
" cells to cellSet " << cellRegions[i].name() <<
endl;
451 cellRegions[i].
write();
457 Info<<
" <<Writing " << nPoints
458 <<
" points that are in multiple regions to set " 461 if (setWriter.valid())
471 if (!Pstream::parRun())
473 Info<<
"\nChecking patch topology for multiply connected" 474 <<
" surfaces..." <<
endl;
478 Info<<
"\nChecking basic patch addressing..." <<
endl;
482 const polyBoundaryMesh& patches = mesh.boundaryMesh();
495 <<
setw(20) <<
"Patch" 496 <<
setw(9) <<
"Faces" 497 <<
setw(9) <<
"Points";
498 if (!Pstream::parRun())
500 Info<<
setw(34) <<
"Surface topology";
504 Info<<
" Bounding box";
510 const polyPatch& pp = patches[
patchi];
512 if (!isA<processorPolyPatch>(pp))
515 <<
setw(20) << pp.name()
519 if (!Pstream::parRun())
521 primitivePatch::surfaceTopo pTyp = pp.surfaceType();
527 else if (pTyp == primitivePatch::MANIFOLD)
529 if (pp.checkPointManifold(
true, &
points))
532 <<
"multiply connected (shared point)";
536 Info<<
setw(34) <<
"ok (closed singly connected)";
540 pp.checkTopology(
false, &
points);
544 pp.checkTopology(
false, &
points);
546 if (pTyp == primitivePatch::OPEN)
549 <<
"ok (non-closed singly connected)";
554 <<
"multiply connected (shared edge)";
569 bb.min() =
min(bb.min(), pts[mp[i]]);
570 bb.
max() =
max(bb.max(), pts[mp[i]]);
572 reduce(bb.min(), minOp<vector>());
573 reduce(bb.max(), maxOp<vector>());
584 <<
" conflicting points to set " 587 points.instance() = mesh.pointsInstance();
603 mesh.faceNeighbour();
614 return noFailedChecks;
#define forAll(list, i)
Loop across all elements in list.
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
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.
ios_base::fmtflags setf(const ios_base::fmtflags f)
Set flags of stream.
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.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Holds information (coordinate and normal) regarding nearest wall point.
label checkTopology(const polyMesh &, const bool, const bool, const autoPtr< surfaceWriter > &, const autoPtr< setWriter > &)
static const layerAndWeight max
UList< label > labelUList
List< bool > boolList
Bool container classes.
vectorField pointField
pointField is a vectorField.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
List< label > labelList
A List of labels.
Istream and Ostream manipulators taking arguments.
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.
prefixOSstream Pout(cout, "Pout")
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Omanip< int > setw(const int i)
IOList< label > labelIOList
Label container classes.