Loading...
Searching...
No Matches
checkPatchTopology.H
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2023-2025 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
12
13Description
14 Check topology of poly patches used for finite-area.
15
16Input
17 mesh (polyMesh)
18 meshDefDict (system/finite-area/faMeshDefinition)
19
20\*---------------------------------------------------------------------------*/
21
22// Preliminary checks
23{
24 typedef typename uindirectPrimitivePatch::surfaceTopo TopoType;
25
26 const polyBoundaryMesh& pbm = mesh.boundaryMesh();
28 labelList patchIDs;
30 if
31 (
32 wordRes select;
33 meshDefDict.readIfPresent("polyMeshPatches", select)
34 )
35 {
36 patchIDs = pbm.indices(select, true); // useGroups
37 }
38
39 label nFaceLabels = 0;
40 for (const label patchi : patchIDs)
41 {
42 nFaceLabels += pbm[patchi].size();
43 }
44
47 nFaceLabels = 0;
48 for (const label patchi : patchIDs)
49 {
50 for (const label facei : pbm[patchi].range())
51 {
52 faceLabels[nFaceLabels] = facei;
54 }
55 }
56
58 (
59 UIndirectList<face>(mesh.faces(), faceLabels),
60 mesh.points()
61 );
62
63 // Non-manifold
64 labelHashSet badEdges(pp.nEdges()/20);
66 labelHashSet* pointSetPtr = nullptr;
67 labelHashSet* badEdgesPtr = &badEdges;
69 bool foundError = false;
71 if (returnReduceAnd(pp.empty()))
72 {
73 // Empty
74 }
75 else if (UPstream::parRun())
76 {
77 const labelList meshEdges
78 (
79 pp.meshEdges(mesh.edges(), mesh.pointEdges())
80 );
81
82 // Parallel - use mesh edges
83 // - no check for point-pinch
84 // - no check for consistent orientation (if that is posible to
85 // check?)
86
87 // Count number of edge/face connections (globally)
88 labelList nEdgeConnections(mesh.nEdges(), Zero);
89
90 const labelListList& edgeFaces = pp.edgeFaces();
91
92 forAll(edgeFaces, edgei)
93 {
94 nEdgeConnections[meshEdges[edgei]] = edgeFaces[edgei].size();
95 }
96
97 // Synchronise across coupled edges
98 syncTools::syncEdgeList
99 (
100 mesh,
101 nEdgeConnections,
102 plusEqOp<label>(),
103 label(0) // null value
104 );
105
106 label labelTyp = TopoType::MANIFOLD;
107 forAll(meshEdges, edgei)
108 {
109 const label meshEdgei = meshEdges[edgei];
110 const label numNbrs = nEdgeConnections[meshEdgei];
111 if (numNbrs == 1)
112 {
113 //if (pointSetPtr) pointSetPtr->insert(mesh.edges()[meshEdgei]);
114 labelTyp = Foam::max(labelTyp, TopoType::OPEN);
115 }
116 else if (numNbrs == 0 || numNbrs > 2)
117 {
118 if (pointSetPtr) pointSetPtr->insert(mesh.edges()[meshEdgei]);
119 if (badEdgesPtr) badEdgesPtr->insert(edgei);
120 labelTyp = Foam::max(labelTyp, TopoType::ILLEGAL);
121 }
122 }
123 reduce(labelTyp, maxOp<label>());
124
125 foundError = (labelTyp == TopoType::ILLEGAL);
126 }
127 else
129 const TopoType pTyp = pp.surfaceType(badEdgesPtr);
130
131 foundError = (pTyp == TopoType::ILLEGAL);
132 }
133
134 if (foundError)
136 edgeList dumpEdges(pp.edges(), badEdges.sortedToc());
137
138 vtk::lineWriter writer
139 (
140 pp.localPoints(),
141 dumpEdges,
142 fileName
143 (
144 mesh.time().globalPath()
145 / ("faMesh-construct.illegalEdges")
146 )
147 );
148
149 writer.writeGeometry();
150
151 // CellData
152 writer.beginCellData();
153 writer.writeProcIDs();
154
155 Info<< "Wrote "
156 << returnReduce(dumpEdges.size(), sumOp<label>())
157 << " bad edges: " << writer.output().name() << nl;
158 writer.close();
159 }
160}
161
162// ************************************************************************* //
scalar range
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edgesCentres")))
labelHashSet * pointSetPtr
bool foundError
label nFaceLabels
labelList faceLabels(nFaceLabels)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
labelList patchIDs
const polyBoundaryMesh & pbm
labelHashSet badEdges(pp.nEdges()/20)
labelHashSet * badEdgesPtr
dynamicFvMesh & mesh
return returnReduce(nRefine-oldNRefine, sumOp< label >())
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
List< label > labelList
A List of labels.
Definition List.H:62
PrimitivePatch< UIndirectList< face >, const pointField & > uindirectPrimitivePatch
A PrimitivePatch with UIndirectList for the faces, const reference for the point field.
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299