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 "mapPolyMesh.H"
#include "volFields.H" #include "volFields.H"
#include "HashOps.H" #include "HashOps.H"
#include "ListOps.H"
#include "Time.H" #include "Time.H"
#include "UIndirectList.H" #include "UIndirectList.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
@ -168,12 +169,18 @@ void Foam::sampledSurfaces::countFields()
forAll(*this, surfi) forAll(*this, surfi)
{ {
const sampledSurface& s = (*this)[surfi]; const sampledSurface& s = (*this)[surfi];
surfaceWriter& outWriter = writers_[surfi];
writers_[surfi].nFields() = outWriter.nFields() =
( (
nVolumeFields nVolumeFields
+ (s.withSurfaceFields() ? nSurfaceFields : 0) + (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(); const dictionary& surfDict = dEntry.dict();
autoPtr<sampledSurface> surf = autoPtr<sampledSurface> surf =
sampledSurface::New sampledSurface::New
( (
dEntry.keyword(), dEntry.keyword(),
mesh_, mesh_,
@ -555,20 +562,29 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
outWriter.beginTime(obr_.time()); outWriter.beginTime(obr_.time());
// Write original ids // Face-id field, but not if the writer manages that itself
if (s.hasFaceIds() && !s.interpolate()) if (!s.interpolate() && s.hasFaceIds() && !outWriter.usesFaceIds())
{ {
// This is still quite horrible. // This is still quite horrible.
Field<label> ids(s.faceIds()); Field<label> ids(s.faceIds());
ids += label(1); // From 0-based to 1-based
writeSurface if
( (
outWriter, returnReduce
ids, (
"Ids" !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 "ABAQUSsurfaceFormat.H"
#include "ListOps.H"
#include "IFstream.H" #include "IFstream.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "faceTraits.H" #include "faceTraits.H"
#include "stringOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -267,13 +267,17 @@ void Foam::fileFormats::ABAQUSsurfaceFormat<Face>::write
const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1); const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
// Possible to use faceIds? // Possible to use faceIds?
// - cannot if there are negative ids (eg, encoded solid/side)
bool useOrigFaceIds = 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) if (useOrigFaceIds)
{ {
// Not possible with on-the-fly face decomposition
for (const auto& f : faceLst) for (const auto& f : faceLst)
{ {
if (f.size() > 4) if (f.size() > 4)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -300,6 +300,14 @@ public:
return false; 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 // Bookkeeping