ENH: suppress surface Face-id field if writer manages that itself (#1600)

- for CAE formats such as abaqus, nastran, starcd, etc, the element id
  is already part of the output format itself. For these cases, there
  is no use in generating an additional "Ids" field.

ENH: add code to ignore negative face ids

- these will arise from very special cases, such as when a
  solid element and side are encoded into a single integer.

BUG: starcd surface values output did not use original face ids
This commit is contained in:
Mark Olesen 2020-09-08 09:17:35 +02:00
parent a001c0d2fa
commit a9bf69b551
10 changed files with 105 additions and 33 deletions

View File

@ -32,6 +32,7 @@ License
#include "mapPolyMesh.H"
#include "volFields.H"
#include "HashOps.H"
#include "ListOps.H"
#include "Time.H"
#include "UIndirectList.H"
#include "addToRunTimeSelectionTable.H"
@ -168,12 +169,18 @@ void Foam::sampledSurfaces::countFields()
forAll(*this, surfi)
{
const sampledSurface& s = (*this)[surfi];
surfaceWriter& outWriter = writers_[surfi];
writers_[surfi].nFields() =
outWriter.nFields() =
(
nVolumeFields
+ (s.withSurfaceFields() ? nSurfaceFields : 0)
+ ((s.hasFaceIds() && !s.interpolate()) ? 1 : 0)
+
(
// Face-id field, but not if the writer manages that itself
!s.interpolate() && s.hasFaceIds() && !outWriter.usesFaceIds()
? 1 : 0
)
);
}
}
@ -319,7 +326,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
const dictionary& surfDict = dEntry.dict();
autoPtr<sampledSurface> surf =
sampledSurface::New
sampledSurface::New
(
dEntry.keyword(),
mesh_,
@ -555,20 +562,29 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
outWriter.beginTime(obr_.time());
// Write original ids
if (s.hasFaceIds() && !s.interpolate())
// Face-id field, but not if the writer manages that itself
if (!s.interpolate() && s.hasFaceIds() && !outWriter.usesFaceIds())
{
// This is still quite horrible.
Field<label> ids(s.faceIds());
ids += label(1); // From 0-based to 1-based
writeSurface
if
(
outWriter,
ids,
"Ids"
);
returnReduce
(
!ListOps::found(ids, lessOp1<label>(0)),
andOp<bool>()
)
)
{
// From 0-based to 1-based, provided there are no
// negative ids (eg, encoded solid/side)
ids += label(1);
}
writeSurface(outWriter, ids, "Ids");
}
}
}

View File

