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

createTopology.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 \*---------------------------------------------------------------------------*/
00025 
00026 #include "blockMesh.H"
00027 #include <OpenFOAM/Time.H>
00028 #include <OpenFOAM/preservePatchTypes.H>
00029 #include <OpenFOAM/emptyPolyPatch.H>
00030 
00031 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00032 
00033 bool Foam::blockMesh::blockLabelsOK
00034 (
00035     const label blockLabel,
00036     const pointField& points,
00037     const cellShape& blockShape
00038 )
00039 {
00040     bool ok = true;
00041 
00042     forAll(blockShape, blockI)
00043     {
00044         if (blockShape[blockI] < 0)
00045         {
00046             ok = false;
00047 
00048             WarningIn
00049             (
00050                 "bool Foam::blockMesh::blockLabelsOK"
00051                 "(const label blockLabel, const pointField& points, "
00052                 "const cellShape& blockShape)"
00053             )   << "block " << blockLabel
00054                 << " point label " << blockShape[blockI]
00055                 << " less than zero" << endl;
00056         }
00057         else if (blockShape[blockI] >= points.size())
00058         {
00059             ok = false;
00060 
00061             WarningIn
00062             (
00063                 "bool Foam::blockMesh::blockLabelsOK"
00064                 "(const label blockLabel, const pointField& points, "
00065                 "const cellShape& blockShape)"
00066             )   << "block " << blockLabel
00067                 << " point label " << blockShape[blockI]
00068                 << " larger than " << points.size() - 1
00069                 << " the largest defined point label" << endl;
00070         }
00071     }
00072 
00073     return ok;
00074 }
00075 
00076 
00077 bool Foam::blockMesh::patchLabelsOK
00078 (
00079     const label patchLabel,
00080     const pointField& points,
00081     const faceList& patchFaces
00082 )
00083 {
00084     bool ok = true;
00085 
00086     forAll(patchFaces, faceI)
00087     {
00088         const labelList& f = patchFaces[faceI];
00089 
00090         forAll(f, fp)
00091         {
00092             if (f[fp] < 0)
00093             {
00094                 ok = false;
00095 
00096                 WarningIn
00097                 (
00098                     "bool Foam::blockMesh::patchLabelsOK(...)"
00099                 )   << "patch " << patchLabel
00100                     << " face " << faceI
00101                     << " point label " << f[fp]
00102                     << " less than zero" << endl;
00103             }
00104             else if (f[fp] >= points.size())
00105             {
00106                 ok = false;
00107 
00108                 WarningIn
00109                 (
00110                     "bool Foam::blockMesh::patchLabelsOK(...)"
00111                 )   << "patch " << patchLabel
00112                     << " face " << faceI
00113                     << " point label " << f[fp]
00114                     << " larger than " << points.size() - 1
00115                     << " the largest defined point label" << endl;
00116             }
00117         }
00118     }
00119 
00120     return ok;
00121 }
00122 
00123 
00124 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00125 
00126 Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription)
00127 {
00128     bool topologyOK = true;
00129 
00130     blockMesh& blocks = *this;
00131 
00132     word defaultPatchName = "defaultFaces";
00133     word defaultPatchType = emptyPolyPatch::typeName;
00134 
00135     // get names/types for the unassigned patch faces
00136     // this is a bit heavy handed (and ugly), but there is currently
00137     // no easy way to rename polyMesh patches subsequently
00138     if (const dictionary* dictPtr = meshDescription.subDictPtr("defaultPatch"))
00139     {
00140         dictPtr->readIfPresent("name", defaultPatchName);
00141         dictPtr->readIfPresent("type", defaultPatchType);
00142     }
00143 
00144     Info<< nl << "Creating blockCorners" << endl;
00145 
00146     // create blockCorners
00147     pointField tmpBlockPoints(meshDescription.lookup("vertices"));
00148 
00149     if (meshDescription.found("edges"))
00150     {
00151         // read number of non-linear edges in mesh
00152         Info<< nl << "Creating curved edges" << endl;
00153 
00154         ITstream& edgesStream(meshDescription.lookup("edges"));
00155 
00156         label nEdges = 0;
00157 
00158         token firstToken(edgesStream);
00159 
00160         if (firstToken.isLabel())
00161         {
00162             nEdges = firstToken.labelToken();
00163             edges_.setSize(nEdges);
00164         }
00165         else
00166         {
00167             edgesStream.putBack(firstToken);
00168         }
00169 
00170         // Read beginning of edges
00171         edgesStream.readBegin("edges");
00172 
00173         nEdges = 0;
00174 
00175         token lastToken(edgesStream);
00176         while
00177         (
00178             !(
00179                 lastToken.isPunctuation()
00180                 && lastToken.pToken() == token::END_LIST
00181             )
00182         )
00183         {
00184             if (edges_.size() <= nEdges)
00185             {
00186                 edges_.setSize(nEdges + 1);
00187             }
00188 
00189             edgesStream.putBack(lastToken);
00190 
00191             edges_.set
00192             (
00193                 nEdges,
00194                 curvedEdge::New(tmpBlockPoints, edgesStream)
00195             );
00196 
00197             nEdges++;
00198 
00199             edgesStream >> lastToken;
00200         }
00201         edgesStream.putBack(lastToken);
00202 
00203         // Read end of edges
00204         edgesStream.readEnd("edges");
00205     }
00206     else
00207     {
00208         Info<< nl << "There are no non-linear edges" << endl;
00209     }
00210 
00211 
00212     Info<< nl << "Creating blocks" << endl;
00213     {
00214         ITstream& blockDescriptorStream(meshDescription.lookup("blocks"));
00215 
00216         // read number of blocks in mesh
00217         label nBlocks = 0;
00218 
00219         token firstToken(blockDescriptorStream);
00220 
00221         if (firstToken.isLabel())
00222         {
00223             nBlocks = firstToken.labelToken();
00224             blocks.setSize(nBlocks);
00225         }
00226         else
00227         {
00228             blockDescriptorStream.putBack(firstToken);
00229         }
00230 
00231         // Read beginning of blocks
00232         blockDescriptorStream.readBegin("blocks");
00233 
00234         nBlocks = 0;
00235 
00236         token lastToken(blockDescriptorStream);
00237         while
00238         (
00239             !(
00240                 lastToken.isPunctuation()
00241                 && lastToken.pToken() == token::END_LIST
00242             )
00243         )
00244         {
00245             if (blocks.size() <= nBlocks)
00246             {
00247                 blocks.setSize(nBlocks + 1);
00248             }
00249 
00250             blockDescriptorStream.putBack(lastToken);
00251 
00252             blocks.set
00253             (
00254                 nBlocks,
00255                 new block
00256                 (
00257                     blockDescriptor
00258                     (
00259                         tmpBlockPoints,
00260                         edges_,
00261                         blockDescriptorStream
00262                     )
00263                 )
00264             );
00265 
00266             topologyOK = topologyOK && blockLabelsOK
00267             (
00268                 nBlocks,
00269                 tmpBlockPoints,
00270                 blocks[nBlocks].blockDef().blockShape()
00271             );
00272 
00273             nBlocks++;
00274 
00275             blockDescriptorStream >> lastToken;
00276         }
00277         blockDescriptorStream.putBack(lastToken);
00278 
00279         // Read end of blocks
00280         blockDescriptorStream.readEnd("blocks");
00281     }
00282 
00283 
00284     Info<< nl << "Creating patches" << endl;
00285 
00286     faceListList tmpBlocksPatches;
00287     wordList patchNames;
00288     wordList patchTypes;
00289 
00290     {
00291         ITstream& patchStream(meshDescription.lookup("patches"));
00292 
00293         // read number of patches in mesh
00294         label nPatches = 0;
00295 
00296         token firstToken(patchStream);
00297 
00298         if (firstToken.isLabel())
00299         {
00300             nPatches = firstToken.labelToken();
00301 
00302             tmpBlocksPatches.setSize(nPatches);
00303             patchNames.setSize(nPatches);
00304             patchTypes.setSize(nPatches);
00305         }
00306         else
00307         {
00308             patchStream.putBack(firstToken);
00309         }
00310 
00311         // Read beginning of blocks
00312         patchStream.readBegin("patches");
00313 
00314         nPatches = 0;
00315 
00316         token lastToken(patchStream);
00317         while
00318         (
00319             !(
00320                 lastToken.isPunctuation()
00321                 && lastToken.pToken() == token::END_LIST
00322             )
00323         )
00324         {
00325             if (tmpBlocksPatches.size() <= nPatches)
00326             {
00327                 tmpBlocksPatches.setSize(nPatches + 1);
00328                 patchNames.setSize(nPatches + 1);
00329                 patchTypes.setSize(nPatches + 1);
00330             }
00331 
00332             patchStream.putBack(lastToken);
00333 
00334             patchStream
00335                 >> patchTypes[nPatches]
00336                 >> patchNames[nPatches]
00337                 >> tmpBlocksPatches[nPatches];
00338 
00339 
00340             // Catch multiple patches asap.
00341             for (label i = 0; i < nPatches; i++)
00342             {
00343                 if (patchNames[nPatches] == patchNames[i])
00344                 {
00345                     FatalErrorIn
00346                     (
00347                         "blockMesh::createTopology(IOdictionary&)"
00348                     )   << "Duplicate patch " << patchNames[nPatches]
00349                         << " at line " << patchStream.lineNumber()
00350                         << ". Exiting !" << nl
00351                         << exit(FatalError);
00352                 }
00353             }
00354 
00355             topologyOK = topologyOK && patchLabelsOK
00356             (
00357                 nPatches,
00358                 tmpBlockPoints,
00359                 tmpBlocksPatches[nPatches]
00360             );
00361 
00362             nPatches++;
00363 
00364             patchStream >> lastToken;
00365         }
00366         patchStream.putBack(lastToken);
00367 
00368         // Read end of blocks
00369         patchStream.readEnd("patches");
00370     }
00371 
00372 
00373     if (!topologyOK)
00374     {
00375         FatalErrorIn("blockMesh::createTopology(IOdictionary&)")
00376             << "Cannot create mesh due to errors in topology, exiting !" << nl
00377             << exit(FatalError);
00378     }
00379 
00380 
00381     Info<< nl << "Creating block mesh topology" << endl;
00382 
00383     PtrList<cellShape> tmpBlockCells(blocks.size());
00384     forAll(blocks, blockLabel)
00385     {
00386         tmpBlockCells.set
00387         (
00388             blockLabel,
00389             new cellShape(blocks[blockLabel].blockDef().blockShape())
00390         );
00391 
00392         if (tmpBlockCells[blockLabel].mag(tmpBlockPoints) < 0.0)
00393         {
00394             WarningIn
00395             (
00396                 "blockMesh::createTopology(IOdictionary&)"
00397             )   << "negative volume block : " << blockLabel
00398                 << ", probably defined inside-out" << endl;
00399         }
00400     }
00401 
00402     wordList patchPhysicalTypes(tmpBlocksPatches.size());
00403 
00404     preservePatchTypes
00405     (
00406         meshDescription.time(),
00407         meshDescription.time().constant(),
00408         polyMesh::meshSubDir,
00409         patchNames,
00410         patchTypes,
00411         defaultPatchName,
00412         defaultPatchType,
00413         patchPhysicalTypes
00414     );
00415 
00416     polyMesh* blockMeshPtr = new polyMesh
00417     (
00418         IOobject
00419         (
00420             "blockMesh",
00421             meshDescription.time().constant(),
00422             meshDescription.time(),
00423             IOobject::NO_READ,
00424             IOobject::NO_WRITE,
00425             false
00426         ),
00427         xferMove(tmpBlockPoints),
00428         tmpBlockCells,
00429         tmpBlocksPatches,
00430         patchNames,
00431         patchTypes,
00432         defaultPatchName,
00433         defaultPatchType,
00434         patchPhysicalTypes
00435     );
00436 
00437     checkBlockMesh(*blockMeshPtr);
00438 
00439     return blockMeshPtr;
00440 }
00441 
00442 
00443 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines