diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C index 3779ff20d3c396679e015bf4d922a478330b1aa7..48b65330f9e093dd2a119ced4c10b9f292529fa7 100644 --- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C +++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C @@ -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"); } } } diff --git a/src/surfMesh/surfaceFormats/abaqus/ABAQUSsurfaceFormat.C b/src/surfMesh/surfaceFormats/abaqus/ABAQUSsurfaceFormat.C index 810fb2c17968cf5cfcf15a8aa06629e439cb25af..72ebcfc65e22452b43cec5d370a70f06ff335091 100644 --- a/src/surfMesh/surfaceFormats/abaqus/ABAQUSsurfaceFormat.C +++ b/src/surfMesh/surfaceFormats/abaqus/ABAQUSsurfaceFormat.C @@ -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) diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C index b76b3562e7a0d5a39f4bb78ee63119e76aadcab3..ad4e03eab61ddd369f2ce7a5eab087f2518bc959 100644 --- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C +++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C @@ -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) diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C index d1db77d26f7601b64d697dba228e6bf372241c8b..3914fa32566d3a11a6bae213da508e6268b85cf7 100644 --- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C +++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C @@ -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)) ); diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C index c5c4dfbb2d270ce9803cecfb76e0cfd6b0d73811..5f377ab46b89a252117eafe2b702a6ab1d52cc74 100644 --- a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C @@ -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]; } diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.H b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H index a56169167bedfef3e549d2a9aee33f4d2b055fb6..c22c082cb97a385c96086d024d9a46deb8024949 100644 --- a/src/surfMesh/writers/nastran/nastranSurfaceWriter.H +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H @@ -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 diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C index bcffc522e3047040ca55c6e4804143a9f401267c..a417f374c2599a69e5bc570ed58faf561f8ab6df 100644 --- a/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C @@ -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]; } diff --git a/src/surfMesh/writers/starcd/starcdSurfaceWriter.C b/src/surfMesh/writers/starcd/starcdSurfaceWriter.C index 0aa30d2a81171078ceb3518f63f223fb466f1c28..b036e14d284a6c4b312a94b1af536a0253dda317 100644 --- a/src/surfMesh/writers/starcd/starcdSurfaceWriter.C +++ b/src/surfMesh/writers/starcd/starcdSurfaceWriter.C @@ -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; } } diff --git a/src/surfMesh/writers/starcd/starcdSurfaceWriter.H b/src/surfMesh/writers/starcd/starcdSurfaceWriter.H index 4e3b525029895e4bb1fdbfe7a58c9faf3fcc63b8..0955d210370b512b6ca18310d8bbb534e141745c 100644 --- a/src/surfMesh/writers/starcd/starcdSurfaceWriter.H +++ b/src/surfMesh/writers/starcd/starcdSurfaceWriter.H @@ -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 diff --git a/src/surfMesh/writers/surfaceWriter.H b/src/surfMesh/writers/surfaceWriter.H index 7813347d3be287c8cfa249da857f66ed55470cbf..c1142e88b86352f2705ea189c8ca8262d1e580e9 100644 --- a/src/surfMesh/writers/surfaceWriter.H +++ b/src/surfMesh/writers/surfaceWriter.H @@ -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