Commit 319e09e3 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: avoid blockMesh removal of files for special cases (issue #963)

- do not remove if the dictionary failed to load.
- do not remove if -blockTopology was used.
parent 88e5334a
......@@ -28,8 +28,7 @@ Group
grpMeshConversionUtilities
Description
For mesh debugging: writes mesh as three separate OBJ files which can
be viewed with e.g. javaview.
For mesh debugging: writes mesh as three separate OBJ files.
meshPoints_XXX.obj : all points and edges as lines.
meshFaceCentres_XXX.obj : all face centres.
......@@ -61,6 +60,7 @@ void writeOBJ(const point& pt, Ostream& os)
os << "v " << pt.x() << ' ' << pt.y() << ' ' << pt.z() << nl;
}
// All edges of mesh
void writePoints(const polyMesh& mesh, const fileName& timeName)
{
......
// Set any cellZones
// Note cell labelling unaffected by previous mergePatchPairs
{
const label nZones = blocks.numZonedBlocks();
if (nZones)
{
Info<< nl << "Adding cell zones" << endl;
// Map from zoneName to cellZone index
HashTable<label> zoneMap(nZones);
// Cells per zone.
List<DynamicList<label>> zoneCells(nZones);
// Running cell counter
label celli = 0;
// Largest zone so far
label freeZoneI = 0;
for (const block& b : blocks)
{
const word& zoneName = b.zoneName();
const label nCellsInBlock = b.cells().size();
if (zoneName.size())
{
const auto iter = zoneMap.cfind(zoneName);
label zonei;
if (iter.found())
{
zonei = *iter;
}
else
{
zonei = freeZoneI++;
Info<< " " << zonei << '\t' << zoneName << endl;
zoneMap.insert(zoneName, zonei);
}
// Fill with cell ids
zoneCells[zonei].reserve
(
zoneCells[zonei].size() + nCellsInBlock
);
const label endOfFill = celli + nCellsInBlock;
for (; celli < endOfFill; ++celli)
{
zoneCells[zonei].append(celli);
}
}
else
{
celli += nCellsInBlock;
}
}
List<cellZone*> cz(zoneMap.size());
forAllConstIters(zoneMap, iter)
{
const word& zoneName = iter.key();
const label zonei = iter.object();
cz[zonei] = new cellZone
(
zoneName,
zoneCells[zonei].shrink(),
zonei,
mesh.cellZones()
);
}
mesh.pointZones().resize(0);
mesh.faceZones().resize(0);
mesh.cellZones().resize(0);
mesh.addZones(List<pointZone*>(), List<faceZone*>(), cz);
}
}
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -41,17 +41,20 @@ Usage
Options:
- \par -blockTopology
Write the topology as a set of edges in OBJ format.
Write the topology as a set of edges in OBJ format and exit.
- \par -region \<name\>
Specify an alternative mesh region.
Specify alternative mesh region.
- \par -dict \<filename\>
Specify alternative dictionary for the block mesh description.
Alternative dictionary for the block mesh description.
- \par -sets
Write cellZones as cellSets too (for processing purposes)
- \par -noClean
Do not remove any existing polyMesh/ directory or files
\*---------------------------------------------------------------------------*/
#include "Time.H"
......@@ -78,58 +81,55 @@ using namespace Foam;
int main(int argc, char *argv[])
{
argList::addNote
(
"Block mesh generator.\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-direction) are left, right.\n"
" Faces 2, 3 (y-direction) are front, back.\n"
" Faces 4, 5 (z-direction) are bottom, top.\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::addBoolOption
(
"blockTopology",
"Write block edges and centres as .obj files"
"Write block edges and centres as obj files and exit"
);
argList::addBoolOption
(
"noClean",
"Keep the existing files in the polyMesh"
"Do not remove any existing polyMesh/ directory or files"
);
argList::addOption
(
"dict",
"file",
"Specify alternative dictionary for the blockMesh description"
"Alternative dictionary for the blockMesh description"
);
argList::addBoolOption
(
"sets",
"Write cellZones as cellSets too (for processing purposes)"
);
argList::addNote
(
"Block description\n"
"\n"
" For a given block, the correspondence between the ordering of\n"
" vertex labels and face labels is shown below.\n"
" For vertex numbering in the sequence 0 to 7 (block, centre):\n"
" faces 0 (f0) and 1 are left and right, respectively;\n"
" faces 2 and 3 are front and back; \n"
" and faces 4 and 5 are bottom and top::\n"
"\n"
" 7 ---- 6\n"
" f5 |\\ |\\ f3\n"
" | | 4 ---- 5 \\\n"
" | 3 |--- 2 | \\\n"
" | \\| \\| f2\n"
" f4 0 ---- 1\n"
"\n"
" Z f0 ----- f1\n"
" | Y\n"
" | /\n"
" O --- X\n"
);
#include "addRegionOption.H"
#include "setRootCase.H"
#include "createTime.H"
const word dictName("blockMeshDict");
word regionName;
word regionPath;
......@@ -140,139 +140,89 @@ int main(int argc, char *argv[])
regionPath = regionName;
}
// Search for the appropriate blockMesh dictionary....
fileName dictPath;
// Locate appropriate blockMeshDict
#include "findBlockMeshDict.H"
// Check if the dictionary is specified on the command-line
if (args.readIfPresent("dict", dictPath))
{
if (isDir(dictPath))
{
dictPath /= dictName;
}
}
// Check if dictionary is present in the constant directory
else if
(
exists
(
runTime.path()/runTime.constant()
/regionPath/polyMesh::meshSubDir/dictName
)
)
{
dictPath =
runTime.constant()
/regionPath/polyMesh::meshSubDir/dictName;
// Warn that constant/polyMesh/blockMesh was selected instead of
// system/blockMesh
WarningIn(args[0])
<< "Using the old blockMeshDict location: "
<< dictPath << nl
<< " instead of the default location: "
<< runTime.system()/regionPath/dictName << nl
<< endl;
}
// Otherwise assume the dictionary is present in the system directory
else
{
dictPath = runTime.system()/regionPath/dictName;
}
blockMesh blocks(meshDict, regionName);
if (!args.found("noClean"))
if (!blocks.valid())
{
fileName polyMeshPath
(
runTime.path()/runTime.constant()/regionPath/polyMesh::meshSubDir
);
if (exists(polyMeshPath))
{
if (exists(polyMeshPath/dictName))
{
Info<< "Not deleting polyMesh directory " << nl
<< " " << polyMeshPath << nl
<< " because it contains " << dictName << endl;
}
else
{
Info<< "Deleting polyMesh directory" << nl
<< " " << polyMeshPath << endl;
rmDir(polyMeshPath);
}
}
}
// Could/should be Fatal?
IOobject meshDictIO
(
dictPath,
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
);
WarningIn(args.executable())
<< "Did not generate any blocks. Stopping." << nl << endl;
if (!meshDictIO.typeHeaderOk<IOdictionary>(true))
{
FatalErrorInFunction
<< meshDictIO.objectPath()
<< nl
<< exit(FatalError);
return 1;
}
Info<< "Creating block mesh from\n "
<< meshDictIO.objectPath() << endl;
IOdictionary meshDict(meshDictIO);
blockMesh blocks(meshDict, regionName);
if (args.found("blockTopology"))
{
Info<< nl;
// Write mesh as edges.
{
fileName objMeshFile("blockTopology.obj");
OFstream str(runTime.path()/objMeshFile);
OFstream os(runTime.path()/"blockTopology.obj");
Info<< nl << "Dumping block structure as Lightwave obj format"
<< " to " << objMeshFile << endl;
Info<< "Writing block structure as obj format: "
<< os.name().name() << endl;
blocks.writeTopology(str);
blocks.writeTopology(os);
}
// Write centres of blocks
{
fileName objCcFile("blockCentres.obj");
OFstream os(runTime.path()/"blockCentres.obj");
OFstream str(runTime.path()/objCcFile);
Info<< nl << "Dumping block centres as Lightwave obj format"
<< " to " << objCcFile << endl;
Info<< "Writing block centres as obj format: "
<< os.name().name() << endl;
const polyMesh& topo = blocks.topology();
const pointField& cellCentres = topo.cellCentres();
for (const point& cc : cellCentres)
for (const point& cc : topo.cellCentres())
{
//point cc = b.blockShape().centre(b.points());
str << "v " << cc.x() << ' ' << cc.y() << ' ' << cc.z() << nl;
os << "v " << cc.x() << ' ' << cc.y() << ' ' << cc.z() << nl;
}
}
Info<< nl << "end" << endl;
Info<< "\nEnd\n" << endl;
return 0;
}
if (!args.found("noClean"))
{
fileName polyMeshPath
(
runTime.path()/runTime.constant()/regionPath/polyMesh::meshSubDir
);
if (exists(polyMeshPath))
{
if (exists(polyMeshPath/dictName))
{
Info<< "Not deleting polyMesh directory " << nl
<< " " << polyMeshPath << nl
<< " because it contains " << dictName << endl;
}
else
{
Info<< "Deleting polyMesh directory" << nl
<< " " << polyMeshPath << endl;
rmDir(polyMeshPath);
}
}
}
Info<< nl << "Creating polyMesh from blockMesh" << endl;
word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
polyMesh mesh
(
IOobject
......@@ -290,97 +240,12 @@ int main(int argc, char *argv[])
defaultFacesType
);
// Read in a list of dictionaries for the merge patch pairs
if (meshDict.found("mergePatchPairs"))
{
List<Pair<word>> mergePatchPairs
(
meshDict.lookup("mergePatchPairs")
);
#include "mergePatchPairs.H"
}
else
{
Info<< nl << "There are no merge patch pairs edges" << endl;
}
// Set any cellZones (note: cell labelling unaffected by above
// mergePatchPairs)
const label nZones = blocks.numZonedBlocks();
if (nZones > 0)
{
Info<< nl << "Adding cell zones" << endl;
// Map from zoneName to cellZone index
HashTable<label> zoneMap(nZones);
// Cells per zone.
List<DynamicList<label>> zoneCells(nZones);
// Running cell counter
label celli = 0;
// Largest zone so far
label freeZoneI = 0;
forAll(blocks, blockI)
{
const block& b = blocks[blockI];
const List<FixedList<label, 8>> blockCells = b.cells();
const word& zoneName = b.zoneName();
if (zoneName.size())
{
HashTable<label>::const_iterator iter = zoneMap.find(zoneName);
label zoneI;
if (iter == zoneMap.end())
{
zoneI = freeZoneI++;
// Handle merging of patch pairs. Dictionary entry "mergePatchPairs"
#include "mergePatchPairs.H"
Info<< " " << zoneI << '\t' << zoneName << endl;
zoneMap.insert(zoneName, zoneI);
}
else
{
zoneI = iter();
}
forAll(blockCells, i)
{
zoneCells[zoneI].append(celli++);
}
}
else
{
celli += b.cells().size();
}
}
List<cellZone*> cz(zoneMap.size());
forAllConstIter(HashTable<label>, zoneMap, iter)
{
label zoneI = iter();
cz[zoneI] = new cellZone
(
iter.key(),
zoneCells[zoneI].shrink(),
zoneI,
mesh.cellZones()
);
}
mesh.pointZones().setSize(0);
mesh.faceZones().setSize(0);
mesh.cellZones().setSize(0);
mesh.addZones(List<pointZone*>(0), List<faceZone*>(0), cz);
}
// Set any cellZones
#include "addCellZones.H"
// Detect any cyclic patches and force re-ordering of the faces
......@@ -413,6 +278,7 @@ int main(int argc, char *argv[])
Info<< nl << "Writing polyMesh with "
<< mesh.cellZones().size() << " cellZones";
if (args.found("sets") && !mesh.cellZones().empty())
{
Info<< " (written as cellSets too)";
......@@ -429,9 +295,8 @@ int main(int argc, char *argv[])
if (args.found("sets"))
{
forAll(mesh.cellZones(), zonei)
for (const cellZone& cz : mesh.cellZones())
{
const cellZone& cz = mesh.cellZones()[zonei];
cellSet(mesh, cz.name(), cz).write();
}
}
......@@ -453,11 +318,9 @@ int main(int argc, char *argv[])
<< "Patches" << nl
<< "----------------" << nl;
forAll(patches, patchi)
for (const polyPatch& p : patches)
{
const polyPatch& p = patches[patchi];
Info<< " " << "patch " << patchi
Info<< " " << "patch " << p.index()
<< " (start: " << p.start()
<< " size: " << p.size()
<< ") name: " << p.name()
......
// Search for the appropriate blockMesh dictionary....
const word dictName("blockMeshDict");
autoPtr<IOdictionary> meshDictPtr;
{
fileName dictPath;
if (args.readIfPresent("dict", dictPath))
{
// Dictionary specified on the command-line ...
if (isDir(dictPath))
{
dictPath /= dictName;
}
}
else if
(
exists
(
runTime.path()/runTime.constant()
/regionPath/polyMesh::meshSubDir/dictName
)
)
{
// Dictionary present constant polyMesh directory (old-style)
dictPath =
runTime.constant()
/regionPath/polyMesh::meshSubDir/dictName;
// Warn that constant/polyMesh/blockMeshDict was used
// instead of system/blockMeshDict
WarningIn(args.executable())
<< "Using the old blockMeshDict location: "
<< dictPath << nl
<< " instead of the default location: "
<< runTime.system()/regionPath/dictName << nl
<< endl;
}
else
{
// Assume dictionary is to be found in the system directory
dictPath = runTime.system()/regionPath/dictName;
}
IOobject meshDictIO
(
dictPath,
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
);
if (!meshDictIO.typeHeaderOk<IOdictionary>(true