topologicalCleanerInvalidVertices.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | cfMesh: A library for mesh generation
4  \\ / O peration |
5  \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6  \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9  This file is part of cfMesh.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "topologicalCleaner.H"
29 #include "polyMeshGenAddressing.H"
30 #include "DynList.H"
31 #include "meshSurfaceEngine.H"
32 
33 #include <map>
34 
35 //#define DEBUGCheck
36 
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
45 (
46  labelHashSet* irregularNodesPtr
47 )
48 {
49  if( Pstream::parRun() )
50  {
51  return;
52 
54  (
55  "void topologicalCleaner::checkInvalidConnectionsForVerticesCells()"
56  ) << "This does not run in parallel!" << exit(FatalError);
57  }
58 
59  polyMeshGenModifier meshModifier(mesh_);
60 
61  label nPoints = mesh_.points().size();
62  pointFieldPMG& points = meshModifier.pointsAccess();
63  faceListPMG& faces = meshModifier.facesAccess();
64  const cellListPMG& cells = mesh_.cells();
65 
66  const VRWGraph& pointCells = mesh_.addressingData().pointCells();
67  const VRWGraph& cellCells = mesh_.addressingData().cellCells();
68 
69  meshSurfaceEngine mse(mesh_);
70  const labelList& bPoints = mse.boundaryPoints();
71 
72  label nInvalidConnections(0);
73 
74  forAll(bPoints, bpI)
75  {
76  const label pointI = bPoints[bpI];
77 
78  # ifdef DEBUGCheck
79  Info << "Checking point " << pointI << endl;
80  # endif
81 
82  label material(1);
83 
84  labelList materialForCell(pointCells.sizeOfRow(pointI), 0);
85 
86  forAllRow(pointCells, pointI, cI)
87  if( !materialForCell[cI] )
88  {
89  materialForCell[cI] = material;
90 
91  DynList<label> frontCells;
92  frontCells.append(cI);
93 
94  do
95  {
96  DynList<label> newFrontCells;
97 
98  forAll(frontCells, fcI)
99  {
100  const label pointCellI =
101  pointCells(pointI, frontCells[fcI]);
102 
103  forAllRow(cellCells, pointCellI, nI)
104  {
105  forAllRow(pointCells, pointI, pcI)
106  {
107  if( materialForCell[pcI] )
108  continue;
109 
110  if(
111  cellCells(pointCellI, nI) ==
112  pointCells(pointI, pcI)
113  )
114  {
115  newFrontCells.append(pcI);
116  materialForCell[pcI] = material;
117  break;
118  }
119  }
120  }
121  }
122 
123  frontCells = newFrontCells;
124 
125  } while( frontCells.size() != 0 );
126 
127  ++material;
128  }
129 
130  # ifdef DEBUGCheck
131  Info << "Number of materials for vertex is " << material << endl;
132  # endif
133 
134  if( material > 2 )
135  {
136  ++nInvalidConnections;
137 
138  if( irregularNodesPtr )
139  {
140  irregularNodesPtr->insert(pointI);
141  continue;
142  }
143 
144  forAllRow(pointCells, pointI, pcI)
145  {
146  if( materialForCell[pcI] == 1 )
147  continue;
148 
149  const cell& c = cells[pointCells(pointI, pcI)];
150 
151  forAll(c, fI)
152  {
153  face& f = faces[c[fI]];
154 
155  forAll(f, pI)
156  if( f[pI] == pointI )
157  f[pI] = nPoints + materialForCell[pcI] - 1;
158  }
159  }
160 
161  for(label i=1;i<material;++i)
162  {
163  const point p = points[pointI];
164  points.append(p);
165  ++nPoints;
166  }
167  }
168  }
169 
170  Info << "Found " << nInvalidConnections
171  << " invalid cell connections" << endl;
172 
173  mesh_.clearAddressingData();
174 
175  if( nInvalidConnections != 0 )
176  meshModifier.removeUnusedVertices();
177 }
178 
180 (
181  labelHashSet* /*irregularNodesPtr*/
182 )
183 {
184  const meshSurfaceEngine mse(mesh_);
185 
186  const VRWGraph& edgeFaces = mse.edgeFaces();
187  const labelList& faceOwner = mse.faceOwners();
188 
189  boolList removeCell(mesh_.cells().size(), false);
190  bool changed(false);
191 
192  # ifdef USE_OMP
193  # pragma omp parallel for schedule(static, 1)
194  # endif
195  forAll(edgeFaces, edgeI)
196  if( edgeFaces.sizeOfRow(edgeI) > 2 )
197  {
198  forAllRow(edgeFaces, edgeI, fI)
199  removeCell[faceOwner[edgeFaces(edgeI, fI)]] = true;
200 
201  changed = true;
202  }
203 
204  if( Pstream::parRun() )
205  {
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();
211 
212  DynList<label> neiProcs;
213  std::map<label, labelLongList> exchangeData;
214  std::map<label, labelLongList>::iterator eIter;
215 
216  forAll(edgeFaces, eI)
217  {
218  if( edgesAtProcs.sizeOfRow(eI) > 0 )
219  {
220  numFacesAtEdge.insert
221  (
222  globalEdgeLabel[eI],
223  edgeFaces.sizeOfRow(eI)
224  );
225 
226  forAllRow(edgesAtProcs, eI, procI)
227  {
228  const label neiProc = edgesAtProcs(eI, procI);
229 
230  if( neiProc == Pstream::myProcNo() )
231  continue;
232 
233  eIter = exchangeData.find(neiProc);
234  if( eIter == exchangeData.end() )
235  {
236  neiProcs.append(neiProc);
237  exchangeData.insert
238  (
239  std::pair<label, labelLongList>
240  (
241  neiProc,
242  labelLongList()
243  )
244  );
245 
246  eIter = exchangeData.find(neiProc);
247  }
248 
249  eIter->second.append(globalEdgeLabel[eI]);
250  eIter->second.append(edgeFaces.sizeOfRow(eI));
251  }
252  }
253  }
254 
255  //- send data to other processors
256  forAll(neiProcs, procI)
257  {
258  eIter = exchangeData.find(neiProcs[procI]);
259  const labelLongList& dataToSend = eIter->second;
260 
261  OPstream toOtherProc
262  (
264  neiProcs[procI],
265  dataToSend.byteSize()
266  );
267  toOtherProc << dataToSend;
268  }
269 
270  forAll(neiProcs, procI)
271  {
272  labelList receivedData;
273  IPstream fromOtherProc(Pstream::blocking, neiProcs[procI]);
274  fromOtherProc >> receivedData;
275 
276  label counter(0);
277  while( counter < receivedData.size() )
278  {
279  const label geI = receivedData[counter++];
280  const label nFaces = receivedData[counter++];
281 
282  numFacesAtEdge[geI] += nFaces;
283 
284  if( numFacesAtEdge[geI] > 2 )
285  {
286  const label edgeI = globalToLocal[geI];
287  forAllRow(edgeFaces, edgeI, fI)
288  removeCell[faceOwner[edgeFaces(edgeI, fI)]] = true;
289 
290  changed = true;
291  }
292  }
293  }
294  }
295 
296  reduce(changed, maxOp<bool>());
297 
298  if( changed )
299  {
300  polyMeshGenModifier(mesh_).removeCells(removeCell);
301 
302  decomposeCell_.setSize(mesh_.cells().size());
303  decomposeCell_ = false;
304  }
305 }
306 
307 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
308 
309 } // End namespace Foam
310 
311 // ************************************************************************* //
Foam::meshSurfaceEngine::beAtProcs
const VRWGraph & beAtProcs() const
processors which contain the edges
Definition: meshSurfaceEngineI.H:530
Foam::maxOp
Definition: ops.H:172
p
p
Definition: pEqn.H:62
Foam::meshSurfaceEngine::globalToLocalBndEdgeAddressing
const Map< label > & globalToLocalBndEdgeAddressing() const
global boundary edge label to local label. Only for processor edges
Definition: meshSurfaceEngineI.H:510
Foam::meshSurfaceEngine::globalBoundaryEdgeLabel
const labelList & globalBoundaryEdgeLabel() const
global boundary edge label
Definition: meshSurfaceEngineI.H:489
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:50
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::Map< label >
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::cellListPMG
Definition: cellListPMG.H:49
Foam::HashSet< label, Hash< label > >
topologicalCleaner.H
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::LongList< label >
Foam::UPstream::blocking
@ blocking
Definition: UPstream.H:66
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:43
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Info
messageStream Info
forAllRow
#define forAllRow(graph, rowI, index)
Definition: VRWGraph.H:277
Foam::polyMeshGenModifier::removeUnusedVertices
void removeUnusedVertices()
remove unused vertices
Definition: polyMeshGenModifierRemoveUnusedVertices.C:37
Foam::VRWGraph::sizeOfRow
label sizeOfRow(const label rowI) const
Returns the number of elements in the given row.
Definition: VRWGraphI.H:127
Foam::FatalError
error FatalError
Foam::polyMeshGenModifier::pointsAccess
pointFieldPMG & pointsAccess()
access to mesh points
Definition: polyMeshGenModifier.H:107
Foam::meshSurfaceEngine::edgeFaces
const VRWGraph & edgeFaces() const
Definition: meshSurfaceEngineI.H:334
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
meshSurfaceEngine.H
Foam::DynList< label >
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::polyMeshGenModifier
Definition: polyMeshGenModifier.H:52
Foam::LongList::byteSize
label byteSize() const
Return the binary size in number of characters of the UList.
Definition: LongListI.H:209
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:116
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::meshSurfaceEngine::boundaryPoints
const labelList & boundaryPoints() const
Definition: meshSurfaceEngineI.H:84
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:50
FatalErrorIn
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:313
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::DynList::size
label size() const
Definition: DynListI.H:235
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
Foam::polyMeshGenModifier::facesAccess
faceListPMG & facesAccess()
access to mesh faces
Definition: polyMeshGenModifier.H:113
Foam::faceListPMG
Definition: faceListPMG.H:50
Foam::pointFieldPMG
Definition: pointFieldPMG.H:50
Foam::VRWGraph
Definition: VRWGraph.H:101
Foam::labelLongList
LongList< label > labelLongList
Definition: labelLongList.H:46
polyMeshGenAddressing.H
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
Foam::topologicalCleaner::checkInvalidConnectionsForVerticesCells
void checkInvalidConnectionsForVerticesCells(labelHashSet *irregularNodes=NULL)
check and fix vertices where two or more groups of cells meet
Definition: topologicalCleanerInvalidVertices.C:45
Foam::meshSurfaceEngine
Definition: meshSurfaceEngine.H:54
DynList.H
Foam::polyMeshGenModifier::removeCells
void removeCells(const boolList &removeCell, const bool removeProcFaces=true)
remove cells
Definition: polyMeshGenModifierRemoveCells.C:41
Foam::topologicalCleaner::checkInvalidConnectionsForVerticesFaces
void checkInvalidConnectionsForVerticesFaces(labelHashSet *irregularNodes=NULL)
check and fix vertices where two or more groups of faces meet
Definition: topologicalCleanerInvalidVertices.C:180
Foam::DynList::append
void append(const T &e)
Append an element at the end of the list.
Definition: DynListI.H:304
Foam::meshSurfaceEngine::faceOwners
const labelList & faceOwners() const
Definition: meshSurfaceEngineI.H:143