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-------------------------------------------------------------------------------
11License
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
27Description
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
43void 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
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// ************************************************************************* //
bool found
void setSize(const label n)
Alias for resize()
Definition: List.H:218
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
static int compare(const face &a, const face &b)
Compare faces.
Definition: face.C:281
faceList meshFaces_
Global face list for polyMesh.
Definition: meshReader.H:242
label nInternalFaces_
Number of internal faces for polyMesh.
Definition: meshReader.H:239
labelList origCellId_
Lookup original Cell number for a given cell.
Definition: meshReader.H:219
faceList baffleFaces_
List of each baffle face.
Definition: meshReader.H:248
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
labelHashSet used(const bitSet &select)
Convert a bitset to a labelHashSet of the indices used.
Definition: HashOps.C:35
List< label > labelList
A List of labels.
Definition: List.H:66
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
List< faceList > faceListList
A List of faceList.
Definition: faceListFwd.H:49
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333