diff --git a/src/conversion/ensight/output/ensightOutputAreaField.H b/src/conversion/ensight/output/ensightOutputAreaField.H new file mode 100644 index 0000000000000000000000000000000000000000..37618cca6d097ef1cf2ee65e067d44b3c03d3fa3 --- /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 <http://www.gnu.org/licenses/>. + +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<class Type> +bool writeAreaField +( + ensightFile& os, + const GeometricField<Type, faPatchField, areaMesh>& 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 0000000000000000000000000000000000000000..aaccbd3cc212cdb6dc2ce61c06c412dc68d5e98e --- /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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "ensightOutputAreaField.H" +#include "ensightFaMesh.H" +#include "areaFaMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +bool Foam::ensightOutput::writeAreaField +( + ensightFile& os, + const GeometricField<Type, faPatchField, areaMesh>& 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 f85dddb5bf992a40c4045c73ec3a9aeec7c0dd40..6c0427f9772ffb6608f90d2223bba69dd5517aa8 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<ensightCells>& cellZoneParts() const; + const Map<ensightCells>& cellZoneParts() const noexcept + { + return cellZoneParts_; + } //- Face elements per faceZone, lookup by zone index. // Process in sorted order. - inline const Map<ensightFaces>& faceZoneParts() const; + const Map<ensightFaces>& faceZoneParts() const noexcept + { + return faceZoneParts_; + } //- Face elements per selected patch, lookup by patch index // Process in sorted order. - inline const Map<ensightFaces>& boundaryParts() const; + const Map<ensightFaces>& 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<ensightGeoFile>& os, + ensightGeoFile& os, bool parallel = Pstream::parRun() ) const; //- Write geometry to file. Normally in parallel - void write + inline void write ( - ensightGeoFile& os, + autoPtr<ensightGeoFile>& 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<wordRe>& patterns); diff --git a/src/fileFormats/ensight/mesh/ensightMeshI.H b/src/fileFormats/ensight/mesh/ensightMeshI.H index a9cdbfbc730f8dfb34a7b87404ef52793990b55a..ed8499fd54508777bc68921685f24b69321895a6 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::ensightCells>& -Foam::ensightMesh::cellZoneParts() const -{ - return cellZoneParts_; -} - - -inline const Foam::Map<Foam::ensightFaces>& -Foam::ensightMesh::faceZoneParts() const -{ - return faceZoneParts_; -} - - -inline const Foam::Map<Foam::ensightFaces>& -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 831d076897fdddeeb2a9fad57e06c988ccf19f37..333ce8602a15411b6e81510d9969822f6c3cee84 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 4a2f77dcbf4f0ea411e9ca1e4ea5de6a98335a13..fefe06a5358e69eb1fc278a68b8fbba46c423fa4 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<class Type> +bool writeFaceLocalField +( + ensightFile& os, + const Field<Type>& 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 00f5ab4d234585be2db9c44cb2f69c30c4da475e..3c408d6fc2ff39c88dc0f67776f5ce258b580ef2 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<class Type> +bool Foam::ensightOutput::Detail::writeFaceLocalField +( + ensightFile& os, + const Field<Type>& 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<bool>()); + } + + // No field + if (!hasField) return false; + } + + bool validAddressing = (part.size() == part.faceOrder().size()); + + if (parallel) + { + reduce(validAddressing, orOp<bool>()); + } + + 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<Type>(fld, part.faceOrder(etype)), + parallel + ); + } + + return true; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + template<class Type> bool Foam::ensightOutput::writeField ( diff --git a/src/fileFormats/ensight/part/cells/ensightCells.C b/src/fileFormats/ensight/part/cells/ensightCells.C index 4cc92045e87f5591a3cc357b968829afee73821b..2aca01bd2555b4bd0ec15d5131453c2be0bac42d 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::label, 5> 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 ee5c1ea7cf4baa2baa072a3c6fdf7a66e667f28a..e24e712ad5ba65ed2d057930dc4e5dd7c1bf3cfb 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 cfccab8eed477d488552471acf5de617f30702a3..58e80324f35a26e0beca0d1b29a0bd7df7dad142 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 d818a06536e1e704463fb3e7c48bebba9ca78d66..e3ee917d1215154505f6cf74782dfd3a6d5fe84e 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::label, 3> 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()); + // Some extra safety + if (faceOrder_.size() != size()) + { + faceOrder_.clear(); + } + if (flipMap_.size() != size()) + { + flipMap_.clear(); + } - if (useFlip) + // Sort by face Ids. + // Use to reorder flip maps and face-order too. + + for (int typei=0; typei < nTypes; ++typei) { - // Must sort flip map as well - labelList order; + const labelRange sub(range(elemType(typei))); - for (int typei=0; typei < nTypes; ++typei) + if (!sub.empty()) { - const labelRange sub(range(elemType(typei))); + SubList<label> ids(sub, addressing()); + labelList order(Foam::sortedOrder(ids)); + + ids = reorder<labelList>(order, ids); - if (!sub.empty()) + // Sort flip map as well + if (!flipMap_.empty()) { - SubList<label> ids(addressing(), sub); SubList<bool> flips(flipMap_, sub); - - Foam::sortedOrder(ids, order); - - ids = reorder<labelList>(order, ids); - flips = reorder<boolList>(order, flips); + flips = reorder<boolList>(order, flips); } - } - } - else - { - flipMap_.clear(); // Extra safety - // No flip-maps, simply sort addresses - for (int typei=0; typei < nTypes; ++typei) - { - const labelRange sub(range(elemType(typei))); - - if (!sub.empty()) + // Sort face ordering as well + if (!faceOrder_.empty()) { - SubList<label> ids(addressing(), sub); - Foam::sort(ids); + SubList<label> faceOrder(faceOrder_, sub); + faceOrder = reorder<labelList>(order, faceOrder); } } } @@ -226,7 +233,6 @@ void Foam::ensightFaces::classify(const UList<face>& faces) resizeAll(); // adjust allocation sizes_ = Zero; // reset sizes - use for local indexing here - // Pass 2: Assign face-id per shape type for (label listi = 0; listi < len; ++listi) @@ -283,28 +289,34 @@ void Foam::ensightFaces::classify resizeAll(); // adjust allocation sizes_ = Zero; // reset sizes - use for local indexing here + label nUsed = addressing().size(); + if (useFlip) { - flipMap_.resize(len); + flipMap_.resize(nUsed); flipMap_ = false; } - else - { - flipMap_.clear(); // Extra safety - } + + faceOrder_.resize(nUsed); // Pass 2: Assign face-id per shape type + // - also record the face order + nUsed = 0; for (label listi = 0; listi < len; ++listi) { const label faceId = addr[listi]; - const bool doFlip = useFlip && flipMap[listi]; if (!exclude.test(faceId)) { + const bool doFlip = useFlip && flipMap.test(listi); + const auto etype = whatType(faces[faceId]); - add(etype, faceId, doFlip); + const label idx = add(etype, faceId, doFlip); + + faceOrder_[nUsed] = idx; + ++nUsed; } } } diff --git a/src/fileFormats/ensight/part/faces/ensightFaces.H b/src/fileFormats/ensight/part/faces/ensightFaces.H index dd77bac66fb902794f466ab929f49e697624794d..38b804859e076d8bcff72be2091da022fe443cf6 100644 --- a/src/fileFormats/ensight/part/faces/ensightFaces.H +++ b/src/fileFormats/ensight/part/faces/ensightFaces.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. @@ -43,14 +43,17 @@ Description // Can now address into boundaryField \endcode + Additionally, for some uses (eg, finiteArea), the ordered + list of faces can be used for a direct local lookup into the field + instead of via the overall mesh face addressing. + \*---------------------------------------------------------------------------*/ #ifndef ensightFaces_H #define ensightFaces_H #include "ensightPart.H" -#include "boolList.H" -#include "faceList.H" +#include "face.H" #include "FixedList.H" #include "bitSet.H" @@ -100,7 +103,10 @@ private: // Private Data - //- Linear list of face-flips + //- The input face order, for indirect face lists + labelList faceOrder_; + + //- List of face-flips (optional) boolList flipMap_; //- Begin/end offsets for address/flips of each element type @@ -113,8 +119,9 @@ private: // Private Member Functions - //- Low-level internal addition routine - inline void add(const elemType etype, label id, bool flip=false); + //- Low-level internal addition routine. + // \return insertion locaion + inline label add(const elemType etype, label id, bool flip=false); //- Use temporarily stored sizes to redimension the element lists void resizeAll(); @@ -168,7 +175,7 @@ public: FixedList<label, nTypes> sizes() const; //- Processor-local face ids of all elements - inline const labelList& faceIds() const; + inline const labelList& faceIds() const noexcept; //- Processor-local face ids of the specified element type inline const labelUList faceIds(const elemType etype) const; @@ -179,6 +186,14 @@ public: //- True for non-zero flip-map that spans the addresses inline bool usesFlipMap() const; + //- Processor-local face order + //- (where applicable) + inline const labelList& faceOrder() const noexcept; + + //- Processor-local face order of specified element type + //- (where applicable) + inline const labelUList faceOrder(const elemType etype) const; + // Edit @@ -211,7 +226,7 @@ public: //- Sum element counts across all processes. void reduce(); - //- Sort element lists numerically. + //- Inplace sort element lists numerically. void sort(); diff --git a/src/fileFormats/ensight/part/faces/ensightFacesI.H b/src/fileFormats/ensight/part/faces/ensightFacesI.H index b971115ac8e8dcfbb2146d8c10b9a6f89cbb05d2..24ff96a866c8b7c8c700de72d1f87b710b701b96 100644 --- a/src/fileFormats/ensight/part/faces/ensightFacesI.H +++ b/src/fileFormats/ensight/part/faces/ensightFacesI.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,7 +27,8 @@ License // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -inline void Foam::ensightFaces::add(const elemType etype, label id, bool flip) +inline Foam::label +Foam::ensightFaces::add(const elemType etype, label id, bool flip) { // Linear addressing location const label index = offsets_[etype] + sizes_[etype]++; @@ -38,6 +39,8 @@ inline void Foam::ensightFaces::add(const elemType etype, label id, bool flip) { flipMap_[index] = flip; } + + return index; } @@ -73,7 +76,7 @@ inline Foam::labelRange Foam::ensightFaces::range(const elemType etype) const } -inline const Foam::labelList& Foam::ensightFaces::faceIds() const +inline const Foam::labelList& Foam::ensightFaces::faceIds() const noexcept { return addressing(); } @@ -98,6 +101,20 @@ inline bool Foam::ensightFaces::usesFlipMap() const } +inline const Foam::labelList& +Foam::ensightFaces::faceOrder() const noexcept +{ + return faceOrder_; +} + + +inline const Foam::labelUList +Foam::ensightFaces::faceOrder(const elemType etype) const +{ + return faceOrder_[range(etype)]; +} + + inline void Foam::ensightFaces::incrFaceIds(const label off) { incrAddressing(off); diff --git a/src/fileFormats/ensight/part/part/ensightPart.C b/src/fileFormats/ensight/part/part/ensightPart.C index 70d7d51e2ea64f4330369839990e6eb1c814fac8..4f218b7864573e70e1342493099fcb0c25e04464 100644 --- a/src/fileFormats/ensight/part/part/ensightPart.C +++ b/src/fileFormats/ensight/part/part/ensightPart.C @@ -58,7 +58,7 @@ void Foam::ensightPart::decrAddressing(const label off) // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::ensightPart::ensightPart() noexcept +Foam::ensightPart::ensightPart() : index_(0), identifier_(-1), diff --git a/src/fileFormats/ensight/part/part/ensightPart.H b/src/fileFormats/ensight/part/part/ensightPart.H index 9bb3d4e250e91eb9b8573ed643e6f06cfface2a6..a420b6bb1e304f19419608dbdd3c6d9f63db575d 100644 --- a/src/fileFormats/ensight/part/part/ensightPart.H +++ b/src/fileFormats/ensight/part/part/ensightPart.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -74,13 +74,13 @@ class ensightPart protected: //- Element addressing - const labelList& addressing() const + const labelList& addressing() const noexcept { return address_; } //- Element addressing - labelList& addressing() + labelList& addressing() noexcept { return address_; } @@ -109,7 +109,7 @@ public: // Constructors //- Default construct. Index=0, identifier = -1 - ensightPart() noexcept; + ensightPart(); //- Default construct, with description/partName explicit ensightPart(const string& description); @@ -122,43 +122,43 @@ public: // Member Functions //- The index in a list (0-based) - label index() const + label index() const noexcept { return index_; } //- The index in a list (0-based) - label& index() + label& index() noexcept { return index_; } //- OpenFOAM identifier (patch, zone, etc), -1 when not in use. - label identifier() const + label identifier() const noexcept { return identifier_; } //- OpenFOAM identifier (patch, zone, etc), -1 when not in use. - label& identifier() + label& identifier() noexcept { return identifier_; } //- Processor-local test for any elements. - bool empty() const + bool empty() const noexcept { return address_.empty(); } //- Processor-local size of all elements. - label size() const + label size() const noexcept { return address_.size(); } //- The part name or description - const string& name() const + const string& name() const noexcept { return name_; } diff --git a/src/finiteArea/Make/files b/src/finiteArea/Make/files index 7a96d8c4a1ef5c25e0f3b7611f220daccd7c9d14..14d538ace1fe33eb3e0905b77024e0f32019a259 100644 --- a/src/finiteArea/Make/files +++ b/src/finiteArea/Make/files @@ -16,6 +16,9 @@ $(faPatches)/constraint/wedge/wedgeFaPatch.C $(faPatches)/constraint/cyclic/cyclicFaPatch.C $(faPatches)/constraint/symmetry/symmetryFaPatch.C +ensight = output/ensight +$(ensight)/ensightFaMesh.C + faMeshMapper = faMesh/faMeshMapper $(faMeshMapper)/faMeshMapper.C $(faMeshMapper)/faAreaMapper.C diff --git a/src/finiteArea/output/ensight/ensightFaMesh.C b/src/finiteArea/output/ensight/ensightFaMesh.C new file mode 100644 index 0000000000000000000000000000000000000000..09a88c5332a31ebba9db422e9eac43561dc38101 --- /dev/null +++ b/src/finiteArea/output/ensight/ensightFaMesh.C @@ -0,0 +1,114 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "ensightFaMesh.H" +#include "ensightGeoFile.H" +#include "faMesh.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::ensightFaMesh::clear() +{ + areaPart_.clear(); +} + + +void Foam::ensightFaMesh::renumber() +{ + label partNo = 0; + + areaPart_.index() = partNo++; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::ensightFaMesh::ensightFaMesh +( + const faMesh& mesh +) +: + mesh_(mesh), + needsUpdate_(true) +{ + // Lazy? + if (true) + { + correct(); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::ensightFaMesh::correct() +{ + clear(); + + // Area meshes (currently only one) + const label areaId = 0; + { + ensightFaces& part = areaPart_; + + part.clear(); + part.identifier() = areaId; + part.rename("finite-area"); + + part.classify + ( + mesh_.mesh().faces(), + mesh_.faceLabels() + ); + + // Finalize + part.reduce(); + + // if (!part.total()) + // { + // areaParts_.erase(areaId); + // } + } + + renumber(); + + needsUpdate_ = false; +} + + +void Foam::ensightFaMesh::write +( + ensightGeoFile& os, + bool parallel +) const +{ + // Area meshes (currently only one) + // const label areaId = 0; + areaPart_.write(os, mesh_.mesh(), parallel); +} + + +// ************************************************************************* // diff --git a/src/finiteArea/output/ensight/ensightFaMesh.H b/src/finiteArea/output/ensight/ensightFaMesh.H new file mode 100644 index 0000000000000000000000000000000000000000..ee42b6aa240d8839cde63786d89816bf0557404a --- /dev/null +++ b/src/finiteArea/output/ensight/ensightFaMesh.H @@ -0,0 +1,162 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 <http://www.gnu.org/licenses/>. + +Class + Foam::ensightFaMesh + +Description + Encapsulation of area meshes for writing in ensight format. + +Note + Currently restricted to a single faMesh representation. + The face elements are created from a specified subset of polyMesh + faces. The original ordering of these faces is retained in the + ensightFaces faceOrder(). + +SourceFiles + ensightFaMesh.C + ensightFaMeshI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef fa_ensightMesh_H +#define fa_ensightMesh_H + +#include "ensightFaces.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward Declarations +class faMesh; +class ensightGeoFile; +class ensightFaMesh; + +/*---------------------------------------------------------------------------*\ + Class ensightMesh Declaration +\*---------------------------------------------------------------------------*/ + +class ensightFaMesh +{ + // Private Data + + //- Reference to the finite-area mesh + const faMesh& mesh_; + + //- Face elements for the area mesh (currently only one) + ensightFaces areaPart_; + + //- Track if it needs an update + mutable bool needsUpdate_; + + + // Private Member Functions + + //- Clear all storage + void clear(); + + //- Enforce consistent index/part numbering + void renumber(); + + //- No copy construct + ensightFaMesh(const ensightFaMesh&) = delete; + + //- No copy assignment + void operator=(const ensightFaMesh&) = delete; + + +public: + + // Constructors + + //- Construct from mesh with all default options + explicit ensightFaMesh(const faMesh& mesh); + + + // Member Functions + + // Access + + //- Reference to the underlying faMesh + const faMesh& mesh() const noexcept + { + return mesh_; + } + + //- Face elements for finite-area + const ensightFaces& areaPart() const noexcept + { + return areaPart_; + } + + + // Other + + //- Does the content need an update? + bool needsUpdate() const noexcept + { + return needsUpdate_; + } + + //- Mark as needing an update. + // May also free up unneeded data. + // Return false if already marked as expired. + inline bool expire(); + + //- Update for new mesh + void correct(); + + + // Output + + //- Write geometry to file. Normally in parallel + void write + ( + ensightGeoFile& os, + bool parallel = Pstream::parRun() + ) const; + + //- Write geometry to file. Normally in parallel + inline void write + ( + autoPtr<ensightGeoFile>& os, + bool parallel = Pstream::parRun() + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "ensightFaMeshI.H" + +#endif + +// ************************************************************************* // diff --git a/src/finiteArea/output/ensight/ensightFaMeshI.H b/src/finiteArea/output/ensight/ensightFaMeshI.H new file mode 100644 index 0000000000000000000000000000000000000000..6e989cc12f54bc72e7a5c9ee6c33dc85fc865a18 --- /dev/null +++ b/src/finiteArea/output/ensight/ensightFaMeshI.H @@ -0,0 +1,55 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline bool Foam::ensightFaMesh::expire() +{ + clear(); + + // Already marked as expired + if (needsUpdate_) + { + return false; + } + + needsUpdate_ = true; + return true; +} + + +inline void Foam::ensightFaMesh::write +( + autoPtr<ensightGeoFile>& os, + bool parallel +) const +{ + write(os.ref(), parallel); +} + + +// ************************************************************************* //