1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 - use pointCells when searching for connectivity
28 - initialize the cell connectivity with '-1'
29 - find both cell faces corresponding to the baffles and mark them
30 to prevent a connection
31 - standard connectivity checks
33 - added baffle and monitoring support
35 \*---------------------------------------------------------------------------*/
37 #include "meshReader.H"
39 #include "polyPatch.H"
40 #include "emptyPolyPatch.H"
41 #include "preservePatchTypes.H"
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 void Foam::meshReader::addPolyBoundaryFace
48 const label cellFaceId,
49 const label nCreatedFaces
54 << " add bnd for cell " << cellId
55 << " face " << cellFaceId
56 << " (original cell " << origCellId_[cellId] << ")"
60 // standard case: volume cells
61 const face& thisFace = cellFaces_[cellId][cellFaceId];
64 if (cellPolys_[cellId][cellFaceId] > nInternalFaces_)
66 Info<< "meshReader::createPolyBoundary(): "
67 << "Problem with face: " << thisFace << endl
68 << "Probably multiple definitions "
69 << "of a single boundary face." << endl
72 else if (cellPolys_[cellId][cellFaceId] >= 0)
74 Info<< "meshReader::createPolyBoundary(): "
75 << "Problem with face: " << thisFace << endl
76 << "Probably trying to define a boundary face "
77 << "on a previously matched internal face." << endl
79 << meshFaces_[cellPolys_[cellId][cellFaceId]]
83 meshFaces_[nCreatedFaces] = thisFace;
84 cellPolys_[cellId][cellFaceId] = nCreatedFaces;
88 void Foam::meshReader::addPolyBoundaryFace
90 const cellFaceIdentifier& identifier,
91 const label nCreatedFaces
94 addPolyBoundaryFace(identifier.cell, identifier.face, nCreatedFaces);
98 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
100 void Foam::meshReader::createPolyBoundary()
102 label nBoundaryFaces = 0;
103 label nMissingFaces = 0;
104 label nInterfaces = 0;
106 const faceListList& cFaces = cellFaces();
108 // determine number of non-patched faces:
109 forAll(cellPolys_, cellI)
111 cell& curCell = cellPolys_[cellI];
122 forAll(boundaryIds_, patchI)
124 nBoundaryFaces += boundaryIds_[patchI].size();
128 << "There are " << nMissingFaces
129 << " faces to be patched and " << nBoundaryFaces
130 << " specified - collect missed boundaries to final patch" << endl;
132 patchStarts_.setSize(boundaryIds_.size());
133 patchSizes_.setSize(boundaryIds_.size());
135 label nCreatedFaces = nInternalFaces_;
136 label baffleOffset = cFaces.size();
137 interfaces_.setSize(baffleIds_.size());
140 forAll(boundaryIds_, patchI)
142 const List<cellFaceIdentifier>& idList = boundaryIds_[patchI];
144 patchStarts_[patchI] = nCreatedFaces;
146 // write each baffle side separately
147 if (patchPhysicalTypes_[patchI] == "baffle")
151 for (label side = 0; side < 2; ++side)
153 label position = nInterfaces;
157 label baffleI = idList[bndI].cell - baffleOffset;
162 && baffleI < baffleFaces_.size()
163 && baffleIds_[baffleI].size()
168 baffleIds_[baffleI][side],
172 // remove applied boundaries (2nd pass)
175 baffleIds_[baffleI].clear();
178 interfaces_[position][side] = nCreatedFaces;
188 nInterfaces += (count - (count % 2)) / 2;
190 else if (patchPhysicalTypes_[patchI] == "monitoring")
192 // translate the "monitoring" pseudo-boundaries to face sets
193 List<label> monitoring(idList.size());
198 label cellId = idList[bndI].cell;
199 label faceId = idList[bndI].face;
201 // standard case: volume cells
202 if (cellId < baffleOffset)
204 label faceNr = cellPolys_[cellId][faceId];
207 monitoring[monitorI++] = faceNr;
212 monitoringSets_.insert(patchNames_[patchI], monitoring);
218 // standard case: volume cells
219 if (idList[bndI].cell < baffleOffset)
233 patchSizes_[patchI] = nCreatedFaces - patchStarts_[patchI];
236 // add in missing faces
237 Info<< "Missing faces added to patch after face "
238 << nCreatedFaces << ":" <<endl;
241 // look for baffles first - keep them together at the start of the patch
242 for (label side = 0; side < 2; ++side)
244 label position = nInterfaces;
246 forAll(baffleIds_, baffleI)
248 if (baffleIds_[baffleI].size())
250 // add each side for each baffle
253 baffleIds_[baffleI][side],
257 interfaces_[position][side] = nCreatedFaces;
259 // remove applied boundaries (2nd pass)
262 baffleIds_[baffleI].clear();
272 nInterfaces += (nMissingFaces - (nMissingFaces % 2)) / 2;
274 // scan for any other missing faces
275 forAll(cellPolys_, cellI)
277 const labelList& curFaces = cellPolys_[cellI];
279 forAll(curFaces, cellFaceI)
281 if (curFaces[cellFaceI] < 0)
283 // just report the first few
284 if (nMissingFaces < 4)
286 const face& thisFace = cFaces[cellI][cellFaceI];
288 Info<< " cell " << cellI << " face " << cellFaceI
289 << " (original cell " << origCellId_[cellI] << ")"
290 << " face: " << thisFace
293 else if (nMissingFaces == 5)
295 Info<< " ..." << nl << endl;
298 addPolyBoundaryFace(cellI, cellFaceI, nCreatedFaces);
305 Info<< "Added " << nMissingFaces << " unmatched faces" << endl;
307 if (nMissingFaces > 0)
309 patchSizes_[patchSizes_.size() - 1] = nMissingFaces;
313 patchStarts_.setSize(patchStarts_.size() - 1);
316 // reset the size of the face list
317 meshFaces_.setSize(nCreatedFaces);
319 // check the mesh for face mismatch
320 // (faces addressed once or more than twice)
321 labelList markupFaces(meshFaces_.size(), 0);
323 forAll(cellPolys_, cellI)
325 const labelList& curFaces = cellPolys_[cellI];
327 forAll(curFaces, faceI)
329 markupFaces[curFaces[faceI]]++;
333 for (label i = nInternalFaces_; i < markupFaces.size(); i++)
338 label nProblemFaces = 0;
340 forAll(markupFaces, faceI)
342 if (markupFaces[faceI] != 2)
344 const face& problemFace = meshFaces_[faceI];
346 Info<< "meshReader::createPolyBoundary() : "
347 << "problem with face " << faceI << ": addressed "
348 << markupFaces[faceI] << " times (should be 2!). Face: "
349 << problemFace << endl;
355 if (nProblemFaces > 0)
357 Info<< "Number of incorrectly matched faces: "
358 << nProblemFaces << endl;
361 // adjust for missing members
362 if (nInterfaces < interfaces_.size())
364 interfaces_.setSize(nInterfaces);
367 Info<< "Number of boundary faces: " << nBoundaryFaces << nl
368 << "Total number of faces: " << nCreatedFaces << nl
369 << "Number of interfaces: " << nInterfaces << endl;
373 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
375 Foam::List<Foam::polyPatch*>
376 Foam::meshReader::polyBoundaryPatches(const polyMesh& mesh)
378 label nUsed = 0, nEmpty = 0;
379 label nPatches = patchStarts_.size();
381 // avoid empty patches - move to the end of the lists and truncate
382 labelList oldToNew = identity(nPatches);
383 forAll(patchSizes_, patchI)
385 if (patchSizes_[patchI] > 0)
387 oldToNew[patchI] = nUsed++;
392 oldToNew[patchI] = nPatches - nEmpty;
400 Info<< "Removing " << nEmpty << " empty patches" << endl;
402 inplaceReorder(oldToNew, patchTypes_);
403 inplaceReorder(oldToNew, patchNames_);
404 inplaceReorder(oldToNew, patchStarts_);
405 inplaceReorder(oldToNew, patchSizes_);
408 patchTypes_.setSize(nPatches);
409 patchNames_.setSize(nPatches);
410 patchStarts_.setSize(nPatches);
411 patchSizes_.setSize(nPatches);
414 List<polyPatch*> p(nPatches);
416 // Default boundary patch types
417 word defaultFacesType(emptyPolyPatch::typeName);
419 // we could consider dropping this entirely
432 forAll(patchStarts_, patchI)
434 p[patchI] = polyPatch::New
439 patchStarts_[patchI],
449 // ************************************************************************* //