diff --git a/applications/utilities/finiteArea/makeFaMesh/checkPatchTopology.H b/applications/utilities/finiteArea/makeFaMesh/checkPatchTopology.H new file mode 100644 index 0000000000..5fdf2c255b --- /dev/null +++ b/applications/utilities/finiteArea/makeFaMesh/checkPatchTopology.H @@ -0,0 +1,164 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM, distributed under GPL-3.0-or-later. + +Description + Check topology of poly patches used for finite-area. + +Input + mesh (polyMesh) + meshDefDict (system/faMeshDefintion) + +\*---------------------------------------------------------------------------*/ + +// Preliminary checks +{ + typedef typename uindirectPrimitivePatch::surfaceTopo TopoType; + + const polyBoundaryMesh& pbm = mesh.boundaryMesh(); + + wordRes polyPatchNames; + meshDefDict.readIfPresent("polyMeshPatches", polyPatchNames); + + const labelList patchIDs + ( + pbm.patchSet + ( + polyPatchNames, + false, // warnNotFound + true // useGroups + ).sortedToc() + ); + + label nFaceLabels = 0; + for (const label patchi : patchIDs) + { + nFaceLabels += pbm[patchi].size(); + } + + labelList faceLabels(nFaceLabels); + + nFaceLabels = 0; + for (const label patchi : patchIDs) + { + for (const label facei : pbm[patchi].range()) + { + faceLabels[nFaceLabels] = facei; + ++nFaceLabels; + } + } + + uindirectPrimitivePatch pp + ( + UIndirectList(mesh.faces(), faceLabels), + mesh.points() + ); + + // Non-manifold + labelHashSet badEdges(pp.nEdges()/20); + + labelHashSet* pointSetPtr = nullptr; + labelHashSet* badEdgesPtr = &badEdges; + + bool foundError = false; + + if (returnReduceAnd(pp.empty())) + { + // Empty + } + else if (UPstream::parRun()) + { + const labelList meshEdges + ( + pp.meshEdges(mesh.edges(), mesh.pointEdges()) + ); + + // Parallel - use mesh edges + // - no check for point-pinch + // - no check for consistent orientation (if that is posible to + // check?) + + // Count number of edge/face connections (globally) + labelList nEdgeConnections(mesh.nEdges(), Zero); + + const labelListList& edgeFaces = pp.edgeFaces(); + + forAll(edgeFaces, edgei) + { + nEdgeConnections[meshEdges[edgei]] = edgeFaces[edgei].size(); + } + + // Synchronise across coupled edges + syncTools::syncEdgeList + ( + mesh, + nEdgeConnections, + plusEqOp