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 "demandDrivenData.H"
29 #include "topologicalCleaner.H"
30 #include "decomposeFaces.H"
33 //#define DEBUGCleaner
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 void topologicalCleaner::checkNonMappableCells()
44 Info << "Checking for non-mappable cells" << endl;
45 //- decompose cells with more than one boundary face
46 const labelList& owner = mesh_.owner();
48 List<direction> nBoundaryFaces(mesh_.cells().size(), direction(0));
49 const PtrList<boundaryPatch>& boundaries = mesh_.boundaries();
50 forAll(boundaries, patchI)
52 const label start = boundaries[patchI].patchStart();
53 const label end = start + boundaries[patchI].patchSize();
55 for(label faceI=start;faceI<end;++faceI)
57 ++nBoundaryFaces[owner[faceI]];
62 forAll(nBoundaryFaces, cI)
63 if( nBoundaryFaces[cI] > 1 )
66 decomposeCell_[cI] = true;
69 if( Pstream::parRun() )
70 reduce(nBadCells, sumOp<label>());
75 Info << "Found " << nBadCells << " non-mappable cells" << endl;
76 Info << "Finished checking for non-mappable cells" << endl;
79 void topologicalCleaner::checkNonMappableFaces()
81 Info << "Checking for non-mappable faces" << endl;
83 const faceListPMG& faces = mesh_.faces();
84 const labelList& owner = mesh_.owner();
85 const labelList& neighbour = mesh_.neighbour();
87 //- find boundary vertices
88 boolList boundaryVertex(mesh_.points().size(), false);
89 const PtrList<boundaryPatch>& boundaries = mesh_.boundaries();
90 forAll(boundaries, patchI)
92 const label start = boundaries[patchI].patchStart();
93 const label end = start + boundaries[patchI].patchSize();
95 for(label faceI=start;faceI<end;++faceI)
97 const face& f = faces[faceI];
99 boundaryVertex[f[pI]] = true;
103 boolList decomposeFace(faces.size(), false);
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();
111 //bool changed(false);
114 for(label faceI=0;faceI<nIntFaces;++faceI)
116 const face& f = faces[faceI];
120 if( boundaryVertex[f[pI]] )
126 (bPos.size() == 2) &&
128 (bPos[1] != (bPos[0] + 1)) &&
129 !((bPos[0] == 0) && (bPos[1] == (f.size() - 1)))
135 decomposeFace[faceI] = true;
136 decomposeCell_[owner[faceI]] = true;
137 decomposeCell_[neighbour[faceI]] = true;
141 if( Pstream::parRun() )
143 //- check processor faces
144 const PtrList<processorBoundaryPatch>& procBoundaries =
145 mesh_.procBoundaries();
147 forAll(procBoundaries, patchI)
149 const label start = procBoundaries[patchI].patchStart();
150 const label end = start + procBoundaries[patchI].patchSize();
152 boolList decProcFace(procBoundaries[patchI].patchSize(), false);
154 for(label faceI=start;faceI<end;++faceI)
156 const face& f = faces[faceI];
160 if( boundaryVertex[f[pI]] )
166 (bPos.size() == 2) &&
168 (bPos[1] != (bPos[0] + 1)) &&
169 !((bPos[0] == 0) && (bPos[1] == (f.size() - 1)))
175 decProcFace[faceI-start] = true;
176 decomposeFace[faceI] = true;
177 decomposeCell_[owner[faceI]] = true;
181 //- send information about decomposed faces to other processor
185 procBoundaries[patchI].neiProcNo(),
186 decProcFace.byteSize()
188 toOtherProc << decProcFace;
191 forAll(procBoundaries, patchI)
193 boolList decOtherProc;
194 IPstream fromOtherProc
197 procBoundaries[patchI].neiProcNo()
199 fromOtherProc >> decOtherProc;
201 const label start = procBoundaries[patchI].patchStart();
202 forAll(decOtherProc, faceI)
203 if( decOtherProc[faceI] )
205 decomposeFace[start+faceI] = true;
206 decomposeCell_[owner[start+faceI]] = true;
210 reduce(nBadFaces, sumOp<label>());
213 Info << "Found " << nBadFaces << " non-mappable faces" << endl;
218 decomposeFaces(mesh_).decomposeMeshFaces(decomposeFace);
221 Info << "Finished checking non-mappable faces" << endl;
224 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
226 } // End namespace Foam
228 // ************************************************************************* //