1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
11 cfMesh is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
16 cfMesh is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with cfMesh. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
28 #include "topologicalCleaner.H"
29 #include "polyMeshGenAddressing.H"
31 #include "meshSurfaceEngine.H"
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 void topologicalCleaner::checkInvalidConnectionsForVerticesCells
46 labelHashSet* irregularNodesPtr
49 if( Pstream::parRun() )
55 "void topologicalCleaner::checkInvalidConnectionsForVerticesCells()"
56 ) << "This does not run in parallel!" << exit(FatalError);
59 polyMeshGenModifier meshModifier(mesh_);
61 label nPoints = mesh_.points().size();
62 pointFieldPMG& points = meshModifier.pointsAccess();
63 faceListPMG& faces = meshModifier.facesAccess();
64 const cellListPMG& cells = mesh_.cells();
66 const VRWGraph& pointCells = mesh_.addressingData().pointCells();
67 const VRWGraph& cellCells = mesh_.addressingData().cellCells();
69 meshSurfaceEngine mse(mesh_);
70 const labelList& bPoints = mse.boundaryPoints();
72 label nInvalidConnections(0);
76 const label pointI = bPoints[bpI];
79 Info << "Checking point " << pointI << endl;
84 labelList materialForCell(pointCells.sizeOfRow(pointI), 0);
86 forAllRow(pointCells, pointI, cI)
87 if( !materialForCell[cI] )
89 materialForCell[cI] = material;
91 DynList<label> frontCells;
92 frontCells.append(cI);
96 DynList<label> newFrontCells;
98 forAll(frontCells, fcI)
100 const label pointCellI =
101 pointCells(pointI, frontCells[fcI]);
103 forAllRow(cellCells, pointCellI, nI)
105 forAllRow(pointCells, pointI, pcI)
107 if( materialForCell[pcI] )
111 cellCells(pointCellI, nI) ==
112 pointCells(pointI, pcI)
115 newFrontCells.append(pcI);
116 materialForCell[pcI] = material;
123 frontCells = newFrontCells;
125 } while( frontCells.size() != 0 );
131 Info << "Number of materials for vertex is " << material << endl;
136 ++nInvalidConnections;
138 if( irregularNodesPtr )
140 irregularNodesPtr->insert(pointI);
144 forAllRow(pointCells, pointI, pcI)
146 if( materialForCell[pcI] == 1 )
149 const cell& c = cells[pointCells(pointI, pcI)];
153 face& f = faces[c[fI]];
156 if( f[pI] == pointI )
157 f[pI] = nPoints + materialForCell[pcI] - 1;
161 for(label i=1;i<material;++i)
163 const point p = points[pointI];
170 Info << "Found " << nInvalidConnections
171 << " invalid cell connections" << endl;
173 mesh_.clearAddressingData();
175 if( nInvalidConnections != 0 )
176 meshModifier.removeUnusedVertices();
179 void topologicalCleaner::checkInvalidConnectionsForVerticesFaces
181 labelHashSet* irregularNodesPtr
184 const meshSurfaceEngine mse(mesh_);
186 const VRWGraph& edgeFaces = mse.edgeFaces();
187 const labelList& faceOwner = mse.faceOwners();
189 boolList removeCell(mesh_.cells().size(), false);
193 # pragma omp parallel for schedule(static, 1)
195 forAll(edgeFaces, edgeI)
196 if( edgeFaces.sizeOfRow(edgeI) > 2 )
198 forAllRow(edgeFaces, edgeI, fI)
199 removeCell[faceOwner[edgeFaces(edgeI, fI)]] = true;
204 if( Pstream::parRun() )
206 //- boundary edges at processor boundaries
207 Map<label> numFacesAtEdge;
208 const labelList& globalEdgeLabel = mse.globalBoundaryEdgeLabel();
209 const Map<label>& globalToLocal = mse.globalToLocalBndEdgeAddressing();
210 const VRWGraph& edgesAtProcs = mse.beAtProcs();
212 DynList<label> neiProcs;
213 std::map<label, labelLongList> exchangeData;
214 std::map<label, labelLongList>::iterator eIter;
216 forAll(edgeFaces, eI)
218 if( edgesAtProcs.sizeOfRow(eI) > 0 )
220 numFacesAtEdge.insert
223 edgeFaces.sizeOfRow(eI)
226 forAllRow(edgesAtProcs, eI, procI)
228 const label neiProc = edgesAtProcs(eI, procI);
230 if( neiProc == Pstream::myProcNo() )
233 eIter = exchangeData.find(neiProc);
234 if( eIter == exchangeData.end() )
236 neiProcs.append(neiProc);
239 std::pair<label, labelLongList>
246 eIter = exchangeData.find(neiProc);
249 eIter->second.append(globalEdgeLabel[eI]);
250 eIter->second.append(edgeFaces.sizeOfRow(eI));
255 //- send data to other processors
256 forAll(neiProcs, procI)
258 eIter = exchangeData.find(neiProcs[procI]);
259 const labelLongList& dataToSend = eIter->second;
265 dataToSend.byteSize()
267 toOtherProc << dataToSend;
270 forAll(neiProcs, procI)
272 labelList receivedData;
273 IPstream fromOtherProc(Pstream::blocking, neiProcs[procI]);
274 fromOtherProc >> receivedData;
277 while( counter < receivedData.size() )
279 const label geI = receivedData[counter++];
280 const label nFaces = receivedData[counter++];
282 numFacesAtEdge[geI] += nFaces;
284 if( numFacesAtEdge[geI] > 2 )
286 const label edgeI = globalToLocal[geI];
287 forAllRow(edgeFaces, edgeI, fI)
288 removeCell[faceOwner[edgeFaces(edgeI, fI)]] = true;
296 reduce(changed, maxOp<bool>());
300 polyMeshGenModifier(mesh_).removeCells(removeCell);
302 decomposeCell_.setSize(mesh_.cells().size());
303 decomposeCell_ = false;
307 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
309 } // End namespace Foam
311 // ************************************************************************* //