Moving cfMesh into place. Updated contibutors list
[foam-extend-3.2.git] / src / mesh / cfMesh / meshLibrary / utilities / smoothers / topology / topologicalCleaner / topologyCleanerNonMappableCells.C
blob3b280547aee2e511018cd563d4dc1e9c0ce0535f
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.
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
19     for more details.
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/>.
24 Description
26 \*---------------------------------------------------------------------------*/
28 #include "demandDrivenData.H"
29 #include "topologicalCleaner.H"
30 #include "decomposeFaces.H"
31 #include "DynList.H"
33 //#define DEBUGCleaner
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 namespace Foam
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)
51     {
52         const label start = boundaries[patchI].patchStart();
53         const label end = start + boundaries[patchI].patchSize();
55         for(label faceI=start;faceI<end;++faceI)
56         {
57             ++nBoundaryFaces[owner[faceI]];
58         }
59     }
61     label nBadCells(0);
62     forAll(nBoundaryFaces, cI)
63         if( nBoundaryFaces[cI] > 1 )
64         {
65             ++nBadCells;
66             decomposeCell_[cI] = true;
67         }
69     if( Pstream::parRun() )
70         reduce(nBadCells, sumOp<label>());
72     if( nBadCells != 0 )
73         changed_ = true;
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)
91     {
92         const label start = boundaries[patchI].patchStart();
93         const label end = start + boundaries[patchI].patchSize();
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     }
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);
113     label nBadFaces(0);
114     for(label faceI=0;faceI<nIntFaces;++faceI)
115     {
116         const face& f = faces[faceI];
118         DynList<label> bPos;
119         forAll(f, pI)
120             if( boundaryVertex[f[pI]] )
121                 bPos.append(pI);
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     }
141     if( Pstream::parRun() )
142     {
143         //- check processor faces
144         const PtrList<processorBoundaryPatch>& procBoundaries =
145             mesh_.procBoundaries();
147         forAll(procBoundaries, patchI)
148         {
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)
155             {
156                 const face& f = faces[faceI];
158                 DynList<label> bPos;
159                 forAll(f, pI)
160                     if( boundaryVertex[f[pI]] )
161                         bPos.append(pI);
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             }
181             //- send information about decomposed faces to other processor
182             OPstream toOtherProc
183             (
184                 Pstream::blocking,
185                 procBoundaries[patchI].neiProcNo(),
186                 decProcFace.byteSize()
187             );
188             toOtherProc << decProcFace;
189         }
191         forAll(procBoundaries, patchI)
192         {
193             boolList decOtherProc;
194             IPstream fromOtherProc
195             (
196                 Pstream::blocking,
197                 procBoundaries[patchI].neiProcNo()
198             );
199             fromOtherProc >> decOtherProc;
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         }
210         reduce(nBadFaces, sumOp<label>());
211     }
213     Info << "Found " << nBadFaces << " non-mappable faces" << endl;
215     if( nBadFaces != 0 )
216     {
217         changed_ = true;
218         decomposeFaces(mesh_).decomposeMeshFaces(decomposeFace);
219     }
221     Info << "Finished checking non-mappable faces" << endl;
224 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
226 } // End namespace Foam
228 // ************************************************************************* //