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"
35 // #define DEBUGSearch
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 void polyMeshGenModifier::reorderBoundaryFaces()
46 Info << "Reordering boundary faces " << endl;
48 if( Pstream::parRun() )
49 reorderProcBoundaryFaces();
51 faceListPMG& faces = mesh_.faces_;
52 cellListPMG& cells = mesh_.cells_;
54 const labelList& neighbour = mesh_.neighbour();
55 const label nInternalFaces = mesh_.nInternalFaces();
57 //- count internal and boundary faces
58 const label numBFaces = faces.size() - nInternalFaces;
60 labelLongList newFaceLabel(faces.size(), -1);
62 //- find faces which should be repositioned
64 labelList internalToChange;
65 labelList boundaryToChange;
68 const label nThreads = 3 * omp_get_num_procs();
70 const label nThreads(1);
72 labelList nInternalToChangeThread(nThreads);
73 labelList nBoundaryToChangeThread(nThreads);
76 # pragma omp parallel num_threads(nThreads)
80 const label threadI = omp_get_thread_num();
82 const label threadI = 0;
85 label& nItc = nInternalToChangeThread[threadI];
86 label& nBtc = nBoundaryToChangeThread[threadI];
88 labelLongList internalToChangeLocal, boundaryToChangeLocal;
90 //- find the boundary faces within the range of internal faces
92 # pragma omp for schedule(static)
94 for(label faceI=0;faceI<nInternalFaces;++faceI)
96 if( neighbour[faceI] == -1 )
97 internalToChangeLocal.append(faceI);
100 nItc = internalToChangeLocal.size();
102 //- find the internal faces within the range of boundary faces
104 # pragma omp for schedule(static)
106 for(label faceI=nInternalFaces;faceI<faces.size();++faceI)
108 if( neighbour[faceI] != -1 )
109 boundaryToChangeLocal.append(faceI);
112 nBtc = boundaryToChangeLocal.size();
114 //- perform reduction such that all threads know how many faces
115 //- need to be swapped
117 # pragma omp critical
127 internalToChange.setSize(nReplaced);
128 boundaryToChange.setSize(nReplaced);
136 for(label i=0;i<threadI;++i)
137 localStart += nInternalToChangeThread[i];
139 forAll(internalToChangeLocal, i)
140 internalToChange[localStart++] = internalToChangeLocal[i];
143 for(label i=0;i<threadI;++i)
144 localStart += nBoundaryToChangeThread[i];
146 forAll(boundaryToChangeLocal, i)
147 boundaryToChange[localStart++] = boundaryToChangeLocal[i];
152 //- start moving positions of faces
153 # pragma omp for schedule(static)
155 forAll(internalToChange, fI)
157 //- swap with the face at the location the face should be
159 f.transfer(faces[internalToChange[fI]]);
160 faces[internalToChange[fI]].transfer(faces[boundaryToChange[fI]]);
161 faces[boundaryToChange[fI]].transfer(f);
162 newFaceLabel[internalToChange[fI]] = boundaryToChange[fI];
163 newFaceLabel[boundaryToChange[fI]] = internalToChange[fI];
170 # pragma omp for schedule(dynamic, 40)
174 cell& c = cells[cellI];
177 if( newFaceLabel[c[fI]] != -1 )
178 c[fI] = newFaceLabel[c[fI]];
182 //- re-create boundary data
183 PtrList<boundaryPatch>& boundaries = mesh_.boundaries_;
184 if( boundaries.size() != 1 )
187 boundaries.setSize(1);
202 boundaries[0].patchStart() = nInternalFaces;
203 boundaries[0].patchSize() = numBFaces;
206 if( Pstream::parRun() )
208 //- processor boundary faces must be contained at the end
210 forAll(mesh_.procBoundaries_, procPatchI)
211 nProcFaces += mesh_.procBoundaries_[procPatchI].patchSize();
213 boundaries[0].patchSize() -= nProcFaces;
216 //- update face subsets
217 mesh_.updateFaceSubsets(newFaceLabel);
219 //- delete invalid data
223 Info << "Finished reordering boundary faces" << endl;
226 void polyMeshGenModifier::reorderProcBoundaryFaces()
228 PtrList<processorBoundaryPatch>& procBoundaries = mesh_.procBoundaries_;
229 if( procBoundaries.size() == 0 )
231 Warning << "Processor " << Pstream::myProcNo() << " has no "
232 << "processor boundaries!" << endl;
236 //- check if there exist any internal or ordinary bnd faces
237 //- which appear after processor bnd faces. Move those faces before
238 //- the processor boundary
239 const label origProcStart = procBoundaries[0].patchStart();
241 forAll(procBoundaries, patchI)
242 nProcFaces += procBoundaries[patchI].patchSize();
244 faceListPMG& faces = mesh_.faces_;
245 cellListPMG& cells = mesh_.cells_;
247 const label shift = faces.size() - (origProcStart + nProcFaces);
253 "void polyMeshGenModifier::reorderProcBoundaryFaces()"
254 ) << "Missing some faces!" << abort(FatalError);
256 labelLongList newFaceLabel(faces.size(), -1);
258 //- faces added after processor boundaries should be moved up front
259 faceList facesAtEnd(shift);
261 for(label faceI=(origProcStart + nProcFaces);faceI<faces.size();++faceI)
263 facesAtEnd[counter].transfer(faces[faceI]);
264 newFaceLabel[faceI] = origProcStart + counter;
269 forAllReverse(procBoundaries, patchI)
271 const label start = procBoundaries[patchI].patchStart();
272 const label end = start + procBoundaries[patchI].patchSize();
274 //- set patch start to the new value
275 procBoundaries[patchI].patchStart() += shift;
277 for(label faceI=end-1;faceI>=start;--faceI)
279 faces[faceI+shift].transfer(faces[faceI]);
280 newFaceLabel[faceI] = faceI + shift;
284 //- store faces taken from the end
285 forAll(facesAtEnd, fI)
287 faces[origProcStart+fI].transfer(facesAtEnd[fI]);
290 //- set correct patch size
291 PtrList<boundaryPatch>& boundaries = mesh_.boundaries_;
292 if( boundaries.size() == 1 )
294 boundaries[0].patchSize() =
295 procBoundaries[0].patchStart() - boundaries[0].patchStart();
299 const label start = boundaries[0].patchStart();
302 boundaries.setSize(1);
310 procBoundaries[0].patchStart() - start,
318 # pragma omp parallel for schedule(dynamic, 40)
322 cell& c = cells[cellI];
325 if( newFaceLabel[c[fI]] != -1 )
326 c[fI] = newFaceLabel[c[fI]];
329 //- update face subsets
330 mesh_.updateFaceSubsets(newFaceLabel);
332 //- delete invalid data
337 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
339 } // End namespace Foam
341 // ************************************************************************* //