createPolyBoundary.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 | Copyright (C) 2011-2012 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM 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 OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  boundary faces
26  - use pointCells when searching for connectivity
27  - initialize the cell connectivity with '-1'
28  - find both cell faces corresponding to the baffles and mark them
29  to prevent a connection
30  - standard connectivity checks
31 
32  - added baffle and monitoring support
33 
34 \*---------------------------------------------------------------------------*/
35 
36 #include "meshReader.H"
37 #include "Time.H"
38 #include "polyPatch.H"
39 #include "emptyPolyPatch.H"
40 #include "preservePatchTypes.H"
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
45 (
46  const label cellId,
47  const label cellFaceId,
48  const label nCreatedFaces
49 )
50 {
51 #ifdef DEBUG_BOUNDARY
52  Info<< nCreatedFaces
53  << " add bnd for cell " << cellId
54  << " face " << cellFaceId
55  << " (original cell " << origCellId_[cellId] << ")"
56  << endl;
57 #endif
58 
59  // standard case: volume cells
60  const face& thisFace = cellFaces_[cellId][cellFaceId];
61 
62  // Debugging
63  if (cellPolys_[cellId][cellFaceId] > nInternalFaces_)
64  {
65  Info<< "meshReader::createPolyBoundary(): "
66  << "Problem with face: " << thisFace << endl
67  << "Probably multiple definitions "
68  << "of a single boundary face." << endl
69  << endl;
70  }
71  else if (cellPolys_[cellId][cellFaceId] >= 0)
72  {
73  Info<< "meshReader::createPolyBoundary(): "
74  << "Problem with face: " << thisFace << endl
75  << "Probably trying to define a boundary face "
76  << "on a previously matched internal face." << endl
77  << "Internal face: "
78  << meshFaces_[cellPolys_[cellId][cellFaceId]]
79  << endl;
80  }
81 
82  meshFaces_[nCreatedFaces] = thisFace;
83  cellPolys_[cellId][cellFaceId] = nCreatedFaces;
84 }
85 
86 
88 (
89  const cellFaceIdentifier& identifier,
90  const label nCreatedFaces
91 )
92 {
93  addPolyBoundaryFace(identifier.cell, identifier.face, nCreatedFaces);
94 }
95 
96 
97 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
98 
100 {
101  label nBoundaryFaces = 0;
102  label nMissingFaces = 0;
103  label nInterfaces = 0;
104 
105  const faceListList& cFaces = cellFaces();
106 
107  // determine number of non-patched faces:
108  forAll(cellPolys_, cellI)
109  {
110  cell& curCell = cellPolys_[cellI];
111 
112  forAll(curCell, fI)
113  {
114  if (curCell[fI] < 0)
115  {
116  nMissingFaces++;
117  }
118  }
119  }
120 
121  forAll(boundaryIds_, patchI)
122  {
123  nBoundaryFaces += boundaryIds_[patchI].size();
124  }
125 
126  Info<< nl
127  << "There are " << nMissingFaces
128  << " faces to be patched and " << nBoundaryFaces
129  << " specified - collect missed boundaries to final patch" << endl;
130 
133 
134  label nCreatedFaces = nInternalFaces_;
135  label baffleOffset = cFaces.size();
136  interfaces_.setSize(baffleIds_.size());
137  nBoundaryFaces = 0;
138 
139  forAll(boundaryIds_, patchI)
140  {
141  const List<cellFaceIdentifier>& idList = boundaryIds_[patchI];
142 
143  patchStarts_[patchI] = nCreatedFaces;
144 
145  // write each baffle side separately
146  if (patchPhysicalTypes_[patchI] == "baffle")
147  {
148  label count = 0;
149 
150  for (label side = 0; side < 2; ++side)
151  {
152  label position = nInterfaces;
153 
154  forAll(idList, bndI)
155  {
156  label baffleI = idList[bndI].cell - baffleOffset;
157 
158  if
159  (
160  baffleI >= 0
161  && baffleI < baffleFaces_.size()
162  && baffleIds_[baffleI].size()
163  )
164  {
166  (
167  baffleIds_[baffleI][side],
168  nCreatedFaces
169  );
170 
171  // remove applied boundaries (2nd pass)
172  if (side == 1)
173  {
174  baffleIds_[baffleI].clear();
175  }
176 
177  interfaces_[position][side] = nCreatedFaces;
178 
179  nBoundaryFaces++;
180  nCreatedFaces++;
181  position++;
182  count++;
183  }
184  }
185  }
186 
187  nInterfaces += (count - (count % 2)) / 2;
188  }
189  else if (patchPhysicalTypes_[patchI] == "monitoring")
190  {
191  // translate the "monitoring" pseudo-boundaries to face sets
192  List<label> monitoring(idList.size());
193 
194  label monitorI = 0;
195  forAll(idList, bndI)
196  {
197  label cellId = idList[bndI].cell;
198  label faceId = idList[bndI].face;
199 
200  // standard case: volume cells
201  if (cellId < baffleOffset)
202  {
203  label faceNr = cellPolys_[cellId][faceId];
204  if (faceNr >= 0)
205  {
206  monitoring[monitorI++] = faceNr;
207  }
208  }
209  }
210 
211  monitoringSets_.insert(patchNames_[patchI], monitoring);
212  }
213  else
214  {
215  forAll(idList, bndI)
216  {
217  // standard case: volume cells
218  if (idList[bndI].cell < baffleOffset)
219  {
221  (
222  idList[bndI],
223  nCreatedFaces
224  );
225 
226  nBoundaryFaces++;
227  nCreatedFaces++;
228  }
229  }
230  }
231 
232  patchSizes_[patchI] = nCreatedFaces - patchStarts_[patchI];
233  }
234 
235  // add in missing faces
236  Info<< "Missing faces added to patch after face "
237  << nCreatedFaces << ":" <<endl;
238  nMissingFaces = 0;
239 
240  // look for baffles first - keep them together at the start of the patch
241  for (label side = 0; side < 2; ++side)
242  {
243  label position = nInterfaces;
244 
245  forAll(baffleIds_, baffleI)
246  {
247  if (baffleIds_[baffleI].size())
248  {
249  // add each side for each baffle
251  (
252  baffleIds_[baffleI][side],
253  nCreatedFaces
254  );
255 
256  interfaces_[position][side] = nCreatedFaces;
257 
258  // remove applied boundaries (2nd pass)
259  if (side == 1)
260  {
261  baffleIds_[baffleI].clear();
262  }
263 
264  nMissingFaces++;
265  nCreatedFaces++;
266  position++;
267  }
268  }
269  }
270 
271  nInterfaces += (nMissingFaces - (nMissingFaces % 2)) / 2;
272 
273  // scan for any other missing faces
274  forAll(cellPolys_, cellI)
275  {
276  const labelList& curFaces = cellPolys_[cellI];
277 
278  forAll(curFaces, cellFaceI)
279  {
280  if (curFaces[cellFaceI] < 0)
281  {
282  // just report the first few
283  if (nMissingFaces < 4)
284  {
285  const face& thisFace = cFaces[cellI][cellFaceI];
286 
287  Info<< " cell " << cellI << " face " << cellFaceI
288  << " (original cell " << origCellId_[cellI] << ")"
289  << " face: " << thisFace
290  << endl;
291  }
292  else if (nMissingFaces == 5)
293  {
294  Info<< " ..." << nl << endl;
295  }
296 
297  addPolyBoundaryFace(cellI, cellFaceI, nCreatedFaces);
298  nMissingFaces++;
299  nCreatedFaces++;
300  }
301  }
302  }
303 
304  Info<< "Added " << nMissingFaces << " unmatched faces" << endl;
305 
306  // Add missing faces to last patch ('Default_Empty' etc.)
307  if (nMissingFaces > 0)
308  {
309  patchSizes_.last() = nMissingFaces;
310  }
311 
312 
313  // reset the size of the face list
314  meshFaces_.setSize(nCreatedFaces);
315 
316  // check the mesh for face mismatch
317  // (faces addressed once or more than twice)
318  labelList markupFaces(meshFaces_.size(), 0);
319 
320  forAll(cellPolys_, cellI)
321  {
322  const labelList& curFaces = cellPolys_[cellI];
323 
324  forAll(curFaces, faceI)
325  {
326  markupFaces[curFaces[faceI]]++;
327  }
328  }
329 
330  for (label i = nInternalFaces_; i < markupFaces.size(); i++)
331  {
332  markupFaces[i]++;
333  }
334 
335  label nProblemFaces = 0;
336 
337  forAll(markupFaces, faceI)
338  {
339  if (markupFaces[faceI] != 2)
340  {
341  const face& problemFace = meshFaces_[faceI];
342 
343  Info<< "meshReader::createPolyBoundary() : "
344  << "problem with face " << faceI << ": addressed "
345  << markupFaces[faceI] << " times (should be 2!). Face: "
346  << problemFace << endl;
347 
348  nProblemFaces++;
349  }
350  }
351 
352  if (nProblemFaces > 0)
353  {
354  Info<< "Number of incorrectly matched faces: "
355  << nProblemFaces << endl;
356  }
357 
358  // adjust for missing members
359  if (nInterfaces < interfaces_.size())
360  {
361  interfaces_.setSize(nInterfaces);
362  }
363 
364  Info<< "Number of boundary faces: " << nBoundaryFaces << nl
365  << "Total number of faces: " << nCreatedFaces << nl
366  << "Number of interfaces: " << nInterfaces << endl;
367 }
368 
369 
370 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
371 
374 {
375  label nUsed = 0, nEmpty = 0;
376  label nPatches = patchStarts_.size();
377 
378  // avoid empty patches - move to the end of the lists and truncate
379  // Size loop according to patchStarts_ can be smaller than patchSizes_
380  labelList oldToNew = identity(nPatches);
381  forAll(patchStarts_, patchI)
382  {
383  if (patchSizes_[patchI] > 0)
384  {
385  oldToNew[patchI] = nUsed++;
386  }
387  else
388  {
389  nEmpty++;
390  oldToNew[patchI] = nPatches - nEmpty;
391  }
392  }
393 
394  nPatches = nUsed;
395 
396  if (nEmpty)
397  {
398  Info<< "Removing " << nEmpty << " empty patches" << endl;
399 
400  inplaceReorder(oldToNew, patchTypes_);
401  inplaceReorder(oldToNew, patchNames_);
402  inplaceReorder(oldToNew, patchStarts_);
403  inplaceReorder(oldToNew, patchSizes_);
404  }
405 
406  patchTypes_.setSize(nPatches);
407  patchNames_.setSize(nPatches);
408  patchStarts_.setSize(nPatches);
409  patchSizes_.setSize(nPatches);
410 
411 
413 
414  // All patch dictionaries
415  PtrList<dictionary> patchDicts(patchNames_.size());
416  // Default boundary patch types
417  word defaultFacesType(emptyPolyPatch::typeName);
418 
419  // we could consider dropping this entirely
421  (
422  mesh,
423  mesh.instance(),
424  mesh.meshDir(),
425  patchNames_,
426  patchDicts,
427  "defaultFaces",
429  );
430  forAll(patchDicts, patchI)
431  {
432  if (!patchDicts.set(patchI))
433  {
434  patchDicts.set(patchI, new dictionary());
435  }
436  dictionary& patchDict = patchDicts[patchI];
437 
438  // add but not overwrite type
439  patchDict.add("type", patchTypes_[patchI], false);
440  if (patchPhysicalTypes_.size() && patchPhysicalTypes_[patchI].size())
441  {
442  patchDict.add("startFace", patchPhysicalTypes_[patchI], false);
443  }
444 
445  // overwrite sizes and start
446  patchDict.add("nFaces", patchSizes_[patchI], true);
447  patchDict.add("startFace", patchStarts_[patchI], true);
448  }
449 
450 
451  forAll(patchStarts_, patchI)
452  {
453  p[patchI] = polyPatch::New
454  (
455  patchNames_[patchI],
456  patchDicts[patchI],
457  patchI,
459  ).ptr();
460  }
461 
462  return p;
463 }
464 
465 
466 // ************************************************************************* //
Foam::meshReader::cellFaceIdentifier::face
label face
Face Id.
Definition: meshReader.H:87
Foam::meshReader::addPolyBoundaryFace
void addPolyBoundaryFace(const label cellId, const label cellFaceId, const label nCreatedFaces)
Add in boundary face.
Definition: createPolyBoundary.C:45
p
p
Definition: pEqn.H:62
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
Foam::meshReader::cellPolys_
cellList cellPolys_
Cells as polyhedra for polyMesh.
Definition: meshReader.H:166
Foam::meshReader::monitoringSets_
HashTable< List< label >, word, string::hash > monitoringSets_
Face sets for monitoring.
Definition: meshReader.H:169
nPatches
label nPatches
Definition: readKivaGrid.H:402
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
polyPatch.H
Foam::meshReader::createPolyBoundary
void createPolyBoundary()
Make polyhedral boundary from shape boundary.
Definition: createPolyBoundary.C:99
Foam::meshReader::patchNames_
wordList patchNames_
Boundary patch names.
Definition: meshReader.H:269
Foam::preservePatchTypes
void preservePatchTypes(const objectRegistry &obr, const word &meshInstance, const fileName &meshDir, const wordList &patchNames, PtrList< dictionary > &patchDicts, const word &defaultFacesName, word &defaultFacesType)
Preserve patch types.
Definition: preservePatchTypes.C:32
Foam::meshReader::patchStarts_
labelList patchStarts_
Polyhedral mesh boundary patch start indices and dimensions.
Definition: meshReader.H:153
preservePatchTypes.H
preservePatchTypes
Foam::meshReader::cellFaceIdentifier
Identify cell faces in terms of cell Id and face Id.
Definition: meshReader.H:78
Foam::meshReader::patchPhysicalTypes_
wordList patchPhysicalTypes_
Boundary patch physical types.
Definition: meshReader.H:272
Foam::meshReader::patchSizes_
labelList patchSizes_
Definition: meshReader.H:154
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::meshReader::baffleIds_
List< List< cellFaceIdentifier > > baffleIds_
List of cells/faces id pairs for each baffle.
Definition: meshReader.H:160
Foam::meshReader::boundaryIds_
List< List< cellFaceIdentifier > > boundaryIds_
Identify boundary faces by cells and their faces.
Definition: meshReader.H:263
Foam::IOobject::instance
const fileName & instance() const
Definition: IOobject.H:350
defaultFacesType
word defaultFacesType
Definition: readKivaGrid.H:461
Foam::meshReader::baffleFaces_
faceList baffleFaces_
List of each baffle face.
Definition: meshReader.H:278
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
patchDicts
PtrList< dictionary > patchDicts
Definition: readKivaGrid.H:537
Foam::meshReader::origCellId_
labelList origCellId_
Lookup original Cell number for a given cell.
Definition: meshReader.H:259
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:102
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::meshReader::interfaces_
List< labelPair > interfaces_
Association between two faces.
Definition: meshReader.H:157
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
faceId
label faceId(-1)
Foam::PtrList
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:61
Foam::identity
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
Foam::polyPatch::New
static autoPtr< polyPatch > New(const word &patchType, const word &name, const label size, const label start, const label index, const polyBoundaryMesh &bm)
Return a pointer to a new patch created on freestore from.
Definition: polyPatchNew.C:32
Foam::meshReader::cellFaceIdentifier::cell
label cell
Cell Id.
Definition: meshReader.H:84
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
emptyPolyPatch.H
Foam::polyMesh::meshDir
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:766
cellId
label cellId
Definition: interrogateWallPatches.H:67
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::meshReader::meshFaces_
faceList meshFaces_
Global face list for polyMesh.
Definition: meshReader.H:163
Foam::List< faceList >
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
meshReader.H
Foam::meshReader::cellFaces
faceListList & cellFaces() const
Return list of faces for every cell.
Definition: meshReader.H:232
Foam::cell
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
Foam::meshReader::nInternalFaces_
label nInternalFaces_
Number of internal faces for polyMesh.
Definition: meshReader.H:150
Foam::dictionary::add
bool add(entry *, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:729
Foam::meshReader::polyBoundaryPatches
List< polyPatch * > polyBoundaryPatches(const polyMesh &)
Add polyhedral boundary.
Definition: createPolyBoundary.C:373