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 "polyMeshGenModifier.H"
29 #include "demandDrivenData.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 void polyMeshGenModifier::removeFaces(const boolList& removeFace)
44 Info << "Removing faces" << endl;
45 faceListPMG& faces = mesh_.faces_;
46 cellListPMG& cells = mesh_.cells_;
49 labelLongList newFaceLabel(faces.size(), -1);
51 //- copy internal faces
52 const label nInternalFaces = mesh_.nInternalFaces();
53 for(label faceI=0;faceI<nInternalFaces;++faceI)
54 if( !removeFace[faceI] )
57 faces[nFaces].transfer(faces[faceI]);
59 newFaceLabel[faceI] = nFaces;
63 //- copy boundary faces
64 PtrList<boundaryPatch>& boundaries = mesh_.boundaries_;
65 labelList patchStart(boundaries.size());
66 labelList nFacesInPatch(boundaries.size());
68 forAll(boundaries, patchI)
70 const label oldStart = boundaries[patchI].patchStart();
71 const label oldNumFacesInPatch = boundaries[patchI].patchSize();
73 patchStart[npI] = nFaces;
74 nFacesInPatch[npI] = 0;
76 for(label faceI=0;faceI<oldNumFacesInPatch;++faceI)
77 if( !removeFace[oldStart+faceI] )
80 if( nFaces < (oldStart+faceI) )
81 faces[nFaces].transfer(faces[oldStart+faceI]);
82 newFaceLabel[oldStart+faceI] = nFaces++;
88 forAll(boundaries, patchI)
90 boundaries[patchI].patchStart() = patchStart[patchI];
91 boundaries[patchI].patchSize() = nFacesInPatch[patchI];
94 if( Pstream::parRun() )
96 PtrList<processorBoundaryPatch>& procBoundaries =
97 mesh_.procBoundaries_;
100 forAll(procBoundaries, patchI)
101 nProcFaces += procBoundaries[patchI].patchSize();
103 //- copy processor faces into a separate list
104 //- this preserves the order of faces after the modification is finished
105 faceList procFaces(nProcFaces);
107 forAll(procBoundaries, patchI)
109 const label start = procBoundaries[patchI].patchStart();
110 const label end = start + procBoundaries[patchI].patchSize();
111 for(label faceI=start;faceI<end;++faceI)
112 procFaces[nProcFaces++].transfer(faces[faceI]);
115 //- create ordinary boundary faces from processor faces
116 //- which are removed from one processor only
117 //- these faces are stored in the latest ordinary patch
118 forAll(procBoundaries, patchI)
120 //- send data to other proc
121 const label start = procBoundaries[patchI].patchStart();
122 boolList removeProcFace(procBoundaries[patchI].patchSize(), false);
123 forAll(removeProcFace, faceI)
124 if( removeFace[start+faceI] )
125 removeProcFace[faceI] = true;
130 procBoundaries[patchI].neiProcNo(),
131 removeProcFace.byteSize()
133 toOtherProc << removeProcFace;
137 boolList ordinaryBoundaryFace(procFaces.size(), false);
139 forAll(procBoundaries, patchI)
141 const label start = procBoundaries[patchI].patchStart();
142 boolList removeOtherProcFace;
143 IPstream fromOtherProc
146 procBoundaries[patchI].neiProcNo()
148 fromOtherProc >> removeOtherProcFace;
150 forAll(removeOtherProcFace, faceI)
152 if( !removeFace[start+faceI] && removeOtherProcFace[faceI] )
154 //- this face becomes an ordinary boundary face
155 //- because the face on the other side of the processor
156 //- boundary has been deleted
157 ordinaryBoundaryFace[nProcFaces] = true;
158 ++boundaries[npI].patchSize();
159 if( nFaces < (start+faceI) )
160 faces[nFaces].transfer(procFaces[nProcFaces]);
161 newFaceLabel[start+faceI] = nFaces++;
168 if( nProcFaces != procFaces.size() )
171 "void polyMeshGenModifier::removeFaces()"
172 ) << "Invalid number of processor faces!" << abort(FatalError);
174 //- remove faces from processor patches
176 nFacesInPatch.setSize(procBoundaries.size());
177 patchStart.setSize(procBoundaries.size());
178 labelList neiProcNo(procBoundaries.size());
181 forAll(procBoundaries, patchI)
183 const label oldStart = procBoundaries[patchI].patchStart();
184 const label oldNumFacesInPatch = procBoundaries[patchI].patchSize();
186 patchStart[npI] = nFaces;
187 neiProcNo[npI] = procBoundaries[patchI].neiProcNo();
188 nFacesInPatch[npI] = 0;
190 for(register label faceI=0;faceI<oldNumFacesInPatch;++faceI)
193 !removeFace[oldStart+faceI] &&
194 !ordinaryBoundaryFace[nProcFaces]
197 ++nFacesInPatch[npI];
198 faces[nFaces].transfer(procFaces[nProcFaces]);
199 newFaceLabel[oldStart+faceI] = nFaces++;
208 //- all patches still exist
209 forAll(procBoundaries, patchI)
211 procBoundaries[patchI].patchSize() = nFacesInPatch[patchI];
212 procBoundaries[patchI].patchStart() = patchStart[patchI];
216 faces.setSize(nFaces);
218 //- update face subsets in the mesh
219 mesh_.updateFaceSubsets(newFaceLabel);
223 # pragma omp parallel for if( cells.size() > 1000 ) schedule(dynamic, 40)
227 cell& c = cells[cellI];
232 if( newFaceLabel[c[fI]] != -1 )
233 newC.append(newFaceLabel[c[fI]]);
235 c.setSize(newC.size());
243 Info << "Finished removing faces" << endl;
246 void polyMeshGenModifier::removeDuplicateFaces()
248 VRWGraph& pointFaces = this->pointFaces();
250 faceListPMG& faces = mesh_.faces_;
252 labelLongList newFaceLabel(faces.size(), -1);
257 if( newFaceLabel[faceI] != -1 )
260 const face& f = faces[faceI];
261 DynList<label> duplicates;
262 forAllRow(pointFaces, f[0], pfI)
264 const label faceJ = pointFaces(f[0], pfI);
269 if( faces[faceJ] == f )
270 duplicates.append(faceJ);
273 newFaceLabel[faceI] = nFaces;
274 forAll(duplicates, i)
275 newFaceLabel[duplicates[i]] = nFaces;
279 label nInternalFaces(faces.size());
280 if( mesh_.boundaries_.size() != 0 )
281 nInternalFaces = mesh_.boundaries_[0].patchStart();
283 //- remove internal faces
284 for(label faceI=0;faceI<nInternalFaces;++faceI)
286 if( newFaceLabel[faceI] >= faceI )
289 faces[newFaceLabel[faceI]].transfer(faces[faceI]);
292 //- update boundary faces (they cannot be duplicated)
293 forAll(mesh_.boundaries_, patchI)
295 boundaryPatch& patch = mesh_.boundaries_[patchI];
297 const label start = patch.patchStart();
298 const label end = start + patch.patchSize();
300 patch.patchStart() = newFaceLabel[start];
301 for(label faceI=start;faceI<end;++faceI)
303 if( newFaceLabel[faceI] < faceI )
304 faces[newFaceLabel[faceI]].transfer(faces[faceI]);
308 //- update processor faces (they cannot be duplicated)
309 forAll(mesh_.procBoundaries_, patchI)
311 processorBoundaryPatch& patch = mesh_.procBoundaries_[patchI];
313 const label start = patch.patchStart();
314 const label end = start + patch.patchSize();
316 patch.patchStart() = newFaceLabel[start];
317 for(label faceI=start;faceI<end;++faceI)
319 if( newFaceLabel[faceI] < faceI )
320 faces[newFaceLabel[faceI]].transfer(faces[faceI]);
324 faces.setSize(nFaces);
325 mesh_.updateFaceSubsets(newFaceLabel);
328 cellListPMG& cells = mesh_.cells_;
330 # pragma omp parallel for if( cells.size() > 1000 ) schedule(dynamic, 40)
334 cell& c = cells[cellI];
339 if( newFaceLabel[c[fI]] != -1 )
340 newC.append(newFaceLabel[c[fI]]);
342 c.setSize(newC.size());
351 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
353 } // End namespace Foam
355 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //