mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
triSurface Nastran reader: bugfix and enhancement
- handle long format (GRID*), even when fields are not separated by spaces - added support for Hypermesh "$HMNAME COMP" extension
This commit is contained in:
@ -23,10 +23,16 @@ License
|
|||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Nastran surface reader. Does Ansa $ANSA_NAME extension to get name
|
Nastran surface reader.
|
||||||
of patch. Handles Ansa coordinates like:
|
|
||||||
|
|
||||||
|
- Uses the Ansa "$ANSA_NAME" or the Hypermesh "$HMNAME COMP" extensions
|
||||||
|
to obtain patch names.
|
||||||
|
- Handles Nastran short and long formats, but not free format.
|
||||||
|
- Properly handles the Nastran compact floating point notation: \n
|
||||||
|
@verbatim
|
||||||
GRID 28 10.20269-.030265-2.358-8
|
GRID 28 10.20269-.030265-2.358-8
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -49,13 +55,13 @@ static scalar parseNASCoord(const string& s)
|
|||||||
if (expSign != string::npos && expSign > 0 && !isspace(s[expSign-1]))
|
if (expSign != string::npos && expSign > 0 && !isspace(s[expSign-1]))
|
||||||
{
|
{
|
||||||
scalar mantissa = readScalar(IStringStream(s.substr(0, expSign))());
|
scalar mantissa = readScalar(IStringStream(s.substr(0, expSign))());
|
||||||
scalar exp = readScalar(IStringStream(s.substr(expSign+1))());
|
scalar exponent = readScalar(IStringStream(s.substr(expSign+1))());
|
||||||
|
|
||||||
if (s[expSign] == '-')
|
if (s[expSign] == '-')
|
||||||
{
|
{
|
||||||
exp = -exp;
|
exponent = -exponent;
|
||||||
}
|
}
|
||||||
return mantissa*pow(10, exp);
|
return mantissa*pow(10, exponent);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -64,14 +70,14 @@ static scalar parseNASCoord(const string& s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool triSurface::readNAS(const fileName& OBJfileName)
|
bool triSurface::readNAS(const fileName& fName)
|
||||||
{
|
{
|
||||||
IFstream OBJfile(OBJfileName);
|
IFstream is(fName);
|
||||||
|
|
||||||
if (!OBJfile.good())
|
if (!is.good())
|
||||||
{
|
{
|
||||||
FatalErrorIn("triSurface::readNAS(const fileName&)")
|
FatalErrorIn("triSurface::readNAS(const fileName&)")
|
||||||
<< "Cannot read file " << OBJfileName
|
<< "Cannot read file " << fName
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,17 +96,17 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
// Ansa tags. Denoted by $ANSA_NAME. These will appear just before the
|
// Ansa tags. Denoted by $ANSA_NAME. These will appear just before the
|
||||||
// first use of a type. We read them and store the pshell types which
|
// first use of a type. We read them and store the pshell types which
|
||||||
// are used to name the patches.
|
// are used to name the patches.
|
||||||
label ansaID = -1;
|
label ansaId = -1;
|
||||||
word ansaType;
|
word ansaType;
|
||||||
string ansaName;
|
string ansaName;
|
||||||
|
|
||||||
// Done warnings per unrecognized command
|
// A single warning per unrecognized command
|
||||||
HashSet<word> unhandledCmd;
|
HashSet<word> unhandledCmd;
|
||||||
|
|
||||||
while (OBJfile.good())
|
while (is.good())
|
||||||
{
|
{
|
||||||
string line;
|
string line;
|
||||||
OBJfile.getLine(line);
|
is.getLine(line);
|
||||||
|
|
||||||
// Ansa extension
|
// Ansa extension
|
||||||
if (line.substr(0, 10) == "$ANSA_NAME")
|
if (line.substr(0, 10) == "$ANSA_NAME")
|
||||||
@ -116,14 +122,14 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
&& sem2 != string::npos
|
&& sem2 != string::npos
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ansaID = readLabel
|
ansaId = readLabel
|
||||||
(
|
(
|
||||||
IStringStream(line.substr(sem0+1, sem1-sem0-1))()
|
IStringStream(line.substr(sem0+1, sem1-sem0-1))()
|
||||||
);
|
);
|
||||||
ansaType = line.substr(sem1+1, sem2-sem1-1);
|
ansaType = line.substr(sem1+1, sem2-sem1-1);
|
||||||
|
|
||||||
string nameString;
|
string nameString;
|
||||||
OBJfile.getLine(ansaName);
|
is.getLine(ansaName);
|
||||||
if (ansaName[ansaName.size()-1] == '\r')
|
if (ansaName[ansaName.size()-1] == '\r')
|
||||||
{
|
{
|
||||||
ansaName = ansaName.substr(1, ansaName.size()-2);
|
ansaName = ansaName.substr(1, ansaName.size()-2);
|
||||||
@ -132,13 +138,37 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
{
|
{
|
||||||
ansaName = ansaName.substr(1, ansaName.size()-1);
|
ansaName = ansaName.substr(1, ansaName.size()-1);
|
||||||
}
|
}
|
||||||
//Pout<< "ANSA tag for NastranID:" << ansaID
|
|
||||||
// << " of type " << ansaType
|
// Info<< "ANSA tag for NastranID:" << ansaId
|
||||||
// << " name " << ansaName << endl;
|
// << " of type " << ansaType
|
||||||
|
// << " name " << ansaName << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Hypermesh extension
|
||||||
|
// $HMNAME COMP 1"partName"
|
||||||
|
if
|
||||||
|
(
|
||||||
|
line.substr(0, 12) == "$HMNAME COMP"
|
||||||
|
&& line.find ('"') != string::npos
|
||||||
|
)
|
||||||
|
{
|
||||||
|
label groupId = readLabel
|
||||||
|
(
|
||||||
|
IStringStream(line.substr(16, 16))()
|
||||||
|
);
|
||||||
|
|
||||||
|
IStringStream lineStream(line.substr(32));
|
||||||
|
|
||||||
|
string rawName;
|
||||||
|
lineStream >> rawName;
|
||||||
|
|
||||||
|
groupToName.insert(groupId, string::validate<word>(rawName));
|
||||||
|
Info<< "group " << groupId << " => " << rawName << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (line.size() == 0 || line[0] == '$')
|
if (line.size() == 0 || line[0] == '$')
|
||||||
{
|
{
|
||||||
// Skip empty or comment
|
// Skip empty or comment
|
||||||
@ -153,7 +183,7 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
string buf;
|
string buf;
|
||||||
OBJfile.getLine(buf);
|
is.getLine(buf);
|
||||||
|
|
||||||
if (buf.size() > 72 && buf[72]=='+')
|
if (buf.size() > 72 && buf[72]=='+')
|
||||||
{
|
{
|
||||||
@ -174,26 +204,21 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
|
|
||||||
if (cmd == "CTRIA3")
|
if (cmd == "CTRIA3")
|
||||||
{
|
{
|
||||||
//label index, group, a, b, c;
|
label groupId = readLabel(IStringStream(line.substr(16,8))());
|
||||||
//lineStream >> index >> group >> a >> b >> c;
|
|
||||||
label group = readLabel(IStringStream(line.substr(16,8))());
|
|
||||||
label a = readLabel(IStringStream(line.substr(24,8))());
|
label a = readLabel(IStringStream(line.substr(24,8))());
|
||||||
label b = readLabel(IStringStream(line.substr(32,8))());
|
label b = readLabel(IStringStream(line.substr(32,8))());
|
||||||
label c = readLabel(IStringStream(line.substr(40,8))());
|
label c = readLabel(IStringStream(line.substr(40,8))());
|
||||||
|
|
||||||
|
|
||||||
// Convert group into patch
|
// Convert group into patch
|
||||||
Map<label>::const_iterator iter = groupToPatch.find(group);
|
Map<label>::const_iterator iter = groupToPatch.find(groupId);
|
||||||
|
|
||||||
label patchI;
|
label patchI;
|
||||||
if (iter == groupToPatch.end())
|
if (iter == groupToPatch.end())
|
||||||
{
|
{
|
||||||
patchI = nPatches++;
|
patchI = nPatches++;
|
||||||
|
groupToPatch.insert(groupId, patchI);
|
||||||
Pout<< "Allocating Foam patch " << patchI
|
Info<< "patch " << patchI << " => group " << groupId << endl;
|
||||||
<< " for group " << group << endl;
|
|
||||||
|
|
||||||
groupToPatch.insert(group, patchI);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -204,26 +229,21 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
}
|
}
|
||||||
else if (cmd == "CQUAD4")
|
else if (cmd == "CQUAD4")
|
||||||
{
|
{
|
||||||
//label index, group, a, b, c, d;
|
label groupId = readLabel(IStringStream(line.substr(16,8))());
|
||||||
//lineStream >> index >> group >> a >> b >> c >> d;
|
|
||||||
label group = readLabel(IStringStream(line.substr(16,8))());
|
|
||||||
label a = readLabel(IStringStream(line.substr(24,8))());
|
label a = readLabel(IStringStream(line.substr(24,8))());
|
||||||
label b = readLabel(IStringStream(line.substr(32,8))());
|
label b = readLabel(IStringStream(line.substr(32,8))());
|
||||||
label c = readLabel(IStringStream(line.substr(40,8))());
|
label c = readLabel(IStringStream(line.substr(40,8))());
|
||||||
label d = readLabel(IStringStream(line.substr(48,8))());
|
label d = readLabel(IStringStream(line.substr(48,8))());
|
||||||
|
|
||||||
// Convert group into patch
|
// Convert group into patch
|
||||||
Map<label>::const_iterator iter = groupToPatch.find(group);
|
Map<label>::const_iterator iter = groupToPatch.find(groupId);
|
||||||
|
|
||||||
label patchI;
|
label patchI;
|
||||||
if (iter == groupToPatch.end())
|
if (iter == groupToPatch.end())
|
||||||
{
|
{
|
||||||
patchI = nPatches++;
|
patchI = nPatches++;
|
||||||
|
groupToPatch.insert(groupId, patchI);
|
||||||
Pout<< "Allocating Foam patch " << patchI
|
Info<< "patch " << patchI << " => group " << groupId << endl;
|
||||||
<< " for group " << group << endl;
|
|
||||||
|
|
||||||
groupToPatch.insert(group, patchI);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -235,66 +255,56 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
}
|
}
|
||||||
else if (cmd == "PSHELL")
|
else if (cmd == "PSHELL")
|
||||||
{
|
{
|
||||||
// Read shell type since gives patchnames.
|
// Read shell type since group gives patchnames
|
||||||
//label group;
|
label groupId = readLabel(IStringStream(line.substr(8,8))());
|
||||||
//lineStream >> group;
|
if (groupId == ansaId && ansaType == "PSHELL")
|
||||||
label group = readLabel(IStringStream(line.substr(8,8))());
|
|
||||||
|
|
||||||
if (group == ansaID && ansaType == "PSHELL")
|
|
||||||
{
|
{
|
||||||
Pout<< "Found name " << ansaName << " for group "
|
groupToName.insert(groupId, string::validate<word>(ansaName));
|
||||||
<< group << endl;
|
Info<< "group " << groupId << " => " << ansaName << endl;
|
||||||
groupToName.insert(group, string::validate<word>(ansaName));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cmd == "GRID")
|
else if (cmd == "GRID")
|
||||||
{
|
{
|
||||||
//label index;
|
|
||||||
//lineStream >> index;
|
|
||||||
label index = readLabel(IStringStream(line.substr(8,8))());
|
label index = readLabel(IStringStream(line.substr(8,8))());
|
||||||
indices.append(index);
|
|
||||||
|
|
||||||
scalar x = parseNASCoord(line.substr(24, 8));
|
scalar x = parseNASCoord(line.substr(24, 8));
|
||||||
scalar y = parseNASCoord(line.substr(32, 8));
|
scalar y = parseNASCoord(line.substr(32, 8));
|
||||||
scalar z = parseNASCoord(line.substr(40, 8));
|
scalar z = parseNASCoord(line.substr(40, 8));
|
||||||
|
|
||||||
|
indices.append(index);
|
||||||
points.append(point(x, y, z));
|
points.append(point(x, y, z));
|
||||||
}
|
}
|
||||||
else if (cmd == "GRID*")
|
else if (cmd == "GRID*")
|
||||||
{
|
{
|
||||||
// Assume on two lines with '*' continuation symbol on start of
|
// Long format is on two lines with '*' continuation symbol
|
||||||
// second line. (comes out of Tgrid. Typical line (spaces truncated)
|
// on start of second line.
|
||||||
|
// Typical line (spaces compacted)
|
||||||
// GRID* 126 0 -5.55999875E+02 -5.68730474E+02
|
// GRID* 126 0 -5.55999875E+02 -5.68730474E+02
|
||||||
// * 2.14897901E+02
|
// * 2.14897901E+02
|
||||||
string line2;
|
|
||||||
OBJfile.getLine(line2);
|
label index = readLabel(IStringStream(line.substr(8,16))());
|
||||||
if (line2[0] != '*')
|
scalar x = parseNASCoord(line.substr(40, 16));
|
||||||
|
scalar y = parseNASCoord(line.substr(56, 16));
|
||||||
|
|
||||||
|
is.getLine(line);
|
||||||
|
if (line[0] != '*')
|
||||||
{
|
{
|
||||||
FatalErrorIn("triSurface::readNAS(const fileName&)")
|
FatalErrorIn("triSurface::readNAS(const fileName&)")
|
||||||
<< "Expected continuation symbol '*' when reading GRID*"
|
<< "Expected continuation symbol '*' when reading GRID*"
|
||||||
<< " (double precision coordinate) output by Tgrid" << nl
|
<< " (double precision coordinate) output" << nl
|
||||||
<< "Read:" << line2 << nl
|
<< "Read:" << line << nl
|
||||||
<< "File:" << OBJfile.name()
|
<< "File:" << is.name()
|
||||||
<< " line:" << OBJfile.lineNumber()
|
<< " line:" << is.lineNumber()
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
IStringStream lineStream(line.substr(10) + line2.substr(1));
|
scalar z = parseNASCoord(line.substr(8, 16));
|
||||||
|
|
||||||
label index;
|
|
||||||
lineStream >> index;
|
|
||||||
indices.append(index);
|
indices.append(index);
|
||||||
|
|
||||||
readScalar(lineStream); // What is this field?
|
|
||||||
scalar x = readScalar(lineStream);
|
|
||||||
scalar y = readScalar(lineStream);
|
|
||||||
scalar z = readScalar(lineStream);
|
|
||||||
points.append(point(x, y, z));
|
points.append(point(x, y, z));
|
||||||
}
|
}
|
||||||
else if (unhandledCmd.insert(cmd))
|
else if (unhandledCmd.insert(cmd))
|
||||||
{
|
{
|
||||||
Info<< "Unhandled Nastran command " << line << nl
|
Info<< "Unhandled Nastran command " << line << nl
|
||||||
<< "File:" << OBJfile.name()
|
<< "File:" << is.name() << " line:" << is.lineNumber() << endl;
|
||||||
<< " line:" << OBJfile.lineNumber()
|
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +313,7 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
faces.shrink();
|
faces.shrink();
|
||||||
|
|
||||||
|
|
||||||
Pout<< "Read triangles:" << faces.size() << " points:" << points.size()
|
Info<< "Read triangles:" << faces.size() << " points:" << points.size()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -314,7 +324,7 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
indexToPoint.insert(indices[i], i);
|
indexToPoint.insert(indices[i], i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relabel triangles
|
// Relabel faces
|
||||||
forAll(faces, i)
|
forAll(faces, i)
|
||||||
{
|
{
|
||||||
labelledTri& f = faces[i];
|
labelledTri& f = faces[i];
|
||||||
@ -341,7 +351,7 @@ bool triSurface::readNAS(const fileName& OBJfileName)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pout<< "patches:" << patches << endl;
|
Info<< "patches:" << patches << endl;
|
||||||
|
|
||||||
|
|
||||||
// Transfer DynamicLists to straight ones.
|
// Transfer DynamicLists to straight ones.
|
||||||
|
|||||||
Reference in New Issue
Block a user