FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

createPolyBoundary.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Description
00025     boundary faces
00026     - use pointCells when searching for connectivity
00027     - initialize the cell connectivity with '-1'
00028     - find both cell faces corresponding to the baffles and mark them
00029       to prevent a connection
00030     - standard connectivity checks
00031 
00032     - added baffle and monitoring support
00033 
00034 \*---------------------------------------------------------------------------*/
00035 
00036 #include "meshReader.H"
00037 #include <OpenFOAM/Time.H>
00038 #include <OpenFOAM/polyPatch.H>
00039 #include <OpenFOAM/emptyPolyPatch.H>
00040 #include <OpenFOAM/preservePatchTypes.H>
00041 
00042 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00043 
00044 void Foam::meshReader::addPolyBoundaryFace
00045 (
00046     const label cellId,
00047     const label cellFaceId,
00048     const label nCreatedFaces
00049 )
00050 {
00051 #ifdef DEBUG_BOUNDARY
00052     Info<< nCreatedFaces
00053         << " add bnd for cell " << cellId
00054         << " face " << cellFaceId
00055         << " (original cell " << origCellId_[cellId] << ")"
00056         << endl;
00057 #endif
00058 
00059     // standard case: volume cells
00060     const face& thisFace = cellFaces_[cellId][cellFaceId];
00061 
00062     // Debugging
00063     if (cellPolys_[cellId][cellFaceId] > nInternalFaces_)
00064     {
00065         Info<< "meshReader::createPolyBoundary(): "
00066             << "Problem with face: " << thisFace << endl
00067             << "Probably multiple definitions "
00068             << "of a single boundary face." << endl
00069             << endl;
00070     }
00071     else if (cellPolys_[cellId][cellFaceId] >= 0)
00072     {
00073         Info<< "meshReader::createPolyBoundary(): "
00074             << "Problem with face: " << thisFace << endl
00075             << "Probably trying to define a boundary face "
00076             << "on a previously matched internal face." << endl
00077             << "Internal face: "
00078             << meshFaces_[cellPolys_[cellId][cellFaceId]]
00079             << endl;
00080     }
00081 
00082     meshFaces_[nCreatedFaces] = thisFace;
00083     cellPolys_[cellId][cellFaceId] = nCreatedFaces;
00084 }
00085 
00086 
00087 void Foam::meshReader::addPolyBoundaryFace
00088 (
00089     const cellFaceIdentifier& identifier,
00090     const label nCreatedFaces
00091 )
00092 {
00093     addPolyBoundaryFace(identifier.cell, identifier.face, nCreatedFaces);
00094 }
00095 
00096 
00097 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00098 
00099 void Foam::meshReader::createPolyBoundary()
00100 {
00101     label nBoundaryFaces = 0;
00102     label nMissingFaces = 0;
00103     label nInterfaces = 0;
00104 
00105     const faceListList& cFaces = cellFaces();
00106 
00107     // determine number of non-patched faces:
00108     forAll(cellPolys_, cellI)
00109     {
00110         cell& curCell = cellPolys_[cellI];
00111 
00112         forAll(curCell, fI)
00113         {
00114             if (curCell[fI] < 0)
00115             {
00116                 nMissingFaces++;
00117             }
00118         }
00119     }
00120 
00121     forAll(boundaryIds_, patchI)
00122     {
00123         nBoundaryFaces += boundaryIds_[patchI].size();
00124     }
00125 
00126     Info<< nl
00127         << "There are " << nMissingFaces
00128         << " faces to be patched and " << nBoundaryFaces
00129         << " specified - collect missed boundaries to final patch" << endl;
00130 
00131     patchStarts_.setSize(boundaryIds_.size());
00132     patchSizes_.setSize(boundaryIds_.size());
00133 
00134     label nCreatedFaces = nInternalFaces_;
00135     label baffleOffset  = cFaces.size();
00136     interfaces_.setSize(baffleIds_.size());
00137     nBoundaryFaces = 0;
00138 
00139     forAll(boundaryIds_, patchI)
00140     {
00141         const List<cellFaceIdentifier>& idList = boundaryIds_[patchI];
00142 
00143         patchStarts_[patchI] = nCreatedFaces;
00144 
00145         // write each baffle side separately
00146         if (patchPhysicalTypes_[patchI] == "baffle")
00147         {
00148             label count = 0;
00149 
00150             for (label side = 0; side < 2; ++side)
00151             {
00152                 label position = nInterfaces;
00153 
00154                 forAll(idList, bndI)
00155                 {
00156                     label baffleI = idList[bndI].cell - baffleOffset;
00157 
00158                     if
00159                     (
00160                         baffleI >= 0
00161                      && baffleI < baffleFaces_.size()
00162                      && baffleIds_[baffleI].size()
00163                     )
00164                     {
00165                         addPolyBoundaryFace
00166                         (
00167                             baffleIds_[baffleI][side],
00168                             nCreatedFaces
00169                         );
00170 
00171                         // remove applied boundaries (2nd pass)
00172                         if (side == 1)
00173                         {
00174                             baffleIds_[baffleI].clear();
00175                         }
00176 
00177                         interfaces_[position][side] = nCreatedFaces;
00178 
00179                         nBoundaryFaces++;
00180                         nCreatedFaces++;
00181                         position++;
00182                         count++;
00183                     }
00184                 }
00185             }
00186 
00187             nInterfaces += (count - (count % 2)) / 2;
00188         }
00189         else if (patchPhysicalTypes_[patchI] == "monitoring")
00190         {
00191             // translate the "monitoring" pseudo-boundaries to face sets
00192             List<label> monitoring(idList.size());
00193 
00194             label monitorI = 0;
00195             forAll(idList, bndI)
00196             {
00197                 label cellId = idList[bndI].cell;
00198                 label faceId = idList[bndI].face;
00199 
00200                 // standard case: volume cells
00201                 if (cellId < baffleOffset)
00202                 {
00203                     label faceNr = cellPolys_[cellId][faceId];
00204                     if (faceNr >= 0)
00205                     {
00206                         monitoring[monitorI++] = faceNr;
00207                     }
00208                 }
00209             }
00210 
00211             monitoringSets_.insert(patchNames_[patchI], monitoring);
00212         }
00213         else
00214         {
00215             forAll(idList, bndI)
00216             {
00217                 // standard case: volume cells
00218                 if (idList[bndI].cell < baffleOffset)
00219                 {
00220                     addPolyBoundaryFace
00221                     (
00222                         idList[bndI],
00223                         nCreatedFaces
00224                     );
00225 
00226                     nBoundaryFaces++;
00227                     nCreatedFaces++;
00228                 }
00229             }
00230         }
00231 
00232         patchSizes_[patchI] = nCreatedFaces - patchStarts_[patchI];
00233     }
00234 
00235     // add in missing faces
00236     Info<< "Missing faces added to patch after face "
00237         << nCreatedFaces << ":" <<endl;
00238     nMissingFaces = 0;
00239 
00240     // look for baffles first - keep them together at the start of the patch
00241     for (label side = 0; side < 2; ++side)
00242     {
00243         label position = nInterfaces;
00244 
00245         forAll(baffleIds_, baffleI)
00246         {
00247             if (baffleIds_[baffleI].size())
00248             {
00249                 // add each side for each baffle
00250                 addPolyBoundaryFace
00251                 (
00252                     baffleIds_[baffleI][side],
00253                     nCreatedFaces
00254                 );
00255 
00256                 interfaces_[position][side] = nCreatedFaces;
00257 
00258                 // remove applied boundaries (2nd pass)
00259                 if (side == 1)
00260                 {
00261                     baffleIds_[baffleI].clear();
00262                 }
00263 
00264                 nMissingFaces++;
00265                 nCreatedFaces++;
00266                 position++;
00267             }
00268         }
00269     }
00270 
00271     nInterfaces += (nMissingFaces - (nMissingFaces % 2)) / 2;
00272 
00273     // scan for any other missing faces
00274     forAll(cellPolys_, cellI)
00275     {
00276         const labelList& curFaces = cellPolys_[cellI];
00277 
00278         forAll(curFaces, cellFaceI)
00279         {
00280             if (curFaces[cellFaceI] < 0)
00281             {
00282                 // just report the first few
00283                 if (nMissingFaces < 4)
00284                 {
00285                     const face& thisFace = cFaces[cellI][cellFaceI];
00286 
00287                     Info<< "  cell " << cellI << " face " << cellFaceI
00288                         << " (original cell " << origCellId_[cellI] << ")"
00289                         << " face: " << thisFace
00290                         << endl;
00291                 }
00292                 else if (nMissingFaces == 5)
00293                 {
00294                     Info<< "  ..." << nl << endl;
00295                 }
00296 
00297                 addPolyBoundaryFace(cellI, cellFaceI, nCreatedFaces);
00298                 nMissingFaces++;
00299                 nCreatedFaces++;
00300             }
00301         }
00302     }
00303 
00304     Info<< "Added " << nMissingFaces << " unmatched faces" << endl;
00305 
00306     if (nMissingFaces > 0)
00307     {
00308         patchSizes_[patchSizes_.size() - 1] = nMissingFaces;
00309     }
00310     else
00311     {
00312         patchStarts_.setSize(patchStarts_.size() - 1);
00313     }
00314 
00315     // reset the size of the face list
00316     meshFaces_.setSize(nCreatedFaces);
00317 
00318     // check the mesh for face mismatch
00319     // (faces addressed once or more than twice)
00320     labelList markupFaces(meshFaces_.size(), 0);
00321 
00322     forAll(cellPolys_, cellI)
00323     {
00324         const labelList& curFaces = cellPolys_[cellI];
00325 
00326         forAll(curFaces, faceI)
00327         {
00328             markupFaces[curFaces[faceI]]++;
00329         }
00330     }
00331 
00332     for (label i = nInternalFaces_; i < markupFaces.size(); i++)
00333     {
00334         markupFaces[i]++;
00335     }
00336 
00337     label nProblemFaces = 0;
00338 
00339     forAll(markupFaces, faceI)
00340     {
00341         if (markupFaces[faceI] != 2)
00342         {
00343             const face& problemFace = meshFaces_[faceI];
00344 
00345             Info<< "meshReader::createPolyBoundary() : "
00346                 << "problem with face " << faceI << ": addressed "
00347                 << markupFaces[faceI] << " times (should be 2!). Face: "
00348                 << problemFace << endl;
00349 
00350             nProblemFaces++;
00351         }
00352     }
00353 
00354     if (nProblemFaces > 0)
00355     {
00356         Info<< "Number of incorrectly matched faces: "
00357             << nProblemFaces << endl;
00358     }
00359 
00360     // adjust for missing members
00361     if (nInterfaces < interfaces_.size())
00362     {
00363         interfaces_.setSize(nInterfaces);
00364     }
00365 
00366     Info<< "Number of boundary faces: " << nBoundaryFaces << nl
00367         << "Total number of faces: " << nCreatedFaces << nl
00368         << "Number of interfaces: " << nInterfaces << endl;
00369 }
00370 
00371 
00372 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00373 
00374 Foam::List<Foam::polyPatch*>
00375 Foam::meshReader::polyBoundaryPatches(const polyMesh& mesh)
00376 {
00377     label nUsed = 0, nEmpty = 0;
00378     label nPatches = patchStarts_.size();
00379 
00380     // avoid empty patches - move to the end of the lists and truncate
00381     labelList oldToNew = identity(nPatches);
00382     forAll(patchSizes_, patchI)
00383     {
00384         if (patchSizes_[patchI] > 0)
00385         {
00386             oldToNew[patchI] = nUsed++;
00387         }
00388         else
00389         {
00390             nEmpty++;
00391             oldToNew[patchI] = nPatches - nEmpty;
00392         }
00393     }
00394 
00395     nPatches = nUsed;
00396 
00397     if (nEmpty)
00398     {
00399         Info<< "Removing " << nEmpty << " empty patches" << endl;
00400 
00401         inplaceReorder(oldToNew, patchTypes_);
00402         inplaceReorder(oldToNew, patchNames_);
00403         inplaceReorder(oldToNew, patchStarts_);
00404         inplaceReorder(oldToNew, patchSizes_);
00405     }
00406 
00407     patchTypes_.setSize(nPatches);
00408     patchNames_.setSize(nPatches);
00409     patchStarts_.setSize(nPatches);
00410     patchSizes_.setSize(nPatches);
00411 
00412 
00413     List<polyPatch*> p(nPatches);
00414 
00415     // Default boundary patch types
00416     word defaultFacesType(emptyPolyPatch::typeName);
00417 
00418     // we could consider dropping this entirely
00419     preservePatchTypes
00420     (
00421         mesh,
00422         mesh.instance(),
00423         mesh.meshDir(),
00424         patchNames_,
00425         patchTypes_,
00426         "defaultFaces",
00427         defaultFacesType,
00428         patchPhysicalTypes_
00429     );
00430 
00431     forAll(patchStarts_, patchI)
00432     {
00433         p[patchI] = polyPatch::New
00434         (
00435             patchTypes_[patchI],
00436             patchNames_[patchI],
00437             patchSizes_[patchI],
00438             patchStarts_[patchI],
00439             patchI,
00440             mesh.boundaryMesh()
00441         ).ptr();
00442     }
00443 
00444     return p;
00445 }
00446 
00447 
00448 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines