Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / mesh / cfMesh / utilities / meshes / polyMeshGenModifier / polyMeshGenModifierRenumberMesh.C
blob8949b3b0db7dac35247d67a5cf2de1327e99465e
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 "polyMeshGenModifier.H"
29 #include "demandDrivenData.H"
30 #include "polyMeshGenAddressing.H"
31 #include "SLList.H"
33 //#define DEBUG_ZIPUP
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 namespace Foam
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 void polyMeshGenModifier::renumberMesh()
44     Info << "Renumbering the mesh" << endl;
46     labelList newOrder(mesh_.cells().size());
48     if( true )
49     {
50         const VRWGraph& cellCells = mesh_.addressingData().cellCells();
52         //- the business bit of the renumbering
53         labelLongList nextCell;
55         boolList visited(cellCells.size(), false);
57         label currentCell;
58         label cellInOrder = 0;
60         //- loop over the cells
61         forAll(visited, cellI)
62         {
63             //- find the first cell that has not been visited yet
64             if( !visited[cellI] )
65             {
66                 currentCell = cellI;
68                 //- use this cell as a start
69                 nextCell.append(currentCell);
71                 //- loop through the nextCell list.
72                 //- Add the first cell into the
73                 //- cell order if it has not already been
74                 //- visited and ask for its
75                 //- neighbours. If the neighbour in question
76                 //- has not been visited,
77                 //- add it to the end of the nextCell list
78                 while( nextCell.size() > 0 )
79                 {
80                     currentCell = nextCell.removeLastElement();
82                     if( !visited[currentCell] )
83                     {
84                         visited[currentCell] = true;
86                         //- add into cellOrder
87                         newOrder[cellInOrder] = currentCell;
88                         ++cellInOrder;
90                         //- find if the neighbours have been visited
91                         forAllRow(cellCells, currentCell, nI)
92                         {
93                             const label nei = cellCells(currentCell, nI);
95                             if( !visited[nei] )
96                             {
97                                 //- not visited, add to the list
98                                 nextCell.append(nei);
99                             }
100                         }
101                     }
102                 }
103             }
104         }
105     }
107     cellListPMG& oldCells = this->cellsAccess();
108     const labelList& oldOwner = mesh_.owner();
109     const labelList& oldNeighbour = mesh_.neighbour();
111     cellList newCells(oldCells.size());
113     //- The reverse order list gives the new cell label for every old cell
114     labelLongList reverseOrder(newOrder.size());
116     forAll(newOrder, cellI)
117     {
118         newCells[cellI].transfer(oldCells[newOrder[cellI]]);
120         reverseOrder[newOrder[cellI]] = cellI;
121     }
123     //- Renumber the faces.
124     //- Reverse face order gives the new face number for every old face
125     labelLongList reverseFaceOrder(oldOwner.size(), 0);
127     //- Mark the internal faces with -2 so that they are inserted first
128     forAll(newCells, cellI)
129     {
130         const cell& c = newCells[cellI];
132         forAll(c, faceI)
133         {
134             --reverseFaceOrder[c[faceI]];
135         }
136     }
138     //- Order internal faces
139     label nMarkedFaces = 0;
141     forAll(newCells, cellI)
142     {
143         //- Note:
144         //- Insertion cannot be done in one go as the faces need to be
145         //- added into the list in the increasing order of neighbour
146         //- cells.  Therefore, all neighbours will be detected first
147         //- and then added in the correct order.
149         const cell& c = newCells[cellI];
151         //- Record the neighbour cell
152         DynList<label, 24> neiCells(c.size(), -1);
154         label nNeighbours(0);
156         forAll(c, faceI)
157         {
158             if( reverseFaceOrder[c[faceI]] == -2 )
159             {
160                 //- Face is internal and gets reordered
161                 if( cellI == reverseOrder[oldOwner[c[faceI]]] )
162                 {
163                     neiCells[faceI] = reverseOrder[oldNeighbour[c[faceI]]];
164                 }
165                 else if( cellI == reverseOrder[oldNeighbour[c[faceI]]] )
166                 {
167                     neiCells[faceI] = reverseOrder[oldOwner[c[faceI]]];
168                 }
169                 else
170                 {
171                     Info << "Screwed up!!!" << endl;
172                 }
174                 ++nNeighbours;
175             }
176         }
178         //- Add the faces in the increasing order of neighbours
179         for(label i=0;i<nNeighbours;++i)
180         {
181             //- Find the lowest neighbour which is still valid
182             label nextNei = -1;
183             label minNei = oldCells.size();
185             forAll(neiCells, ncI)
186             {
187                 if( (neiCells[ncI] > -1) && (neiCells[ncI] < minNei) )
188                 {
189                     nextNei = ncI;
190                     minNei = neiCells[ncI];
191                 }
192             }
194             if( nextNei > -1 )
195             {
196                 //- Face is internal and gets reordered
197                 reverseFaceOrder[c[nextNei]] = nMarkedFaces;
199                 //- Stop the neighbour from being used again
200                 neiCells[nextNei] = -1;
202                 ++nMarkedFaces;
203             }
204             else
205             {
206                 FatalErrorIn
207                 (
208                     "void polyMeshGenModifier::renumberedMesh() const"
209                 )   << "Error in internal face insertion"
210                     << abort(FatalError);
211             }
212         }
213     }
215     //- Insert the boundary faces into reordering list
216     forAll(reverseFaceOrder, faceI)
217     {
218         if( reverseFaceOrder[faceI] < 0 )
219         {
220             reverseFaceOrder[faceI] = nMarkedFaces;
222             ++nMarkedFaces;
223         }
224     }
226     //- Face order gives the old face label for every new face
227     labelLongList faceOrder(reverseFaceOrder.size());
229     forAll(faceOrder, faceI)
230     {
231         faceOrder[reverseFaceOrder[faceI]] = faceI;
232     }
234     //- Renumber the cells
235     forAll(newCells, cellI)
236     {
237         cell& c = newCells[cellI];
239         forAll(c, fI)
240         {
241             c[fI] = reverseFaceOrder[c[fI]];
242         }
243     }
245     faceListPMG& oldFaces = this->facesAccess();
246     faceList newFaces(oldFaces.size());
248     forAll(newFaces, faceI)
249     {
250         newFaces[faceI].transfer(oldFaces[faceOrder[faceI]]);
251     }
253     //- Turn the face that need to be turned
254     //- Only loop through internal faces
255     forAll(oldNeighbour, faceI)
256     {
257         const label oldFaceI = faceOrder[faceI];
258         if( oldNeighbour[oldFaceI] < 0 )
259             continue;
261         if
262         (
263             reverseOrder[oldNeighbour[oldFaceI]]
264           < reverseOrder[oldOwner[oldFaceI]]
265         )
266         {
267             newFaces[faceI] = newFaces[faceI].reverseFace();
268         }
269     }
271     //- transfer faces and cells back to the original lists
272     forAll(newCells, cellI)
273         oldCells[cellI].transfer(newCells[cellI]);
274     forAll(newFaces, faceI)
275         oldFaces[faceI].transfer(newFaces[faceI]);
277     mesh_.updateFaceSubsets(reverseFaceOrder);
278     mesh_.updateCellSubsets(reverseOrder);
279     this->clearOut();
280     mesh_.clearOut();
282     Info << "Finished renumbering the mesh" << endl;
285 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
287 } // End namespace Foam
289 // ************************************************************************* //