createPolyCells.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Description
28  create cellPolys
29  - use pointCells when searching for connectivity
30  - initialize the cell connectivity with '-1'
31  - find both cell faces corresponding to the baffles and mark them
32  to prevent a connection
33  - standard connectivity checks
34 
35  - added baffle support
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #include "meshReader.H"
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 void Foam::meshReader::createPolyCells()
44 {
45  // loop through all cell faces and create connectivity. This will produce
46  // a global face list and will describe all cells as lists of face labels
47 
48  const faceListList& cFaces = cellFaces();
49 
50  // count the maximum number of faces and set the size of the cellPolys_
51  cellPolys_.setSize(cFaces.size());
52 
53  label maxFaces = 0;
54 
55  forAll(cellPolys_, celli)
56  {
57  cellPolys_[celli].setSize(cFaces[celli].size(), -1);
58 
59  maxFaces += cFaces[celli].size();
60  }
61 
62  Info<< "Maximum possible number of faces in mesh: " << maxFaces << endl;
63 
64  meshFaces_.setSize(maxFaces);
65 
66  // set reference to point-cell addressing
67  const labelListList& ptCells = pointCells();
68 
69  // size the baffle lists and initialize to -1
70  baffleIds_.setSize(baffleFaces_.size());
71  forAll(baffleIds_, baffleI)
72  {
73  baffleIds_[baffleI].setSize(2);
74  }
75 
76  // block off baffles first
77  //
78  // To prevent internal faces, we'll mark the cell faces
79  // with negative cell ids (offset by nCells).
80  // eg,
81  // celli = -(nCells + baffleI)
82  //
83  // To distinguish these from the normal '-1' marker, we require
84  // celli = -(nCells + baffleI) < -1
85  //
86  // This condition is met provided that nCells > 1.
87  // ie., baffles require at least 2 volume cells
88 
89  label baffleOffset = cFaces.size();
90  forAll(baffleFaces_, baffleI)
91  {
92  label celli = -(baffleOffset + baffleI);
93  const face& curFace = baffleFaces_[baffleI];
94 
95  // get the list of labels
96  const labelList& curPoints = curFace;
97 
98  // a baffle is a single face - only need to match one face
99  // get the list of cells sharing this point
100  const labelList& curNeighbours = ptCells[curPoints[0]];
101 
102  label nNeighbours = 0;
103 
104  // For all neighbours
105  forAll(curNeighbours, neiI)
106  {
107  label curNei = curNeighbours[neiI];
108 
109  // get the list of search faces
110  const faceList& searchFaces = cFaces[curNei];
111 
112  forAll(searchFaces, neiFacei)
113  {
114  int cmp = face::compare(curFace, searchFaces[neiFacei]);
115 
116  if (cmp)
117  {
118  // maintain baffle orientation
119  // side0: baffle normal same as attached face
120  // side1: baffle normal opposite from attached face
121  //
122  label side = 0;
123  if (cmp < 0)
124  {
125  side = 1;
126  }
127 
128 #ifdef DEBUG_FACE_ORDERING
129  Info<< "cmp " << cmp << " matched " << curFace
130  << " with " << searchFaces[neiFacei]
131  << endl;
132 
133 
134  Info<< "match " << baffleI
135  << " (" << origCellId_[baffleOffset+baffleI] << ")"
136  << " side " << side
137  << " against cell " << curNei
138  << " face " << neiFacei
139  << " curFace " << curFace[1]
140  << " neiFace " << searchFaces[neiFacei][1]
141  << endl;
142 #endif
143 
144  if (baffleIds_[baffleI][side].notUsed())
145  {
146  baffleIds_[baffleI][side] = cellFaceIdentifier
147  (
148  curNei,
149  neiFacei
150  );
151 
152  nNeighbours++;
153  }
154  else
155  {
156  Info<< "multiple matches for side " << side
157  << " of baffle " << baffleI
158  << " (original cell "
159  << origCellId_[baffleOffset+baffleI] << ")"
160  << endl;
161  }
162  break;
163  }
164  }
165  if (nNeighbours >= 2) break;
166  }
167 
168  if (nNeighbours == 2)
169  {
170  for (label side = 0; side < nNeighbours; ++side)
171  {
172  label neiCell = baffleIds_[baffleI][side].cellId();
173  label neiFace = baffleIds_[baffleI][side].faceId();
174 
175  if (baffleIds_[baffleI][side].used())
176  {
177  cellPolys_[neiCell][neiFace] = celli;
178  }
179  }
180  }
181  else
182  {
183  Info<< "drop baffle " << baffleI
184  << " (original cell "
185  << origCellId_[baffleOffset+baffleI] << ")"
186  << " with " << nNeighbours << " neighbours" << endl;
187 
188  baffleFaces_[baffleI].clear();
189  baffleIds_[baffleI].clear();
190  }
191  }
192 
193 #ifdef DEBUG_CELLPOLY
194  Info<< "cellPolys_" << cellPolys_ << endl;
195  Info<< "baffleFaces_" << baffleFaces_ << endl;
196  Info<< "baffleIds_" << baffleIds_ << endl;
197 #endif
198 
199  bool found = false;
200 
201  nInternalFaces_ = 0;
202 
203  forAll(cFaces, celli)
204  {
205  // Note:
206  // Insertion cannot be done in one go as the faces need to be
207  // added into the list in the increasing order of neighbour
208  // cells. Therefore, all neighbours will be detected first
209  // and then added in the correct order.
210 
211  const faceList& curFaces = cFaces[celli];
212 
213  // Record the neighbour cell
214  labelList neiCells(curFaces.size(), -1);
215 
216  // Record the face of neighbour cell
217  labelList faceOfNeiCell(curFaces.size(), -1);
218 
219  label nNeighbours = 0;
220 
221  // For all faces ...
222  forAll(curFaces, facei)
223  {
224  // Skip already matched faces or those tagged by baffles
225  if (cellPolys_[celli][facei] != -1) continue;
226 
227  found = false;
228 
229  const face& curFace = curFaces[facei];
230 
231  // get the list of labels
232  const labelList& curPoints = curFace;
233 
234  // For all points
235  forAll(curPoints, pointi)
236  {
237  // get the list of cells sharing this point
238  const labelList& curNeighbours = ptCells[curPoints[pointi]];
239 
240  // For all neighbours
241  forAll(curNeighbours, neiI)
242  {
243  label curNei = curNeighbours[neiI];
244 
245  // reject neighbours with the lower label. This should
246  // also reject current cell.
247  if (curNei > celli)
248  {
249  // get the list of search faces
250  const faceList& searchFaces = cFaces[curNei];
251 
252  forAll(searchFaces, neiFacei)
253  {
254  if (searchFaces[neiFacei] == curFace)
255  {
256  // Record the neighbour cell and face
257  neiCells[facei] = curNei;
258  faceOfNeiCell[facei] = neiFacei;
259  nNeighbours++;
260 #ifdef DEBUG_FACE_ORDERING
261  Info<< " cell " << celli
262  << " face " << facei
263  << " point " << pointi
264  << " nei " << curNei
265  << " neiFace " << neiFacei
266  << endl;
267 #endif
268  found = true;
269  break;
270  }
271  }
272  if (found) break;
273  }
274  if (found) break;
275  }
276  if (found) break;
277  } // End of current points
278  } // End of current faces
279 
280  // Add the faces in the increasing order of neighbours
281  for (label neiSearch = 0; neiSearch < nNeighbours; neiSearch++)
282  {
283  // Find the lowest neighbour which is still valid
284  label nextNei = -1;
285  label minNei = cellPolys_.size();
286 
287  forAll(neiCells, ncI)
288  {
289  if (neiCells[ncI] > -1 && neiCells[ncI] < minNei)
290  {
291  nextNei = ncI;
292  minNei = neiCells[ncI];
293  }
294  }
295 
296  if (nextNei > -1)
297  {
298  // Add the face to the list of faces
299  meshFaces_[nInternalFaces_] = curFaces[nextNei];
300 
301  // Mark for owner
302  cellPolys_[celli][nextNei] = nInternalFaces_;
303 
304  // Mark for neighbour
305  cellPolys_[neiCells[nextNei]][faceOfNeiCell[nextNei]] =
307 
308  // Stop the neighbour from being used again
309  neiCells[nextNei] = -1;
310 
311  // Increment number of faces counter
312  nInternalFaces_++;
313  }
314  else
315  {
317  << "Error in internal face insertion"
318  << abort(FatalError);
319  }
320  }
321  }
322 
323 #ifdef DEBUG_CELLPOLY
324  Info<< "cellPolys = " << cellPolys_ << endl;
325 #endif
326 
327  // don't reset the size of internal faces, because more faces will be
328  // added in createPolyBoundary()
329 }
330 
331 
332 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::meshReader::baffleFaces_
faceList baffleFaces_
List of each baffle face.
Definition: meshReader.H:248
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::face::compare
static int compare(const face &a, const face &b)
Compare faces.
Definition: face.C:281
Foam::meshReader::origCellId_
labelList origCellId_
Lookup original Cell number for a given cell.
Definition: meshReader.H:219
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::FatalError
error FatalError
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
found
bool found
Definition: TABSMDCalcMethod2.H:32
Foam::meshReader::meshFaces_
faceList meshFaces_
Global face list for polyMesh.
Definition: meshReader.H:242
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::faceListList
List< faceList > faceListList
A List of faceList.
Definition: faceListFwd.H:49
Foam::faceList
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
Foam::HashSetOps::used
labelHashSet used(const bitSet &select)
Convert a bitset to a labelHashSet of the indices used.
Definition: HashOps.C:35
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
meshReader.H
Foam::meshReader::nInternalFaces_
label nInternalFaces_
Number of internal faces for polyMesh.
Definition: meshReader.H:239