/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 3.2
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
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 .
Description
Converts .ele and .node and .face files, written by tetgen.
Make sure to use add boundary attributes to the smesh file
(5 fifth column in the element section)
and run tetgen with -f option.
Sample smesh file:
# cube.smesh -- A 10x10x10 cube
8 3
1 0 0 0
2 0 10 0
3 10 10 0
4 10 0 0
5 0 0 10
6 0 10 10
7 10 10 10
8 10 0 10
6 1 # 1 for boundary info present
4 1 2 3 4 11 # region number 11
4 5 6 7 8 21 # region number 21
4 1 2 6 5 3
4 4 3 7 8 43
4 1 5 8 4 5
4 2 6 7 3 65
0
0
NOTE:
- for some reason boundary faces point inwards. I just reverse them
always. Might use some geometric check instead.
- marked faces might not actually be boundary faces of mesh.
This is hopefully handled now by first constructing without boundaries
and then reconstructing with boundary faces.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "objectRegistry.H"
#include "foamTime.H"
#include "polyMesh.H"
#include "IFstream.H"
#include "cellModeller.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Find label of face.
label findFace(const primitiveMesh& mesh, const face& f)
{
const labelList& pFaces = mesh.pointFaces()[f[0]];
forAll(pFaces, i)
{
label faceI = pFaces[i];
if (mesh.faces()[faceI] == f)
{
return faceI;
}
}
FatalErrorIn("findFace(const primitiveMesh&, const face&)")
<< "Cannot find face " << f << " in mesh." << abort(FatalError);
return -1;
}
// Main program:
int main(int argc, char *argv[])
{
argList::validArgs.append("file prefix");
argList::validOptions.insert("noFaceFile", "");
# include "setRootCase.H"
# include "createTime.H"
bool readFaceFile = !args.optionFound("noFaceFile");
fileName prefix(args.additionalArgs()[0]);
fileName nodeFile(prefix + ".node");
fileName eleFile(prefix + ".ele");
fileName faceFile(prefix + ".face");
if (!readFaceFile)
{
Info<< "Files:" << endl
<< " nodes : " << nodeFile << endl
<< " elems : " << eleFile << endl
<< endl;
}
else
{
Info<< "Files:" << endl
<< " nodes : " << nodeFile << endl
<< " elems : " << eleFile << endl
<< " faces : " << faceFile << endl
<< endl;
Info<< "Reading .face file for boundary information" << nl << endl;
}
if (!isFile(nodeFile) || !isFile(eleFile))
{
FatalErrorIn(args.executable())
<< "Cannot read " << nodeFile << " or " << eleFile
<< exit(FatalError);
}
if (readFaceFile && !isFile(faceFile))
{
FatalErrorIn(args.executable())
<< "Cannot read " << faceFile << endl
<< "Did you run tetgen with -f option?" << endl
<< "If you don't want to read the .face file and thus not have"
<< " patches please\nrerun with the -noFaceFile option"
<< exit(FatalError);
}
IFstream nodeStream(nodeFile);
//
// Read nodes.
//
// Read header.
string line;
do
{
nodeStream.getLine(line);
}
while (line.size() && line[0] == '#');
IStringStream nodeLine(line);
label nNodes, nDims, nNodeAttr;
bool hasRegion;
nodeLine >> nNodes >> nDims >> nNodeAttr >> hasRegion;
Info<< "Read .node header:" << endl
<< " nodes : " << nNodes << endl
<< " nDims : " << nDims << endl
<< " nAttr : " << nNodeAttr << endl
<< " hasRegion : " << hasRegion << endl
<< endl;
//
// read points
//
pointField points(nNodes);
Map