Adding cfMesh-v1.0 into the repository
[foam-extend-3.2.git] / src / meshLibrary / utilities / surfaceTools / surfaceMorpherCells / surfaceMorpherCellsCreateBoundaryFaces.C
blob20304fdcf3cf8185d07bd2b355e8a4371bf0a716
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 "surfaceMorpherCells.H"
29 #include "demandDrivenData.H"
30 #include "helperFunctions.H"
31 #include "primitiveMesh.H"
33 //#define DEBUGMorph
35 # ifdef DEBUGMorph
36 #include "HashSet.H"
37 # endif
39 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 namespace Foam
44 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 bool surfaceMorpherCells::removeCellsWithAllVerticesAtTheBoundary()
48     boolList removeCells(cellFlags_.size(), false);
50     const faceListPMG& faces = mesh_.faces();
51     const cellListPMG& cells = mesh_.cells();
53     bool changed(false);
55     label nRemoved(0);
56     forAll(cellFlags_, cellI)
57         if( cellFlags_[cellI] & BOUNDARY )
58         {
59             const cell& c = cells[cellI];
60             //- remove cells which have all their vertices at the boundary
61             bool allBoundary(true);
63             const labelList labels = c.labels(faces);
65             forAll(labels, lI)
66                 if( !boundaryVertex_[labels[lI]] )
67                 {
68                     allBoundary = false;
69                     break;
70                 }
72             if( allBoundary )
73             {
74                 ++nRemoved;
75                 changed = true;
76                 removeCells[cellI] = true;
77             }
79             //- remove cells which are not topologically closed
80             DynList<edge> edges;
81             DynList<direction> nAppearances;
83             forAll(c, fI)
84             {
85                 const face& f = faces[c[fI]];
86                 forAll(f, eI)
87                 {
88                     const label pos = edges.containsAtPosition(f.faceEdge(eI));
90                     if( pos == -1 )
91                     {
92                         edges.append(f.faceEdge(eI));
93                         nAppearances.append(1);
94                     }
95                     else
96                     {
97                         ++nAppearances[pos];
98                     }
99                 }
100             }
102             forAll(nAppearances, eI)
103                 if( nAppearances[eI] != 2 )
104                 {
105                     ++nRemoved;
106                     changed = true;
107                     removeCells[cellI] = true;
108                 }
110         }
112     if( Pstream::parRun() )
113         reduce(nRemoved, sumOp<label>());
115     if( nRemoved != 0 )
116     {
117         Info << "Removing " << nRemoved
118             << " cells which cannot be morphed" << endl;
119         polyMeshGenModifier(mesh_).removeCells(removeCells);
120     }
122     if( Pstream::parRun() )
123     {
124         reduce(changed, maxOp<bool>());
125     }
127     return changed;
130 bool surfaceMorpherCells::morphBoundaryFaces()
132     Info << "Morphing boundary faces" << endl;
134     newBoundaryFaces_.setSize(0);
135     newBoundaryOwners_.setSize(0);
136     newBoundaryPatches_.setSize(0);
138     const faceListPMG& faces = mesh_.faces();
139     const cellListPMG& cells = mesh_.cells();
141     bool changed(false);
143     forAll(cells, cellI)
144         if( cellFlags_[cellI] & BOUNDARY )
145         {
146             const cell& c = cells[cellI];
148             DynList<label> bFaces;
150             forAll(c, fI)
151                 if( mesh_.faceIsInPatch(c[fI]) != -1 )
152                     bFaces.append(c[fI]);
154             # ifdef DEBUGMorph
155             Info << "Boundary faces in cell " << cellI
156                 << " are " << bFaces << endl;
157             forAll(bFaces, bfI)
158                 Info << "Face " << bFaces[bfI] << " is "
159                     << faces[bFaces[bfI]] << endl;
160             # endif
162             boolList mergedFaces(bFaces.size(), false);
164             face mf = faces[bFaces[0]];
165             mergedFaces[0] = true;
167             bool finished;
168             do
169             {
170                 finished = true;
171                 for(label i=1;i<bFaces.size();++i)
172                 {
173                     if( mergedFaces[i] ) continue;
175                     const face& bf = faces[bFaces[i]];
176                     const edgeList bEdges = bf.edges();
177                     const edgeList mEdges = mf.edges();
179                     direction nSharedEdges(0);
180                     forAll(bEdges, eI)
181                         forAll(mEdges, eJ)
182                             if( bEdges[eI] == mEdges[eJ] )
183                                 ++nSharedEdges;
185                     direction nSharedPoints(0);
186                     forAll(bf, pI)
187                         forAll(mf, pJ)
188                             if( bf[pI] == mf[pJ] )
189                                 ++nSharedPoints;
191                     if(
192                         nSharedEdges &&
193                         ((nSharedEdges + 1) == nSharedPoints)
194                     )
195                     {
196                         mf = help::mergeTwoFaces(mf, bf);
197                         mergedFaces[i] = true;
198                         changed = true;
199                         finished = false;
201                         //- set CHANGED flag
202                         cellFlags_[cellI] |= CHANGED;
203                     }
204                 }
205             }  while( !finished );
207             newBoundaryFaces_.appendList(mf);
208             newBoundaryOwners_.append(cellI);
209             newBoundaryPatches_.append(0);
211             # ifdef DEBUGMorph
212             Info << "Adding merged face " << mf << endl;
213             # endif
215             for(label i=1;i<bFaces.size();++i)
216                 if( !mergedFaces[i] )
217                 {
218                     newBoundaryFaces_.appendList(faces[bFaces[i]]);
219                     newBoundaryOwners_.append(cellI);
220                     newBoundaryPatches_.append(0);
222                     # ifdef DEBUGMorph
223                     Info << "Adding untouched boundary face "
224                         << faces[bFaces[i]] << endl;
225                     # endif
226                 }
227         }
229     if( Pstream::parRun() )
230     {
231         reduce(changed, maxOp<bool>());
232     }
234     if( changed )
235     {
236         replaceMeshBoundary();
237     }
239     # ifdef DEBUGMorph
240     labelHashSet zipCells;
241     mesh_.addressingData().checkCellsZipUp(true, &zipCells);
242     if( zipCells.size() )
243     {
244         Info << "Cells " << zipCells << " are not zipped!!" << endl;
245         ::exit(EXIT_FAILURE);
246     }
247     mesh_.clearAddressingData();
248     # endif
250     Info << "Finished morphing boundary faces" << endl;
252     return changed;
255 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
257 } // End namespace Foam
259 // ************************************************************************* //