ENH: new PDRblockMesh mesh generation utility (issue #1216)

- While a rectilinear mesh can be created with blockMesh, not every mesh
  created with blockMesh will satisfy the requirements for being a
  rectilinear mesh.

  This alternative to blockMesh uses a single block that is aligned
  with the xy-z directions and specifications of the control points,
  mesh divisions and expansion ratios. For example,

    x
    {
        points  ( -13.28 -0.10 6.0 19.19 );
        nCells  (  10  12 10 );
        ratios  ( 0.2   1  5 );
    }

    y { ... }
    z { ... }

  With only one block, the boundary patch definition is simple and the
  canonical face number is used directly. For example,

    inlet
    {
        type    patch;
        faces   ( 0 );
    }
    outlet
    {
        type    patch;
        faces   ( 1 );
    }

    sides
    {
        type    patch;
        faces   ( 2 3 );
    }

    ...

- After a mesh is defined, it is trivial to retrieve mesh-related
  information such as cell-volume, cell-centres for any i-j-k location
  without an actual polyMesh.

STYLE: remove -noFunctionObjects from blockMesh

- no time loop, so function objects cannot be triggered anyhow.
This commit is contained in:
Mark Olesen
2019-02-23 15:45:32 +01:00
parent 9d5edd161c
commit 2d26655a19
27 changed files with 2343 additions and 35 deletions

View File

@ -0,0 +1,3 @@
PDRblockMesh.C
EXE = $(FOAM_APPBIN)/PDRblockMesh

View File

@ -0,0 +1,5 @@
EXE_INC = \
-I$(LIB_SRC)/mesh/blockMesh/lnInclude
EXE_LIBS = \
-lblockMesh

View File

@ -0,0 +1,238 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
Application
PDRblockMesh
Group
grpMeshGenerationUtilities
Description
A specialized single-block mesh generator for a rectilinear mesh
in x-y-z.
Uses the mesh description found in
- \c system/PDRblockMeshDict
Usage
\b PDRblockMesh [OPTION]
Options:
- \par -dict \<filename\>
Alternative dictionary for the mesh description.
- \par -noClean
Do not remove any existing polyMesh/ directory or files
- \par -time
Write resulting mesh to a time directory (instead of constant)
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "polyMesh.H"
#include "PDRblock.H"
#include "Time.H"
#include "IOdictionary.H"
#include "OSspecific.H"
#include "OFstream.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"A block mesh generator for a rectilinear mesh in x-y-z.\n"
" The ordering of vertex and face labels within a block as shown "
"below.\n"
" For the local vertex numbering in the sequence 0 to 7:\n"
" Faces 0, 1 == x-min, x-max.\n"
" Faces 2, 3 == y-min, y-max.\n"
" Faces 4, 5 == z-min, z-max.\n"
"\n"
" 7 ---- 6\n"
" f5 |\\ |\\ f3\n"
" | | 4 ---- 5 \\\n"
" | 3 |--- 2 | \\\n"
" | \\| \\| f2\n"
" f4 0 ---- 1\n"
" Y Z\n"
" \\ | f0 ------ f1\n"
" \\|\n"
" O--- X\n"
);
argList::noParallel();
argList::noFunctionObjects();
argList::addBoolOption
(
"noClean",
"Do not remove any existing polyMesh/ directory or files"
);
argList::addOption
(
"dict",
"file",
"Alternative dictionary for the PDRblockMesh description"
);
argList::addOption
(
"time",
"time",
"Specify a time to write mesh to (default: constant)"
);
#include "setRootCase.H"
#include "createTime.H"
// Instance for resulting mesh
bool useTime = false;
word meshInstance(runTime.constant());
if
(
args.readIfPresent("time", meshInstance)
&& runTime.constant() != meshInstance
)
{
// Verify that the value is actually good
scalar timeValue;
useTime = readScalar(meshInstance, timeValue);
if (!useTime)
{
FatalErrorInFunction
<< "Bad input value: " << meshInstance
<< "Should be a scalar or 'constant'"
<< nl << endl
<< exit(FatalError);
}
}
const word dictName("PDRblockMeshDict");
#include "setSystemRunTimeDictionaryIO.H"
IOdictionary meshDict(dictIO);
Info<< "Creating PDRblockMesh from "
<< runTime.relativePath(dictIO.objectPath()) << endl;
PDRblock blkMesh(meshDict, true);
// Instance for resulting mesh
if (useTime)
{
Info<< "Writing polyMesh to " << meshInstance << nl << endl;
// Make sure that the time is seen to be the current time.
// This is the logic inside regIOobject that resets the instance
// to the current time before writing
runTime.setTime(instant(meshInstance), 0);
}
if (!args.found("noClean"))
{
const fileName polyMeshPath
(
runTime.path()/meshInstance/polyMesh::meshSubDir
);
if (exists(polyMeshPath))
{
Info<< "Deleting polyMesh directory "
<< runTime.relativePath(polyMeshPath) << endl;
rmDir(polyMeshPath);
}
}
Info<< nl << "Creating polyMesh from PDRblockMesh" << endl;
auto meshPtr = blkMesh.mesh
(
IOobject
(
polyMesh::defaultRegion,
meshInstance,
runTime,
IOobject::NO_READ,
IOobject::AUTO_WRITE
)
);
const polyMesh& mesh = *meshPtr;
// Set the precision of the points data to 10
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
Info<< nl << "Writing polyMesh with "
<< mesh.cellZones().size() << " cellZones" << endl;
mesh.removeFiles();
if (!mesh.write())
{
FatalErrorInFunction
<< "Failed writing polyMesh."
<< exit(FatalError);
}
// Mesh summary
{
Info<< "----------------" << nl
<< "Mesh Information" << nl
<< "----------------" << nl
<< " " << "boundingBox: " << boundBox(mesh.points()) << nl
<< " " << "nPoints: " << mesh.nPoints() << nl
<< " " << "nCells: " << mesh.nCells() << nl
<< " " << "nFaces: " << mesh.nFaces() << nl
<< " " << "nInternalFaces: " << mesh.nInternalFaces() << nl;
Info<< "----------------" << nl
<< "Patches" << nl
<< "----------------" << nl;
for (const polyPatch& p : mesh.boundaryMesh())
{
Info<< " " << "patch " << p.index()
<< " (start: " << p.start()
<< " size: " << p.size()
<< ") name: " << p.name()
<< nl;
}
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011, 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
@ -109,6 +109,8 @@ int main(int argc, char *argv[])
);
argList::noParallel();
argList::noFunctionObjects();
argList::addBoolOption
(
"blockTopology",
@ -134,7 +136,7 @@ int main(int argc, char *argv[])
(
"time",
"time",
"specify a time to write mesh to"
"Specify a time to write mesh to (default: constant)"
);
#include "addRegionOption.H"
@ -234,15 +236,15 @@ int main(int argc, char *argv[])
{
Info<< "Writing polyMesh to " << meshInstance << nl << endl;
// Make sure that the time is seen to be the current time. This
// is the logic inside regIOobject which resets the instance to the
// current time before writing
// Make sure that the time is seen to be the current time.
// This is the logic inside regIOobject that resets the instance
// to the current time before writing
runTime.setTime(instant(meshInstance), 0);
}
if (!args.found("noClean"))
{
fileName polyMeshPath
const fileName polyMeshPath
(
runTime.path()/meshInstance/regionPath/polyMesh::meshSubDir
);
@ -251,14 +253,14 @@ int main(int argc, char *argv[])
{
if (exists(polyMeshPath/dictName))
{
Info<< "Not deleting polyMesh directory " << nl
<< " " << polyMeshPath << nl
Info<< "Not deleting polyMesh directory "
<< runTime.relativePath(polyMeshPath) << nl
<< " because it contains " << dictName << endl;
}
else
{
Info<< "Deleting polyMesh directory" << nl
<< " " << polyMeshPath << endl;
Info<< "Deleting polyMesh directory "
<< runTime.relativePath(polyMeshPath) << endl;
rmDir(polyMeshPath);
}
}
@ -267,9 +269,6 @@ int main(int argc, char *argv[])
Info<< nl << "Creating polyMesh from blockMesh" << endl;
word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
polyMesh mesh
(
IOobject
@ -283,8 +282,8 @@ int main(int argc, char *argv[])
blocks.patches(),
blocks.patchNames(),
blocks.patchDicts(),
defaultFacesName,
defaultFacesType
"defaultFaces", // Default patch name
emptyPolyPatch::typeName // Default patch type
);
@ -297,9 +296,8 @@ int main(int argc, char *argv[])
// Detect any cyclic patches and force re-ordering of the faces
{
const polyPatchList& patches = mesh.boundaryMesh();
bool hasCyclic = false;
for (const polyPatch& pp : patches)
for (const polyPatch& pp : mesh.boundaryMesh())
{
if (isA<cyclicPolyPatch>(pp))
{
@ -350,8 +348,6 @@ int main(int argc, char *argv[])
// Write summary
{
const polyPatchList& patches = mesh.boundaryMesh();
Info<< "----------------" << nl
<< "Mesh Information" << nl
<< "----------------" << nl
@ -365,7 +361,7 @@ int main(int argc, char *argv[])
<< "Patches" << nl
<< "----------------" << nl;
for (const polyPatch& p : patches)
for (const polyPatch& p : mesh.boundaryMesh())
{
Info<< " " << "patch " << p.index()
<< " (start: " << p.start()

View File

@ -24,7 +24,7 @@ autoPtr<IOdictionary> meshDictPtr;
)
)
{
// Dictionary present constant polyMesh directory (old-style)
// Dictionary present in constant polyMesh directory (old-style)
dictPath =
runTime.constant()
@ -63,8 +63,8 @@ autoPtr<IOdictionary> meshDictPtr;
<< exit(FatalError);
}
Info<< "Creating block mesh from\n "
<< meshDictIO.objectPath() << endl;
Info<< "Creating block mesh from "
<< runTime.relativePath(meshDictIO.objectPath()) << endl;
meshDictPtr = autoPtr<IOdictionary>::New(meshDictIO);
}