/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | foam-extend: Open Source CFD \\ / O peration | \\ / A nd | For copyright notice see file Copyright \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of foam-extend. foam-extend is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. foam-extend is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with foam-extend. If not, see . \*---------------------------------------------------------------------------*/ #include "blockMesh.H" #include "Time.H" #include "preservePatchTypes.H" #include "emptyPolyPatch.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // bool Foam::blockMesh::blockLabelsOK ( const label blockLabel, const pointField& points, const cellShape& blockShape ) { bool ok = true; forAll(blockShape, blockI) { if (blockShape[blockI] < 0) { ok = false; WarningIn ( "bool Foam::blockMesh::blockLabelsOK" "(const label blockLabel, const pointField& points, " "const cellShape& blockShape)" ) << "block " << blockLabel << " point label " << blockShape[blockI] << " less than zero" << endl; } else if (blockShape[blockI] >= points.size()) { ok = false; WarningIn ( "bool Foam::blockMesh::blockLabelsOK" "(const label blockLabel, const pointField& points, " "const cellShape& blockShape)" ) << "block " << blockLabel << " point label " << blockShape[blockI] << " larger than " << points.size() - 1 << " the largest defined point label" << endl; } } return ok; } bool Foam::blockMesh::patchLabelsOK ( const label patchLabel, const pointField& points, const faceList& patchFaces ) { bool ok = true; forAll(patchFaces, faceI) { const labelList& f = patchFaces[faceI]; forAll(f, fp) { if (f[fp] < 0) { ok = false; WarningIn ( "bool Foam::blockMesh::patchLabelsOK(...)" ) << "patch " << patchLabel << " face " << faceI << " point label " << f[fp] << " less than zero" << endl; } else if (f[fp] >= points.size()) { ok = false; WarningIn ( "bool Foam::blockMesh::patchLabelsOK(...)" ) << "patch " << patchLabel << " face " << faceI << " point label " << f[fp] << " larger than " << points.size() - 1 << " the largest defined point label" << endl; } } } return ok; } // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription) { bool topologyOK = true; blockMesh& blocks = *this; word defaultPatchName = "defaultFaces"; word defaultPatchType = emptyPolyPatch::typeName; // get names/types for the unassigned patch faces // this is a bit heavy handed (and ugly), but there is currently // no easy way to rename polyMesh patches subsequently if (const dictionary* dictPtr = meshDescription.subDictPtr("defaultPatch")) { dictPtr->readIfPresent("name", defaultPatchName); dictPtr->readIfPresent("type", defaultPatchType); } Info<< nl << "Creating blockCorners" << endl; // create blockCorners pointField tmpBlockPoints(meshDescription.lookup("vertices")); if (meshDescription.found("edges")) { // read number of non-linear edges in mesh Info<< nl << "Creating curved edges" << endl; ITstream& edgesStream(meshDescription.lookup("edges")); label nEdges = 0; token firstToken(edgesStream); if (firstToken.isLabel()) { nEdges = firstToken.labelToken(); edges_.setSize(nEdges); } else { edgesStream.putBack(firstToken); } // Read beginning of edges edgesStream.readBegin("edges"); nEdges = 0; token lastToken(edgesStream); while ( !( lastToken.isPunctuation() && lastToken.pToken() == token::END_LIST ) ) { if (edges_.size() <= nEdges) { edges_.setSize(nEdges + 1); } edgesStream.putBack(lastToken); edges_.set ( nEdges, curvedEdge::New(tmpBlockPoints, edgesStream) ); nEdges++; edgesStream >> lastToken; } edgesStream.putBack(lastToken); // Read end of edges edgesStream.readEnd("edges"); } else { Info<< nl << "There are no non-linear edges" << endl; } Info<< nl << "Creating blocks" << endl; { ITstream& blockDescriptorStream(meshDescription.lookup("blocks")); // read number of blocks in mesh label nBlocks = 0; token firstToken(blockDescriptorStream); if (firstToken.isLabel()) { nBlocks = firstToken.labelToken(); blocks.setSize(nBlocks); } else { blockDescriptorStream.putBack(firstToken); } // Read beginning of blocks blockDescriptorStream.readBegin("blocks"); nBlocks = 0; token lastToken(blockDescriptorStream); while ( !( lastToken.isPunctuation() && lastToken.pToken() == token::END_LIST ) ) { if (blocks.size() <= nBlocks) { blocks.setSize(nBlocks + 1); } blockDescriptorStream.putBack(lastToken); blocks.set ( nBlocks, new block ( blockDescriptor ( tmpBlockPoints, edges_, blockDescriptorStream ) ) ); topologyOK = topologyOK && blockLabelsOK ( nBlocks, tmpBlockPoints, blocks[nBlocks].blockDef().blockShape() ); nBlocks++; blockDescriptorStream >> lastToken; } blockDescriptorStream.putBack(lastToken); // Read end of blocks blockDescriptorStream.readEnd("blocks"); } Info<< nl << "Creating patches" << endl; faceListList tmpBlocksPatches; wordList patchNames; wordList patchTypes; { ITstream& patchStream(meshDescription.lookup("patches")); // read number of patches in mesh label nPatches = 0; token firstToken(patchStream); if (firstToken.isLabel()) { nPatches = firstToken.labelToken(); tmpBlocksPatches.setSize(nPatches); patchNames.setSize(nPatches); patchTypes.setSize(nPatches); } else { patchStream.putBack(firstToken); } // Read beginning of blocks patchStream.readBegin("patches"); nPatches = 0; token lastToken(patchStream); while ( !( lastToken.isPunctuation() && lastToken.pToken() == token::END_LIST ) ) { if (tmpBlocksPatches.size() <= nPatches) { tmpBlocksPatches.setSize(nPatches + 1); patchNames.setSize(nPatches + 1); patchTypes.setSize(nPatches + 1); } patchStream.putBack(lastToken); patchStream >> patchTypes[nPatches] >> patchNames[nPatches] >> tmpBlocksPatches[nPatches]; // Catch multiple patches asap. for (label i = 0; i < nPatches; i++) { if (patchNames[nPatches] == patchNames[i]) { FatalErrorIn ( "blockMesh::createTopology(IOdictionary&)" ) << "Duplicate patch " << patchNames[nPatches] << " at line " << patchStream.lineNumber() << ". Exiting !" << nl << exit(FatalError); } } topologyOK = topologyOK && patchLabelsOK ( nPatches, tmpBlockPoints, tmpBlocksPatches[nPatches] ); nPatches++; patchStream >> lastToken; } patchStream.putBack(lastToken); // Read end of blocks patchStream.readEnd("patches"); } if (!topologyOK) { FatalErrorIn("blockMesh::createTopology(IOdictionary&)") << "Cannot create mesh due to errors in topology, exiting !" << nl << exit(FatalError); } Info<< nl << "Creating block mesh topology" << endl; PtrList tmpBlockCells(blocks.size()); forAll(blocks, blockLabel) { tmpBlockCells.set ( blockLabel, new cellShape(blocks[blockLabel].blockDef().blockShape()) ); if (tmpBlockCells[blockLabel].mag(tmpBlockPoints) < 0.0) { WarningIn ( "blockMesh::createTopology(IOdictionary&)" ) << "negative volume block : " << blockLabel << ", probably defined inside-out" << endl; } } wordList patchPhysicalTypes(tmpBlocksPatches.size()); preservePatchTypes ( meshDescription.time(), meshDescription.time().constant(), polyMesh::meshSubDir, patchNames, patchTypes, defaultPatchName, defaultPatchType, patchPhysicalTypes ); polyMesh* blockMeshPtr = new polyMesh ( IOobject ( "blockMesh", meshDescription.time().constant(), meshDescription.time(), IOobject::NO_READ, IOobject::NO_WRITE, false ), xferMove(tmpBlockPoints), tmpBlockCells, tmpBlocksPatches, patchNames, patchTypes, defaultPatchName, defaultPatchType, patchPhysicalTypes ); checkBlockMesh(*blockMeshPtr); return blockMeshPtr; } // ************************************************************************* //