topologyCleanerNonMappableCells.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 "demandDrivenData.H"
29 #include "topologicalCleaner.H"
30 #include "decomposeFaces.H"
31 #include "DynList.H"
32 
33 //#define DEBUGCleaner
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 
43 {
44  Info << "Checking for non-mappable cells" << endl;
45  //- decompose cells with more than one boundary face
46  const labelList& owner = mesh_.owner();
47 
48  List<direction> nBoundaryFaces(mesh_.cells().size(), direction(0));
49  const PtrList<boundaryPatch>& boundaries = mesh_.boundaries();
50  forAll(boundaries, patchI)
51  {
52  const label start = boundaries[patchI].patchStart();
53  const label end = start + boundaries[patchI].patchSize();
54 
55  for(label faceI=start;faceI<end;++faceI)
56  {
57  ++nBoundaryFaces[owner[faceI]];
58  }
59  }
60 
61  label nBadCells(0);
62  forAll(nBoundaryFaces, cI)
63  if( nBoundaryFaces[cI] > 1 )
64  {
65  ++nBadCells;
66  decomposeCell_[cI] = true;
67  }
68 
69  if( Pstream::parRun() )
70  reduce(nBadCells, sumOp<label>());
71 
72  if( nBadCells != 0 )
73  changed_ = true;
74 
75  Info << "Found " << nBadCells << " non-mappable cells" << endl;
76  Info << "Finished checking for non-mappable cells" << endl;
77 }
78 
80 {
81  Info << "Checking for non-mappable faces" << endl;
82 
83  const faceListPMG& faces = mesh_.faces();
84  const labelList& owner = mesh_.owner();
85  const labelList& neighbour = mesh_.neighbour();
86 
87  //- find boundary vertices
88  boolList boundaryVertex(mesh_.points().size(), false);
89  const PtrList<boundaryPatch>& boundaries = mesh_.boundaries();
90  forAll(boundaries, patchI)
91  {
92  const label start = boundaries[patchI].patchStart();
93  const label end = start + boundaries[patchI].patchSize();
94 
95  for(label faceI=start;faceI<end;++faceI)
96  {
97  const face& f = faces[faceI];
98  forAll(f, pI)
99  boundaryVertex[f[pI]] = true;
100  }
101  }
102 
103  boolList decomposeFace(faces.size(), false);
104 
105  //- internal faces which have more than two vertices at the boundary
106  //- cannot always be mapped at the boundary and form a valid cell
107  //- The second case of interest are faces which have two vertices at the
108  //- boundary but are not connected over an edge
109  const label nIntFaces = mesh_.nInternalFaces();
110 
111  //bool changed(false);
112 
113  label nBadFaces(0);
114  for(label faceI=0;faceI<nIntFaces;++faceI)
115  {
116  const face& f = faces[faceI];
117 
118  DynList<label> bPos;
119  forAll(f, pI)
120  if( boundaryVertex[f[pI]] )
121  bPos.append(pI);
122 
123  if(
124  (bPos.size() > 2) ||
125  (
126  (bPos.size() == 2) &&
127  (
128  (bPos[1] != (bPos[0] + 1)) &&
129  !((bPos[0] == 0) && (bPos[1] == (f.size() - 1)))
130  )
131  )
132  )
133  {
134  ++nBadFaces;
135  decomposeFace[faceI] = true;
136  decomposeCell_[owner[faceI]] = true;
137  decomposeCell_[neighbour[faceI]] = true;
138  }
139  }
140 
141  if( Pstream::parRun() )
142  {
143  //- check processor faces
144  const PtrList<processorBoundaryPatch>& procBoundaries =
146 
147  forAll(procBoundaries, patchI)
148  {
149  const label start = procBoundaries[patchI].patchStart();
150  const label end = start + procBoundaries[patchI].patchSize();
151 
152  boolList decProcFace(procBoundaries[patchI].patchSize(), false);
153 
154  for(label faceI=start;faceI<end;++faceI)
155  {
156  const face& f = faces[faceI];
157 
158  DynList<label> bPos;
159  forAll(f, pI)
160  if( boundaryVertex[f[pI]] )
161  bPos.append(pI);
162 
163  if(
164  (bPos.size() > 2) ||
165  (
166  (bPos.size() == 2) &&
167  (
168  (bPos[1] != (bPos[0] + 1)) &&
169  !((bPos[0] == 0) && (bPos[1] == (f.size() - 1)))
170  )
171  )
172  )
173  {
174  ++nBadFaces;
175  decProcFace[faceI-start] = true;
176  decomposeFace[faceI] = true;
177  decomposeCell_[owner[faceI]] = true;
178  }
179  }
180 
181  //- send information about decomposed faces to other processor
182  OPstream toOtherProc
183  (
185  procBoundaries[patchI].neiProcNo(),
186  decProcFace.byteSize()
187  );
188  toOtherProc << decProcFace;
189  }
190 
191  forAll(procBoundaries, patchI)
192  {
193  boolList decOtherProc;
194  IPstream fromOtherProc
195  (
197  procBoundaries[patchI].neiProcNo()
198  );
199  fromOtherProc >> decOtherProc;
200 
201  const label start = procBoundaries[patchI].patchStart();
202  forAll(decOtherProc, faceI)
203  if( decOtherProc[faceI] )
204  {
205  decomposeFace[start+faceI] = true;
206  decomposeCell_[owner[start+faceI]] = true;
207  }
208  }
209 
210  reduce(nBadFaces, sumOp<label>());
211  }
212 
213  Info << "Found " << nBadFaces << " non-mappable faces" << endl;
214 
215  if( nBadFaces != 0 )
216  {
217  changed_ = true;
218  decomposeFaces(mesh_).decomposeMeshFaces(decomposeFace);
219  }
220 
221  Info << "Finished checking non-mappable faces" << endl;
222 }
223 
224 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
225 
226 } // End namespace Foam
227 
228 // ************************************************************************* //
Foam::polyMeshGenFaces::neighbour
const labelList & neighbour() const
Definition: polyMeshGenFacesI.H:86
Foam::polyMeshGenFaces::owner
const labelList & owner() const
owner and neighbour cells for faces
Definition: polyMeshGenFacesI.H:67
Foam::decomposeFaces
Definition: decomposeFaces.H:47
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
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:377
Foam::topologicalCleaner::changed_
bool changed_
Definition: topologicalCleaner.H:55
decomposeFaces.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::polyMeshGenPoints::points
const pointFieldPMG & points() const
access to points
Definition: polyMeshGenPointsI.H:44
topologicalCleaner.H
Foam::polyMeshGenFaces::faces
const faceListPMG & faces() const
access to faces
Definition: polyMeshGenFacesI.H:43
Foam::polyMeshGenFaces::nInternalFaces
label nInternalFaces() const
return number of internal faces
Definition: polyMeshGenFacesI.H:48
Foam::UPstream::blocking
@ blocking
Definition: UPstream.H:66
Foam::topologicalCleaner::decomposeCell_
boolList decomposeCell_
Definition: topologicalCleaner.H:57
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::topologicalCleaner::checkNonMappableFaces
void checkNonMappableFaces()
check and fix non-mappable faces
Definition: topologyCleanerNonMappableCells.C:79
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
Foam::polyMeshGenCells::cells
const cellListPMG & cells() const
access to cells
Definition: polyMeshGenCellsI.H:39
Foam::PtrList
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:61
Foam::pointFieldPMG::size
label size() const
return the number of used elements
Definition: pointFieldPMGI.H:71
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::topologicalCleaner::mesh_
polyMeshGen & mesh_
Definition: topologicalCleaner.H:53
Foam::topologicalCleaner::checkNonMappableCells
void checkNonMappableCells()
check and fix non-mappable cells
Definition: topologyCleanerNonMappableCells.C:42
Foam::DynList< label >
Foam::decomposeFaces::decomposeMeshFaces
void decomposeMeshFaces(const boolList &decomposeFace)
decompose selected faces into triangles using midnode subdivision
Definition: decomposeFaces.C:62
Foam::sumOp
Definition: ops.H:162
f
labelList f(nPoints)
Foam::faceListPMG::size
label size() const
return the number of used elements
Definition: faceListPMGI.H:73
Foam::polyMeshGenFaces::boundaries
const PtrList< boundaryPatch > & boundaries() const
ordinary boundaries
Definition: polyMeshGenFacesI.H:111
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
Foam::polyMeshGenFaces::procBoundaries
const PtrList< processorBoundaryPatch > & procBoundaries() const
inter-processor boundaries
Definition: polyMeshGenFacesI.H:106
Foam::direction
unsigned char direction
Definition: direction.H:43
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:50
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
Foam::faceListPMG
Definition: faceListPMG.H:50
DynList.H
Foam::cellListPMG::size
label size() const
return the number of used elements
Definition: cellListPMGI.H:56
Foam::DynList::append
void append(const T &e)
Append an element at the end of the list.
Definition: DynListI.H:304