diff --git a/src/conversion/ensight/output/ensightOutputAreaField.H b/src/conversion/ensight/output/ensightOutputAreaField.H new file mode 100644 index 0000000000..37618cca6d --- /dev/null +++ b/src/conversion/ensight/output/ensightOutputAreaField.H @@ -0,0 +1,79 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +InNamespace + Foam::ensightOutput + +Description + A collection of functions for writing areaField content in ensight format. + +\*---------------------------------------------------------------------------*/ + +#ifndef ensightOutputAreaField_H +#define ensightOutputAreaField_H + +#include "ensightOutput.H" +#include "ensightFaces.H" +#include "areaFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward Declarations +class ensightFaMesh; + +namespace ensightOutput +{ + +/*---------------------------------------------------------------------------*\ + Namespace ensightOutput +\*---------------------------------------------------------------------------*/ + +//- Write finite-area field component-wise +template +bool writeAreaField +( + ensightFile& os, + const GeometricField& fld, + const ensightFaMesh& ensMesh +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace ensightOutput +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "ensightOutputAreaFieldTemplates.C" +#endif + +#endif + +// ************************************************************************* // diff --git a/src/conversion/ensight/output/ensightOutputAreaFieldTemplates.C b/src/conversion/ensight/output/ensightOutputAreaFieldTemplates.C new file mode 100644 index 0000000000..aaccbd3cc2 --- /dev/null +++ b/src/conversion/ensight/output/ensightOutputAreaFieldTemplates.C @@ -0,0 +1,59 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "ensightOutputAreaField.H" +#include "ensightFaMesh.H" +#include "areaFaMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template +bool Foam::ensightOutput::writeAreaField +( + ensightFile& os, + const GeometricField& fld, + const ensightFaMesh& ensMesh +) +{ + bool parallel = Pstream::parRun(); + + // Write area part(s) + { + ensightOutput::Detail::writeFaceLocalField + ( + os, + fld, + ensMesh.areaPart(), + parallel + ); + } + + return true; +} + + +// ************************************************************************* // diff --git a/src/fileFormats/ensight/mesh/ensightMesh.H b/src/fileFormats/ensight/mesh/ensightMesh.H index f85dddb5bf..6c0427f977 100644 --- a/src/fileFormats/ensight/mesh/ensightMesh.H +++ b/src/fileFormats/ensight/mesh/ensightMesh.H @@ -146,7 +146,10 @@ public: // Access //- Reference to the underlying polyMesh - inline const polyMesh& mesh() const; + const polyMesh& mesh() const noexcept + { + return mesh_; + } //- Reference to the writer/mesh options inline const ensightMesh::options& option() const; @@ -154,30 +157,42 @@ public: //- Face elements per selected patch, lookup by patch index // Process in sorted order. // May require special treatment for zone -1 (internal). - inline const Map& cellZoneParts() const; + const Map& cellZoneParts() const noexcept + { + return cellZoneParts_; + } //- Face elements per faceZone, lookup by zone index. // Process in sorted order. - inline const Map& faceZoneParts() const; + const Map& faceZoneParts() const noexcept + { + return faceZoneParts_; + } //- Face elements per selected patch, lookup by patch index // Process in sorted order. - inline const Map& boundaryParts() const; + const Map& boundaryParts() const noexcept + { + return boundaryParts_; + } // Sizing Information //- Any parts? - inline bool empty() const; + inline bool empty() const noexcept; //- Number of parts - inline label size() const; + inline label size() const noexcept; // Other //- Does the content need an update? - inline bool needsUpdate() const; + bool needsUpdate() const noexcept + { + return needsUpdate_; + } //- Mark as needing an update. // May also free up unneeded data. @@ -191,16 +206,16 @@ public: // Output //- Write geometry to file. Normally in parallel - inline void write + void write ( - autoPtr& os, + ensightGeoFile& os, bool parallel = Pstream::parRun() ) const; //- Write geometry to file. Normally in parallel - void write + inline void write ( - ensightGeoFile& os, + autoPtr& os, bool parallel = Pstream::parRun() ) const; }; @@ -252,32 +267,44 @@ public: // Access - //- Lazy creation? (ie, ensightMesh starts as needsUpdate) - bool lazy() const; + //- Lazy creation? (ie, starts as needsUpdate) + bool lazy() const noexcept; //- Using internal? - bool useInternalMesh() const; + bool useInternalMesh() const noexcept; //- Using boundary? - bool useBoundaryMesh() const; + bool useBoundaryMesh() const noexcept; //- Using faceZones? - bool useFaceZones() const; + bool useFaceZones() const noexcept; //- Using cellZones? - bool useCellZones() const; + bool useCellZones() const noexcept; //- Selection of patches. Empty if unspecified. - const wordRes& patchSelection() const; + const wordRes& patchSelection() const noexcept + { + return patchInclude_; + } //- Selection of black listed patches. Empty if unspecified. - const wordRes& patchExclude() const; + const wordRes& patchExclude() const noexcept + { + return patchExclude_; + } //- Selection of faceZones. Empty if unspecified. - const wordRes& faceZoneSelection() const; + const wordRes& faceZoneSelection() const noexcept + { + return faceZoneInclude_; + } //- Selection of faceZones. Empty if unspecified. - const wordRes& cellZoneSelection() const; + const wordRes& cellZoneSelection() const noexcept + { + return cellZoneInclude_; + } // Edit @@ -286,16 +313,20 @@ public: void reset(); //- Lazy creation - ensightMesh starts as needsUpdate - void lazy(bool beLazy); + // \return old value + bool lazy(bool on) noexcept; //- Alter the useBoundaryMesh state - void useInternalMesh(bool on); + // \return old value + bool useInternalMesh(bool on) noexcept; //- Alter the useBoundaryMesh state - void useBoundaryMesh(bool on); + // \return old value + bool useBoundaryMesh(bool on); //- Alter the useCellZones state - void useCellZones(bool on); + // \return old value + bool useCellZones(bool on); //- Define patch selection matcher void patchSelection(const UList& patterns); diff --git a/src/fileFormats/ensight/mesh/ensightMeshI.H b/src/fileFormats/ensight/mesh/ensightMeshI.H index a9cdbfbc73..ed8499fd54 100644 --- a/src/fileFormats/ensight/mesh/ensightMeshI.H +++ b/src/fileFormats/ensight/mesh/ensightMeshI.H @@ -27,39 +27,12 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -inline const Foam::polyMesh& Foam::ensightMesh::mesh() const -{ - return mesh_; -} - - inline const Foam::ensightMesh::options& Foam::ensightMesh::option() const { return *options_; } -inline const Foam::Map& -Foam::ensightMesh::cellZoneParts() const -{ - return cellZoneParts_; -} - - -inline const Foam::Map& -Foam::ensightMesh::faceZoneParts() const -{ - return faceZoneParts_; -} - - -inline const Foam::Map& -Foam::ensightMesh::boundaryParts() const -{ - return boundaryParts_; -} - - inline bool Foam::ensightMesh::expire() { clear(); @@ -75,13 +48,7 @@ inline bool Foam::ensightMesh::expire() } -inline bool Foam::ensightMesh::needsUpdate() const -{ - return needsUpdate_; -} - - -inline bool Foam::ensightMesh::empty() const +inline bool Foam::ensightMesh::empty() const noexcept { return ( @@ -92,7 +59,7 @@ inline bool Foam::ensightMesh::empty() const } -inline Foam::label Foam::ensightMesh::size() const +inline Foam::label Foam::ensightMesh::size() const noexcept { return ( diff --git a/src/fileFormats/ensight/mesh/ensightMeshOptions.C b/src/fileFormats/ensight/mesh/ensightMeshOptions.C index 831d076897..333ce8602a 100644 --- a/src/fileFormats/ensight/mesh/ensightMeshOptions.C +++ b/src/fileFormats/ensight/mesh/ensightMeshOptions.C @@ -43,9 +43,9 @@ static Ostream& printPatterns(Ostream& os, const wordRes& list) for (const wordRe& item : list) { if (sep) os << token::SPACE; - os << item; - sep = true; + + os << item; } os << token::END_LIST; @@ -72,31 +72,31 @@ Foam::ensightMesh::options::options() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -bool Foam::ensightMesh::options::lazy() const +bool Foam::ensightMesh::options::lazy() const noexcept { return lazy_; } -bool Foam::ensightMesh::options::useInternalMesh() const +bool Foam::ensightMesh::options::useInternalMesh() const noexcept { return internal_; } -bool Foam::ensightMesh::options::useBoundaryMesh() const +bool Foam::ensightMesh::options::useBoundaryMesh() const noexcept { return boundary_; } -bool Foam::ensightMesh::options::useCellZones() const +bool Foam::ensightMesh::options::useCellZones() const noexcept { return cellZones_; } -bool Foam::ensightMesh::options::useFaceZones() const +bool Foam::ensightMesh::options::useFaceZones() const noexcept { return faceZoneInclude_.size(); } @@ -114,20 +114,25 @@ void Foam::ensightMesh::options::reset() } -void Foam::ensightMesh::options::lazy(bool beLazy) +bool Foam::ensightMesh::options::lazy(bool on) noexcept { - lazy_ = beLazy; + bool old(lazy_); + lazy_ = on; + return old; } -void Foam::ensightMesh::options::useInternalMesh(bool on) +bool Foam::ensightMesh::options::useInternalMesh(bool on) noexcept { + bool old(internal_); internal_ = on; + return old; } -void Foam::ensightMesh::options::useBoundaryMesh(bool on) +bool Foam::ensightMesh::options::useBoundaryMesh(bool on) { + bool old(boundary_); boundary_ = on; if (!boundary_) @@ -141,11 +146,14 @@ void Foam::ensightMesh::options::useBoundaryMesh(bool on) << endl; } } + + return old; } -void Foam::ensightMesh::options::useCellZones(bool on) +bool Foam::ensightMesh::options::useCellZones(bool on) { + bool old(cellZones_); cellZones_ = on; if (!cellZones_ && cellZoneInclude_.size()) @@ -156,6 +164,8 @@ void Foam::ensightMesh::options::useCellZones(bool on) << "Deactivating cellZones, removed old zone selection" << endl; } + + return old; } @@ -267,30 +277,6 @@ void Foam::ensightMesh::options::cellZoneSelection } -const Foam::wordRes& Foam::ensightMesh::options::patchSelection() const -{ - return patchInclude_; -} - - -const Foam::wordRes& Foam::ensightMesh::options::patchExclude() const -{ - return patchExclude_; -} - - -const Foam::wordRes& Foam::ensightMesh::options::faceZoneSelection() const -{ - return faceZoneInclude_; -} - - -const Foam::wordRes& Foam::ensightMesh::options::cellZoneSelection() const -{ - return cellZoneInclude_; -} - - void Foam::ensightMesh::options::print(Ostream& os) const { os << "internal: " << Switch::name(internal_) << nl; diff --git a/src/fileFormats/ensight/output/ensightOutput.H b/src/fileFormats/ensight/output/ensightOutput.H index 4a2f77dcbf..fefe06a535 100644 --- a/src/fileFormats/ensight/output/ensightOutput.H +++ b/src/fileFormats/ensight/output/ensightOutput.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -307,6 +307,18 @@ bool writeFaceSubField ); +//- Write a field of faces values as an indirect list, +//- using the face order from ensightFaces +template +bool writeFaceLocalField +( + ensightFile& os, + const Field& fld, + const ensightFaces& part, + bool parallel //!< Collective write? +); + + } // End namespace Detail diff --git a/src/fileFormats/ensight/output/ensightOutputTemplates.C b/src/fileFormats/ensight/output/ensightOutputTemplates.C index 00f5ab4d23..3c408d6fc2 100644 --- a/src/fileFormats/ensight/output/ensightOutputTemplates.C +++ b/src/fileFormats/ensight/output/ensightOutputTemplates.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -236,8 +236,6 @@ bool Foam::ensightOutput::Detail::writeFaceSubField os.beginPart(part.index()); } - labelList localAddr; - for (int typei=0; typei < ensightFaces::nTypes; ++typei) { const auto etype = ensightFaces::elemType(typei); @@ -255,6 +253,71 @@ bool Foam::ensightOutput::Detail::writeFaceSubField } +template +bool Foam::ensightOutput::Detail::writeFaceLocalField +( + ensightFile& os, + const Field& fld, + const ensightFaces& part, + bool parallel +) +{ + parallel = parallel && Pstream::parRun(); + + // Preliminary checks: total() contains pre-reduced information + { + // No geometry + if (parallel ? !part.total() : !part.size()) return false; + + bool hasField = !fld.empty(); + + if (parallel) + { + reduce(hasField, orOp()); + } + + // No field + if (!hasField) return false; + } + + bool validAddressing = (part.size() == part.faceOrder().size()); + + if (parallel) + { + reduce(validAddressing, orOp()); + } + + if (!validAddressing) + { + FatalErrorInFunction + << "Called without faceOrder having been set" << nl + << exit(FatalError); + } + + if (Pstream::master()) + { + os.beginPart(part.index()); + } + + for (int typei=0; typei < ensightFaces::nTypes; ++typei) + { + const auto etype = ensightFaces::elemType(typei); + + ensightOutput::Detail::writeFieldComponents + ( + os, + ensightFaces::key(etype), + UIndirectList(fld, part.faceOrder(etype)), + parallel + ); + } + + return true; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + template bool Foam::ensightOutput::writeField ( diff --git a/src/fileFormats/ensight/part/cells/ensightCells.C b/src/fileFormats/ensight/part/cells/ensightCells.C index 4cc92045e8..2aca01bd25 100644 --- a/src/fileFormats/ensight/part/cells/ensightCells.C +++ b/src/fileFormats/ensight/part/cells/ensightCells.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -39,7 +39,9 @@ namespace Foam } const char* Foam::ensightCells::elemNames[5] = - { "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" }; +{ + "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" +}; static_assert ( @@ -106,12 +108,12 @@ Foam::FixedList Foam::ensightCells::sizes() const Foam::label Foam::ensightCells::total() const { - label n = 0; + label nTotal = 0; forAll(sizes_, typei) { - n += sizes_[typei]; + nTotal += sizes_[typei]; } - return n; + return nTotal; } diff --git a/src/fileFormats/ensight/part/cells/ensightCells.H b/src/fileFormats/ensight/part/cells/ensightCells.H index ee5c1ea7cf..e24e712ad5 100644 --- a/src/fileFormats/ensight/part/cells/ensightCells.H +++ b/src/fileFormats/ensight/part/cells/ensightCells.H @@ -99,7 +99,8 @@ private: // Private Member Functions //- Low-level internal addition routine - inline void add(const elemType etype, label id); + // \return insertion locaion + inline label add(const elemType etype, label id); //- Use temporarily stored sizes to redimension the element lists void resizeAll(); diff --git a/src/fileFormats/ensight/part/cells/ensightCellsI.H b/src/fileFormats/ensight/part/cells/ensightCellsI.H index cfccab8eed..58e80324f3 100644 --- a/src/fileFormats/ensight/part/cells/ensightCellsI.H +++ b/src/fileFormats/ensight/part/cells/ensightCellsI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,12 +27,14 @@ License // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -inline void Foam::ensightCells::add(const elemType etype, label id) +inline Foam::label Foam::ensightCells::add(const elemType etype, label id) { // Linear addressing location const label index = offsets_[etype] + sizes_[etype]++; addressing()[index] = id; + + return index; } diff --git a/src/fileFormats/ensight/part/faces/ensightFaces.C b/src/fileFormats/ensight/part/faces/ensightFaces.C index d818a06536..e3ee917d12 100644 --- a/src/fileFormats/ensight/part/faces/ensightFaces.C +++ b/src/fileFormats/ensight/part/faces/ensightFaces.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,7 +37,9 @@ namespace Foam } const char* Foam::ensightFaces::elemNames[3] = - { "tria3", "quad4", "nsided" }; +{ + "tria3", "quad4", "nsided" +}; static_assert ( @@ -52,7 +54,7 @@ namespace { // Trivial shape classifier -static inline Foam::ensightFaces::elemType whatType(const Foam::face& f) +inline Foam::ensightFaces::elemType whatType(const Foam::face& f) { return ( @@ -71,6 +73,12 @@ static inline Foam::ensightFaces::elemType whatType(const Foam::face& f) void Foam::ensightFaces::resizeAll() { + // Invalidate any previous face ordering + faceOrder_.clear(); + + // Invalidate any previous flipMap + flipMap_.clear(); + // Assign sub-list offsets, determine overall size label len = 0; @@ -87,9 +95,6 @@ void Foam::ensightFaces::resizeAll() // The addressing space addressing().resize(len, Zero); - - // Normally assume no flipMap - flipMap_.clear(); } @@ -98,6 +103,7 @@ void Foam::ensightFaces::resizeAll() Foam::ensightFaces::ensightFaces() : ensightPart(), + faceOrder_(), flipMap_(), offsets_(Zero), sizes_(Zero) @@ -129,12 +135,12 @@ Foam::FixedList Foam::ensightFaces::sizes() const Foam::label Foam::ensightFaces::total() const { - label n = 0; + label nTotal = 0; forAll(sizes_, typei) { - n += sizes_[typei]; + nTotal += sizes_[typei]; } - return n; + return nTotal; } @@ -144,6 +150,7 @@ void Foam::ensightFaces::clear() ensightPart::clear(); + faceOrder_.clear(); flipMap_.clear(); sizes_ = Zero; offsets_ = Zero; @@ -167,42 +174,42 @@ void Foam::ensightFaces::reduce() void Foam::ensightFaces::sort() { - const bool useFlip = (size() == flipMap_.size()); - - if (useFlip) + // Some extra safety + if (faceOrder_.size() != size()) { - // Must sort flip map as well - labelList order; - - for (int typei=0; typei < nTypes; ++typei) - { - const labelRange sub(range(elemType(typei))); - - if (!sub.empty()) - { - SubList