Commit 0a1cd580 authored by Mark Olesen's avatar Mark Olesen

ENH: improvements for nastran surface writer

- select default nastran PLOAD2 or PLOAD4 based on field type.
  Default to PLOAD2 for scalar types and PLOAD4 for vectors etc.

- relocate nastran SHELL/MAT cards.
  Previously wrote at the end of the file, now emit when writing the
  geometry itself. This improves modularity (of code and files)

- initial support for common geometry file for nastran
parent 7d203443
......@@ -303,15 +303,12 @@ void Foam::surfaceWriters::nastranWriter::writeGeometry
// The end offset, which is the next begin offset
decompOffsets[facei+1] = decompFaces.size();
}
}
Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFooter
(
Ostream& os,
const meshedSurf& surf
) const
{
//
// SHELL/MAT information
//
// Zone id have been used for the PID. Find unique values.
labelList pidsUsed = labelHashSet(surf.zoneIds()).sortedToc();
......@@ -339,7 +336,7 @@ Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFooter
const label MID = 1;
writeKeyword(os, "MAT1") << separator_;
writeKeyword(os, "MAT1") << separator_;
writeValue(os, MID);
for (label i = 0; i < 7; ++i)
......@@ -349,8 +346,6 @@ Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFooter
writeValue(os, "");
}
os << nl;
return os;
}
......@@ -361,6 +356,7 @@ Foam::surfaceWriters::nastranWriter::nastranWriter()
surfaceWriter(),
writeFormat_(fieldFormat::SHORT),
fieldMap_(),
commonGeometry_(false),
geometryScale_(1),
fieldScale_(),
separator_()
......@@ -383,6 +379,7 @@ Foam::surfaceWriters::nastranWriter::nastranWriter
)
),
fieldMap_(),
commonGeometry_(options.getOrDefault("commonGeometry", false)),
geometryScale_(options.getOrDefault<scalar>("scale", 1)),
fieldScale_(options.subOrEmptyDict("fieldScale")),
separator_()
......@@ -470,9 +467,7 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::write()
OFstream os(outputFile);
fileFormats::NASCore::setPrecision(os, writeFormat_);
os << "TITLE=OpenFOAM " << outputPath_.name()
<< " mesh" << nl
<< '$' << nl
os << "TITLE=OpenFOAM " << outputPath_.name() << " geometry" << nl
<< "BEGIN BULK" << nl;
labelList decompOffsets;
......@@ -480,8 +475,7 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::write()
writeGeometry(os, surf, decompOffsets, decompFaces);
writeFooter(os, surf)
<< "ENDDATA" << nl;
os << "ENDDATA" << nl;
}
wroteGeom_ = true;
......
......@@ -33,10 +33,11 @@ Description
The formatOptions for nastran:
\table
Property | Description | Required | Default
fields | field pairs for PLOAD2, PLOAD4 | yes |
fields | field pairs for PLOAD2/PLOAD4 | yes |
format | short / long / free | no | long
scale | output geometry scaling | no | 1
fieldScale | output field scaling (dictionary) | no | empty
commonGeometry | use separate geometry files | no | false
\endtable
For example,
......@@ -45,7 +46,7 @@ Description
{
nastran
{
// OpenFOAM field name to NASTRAN field name
// OpenFOAM field name to NASTRAN load types
fields
(
(pMean PLOAD2)
......@@ -71,7 +72,7 @@ Description
\subheading Geometry
\verbatim
rootdir
`-- timeName
`-- <time>
|-- surfaceName0.{nas}
`-- surfaceName1.{nas}
\endverbatim
......@@ -79,17 +80,18 @@ Description
\subheading Fields
\verbatim
rootdir
`-- timeName
`-- <time>
`-- field0
| |-- surfaceName0.{nas}
| `-- surfaceName1.{nas}
| |-- surfaceName0.{bdf}
| `-- surfaceName1.{bdf}
`-- field1
|-- surfaceName0.{nas}
`-- surfaceName1.{nas}
|-- surfaceName0.{bdf}
`-- surfaceName1.{bdf}
\endverbatim
Note
Output variable scaling does not apply to integer types such as Ids.
Field pairs default to PLOAD2 for scalars and PLOAD4 for vectors etc.
SourceFiles
nastranSurfaceWriter.C
......@@ -138,6 +140,9 @@ private:
//- Mapping from field name to data format enumeration
HashTable<loadFormat> fieldMap_;
//- Use common geometry file
bool commonGeometry_;
//- Output geometry scaling
const scalar geometryScale_;
......@@ -169,6 +174,7 @@ private:
) const;
//- Write the surface mesh geometry, tracking face decomposition
// Includes SHELL/MAT information
//
// \param decompOffsets begin/end offsets (size+1) into decompFaces
// \param decompFaces Non tri/quad decomposed into triangles
......@@ -187,9 +193,6 @@ private:
const word& keyword
) const;
//- Write the footer information
Ostream& writeFooter(Ostream& os, const meshedSurf& surf) const;
//- Write a formatted value to the output stream
template<class Type>
Ostream& writeValue(Ostream& os, const Type& value) const;
......
......@@ -145,22 +145,59 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
const Field<Type>& localValues
)
{
// Geometry changed since last output? Capture now before any merging.
/// const bool geomChanged = (!upToDate_);
// Separate geometry, when commonGeometry = true
if (!wroteGeom_ && commonGeometry_)
{
write();
}
checkOpen();
if (!fieldMap_.found(fieldName))
const loadFormat format
(
fieldMap_.lookup
(
fieldName,
// Default format
(
pTraits<Type>::nComponents == 1
? loadFormat::PLOAD2
: loadFormat::PLOAD4
)
)
);
if
(
!std::is_integral<Type>::value // Handle 'Ids' etc silently
&& !fieldMap_.empty()
&& !fieldMap_.found(fieldName)
)
{
FatalErrorInFunction
WarningInFunction
<< "No mapping found between field " << fieldName
<< " and corresponding Nastran field. Available types are:"
<< fieldMap_
<< exit(FatalError);
<< " and corresponding Nastran field. Available types:"
<< fieldMap_ << nl;
}
return fileName::null;
// Emit any common warnings
if (format == loadFormat::PLOAD2 && pTraits<Type>::nComponents != 1)
{
WarningInFunction
<< fileFormats::NASCore::loadFormatNames[format]
<< " cannot be used for higher rank values"
<< " - reverting to mag()" << endl;
}
const loadFormat format(fieldMap_[fieldName]);
// Field: rootdir/<TIME>/field/surfaceName.nas
// Common geometry
// Field: rootdir/<TIME>/<field>_surfaceName.bdf
// Embedded geometry
// Field: rootdir/<TIME>/<field>/surfaceName.bdf
fileName outputFile = outputPath_.path();
if (useTimeDir() && !timeName().empty())
......@@ -168,8 +205,23 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
// Splice in time-directory
outputFile /= timeName();
}
outputFile /= fieldName / outputPath_.name();
outputFile.ext("nas");
fileName geomFileName;
if (commonGeometry_)
{
// Common geometry
geomFileName = outputPath_.name().ext("nas");
// Append <field>_surfaceName.bdf
outputFile /= fieldName + '_' + outputPath_.name();
}
else
{
// Embedded geometry
// Use sub-directory
outputFile /= fieldName / outputPath_.name();
}
outputFile.ext("bdf");
// Output scaling for the variable, but not for integer types.
......@@ -193,16 +245,6 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
}
// Emit any common warnings
if (format == loadFormat::PLOAD2 && pTraits<Type>::nComponents != 1)
{
WarningInFunction
<< fileFormats::NASCore::loadFormatNames[format]
<< " cannot be used for higher rank values"
<< " - reverting to mag()" << endl;
}
// Implicit geometry merge()
tmp<Field<Type>> tfield = mergeField(localValues) * varScale;
......@@ -224,8 +266,6 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
DynamicList<face> decompFaces;
// Could handle separate geometry here
OFstream os(outputFile);
fileFormats::NASCore::setPrecision(os, writeFormat_);
......@@ -238,17 +278,31 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
<< "$ TIME " << timeName() << nl;
}
os << '$' << nl
<< "TIME " << timeValue << nl
<< '$' << nl
os << "TIME " << timeValue << nl
<< nl
<< "BEGIN BULK" << nl;
writeGeometry(os, surf, decompOffsets, decompFaces);
if (commonGeometry_)
{
os << "INCLUDE '" << geomFileName.c_str() << "'" << nl;
// Geometry already written (or suppressed)
// - still need decomposition information
fileFormats::NASCore::faceDecomposition
(
surf.points(),
surf.faces(),
decompOffsets,
decompFaces
);
}
else
{
// Write geometry
writeGeometry(os, surf, decompOffsets, decompFaces);
}
// Write field
os << '$' << nl
<< "$ Field data" << nl
<< '$' << nl;
......@@ -345,8 +399,7 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
}
}
writeFooter(os, surf)
<< "ENDDATA" << endl;
os << "ENDDATA" << endl;
}
wroteGeom_ = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment