444 lines
12 KiB
C
444 lines
12 KiB
C
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | Copyright held by original author
|
|
\\/ M anipulation |
|
|
-------------------------------------------------------------------------------
|
|
License
|
|
This file is part of OpenFOAM.
|
|
|
|
OpenFOAM 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 2 of the License, or (at your
|
|
option) any later version.
|
|
|
|
OpenFOAM 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 OpenFOAM; if not, write to the Free Software Foundation,
|
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#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<cellShape> 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;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|