This repository has been archived on 2023-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
foam-extend4.1-coherent-io/applications/utilities/mesh/conversion/ansysToFoam/ansysToFoam.L
2010-08-25 22:42:57 +01:00

502 lines
14 KiB
C++

/*--------------------------------*- 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
Application
ansysToFoam
Description
Converts an ANSYS input mesh file, exported from I-DEAS, to FOAM format.
\*---------------------------------------------------------------------------*/
%{
#undef yyFlexLexer
/* ------------------------------------------------------------------------- *\
------ local definitions
\* ------------------------------------------------------------------------- */
#include <sstream>
#include "scalar.H"
#include "IStringStream.H"
using namespace Foam;
#include "argList.H"
#include "Time.H"
#include "polyMesh.H"
#include "emptyPolyPatch.H"
#include "preservePatchTypes.H"
#include "cellShape.H"
#include "cellModeller.H"
#include "SLList.H"
#include "SLPtrList.H"
SLList<point> slPoints;
SLList<label> slPointMap;
label maxNodei = 0;
SLPtrList<labelList> slCellLabels;
SLList<label> slCellMap;
label maxCelli = 0;
PtrList<SLList<label> > slPatchCells;
PtrList<SLList<label> > slPatchCellFaces;
// Dummy yywrap to keep yylex happy at compile time.
// It is called by yylex but is not used as the mechanism to change file.
// See <<EOF>>
#if YY_FLEX_SUBMINOR_VERSION < 34
extern "C" int yywrap()
#else
int yyFlexLexer::yywrap()
#endif
{
return 1;
}
%}
one_space [ \t\f\r]
space {one_space}*
some_space {one_space}+
cspace ","{space}
alpha [_A-Za-z]
digit [0-9]
dec_digit [0-9]
octal_digit [0-7]
hex_digit [0-9a-fA-F]
identifier {alpha}({alpha}|{digit})*
integer {dec_digit}+
label [1-9]{dec_digit}*
exponent_part [eE][-+]?{digit}+
fractional_constant [-+]?(({digit}*"."{digit}+)|({digit}+"."?))
double (({fractional_constant}{exponent_part}?)|({digit}+{exponent_part}))
x {double}
y {double}
z {double}
value {double}
node ^{space}"N"{cspace}
element ^{space}"EN"{cspace}
bface ^{space}"SFE"{cspace}
%%
%{
labelList labels(8);
%}
/* ------------------------------------------------------------------------- *\
------ Start Lexing ------
\* ------------------------------------------------------------------------- */
{node}{label}{cspace}{x}{cspace}{y}{cspace}{z}{space}\n {
IStringStream nodeStream(YYText());
char tag, c;
label nodei;
point node;
nodeStream
>> tag
>> c >> nodei
>> c >> node.x()
>> c >> node.y()
>> c >> node.z();
if (nodei > maxNodei) maxNodei = nodei;
slPointMap.append(nodei);
slPoints.append(node);
}
{element}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{cspace}{label}{space}\n {
IStringStream elementStream(YYText());
char tag, c;
label celli;
elementStream
>> tag >> tag
>> c >> celli
>> c >> labels[0]
>> c >> labels[1]
>> c >> labels[2]
>> c >> labels[3]
>> c >> labels[4]
>> c >> labels[5]
>> c >> labels[6]
>> c >> labels[7];
if (celli > maxCelli) maxCelli = celli;
slCellMap.append(celli);
slCellLabels.append(new labelList(labels));
}
{bface}{label}{cspace}{label}{cspace}{identifier}{cspace}{integer}{cspace}{value}{space}\n {
IStringStream bfaceStream(YYText());
char tag, c;
label elementi;
label facei;
scalar indexValue, unknown;
bfaceStream
>> tag >> tag >> tag
>> c >> elementi
>> c >> facei
>> c >> tag >> tag >> tag >> tag
>> c >> unknown
>> c >> indexValue;
label patchi = label(indexValue);
if (patchi > slPatchCells.size())
{
slPatchCells.setSize(patchi);
forAll(slPatchCells, i)
{
if (!slPatchCells(i))
{
slPatchCells.set(i, new SLList<label>);
}
}
}
if (patchi > slPatchCellFaces.size())
{
slPatchCellFaces.setSize(patchi);
forAll(slPatchCells, i)
{
if (!slPatchCellFaces(i))
{
slPatchCellFaces.set(i, new SLList<label>);
}
}
}
slPatchCells[patchi-1].append(elementi);
slPatchCellFaces[patchi-1].append(facei);
}
/* ------------------------------------------------------------------------- *\
------ Ignore remaining space and \n s. Any other characters are errors.
\* ------------------------------------------------------------------------- */
.|\n {}
/* ------------------------------------------------------------------------- *\
------ On EOF return to previous file, if none exists terminate.
\* ------------------------------------------------------------------------- */
<<EOF>> {
yyterminate();
}
%%
#include "fileName.H"
#include <fstream>
using std::ifstream;
int main(int argc, char *argv[])
{
argList::noParallel();
argList::validArgs.append("ANSYS input file");
argList::validOptions.insert("scale", "scale factor");
argList args(argc, argv);
if (!args.check())
{
FatalError.exit();
}
scalar scaleFactor = 1.0;
args.optionReadIfPresent("scale", scaleFactor);
# include "createTime.H"
fileName ansysFile(args.additionalArgs()[0]);
ifstream ansysStream(ansysFile.c_str());
if (!ansysStream)
{
FatalErrorIn("ansysToFoam::main(int argc, char *argv[])")
<< args.executable()
<< ": file " << ansysFile << " not found"
<< exit(FatalError);
}
yyFlexLexer lexer(&ansysStream);
while(lexer.yylex() != 0)
{}
Info << "Creating points" << endl;
pointField points(slPoints.size());
label i=0;
for
(
SLList<point>::iterator pointIter = slPoints.begin();
pointIter != slPoints.end();
++pointIter
)
{
// Scale points for the given scale factor
points[i++] = scaleFactor*pointIter();
}
labelList pointMap(maxNodei+1);
i=0;
for
(
SLList<label>::iterator pointMapIter = slPointMap.begin();
pointMapIter != slPointMap.end();
++pointMapIter
)
{
pointMap[pointMapIter()] = i++;
}
Info << "Creating cells" << endl;
labelList cellMap(maxCelli+1);
i=0;
for
(
SLList<label>::iterator cellMapIter = slCellMap.begin();
cellMapIter != slCellMap.end();
++cellMapIter
)
{
cellMap[cellMapIter()] = i++;
}
const cellModel& hex = *(cellModeller::lookup("hex"));
const cellModel& prism = *(cellModeller::lookup("prism"));
const cellModel& pyr = *(cellModeller::lookup("pyr"));
const cellModel& tet = *(cellModeller::lookup("tet"));
labelList labelsHex(8);
labelList labelsPrism(6);
labelList labelsPyramid(5);
labelList labelsTet(4);
cellShapeList cellShapes(slCellLabels.size());
label nCells = 0;
for
(
SLPtrList<labelList>::iterator cellIter = slCellLabels.begin();
cellIter != slCellLabels.end();
++cellIter
)
{
if // Tetrahedron
(
cellIter()[2] == cellIter()[3]
&& cellIter()[4] == cellIter()[5]
&& cellIter()[5] == cellIter()[6]
&& cellIter()[6] == cellIter()[7]
)
{
labelsTet[0] = pointMap[cellIter()[0] ];
labelsTet[1] = pointMap[cellIter()[1] ];
labelsTet[2] = pointMap[cellIter()[2] ];
labelsTet[3] = pointMap[cellIter()[4] ];
cellShapes[nCells++] = cellShape(tet, labelsTet);
}
else if // Square-based pyramid
(
cellIter()[4] == cellIter()[5]
&& cellIter()[5] == cellIter()[6]
&& cellIter()[6] == cellIter()[7]
)
{
labelsPyramid[0] = pointMap[cellIter()[0] ];
labelsPyramid[1] = pointMap[cellIter()[1] ];
labelsPyramid[2] = pointMap[cellIter()[2] ];
labelsPyramid[3] = pointMap[cellIter()[3] ];
labelsPyramid[4] = pointMap[cellIter()[4] ];
cellShapes[nCells++] = cellShape(pyr, labelsPyramid);
}
else if // Triangular prism
(
cellIter()[2] == cellIter()[3]
&& cellIter()[6] == cellIter()[7]
)
{
labelsPrism[0] = pointMap[cellIter()[0] ];
labelsPrism[1] = pointMap[cellIter()[1] ];
labelsPrism[2] = pointMap[cellIter()[2] ];
labelsPrism[3] = pointMap[cellIter()[4] ];
labelsPrism[4] = pointMap[cellIter()[5] ];
labelsPrism[5] = pointMap[cellIter()[6] ];
cellShapes[nCells++] = cellShape(prism, labelsPrism);
}
else // Hex
{
labelsHex[0] = pointMap[cellIter()[0] ];
labelsHex[1] = pointMap[cellIter()[1] ];
labelsHex[2] = pointMap[cellIter()[2] ];
labelsHex[3] = pointMap[cellIter()[3] ];
labelsHex[4] = pointMap[cellIter()[4] ];
labelsHex[5] = pointMap[cellIter()[5] ];
labelsHex[6] = pointMap[cellIter()[6] ];
labelsHex[7] = pointMap[cellIter()[7] ];
cellShapes[nCells++] = cellShape(hex, labelsHex);
}
}
// Warning: tet face order has changed between version 1.9.6 and 2.0
//
label faceIndex[7][6] =
{
{-1, -1, -1, -1, -1, -1}, // 0
{-1, -1, -1, -1, -1, -1}, // 1
{-1, -1, -1, -1, -1, -1}, // 2
{-1, -1, -1, -1, -1, -1}, // 3
{-1, 2, 0, 3, 1, -1}, // tet (version 2.0)
{ 0, 4, 3, -1, 2, 1}, // prism
{ 4, 2, 1, 3, 0, 5}, // hex
};
Info << "Creating boundary patches" << endl;
faceListList boundary(slPatchCells.size());
wordList patchNames(slPatchCells.size());
forAll(slPatchCells, patchI)
{
SLList<face> patchFaces;
SLList<label>::iterator cellIter(slPatchCells[patchI].begin());
SLList<label>::iterator faceIter(slPatchCellFaces[patchI].begin());
for
(
;
cellIter != slPatchCells[patchI].end()
&& faceIter != slPatchCellFaces[patchI].end();
++cellIter, ++faceIter
)
{
patchFaces.append
(
cellShapes[cellMap[cellIter()] ].faces()
[
faceIndex
[cellShapes[cellMap[cellIter()] ].nFaces()]
[faceIter()-1]
]
);
}
boundary[patchI] = patchFaces;
patchNames[patchI] = word("patch") + name(patchI + 1);
Info << "Patch " << patchI << " named " << patchNames[patchI]
<< ": " << boundary[patchI].size() << " faces" << endl;
}
Info << "ansysToFoam: " << endl
<< "Ansys file format does not provide information about the type of "
<< "the patch (eg. wall, symmetry plane, cyclic etc)." << endl
<< "All the patches have been created "
<< "as type patch. Please reset after mesh conversion as necessary."
<< endl;
wordList patchTypes(boundary.size(), polyPatch::typeName);
word defaultFacesName = "defaultFaces";
word defaultFacesType = emptyPolyPatch::typeName;
wordList patchPhysicalTypes(boundary.size());
preservePatchTypes
(
runTime,
runTime.constant(),
polyMesh::defaultRegion,
patchNames,
patchTypes,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
);
polyMesh pShapeMesh
(
IOobject
(
polyMesh::defaultRegion,
runTime.constant(),
runTime
),
points,
cellShapes,
boundary,
patchNames,
patchTypes,
defaultFacesName,
defaultFacesType,
patchPhysicalTypes
);
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
Info << "Writing polyMesh" << endl;
pShapeMesh.write();
Info<< nl << "end" << endl;
return 0;
}
/* ------------------------------------------------------------------------- *\
------ End of ansysToFoam.L
\* ------------------------------------------------------------------------- */