@ -26,10 +26,10 @@ License
\*---------------------------------------------------------------------------*/
#include "ABAQUSsurfaceFormat.H"
#include "ListOps.H"
#include "IFstream.H"
#include "IOmanip.H"
#include "faceTraits.H"
#include "stringOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -267,13 +267,17 @@ void Foam::fileFormats::ABAQUSsurfaceFormat<Face>::write
const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
// Possible to use faceIds?
// - cannot if there are negative ids (eg, encoded solid/side)
bool useOrigFaceIds =
(!useFaceMap && elemIds.size() == faceLst.size());
(
!useFaceMap
&& elemIds.size() == faceLst.size()
&& !ListOps::found(elemIds, lessOp1<label>(0))
);
// Not possible with on-the-fly face decomposition
if (useOrigFaceIds)
{
// Not possible with on-the-fly face decomposition
for (const auto& f : faceLst)
{
if (f.size() > 4)

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "NASsurfaceFormat.H"
#include "ListOps.H"
#include "IFstream.H"
#include "IOmanip.H"
#include "faceTraits.H"
@ -458,13 +459,17 @@ void Foam::fileFormats::NASsurfaceFormat<Face>::write
const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
// Possible to use faceIds?
// - cannot if there are negative ids (eg, encoded solid/side)
bool useOrigFaceIds =
(!useFaceMap && elemIds.size() == faceLst.size());
(
!useFaceMap
&& elemIds.size() == faceLst.size()
&& !ListOps::found(elemIds, lessOp1<label>(0))
);
// Not possible with on-the-fly face decomposition
if (useOrigFaceIds)
{
// Not possible with on-the-fly face decomposition
for (const auto& f : faceLst)
{
if (f.size() > 4)

View File

@ -284,11 +284,12 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
// Possible to use faceIds?
// - cannot if there are negative ids (eg, encoded solid/side)
const bool useOrigFaceIds =
(
!useFaceMap
&& surf.useFaceIds()
&& elemIds.size() == faceLst.size()
&& !ListOps::found(elemIds, lessOp1<label>(0))
);

View File

@ -29,6 +29,7 @@ License
#include "nastranSurfaceWriter.H"
#include "Pair.H"
#include "IOmanip.H"
#include "ListOps.H"
#include "OSspecific.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"
@ -214,11 +215,15 @@ void Foam::surfaceWriters::nastranWriter::writeGeometry
const labelList& elemIds = surf.faceIds();
// Possible to use faceIds?
bool useOrigFaceIds = (elemIds.size() == faces.size());
bool useOrigFaceIds =
(
elemIds.size() == faces.size()
&& !ListOps::found(elemIds, lessOp1<label>(0))
);
// Not possible with on-the-fly face decomposition
if (useOrigFaceIds)
{
// Not possible with on-the-fly face decomposition
for (const auto& f : faces)
{
if (f.size() > 4)
@ -258,7 +263,6 @@ void Foam::surfaceWriters::nastranWriter::writeGeometry
if (useOrigFaceIds)
{
// When available and not decomposed
elemId = elemIds[facei];
}

View File

@ -254,6 +254,12 @@ public:
// Member Functions
//- Format uses faceIds as part of its output
virtual bool usesFaceIds() const // override
{
return true;
}
//- Write surface geometry to file.
virtual fileName write(); // override

View File

@ -28,6 +28,7 @@ License
#include "OFstream.H"
#include "IOmanip.H"
#include "ListOps.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -254,13 +255,13 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
// Regular (undecomposed) faces
const faceList& faces = surf.faces();
const labelList& elemIds = surf.faceIds();
const labelUList& elemIds = surf.faceIds();
// Possible to use faceIds?
// Not possible with on-the-fly face decomposition
const bool useOrigFaceIds =
(
elemIds.size() == faces.size()
&& !ListOps::found(elemIds, lessOp1<label>(0))
&& decompFaces.empty()
);
@ -273,7 +274,6 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
{
if (useOrigFaceIds)
{
// When available and not decomposed
elemId = elemIds[facei];
}
@ -324,7 +324,6 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
{
if (useOrigFaceIds)
{
// When available and not decomposed
elemId = elemIds[facei];
}

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "starcdSurfaceWriter.H"
#include "ListOps.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "MeshedSurfaceProxy.H"
@ -53,7 +54,7 @@ namespace Foam
template<class Type>
static inline void writeData(Ostream& os, const Type& val)
{
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; ++cmpt)
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; ++cmpt)
{
os << ' ' << component(val, cmpt);
}
@ -145,13 +146,23 @@ Foam::fileName Foam::surfaceWriters::starcdWriter::write()
mkDir(outputFile.path());
}
const labelUList& origFaceIds = surf.faceIds();
// Face ids (if possible)
const labelUList& elemIds =
(
!ListOps::found(origFaceIds, lessOp1<label>(0))
? origFaceIds
: labelUList::null()
);
MeshedSurfaceProxy<face>
(
surf.points(),
surf.faces(),
UList<surfZone>::null(), // one zone
labelUList::null(), // no faceMap
surf.faceIds() // with face ids (if possible)
elemIds // face ids
).write
(
outputFile,
@ -204,6 +215,8 @@ Foam::fileName Foam::surfaceWriters::starcdWriter::writeTemplate
// geometry merge() implicit
tmp<Field<Type>> tfield = mergeField(localValues);
const meshedSurf& surf = surface();
if (Pstream::master() || !parallel_)
{
const auto& values = tfield();
@ -215,16 +228,26 @@ Foam::fileName Foam::surfaceWriters::starcdWriter::writeTemplate
OFstream os(outputFile, streamOpt_);
// 1-based ids
label elemId = 1;
const labelUList& elemIds = surf.faceIds();
// Possible to use faceIds?
const bool useOrigFaceIds =
(
elemIds.size() == values.size()
&& !ListOps::found(elemIds, lessOp1<label>(0))
);
label faceIndex = 0;
// No header, just write values
for (const Type& val : values)
{
os << elemId;
writeData(os, val);
const label elemId =
(useOrigFaceIds ? elemIds[faceIndex] : faceIndex);
++elemId;
os << (elemId + 1); // 1-based ids
writeData(os, val);
++faceIndex;
}
}

View File

@ -159,6 +159,12 @@ public:
return true;
}
//- Format uses faceIds as part of its output
virtual bool usesFaceIds() const // override
{
return true;
}
//- Write surface geometry to file.
virtual fileName write(); // override

View File

@ -300,6 +300,14 @@ public:
return false;
}
//- True if the writer format uses faceIds as part of its output.
// Element ids are used by various CAE formats
// (abaqus, nastran, starcd, ...)
virtual bool usesFaceIds() const
{
return false;
}
// Bookkeeping