polyMeshGenModifierRenumberMesh.C
Go to the documentation of this file.
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.
10 
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.
15 
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.
20 
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/>.
23 
24 Description
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "polyMeshGenModifier.H"
29 #include "demandDrivenData.H"
30 #include "polyMeshGenAddressing.H"
31 #include "SLList.H"
32 
33 //#define DEBUG_ZIPUP
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 
43 {
44  Info << "Renumbering the mesh" << endl;
45 
46  labelList newOrder(mesh_.cells().size());
47 
48  if( true )
49  {
50  const VRWGraph& cellCells = mesh_.addressingData().cellCells();
51 
52  //- the business bit of the renumbering
53  labelLongList nextCell;
54 
55  boolList visited(cellCells.size(), false);
56 
57  label currentCell;
58  label cellInOrder = 0;
59 
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;
67 
68  //- use this cell as a start
69  nextCell.append(currentCell);
70 
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();
81 
82  if( !visited[currentCell] )
83  {
84  visited[currentCell] = true;
85 
86  //- add into cellOrder
87  newOrder[cellInOrder] = currentCell;
88  ++cellInOrder;
89 
90  //- find if the neighbours have been visited
91  forAllRow(cellCells, currentCell, nI)
92  {
93  const label nei = cellCells(currentCell, nI);
94 
95  if( !visited[nei] )
96  {
97  //- not visited, add to the list
98  nextCell.append(nei);
99  }
100  }
101  }
102  }
103  }
104  }
105  }
106 
107  cellListPMG& oldCells = this->cellsAccess();
108  const labelList& oldOwner = mesh_.owner();
109  const labelList& oldNeighbour = mesh_.neighbour();
110 
111  cellList newCells(oldCells.size());
112 
113  //- The reverse order list gives the new cell label for every old cell
114  labelLongList reverseOrder(newOrder.size());
115 
116  forAll(newOrder, cellI)
117  {
118  newCells[cellI].transfer(oldCells[newOrder[cellI]]);
119 
120  reverseOrder[newOrder[cellI]] = cellI;
121  }
122 
123  //- Renumber the faces.
124  //- Reverse face order gives the new face number for every old face
125  labelLongList reverseFaceOrder(oldOwner.size(), 0);
126 
127  //- Mark the internal faces with -2 so that they are inserted first
128  forAll(newCells, cellI)
129  {
130  const cell& c = newCells[cellI];
131 
132  forAll(c, faceI)
133  {
134  --reverseFaceOrder[c[faceI]];
135  }
136  }
137 
138  //- Order internal faces
139  label nMarkedFaces = 0;
140 
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.
148 
149  const cell& c = newCells[cellI];
150 
151  //- Record the neighbour cell
152  DynList<label, 24> neiCells(c.size(), -1);
153 
154  label nNeighbours(0);
155 
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  }
173 
174  ++nNeighbours;
175  }
176  }
177 
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();
184 
185  forAll(neiCells, ncI)
186  {
187  if( (neiCells[ncI] > -1) && (neiCells[ncI] < minNei) )
188  {
189  nextNei = ncI;
190  minNei = neiCells[ncI];
191  }
192  }
193 
194  if( nextNei > -1 )
195  {
196  //- Face is internal and gets reordered
197  reverseFaceOrder[c[nextNei]] = nMarkedFaces;
198 
199  //- Stop the neighbour from being used again
200  neiCells[nextNei] = -1;
201 
202  ++nMarkedFaces;
203  }
204  else
205  {
207  (
208  "void polyMeshGenModifier::renumberedMesh() const"
209  ) << "Error in internal face insertion"
210  << abort(FatalError);
211  }
212  }
213  }
214 
215  //- Insert the boundary faces into reordering list
216  forAll(reverseFaceOrder, faceI)
217  {
218  if( reverseFaceOrder[faceI] < 0 )
219  {
220  reverseFaceOrder[faceI] = nMarkedFaces;
221 
222  ++nMarkedFaces;
223  }
224  }
225 
226  //- Face order gives the old face label for every new face
227  labelLongList faceOrder(reverseFaceOrder.size());
228 
229  forAll(faceOrder, faceI)
230  {
231  faceOrder[reverseFaceOrder[faceI]] = faceI;
232  }
233 
234  //- Renumber the cells
235  forAll(newCells, cellI)
236  {
237  cell& c = newCells[cellI];
238 
239  forAll(c, fI)
240  {
241  c[fI] = reverseFaceOrder[c[fI]];
242  }
243  }
244 
245  faceListPMG& oldFaces = this->facesAccess();
246  faceList newFaces(oldFaces.size());
247 
248  forAll(newFaces, faceI)
249  {
250  newFaces[faceI].transfer(oldFaces[faceOrder[faceI]]);
251  }
252 
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;
260 
261  if
262  (
263  reverseOrder[oldNeighbour[oldFaceI]]
264  < reverseOrder[oldOwner[oldFaceI]]
265  )
266  {
267  newFaces[faceI] = newFaces[faceI].reverseFace();
268  }
269  }
270 
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]);
276 
277  mesh_.updateFaceSubsets(reverseFaceOrder);
278  mesh_.updateCellSubsets(reverseOrder);
279  this->clearOut();
280  mesh_.clearOut();
281 
282  Info << "Finished renumbering the mesh" << endl;
283 }
284 
285 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
286 
287 } // End namespace Foam
288 
289 // ************************************************************************* //
Foam::polyMeshGenFaces::neighbour
const labelList & neighbour() const
Definition: polyMeshGenFacesI.H:86
Foam::polyMeshGenFaces::owner
const labelList & owner() const
owner and neighbour cells for faces
Definition: polyMeshGenFacesI.H:67
Foam::polyMeshGenCells::addressingData
const polyMeshGenAddressing & addressingData() const
addressing which may be needed
Definition: polyMeshGenCells.C:327
Foam::LongList::append
void append(const T &e)
Append an element at the end of the list.
Definition: LongListI.H:265
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
polyMeshGenModifier.H
Foam::List::transfer
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::polyMeshGenCells::clearOut
void clearOut() const
clear all pointer data
Definition: polyMeshGenCells.C:254
Foam::LongList::size
label size() const
Size of the active part of the list.
Definition: LongListI.H:203
Foam::polyMeshGenModifier::mesh_
polyMeshGen & mesh_
reference to the mesh
Definition: polyMeshGenModifier.H:56
Foam::cellListPMG::transfer
void transfer(cellList &)
Foam::cellListPMG
Definition: cellListPMG.H:49
Foam::polyMeshGenFaces::updateFaceSubsets
void updateFaceSubsets(const ListType &)
Definition: polyMeshGenFacesI.H:194
Foam::LongList< label >
Foam::polyMeshGenModifier::cellsAccess
cellListPMG & cellsAccess()
access to cells
Definition: polyMeshGenModifier.H:119
Foam::polyMeshGenCells::updateCellSubsets
void updateCellSubsets(const ListType &)
Definition: polyMeshGenCellsI.H:124
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::polyMeshGenModifier::clearOut
void clearOut()
clear out unnecessary data (pointFacesPtr_);
Definition: polyMeshGenModifier.H:194
Foam::Info
messageStream Info
Foam::polyMeshGenCells::cells
const cellListPMG & cells() const
access to cells
Definition: polyMeshGenCellsI.H:39
Foam::VRWGraph::size
label size() const
Returns the number of rows.
Definition: VRWGraphI.H:122
forAllRow
#define forAllRow(graph, rowI, index)
Definition: VRWGraph.H:277
Foam::FatalError
error FatalError
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::DynList
Definition: DynList.H:53
Foam::polyMeshGenModifier::renumberMesh
void renumberMesh()
reorder the cells and faces to reduce the matrix bandwidth
Definition: polyMeshGenModifierRenumberMesh.C:42
Foam::faceListPMG::size
label size() const
return the number of used elements
Definition: faceListPMGI.H:73
SLList.H
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
FatalErrorIn
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:313
Foam::polyMeshGenModifier::facesAccess
faceListPMG & facesAccess()
access to mesh faces
Definition: polyMeshGenModifier.H:113
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::faceListPMG
Definition: faceListPMG.H:50
Foam::VRWGraph
Definition: VRWGraph.H:101
polyMeshGenAddressing.H
Foam::LongList::removeLastElement
T removeLastElement()
Definition: LongListI.H:323
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
Foam::faceListPMG::transfer
void transfer(faceList &)
Foam::polyMeshGenAddressing::cellCells
const VRWGraph & cellCells() const
Definition: polyMeshGenAddressingCellCells.C:134
Foam::cellListPMG::size
label size() const
return the number of used elements
Definition: cellListPMGI.H:56